import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Box, Typography, LinearProgress, Alert, Dialog, DialogTitle, DialogContent, DialogActions, Button, TextField, Breadcrumbs, Link, Stack, } from '@mui/material'; import { type GridRowSelectionModel } from '@mui/x-data-grid'; import knowledgeService from '@/services/knowledge_service'; import type { IKnowledge, IKnowledgeFile } from '@/interfaces/database/knowledge'; import FileUploadDialog from '@/components/FileUploadDialog'; import KnowledgeInfoCard from './components/KnowledgeInfoCard'; import FileListComponent from './components/FileListComponent'; import FloatingActionButtons from './components/FloatingActionButtons'; import KnowledgeBreadcrumbs from './components/KnowledgeBreadcrumbs'; import { useDocumentList, useDocumentOperations } from '@/hooks/document-hooks'; function KnowledgeBaseDetail() { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); // 状态管理 const [knowledgeBase, setKnowledgeBase] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [searchKeyword, setSearchKeyword] = useState(''); const [rowSelectionModel, setRowSelectionModel] = useState({ type: 'include', ids: new Set() }); const [uploadDialogOpen, setUploadDialogOpen] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [testingDialogOpen, setTestingDialogOpen] = useState(false); const [configDialogOpen, setConfigDialogOpen] = useState(false); // 使用新的document hooks const { documents: files, total, loading: filesLoading, error: filesError, currentPage, pageSize, refresh: refreshFiles, setKeywords, setCurrentPage, setPageSize, } = useDocumentList(id || ''); const { uploadDocuments, deleteDocuments, runDocuments, loading: operationLoading, error: operationError, } = useDocumentOperations(); // 获取知识库详情 const fetchKnowledgeDetail = async () => { if (!id) return; try { setLoading(true); const response = await knowledgeService.getKnowledgeDetail({ kb_id: id }); if (response.data.code === 0) { setKnowledgeBase(response.data.data); } else { setError(response.data.message || '获取知识库详情失败'); } } catch (err: any) { setError(err.response?.data?.message || err.message || '获取知识库详情失败'); } finally { setLoading(false); } }; // 删除文件 const handleDeleteFiles = async () => { try { await deleteDocuments(Array.from(rowSelectionModel.ids) as string[]); setDeleteDialogOpen(false); setRowSelectionModel({ type: 'include', ids: new Set() }); refreshFiles(); fetchKnowledgeDetail(); } catch (err: any) { setError(err.response?.data?.message || err.message || '删除文件失败'); } }; // 上传文件处理 const handleUploadFiles = async (uploadFiles: File[]) => { console.log('上传文件:', uploadFiles); const kb_id = knowledgeBase?.id || ''; try { await uploadDocuments(kb_id, uploadFiles); refreshFiles(); fetchKnowledgeDetail(); } catch (err: any) { throw new Error(err.response?.data?.message || err.message || '上传文件失败'); } }; // 重新解析文件 const handleReparse = async (docIds: string[]) => { try { await runDocuments(docIds); refreshFiles(); // 刷新列表 } catch (err: any) { setError(err.response?.data?.message || err.message || '重新解析失败'); } }; // 初始化数据 useEffect(() => { fetchKnowledgeDetail(); }, [id]); // 搜索文件 useEffect(() => { const timer = setTimeout(() => { setKeywords(searchKeyword); }, 500); return () => clearTimeout(timer); }, [searchKeyword, setKeywords]); // 合并错误状态 const combinedError = error || filesError || operationError; if (loading) { return ( 加载中... ); } if (combinedError) { return ( {combinedError} ); } if (!knowledgeBase) { return ( 知识库不存在 ); } return ( {/* 面包屑导航 */} {/* 知识库信息卡片 */} {/* 文件列表组件 */} handleReparse(fileIds)} onDelete={(fileIds) => { console.log('删除文件:', fileIds); setRowSelectionModel({ type: 'include', ids: new Set(fileIds) }); setDeleteDialogOpen(true); }} onUpload={() => setUploadDialogOpen(true)} onRefresh={() => { refreshFiles(); fetchKnowledgeDetail(); }} rowSelectionModel={rowSelectionModel} onRowSelectionModelChange={(newModel) => { console.log('新的选择模型:', newModel); setRowSelectionModel(newModel); }} total={total} page={currentPage} pageSize={pageSize} onPageChange={setCurrentPage} onPageSizeChange={setPageSize} /> {/* 浮动操作按钮 */} navigate(`/knowledge/${id}/testing`)} onConfigClick={() => navigate(`/knowledge/${id}/setting`)} /> {/* 上传文件对话框 */} setUploadDialogOpen(false)} onUpload={handleUploadFiles} title="上传文件到知识库" acceptedFileTypes={['.pdf', '.docx', '.txt', '.md', '.png', '.jpg', '.jpeg', '.mp4', '.wav']} maxFileSize={100} maxFiles={10} /> {/* 删除确认对话框 */} setDeleteDialogOpen(false)}> 确认删除 确定要删除选中的 {rowSelectionModel.ids.size} 个文件吗?此操作不可撤销。 {/* 检索测试对话框 */} setTestingDialogOpen(false)} maxWidth="md" fullWidth> 检索测试 测试结果将在这里显示... {/* 配置设置对话框 */} setConfigDialogOpen(false)} maxWidth="sm" fullWidth> 配置设置 ); } export default KnowledgeBaseDetail;