mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-06-04 11:24:00 +08:00
### What problem does this PR solve? feat: upload file in FileManager #345 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
b06d6395bb
commit
51e7697df7
@ -1,4 +1,8 @@
|
|||||||
import { IFileListRequestBody } from '@/interfaces/request/file-manager';
|
import {
|
||||||
|
IConnectRequestBody,
|
||||||
|
IFileListRequestBody,
|
||||||
|
} from '@/interfaces/request/file-manager';
|
||||||
|
import { UploadFile } from 'antd';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useDispatch, useSelector } from 'umi';
|
import { useDispatch, useSelector } from 'umi';
|
||||||
|
|
||||||
@ -94,3 +98,47 @@ export const useSelectParentFolderList = () => {
|
|||||||
);
|
);
|
||||||
return parentFolderList.toReversed();
|
return parentFolderList.toReversed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useUploadFile = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const uploadFile = useCallback(
|
||||||
|
(file: UploadFile, parentId: string, path: string) => {
|
||||||
|
try {
|
||||||
|
return dispatch<any>({
|
||||||
|
type: 'fileManager/uploadFile',
|
||||||
|
payload: {
|
||||||
|
file,
|
||||||
|
parentId,
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (errorInfo) {
|
||||||
|
console.log('Failed:', errorInfo);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return uploadFile;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useConnectToKnowledge = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const uploadFile = useCallback(
|
||||||
|
(payload: IConnectRequestBody) => {
|
||||||
|
try {
|
||||||
|
return dispatch<any>({
|
||||||
|
type: 'fileManager/connectFileToKnowledge',
|
||||||
|
payload,
|
||||||
|
});
|
||||||
|
} catch (errorInfo) {
|
||||||
|
console.log('Failed:', errorInfo);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch],
|
||||||
|
);
|
||||||
|
|
||||||
|
return uploadFile;
|
||||||
|
};
|
||||||
|
@ -3,7 +3,7 @@ export interface IFile {
|
|||||||
create_time: number;
|
create_time: number;
|
||||||
created_by: string;
|
created_by: string;
|
||||||
id: string;
|
id: string;
|
||||||
kb_ids: string[];
|
kbs_info: { kb_id: string; kb_name: string }[];
|
||||||
location: string;
|
location: string;
|
||||||
name: string;
|
name: string;
|
||||||
parent_id: string;
|
parent_id: string;
|
||||||
|
@ -3,3 +3,12 @@ import { IPaginationRequestBody } from './base';
|
|||||||
export interface IFileListRequestBody extends IPaginationRequestBody {
|
export interface IFileListRequestBody extends IPaginationRequestBody {
|
||||||
parent_id?: string; // folder id
|
parent_id?: string; // folder id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface BaseRequestBody {
|
||||||
|
parentId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IConnectRequestBody extends BaseRequestBody {
|
||||||
|
fileIds: string[];
|
||||||
|
kbIds: string[];
|
||||||
|
}
|
||||||
|
@ -382,7 +382,7 @@ export default {
|
|||||||
passwordDescription:
|
passwordDescription:
|
||||||
'Please enter your current password to change your password.',
|
'Please enter your current password to change your password.',
|
||||||
model: 'Model Providers',
|
model: 'Model Providers',
|
||||||
modelDescription: 'Manage your account settings and preferences here.',
|
modelDescription: 'Set the model parameter and API Key here.',
|
||||||
team: 'Team',
|
team: 'Team',
|
||||||
logout: 'Log out',
|
logout: 'Log out',
|
||||||
username: 'Username',
|
username: 'Username',
|
||||||
|
@ -352,7 +352,7 @@ export default {
|
|||||||
password: '密碼',
|
password: '密碼',
|
||||||
passwordDescription: '請輸入您當前的密碼以更改您的密碼。',
|
passwordDescription: '請輸入您當前的密碼以更改您的密碼。',
|
||||||
model: '模型提供商',
|
model: '模型提供商',
|
||||||
modelDescription: '在此管理您的帳戶設置和首選項。',
|
modelDescription: '在此設置模型參數和 API Key。',
|
||||||
team: '團隊',
|
team: '團隊',
|
||||||
logout: '登出',
|
logout: '登出',
|
||||||
username: '使用者名稱',
|
username: '使用者名稱',
|
||||||
|
@ -369,7 +369,7 @@ export default {
|
|||||||
password: '密码',
|
password: '密码',
|
||||||
passwordDescription: '请输入您当前的密码以更改您的密码。',
|
passwordDescription: '请输入您当前的密码以更改您的密码。',
|
||||||
model: '模型提供商',
|
model: '模型提供商',
|
||||||
modelDescription: '在此管理您的帐户设置和首选项。',
|
modelDescription: '在此设置模型参数和 API Key。',
|
||||||
team: '团队',
|
team: '团队',
|
||||||
logout: '登出',
|
logout: '登出',
|
||||||
username: '用户名',
|
username: '用户名',
|
||||||
|
@ -17,9 +17,15 @@ interface IProps {
|
|||||||
record: IFile;
|
record: IFile;
|
||||||
setCurrentRecord: (record: any) => void;
|
setCurrentRecord: (record: any) => void;
|
||||||
showRenameModal: (record: IFile) => void;
|
showRenameModal: (record: IFile) => void;
|
||||||
|
showConnectToKnowledgeModal: (ids: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => {
|
const ActionCell = ({
|
||||||
|
record,
|
||||||
|
setCurrentRecord,
|
||||||
|
showRenameModal,
|
||||||
|
showConnectToKnowledgeModal,
|
||||||
|
}: IProps) => {
|
||||||
const documentId = record.id;
|
const documentId = record.id;
|
||||||
const beingUsed = false;
|
const beingUsed = false;
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
@ -41,9 +47,17 @@ const ActionCell = ({ record, setCurrentRecord, showRenameModal }: IProps) => {
|
|||||||
showRenameModal(record);
|
showRenameModal(record);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onShowConnectToKnowledgeModal = () => {
|
||||||
|
showConnectToKnowledgeModal([documentId]);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Space size={0}>
|
<Space size={0}>
|
||||||
<Button type="text" className={styles.iconButton}>
|
<Button
|
||||||
|
type="text"
|
||||||
|
className={styles.iconButton}
|
||||||
|
onClick={onShowConnectToKnowledgeModal}
|
||||||
|
>
|
||||||
<ToolOutlined size={20} />
|
<ToolOutlined size={20} />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
import { useFetchKnowledgeList } from '@/hooks/knowledgeHook';
|
||||||
|
import { IModalProps } from '@/interfaces/common';
|
||||||
|
import { Form, Modal, Select, SelectProps } from 'antd';
|
||||||
|
|
||||||
|
const ConnectToKnowledgeModal = ({
|
||||||
|
visible,
|
||||||
|
hideModal,
|
||||||
|
onOk,
|
||||||
|
}: IModalProps<string[]>) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const { list } = useFetchKnowledgeList();
|
||||||
|
|
||||||
|
const options: SelectProps['options'] = list?.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const handleOk = async () => {
|
||||||
|
const values = await form.getFieldsValue();
|
||||||
|
const knowledgeIds = values.knowledgeIds ?? [];
|
||||||
|
if (knowledgeIds.length > 0) {
|
||||||
|
return onOk?.(knowledgeIds);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title="Add to Knowledge Base"
|
||||||
|
open={visible}
|
||||||
|
onOk={handleOk}
|
||||||
|
onCancel={hideModal}
|
||||||
|
>
|
||||||
|
<Form form={form}>
|
||||||
|
<Form.Item
|
||||||
|
name="knowledgeIds"
|
||||||
|
noStyle
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: 'Please select your favourite colors!',
|
||||||
|
type: 'array',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Select
|
||||||
|
mode="multiple"
|
||||||
|
allowClear
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
placeholder="Please select"
|
||||||
|
options={options}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ConnectToKnowledgeModal;
|
@ -32,6 +32,7 @@ import styles from './index.less';
|
|||||||
interface IProps {
|
interface IProps {
|
||||||
selectedRowKeys: string[];
|
selectedRowKeys: string[];
|
||||||
showFolderCreateModal: () => void;
|
showFolderCreateModal: () => void;
|
||||||
|
showFileUploadModal: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemRender: BreadcrumbProps['itemRender'] = (
|
const itemRender: BreadcrumbProps['itemRender'] = (
|
||||||
@ -48,7 +49,11 @@ const itemRender: BreadcrumbProps['itemRender'] = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const FileToolbar = ({ selectedRowKeys, showFolderCreateModal }: IProps) => {
|
const FileToolbar = ({
|
||||||
|
selectedRowKeys,
|
||||||
|
showFolderCreateModal,
|
||||||
|
showFileUploadModal,
|
||||||
|
}: IProps) => {
|
||||||
const { t } = useTranslate('knowledgeDetails');
|
const { t } = useTranslate('knowledgeDetails');
|
||||||
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
const { fetchDocumentList } = useFetchDocumentListOnMount();
|
||||||
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
|
const { setPagination, searchString } = useGetPagination(fetchDocumentList);
|
||||||
@ -59,6 +64,7 @@ const FileToolbar = ({ selectedRowKeys, showFolderCreateModal }: IProps) => {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
key: '1',
|
key: '1',
|
||||||
|
onClick: showFileUploadModal,
|
||||||
label: (
|
label: (
|
||||||
<div>
|
<div>
|
||||||
<Button type="link">
|
<Button type="link">
|
||||||
@ -85,7 +91,7 @@ const FileToolbar = ({ selectedRowKeys, showFolderCreateModal }: IProps) => {
|
|||||||
// disabled: true,
|
// disabled: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [t, showFolderCreateModal]);
|
}, [t, showFolderCreateModal, showFileUploadModal]);
|
||||||
|
|
||||||
const { handleRemoveFile } = useHandleDeleteFile(selectedRowKeys);
|
const { handleRemoveFile } = useHandleDeleteFile(selectedRowKeys);
|
||||||
|
|
||||||
|
@ -1,61 +1,124 @@
|
|||||||
|
import { IModalProps } from '@/interfaces/common';
|
||||||
import { InboxOutlined } from '@ant-design/icons';
|
import { InboxOutlined } from '@ant-design/icons';
|
||||||
import { Modal, Segmented, Upload, UploadProps, message } from 'antd';
|
import {
|
||||||
import { useState } from 'react';
|
Flex,
|
||||||
|
Modal,
|
||||||
|
Segmented,
|
||||||
|
Tabs,
|
||||||
|
TabsProps,
|
||||||
|
Upload,
|
||||||
|
UploadFile,
|
||||||
|
UploadProps,
|
||||||
|
} from 'antd';
|
||||||
|
import { Dispatch, SetStateAction, useState } from 'react';
|
||||||
|
import { useHandleUploadFile } from '../hooks';
|
||||||
|
|
||||||
const { Dragger } = Upload;
|
const { Dragger } = Upload;
|
||||||
|
|
||||||
const FileUploadModal = () => {
|
const FileUpload = ({
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
directory,
|
||||||
|
fileList,
|
||||||
|
setFileList,
|
||||||
|
}: {
|
||||||
|
directory: boolean;
|
||||||
|
fileList: UploadFile[];
|
||||||
|
setFileList: Dispatch<SetStateAction<UploadFile[]>>;
|
||||||
|
}) => {
|
||||||
const props: UploadProps = {
|
const props: UploadProps = {
|
||||||
name: 'file',
|
|
||||||
multiple: true,
|
multiple: true,
|
||||||
action: 'https://660d2bd96ddfa2943b33731c.mockapi.io/api/upload',
|
onRemove: (file) => {
|
||||||
onChange(info) {
|
const index = fileList.indexOf(file);
|
||||||
const { status } = info.file;
|
const newFileList = fileList.slice();
|
||||||
if (status !== 'uploading') {
|
newFileList.splice(index, 1);
|
||||||
console.log(info.file, info.fileList);
|
setFileList(newFileList);
|
||||||
}
|
|
||||||
if (status === 'done') {
|
|
||||||
message.success(`${info.file.name} file uploaded successfully.`);
|
|
||||||
} else if (status === 'error') {
|
|
||||||
message.error(`${info.file.name} file upload failed.`);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
onDrop(e) {
|
beforeUpload: (file) => {
|
||||||
console.log('Dropped files', e.dataTransfer.files);
|
setFileList((pre) => {
|
||||||
|
return [...pre, file];
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
|
directory,
|
||||||
|
fileList,
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
return (
|
||||||
setIsModalOpen(false);
|
<Dragger {...props}>
|
||||||
|
<p className="ant-upload-drag-icon">
|
||||||
|
<InboxOutlined />
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-text">
|
||||||
|
Click or drag file to this area to upload
|
||||||
|
</p>
|
||||||
|
<p className="ant-upload-hint">
|
||||||
|
Support for a single or bulk upload. Strictly prohibited from uploading
|
||||||
|
company data or other banned files.
|
||||||
|
</p>
|
||||||
|
</Dragger>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const FileUploadModal = ({ visible, hideModal }: IModalProps<any>) => {
|
||||||
|
const [value, setValue] = useState<string | number>('local');
|
||||||
|
const { onFileUploadOk, fileUploadLoading } = useHandleUploadFile();
|
||||||
|
const [fileList, setFileList] = useState<UploadFile[]>([]);
|
||||||
|
const [directoryFileList, setDirectoryFileList] = useState<UploadFile[]>([]);
|
||||||
|
|
||||||
|
const onOk = () => {
|
||||||
|
onFileUploadOk([...fileList, ...directoryFileList]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCancel = () => {
|
const items: TabsProps['items'] = [
|
||||||
setIsModalOpen(false);
|
{
|
||||||
};
|
key: '1',
|
||||||
|
label: 'File',
|
||||||
|
children: (
|
||||||
|
<FileUpload
|
||||||
|
directory={false}
|
||||||
|
fileList={fileList}
|
||||||
|
setFileList={setFileList}
|
||||||
|
></FileUpload>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '2',
|
||||||
|
label: 'Directory',
|
||||||
|
children: (
|
||||||
|
<FileUpload
|
||||||
|
directory
|
||||||
|
fileList={directoryFileList}
|
||||||
|
setFileList={setDirectoryFileList}
|
||||||
|
></FileUpload>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Modal
|
<Modal
|
||||||
title="File upload"
|
title="File upload"
|
||||||
open={isModalOpen}
|
open={visible}
|
||||||
onOk={handleOk}
|
onOk={onOk}
|
||||||
onCancel={handleCancel}
|
onCancel={hideModal}
|
||||||
|
confirmLoading={fileUploadLoading}
|
||||||
>
|
>
|
||||||
<Segmented options={['Local uploads', 'S3 uploads']} block />
|
<Flex gap={'large'} vertical>
|
||||||
<Dragger {...props}>
|
<Segmented
|
||||||
<p className="ant-upload-drag-icon">
|
options={[
|
||||||
<InboxOutlined />
|
{ label: 'Local uploads', value: 'local' },
|
||||||
</p>
|
{ label: 'S3 uploads', value: 's3' },
|
||||||
<p className="ant-upload-text">
|
]}
|
||||||
Click or drag file to this area to upload
|
block
|
||||||
</p>
|
value={value}
|
||||||
<p className="ant-upload-hint">
|
onChange={setValue}
|
||||||
Support for a single or bulk upload. Strictly prohibited from
|
/>
|
||||||
uploading company data or other banned files.
|
{value === 'local' ? (
|
||||||
</p>
|
<Tabs defaultActiveKey="1" items={items} />
|
||||||
</Dragger>
|
) : (
|
||||||
|
'coming soon'
|
||||||
|
)}
|
||||||
|
</Flex>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
useTranslate,
|
useTranslate,
|
||||||
} from '@/hooks/commonHooks';
|
} from '@/hooks/commonHooks';
|
||||||
import {
|
import {
|
||||||
|
useConnectToKnowledge,
|
||||||
useCreateFolder,
|
useCreateFolder,
|
||||||
useFetchFileList,
|
useFetchFileList,
|
||||||
useFetchParentFolderList,
|
useFetchParentFolderList,
|
||||||
@ -11,11 +12,14 @@ import {
|
|||||||
useRenameFile,
|
useRenameFile,
|
||||||
useSelectFileList,
|
useSelectFileList,
|
||||||
useSelectParentFolderList,
|
useSelectParentFolderList,
|
||||||
|
useUploadFile,
|
||||||
} from '@/hooks/fileManagerHooks';
|
} from '@/hooks/fileManagerHooks';
|
||||||
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks';
|
||||||
import { Pagination } from '@/interfaces/common';
|
import { Pagination } from '@/interfaces/common';
|
||||||
import { IFile } from '@/interfaces/database/file-manager';
|
import { IFile } from '@/interfaces/database/file-manager';
|
||||||
|
import { getFilePathByWebkitRelativePath } from '@/utils/fileUtil';
|
||||||
import { PaginationProps } from 'antd';
|
import { PaginationProps } from 'antd';
|
||||||
|
import { UploadFile } from 'antd/lib';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
import { useDispatch, useNavigate, useSearchParams, useSelector } from 'umi';
|
import { useDispatch, useNavigate, useSearchParams, useSelector } from 'umi';
|
||||||
|
|
||||||
@ -250,3 +254,87 @@ export const useHandleDeleteFile = (fileIds: string[]) => {
|
|||||||
export const useSelectFileListLoading = () => {
|
export const useSelectFileListLoading = () => {
|
||||||
return useOneNamespaceEffectsLoading('fileManager', ['listFile']);
|
return useOneNamespaceEffectsLoading('fileManager', ['listFile']);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useHandleUploadFile = () => {
|
||||||
|
const {
|
||||||
|
visible: fileUploadVisible,
|
||||||
|
hideModal: hideFileUploadModal,
|
||||||
|
showModal: showFileUploadModal,
|
||||||
|
} = useSetModalState();
|
||||||
|
const uploadFile = useUploadFile();
|
||||||
|
const id = useGetFolderId();
|
||||||
|
|
||||||
|
const onFileUploadOk = useCallback(
|
||||||
|
async (fileList: UploadFile[]) => {
|
||||||
|
console.info('fileList', fileList);
|
||||||
|
if (fileList.length > 0) {
|
||||||
|
const ret = await uploadFile(
|
||||||
|
fileList[0],
|
||||||
|
id,
|
||||||
|
getFilePathByWebkitRelativePath(fileList[0] as any),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ret === 0) {
|
||||||
|
hideFileUploadModal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[uploadFile, hideFileUploadModal, id],
|
||||||
|
);
|
||||||
|
|
||||||
|
const loading = useOneNamespaceEffectsLoading('fileManager', ['uploadFile']);
|
||||||
|
|
||||||
|
return {
|
||||||
|
fileUploadLoading: loading,
|
||||||
|
onFileUploadOk,
|
||||||
|
fileUploadVisible,
|
||||||
|
hideFileUploadModal,
|
||||||
|
showFileUploadModal,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useHandleConnectToKnowledge = () => {
|
||||||
|
const {
|
||||||
|
visible: connectToKnowledgeVisible,
|
||||||
|
hideModal: hideConnectToKnowledgeModal,
|
||||||
|
showModal: showConnectToKnowledgeModal,
|
||||||
|
} = useSetModalState();
|
||||||
|
const connectToKnowledge = useConnectToKnowledge();
|
||||||
|
const id = useGetFolderId();
|
||||||
|
const [fileIds, setFileIds] = useState<string[]>([]);
|
||||||
|
|
||||||
|
const onConnectToKnowledgeOk = useCallback(
|
||||||
|
async (knowledgeIds: string[]) => {
|
||||||
|
const ret = await connectToKnowledge({
|
||||||
|
parentId: id,
|
||||||
|
fileIds,
|
||||||
|
kbIds: knowledgeIds,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (ret === 0) {
|
||||||
|
hideConnectToKnowledgeModal();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[connectToKnowledge, hideConnectToKnowledgeModal, id, fileIds],
|
||||||
|
);
|
||||||
|
|
||||||
|
const loading = useOneNamespaceEffectsLoading('fileManager', [
|
||||||
|
'connectFileToKnowledge',
|
||||||
|
]);
|
||||||
|
|
||||||
|
const handleShowConnectToKnowledgeModal = useCallback(
|
||||||
|
(ids: string[]) => {
|
||||||
|
setFileIds(ids);
|
||||||
|
showConnectToKnowledgeModal();
|
||||||
|
},
|
||||||
|
[showConnectToKnowledgeModal],
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
connectToKnowledgeLoading: loading,
|
||||||
|
onConnectToKnowledgeOk,
|
||||||
|
connectToKnowledgeVisible,
|
||||||
|
hideConnectToKnowledgeModal,
|
||||||
|
showConnectToKnowledgeModal: handleShowConnectToKnowledgeModal,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -7,13 +7,17 @@ import ActionCell from './action-cell';
|
|||||||
import FileToolbar from './file-toolbar';
|
import FileToolbar from './file-toolbar';
|
||||||
import {
|
import {
|
||||||
useGetRowSelection,
|
useGetRowSelection,
|
||||||
|
useHandleConnectToKnowledge,
|
||||||
useHandleCreateFolder,
|
useHandleCreateFolder,
|
||||||
|
useHandleUploadFile,
|
||||||
useNavigateToOtherFolder,
|
useNavigateToOtherFolder,
|
||||||
useRenameCurrentFile,
|
useRenameCurrentFile,
|
||||||
useSelectFileListLoading,
|
useSelectFileListLoading,
|
||||||
} from './hooks';
|
} from './hooks';
|
||||||
|
|
||||||
import RenameModal from '@/components/rename-modal';
|
import RenameModal from '@/components/rename-modal';
|
||||||
|
import ConnectToKnowledgeModal from './connect-to-knowledge-modal';
|
||||||
|
import FileUploadModal from './file-upload-modal';
|
||||||
import FolderCreateModal from './folder-create-modal';
|
import FolderCreateModal from './folder-create-modal';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
@ -37,6 +41,14 @@ const FileManager = () => {
|
|||||||
folderCreateLoading,
|
folderCreateLoading,
|
||||||
onFolderCreateOk,
|
onFolderCreateOk,
|
||||||
} = useHandleCreateFolder();
|
} = useHandleCreateFolder();
|
||||||
|
const { fileUploadVisible, hideFileUploadModal, showFileUploadModal } =
|
||||||
|
useHandleUploadFile();
|
||||||
|
const {
|
||||||
|
connectToKnowledgeVisible,
|
||||||
|
hideConnectToKnowledgeModal,
|
||||||
|
showConnectToKnowledgeModal,
|
||||||
|
onConnectToKnowledgeOk,
|
||||||
|
} = useHandleConnectToKnowledge();
|
||||||
|
|
||||||
const columns: ColumnsType<IFile> = [
|
const columns: ColumnsType<IFile> = [
|
||||||
{
|
{
|
||||||
@ -64,6 +76,17 @@ const FileManager = () => {
|
|||||||
return formatDate(text);
|
return formatDate(text);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'kbs_info',
|
||||||
|
dataIndex: 'kbs_info',
|
||||||
|
key: 'kbs_info',
|
||||||
|
render(value) {
|
||||||
|
console.info(value);
|
||||||
|
return Array.isArray(value)
|
||||||
|
? value?.map((x) => x.kb_name).join(',')
|
||||||
|
: '';
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Location',
|
title: 'Location',
|
||||||
dataIndex: 'location',
|
dataIndex: 'location',
|
||||||
@ -80,6 +103,7 @@ const FileManager = () => {
|
|||||||
console.info(record);
|
console.info(record);
|
||||||
}}
|
}}
|
||||||
showRenameModal={showFileRenameModal}
|
showRenameModal={showFileRenameModal}
|
||||||
|
showConnectToKnowledgeModal={showConnectToKnowledgeModal}
|
||||||
></ActionCell>
|
></ActionCell>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@ -90,6 +114,7 @@ const FileManager = () => {
|
|||||||
<FileToolbar
|
<FileToolbar
|
||||||
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
selectedRowKeys={rowSelection.selectedRowKeys as string[]}
|
||||||
showFolderCreateModal={showFolderCreateModal}
|
showFolderCreateModal={showFolderCreateModal}
|
||||||
|
showFileUploadModal={showFileUploadModal}
|
||||||
></FileToolbar>
|
></FileToolbar>
|
||||||
<Table
|
<Table
|
||||||
dataSource={fileList}
|
dataSource={fileList}
|
||||||
@ -111,6 +136,15 @@ const FileManager = () => {
|
|||||||
hideModal={hideFolderCreateModal}
|
hideModal={hideFolderCreateModal}
|
||||||
onOk={onFolderCreateOk}
|
onOk={onFolderCreateOk}
|
||||||
></FolderCreateModal>
|
></FolderCreateModal>
|
||||||
|
<FileUploadModal
|
||||||
|
visible={fileUploadVisible}
|
||||||
|
hideModal={hideFileUploadModal}
|
||||||
|
></FileUploadModal>
|
||||||
|
<ConnectToKnowledgeModal
|
||||||
|
visible={connectToKnowledgeVisible}
|
||||||
|
hideModal={hideConnectToKnowledgeModal}
|
||||||
|
onOk={onConnectToKnowledgeOk}
|
||||||
|
></ConnectToKnowledgeModal>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -56,6 +56,20 @@ const model: DvaModel<FileManagerModelState> = {
|
|||||||
}
|
}
|
||||||
return data.retcode;
|
return data.retcode;
|
||||||
},
|
},
|
||||||
|
*uploadFile({ payload = {} }, { call, put }) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('parent_id', payload.parentId);
|
||||||
|
formData.append('file', payload.file);
|
||||||
|
formData.append('path', payload.path);
|
||||||
|
const { data } = yield call(fileManagerService.uploadFile, formData);
|
||||||
|
if (data.retcode === 0) {
|
||||||
|
yield put({
|
||||||
|
type: 'listFile',
|
||||||
|
payload: { parentId: payload.parentId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data.retcode;
|
||||||
|
},
|
||||||
*createFolder({ payload = {} }, { call, put }) {
|
*createFolder({ payload = {} }, { call, put }) {
|
||||||
const { data } = yield call(fileManagerService.createFolder, payload);
|
const { data } = yield call(fileManagerService.createFolder, payload);
|
||||||
if (data.retcode === 0) {
|
if (data.retcode === 0) {
|
||||||
@ -79,6 +93,19 @@ const model: DvaModel<FileManagerModelState> = {
|
|||||||
}
|
}
|
||||||
return data.retcode;
|
return data.retcode;
|
||||||
},
|
},
|
||||||
|
*connectFileToKnowledge({ payload = {} }, { call, put }) {
|
||||||
|
const { data } = yield call(
|
||||||
|
fileManagerService.connectFileToKnowledge,
|
||||||
|
omit(payload, 'parentId'),
|
||||||
|
);
|
||||||
|
if (data.retcode === 0) {
|
||||||
|
yield put({
|
||||||
|
type: 'listFile',
|
||||||
|
payload: { parentId: payload.parentId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return data.retcode;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default model;
|
export default model;
|
||||||
|
@ -228,7 +228,7 @@ const UserSettingModel = () => {
|
|||||||
<section className={styles.modelWrapper}>
|
<section className={styles.modelWrapper}>
|
||||||
<SettingTitle
|
<SettingTitle
|
||||||
title={t('model')}
|
title={t('model')}
|
||||||
description={t('profileDescription')}
|
description={t('modelDescription')}
|
||||||
showRightButton
|
showRightButton
|
||||||
clickButton={showSystemSettingModal}
|
clickButton={showSystemSettingModal}
|
||||||
></SettingTitle>
|
></SettingTitle>
|
||||||
|
@ -9,6 +9,7 @@ const {
|
|||||||
renameFile,
|
renameFile,
|
||||||
getAllParentFolder,
|
getAllParentFolder,
|
||||||
createFolder,
|
createFolder,
|
||||||
|
connectFileToKnowledge,
|
||||||
} = api;
|
} = api;
|
||||||
|
|
||||||
const methods = {
|
const methods = {
|
||||||
@ -36,6 +37,10 @@ const methods = {
|
|||||||
url: createFolder,
|
url: createFolder,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
},
|
},
|
||||||
|
connectFileToKnowledge: {
|
||||||
|
url: connectFileToKnowledge,
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const fileManagerService = registerServer<keyof typeof methods>(
|
const fileManagerService = registerServer<keyof typeof methods>(
|
||||||
|
@ -74,4 +74,5 @@ export default {
|
|||||||
renameFile: `${api_host}/file/rename`,
|
renameFile: `${api_host}/file/rename`,
|
||||||
getAllParentFolder: `${api_host}/file/all_parent_folder`,
|
getAllParentFolder: `${api_host}/file/all_parent_folder`,
|
||||||
createFolder: `${api_host}/file/create`,
|
createFolder: `${api_host}/file/create`,
|
||||||
|
connectFileToKnowledge: `${api_host}/file2document/convert`,
|
||||||
};
|
};
|
||||||
|
@ -85,3 +85,12 @@ export const downloadFile = ({
|
|||||||
downloadElement.click();
|
downloadElement.click();
|
||||||
document.body.removeChild(downloadElement);
|
document.body.removeChild(downloadElement);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getFilePathByWebkitRelativePath = (file: File) => {
|
||||||
|
const path = file.webkitRelativePath;
|
||||||
|
return path;
|
||||||
|
// if (path !== '') {
|
||||||
|
// return path.slice(0, path.lastIndexOf('/'));
|
||||||
|
// }
|
||||||
|
// return path;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user