|
|
@@ -2,7 +2,17 @@ import * as React from 'react';
|
|
|
import { generatePath, useParams } from 'react-router-dom';
|
|
|
import { observer } from 'mobx-react';
|
|
|
|
|
|
-import { Button, Table, TableColumnsType, Modal, TablePaginationConfig, Upload, UploadProps, message, Spin } from 'antd';
|
|
|
+import {
|
|
|
+ Button,
|
|
|
+ Table,
|
|
|
+ TableColumnsType,
|
|
|
+ Modal,
|
|
|
+ TablePaginationConfig,
|
|
|
+ Upload,
|
|
|
+ UploadProps,
|
|
|
+ message,
|
|
|
+ Spin
|
|
|
+} from 'antd';
|
|
|
import { EditOutlined, DeleteOutlined, InboxOutlined, PlusOutlined, ArrowLeftOutlined } from '@ant-design/icons';
|
|
|
import InfoModal from './components/InfoModal';
|
|
|
import InfoModalSetting from './components/InfoModalSetting';
|
|
|
@@ -16,419 +26,419 @@ import './style.less';
|
|
|
|
|
|
const { Dragger } = Upload;
|
|
|
|
|
|
-const KnowledgeLibInfo: React.FC = () => {
|
|
|
-
|
|
|
- const {
|
|
|
- state,
|
|
|
- init,
|
|
|
- onClickModify,
|
|
|
- onClickDelete,
|
|
|
- onChangePagination,
|
|
|
- onClickDocumentDetail,
|
|
|
- infoModalOnClickConfirm,
|
|
|
- infoModalOnClickCancel,
|
|
|
- infoModalSettingOnClickConfirm,
|
|
|
- infoModalSettingOnClickCancel,
|
|
|
- onClickSettings,
|
|
|
- reset
|
|
|
- } = store;
|
|
|
- const {
|
|
|
- knowledge_id,
|
|
|
- listLoading,
|
|
|
- page,
|
|
|
- list,
|
|
|
- infoModalOpen,
|
|
|
- infoModalId,
|
|
|
- infoModalSettingOpen,
|
|
|
- infoModalSettingId,
|
|
|
- knowledgeDetail,
|
|
|
- } = state;
|
|
|
-
|
|
|
- const [uploadLoading, setUploadLoading] = React.useState(false);
|
|
|
-
|
|
|
- const params = useParams();
|
|
|
-
|
|
|
- const [fileList, setFileList] = React.useState<any[]>([]);
|
|
|
- const [uploading, setUploading] = React.useState(false);
|
|
|
-
|
|
|
- const [sListFlag, setSListFlag] = React.useState<boolean>();
|
|
|
- const [cUpdateFlag, setCUpdateFlag] = React.useState<boolean>();
|
|
|
- const [detailFlag, setDetailFlag] = React.useState<boolean>();
|
|
|
- const [deleteFlag, setDeleteFlag] = React.useState<boolean>();
|
|
|
- const [createFlag, setCreateFlag] = React.useState<boolean>();
|
|
|
-
|
|
|
- const props: UploadProps = {
|
|
|
- name: 'files',
|
|
|
- multiple: true,
|
|
|
- action: '/api/deepseek/api/uploadDocument/' + params.knowledgeId,
|
|
|
-
|
|
|
- beforeUpload(file, fileList) {
|
|
|
- setUploadLoading(true);
|
|
|
- // const allowedExtensions = ['md', 'txt', 'pdf', 'jpg', 'png', 'jpeg', 'docx', 'xlsx', 'pptx', 'eml', 'csv', 'tar', 'gz', 'bz2', 'zip', 'rar', 'jar'];
|
|
|
-
|
|
|
- const allowedExtensions = ['txt', 'pdf', 'jpg', 'png', 'jpeg', 'doc', 'docx', 'ppt', 'pptx'];
|
|
|
-
|
|
|
- // 检查文件类型
|
|
|
- for (const file of fileList) {
|
|
|
- const fileExt = file.name.split('.').pop()?.toLowerCase();
|
|
|
- if (!fileExt || !allowedExtensions.includes(fileExt)) {
|
|
|
- message.error(`不支持 ${fileExt} 格式的文件上传`);
|
|
|
- setUploadLoading(false);
|
|
|
- return Upload.LIST_IGNORE;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 检查文件大小
|
|
|
- let totalSize = 0;
|
|
|
- for (const file of fileList) {
|
|
|
- const fileExt = file.name.split('.').pop()?.toLowerCase();
|
|
|
- const fileSizeMB = file.size / 1024 / 1024;
|
|
|
-
|
|
|
- if (fileSizeMB > 30) {
|
|
|
- message.error('单个文件不能大于30M');
|
|
|
- setUploadLoading(false);
|
|
|
- return Upload.LIST_IGNORE;
|
|
|
- }
|
|
|
-
|
|
|
- if (['jpg', 'png', 'jpeg'].includes(fileExt!) && fileSizeMB > 5) {
|
|
|
- message.error('单张图片不能大于5M');
|
|
|
- setUploadLoading(false);
|
|
|
- return Upload.LIST_IGNORE;
|
|
|
- }
|
|
|
-
|
|
|
- totalSize += fileSizeMB;
|
|
|
- }
|
|
|
-
|
|
|
- if (totalSize > 125) {
|
|
|
- message.error('文件总大小超过125M');
|
|
|
- setUploadLoading(false);
|
|
|
- return Upload.LIST_IGNORE;
|
|
|
- }
|
|
|
-
|
|
|
- },
|
|
|
- onChange(info) {
|
|
|
- const { status } = info.file;
|
|
|
-
|
|
|
- if (status !== 'uploading') {
|
|
|
- console.log(status, 'status--uploading');
|
|
|
- }
|
|
|
- if (status === 'done') {
|
|
|
- console.log(status, 'status--done');
|
|
|
- console.info(info.file.response, 'info.file.response.data');
|
|
|
- if (info.file.response.code === 200 && info.file.response.data === 1) {
|
|
|
- message.success(`${info.file.name} file uploaded successfully.`);
|
|
|
- init(params.knowledgeId);
|
|
|
- }
|
|
|
- setUploadLoading(false);
|
|
|
- } else if (status === 'error') {
|
|
|
- console.log(status, 'status--error');
|
|
|
- message.error(`${info.file.name} file upload failed.`);
|
|
|
- setUploadLoading(false);
|
|
|
- }
|
|
|
- },
|
|
|
- onDrop(e) {
|
|
|
- console.log('Dropped files', e.dataTransfer.files);
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- const handleUpload = async () => {
|
|
|
- if (fileList.length === 0) return;
|
|
|
-
|
|
|
- setUploading(true);
|
|
|
- const formData = new FormData();
|
|
|
-
|
|
|
- // 添加所有文件
|
|
|
- fileList.forEach(file => {
|
|
|
- if (file.originFileObj) {
|
|
|
- formData.append('files', file.originFileObj);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- try {
|
|
|
- const res = await axios.post('/api/deepseek/api/uploadDocument/' + params.knowledgeId, formData, {
|
|
|
- headers: { 'Content-Type': 'multipart/form-data' }
|
|
|
- });
|
|
|
-
|
|
|
- message.success(`${fileList.length}个文件上传成功`);
|
|
|
- setFileList([]);
|
|
|
- } catch (err) {
|
|
|
- message.error('上传失败');
|
|
|
- } finally {
|
|
|
- setUploading(false);
|
|
|
+const KnowledgeLibInfo : React.FC = () => {
|
|
|
+
|
|
|
+ const {
|
|
|
+ state,
|
|
|
+ init,
|
|
|
+ onClickModify,
|
|
|
+ onClickDelete,
|
|
|
+ onChangePagination,
|
|
|
+ onClickDocumentDetail,
|
|
|
+ infoModalOnClickConfirm,
|
|
|
+ infoModalOnClickCancel,
|
|
|
+ infoModalSettingOnClickConfirm,
|
|
|
+ infoModalSettingOnClickCancel,
|
|
|
+ onClickSettings,
|
|
|
+ reset
|
|
|
+ } = store;
|
|
|
+ const {
|
|
|
+ knowledge_id,
|
|
|
+ listLoading,
|
|
|
+ page,
|
|
|
+ list,
|
|
|
+ infoModalOpen,
|
|
|
+ infoModalId,
|
|
|
+ infoModalSettingOpen,
|
|
|
+ infoModalSettingId,
|
|
|
+ knowledgeDetail,
|
|
|
+ } = state;
|
|
|
+
|
|
|
+ const [ uploadLoading, setUploadLoading ] = React.useState( false );
|
|
|
+
|
|
|
+ const params = useParams();
|
|
|
+
|
|
|
+ const [ fileList, setFileList ] = React.useState<any[]>( [] );
|
|
|
+ const [ uploading, setUploading ] = React.useState( false );
|
|
|
+
|
|
|
+ const [ sListFlag, setSListFlag ] = React.useState<boolean>();
|
|
|
+ const [ cUpdateFlag, setCUpdateFlag ] = React.useState<boolean>();
|
|
|
+ const [ detailFlag, setDetailFlag ] = React.useState<boolean>();
|
|
|
+ const [ deleteFlag, setDeleteFlag ] = React.useState<boolean>();
|
|
|
+ const [ createFlag, setCreateFlag ] = React.useState<boolean>();
|
|
|
+
|
|
|
+ const props : UploadProps = {
|
|
|
+ name: 'files',
|
|
|
+ multiple: true,
|
|
|
+ action: '/api/deepseek/api/uploadDocument/' + params.knowledgeId,
|
|
|
+
|
|
|
+ beforeUpload( file, fileList ) {
|
|
|
+ setUploadLoading( true );
|
|
|
+ // const allowedExtensions = ['md', 'txt', 'pdf', 'jpg', 'png', 'jpeg', 'docx', 'xlsx', 'pptx', 'eml', 'csv', 'tar', 'gz', 'bz2', 'zip', 'rar', 'jar'];
|
|
|
+
|
|
|
+ const allowedExtensions = [ 'txt', 'pdf', 'jpg', 'png', 'jpeg', 'doc', 'docx', 'ppt', 'pptx' ];
|
|
|
+
|
|
|
+ // 检查文件类型
|
|
|
+ for ( const file of fileList ) {
|
|
|
+ const fileExt = file.name.split( '.' ).pop()?.toLowerCase();
|
|
|
+ if ( !fileExt || !allowedExtensions.includes( fileExt ) ) {
|
|
|
+ message.error( `不支持 ${ fileExt } 格式的文件上传` );
|
|
|
+ setUploadLoading( false );
|
|
|
+ return Upload.LIST_IGNORE;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- React.useEffect(() => {
|
|
|
- init(params.knowledgeId);
|
|
|
- const cList = LocalStorage.getStatusFlag('deepseek:slice:list');
|
|
|
- setSListFlag(cList);
|
|
|
- const cDetail = LocalStorage.getStatusFlag('deepseek:config:update');
|
|
|
- setCUpdateFlag(cDetail);
|
|
|
- const detail = LocalStorage.getStatusFlag('deepseek:document:detail');
|
|
|
- setDetailFlag(detail);
|
|
|
- const deleteF = LocalStorage.getStatusFlag('deepseek:document:delete');
|
|
|
- setDeleteFlag(deleteF);
|
|
|
- const createF = LocalStorage.getStatusFlag('deepseek:document:create');
|
|
|
- setCreateFlag(createF);
|
|
|
- return () => reset();
|
|
|
- }, []);
|
|
|
-
|
|
|
- const columns: TableColumnsType<Record> = [
|
|
|
- {
|
|
|
- title: '序号',
|
|
|
- dataIndex: 'index',
|
|
|
- width: 80,
|
|
|
- render: (text, record, index) => {
|
|
|
- return index + 1;
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '文件名',
|
|
|
- dataIndex: 'name',
|
|
|
- width: 300,
|
|
|
- render: (text, record) => {
|
|
|
- return (
|
|
|
- `${text}`
|
|
|
- )
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '文件大小',
|
|
|
- dataIndex: 'length',
|
|
|
- width: 100,
|
|
|
- render: (text) => {
|
|
|
- if (text) {
|
|
|
- const size = (text / 1024 / 1024).toFixed(2);
|
|
|
- return `${size} M`;
|
|
|
- } else {
|
|
|
- return '--'
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '字符数量',
|
|
|
- dataIndex: 'wordNum',
|
|
|
- width: 100,
|
|
|
- render: (text) => {
|
|
|
- if (text) {
|
|
|
- return `${text}`;
|
|
|
- } else {
|
|
|
- return '--'
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '分段',
|
|
|
- dataIndex: 'sliceTotal',
|
|
|
- width: 100,
|
|
|
- render: (text) => {
|
|
|
- if (text) {
|
|
|
- return `${text}`;
|
|
|
- } else {
|
|
|
- return '--';
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '上传时间',
|
|
|
- dataIndex: 'createTime',
|
|
|
- width: 180,
|
|
|
- render: (text) => {
|
|
|
- if (text) {
|
|
|
- return dayjs(text).format('YYYY-MM-DD HH:mm:ss');
|
|
|
- } else {
|
|
|
- return '--';
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '更新时间',
|
|
|
- dataIndex: 'updateTime',
|
|
|
- width: 180,
|
|
|
- render: (text) => {
|
|
|
- if (text) {
|
|
|
- return dayjs(text).format('YYYY-MM-DD HH:mm:ss');
|
|
|
- } else {
|
|
|
- return '--';
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- {
|
|
|
- title: '操作',
|
|
|
- dataIndex: 'operation',
|
|
|
- width: 180,
|
|
|
- fixed: 'right',
|
|
|
- render: (text, record) => {
|
|
|
- return (
|
|
|
- <>
|
|
|
- {createFlag &&
|
|
|
- <a
|
|
|
- style={{ marginRight: 16 }}
|
|
|
- onClick={() => {
|
|
|
- const path = generatePath('/deepseek/knowledgeLib/:knowledgeId/slice/:documentId/:embeddingId', {
|
|
|
- knowledgeId: params.knowledgeId as string,
|
|
|
- documentId: record.documentId,
|
|
|
- embeddingId: state.knowledgeDetail.embeddingId,
|
|
|
- });
|
|
|
- router.navigate({ pathname: path });
|
|
|
- }}
|
|
|
- >
|
|
|
- 切片
|
|
|
- </a>
|
|
|
- }
|
|
|
- {
|
|
|
- cUpdateFlag &&
|
|
|
- <a
|
|
|
- style={{ marginRight: 16 }}
|
|
|
- onClick={() => {
|
|
|
- onClickSettings(record.documentId);
|
|
|
- }}
|
|
|
- >
|
|
|
- 配置
|
|
|
- </a>
|
|
|
- }
|
|
|
- {
|
|
|
- cUpdateFlag &&
|
|
|
- <a
|
|
|
- style={{ marginRight: 16 }}
|
|
|
- onClick={() => {
|
|
|
- onClickModify(record.documentId);
|
|
|
- }}>
|
|
|
- <EditOutlined />
|
|
|
- </a>
|
|
|
- }
|
|
|
- {
|
|
|
- deleteFlag &&
|
|
|
- <a
|
|
|
- className='text-error'
|
|
|
- onClick={() => {
|
|
|
- Modal.confirm({
|
|
|
- title: '删除',
|
|
|
- content: `确定删除知识文件:${record.name}吗?`,
|
|
|
- okType: 'danger',
|
|
|
- onOk: async () => {
|
|
|
- const userInfo = LocalStorage.getUserInfo();
|
|
|
- await onClickDelete(record.documentId);
|
|
|
- }
|
|
|
- });
|
|
|
- }}
|
|
|
- >
|
|
|
- <DeleteOutlined />
|
|
|
- </a>
|
|
|
- }
|
|
|
- </>
|
|
|
- )
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查文件大小
|
|
|
+ let totalSize = 0;
|
|
|
+ for ( const file of fileList ) {
|
|
|
+ const fileExt = file.name.split( '.' ).pop()?.toLowerCase();
|
|
|
+ const fileSizeMB = file.size / 1024 / 1024;
|
|
|
+
|
|
|
+ if ( fileSizeMB > 30 ) {
|
|
|
+ message.error( '单个文件不能大于30M' );
|
|
|
+ setUploadLoading( false );
|
|
|
+ return Upload.LIST_IGNORE;
|
|
|
}
|
|
|
- ];
|
|
|
-
|
|
|
- const paginationConfig: TablePaginationConfig = {
|
|
|
- // 显示数据总量
|
|
|
- showTotal: (total: number) => {
|
|
|
- return `共 ${total} 条`;
|
|
|
- },
|
|
|
- // 展示分页条数切换
|
|
|
- showSizeChanger: true,
|
|
|
- // 指定每页显示条数
|
|
|
- pageSizeOptions: ['10', '20', '50', '100'],
|
|
|
- // 快速跳转至某页
|
|
|
- showQuickJumper: true,
|
|
|
- current: page.page,
|
|
|
- pageSize: page.size,
|
|
|
- total: page.total,
|
|
|
- onChange: async (page, pageSize) => {
|
|
|
- await onChangePagination(page, pageSize);
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- return (
|
|
|
- <div className='knowledgeLibInfo'>
|
|
|
- <Spin spinning={uploadLoading || listLoading}>
|
|
|
+
|
|
|
+ if ( [ 'jpg', 'png', 'jpeg' ].includes( fileExt! ) && fileSizeMB > 5 ) {
|
|
|
+ message.error( '单张图片不能大于5M' );
|
|
|
+ setUploadLoading( false );
|
|
|
+ return Upload.LIST_IGNORE;
|
|
|
+ }
|
|
|
+
|
|
|
+ totalSize += fileSizeMB;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( totalSize > 125 ) {
|
|
|
+ message.error( '文件总大小超过125M' );
|
|
|
+ setUploadLoading( false );
|
|
|
+ return Upload.LIST_IGNORE;
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ onChange( info ) {
|
|
|
+ const { status } = info.file;
|
|
|
+
|
|
|
+ if ( status !== 'uploading' ) {
|
|
|
+ console.log( status, 'status--uploading' );
|
|
|
+ }
|
|
|
+ if ( status === 'done' ) {
|
|
|
+ console.log( status, 'status--done' );
|
|
|
+ console.info( info.file.response, 'info.file.response.data' );
|
|
|
+ if ( info.file.response.code === 200 && info.file.response.data === 1 ) {
|
|
|
+ message.success( `${ info.file.name } file uploaded successfully.` );
|
|
|
+ init( params.knowledgeId );
|
|
|
+ }
|
|
|
+ setUploadLoading( false );
|
|
|
+ } else if ( status === 'error' ) {
|
|
|
+ console.log( status, 'status--error' );
|
|
|
+ message.error( `${ info.file.name } file upload failed.` );
|
|
|
+ setUploadLoading( false );
|
|
|
+ }
|
|
|
+ },
|
|
|
+ onDrop( e ) {
|
|
|
+ console.log( 'Dropped files', e.dataTransfer.files );
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleUpload = async () => {
|
|
|
+ if ( fileList.length === 0 ) return;
|
|
|
+
|
|
|
+ setUploading( true );
|
|
|
+ const formData = new FormData();
|
|
|
+
|
|
|
+ // 添加所有文件
|
|
|
+ fileList.forEach( file => {
|
|
|
+ if ( file.originFileObj ) {
|
|
|
+ formData.append( 'files', file.originFileObj );
|
|
|
+ }
|
|
|
+ } );
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await axios.post( '/api/deepseek/api/uploadDocument/' + params.knowledgeId, formData, {
|
|
|
+ headers: { 'Content-Type': 'multipart/form-data' }
|
|
|
+ } );
|
|
|
+
|
|
|
+ message.success( `${ fileList.length }个文件上传成功` );
|
|
|
+ setFileList( [] );
|
|
|
+ } catch ( err ) {
|
|
|
+ message.error( '上传失败' );
|
|
|
+ } finally {
|
|
|
+ setUploading( false );
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ React.useEffect( () => {
|
|
|
+ init( params.knowledgeId );
|
|
|
+ const cList = LocalStorage.getStatusFlag( 'deepseek:slice:list' );
|
|
|
+ setSListFlag( cList );
|
|
|
+ const cDetail = LocalStorage.getStatusFlag( 'deepseek:config:update' );
|
|
|
+ setCUpdateFlag( cDetail );
|
|
|
+ const detail = LocalStorage.getStatusFlag( 'deepseek:document:detail' );
|
|
|
+ setDetailFlag( detail );
|
|
|
+ const deleteF = LocalStorage.getStatusFlag( 'deepseek:document:delete' );
|
|
|
+ setDeleteFlag( deleteF );
|
|
|
+ const createF = LocalStorage.getStatusFlag( 'deepseek:document:create' );
|
|
|
+ setCreateFlag( createF );
|
|
|
+ return () => reset();
|
|
|
+ }, [] );
|
|
|
+
|
|
|
+ const columns : TableColumnsType<Record> = [
|
|
|
+ {
|
|
|
+ title: '序号',
|
|
|
+ dataIndex: 'index',
|
|
|
+ width: 80,
|
|
|
+ render: ( text, record, index ) => {
|
|
|
+ return index + 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '文件名',
|
|
|
+ dataIndex: 'name',
|
|
|
+ width: 300,
|
|
|
+ render: ( text, record ) => {
|
|
|
+ return (
|
|
|
+ `${ text }`
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '文件大小',
|
|
|
+ dataIndex: 'length',
|
|
|
+ width: 100,
|
|
|
+ render: ( text ) => {
|
|
|
+ if ( text ) {
|
|
|
+ const size = ( text / 1024 / 1024 ).toFixed( 2 );
|
|
|
+ return `${ size } M`;
|
|
|
+ } else {
|
|
|
+ return '--'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '字符数量',
|
|
|
+ dataIndex: 'wordNum',
|
|
|
+ width: 100,
|
|
|
+ render: ( text ) => {
|
|
|
+ if ( text ) {
|
|
|
+ return `${ text }`;
|
|
|
+ } else {
|
|
|
+ return '--'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '分段',
|
|
|
+ dataIndex: 'sliceTotal',
|
|
|
+ width: 100,
|
|
|
+ render: ( text ) => {
|
|
|
+ if ( text ) {
|
|
|
+ return `${ text }`;
|
|
|
+ } else {
|
|
|
+ return '--';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '上传时间',
|
|
|
+ dataIndex: 'createTime',
|
|
|
+ width: 180,
|
|
|
+ render: ( text ) => {
|
|
|
+ if ( text ) {
|
|
|
+ return dayjs( text ).format( 'YYYY-MM-DD HH:mm:ss' );
|
|
|
+ } else {
|
|
|
+ return '--';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '更新时间',
|
|
|
+ dataIndex: 'updateTime',
|
|
|
+ width: 180,
|
|
|
+ render: ( text ) => {
|
|
|
+ if ( text ) {
|
|
|
+ return dayjs( text ).format( 'YYYY-MM-DD HH:mm:ss' );
|
|
|
+ } else {
|
|
|
+ return '--';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'operation',
|
|
|
+ width: 180,
|
|
|
+ fixed: 'right',
|
|
|
+ render: ( text, record ) => {
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ { createFlag &&
|
|
|
+ <a
|
|
|
+ style={ { marginRight: 16 } }
|
|
|
+ onClick={ () => {
|
|
|
+ const path = generatePath( '/deepseek/knowledgeLib/:knowledgeId/slice/:documentId/:embeddingId', {
|
|
|
+ knowledgeId: params.knowledgeId as string,
|
|
|
+ documentId: record.documentId,
|
|
|
+ embeddingId: state.knowledgeDetail.embeddingId,
|
|
|
+ } );
|
|
|
+ router.navigate( { pathname: path } );
|
|
|
+ } }
|
|
|
+ >
|
|
|
+ 切片
|
|
|
+ </a>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ cUpdateFlag &&
|
|
|
+ <a
|
|
|
+ style={ { marginRight: 16 } }
|
|
|
+ onClick={ () => {
|
|
|
+ onClickSettings( record.documentId );
|
|
|
+ } }
|
|
|
+ >
|
|
|
+ 配置
|
|
|
+ </a>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ cUpdateFlag &&
|
|
|
+ <a
|
|
|
+ style={ { marginRight: 16 } }
|
|
|
+ onClick={ () => {
|
|
|
+ onClickModify( record.documentId );
|
|
|
+ } }>
|
|
|
+ <EditOutlined />
|
|
|
+ </a>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ deleteFlag &&
|
|
|
+ <a
|
|
|
+ className='text-error'
|
|
|
+ onClick={ () => {
|
|
|
+ Modal.confirm( {
|
|
|
+ title: '删除',
|
|
|
+ content: `确定删除知识文件:${ record.name }吗?`,
|
|
|
+ okType: 'danger',
|
|
|
+ onOk: async () => {
|
|
|
+ const userInfo = LocalStorage.getUserInfo();
|
|
|
+ await onClickDelete( record.documentId );
|
|
|
+ }
|
|
|
+ } );
|
|
|
+ } }
|
|
|
+ >
|
|
|
+ <DeleteOutlined />
|
|
|
+ </a>
|
|
|
+ }
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ const paginationConfig : TablePaginationConfig = {
|
|
|
+ // 显示数据总量
|
|
|
+ showTotal: ( total : number ) => {
|
|
|
+ return `共 ${ total } 条`;
|
|
|
+ },
|
|
|
+ // 展示分页条数切换
|
|
|
+ showSizeChanger: true,
|
|
|
+ // 指定每页显示条数
|
|
|
+ pageSizeOptions: [ '10', '20', '50', '100' ],
|
|
|
+ // 快速跳转至某页
|
|
|
+ showQuickJumper: true,
|
|
|
+ current: page.page,
|
|
|
+ pageSize: page.size,
|
|
|
+ total: page.total,
|
|
|
+ onChange: async ( page, pageSize ) => {
|
|
|
+ await onChangePagination( page, pageSize );
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className='knowledgeLibInfo'>
|
|
|
+ <Spin spinning={ uploadLoading || listLoading }>
|
|
|
+ {
|
|
|
+ page.total === 0 &&
|
|
|
+ <div className='knowledgeLibInfo-operation'>
|
|
|
+ <div>
|
|
|
+ <Button
|
|
|
+ type='primary'
|
|
|
+ icon={ <ArrowLeftOutlined /> }
|
|
|
+ onClick={ () => {
|
|
|
+ router.navigate( { pathname: '/deepseek/knowledgeLib' } );
|
|
|
+ } }
|
|
|
+ >
|
|
|
+ 返回
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
{
|
|
|
- page.total === 0 &&
|
|
|
- <div className='knowledgeLibInfo-operation'>
|
|
|
- <div>
|
|
|
- <Button
|
|
|
- type='primary'
|
|
|
- icon={<ArrowLeftOutlined />}
|
|
|
- onClick={() => {
|
|
|
- router.navigate({ pathname: '/deepseek/knowledgeLib' });
|
|
|
- }}
|
|
|
- >
|
|
|
- 返回
|
|
|
- </Button>
|
|
|
- </div>
|
|
|
- {
|
|
|
- createFlag &&
|
|
|
- <div style={{ marginTop: 20, width: '100%', height: '200px' }}>
|
|
|
- <Dragger {...props}>
|
|
|
- <p className="ant-upload-drag-icon">
|
|
|
- <InboxOutlined />
|
|
|
- </p>
|
|
|
- <p >
|
|
|
- 点击上传,或拖放文件到此处
|
|
|
- </p >
|
|
|
- <p className="ant-upload-hint">
|
|
|
- 支持文件格式md,txt,pdf,jpg,png,jpeg,docx,xlsx,
|
|
|
- pptx,eml,csv,单个文档小雨30M,单张图片小于5M,文件总
|
|
|
- 大小不得超过125M.
|
|
|
- </p>
|
|
|
- </Dragger>
|
|
|
- </div>
|
|
|
- }
|
|
|
+ createFlag &&
|
|
|
+ <div style={ { marginTop: 20, width: '100%', height: '200px' } }>
|
|
|
+ <Dragger { ...props }>
|
|
|
+ <p className="ant-upload-drag-icon">
|
|
|
+ <InboxOutlined />
|
|
|
+ </p>
|
|
|
+ <p>
|
|
|
+ 点击上传,或拖放文件到此处
|
|
|
+ </p>
|
|
|
+ <p className="ant-upload-hint">
|
|
|
+ 支持文件格式md,txt,pdf,jpg,png,jpeg,docx,xlsx,
|
|
|
+ pptx,eml,csv,单个文档 ≤ 30M,单张图片 ≤ 5M,文件总
|
|
|
+ 大小不得超过125M.
|
|
|
+ </p>
|
|
|
+ </Dragger>
|
|
|
</div>
|
|
|
}
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ {
|
|
|
+ page.total > 0 &&
|
|
|
+ <>
|
|
|
+ <div className='knowledgeLibInfo-operation'>
|
|
|
+ <Button
|
|
|
+ style={ { marginRight: 16 } }
|
|
|
+ type='primary'
|
|
|
+ icon={ <ArrowLeftOutlined /> } onClick={ () => {
|
|
|
+ router.navigate( { pathname: '/deepseek/knowledgeLib' } );
|
|
|
+ } }>
|
|
|
+ 返回
|
|
|
+ </Button>
|
|
|
+ {
|
|
|
+ createFlag &&
|
|
|
+ <Upload { ...props }>
|
|
|
+ <Button type='primary' icon={ <PlusOutlined /> }>上传知识文件</Button>
|
|
|
+ </Upload>
|
|
|
+ }
|
|
|
+ </div>
|
|
|
+ <Table
|
|
|
+ scroll={ { x: 'max-content' } }
|
|
|
+ rowKey={ ( record ) => record.documentId }
|
|
|
+ loading={ listLoading }
|
|
|
+ columns={ columns }
|
|
|
+ dataSource={ list }
|
|
|
+ pagination={ paginationConfig }
|
|
|
+ />
|
|
|
{
|
|
|
- page.total > 0 &&
|
|
|
- <>
|
|
|
- <div className='knowledgeLibInfo-operation'>
|
|
|
- <Button
|
|
|
- style={{ marginRight: 16 }}
|
|
|
- type='primary'
|
|
|
- icon={<ArrowLeftOutlined />} onClick={() => {
|
|
|
- router.navigate({ pathname: '/deepseek/knowledgeLib' });
|
|
|
- }}>
|
|
|
- 返回
|
|
|
- </Button>
|
|
|
- {
|
|
|
- createFlag &&
|
|
|
- <Upload {...props}>
|
|
|
- <Button type='primary' icon={<PlusOutlined />}>上传知识文件</Button>
|
|
|
- </Upload>
|
|
|
- }
|
|
|
- </div>
|
|
|
- <Table
|
|
|
- scroll={{ x: 'max-content' }}
|
|
|
- rowKey={(record) => record.documentId}
|
|
|
- loading={listLoading}
|
|
|
- columns={columns}
|
|
|
- dataSource={list}
|
|
|
- pagination={paginationConfig}
|
|
|
- />
|
|
|
- {
|
|
|
- infoModalOpen &&
|
|
|
- <InfoModal
|
|
|
- id={infoModalId}
|
|
|
- open={infoModalOpen}
|
|
|
- onClickConfirm={infoModalOnClickConfirm}
|
|
|
- onClickCancel={infoModalOnClickCancel}
|
|
|
- />
|
|
|
- }
|
|
|
-
|
|
|
- {
|
|
|
- infoModalSettingOpen &&
|
|
|
- <InfoModalSetting
|
|
|
- id={infoModalSettingId}
|
|
|
- open={infoModalSettingOpen}
|
|
|
- onClickConfirm={infoModalSettingOnClickConfirm}
|
|
|
- onClickCancel={infoModalSettingOnClickCancel}
|
|
|
- />
|
|
|
- }
|
|
|
- </>
|
|
|
+ infoModalOpen &&
|
|
|
+ <InfoModal
|
|
|
+ id={ infoModalId }
|
|
|
+ open={ infoModalOpen }
|
|
|
+ onClickConfirm={ infoModalOnClickConfirm }
|
|
|
+ onClickCancel={ infoModalOnClickCancel }
|
|
|
+ />
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ infoModalSettingOpen &&
|
|
|
+ <InfoModalSetting
|
|
|
+ id={ infoModalSettingId }
|
|
|
+ open={ infoModalSettingOpen }
|
|
|
+ onClickConfirm={ infoModalSettingOnClickConfirm }
|
|
|
+ onClickCancel={ infoModalSettingOnClickCancel }
|
|
|
+ />
|
|
|
}
|
|
|
- </Spin>
|
|
|
- </div>
|
|
|
- );
|
|
|
+ </>
|
|
|
+ }
|
|
|
+ </Spin>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
};
|
|
|
|
|
|
-export default observer(KnowledgeLibInfo);
|
|
|
+export default observer( KnowledgeLibInfo );
|