import React, { useState, useEffect } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import { Box, Typography, Paper, CircularProgress, Alert, Button, Breadcrumbs, Link, Card, CardContent, CardMedia, } from '@mui/material'; import { ArrowBack as ArrowBackIcon, Download as DownloadIcon, Visibility as VisibilityIcon, } from '@mui/icons-material'; import knowledgeService from '@/services/knowledge_service'; import type { IKnowledge, IKnowledgeFile } from '@/interfaces/database/knowledge'; interface DocumentPreviewProps {} function DocumentPreview(props: DocumentPreviewProps) { const { kb_id, doc_id } = useParams<{ kb_id: string; doc_id: string }>(); const navigate = useNavigate(); const [kb, setKb] = useState(null); const [documentObj, setDocumentObj] = useState(null); const [documentFile, setDocumentFile] = useState(null); const [fileUrl, setFileUrl] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [fileLoading, setFileLoading] = useState(false); // 获取知识库和文档信息 useEffect(() => { const fetchData = async () => { if (!kb_id || !doc_id) { setError('缺少必要的参数'); setLoading(false); return; } try { setLoading(true); // 并行获取知识库信息和文档详情 const [kbResponse, docResponse] = await Promise.all([ knowledgeService.getKnowledgeDetail({ kb_id }), knowledgeService.getDocumentInfos({ doc_ids: [doc_id] }) ]); if (kbResponse.data.data) { setKb(kbResponse.data.data); } if (docResponse.data.data?.length > 0) { setDocumentObj(docResponse.data.data[0]); } } catch (err) { console.error('获取数据失败:', err); setError('获取数据失败,请稍后重试'); } finally { setLoading(false); } }; fetchData(); }, [kb_id, doc_id]); // 异步加载文档文件 const loadDocumentFile = async () => { if (!doc_id || fileLoading) return; try { setFileLoading(true); setError(null); const fileResponse = await knowledgeService.getDocumentFile({ doc_id }); if (fileResponse.data instanceof Blob) { setDocumentFile(fileResponse.data); const url = URL.createObjectURL(fileResponse.data); setFileUrl(url); } else { setError('文件格式不支持预览'); } } catch (err) { console.error('获取文档文件失败:', err); setError('获取文档文件失败,请稍后重试'); } finally { setFileLoading(false); } }; // 清理文件URL useEffect(() => { return () => { if (fileUrl) { URL.revokeObjectURL(fileUrl); } }; }, [fileUrl]); // 下载文件 const handleDownload = () => { if (fileUrl && window.document) { const link = window.document.createElement('a'); link.href = fileUrl; link.download = documentObj?.name || 'document'; window.document.body.appendChild(link); link.click(); window.document.body.removeChild(link); } }; // 返回上一页 const handleGoBack = () => { navigate(-1); }; // 渲染文件预览 const renderFilePreview = () => { if (!documentFile || !fileUrl) return null; const fileType = documentFile.type; if (fileType.startsWith('image/')) { return ( ); } else if (fileType === 'application/pdf') { return ( ); } else if (fileType.startsWith('text/')) { return ( ); } else { return ( 此文件类型不支持在线预览,请下载后查看。 ); } }; if (loading) { return ( ); } if (error && !documentObj) { return ( {error} ); } return ( {/* 面包屑导航 */} navigate('/knowledge')} sx={{ textDecoration: 'none' }} > 知识库 navigate(`/knowledge/${kb_id}`)} sx={{ textDecoration: 'none' }} > {kb?.name || '知识库详情'} navigate(`/knowledge/${kb_id}/document/${doc_id}/chunks`)} sx={{ textDecoration: 'none' }} > 文档分块 文件预览 {/* 页面标题和操作按钮 */} 文件预览 {documentObj && ( {documentObj.name} )} {!fileUrl && ( )} {fileUrl && ( )} {/* 错误提示 */} {error && ( {error} )} {/* 文件加载状态 */} {fileLoading && ( 正在加载文件... )} {/* 文件预览区域 */} {fileUrl && ( {renderFilePreview()} )} ); } export default DocumentPreview;