import { useCallback, useMemo, useState } from "react"; import { App, Badge, Breadcrumb, Button, Input, Table } from "antd"; import { useNavigate } from "react-router"; import { KBFileStatus, KnowledgeBaseFileSearchResult, } from "../knowledge-base.model"; import { KBFileStatusMap } from "../knowledge-base.const"; import { queryKnowledgeBaseFilesSearchUsingGet } from "../knowledge-base.api"; import { formatDateTime } from "@/utils/unit"; const PATH_SEPARATOR = "/"; const normalizePath = (value?: string) => (value ?? "").replace(/\\/g, PATH_SEPARATOR); const resolvePrefix = (relativePath?: string) => { const normalized = normalizePath(relativePath); const parts = normalized.split(PATH_SEPARATOR).filter(Boolean); if (parts.length <= 1) { return ""; } parts.pop(); return `${parts.join(PATH_SEPARATOR)}${PATH_SEPARATOR}`; }; export default function KnowledgeBaseSearch() { const navigate = useNavigate(); const { message } = App.useApp(); const [searchTerm, setSearchTerm] = useState(""); const [activeKeyword, setActiveKeyword] = useState(""); const [loading, setLoading] = useState(false); const [searched, setSearched] = useState(false); const [results, setResults] = useState([]); const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0, }); const fetchResults = useCallback( async (keyword: string, page?: number, pageSize?: number) => { const resolvedPage = page ?? pagination.current; const resolvedPageSize = pageSize ?? pagination.pageSize; if (!keyword) { setResults([]); setPagination((prev) => ({ ...prev, total: 0, current: resolvedPage })); setSearched(false); return; } setLoading(true); try { const { data } = await queryKnowledgeBaseFilesSearchUsingGet({ fileName: keyword, page: Math.max(resolvedPage - 1, 0), size: resolvedPageSize, }); const content = Array.isArray(data?.content) ? data.content : []; setResults(content); setPagination({ current: resolvedPage, pageSize: resolvedPageSize, total: data?.totalElements ?? 0, }); setSearched(true); } catch (error) { console.error("Failed to search knowledge base files:", error); message.error("检索失败,请稍后重试"); } finally { setLoading(false); } }, [message, pagination] ); const handleSearch = (value?: string) => { const keyword = (value ?? searchTerm).trim(); if (!keyword) { message.warning("请输入文件名"); return; } setActiveKeyword(keyword); fetchResults(keyword, 1, pagination.pageSize); }; const columns = useMemo( () => [ { title: "知识库", dataIndex: "knowledgeBaseName", key: "knowledgeBaseName", width: 220, ellipsis: true, render: (text: string) => text || "-", }, { title: "文件名", dataIndex: "fileName", key: "fileName", width: 220, ellipsis: true, }, { title: "相对路径", dataIndex: "relativePath", key: "relativePath", ellipsis: true, render: (value: string) => value || "-", }, { title: "状态", dataIndex: "status", key: "status", width: 120, render: (status?: KBFileStatus) => { const config = status ? KBFileStatusMap[status] : undefined; if (!config) { return ; } return ; }, }, { title: "更新时间", dataIndex: "updatedAt", key: "updatedAt", width: 180, ellipsis: true, render: (value: string) => formatDateTime(value) || "-", }, { title: "操作", key: "action", width: 120, align: "right" as const, render: (_: unknown, record: KnowledgeBaseFileSearchResult) => ( ), }, ], [navigate] ); return (
navigate("/data/knowledge-base")}>知识库 全库搜索

知识库全库检索

setSearchTerm(event.target.value)} onSearch={handleSearch} placeholder="输入文件名,回车或点击搜索" enterButton="搜索" loading={loading} />
`共 ${total} 条`, onChange: (page, pageSize) => { const nextKeyword = activeKeyword.trim(); if (!nextKeyword) { message.warning("请输入文件名"); return; } fetchResults(nextKeyword, page, pageSize || pagination.pageSize); }, }} locale={{ emptyText: searched ? "暂无匹配文件" : "请输入文件名开始检索", }} onRow={(record) => ({ onClick: () => { const prefix = resolvePrefix(record.relativePath); const searchParams = new URLSearchParams(); if (prefix) { searchParams.set("prefix", prefix); } navigate( `/data/knowledge-base/detail/${record.knowledgeBaseId}?${searchParams.toString()}` ); }, })} /> ); }