import { useCallback, useMemo, useState } from "react"; import { App, Breadcrumb, Button, Input, Table } from "antd"; import { useNavigate } from "react-router"; import { KnowledgeContentType, KnowledgeItemSearchResult, KnowledgeSourceType, } from "../knowledge-management.model"; import { knowledgeContentTypeOptions, knowledgeSourceTypeOptions, } from "../knowledge-management.const"; import { searchKnowledgeItemsUsingGet } from "../knowledge-management.api"; import { formatBytes, formatDateTime } from "@/utils/unit"; const buildOptionMap = (options: { label: string; value: string }[]) => options.reduce>((acc, option) => { acc[option.value] = option.label; return acc; }, {}); export default function KnowledgeManagementSearch() { 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 contentTypeMap = useMemo( () => buildOptionMap(knowledgeContentTypeOptions), [] ); const sourceTypeMap = useMemo( () => buildOptionMap(knowledgeSourceTypeOptions), [] ); 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 searchKnowledgeItemsUsingGet({ 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 items:", 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: "setName", key: "setName", width: 220, ellipsis: true, render: (text: string) => text || "-", }, { title: "文件名", dataIndex: "fileName", key: "fileName", width: 220, ellipsis: true, render: (_: string, record: KnowledgeItemSearchResult) => record.fileName || record.sourceFileId || "-", }, { title: "来源类型", dataIndex: "sourceType", key: "sourceType", width: 140, render: (value: KnowledgeSourceType) => sourceTypeMap[value] || value || "-", }, { title: "内容类型", dataIndex: "contentType", key: "contentType", width: 120, render: (value: KnowledgeContentType) => contentTypeMap[value] || value || "-", }, { title: "大小", dataIndex: "fileSize", key: "fileSize", width: 120, render: (value?: number) => formatBytes(value ?? 0), }, { 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: KnowledgeItemSearchResult) => ( ), }, ], [contentTypeMap, navigate, sourceTypeMap] ); return (
navigate("/data/knowledge-management")}>知识管理 全库搜索

知识管理全库检索

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: () => { navigate(`/data/knowledge-management/detail/${record.setId}`); }, })} /> ); }