From eada5fe8b127d3b71a4fb4c423268b1bdb221260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B6=85=E7=BA=A7=E8=80=81=E7=99=BD=E5=85=94?= Date: Fri, 31 Oct 2025 16:18:12 +0800 Subject: [PATCH] Refactor AIKnowledgeDetail and AIKnowledgeList components to improve user navigation and search functionality. Update deletion logic to navigate back on success and enhance search with debouncing and keyword handling. Adjust API to support keyword filtering in fetchKnowledgeBaseList. --- .../workspace/ai-knowledge/detail/index.tsx | 7 +- .../mobile/workspace/ai-knowledge/list/api.ts | 1 + .../workspace/ai-knowledge/list/index.tsx | 87 +++++++++++-------- 3 files changed, 57 insertions(+), 38 deletions(-) diff --git a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/detail/index.tsx b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/detail/index.tsx index 1728f924..964ad95e 100644 --- a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/detail/index.tsx +++ b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/detail/index.tsx @@ -225,8 +225,8 @@ const AIKnowledgeDetail: React.FC = () => { content: "删除成功", icon: "success", }); - // 刷新素材列表 - await fetchMaterialList(); + // 删除成功后返回上一页 + navigate(-1); } catch (error) { Toast.show({ content: "删除失败", @@ -250,7 +250,8 @@ const AIKnowledgeDetail: React.FC = () => { content: "删除成功", icon: "success", }); - setMaterials(prev => prev.filter(m => m.id !== materialId)); + // 刷新库内素材列表 + await fetchMaterialList(); } catch (error) { Toast.show({ content: "删除失败", diff --git a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/api.ts b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/api.ts index e2e445e8..03d23068 100644 --- a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/api.ts +++ b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/api.ts @@ -24,6 +24,7 @@ export function releaseAIKnowledge(id: number): Promise { export function fetchKnowledgeBaseList(params: { page?: number; limit?: number; + keyword?: string; }): Promise { return request("/v1/knowledge/typeList", params, "GET"); } diff --git a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/index.tsx b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/index.tsx index 5bf52f78..5864c1f5 100644 --- a/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/index.tsx +++ b/Cunkebao/src/pages/mobile/workspace/ai-knowledge/list/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useState, useCallback, useRef } from "react"; import { useNavigate } from "react-router-dom"; import { Button, @@ -18,7 +18,6 @@ import { GlobalOutlined, InfoCircleOutlined, SearchOutlined, - ArrowRightOutlined, } from "@ant-design/icons"; import Layout from "@/components/Layout/Layout"; import NavCommon from "@/components/NavCommon"; @@ -42,26 +41,20 @@ const AIKnowledgeList: React.FC = () => { const [enabledCount, setEnabledCount] = useState(0); const [page, setPage] = useState(1); const [menuLoadingId, setMenuLoadingId] = useState(null); - const [searchValue, setSearchValue] = useState(""); // 搜索内容 + const [searchValue, setSearchValue] = useState(""); // 搜索输入内容 + const [keyword, setKeyword] = useState(""); // 实际用于搜索的关键词 + const isInitialMount = useRef(true); // 标记是否是初始挂载 // 弹窗控制 const [globalPromptVisible, setGlobalPromptVisible] = useState(false); - useEffect(() => { - // 初始化AI功能 - initAIKnowledge().catch(err => { - console.warn("初始化AI功能失败", err); - }); - fetchList(1); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const fetchList = async (pageNum = 1) => { + const fetchList = useCallback(async (pageNum = 1, searchKeyword = "") => { setLoading(true); try { const res = await fetchKnowledgeBaseList({ page: pageNum, limit: PAGE_SIZE, + keyword: searchKeyword || undefined, }); // 转换数据格式,映射接口字段到前端字段 const transformedList = (res?.data || []).map((item: any) => ({ @@ -80,30 +73,46 @@ const AIKnowledgeList: React.FC = () => { } finally { setLoading(false); } - }; + }, []); + + useEffect(() => { + // 初始化AI功能 + initAIKnowledge().catch(err => { + console.warn("初始化AI功能失败", err); + }); + fetchList(1, ""); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + // 搜索防抖处理 + const debouncedSearch = useCallback(() => { + const timer = setTimeout(() => { + const searchKeyword = searchValue.trim(); + setKeyword(searchKeyword); + setPage(1); + fetchList(1, searchKeyword); + }, 500); // 500ms 防抖延迟 + + return () => clearTimeout(timer); + }, [searchValue, fetchList]); + + useEffect(() => { + // 初始挂载时不触发搜索(已在初始化时调用 fetchList) + if (isInitialMount.current) { + isInitialMount.current = false; + return; + } + const cleanup = debouncedSearch(); + return cleanup; + }, [debouncedSearch]); const handlePageChange = (p: number) => { setPage(p); - fetchList(p); + fetchList(p, keyword); }; const handleRefresh = () => { - fetchList(page); - }; - - const handleSearch = () => { - setPage(1); - }; - - const getFilteredList = () => { - const keyword = searchValue.trim().toLowerCase(); - if (!keyword) return list; - return list.filter(item => { - return ( - item.name.toLowerCase().includes(keyword) || - (item.description || "").toLowerCase().includes(keyword) - ); - }); + fetchList(page, keyword); }; // 菜单点击事件 @@ -342,12 +351,18 @@ const AIKnowledgeList: React.FC = () => { }} > setSearchValue(e.target.value)} prefix={} allowClear size="large" + onPressEnter={() => { + const searchKeyword = searchValue.trim(); + setKeyword(searchKeyword); + setPage(1); + fetchList(1, searchKeyword); + }} /> @@ -382,14 +397,16 @@ const AIKnowledgeList: React.FC = () => {
- ) : getFilteredList().length > 0 ? ( - getFilteredList().map(renderCard) + ) : list.length > 0 ? ( + list.map(renderCard) ) : (
-
暂无知识库
+
+ {keyword ? "未找到匹配的知识库" : "暂无知识库"} +
)}