/** * 评查详情页面 * * 功能概述: * - 显示文档评查结果和详细信息 * - 支持查看文档内容及评查点高亮标记 * - 提供评查点列表,分为通过、警告和错误三种类型 * - 支持评查点处理,如一键替换、人工审核等功能 * - 支持导出评查报告和下载原文件 * * 组件结构: * - FileInfo: 显示文件基本信息和操作按钮 * - ReviewTabs: 页面选项卡,包括评查结果、AI智能分析和文件信息 * - FilePreview: 文档预览组件,显示文档内容及高亮问题 * - ReviewPointsList: 评查点列表组件,显示所有评查结果 * - AIAnalysis: AI智能分析结果,提供综合评价 * - FileDetails: 文件详情信息 * * 数据流转: * 1. 页面加载时从API获取评查详情数据 * 2. 根据评查点ID关联文档中的高亮区域 * 3. 点击评查点时在文档中定位对应位置 * 4. 处理评查点时更新状态并反馈到UI * * @author 中国烟草AI合同及卷宗审核系统开发团队 */ import { type MetaFunction } from "@remix-run/node"; import { useState, useEffect } from "react"; import { useNavigate } from "@remix-run/react"; import reviewsStyles from "~/styles/reviews.css?url"; // 导入评查详情页面组件 import { FileInfo, ReviewTabs, FilePreview, ReviewPointsList, AIAnalysis, FileDetails } from "~/components/reviews"; // 定义评查点类型 interface ReviewPoint { id: string; title: string; location: string; status: string; content: string; suggestion: string; needsHumanReview?: boolean; humanReviewNote?: string; humanReviewBy?: string; humanReviewTime?: string; position?: { section: string; index: number; }; } // 定义统计数据类型 interface Statistics { total: number; success: number; warning: number; error: number; score: number; } // 定义文件信息类型 interface FileInfo { fileName: string; contractNumber: string; fileSize: string; fileFormat: string; pageCount: number; uploadTime: string; uploadUser: string; } // 定义合同信息类型 interface ContractInfo { contractType: string; signDate: string; parties: { partyA: string; partyB: string; }; amount: string; period: string; } // 定义评查信息类型 interface ReviewInfo { reviewTime: string; reviewModel: string; ruleGroup: string; result: string; issueCount: 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 AnalysisItem { title: string; content: string; description: string; } // 定义分析数据类型 interface AnalysisData { riskAlerts: AnalysisItem[]; suggestions: AnalysisItem[]; summary: string; } // 定义评查数据类型 interface ReviewData { fileInfo: FileInfo; contractInfo: ContractInfo; reviewInfo: ReviewInfo; statistics: Statistics; fileContent: FileContent; reviewPoints: ReviewPoint[]; aiAnalysis: AnalysisData; } export const meta: MetaFunction = () => { return [ { title: "评查详情 - 中国烟草AI合同及卷宗审核系统" }, { name: "description", content: "查看文档评查结果,处理问题点,确认评查结果" } ]; }; export function links() { return [{ rel: "stylesheet", href: reviewsStyles }]; } export const handle = { breadcrumb: "评查详情" }; export default function ReviewDetails() { const navigate = useNavigate(); const [isLoading, setIsLoading] = useState(true); const [activeTab, setActiveTab] = useState('preview'); // 'preview', 'analysis', 'fileinfo' const [reviewData, setReviewData] = useState(null); const [activeReviewPointId, setActiveReviewPointId] = useState(null); // 模拟获取评查数据 useEffect(() => { // 模拟API请求延迟 const timer = setTimeout(() => { // 模拟评查数据 const mockData = getMockReviewData(); setReviewData(mockData); setIsLoading(false); // 默认选中第一个评查点 if (mockData.reviewPoints.length > 0) { setActiveReviewPointId(mockData.reviewPoints[0].id); } }, 800); return () => clearTimeout(timer); }, []); const handleTabChange = (tabKey: string) => { setActiveTab(tabKey); }; const handleReviewPointSelect = (reviewPointId: string) => { setActiveReviewPointId(reviewPointId); }; const handleReviewPointStatusChange = (reviewPointId: string, newStatus: string) => { // 更新评查点状态 if (reviewData) { const updatedReviewPoints = reviewData.reviewPoints.map(point => point.id === reviewPointId ? { ...point, status: newStatus } : point ); setReviewData({ ...reviewData, reviewPoints: updatedReviewPoints, statistics: calculateStatistics(updatedReviewPoints) }); } }; const handleConfirmResults = () => { alert('评查结果已确认'); navigate('/reviews'); // 假设评查列表页面路径为 /reviews }; return (
{isLoading ? (
加载中...
) : reviewData && ( <> {/* 文件信息和操作按钮 */} {/* 选项卡 */} {/* 评查结果选项卡内容 */} {activeTab === 'preview' && (
{/* 左侧:文件预览 */}
{/* 右侧:评查结果 */}
)} {/* AI智能分析选项卡内容 */} {activeTab === 'analysis' && ( )} {/* 文件信息选项卡内容 */} {activeTab === 'fileinfo' && ( )}
)}
); } // 计算评查统计数据 function calculateStatistics(reviewPoints: ReviewPoint[]): Statistics { const total = reviewPoints.length; const success = reviewPoints.filter(point => point.status === 'success').length; const warning = reviewPoints.filter(point => point.status === 'warning').length; const error = reviewPoints.filter(point => point.status === 'error').length; // 计算评分:通过占总数的百分比,错误项有额外惩罚 const score = Math.round((success / total) * 100 - (error * 5)); return { total, success, warning, error, score: Math.max(0, Math.min(100, score)) // 确保分数在0-100之间 }; } // 模拟评查数据 function getMockReviewData(): ReviewData { return { fileInfo: { fileName: "烟草产品销售合同(2023版).docx", contractNumber: "XS-2023-1025-001", fileSize: "5.2MB", fileFormat: "DOCX", pageCount: 5, uploadTime: "2023-10-25 14:30:45", uploadUser: "张三" }, contractInfo: { contractType: "销售合同", signDate: "2023年10月20日", parties: { partyA: "XX烟草公司", partyB: "YY贸易有限公司" }, amount: "¥ 1,580,000.00", period: "2023年11月1日至2024年10月31日" }, reviewInfo: { reviewTime: "2023-10-25 14:35:12", reviewModel: "DeepSeek", ruleGroup: "合同标准规则组", result: "warning", issueCount: 9 }, statistics: { total: 15, success: 6, warning: 7, error: 2, score: 75 }, fileContent: { title: "烟草产品销售合同", contractNumber: "XS-2023-1025-001", parties: { partyA: { name: "XX烟草公司", address: "XX省XX市XX区XX路XX号", representative: "张XX", phone: "123-4567-8901" }, partyB: { name: "YY贸易有限公司", address: "XX省XX市XX区YY路YY号", representative: "李YY", phone: "123-4567-8902" } }, sections: [ { title: "总则", content: "1.1 本合同适用于甲乙双方之间的烟草制品买卖事宜。\n1.2 双方应本着平等互利、诚实信用的原则履行本合同。" }, { title: "合同标的物", content: "2.1 产品名称:烟草制品\n2.2 规格型号:如附件所列\n2.3 数量:5000箱\n2.4 质量要求:符合国家标准GB/T XXXXX-XXXX" }, { title: "交货与付款", content: "3.1 交货时间:自合同签订之日起30日内。\n3.2 乙方应在收到货物之日起5个工作日内支付合同款项,甲方应在收到乙方全部付款后开具增值税专用发票,乙方应在收到发票后支付剩余款项。\n3.3 交货地点:乙方指定的仓库。\n3.4 运输方式:陆运,运费由甲方承担。" }, { title: "合同文本", content: "本合同一式两份,甲乙双方各执一份,具有同等法律效力。" } ] }, reviewPoints: [ { id: "1", title: "付款条件描述不明确", location: "付款条款清晰性", status: "error", content: "乙方应在收到货物之日起5个工作日内支付合同款项,甲方应在收到乙方全部付款后开具增值税专用发票,乙方应在收到发票后支付剩余款项。", suggestion: "乙方应在收到货物验收合格之日起5个工作日内支付合同总额的70%,甲方收到该部分款项后3个工作日内向乙方开具等额增值税专用发票;乙方应在收到发票之日起5个工作日内支付剩余30%款项。", position: { section: "交货与付款", index: 2 } }, { id: "2", title: "违约责任条款缺失", location: "合同权利义务对等性", status: "warning", content: "如合同发生纠纷,双方应协商解决。", suggestion: "如合同发生纠纷,双方应友好协商解决;协商不成的,任何一方均有权向甲方所在地人民法院提起诉讼。任何一方未能履行本合同约定义务,应向守约方支付合同总金额的10%作为违约金;给对方造成损失的,还应赔偿由此产生的全部损失。", position: { section: "争议解决", index: 0 } }, { id: "3", title: "签章不完整", location: "合同签署规范性", status: "warning", content: "乙方(盖章):YY贸易有限公司\n代表人签字:李YY\n日期:2023年10月20日", suggestion: "需要联系甲方补充公章", needsHumanReview: true, humanReviewNote: "需要联系甲方补充公章", position: { section: "签章", index: 0 } }, { id: "9", title: "交货方式描述模糊", location: "履行条款明确性", status: "success", content: "3.4 运输方式:陆运,运费由甲方承担。", suggestion: "建议补充具体的运输方式和时间", needsHumanReview: true, humanReviewNote: "经核实,该交货方式虽然描述不够详细,但符合行业惯例且双方已经多次合作,不会造成实际履行障碍。", humanReviewBy: "王法务", humanReviewTime: "2023-11-05 14:30:22", position: { section: "交货与付款", index: 4 } }, { id: "10", title: "法律适用条款缺失", location: "争议解决条款完整性", status: "error", content: "", suggestion: "第十三条 法律适用\n本合同的订立、效力、解释、履行及争议的解决均适用中华人民共和国法律。因本合同引起的或与本合同有关的任何争议,双方应友好协商解决。协商不成的,提交甲方所在地人民法院诉讼解决。", position: { section: "缺失", index: 0 } } ], aiAnalysis: { riskAlerts: [ { title: "风险提示", content: "本合同缺少违约责任条款,可能导致权责不明。", description: "根据《中华人民共和国民法典》第五百七十七条规定,建议增加违约责任条款,明确双方违约责任及赔偿方式。" }, { title: "完整性检查", content: "本合同缺少法律适用条款。", description: "根据行业惯例,销售合同应明确约定适用法律和纠纷解决方式,以避免后续争议解决时的不确定性。" } ], suggestions: [ { title: "优化建议", content: "建议完善付款条件描述。", description: "目前合同中关于付款条件的描述存在歧义,可能导致付款时间和条件不明确。建议按系统修改建议优化。" } ], summary: "本合同基本结构完整,主体内容清晰,但存在多处条款描述不完善的问题,主要体现在支付条件、违约责任、不可抗力、保密条款、合同终止条件等方面。这些问题虽不影响合同的基本合规性,但可能在合同履行过程中引发争议和纠纷。同时,合同签章不完整,也影响了合同的法律效力。建议对上述问题进行修改完善后再行签署。" } }; }