diff --git a/frontend/src/pages/KnowledgeManagement/components/KnowledgeItemEditor.tsx b/frontend/src/pages/KnowledgeManagement/components/KnowledgeItemEditor.tsx index 77a89ba..88039de 100644 --- a/frontend/src/pages/KnowledgeManagement/components/KnowledgeItemEditor.tsx +++ b/frontend/src/pages/KnowledgeManagement/components/KnowledgeItemEditor.tsx @@ -1,31 +1,16 @@ import { useEffect, useState } from "react"; -import { Button, DatePicker, Form, Input, message, Modal, Select, Upload, UploadFile } from "antd"; +import { Button, Form, message, Modal, Upload, UploadFile } from "antd"; import { UploadOutlined } from "@ant-design/icons"; -import dayjs from "dayjs"; import { downloadKnowledgeItemFileUsingGet, replaceKnowledgeItemFileUsingPut, - updateKnowledgeItemByIdUsingPut, uploadKnowledgeItemsUsingPost, } from "../knowledge-management.api"; -import { - knowledgeStatusOptions, -} from "../knowledge-management.const"; import { KnowledgeContentType, KnowledgeItem, KnowledgeSourceType, - KnowledgeStatusType, } from "../knowledge-management.model"; -import { queryDatasetTagsUsingGet } from "@/pages/DataManagement/dataset.api"; - -const stripFileExtension = (fileName: string) => { - const dotIndex = fileName.lastIndexOf("."); - if (dotIndex <= 0) { - return fileName; - } - return fileName.slice(0, dotIndex); -}; export default function KnowledgeItemEditor({ open, @@ -42,115 +27,38 @@ export default function KnowledgeItemEditor({ onCancel: () => void; onSuccess: () => void; }) { - const [form] = Form.useForm(); - const [tagOptions, setTagOptions] = useState<{ label: string; value: string }[]>([]); const [fileList, setFileList] = useState([]); const [replaceFileList, setReplaceFileList] = useState([]); - const [titleBeforeReplace, setTitleBeforeReplace] = useState(null); - const isMultiFile = fileList.length > 1; const isFileItem = data?.contentType === KnowledgeContentType.FILE || data?.sourceType === KnowledgeSourceType.FILE_UPLOAD; const isCreateMode = !data?.id; - const contentTypeLabel = isCreateMode - ? "文件" - : data?.contentType === KnowledgeContentType.MARKDOWN - ? "Markdown" - : data?.contentType === KnowledgeContentType.TEXT - ? "文本" - : "文件"; - - const fetchTags = async () => { - try { - const { data: tagData } = await queryDatasetTagsUsingGet(); - const options = Array.isArray(tagData) - ? tagData.map((tag) => ({ label: tag.name, value: tag.name })) - : []; - setTagOptions(options); - } catch (error) { - console.error("获取标签失败", error); - } - }; useEffect(() => { - if (open) { - fetchTags(); - } - }, [open]); - - useEffect(() => { - if (open) { - if (data?.id) { - form.setFieldsValue({ - title: data.title, - status: data.status ?? KnowledgeStatusType.DRAFT, - domain: data.domain, - businessLine: data.businessLine, - owner: data.owner, - sensitivity: data.sensitivity, - validFrom: data.validFrom ? dayjs(data.validFrom) : null, - validTo: data.validTo ? dayjs(data.validTo) : null, - tags: data.tags?.map((tag) => tag.name) || [], - metadata: data.metadata, - }); - setTitleBeforeReplace(null); - } else { - form.resetFields(); - form.setFieldsValue({ - status: KnowledgeStatusType.DRAFT, - tags: [], - }); - setTitleBeforeReplace(null); - } - setFileList([]); - setReplaceFileList([]); - } else { - setFileList([]); - setReplaceFileList([]); - setTitleBeforeReplace(null); - } - }, [open, data, form]); + setFileList([]); + setReplaceFileList([]); + }, [open, data?.id]); const handleFileBeforeUpload = (file: File) => { - setFileList((prev) => { - const nextList = [ - ...prev, - { - uid: `${Date.now()}-${file.name}`, - name: file.name, - status: "done", - originFileObj: file, - }, - ]; - if (nextList.length === 1) { - const currentTitle = form.getFieldValue("title"); - if (!currentTitle) { - form.setFieldsValue({ - title: stripFileExtension(file.name), - }); - } - } - return nextList; - }); + setFileList((prev) => [ + ...prev, + { + uid: `${Date.now()}-${file.name}`, + name: file.name, + status: "done", + originFileObj: file, + }, + ]); message.success("文件已就绪,可提交创建条目"); return false; }; const handleFileRemove = (removedFile: UploadFile) => { - setFileList((prev) => { - const nextList = prev.filter((file) => file.uid !== removedFile.uid); - if (!data?.id && nextList.length === 0) { - form.setFieldsValue({ title: undefined }); - } - return nextList; - }); + setFileList((prev) => prev.filter((file) => file.uid !== removedFile.uid)); return true; }; const handleReplaceFileBeforeUpload = (file: File) => { - if (!titleBeforeReplace) { - setTitleBeforeReplace(form.getFieldValue("title") || null); - } setReplaceFileList([ { uid: `${Date.now()}-${file.name}`, @@ -159,17 +67,12 @@ export default function KnowledgeItemEditor({ originFileObj: file, }, ]); - form.setFieldsValue({ title: stripFileExtension(file.name) }); message.success("已选择替换文件,提交后生效"); return false; }; const handleReplaceFileRemove = (removedFile: UploadFile) => { setReplaceFileList((prev) => prev.filter((file) => file.uid !== removedFile.uid)); - if (titleBeforeReplace !== null) { - form.setFieldsValue({ title: titleBeforeReplace || undefined }); - setTitleBeforeReplace(null); - } return true; }; @@ -187,47 +90,11 @@ export default function KnowledgeItemEditor({ const handleSubmit = async () => { try { - if (!data?.id && fileList.length === 0) { - message.warning("请先选择文件"); - return; - } - const values = await form.validateFields(); - const validFrom = values.validFrom ? values.validFrom.format("YYYY-MM-DD") : undefined; - const validTo = values.validTo ? values.validTo.format("YYYY-MM-DD") : undefined; - - if (validFrom && validTo && dayjs(validFrom).isAfter(dayjs(validTo))) { - message.warning("有效期开始不能晚于结束时间"); - return; - } - - if (data?.id) { - const payload: Record = { - ...values, - validFrom, - validTo, - tags: values.tags || [], - }; - if (replaceFileList.length > 0) { - delete payload.title; - } - await updateKnowledgeItemByIdUsingPut(setId, data.id, payload); - if (replaceFileList.length > 0) { - const formData = new FormData(); - const replaceFile = replaceFileList[0]?.originFileObj as File | undefined; - if (!replaceFile) { - message.warning("请先选择要替换的文件"); - return; - } - formData.append("file", replaceFile); - await replaceKnowledgeItemFileUsingPut(setId, data.id, formData); - } - message.success("知识条目更新成功"); - } else { + if (isCreateMode) { if (fileList.length === 0) { message.warning("请先选择文件"); return; } - const formData = new FormData(); fileList.forEach((file) => { const origin = file.originFileObj as File | undefined; @@ -235,45 +102,33 @@ export default function KnowledgeItemEditor({ formData.append("files", origin); } }); - if (fileList.length === 1 && values.title) { - formData.append("title", values.title); - } - if (values.status) { - formData.append("status", values.status); - } - if (values.tags && Array.isArray(values.tags)) { - values.tags.forEach((tag) => formData.append("tags", tag)); - } - if (values.domain) { - formData.append("domain", values.domain); - } - if (values.businessLine) { - formData.append("businessLine", values.businessLine); - } - if (values.owner) { - formData.append("owner", values.owner); - } - if (values.sensitivity) { - formData.append("sensitivity", values.sensitivity); - } - if (validFrom) { - formData.append("validFrom", validFrom); - } - if (validTo) { - formData.append("validTo", validTo); - } - if (values.metadata) { - formData.append("metadata", values.metadata); - } - await uploadKnowledgeItemsUsingPost(setId, formData); message.success(`已创建 ${fileList.length} 个知识条目`); + } else { + if (!data?.id) { + return; + } + if (!isFileItem) { + message.info("该条目非文件类型,无需替换文件"); + return; + } + if (replaceFileList.length === 0) { + message.warning("请先选择要替换的文件"); + return; + } + const replaceFile = replaceFileList[0]?.originFileObj as File | undefined; + if (!replaceFile) { + message.warning("请先选择要替换的文件"); + return; + } + const formData = new FormData(); + formData.append("file", replaceFile); + await replaceKnowledgeItemFileUsingPut(setId, data.id, formData); + message.success("知识条目更新成功"); } - form.resetFields(); setFileList([]); setReplaceFileList([]); - setTitleBeforeReplace(null); onSuccess(); } catch { message.error("操作失败,请重试"); @@ -294,7 +149,7 @@ export default function KnowledgeItemEditor({ maskClosable={false} okButtonProps={{ disabled: readOnly }} > -
+ {isCreateMode && ( )} - {!isCreateMode && ( - <> -
- - - - - - - - - -
-
- - - - - - -
-
- - - - -