@@ -44,7 +102,8 @@ const DocumentList = ({ knowledgeBaseId }) => {
);
}
- if (items.length === 0) {
+ if (!items || items.length === 0) {
+ console.log('DocumentList - 暂无文档');
return (
暂无文档,请上传文档
@@ -52,6 +111,7 @@ const DocumentList = ({ knowledgeBaseId }) => {
);
}
+ console.log('DocumentList - 渲染文档列表', displayedItems);
return (
<>
@@ -65,22 +125,30 @@ const DocumentList = ({ knowledgeBaseId }) => {
- {items.map((doc) => (
-
- {doc.document_name} |
- {formatDateTime(doc.create_time)} |
- {formatDateTime(doc.update_time)} |
+ {displayedItems.map((doc) => (
+
+
+
+ {doc.document_name || doc.name}
+
+ |
+ {formatDateTime(doc.create_time || doc.created_at)} |
+ {formatDateTime(doc.update_time || doc.updated_at)} |
@@ -91,9 +159,33 @@ const DocumentList = ({ knowledgeBaseId }) => {
|
- {pagination.total > 0 && (
+ {/* 分页控件 */}
+ {items.length > 0 && (
-
共 {pagination.total} 条记录
+
+ 共 {items.length} 条记录,第 {currentPage}/{totalPages} 页
+
+
)}
diff --git a/src/pages/KnowledgeBase/Detail/components/DocumentPreviewModal.jsx b/src/pages/KnowledgeBase/Detail/components/DocumentPreviewModal.jsx
index 1afea74..8b8598b 100644
--- a/src/pages/KnowledgeBase/Detail/components/DocumentPreviewModal.jsx
+++ b/src/pages/KnowledgeBase/Detail/components/DocumentPreviewModal.jsx
@@ -34,6 +34,8 @@ const DocumentPreviewModal = ({ show, documentId, knowledgeBaseId, onClose }) =>
// 兜底情况
setDocumentContent(response);
}
+ console.log(documentContent);
+
} catch (error) {
console.error('获取文档内容失败:', error);
dispatch(
@@ -88,8 +90,8 @@ const DocumentPreviewModal = ({ show, documentId, knowledgeBaseId, onClose }) =>
- {documentContent.content &&
- documentContent.content.map((section, index) => {
+ {documentContent?.paragraphs.length > 0 &&
+ documentContent.paragraphs.map((section, index) => {
let contentDisplay;
try {
// 尝试解析JSON内容
diff --git a/src/pages/KnowledgeBase/Detail/components/FileUploadModal.jsx b/src/pages/KnowledgeBase/Detail/components/FileUploadModal.jsx
index 5078982..301526c 100644
--- a/src/pages/KnowledgeBase/Detail/components/FileUploadModal.jsx
+++ b/src/pages/KnowledgeBase/Detail/components/FileUploadModal.jsx
@@ -9,9 +9,10 @@ const FileUploadModal = ({ show, knowledgeBaseId, onClose }) => {
const dispatch = useDispatch();
const fileInputRef = useRef(null);
const modalRef = useRef(null);
- const [selectedFile, setSelectedFile] = useState(null);
+ const [selectedFiles, setSelectedFiles] = useState([]);
const [isUploading, setIsUploading] = useState(false);
const [fileError, setFileError] = useState('');
+ const [uploadResults, setUploadResults] = useState(null);
// 处理上传区域点击事件
const handleUploadAreaClick = () => {
@@ -29,59 +30,68 @@ const FileUploadModal = ({ show, knowledgeBaseId, onClose }) => {
e.stopPropagation();
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
- handleFileSelected(e.dataTransfer.files[0]);
+ handleFilesSelected(e.dataTransfer.files);
}
};
const handleFileChange = (e) => {
if (e.target.files && e.target.files.length > 0) {
- handleFileSelected(e.target.files[0]);
+ handleFilesSelected(e.target.files);
}
};
- const handleFileSelected = (file) => {
+ const handleFilesSelected = (files) => {
setFileError('');
- setSelectedFile(file);
+ // 将FileList转为数组
+ const filesArray = Array.from(files);
+ setSelectedFiles((prev) => [...prev, ...filesArray]);
+ };
+
+ const removeFile = (index) => {
+ setSelectedFiles((prev) => prev.filter((_, i) => i !== index));
};
const resetFileInput = () => {
- setSelectedFile(null);
+ setSelectedFiles([]);
setFileError('');
+ setUploadResults(null);
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
};
const handleUpload = async () => {
- if (!selectedFile) {
- setFileError('请选择要上传的文件');
+ if (selectedFiles.length === 0) {
+ setFileError('请至少选择一个要上传的文件');
return;
}
setIsUploading(true);
+ setUploadResults(null);
try {
- await dispatch(
+ const result = await dispatch(
uploadDocument({
knowledge_base_id: knowledgeBaseId,
- file: selectedFile,
+ files: selectedFiles,
})
).unwrap();
// 成功上传后刷新文档列表
dispatch(getKnowledgeBaseDocuments({ knowledge_base_id: knowledgeBaseId }));
- // Reset the file input
- resetFileInput();
+ // 显示上传结果
+ setUploadResults(result);
- // 上传成功后关闭模态框
- onClose();
+ // 如果没有失败的文件,就在3秒后自动关闭模态窗
+ if (result.failed_count === 0) {
+ setTimeout(() => {
+ handleClose();
+ }, 3000);
+ }
} catch (error) {
console.error('Upload failed:', error);
setFileError('文件上传失败: ' + (error?.message || '未知错误'));
-
- // 清空选中的文件
- resetFileInput();
} finally {
setIsUploading(false);
}
@@ -130,9 +140,11 @@ const FileUploadModal = ({ show, knowledgeBaseId, onClose }) => {
@@ -162,22 +174,92 @@ const FileUploadModal = ({ show, knowledgeBaseId, onClose }) => {
onChange={handleFileChange}
accept='.pdf,.doc,.docx,.txt,.md,.csv,.xlsx,.xls'
disabled={isUploading}
+ multiple
/>
- {selectedFile ? (
-
-
已选择文件:
-
{selectedFile.name}
-
- ) : (
-
-
点击或拖拽文件到此处上传
-
- 支持 PDF, Word, Excel, TXT, Markdown, CSV 等格式
-
-
- )}
+
+
点击或拖拽文件到此处上传
+
支持 PDF, Word, Excel, TXT, Markdown, CSV 等格式
+
{fileError &&
{fileError}
}
+
+ {/* 选择的文件列表 */}
+ {selectedFiles.length > 0 && (
+
+
已选择 {selectedFiles.length} 个文件:
+
+ {selectedFiles.map((file, index) => (
+ -
+
+
{file.name}
+
+ ({(file.size / 1024).toFixed(0)} KB)
+
+
+ {!isUploading && (
+
+ )}
+
+ ))}
+
+
+ )}
+
+ {/* 上传结果显示 */}
+ {uploadResults && (
+
+
上传结果
+
+ 总文件: {uploadResults.total_files}, 成功: {uploadResults.uploaded_count}, 失败:{' '}
+ {uploadResults.failed_count}
+
+
+ {uploadResults.documents && uploadResults.documents.length > 0 && (
+ <>
+
上传成功:
+
+ {uploadResults.documents.map((doc) => (
+ -
+ ✓
+ {doc.name}
+
+ ))}
+
+ >
+ )}
+
+ {uploadResults.failed_documents && uploadResults.failed_documents.length > 0 && (
+ <>
+
上传失败:
+
+ >
+ )}
+
+ )}
diff --git a/src/store/knowledgeBase/knowledgeBase.slice.js b/src/store/knowledgeBase/knowledgeBase.slice.js
index 95c45dd..e7c925c 100644
--- a/src/store/knowledgeBase/knowledgeBase.slice.js
+++ b/src/store/knowledgeBase/knowledgeBase.slice.js
@@ -218,9 +218,13 @@ const knowledgeBaseSlice = createSlice({
state.documents.items = action.payload.items || [];
state.documents.pagination = {
total: action.payload.total || 0,
- page: action.payload.page || 1,
- page_size: action.payload.page_size || 10,
+ page: 1,
+ page_size: 10,
};
+ console.log('文档数据已更新到store:', {
+ itemsCount: state.documents.items.length,
+ items: state.documents.items,
+ });
})
.addCase(getKnowledgeBaseDocuments.rejected, (state, action) => {
state.documents.loading = false;
diff --git a/src/store/knowledgeBase/knowledgeBase.thunks.js b/src/store/knowledgeBase/knowledgeBase.thunks.js
index 959dc09..62bf221 100644
--- a/src/store/knowledgeBase/knowledgeBase.thunks.js
+++ b/src/store/knowledgeBase/knowledgeBase.thunks.js
@@ -200,32 +200,54 @@ export const requestKnowledgeBaseAccess = createAsyncThunk(
);
/**
- * Upload a document to a knowledge base
+ * Upload documents to a knowledge base
* @param {Object} params - Upload parameters
* @param {string} params.knowledge_base_id - Knowledge base ID
- * @param {File} params.file - File to upload
+ * @param {File[]} params.files - Files to upload
*/
export const uploadDocument = createAsyncThunk(
'knowledgeBase/uploadDocument',
- async ({ knowledge_base_id, file }, { rejectWithValue, dispatch }) => {
+ async ({ knowledge_base_id, files }, { rejectWithValue, dispatch }) => {
try {
const formData = new FormData();
- formData.append('file', file);
+
+ // 支持单文件和多文件上传
+ if (Array.isArray(files)) {
+ // 多文件上传
+ files.forEach(file => {
+ formData.append('files', file);
+ });
+ } else {
+ // 单文件上传(向后兼容)
+ formData.append('files', files);
+ }
const response = await post(`/knowledge-bases/${knowledge_base_id}/upload_document/`, formData, true);
+ // 处理新的返回格式
+ if (response.data && response.data.code === 200) {
+ const result = response.data.data;
+
+ // 使用API返回的消息作为通知
+ dispatch(
+ showNotification({
+ type: 'success',
+ message: response.data.message || `文档上传完成,成功: ${result.uploaded_count},失败: ${result.failed_count}`,
+ })
+ );
+
+ return result;
+ }
+
dispatch(
showNotification({
type: 'success',
- message: `文档 ${file.name} 上传成功`,
+ message: Array.isArray(files)
+ ? `${files.length} 个文档上传成功`
+ : `文档 ${files.name} 上传成功`,
})
);
- // 处理新的返回格式
- if (response.data && response.data.code === 200) {
- return response.data.data;
- }
-
return response.data;
} catch (error) {
const errorMessage = error.response?.data?.message || error.message || '文档上传失败';
@@ -244,24 +266,33 @@ export const uploadDocument = createAsyncThunk(
* Get documents list for a knowledge base
* @param {Object} params - Parameters
* @param {string} params.knowledge_base_id - Knowledge base ID
- * @param {number} params.page - Page number (default: 1)
- * @param {number} params.page_size - Page size (default: 10)
*/
export const getKnowledgeBaseDocuments = createAsyncThunk(
'knowledgeBase/getDocuments',
- async ({ knowledge_base_id, page = 1, page_size = 10 }, { rejectWithValue }) => {
+ async ({ knowledge_base_id }, { rejectWithValue }) => {
try {
- const response = await get(`/knowledge-bases/${knowledge_base_id}/documents/`, {
- params: { page, page_size },
- });
-
+ console.log('获取知识库文档列表:', knowledge_base_id);
+ const { data, code } = await get(`/knowledge-bases/${knowledge_base_id}/documents`);
+ console.log('文档列表API响应:', { data, code });
+
// 处理返回格式
- if (response.data && response.data.code === 200) {
- return response.data.data;
+ if (code === 200) {
+ console.log('API返回数据:', data);
+ return {
+ items: data || [],
+ total: (data || []).length
+ };
+ } else {
+ // 未知格式,尝试提取数据
+ const items = data?.items || data || [];
+ console.log('未识别格式,提取数据:', items);
+ return {
+ items: items,
+ total: items.length
+ };
}
-
- return response.data;
} catch (error) {
+ console.error('获取知识库文档失败:', error);
return rejectWithValue(error.response?.data?.message || '获取文档列表失败');
}
}