feat(KnowledgeBase): 优化知识库文件上传功能

- 添加提交状态控制,防止重复提交
- 将分块选项中的"按章节分块"改为"按句子分块"
- 更新固定长度分块的选项值从FIXED_LENGTH_CHUNK到LENGTH_CHUNK
- 简化文件计数逻辑,直接统计选中文件数量
- 添加上传进度提示消息
- 重构文件数据结构,确保ID为字符串类型
- 添加按钮禁用状态控制,提升用户体验
- 优化消息提示的显示方式,支持更新现有消息
This commit is contained in:
2026-01-30 14:29:45 +08:00
parent 1fd70085e8
commit 98d2ef1aa5

View File

@@ -21,15 +21,16 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
const { message } = App.useApp(); const { message } = App.useApp();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [currentStep, setCurrentStep] = useState(0); const [currentStep, setCurrentStep] = useState(0);
const [isSubmitting, setIsSubmitting] = useState(false);
const [selectedFilesMap, setSelectedFilesMap] = useState({}); const [selectedFilesMap, setSelectedFilesMap] = useState({});
// 定义分块选项 // 定义分块选项
const sliceOptions = [ const sliceOptions = [
{ label: "默认分块", value: "DEFAULT_CHUNK" }, { label: "默认分块", value: "DEFAULT_CHUNK" },
{ label: "按章节分块", value: "CHAPTER_CHUNK" }, { label: "按句子分块", value: "SENTENCE_CHUNK" },
{ label: "按段落分块", value: "PARAGRAPH_CHUNK" }, { label: "按段落分块", value: "PARAGRAPH_CHUNK" },
{ label: "固定长度分块", value: "FIXED_LENGTH_CHUNK" }, { label: "固定长度分块", value: "LENGTH_CHUNK" },
{ label: "自定义分隔符分块", value: "CUSTOM_SEPARATOR_CHUNK" }, { label: "自定义分隔符分块", value: "CUSTOM_SEPARATOR_CHUNK" },
]; ];
@@ -57,12 +58,7 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
]; ];
// 获取已选择文件总数 // 获取已选择文件总数
const getSelectedFilesCount = () => { const getSelectedFilesCount = () => Object.keys(selectedFilesMap).length;
return Object.values(selectedFilesMap).reduce(
(total, ids) => total + ids.length,
0
);
};
const handleNext = () => { const handleNext = () => {
// 验证当前步骤 // 验证当前步骤
@@ -112,15 +108,29 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
}; };
const handleAddData = async () => { const handleAddData = async () => {
if (isSubmitting) {
return;
}
if (getSelectedFilesCount() === 0) { if (getSelectedFilesCount() === 0) {
message.warning("请至少选择一个文件"); message.warning("请至少选择一个文件");
return; return;
} }
try { try {
setIsSubmitting(true);
const uploadMessageKey = "kb-add-files";
message.open({
type: "loading",
content: "正在上传,请稍候...",
key: uploadMessageKey,
duration: 0,
});
// 构造符合API要求的请求数据 // 构造符合API要求的请求数据
const requestData = { const requestData = {
files: Object.values(selectedFilesMap), files: Object.values(selectedFilesMap).map((file) => ({
id: String(file.id),
fileName: file.fileName,
})),
processType: newKB.processType, processType: newKB.processType,
chunkSize: Number(newKB.chunkSize), // 确保是数字类型 chunkSize: Number(newKB.chunkSize), // 确保是数字类型
overlapSize: Number(newKB.overlapSize), // 确保是数字类型 overlapSize: Number(newKB.overlapSize), // 确保是数字类型
@@ -132,12 +142,20 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
// 先通知父组件刷新数据(确保刷新发生在重置前) // 先通知父组件刷新数据(确保刷新发生在重置前)
onDataAdded?.(); onDataAdded?.();
message.success("数据添加成功"); message.success({
content: "数据添加成功",
key: uploadMessageKey,
});
// 重置状态 // 重置状态
setOpen(false); setOpen(false);
} catch (error) { } catch (error) {
message.error("数据添加失败,请重试"); message.error({
content: "数据添加失败,请重试",
key: "kb-add-files",
});
console.error("添加文件失败:", error); console.error("添加文件失败:", error);
} finally {
setIsSubmitting(false);
} }
}; };
@@ -221,10 +239,12 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
footer={ footer={
<div className="space-x-2"> <div className="space-x-2">
{currentStep === 0 && ( {currentStep === 0 && (
<Button onClick={handleModalCancel}></Button> <Button onClick={handleModalCancel} disabled={isSubmitting}>
</Button>
)} )}
{currentStep > 0 && ( {currentStep > 0 && (
<Button disabled={false} onClick={handlePrev}> <Button disabled={isSubmitting} onClick={handlePrev}>
</Button> </Button>
)} )}
@@ -235,14 +255,20 @@ export default function AddDataDialog({ knowledgeBase, onDataAdded }) {
Object.keys(selectedFilesMap).length === 0 || Object.keys(selectedFilesMap).length === 0 ||
!newKB.chunkSize || !newKB.chunkSize ||
!newKB.overlapSize || !newKB.overlapSize ||
!newKB.processType !newKB.processType ||
isSubmitting
} }
onClick={handleNext} onClick={handleNext}
> >
</Button> </Button>
) : ( ) : (
<Button type="primary" onClick={handleAddData}> <Button
type="primary"
onClick={handleAddData}
loading={isSubmitting}
disabled={isSubmitting}
>
</Button> </Button>
)} )}