Merge pull request #1053 from SuanmoSuanyangTechnology/feature/knowledgeBase_zy

feat(web): add csv template
This commit is contained in:
yingzhao
2026-05-07 19:12:06 +08:00
committed by GitHub
4 changed files with 111 additions and 98 deletions

View File

@@ -0,0 +1 @@
Q A
1 Q A

View File

@@ -951,7 +951,8 @@ export const en = {
feishuFolderToken: 'Folder Token', feishuFolderToken: 'Folder Token',
feishuFolderTokenRequired: 'Please enter Folder Token', feishuFolderTokenRequired: 'Please enter Folder Token',
feishuFolderTokenPlaceholder: 'Enter your Feishu Folder Token', feishuFolderTokenPlaceholder: 'Enter your Feishu Folder Token',
} },
csvTemplate: 'Click to download CSV template',
}, },
api: { api: {
pageTitle: 'Memory library IAP document', pageTitle: 'Memory library IAP document',

View File

@@ -438,7 +438,8 @@ export const zh = {
feishuFolderToken: '文件夹 Token', feishuFolderToken: '文件夹 Token',
feishuFolderTokenRequired: '请输入文件夹 Token', feishuFolderTokenRequired: '请输入文件夹 Token',
feishuFolderTokenPlaceholder: '请输入您的飞书文件夹 Token', feishuFolderTokenPlaceholder: '请输入您的飞书文件夹 Token',
} },
csvTemplate: '点击下载 CSV 模板',
}, },
application: { application: {
searchPlaceholder: '搜索应用', searchPlaceholder: '搜索应用',

View File

@@ -596,111 +596,121 @@ const CreateDataset = () => {
</div> } </div> }
<div className='rb:bg-white rb:rounded-xl rb:flex-1 rb:mt-3'> <div className='rb:bg-white rb:rounded-xl rb:flex-1 rb:mt-3'>
{current === 0 && ( {current === 0 && (<>
<div className='rb:flex rb:w-full rb:p-6'> <div className='rb:flex rb:w-full rb:p-6'>
{source && (source === 'local' || source === 'csv') && ( {source && (source === 'local' || source === 'csv') && (
<UploadFiles <UploadFiles
ref={uploadRef} ref={uploadRef}
isCanDrag={true} isCanDrag={true}
fileSize={100} fileSize={100}
multiple={source !== 'csv'} multiple={source !== 'csv'}
maxCount={source === 'csv' ? 1 : 99} maxCount={source === 'csv' ? 1 : 99}
fileType={source === 'csv' ? csvFileType : fileType} fileType={source === 'csv' ? csvFileType : fileType}
customRequest={handleUpload} customRequest={handleUpload}
onChange={(fileList) => { onChange={(fileList) => {
console.log('File list changed:', fileList); console.log('File list changed:', fileList);
}} }}
onRemove={async (file) => { onRemove={async (file) => {
// 如果文件正在上传,取消上传 // 如果文件正在上传,取消上传
const fileUid = file.uid; const fileUid = file.uid;
const abortController = abortControllersRef.current.get(fileUid); const abortController = abortControllersRef.current.get(fileUid);
if (abortController) { if (abortController) {
abortController.abort(); abortController.abort();
abortControllersRef.current.delete(fileUid); abortControllersRef.current.delete(fileUid);
console.log('Upload cancelled:', (file as any).name); console.log('Upload cancelled:', (file as any).name);
// 取消上传后直接返回 true允许移除文件 // 取消上传后直接返回 true允许移除文件
return true; return true;
} }
// Only delete server file when file upload was successful (has response.id) // Only delete server file when file upload was successful (has response.id)
if (file.response?.id) { if (file.response?.id) {
try { try {
await deleteDocument(file.response.id); await deleteDocument(file.response.id);
setRechunkFileIds(prev => prev.filter(id => id !== file.response.id)); setRechunkFileIds(prev => prev.filter(id => id !== file.response.id));
console.log('Server file deleted:', file.response.id); console.log('Server file deleted:', file.response.id);
return true; return true;
} catch (error) { } catch (error) {
console.error('Failed to delete file:', error); console.error('Failed to delete file:', error);
messageApi.error(t('common.deleteFailed') || 'Failed to delete file'); messageApi.error(t('common.deleteFailed') || 'Failed to delete file');
return false; // Don't remove file when deletion fails return false; // Don't remove file when deletion fails
} }
} }
// Also allow removal in other cases (such as failed uploads) // Also allow removal in other cases (such as failed uploads)
return true; return true;
}} /> }}
)} />
{source && source === 'link' && ( )}
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'> {source && source === 'link' && (
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-40'>
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'> <div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
{t('knowledgeBase.webLink')} {t('knowledgeBase.webLink')}
</div>
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} />
<div className='rb:text-sm rb:text-gray-500 rb:mt-3'>
{t('knowledgeBase.webLinkDesc',{count: 5})}
</div>
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
{t('knowledgeBase.selectorTutorial')}
</div>
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
</div> </div>
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} />
<div className='rb:text-sm rb:text-gray-500 rb:mt-3'>
{t('knowledgeBase.webLinkDesc',{count: 5})}
</div>
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
{t('knowledgeBase.selectorTutorial')}
</div>
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
</div>
)} )}
{source && source === 'text' && ( {source && source === 'text' && (
<div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-20'> <div className='rb:flex rb:w-full rb:flex-col rb:mt-10 rb:px-20'>
<Form <Form
form={form} form={form}
layout="vertical" layout="vertical"
onValuesChange={() => { onValuesChange={() => {
// 检查表单字段是否都已填写 // 检查表单字段是否都已填写
const values = form.getFieldsValue(); const values = form.getFieldsValue();
const isValid = !!(values.title?.trim() && values.content?.trim()); const isValid = !!(values.title?.trim() && values.content?.trim());
setTextFormValid(isValid); setTextFormValid(isValid);
}} }}
>
<Form.Item
name="title"
label={t('knowledgeBase.title')}
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterTitle') }]}
> >
<Form.Item <Input placeholder={t('knowledgeBase.pleaseEnterTitle')} />
name="title" </Form.Item>
label={t('knowledgeBase.title')}
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterTitle') }]}
>
<Input placeholder={t('knowledgeBase.pleaseEnterTitle')} />
</Form.Item>
<Form.Item <Form.Item
name="content" name="content"
label={t('knowledgeBase.customContent')} label={t('knowledgeBase.customContent')}
rules={[{ required: true, message: t('knowledgeBase.pleaseEnterContent') }]} rules={[{ required: true, message: t('knowledgeBase.pleaseEnterContent') }]}
> >
<Input.TextArea <Input.TextArea
placeholder={t('knowledgeBase.pleaseEnterContent')} placeholder={t('knowledgeBase.pleaseEnterContent')}
rows={8} rows={8}
showCount showCount
maxLength={5000} maxLength={5000}
/> />
</Form.Item> </Form.Item>
</Form> </Form>
{/* <div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'> {/* <div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mb-3'>
{t('knowledgeBase.customText')} {t('knowledgeBase.customText')}
</div>
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
{t('knowledgeBase.customContent')}
</div>
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} /> */}
</div> </div>
<Input className='rb:w-full' placeholder={t('knowledgeBase.webLinkPlaceholder')}/>
<div className='rb:text-sm rb:font-medium rb:text-gray-800 rb:mt-10 rb:mb-3'>
{t('knowledgeBase.customContent')}
</div>
<TextArea rows={6} placeholder={t('knowledgeBase.webLinkPlaceholder')} /> */}
</div>
)} )}
</div> </div>
)} {source === 'csv' &&
<a
href="@/assets/csv_template.csv"
download="csv_template.csv"
className='rb:mx-6 rb:text-sm rb:font-medium rb:text-gray-800 rb:-mt-6!'
>
{t('knowledgeBase.csvTemplate')}
</a>
}
</>)}
{current === 1 && ( {current === 1 && (
<div className='rb:flex rb:flex-col rb:mt-10 rb:px-40'> <div className='rb:flex rb:flex-col rb:mt-10 rb:px-40'>