/** * 文件预览组件 * 显示文档内容和评查点高亮 */ import { useState, useEffect, useRef } from 'react'; // 定义评查点类型 interface ReviewPoint { id: string; title: string; status: string; content: string; suggestion: string; position?: { section: string; index: number; }; } // 定义文档内容类型 interface FileContent { title: string; contractNumber: string; parties: { partyA: { name: string; address: string; representative: string; phone: string; }; partyB: { name: string; address: string; representative: string; phone: string; }; }; sections: { title: string; content: string; }[]; } interface FilePreviewProps { fileContent: FileContent; reviewPoints: ReviewPoint[]; activeReviewPointId: string | null; } export function FilePreview({ fileContent, reviewPoints, activeReviewPointId }: FilePreviewProps) { const [zoomLevel, setZoomLevel] = useState(100); const [highlightsVisible, setHighlightsVisible] = useState(true); const contentRef = useRef(null); // 放大文档 const handleZoomIn = () => { if (zoomLevel < 200) { setZoomLevel(prevZoom => prevZoom + 10); } }; // 缩小文档 const handleZoomOut = () => { if (zoomLevel > 50) { setZoomLevel(prevZoom => prevZoom - 10); } }; // 切换高亮显示 const toggleHighlights = () => { setHighlightsVisible(!highlightsVisible); }; // 当选中的评查点变化时,滚动到对应位置 useEffect(() => { if (activeReviewPointId && contentRef.current) { const highlightElement = contentRef.current.querySelector(`[data-review-id="${activeReviewPointId}"]`); if (highlightElement) { highlightElement.scrollIntoView({ behavior: 'smooth', block: 'center' }); // 添加临时突出显示效果 highlightElement.classList.add('highlight-focus'); setTimeout(() => { highlightElement.classList.remove('highlight-focus'); }, 1500); } } }, [activeReviewPointId]); // 获取评查点对应的样式类 const getHighlightClass = (status: string) => { switch (status) { case 'warning': return 'warning'; case 'error': return 'error'; case 'success': return 'success'; default: return 'warning'; } }; // 渲染文档内容 const renderDocumentContent = () => { return (

{fileContent.title}

合同编号:{fileContent.contractNumber}

甲方(供方):{fileContent.parties.partyA.name}

地址:{fileContent.parties.partyA.address}

法定代表人:{fileContent.parties.partyA.representative}

联系电话:{fileContent.parties.partyA.phone}

 

乙方(需方):{fileContent.parties.partyB.name}

地址:{fileContent.parties.partyB.address}

法定代表人:{fileContent.parties.partyB.representative}

联系电话:{fileContent.parties.partyB.phone}

根据《中华人民共和国合同法》及有关法律法规的规定,经双方协商一致,签订本合同,共同遵守。

{fileContent.sections.map((section, sectionIndex) => (

{section.title}

{renderSectionContent(section.content, section.title, sectionIndex)}
))}
); }; // 渲染章节内容,处理高亮 const renderSectionContent = (content: string, sectionTitle: string, sectionIndex: number) => { const lines = content.split('\n'); return lines.map((line, lineIndex) => { // 查找该行对应的评查点 const reviewPoint = reviewPoints.find(point => point.position && point.position.section === sectionTitle && point.position.index === lineIndex ); if (reviewPoint && highlightsVisible) { // 如果有对应的评查点,添加高亮 const isActive = reviewPoint.id === activeReviewPointId; return (

{line}

); } else { // 没有评查点,正常显示 return

{line}

; } }); }; return (
文件预览
{renderDocumentContent()}
); }