Skip to content

Commit d89811f

Browse files
authored
add knowledgebase page (#39)
* feat: Update site name to DataMate and refine text for AI data processing * feat: Refactor settings page and implement model access functionality - Created a new ModelAccess component for managing model configurations. - Removed the old Settings component and replaced it with a new SettingsPage component that integrates ModelAccess, SystemConfig, and WebhookConfig. - Added SystemConfig component for managing system settings. - Implemented WebhookConfig component for managing webhook configurations. - Updated API functions for model management in settings.apis.ts. - Adjusted routing to point to the new SettingsPage component. * feat: Implement Data Collection Page with Task Management and Execution Log - Created DataCollectionPage component to manage data collection tasks. - Added TaskManagement and ExecutionLog components for task handling and logging. - Integrated task operations including start, stop, edit, and delete functionalities. - Implemented filtering and searching capabilities in task management. - Introduced SimpleCronScheduler for scheduling tasks with cron expressions. - Updated CreateTask component to utilize new scheduling and template features. - Enhanced BasicInformation component to conditionally render fields based on visibility settings. - Refactored ImportConfiguration component to remove NAS import section. * feat: Update task creation API endpoint and enhance task creation form with new fields and validation * Refactor file upload and operator management components - Removed unnecessary console logs from file download and export functions. - Added size property to TaskItem interface for better task management. - Simplified TaskUpload component by utilizing useFileSliceUpload hook for file upload logic. - Enhanced OperatorPluginCreate component to handle file uploads and parsing more efficiently. - Updated ConfigureStep component to use Ant Design Form for better data handling and validation. - Improved PreviewStep component to navigate back to the operator market. - Added support for additional file types in UploadStep component. - Implemented delete operator functionality in OperatorMarketPage with confirmation prompts. - Cleaned up unused API functions in operator.api.ts to streamline the codebase. - Fixed number formatting utility to handle zero values correctly. * Refactor Knowledge Generation to Knowledge Base - Created new API service for Knowledge Base operations including querying, creating, updating, and deleting knowledge bases and files. - Added constants for Knowledge Base status and type mappings. - Defined models for Knowledge Base and related files. - Removed obsolete Knowledge Base creation and home components, replacing them with new implementations under the Knowledge Base structure. - Updated routing to reflect the new Knowledge Base paths. - Adjusted menu items to align with the new Knowledge Base terminology. - Modified ModelAccess interface to include modelName and type properties.
1 parent ba6caab commit d89811f

16 files changed

Lines changed: 1119 additions & 1166 deletions

frontend/src/pages/KnowledgeBase/Create/KnowledgeBaseCreate.tsx

Lines changed: 582 additions & 0 deletions
Large diffs are not rendered by default.

frontend/src/pages/KnowledgeGeneration/Detail/KnowledgeBaseDetail.tsx renamed to frontend/src/pages/KnowledgeBase/Detail/KnowledgeBaseDetail.tsx

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -30,62 +30,20 @@ import {
3030
Checkbox,
3131
Dropdown,
3232
} from "antd";
33-
import { mockKnowledgeBases } from "@/mock/knowledgeBase";
3433
import { useNavigate } from "react-router";
3534
import DetailHeader from "@/components/DetailHeader";
3635
import { SearchControls } from "@/components/SearchControls";
37-
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
36+
import { KnowledgeBaseItem } from "../knowledge-base.model";
3837

3938
const KnowledgeBaseDetailPage: React.FC = () => {
40-
return <DevelopmentInProgress />;
4139
const navigate = useNavigate();
42-
const knowledgeBase = mockKnowledgeBases[0];
43-
40+
const [knowledgeBase, setKnowledgeBase] = useState<KnowledgeBaseItem>(null);
4441
const [files, setFiles] = useState([]);
4542

46-
// --- 新增的状态 ---
47-
const [fileSearchQuery, setFileSearchQuery] = useState("");
48-
const [fileTypeFilter, setFileTypeFilter] = useState<string | null>(null);
49-
const [fileStatusFilter, setFileStatusFilter] = useState<string | null>(null);
50-
const [fileSortOrder, setFileSortOrder] = useState<
51-
"ascend" | "descend" | null
52-
>(null);
53-
54-
// 获取所有类型和状态选项
55-
const allFileTypes = Array.from(
56-
new Set((knowledgeBase.files ?? []).map((f: KBFile) => f.type))
57-
).filter(Boolean);
58-
59-
const allVectorizationStatuses = [
60-
{ label: "全部", value: null },
61-
{ label: "已完成", value: "completed" },
62-
{ label: "处理中", value: "processing" },
63-
{ label: "向量化中", value: "vectorizing" },
64-
{ label: "导入中", value: "importing" },
65-
{ label: "错误", value: "error" },
66-
{ label: "已禁用", value: "disabled" },
67-
];
68-
69-
useEffect(() => {
70-
setFiles(knowledgeBase.files);
71-
}, [knowledgeBase]);
72-
73-
const [showVectorizationDialog, setShowVectorizationDialog] = useState(false);
74-
const [showEditFileDialog, setShowEditFileDialog] = useState<KBFile | null>(
75-
null
76-
);
7743

7844
// File table logic
7945
const handleDeleteFile = (file: KBFile) => {};
8046

81-
const handleFileSelect = (file: KBFile) => {
82-
setShowEditFileDialog(file);
83-
};
84-
85-
const handleStartVectorization = (fileId?: string) => {
86-
message.info(fileId ? `开始向量化文件 ${fileId}` : "批量向量化所有文件");
87-
// 实际业务逻辑可在此实现
88-
};
8947

9048
const handleDeleteKB = (kb: KnowledgeBase) => {};
9149

@@ -182,7 +140,7 @@ const KnowledgeBaseDetailPage: React.FC = () => {
182140
<Button
183141
type="link"
184142
onClick={() =>
185-
navigate("/data/knowledge-generation/file-detail/" + file.id)
143+
navigate("/data/knowledge-base/file-detail/" + file.id)
186144
}
187145
>
188146
{file.name}
@@ -296,7 +254,7 @@ const KnowledgeBaseDetailPage: React.FC = () => {
296254
<div className="mb-4">
297255
<Breadcrumb>
298256
<Breadcrumb.Item>
299-
<a onClick={() => navigate("/data/knowledge-generation")}>知识库</a>
257+
<a onClick={() => navigate("/data/knowledge-base")}>知识库</a>
300258
</Breadcrumb.Item>
301259
<Breadcrumb.Item>{knowledgeBase.name}</Breadcrumb.Item>
302260
</Breadcrumb>

frontend/src/pages/KnowledgeGeneration/FileDetail/KnowledgeBaseFileDetail.tsx renamed to frontend/src/pages/KnowledgeBase/FileDetail/KnowledgeBaseFileDetail.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { mockChunks, mockQAPairs, sliceOperators } from "@/mock/knowledgeBase";
1616
import type {
1717
KnowledgeBase,
1818
KBFile,
19-
} from "@/pages/KnowledgeGeneration/knowledge-base.model";
19+
} from "@/pages/KnowledgeBase/knowledge-base.model";
2020
import { Link, useNavigate } from "react-router";
2121
import DetailHeader from "@/components/DetailHeader";
2222
import DevelopmentInProgress from "@/components/DevelopmentInProgress";
@@ -258,11 +258,11 @@ const KnowledgeBaseFileDetail: React.FC = () => {
258258
<Breadcrumb
259259
items={[
260260
{
261-
title: <Link to="/data/knowledge-generation">知识库</Link>,
261+
title: <Link to="/data/knowledge-base">知识库</Link>,
262262
},
263263
{
264264
title: (
265-
<Link to="/data/knowledge-generation/detail/1">
265+
<Link to="/data/knowledge-base/detail/1">
266266
{selectedKB?.name}
267267
</Link>
268268
),
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
import { useState } from "react";
2+
import { Card, Button, Table, Tooltip, message } from "antd";
3+
import { DeleteOutlined, EditOutlined } from "@ant-design/icons";
4+
import { SearchControls } from "@/components/SearchControls";
5+
import { useNavigate } from "react-router";
6+
import CardView from "@/components/CardView";
7+
import {
8+
deleteKnowledgeBaseByIdUsingDelete,
9+
queryKnowledgeBasesUsingPost,
10+
} from "../knowledge-base.api";
11+
import useFetchData from "@/hooks/useFetchData";
12+
import { KnowledgeBaseItem } from "../knowledge-base.model";
13+
import CreateKnowledgeBase from "../components/CreateKnowledgeBase";
14+
import { mapKnowledgeBase } from "../knowledge-base.const";
15+
16+
export default function KnowledgeGenerationPage() {
17+
const navigate = useNavigate();
18+
const [viewMode, setViewMode] = useState<"card" | "list">("card");
19+
const [isEdit, setIsEdit] = useState(false);
20+
const [currentKB, setCurrentKB] = useState<KnowledgeBaseItem | null>(null);
21+
const {
22+
loading,
23+
tableData,
24+
searchParams,
25+
pagination,
26+
fetchData,
27+
setSearchParams,
28+
handleFiltersChange,
29+
} = useFetchData<KnowledgeBaseItem>(
30+
queryKnowledgeBasesUsingPost,
31+
mapKnowledgeBase
32+
);
33+
34+
const handleDeleteKB = async (kb: KnowledgeBaseItem) => {
35+
try {
36+
await deleteKnowledgeBaseByIdUsingDelete(kb.id);
37+
message.success("知识库删除成功");
38+
fetchData();
39+
} catch (error) {
40+
message.error("知识库删除失败");
41+
}
42+
};
43+
44+
const operations = [
45+
{
46+
key: "edit",
47+
label: "编辑",
48+
icon: <EditOutlined />,
49+
onClick: (item) => {
50+
setIsEdit(true);
51+
setCurrentKB(item);
52+
},
53+
},
54+
{
55+
key: "delete",
56+
label: "删除",
57+
danger: true,
58+
icon: <DeleteOutlined />,
59+
confirm: {
60+
title: "确认删除",
61+
description: "此操作不可撤销,是否继续?",
62+
okText: "删除",
63+
okType: "danger",
64+
cancelText: "取消",
65+
},
66+
onClick: (item) => handleDeleteKB(item),
67+
},
68+
];
69+
70+
const columns = [
71+
{
72+
title: "知识库",
73+
dataIndex: "name",
74+
key: "name",
75+
fixed: "left" as const,
76+
width: 200,
77+
ellipsis: true,
78+
// render: (_: any, kb: KnowledgeBaseItem) => (
79+
// <Button
80+
// type="link"
81+
// onClick={() => navigate(`/data/knowledge-base/detail/${kb.id}`)}
82+
// >
83+
// {kb.name}
84+
// </Button>
85+
// ),
86+
},
87+
{
88+
title: "向量数据库",
89+
dataIndex: "embeddingModel",
90+
key: "embeddingModel",
91+
width: 150,
92+
ellipsis: true,
93+
},
94+
{
95+
title: "大语言模型",
96+
dataIndex: "chatModel",
97+
key: "chatModel",
98+
width: 150,
99+
ellipsis: true,
100+
},
101+
{
102+
title: "创建时间",
103+
dataIndex: "createdAt",
104+
key: "createdAt",
105+
ellipsis: true,
106+
width: 150,
107+
},
108+
{
109+
title: "更新时间",
110+
dataIndex: "updatedAt",
111+
key: "updatedAt",
112+
ellipsis: true,
113+
width: 150,
114+
},
115+
{
116+
title: "描述",
117+
dataIndex: "description",
118+
key: "description",
119+
width: 120,
120+
ellipsis: true,
121+
},
122+
{
123+
title: "操作",
124+
key: "actions",
125+
fixed: "right" as const,
126+
width: 150,
127+
render: (_: any, kb: KnowledgeBaseItem) => (
128+
<div className="flex items-center gap-2">
129+
{operations.map((op) => (
130+
<Tooltip key={op.key} title={op.label}>
131+
<Button
132+
type="text"
133+
icon={op.icon}
134+
danger={op.danger}
135+
onClick={() => op.onClick(kb)}
136+
/>
137+
</Tooltip>
138+
))}
139+
</div>
140+
),
141+
},
142+
];
143+
// Main list view
144+
return (
145+
<div className="h-full flex flex-col gap-4">
146+
<div className="flex items-center justify-between">
147+
<h1 className="text-xl font-bold">知识生成</h1>
148+
<CreateKnowledgeBase
149+
isEdit={isEdit}
150+
data={currentKB}
151+
onUpdate={fetchData}
152+
/>
153+
</div>
154+
155+
<SearchControls
156+
searchTerm={searchParams.keyword}
157+
onSearchChange={(keyword) =>
158+
setSearchParams({ ...searchParams, keyword })
159+
}
160+
searchPlaceholder="搜索知识库..."
161+
filters={[]}
162+
onFiltersChange={handleFiltersChange}
163+
onClearFilters={() => setSearchParams({ ...searchParams, filter: {} })}
164+
viewMode={viewMode}
165+
onViewModeChange={setViewMode}
166+
showViewToggle
167+
onReload={fetchData}
168+
/>
169+
{viewMode === "card" ? (
170+
<CardView
171+
data={tableData}
172+
operations={operations}
173+
// onView={(item) => navigate(`/data/knowledge-base/detail/${item.id}`)}
174+
pagination={pagination}
175+
/>
176+
) : (
177+
<Card>
178+
<Table
179+
loading={loading}
180+
scroll={{ x: "max-content", y: "calc(100vh - 20rem)" }}
181+
columns={columns}
182+
dataSource={tableData}
183+
rowKey="id"
184+
/>
185+
</Card>
186+
)}
187+
</div>
188+
);
189+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
export default function AddDataDialog() {
2+
const [isOpen, setIsOpen] = useState(false);
3+
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
4+
const { message } = App.useApp();
5+
6+
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
7+
if (e.target.files) {
8+
setSelectedFiles(Array.from(e.target.files));
9+
}
10+
};
11+
12+
const handleUpload = async () => {
13+
if (selectedFiles.length === 0) {
14+
message.error("请先选择文件");
15+
return;
16+
}
17+
18+
try {
19+
const formData = new FormData();
20+
selectedFiles.forEach((file) => {
21+
formData.append("files", file);
22+
});
23+
24+
await uploadDataFilesUsingPost(formData);
25+
message.success("文件上传成功");
26+
setIsOpen(false);
27+
setSelectedFiles([]);
28+
} catch (error) {
29+
message.error("文件上传失败");
30+
}
31+
};
32+
33+
return (
34+
<>
35+
<Button type="primary" onClick={() => setIsOpen(true)}>
36+
添加数据
37+
</Button>
38+
<Modal
39+
title="添加数据文件"
40+
open={isOpen}
41+
onCancel={() => setIsOpen(false)}
42+
onOk={handleUpload}
43+
okText="上传"
44+
>
45+
<input
46+
type="file"
47+
multiple
48+
onChange={handleFileChange}
49+
accept=".txt,.pdf,.docx,.csv,.json"
50+
/>
51+
{selectedFiles.length > 0 && (
52+
<div className="mt-4">
53+
<h4>已选择的文件:</h4>
54+
<ul>
55+
{selectedFiles.map((file, index) => (
56+
<li key={index}>
57+
{file.name} - {(file.size / 1024).toFixed(2)} KB
58+
</li>
59+
))}
60+
</ul>
61+
</div>
62+
)}
63+
</Modal>
64+
</>
65+
);
66+
}

0 commit comments

Comments
 (0)