You've already forked DataMate
feat(knowledge-base): 添加知识库统计功能
- 后端服务新增 KnowledgeBaseStatisticsResp 和 RagFileStatistics 数据传输对象 - 在 KnowledgeBaseService 中实现 getStatistics 方法提供统计信息查询 - 为 RagFileRepository 添加 getStatistics 接口及其实现 - 通过 MyBatis Mapper 实现数据库层面的统计查询功能 - 在 KnowledgeBaseController 中暴露 /statistics 接口供前端调用 - 前端页面集成统计卡片组件展示知识库、文件数量及总大小信息 - 实现前后端数据同步机制确保统计数据实时更新
This commit is contained in:
@@ -1,23 +1,48 @@
|
||||
import { useState } from "react";
|
||||
import { Card, Button, Table, Tooltip, message } from "antd";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Card, Button, Table, Tooltip, message, Statistic } from "antd";
|
||||
import { DeleteOutlined, EditOutlined } from "@ant-design/icons";
|
||||
import { SearchControls } from "@/components/SearchControls";
|
||||
import { useNavigate } from "react-router";
|
||||
import CardView from "@/components/CardView";
|
||||
import {
|
||||
deleteKnowledgeBaseByIdUsingDelete,
|
||||
getKnowledgeBaseStatisticsUsingGet,
|
||||
queryKnowledgeBasesUsingPost,
|
||||
} from "../knowledge-base.api";
|
||||
import useFetchData from "@/hooks/useFetchData";
|
||||
import { KnowledgeBaseItem } from "../knowledge-base.model";
|
||||
import { KnowledgeBaseItem, KnowledgeBaseStatistics } from "../knowledge-base.model";
|
||||
import CreateKnowledgeBase from "../components/CreateKnowledgeBase";
|
||||
import { mapKnowledgeBase } from "../knowledge-base.const";
|
||||
import { formatBytes } from "@/utils/unit";
|
||||
|
||||
type StatisticsItem = {
|
||||
title: string;
|
||||
value: number | string;
|
||||
};
|
||||
|
||||
const DEFAULT_STATISTICS: StatisticsItem[] = [
|
||||
{
|
||||
title: "知识库总数",
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
title: "文件总数",
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
title: "总大小",
|
||||
value: "0 B",
|
||||
},
|
||||
];
|
||||
|
||||
export default function KnowledgeBasePage() {
|
||||
const navigate = useNavigate();
|
||||
const [viewMode, setViewMode] = useState<"card" | "list">("card");
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const [currentKB, setCurrentKB] = useState<KnowledgeBaseItem | null>(null);
|
||||
const [statisticsData, setStatisticsData] = useState<StatisticsItem[]>(
|
||||
DEFAULT_STATISTICS
|
||||
);
|
||||
const {
|
||||
loading,
|
||||
tableData,
|
||||
@@ -32,11 +57,43 @@ export default function KnowledgeBasePage() {
|
||||
(kb) => mapKnowledgeBase(kb, false) // 在首页不显示索引模型和文本理解模型字段
|
||||
);
|
||||
|
||||
const fetchStatistics = useCallback(async () => {
|
||||
try {
|
||||
const { data } = await getKnowledgeBaseStatisticsUsingGet();
|
||||
const stats = data as KnowledgeBaseStatistics | undefined;
|
||||
setStatisticsData([
|
||||
{
|
||||
title: "知识库总数",
|
||||
value: stats?.totalKnowledgeBases ?? 0,
|
||||
},
|
||||
{
|
||||
title: "文件总数",
|
||||
value: stats?.totalFiles ?? 0,
|
||||
},
|
||||
{
|
||||
title: "总大小",
|
||||
value: formatBytes(stats?.totalSize ?? 0),
|
||||
},
|
||||
]);
|
||||
} catch {
|
||||
message.error("统计数据加载失败");
|
||||
setStatisticsData(DEFAULT_STATISTICS);
|
||||
}
|
||||
}, []);
|
||||
|
||||
const refreshAll = useCallback(async () => {
|
||||
await Promise.all([fetchData(), fetchStatistics()]);
|
||||
}, [fetchData, fetchStatistics]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchStatistics();
|
||||
}, [fetchStatistics]);
|
||||
|
||||
const handleDeleteKB = async (kb: KnowledgeBaseItem) => {
|
||||
try {
|
||||
await deleteKnowledgeBaseByIdUsingDelete(kb.id);
|
||||
message.success("知识库删除成功");
|
||||
fetchData();
|
||||
await refreshAll();
|
||||
} catch {
|
||||
message.error("知识库删除失败");
|
||||
}
|
||||
@@ -140,7 +197,7 @@ export default function KnowledgeBasePage() {
|
||||
isEdit={isEdit}
|
||||
data={currentKB}
|
||||
onUpdate={() => {
|
||||
fetchData();
|
||||
refreshAll();
|
||||
}}
|
||||
onClose={() => {
|
||||
setIsEdit(false);
|
||||
@@ -150,6 +207,20 @@ export default function KnowledgeBasePage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
<Card>
|
||||
<div className="grid grid-cols-3">
|
||||
{statisticsData.map((item) => (
|
||||
<Statistic
|
||||
title={item.title}
|
||||
key={item.title}
|
||||
value={`${item.value}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<SearchControls
|
||||
searchTerm={searchParams.keyword}
|
||||
onSearchChange={handleKeywordChange}
|
||||
@@ -160,7 +231,7 @@ export default function KnowledgeBasePage() {
|
||||
viewMode={viewMode}
|
||||
onViewModeChange={setViewMode}
|
||||
showViewToggle
|
||||
onReload={fetchData}
|
||||
onReload={refreshAll}
|
||||
/>
|
||||
{viewMode === "card" ? (
|
||||
<CardView
|
||||
|
||||
@@ -38,6 +38,11 @@ export function queryKnowledgeBaseFilesSearchUsingGet(params: RequestParams) {
|
||||
return get("/api/knowledge-base/files/search", params);
|
||||
}
|
||||
|
||||
// 获取知识库统计
|
||||
export function getKnowledgeBaseStatisticsUsingGet() {
|
||||
return get("/api/knowledge-base/statistics");
|
||||
}
|
||||
|
||||
// 添加文件到知识库
|
||||
export function addKnowledgeBaseFilesUsingPost(baseId: string, data: RequestPayload) {
|
||||
return post(`/api/knowledge-base/${baseId}/files`, data);
|
||||
|
||||
@@ -25,6 +25,12 @@ export interface KnowledgeBaseItem {
|
||||
chat: never;
|
||||
}
|
||||
|
||||
export interface KnowledgeBaseStatistics {
|
||||
totalKnowledgeBases: number;
|
||||
totalFiles: number;
|
||||
totalSize: number;
|
||||
}
|
||||
|
||||
export interface KBFile {
|
||||
id: string;
|
||||
fileName: string;
|
||||
|
||||
Reference in New Issue
Block a user