feat(knowledgeBase): enhance dataset creation with progress tracking and model defaults

- Add Progress component import to display file upload progress in real-time
- Implement progress bar rendering for files with 0-1 progress values (processing state)
- Refactor progress column logic to handle three states: completed (1), processing (0-1), and pending (0)
- Add automatic default model selection for each type when creating new knowledge base
- Improve file removal handling with better error messages and conditional server deletion
- Add console logging for upload cancellation and file deletion operations
- Remove loading state from primary button to prevent UI conflicts
- Comment out Spin wrapper on step 2 to allow better progress visibility
- Update Chinese translation for total_running_apps label for clarity
- Enhance error handling with i18n support for deletion failures
This commit is contained in:
yujiangping
2026-01-22 16:39:27 +08:00
parent 2b017139ef
commit acecdcc041
3 changed files with 62 additions and 16 deletions

View File

@@ -716,7 +716,7 @@ export const zh = {
total_models: '可用模型总数',
total_spaces: '活跃空间数量',
total_users: '用户总数',
total_running_apps: '应用运行次数',
total_running_apps: '正在运行的应用',
desc_models: '包含 {{ account }} 个大语言模型和 {{ nums }} 个嵌入模型',
desc_spaces: '多于上周',
desc_users: '本周新增',

View File

@@ -1,5 +1,5 @@
import { useMemo,useRef, useState, useEffect } from 'react';
import { Button, Flex, Radio, Steps, Modal, Input, Spin, message, Checkbox, Select, Form} from 'antd';
import { Button, Flex, Radio, Steps, Modal, Input, Spin, message, Checkbox, Select, Form, Progress} from 'antd';
import { useTranslation } from 'react-i18next';
import { useLocation, useNavigate, useParams } from 'react-router-dom';
import Table, { type TableRef } from '@/components/Table'
@@ -261,12 +261,36 @@ const CreateDataset = () => {
dataIndex: 'progress',
key: 'progress',
render: (value: number, record: any) => {
return (
<span className="rb:text-xs rb:border rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded rb:items-center rb:text-[#212332] rb:py-1 rb:px-2">
<span className="rb:inline-block rb:w-[5px] rb:h-[5px] rb:mr-2 rb:rounded-full" style={{ backgroundColor: value === 1 ? '#369F21' : '#FF8A4C' }}></span>
<span>{value === 1 ? t('knowledgeBase.completed') : value === 0 ? t('knowledgeBase.pending') : t('knowledgeBase.processing')}</span>
</span>
);
// value = 1 时完成01 时显示进度条
if (value === 1) {
return (
<span className="rb:text-xs rb:border rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded rb:items-center rb:text-[#212332] rb:py-1 rb:px-2">
<span className="rb:inline-block rb:w-[5px] rb:h-[5px] rb:mr-2 rb:rounded-full" style={{ backgroundColor: '#369F21' }}></span>
<span>{t('knowledgeBase.completed')}</span>
</span>
);
} else if (value > 0 && value < 1) {
// 处理中,显示进度条
return (
<div className="rb:flex rb:items-center rb:gap-2">
<Progress
percent={Math.round(value * 100)}
size="small"
status="active"
strokeColor="#1677ff"
style={{ width: '120px' }}
/>
</div>
);
} else {
// value = 0 或其他情况,显示待处理
return (
<span className="rb:text-xs rb:border rb:border-[#DFE4ED] rb:bg-[#FBFDFF] rb:rounded rb:items-center rb:text-[#212332] rb:py-1 rb:px-2">
<span className="rb:inline-block rb:w-[5px] rb:h-[5px] rb:mr-2 rb:rounded-full" style={{ backgroundColor: '#FF8A4C' }}></span>
<span>{t('knowledgeBase.pending')}</span>
</span>
);
}
}
},
{
@@ -553,21 +577,24 @@ const CreateDataset = () => {
if (abortController) {
abortController.abort();
abortControllersRef.current.delete(fileUid);
console.log('已取消上传:', (file as any).name);
}
console.log('文件移除前:', uploadRef.current?.fileList);
// 如果文件已经上传成功删除服务器上的文件并从rechunkFileIds中移除对应的ID
// 只有当文件已经上传成功有response.id才删除服务器上的文件
if (file.response?.id) {
try {
await deleteDocument(file.response.id);
setRechunkFileIds(prev => prev.filter(id => id !== file.response.id));
console.log('已删除服务器文件:', file.response.id);
} catch (error) {
console.error('删除文件失败:', error);
messageApi.error('删除文件失败');
messageApi.error(t('common.deleteFailed') || '删除文件失败');
return false; // 删除失败时不移除文件
}
}
return true; // 允许移除文件
// 允许移除文件(无论是取消上传还是删除成功)
return true;
}} />
)}
{source && source === 'link' && (
@@ -776,7 +803,7 @@ const CreateDataset = () => {
)} */}
{current === 2 && (
<Spin spinning={pollingLoading} tip={t('knowledgeBase.processingDocuments') || '正在处理文档...'}>
// <Spin spinning={pollingLoading} tip={t('knowledgeBase.processingDocuments') || '正在处理文档...'}>
<div className='rb:text-sm rb:text-gray-500 rb:mt-4 rb:h-[calc(100%-160px)] rb:overflow-y-auto'>
{rechunkFileIds.length > 0 ? (
<Table
@@ -797,7 +824,7 @@ const CreateDataset = () => {
/>
)}
</div>
</Spin>
// </Spin>
)}
<div className={`rb:flex rb:gap-3 rb:mt-6 ${current === 1 || (source == 'link' && current === 0) || (source == 'text' && current === 0) ? 'rb:pl-40 rb:mt-10' : ''}`}>
@@ -810,7 +837,6 @@ const CreateDataset = () => {
type='primary'
onClick={current === 2 ? handleStartUpload : handleNext}
disabled={pollingLoading || (current === 0 && rechunkFileIds.length === 0)}
loading={pollingLoading}
>
{current === 2 ? t('knowledgeBase.startUploading') || 'Start Upload' : t('common.next') || 'Next'}
</Button>

View File

@@ -164,6 +164,26 @@ const CreateModal = forwardRef<CreateModalRef, CreateModalRefProps>(({
});
setModelOptionsByType(next);
// 如果不是编辑模式,为每个类型的下拉框设置默认值为第一条数据
if (!datasets?.id) {
const defaultValues: Record<string, string> = {};
types.forEach((tp) => {
const fieldKey = typeToFieldKey(tp);
const options = tp.toLowerCase() === 'llm'
? [...(next['llm'] || []), ...(next['chat'] || [])]
: next[tp] || [];
// 如果有选项且当前字段没有值,设置第一个选项为默认值
if (options.length > 0 && !form.getFieldValue(fieldKey)) {
defaultValues[fieldKey] = options[0].value;
}
});
if (Object.keys(defaultValues).length > 0) {
form.setFieldsValue(defaultValues as Partial<KnowledgeBaseFormData>);
}
}
};
const setBaseFields = (record: KnowledgeBaseListItem | null, type?: string) => {