diff --git a/app/api/evaluation_points/reviews.ts b/app/api/evaluation_points/reviews.ts index d5616fa..32749a4 100644 --- a/app/api/evaluation_points/reviews.ts +++ b/app/api/evaluation_points/reviews.ts @@ -33,6 +33,10 @@ interface EvaluationResult { data?: string; [key: string]: unknown; }; + evaluated_point_results_log?: { + rules?: unknown[]; + [key: string]: unknown; + }; [key: string]: unknown; } @@ -73,7 +77,8 @@ interface ReviewPointResult { suggestion: string; result?: boolean; score: number; - evaluatedPointResultsLog?: Array>; + // evaluatedPointResultsLog: Record>>; + evaluatedPointResultsLog: Record; } // 定义统计数据类型 @@ -244,7 +249,7 @@ export async function getReviewPoints(fileId: string) { const editAuditStatus = editAuditStatusMap.get(result.evaluation_point_id) || {id: '', status: 0}; // 评查结果内容改成由evaluated_point_results_log中获取 - // const evaluatedPointResultsLog = result.evaluated_point_results_log; + const evaluatedPointResultsLog = result.evaluated_point_results_log || {}; // console.log('evaluatedPointResultsLog-------', evaluatedPointResultsLog); @@ -293,192 +298,254 @@ export async function getReviewPoints(fileId: string) { } return { - id: result.id, - documentId: fileId, - pointId: point.id, - editAuditStatusId: editAuditStatus.id, - editAuditStatus: editAuditStatus.status, - title: message, - pointName: point.name || '', - groupName: group.name || '', + id: result.id, + documentId: fileId, + pointId: point.id, + editAuditStatusId: editAuditStatus.id, + editAuditStatus: editAuditStatus.status, + title: message, + pointName: point.name || '', + groupName: group.name || '', - status: point.suggestion_message_type || '', //评查点的评查结果状态 - // status: 'error', //评查点的评查结果状态 + status: point.suggestion_message_type || '', //评查点的评查结果状态 + // status: 'error', //评查点的评查结果状态 - content: data, + content: data, - contentPage: contentPage, + contentPage: contentPage, - suggestion: point.suggestion_message || '', - // suggestion: '只是给建议的修改内容', + suggestion: point.suggestion_message || '', + // suggestion: '只是给建议的修改内容', - result: result.evaluated_results?.result, // 记录评查结果,用于统计 - score: point.score || 0, + result: result.evaluated_results?.result, // 记录评查结果,用于统计 + score: point.score || 0, - postAction: point.post_action || '', - // postAction: 'manual', + postAction: point.post_action || '', + // postAction: 'manual', - actionContent: point.action_config || '', - // actionContent: '用户提前在评查点输入过的修改内容', + actionContent: point.action_config || '', + // actionContent: '用户提前在评查点输入过的修改内容', - legalBasis: point.references_laws || {}, - // legalBasis: { - // name: '中华人民共和国食品安全法', - // content: '中华人民共和国食品安全法', - // article: [ - // { - // name: '中华人民共和国食品安全法', - // content: '中华人民共和国食品安全法' - // } - // ] - // } + legalBasis: point.references_laws || {}, + // legalBasis: { + // name: '中华人民共和国食品安全法', + // content: '中华人民共和国食品安全法', + // article: [ + // { + // name: '中华人民共和国食品安全法', + // content: '中华人民共和国食品安全法' + // } + // ] + // } - // 评查配置: point.evaluation_config - evaluationConfig: point.evaluation_config || {}, + // 评查配置: point.evaluation_config + evaluationConfig: point.evaluation_config || {}, - // evaluatedPointResultsLog: evaluatedPointResultsLog || {} - evaluatedPointResultsLog: [ - { - "id": "1", - "type": "consistency", - "config": { - "logic": "and", - "pairs": [ - { - "sourceField": {"a":{page: 1,value: '张三'}}, - "targetField": {"b":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"b":{page: 1,value: '张三'}}, - "targetField": {"c":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": false - }, - { - "sourceField": {"c":{page: 1,value: '张三'}}, - "targetField": {"d":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"d":{page: 1,value: '张三'}}, - "targetField": {"e":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-被检查人名称":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-目录-名称":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-法定代表人(负责人)":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-烟草专卖许可证号码":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-烟草专卖零售许可证-许可证号":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"证据复制(提取)单-烟草专卖零售许可证-企业名称":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三拉萨看得见佛i啊是觉得离开房间啊善良的是的链接发了上帝就发垃圾袋的时间佛爱上立刻就阿拉山口大家分厘卡即使灯笼裤飞机啊顺利打开解放拉萨酱豆腐立刻阿萨到了经历多空双方叫阿里的肌肤垃圾收到了看见螺丝钉解放了啊撒旦解放垃圾的等级分类教师劳动纠纷爱丽丝的开发教师的肌肤啊撒旦解放考虑进来阿斯兰的看法骄傲'}}, - "compareMethod": "exact", - "result": false - }, - { - "sourceField": {"证据复制(提取)单-烟草专卖零售许可证-负责人姓名":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-单位-名称":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-单位-法定代表人(负责人)":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-单位-地址":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-营业执照-住所":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - } - ], - "selectedFields": [] - } - }, - { - "id": "2", - "type": "consistency", - "config": { - "logic": "and", - "pairs": [ - { - "sourceField": {"现场笔录-被检查人姓名":{page: 1,value: '张三'}}, - "targetField": {"立案报告表-当事人-个人(个体工商户)-姓名":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-个人(个体工商户)-姓名":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-居民身份证-姓名":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-性别":{page: 1,value: '张三'}}, - "targetField": {"立案报告表-当事人-个人(个体工商户)-性别":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-个人(个体工商户)-性别":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-居民身份证-性别":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-证件类型及号码":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-居民身份证-公民身份号码":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"现场笔录-地址":{page: 1,value: '张三'}}, - "targetField": {"立案报告表-当事人-个人(个体工商户)-住址":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - }, - { - "sourceField": {"立案报告表-当事人-个人(个体工商户)-住址":{page: 1,value: '张三'}}, - "targetField": {"证据复制(提取)单-居民身份证-住址":{page: 1,value: '张三'}}, - "compareMethod": "exact", - "result": true - } - ], - "selectedFields": [] - } - } - ] + evaluatedPointResultsLog: evaluatedPointResultsLog || {} + // evaluatedPointResultsLog: { + // rules:[ + // { + // "id": "1", + // "type": "consistency", + // "config": { + // "logic": "and", + // "pairs": [ + // { + // "sourceField": {"a":{page: 1,value: '张三拉萨看得见佛i啊是觉得离开房间啊善良的是的链接发了上帝就发垃圾袋的时间佛爱上立刻就阿拉山口大家分厘卡即使灯笼裤飞机啊顺利打开解放拉萨酱豆腐立刻阿萨到了经历多空双方叫阿里的肌肤垃圾收到了看见螺丝钉解放了啊撒旦解放垃圾的等级分类教师劳动纠纷爱丽丝的开发教师的肌肤啊撒旦解放考虑进来阿斯兰的看法骄傲'}}, + // "targetField": {"b":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"b":{page: 1,value: '张三'}}, + // "targetField": {"c":{page: 1,value: '张三拉萨看得见佛i啊是觉得离开房间啊善良的是的链接发了上帝就发垃圾袋的时间佛爱上立刻就阿拉山口大家分厘卡即使灯笼裤飞机啊顺利打开解放拉萨酱豆腐立刻阿萨到了经历多空双方叫阿里的肌肤垃圾收到了看见螺丝钉解放了啊撒旦解放垃圾的等级分类教师劳动纠纷爱丽丝的开发教师的肌肤啊撒旦解放考虑进来阿斯兰的看法骄傲'}}, + // "compareMethod": "exact", + // "res": false + // }, + // { + // "sourceField": {"c":{page: 1,value: '张三'}}, + // "targetField": {"d":{page: 1,value: '张三'}}, + // "compareMethod": "contains", + // "res": true + // }, + // { + // "sourceField": {"d":{page: 1,value: '张三'}}, + // "targetField": {"e":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"现场笔录-被检查人名称":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-目录-名称":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"现场笔录-法定代表人(负责人)":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"现场笔录-烟草专卖许可证号码":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-烟草专卖零售许可证-许可证号":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"证据复制(提取)单-烟草专卖零售许可证-企业名称":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三拉萨看得见佛i啊是觉得离开房间啊善良的是的链接发了上帝就发垃圾袋的时间佛爱上立刻就阿拉山口大家分厘卡即使灯笼裤飞机啊顺利打开解放拉萨酱豆腐立刻阿萨到了经历多空双方叫阿里的肌肤垃圾收到了看见螺丝钉解放了啊撒旦解放垃圾的等级分类教师劳动纠纷爱丽丝的开发教师的肌肤啊撒旦解放考虑进来阿斯兰的看法骄傲'}}, + // "compareMethod": "exact", + // "res": false + // }, + // { + // "sourceField": {"证据复制(提取)单-烟草专卖零售许可证-负责人姓名":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"立案报告表-当事人-单位-名称":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-名称":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"立案报告表-当事人-单位-法定代表人(负责人)":{page: 1,value: '张三拉萨看得见佛i啊是觉得离开房间啊善良的是的链接发了上帝就发垃圾袋的时间佛爱上立刻就阿拉山口大家分厘卡即使灯笼裤飞机啊顺利打开解放拉萨酱豆腐立刻阿萨到了经历多空双方叫阿里的肌肤垃圾收到了看见螺丝钉解放了啊撒旦解放垃圾的等级分类教师劳动纠纷爱丽丝的开发教师的肌肤啊撒旦解放考虑进来阿斯兰的看法骄傲'}}, + // "targetField": {"证据复制(提取)单-营业执照-法定代表人":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // }, + // { + // "sourceField": {"立案报告表-当事人-单位-地址":{page: 1,value: '张三'}}, + // "targetField": {"证据复制(提取)单-营业执照-住所":{page: 1,value: '张三'}}, + // "compareMethod": "exact", + // "res": true + // } + // ], + // "selectedFields": [] + // } + // }, + // { + // "id": "2", + // "type": "exists", + // "config": { + // "logic": "all", + // "res": true, + // "fields": { + // "证据先行登记保存批准书-负责人意见并签名-时间": {page: 1,value: ''}, + // "证据先行登记保存批准书-负责人意见并签名-签名": {page: 2,value: '有无判断类型'} + // }, + // } + // }, + // { + // "id": "3", + // "type": "exists", + // "config": { + // "logic": "all", + // "res": false, + // "fields": { + // "证据先行登记-负责人意见并签名-时间": {page: 1,value: ''}, + // "证据先行登记-负责人意见并签名-签名": {page: 2,value: '有无判断类型'} + // }, + // } + // }, + // { + // "id": "4", + // "type": "logic", + // "config": { + // "logic": "all", + // "conditions": [ + // { + // "field": { + // "送达回证-送达方式": { + // "page": 5, + // "value": "逻辑判断" + // } + // }, + // "value": "直接送达", + // "operator": "eq", + // "res": true + // }, + // { + // "field": { + // "犯罪证据-犯罪方式": { + // "page": 6, + // "value": "逻辑判断" + // } + // }, + // "value": "直接送达", + // "operator": "eq", + // "res": false + // } + // ], + // "selectedFields": [] + // } + // }, + // { + // "id": "5", + // "type": "regex", + // "config": { + // "res": true, + // "field": { + // "广东省没收、收缴、追缴财务收据-标题":{ + // page: 1,value: 'asdasdasd' + // } + // }, + // "pattern": "^(.*广东省没收.*财务收据.*)", + // "matchType": "match", + // "selectedFields": [] + // } + // }, + // { + // "id": "6", + // "type": "format", + // "config": { + // "field": { + // "广东省没收、收缴、追缴财务收据-标题": { + // "value": "", + // "page": 8 + // } + // }, + // "formatType": "date", + // "parameters": "YYYY-MM-DD", + // "selectedFields": [], + // "res": false + // } + // }, + // { + // "id": "7", + // "type": "ai", + // "config": { + // "res": false, + // "model": "qwen14b", + // "fields": { + // "涉案物件核价表-涉案物品价格-品种规格、单价": { + // "page": 1, + // "value": "规则和单价你都无法想象" + // }, + // "涉案物件核价表-涉案物品种": { + // "page": 1, + // "value": "什么都有" + // }, + // "涉案物件核价表-涉案": { + // "page": 19, + // "value": "" + // } + // }, + // "prompt": "请判断以下{涉案物件核价表-涉案物品价格-品种规格、单价}各品种规格的数量、单价计算的合计金额是否正确,各品种规格合计金额计算总计金额是否正确,仅回答\"符合\"或\"不符合\",并简要说明理由。", + // "message": "缺少字段: 涉案物件核价表-涉案物品价格-品种规格、单价", + // "temperature": 0.1, + // "selectedFields": [] + // } + // } + // ]} }; }); diff --git a/app/components/reviews/ReviewPointsList.tsx b/app/components/reviews/ReviewPointsList.tsx index 3309bd3..44d5ce2 100644 --- a/app/components/reviews/ReviewPointsList.tsx +++ b/app/components/reviews/ReviewPointsList.tsx @@ -21,6 +21,29 @@ import { useState, useEffect } from 'react'; import { toastService } from '../ui/Toast'; // import { toastService } from '../ui/Toast'; +/** + * 比较方法映射 + * 将后端返回的比较方法英文值映射为友好的中文显示 + */ +const compareMethodMap: Record = { + 'exact': '精确匹配', + 'contains': '包含关系', + 'semantic': '大模型语义匹配', + // 可以根据需要添加更多映射 +}; + +/** + * 获取比较方法的中文显示 + * @param method 比较方法的原始值 + * @returns 映射后的中文显示文本 + */ +const getCompareMethodText = (method?: string): string => { + if (!method) return '相等'; + const text = compareMethodMap[method] || method; + // 确保返回的是字符串类型 + return typeof text === 'string' ? text : String(text); +}; + /** * 评查点类型定义 * 用于展示单个评查结果 @@ -65,7 +88,13 @@ export interface ReviewPoint { }; }>; }; - evaluatedPointResultsLog?: Array>; + evaluatedPointResultsLog?: { + rules: Array<{ + id: string; + type: string; + config: Record; + }>; + }; } // 统计数据类型 @@ -77,6 +106,13 @@ interface Statistics { score: number; } +// 统一规则的类型 +// interface pointRule { +// id: string; +// type: string; +// config: Record; +// } + interface ReviewPointsListProps { reviewPoints: ReviewPoint[]; statistics: Statistics; @@ -102,6 +138,9 @@ export function ReviewPointsList({ // 添加重新审核意见的状态/ 用户输入的修改内容 / 用户提前写好的修改内容 const [manualReviewNotes, setManualReviewNotes] = useState>({}); + // 存放属于有无判断,格式判断,逻辑判断,正则表达式这一类的评查点规则设置 + // const [otherRule, setOtherRule] = useState[]>([]); + // 初始化建议文本 useEffect(() => { // 将所有评查点的建议文本存储到状态中 @@ -434,320 +473,135 @@ export function ReviewPointsList({ * @param reviewPoint 评查点 * @returns 人工审核注释组件 */ - const renderHumanReviewNote = (reviewPoint: ReviewPoint) => { - // 目前needsHumanReview和humanReviewNote都为空,所以不显示 - if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { - return ( -
- {reviewPoint.humanReviewNote} - {reviewPoint.humanReviewBy && reviewPoint.humanReviewTime && ( -
- 审核人:{reviewPoint.humanReviewBy} | 时间:{reviewPoint.humanReviewTime} -
- )} -
- ); - } - return null; - }; + // const renderHumanReviewNote = (reviewPoint: ReviewPoint) => { + // // 目前needsHumanReview和humanReviewNote都为空,所以不显示 + // if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { + // return ( + //
+ // {reviewPoint.humanReviewNote} + // {reviewPoint.humanReviewBy && reviewPoint.humanReviewTime && ( + //
+ // 审核人:{reviewPoint.humanReviewBy} | 时间:{reviewPoint.humanReviewTime} + //
+ // )} + //
+ // ); + // } + // return null; + // }; /** * 渲染评查点主要内容 * @param reviewPoint 评查点 * @returns 评查点主要内容组件 */ - const renderContent = (reviewPoint: ReviewPoint, result?: boolean) => { - // 获取evaluationConfig中type为consistency的规则 评查点一致性规则组的规则 - const consistencyRules = reviewPoint.evaluationConfig?.rules?.filter(rule => rule.type === 'consistency') || []; - - // 获取所有consistency规则中的fields - const allConsistencyFields: string[][] = []; - - // 存储 sourceField 和 targetField 的映射关系 - const pairsMapping: Record = {}; - - consistencyRules.forEach(rule => { - if (rule.config?.fields) { - allConsistencyFields.push(rule.config.fields); - } else if (rule.config?.pairs) { - // 处理pairs情况,提取sourceField和targetField - const fields: string[] = []; - rule.config.pairs.forEach(pair => { - if (pair.sourceField) fields.push(pair.sourceField); - if (pair.targetField) fields.push(pair.targetField); - - // 记录 sourceField 和 targetField 的映射关系 - if (pair.sourceField && pair.targetField) { - pairsMapping[pair.sourceField] = pair.targetField; - } - }); - if (fields.length > 0) { - allConsistencyFields.push(fields); - } - } - }); - - // 对content进行排序 - const contentEntries = Object.entries(reviewPoint.content); - - // 按照consistency规则分组 - const groupedContent: Record> = { - 'default': [] // 默认组,存放不属于任何consistency规则的项 - }; - - // 为每个consistency规则创建分组 - allConsistencyFields.forEach((fields, index) => { - groupedContent[`consistency_${index}`] = []; - }); - - // 将content按照规则分组 - contentEntries.forEach(entry => { - const [key] = entry; - - // 检查是否属于某个consistency规则 - let assigned = false; - allConsistencyFields.forEach((fields, index) => { - if (fields.includes(key)) { - groupedContent[`consistency_${index}`].push(entry); - assigned = true; - } - }); - - // 如果不属于任何规则,放入默认组 - if (!assigned) { - groupedContent['default'].push(entry); - } - }); - - // 对每个分组内的条目按照 sourceField 和 targetField 的关系进行排序 - Object.keys(groupedContent).forEach(groupKey => { - if (groupKey !== 'default' && groupedContent[groupKey].length > 1) { - // 创建一个新数组用于存储排序后的结果 - const sortedEntries: Array<[string, { page?: number | string, value?: object }]> = []; - const entriesMap = new Map(groupedContent[groupKey]); - - // 找出所有的源字段和目标字段对 - const processed = new Set(); - - // 构建一个字段之间的连接关系图,用于处理嵌套关系 - const fieldChains: Array = []; - - // 遍历所有映射关系,构建字段链 - const buildFieldChains = () => { - // 创建一个图结构,记录每个字段的后继字段 - const graph: Record = {}; - - // 根据映射关系建立图 - Object.entries(pairsMapping).forEach(([source, target]) => { - if (!graph[source]) graph[source] = []; - graph[source].push(target); - - // 确保目标字段在图中有一个空数组 - if (!graph[target]) graph[target] = []; - }); - - // 查找所有在当前分组中的字段 - const fieldsInGroup = new Set(Array.from(entriesMap.keys())); - - // 找出入度为0的节点(即只作为sourceField而不是任何targetField的字段) - const startNodes: string[] = []; - for (const field of fieldsInGroup) { - // 检查该字段是否作为targetField存在 - const isTarget = Object.values(pairsMapping).includes(field); - // 如果该字段是sourceField但不是targetField,则为起始节点 - if (!isTarget && field in pairsMapping) { - startNodes.push(field); - } - } - - // 从每个起始节点开始,使用DFS构建字段链 - for (const startNode of startNodes) { - const chain: string[] = []; - const dfs = (node: string) => { - // 如果该节点不在当前分组中,则跳过 - if (!fieldsInGroup.has(node)) return; - - chain.push(node); - // 遍历所有后继节点 - for (const nextNode of graph[node] || []) { - dfs(nextNode); - } - }; - - dfs(startNode); - - // 如果链不为空,则添加到字段链列表中 - if (chain.length > 0) { - fieldChains.push(chain); - } - } - - // 处理环形依赖或没有入度为0的节点的情况 - // 找出未被处理的字段 - const processedInChains = new Set(fieldChains.flat()); - const remainingFields = Array.from(fieldsInGroup).filter(f => !processedInChains.has(f)); - - // 将剩余字段按照pairsMapping的关系组织成链 - while (remainingFields.length > 0) { - // !的作用是确保remainingFields.shift()不会返回undefined - const field = remainingFields.shift()!; - - // 如果该字段已经在某个链中,则跳过 - if (processedInChains.has(field)) continue; - - const chain: string[] = [field]; - processedInChains.add(field); - - // 向后查找链 - let currentField = field; - while (currentField in pairsMapping) { - const nextField = pairsMapping[currentField]; - // 如果下一个字段不在分组中或已处理,则中断 - if (!fieldsInGroup.has(nextField) || processedInChains.has(nextField)) break; - - chain.push(nextField); - processedInChains.add(nextField); - currentField = nextField; - - // 从剩余字段中移除 - const index = remainingFields.indexOf(nextField); - if (index !== -1) { - remainingFields.splice(index, 1); - } - } - - if (chain.length > 0) { - fieldChains.push(chain); - } - } - }; - - buildFieldChains(); - - // 根据字段链构建排序后的结果 - fieldChains.forEach(chain => { - chain.forEach(field => { - if (entriesMap.has(field) && !processed.has(field)) { - sortedEntries.push([field, entriesMap.get(field)!]); - processed.add(field); - } - }); - }); - - // 添加剩余未处理的字段 - for (const [key] of groupedContent[groupKey]) { - if (!processed.has(key)) { - sortedEntries.push([key, entriesMap.get(key)!]); - } - } - - // 用排序后的结果替换原数组 - groupedContent[groupKey] = sortedEntries; - } - }); - + const renderContent = (reviewPoint: ReviewPoint, otherRules: Array>) => { return ( <> - {/* 渲染各个分组 */} - {Object.entries(groupedContent).map(([groupKey, entries]) => { - if (entries.length === 0) return null; - - // 非默认组添加边框 - const isDefaultGroup = groupKey === 'default'; - - return ( -
- {/* 分组标题,只有非默认组显示 */} - {/* {!isDefaultGroup && ( -
- 规则组 {groupIndex} -
- )} */} - - {/* 渲染组内内容 */} - {entries.map(([key, value], index) => - !(result && value.value?.toString().trim() == '') && ( -
{ - e.stopPropagation(); - console.log(`单独点击${key}----`, reviewPoint); - const valuePage = parseInt(value.page as string); - const contentPage = parseInt(reviewPoint.contentPage?.[key] as string); - // 检查value中的page属性是否存在,优先取value中的page - if (valuePage > 0) { - console.log(`存在page且不为空:单独点击${key}---------->evaluated_results内的页码:`, valuePage); - onReviewPointSelect(reviewPoint.id, valuePage); - } else if(contentPage && contentPage > 0) { - console.log(`存在page且为空:单独点击${key}---------->ocr_result内的页码:`, contentPage); - onReviewPointSelect(reviewPoint.id, contentPage); - }else { - toastService.error(`无法找到"${key}"对应的索引内容`); - console.log(`单独点击${key}--------没有对应页码`); - } - }} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - e.preventDefault(); - const valuePage = parseInt(value.page as string); - const contentPage = parseInt(reviewPoint.contentPage?.[key] as string); - // 检查value中的page属性是否存在,优先取value中的page - if (valuePage > 0) { - onReviewPointSelect(reviewPoint.id, valuePage); - } else if(contentPage && contentPage > 0) { - onReviewPointSelect(reviewPoint.id, contentPage); - } else { - toastService.error(`无法找到"${key}"对应的索引内容`); - console.log(`单独点击${key}--------没有对应页码`); - } - } - }} - role="button" - tabIndex={0} - aria-label={`查看${key}内容详情`} - onMouseLeave={(e) => { - // 获取容器内的滚动区域元素 - const scrollContainer = e.currentTarget.querySelector('.text-container'); - if (scrollContainer) { - // 在文本缩回之前重置滚动位置 - scrollContainer.scrollTop = 0; - } - }} - > - {/*
*/} -
- - {key} - - - {parseInt(value.page as string)>0 || parseInt(reviewPoint.contentPage?.[key] as string)>0 ? '' : } - {value.value?.toString().trim() ? '' : '缺失'} - -
- -
-

- {(value.value?.toString().trim() === '') - ? "" - : value.value?.toString() || ''} -

-
-
- ))} -
- ); + {/* 渲染其他规则分组 */} + {otherRules.map((rule, index) => { + return
{renderOtherRule(rule, reviewPoint)}
; })} + +
+ {/* 渲染各个一致性的规则分组 */} + {reviewPoint.evaluatedPointResultsLog?.rules?.map((rule, index) => { + // console.log('rule-------', rule); + if (rule.type === 'consistency') { + // console.log('rule-------', rule); + return
{renderConsistencyRule(rule, reviewPoint)}
; + } + + if (rule.type === 'ai') { + return
{renderModelRule(rule, reviewPoint)}
; + } + + + // return ( + // <> + // {/* 渲染组内内容 */} + // {entries.map(([key, value], index) => + // !(result && value.value?.toString().trim() == '') && ( + //
{ + // e.stopPropagation(); + // console.log(`单独点击${key}----`, reviewPoint); + // const valuePage = parseInt(value.page as string); + // const contentPage = parseInt(reviewPoint.contentPage?.[key] as string); + // // 检查value中的page属性是否存在,优先取value中的page + // if (valuePage > 0) { + // console.log(`存在page且不为空:单独点击${key}---------->evaluated_results内的页码:`, valuePage); + // onReviewPointSelect(reviewPoint.id, valuePage); + + // } else if(contentPage && contentPage > 0) { + // console.log(`存在page且为空:单独点击${key}---------->ocr_result内的页码:`, contentPage); + // onReviewPointSelect(reviewPoint.id, contentPage); + // }else { + // toastService.error(`无法找到"${key}"对应的索引内容`); + // console.log(`单独点击${key}--------没有对应页码`); + // } + // }} + // onKeyDown={(e) => { + // if (e.key === 'Enter' || e.key === ' ') { + // e.preventDefault(); + // const valuePage = parseInt(value.page as string); + // const contentPage = parseInt(reviewPoint.contentPage?.[key] as string); + // // 检查value中的page属性是否存在,优先取value中的page + // if (valuePage > 0) { + // onReviewPointSelect(reviewPoint.id, valuePage); + // } else if(contentPage && contentPage > 0) { + // onReviewPointSelect(reviewPoint.id, contentPage); + // } else { + // toastService.error(`无法找到"${key}"对应的索引内容`); + // console.log(`单独点击${key}--------没有对应页码`); + // } + // } + // }} + // role="button" + // tabIndex={0} + // aria-label={`查看${key}内容详情`} + // onMouseLeave={(e) => { + // // 获取容器内的滚动区域元素 + // const scrollContainer = e.currentTarget.querySelector('.text-container'); + // if (scrollContainer) { + // // 在文本缩回之前重置滚动位置 + // scrollContainer.scrollTop = 0; + // } + // }} + // > + // {/*
*/} + //
+ // + // {key} + // + // + // {parseInt(value.page as string)>0 || parseInt(reviewPoint.contentPage?.[key] as string)>0 ? '' : } + // {value.value?.toString().trim() ? '' : '缺失'} + // + //
+ + //
+ //

+ // {(value.value?.toString().trim() === '') + // ? "" + // : value.value?.toString() || ''} + //

+ //
+ //
+ // ))} + // + // ); + })} + ); }; @@ -755,21 +609,21 @@ export function ReviewPointsList({ /** * 渲染评查点一致性的规则的样式 - * @param reviewPoint 评查点 + * @param singleReviewPoint 评查点 * @returns 评查点一致性的规则的样式 */ - const renderConsistencyRule = (singleReviewPoint: Record) => { + const renderConsistencyRule = (singleReviewPoint: Record,reviewPoint: ReviewPoint) => { if (!singleReviewPoint || Object.keys(singleReviewPoint).length === 0) { return null; } - + // console.log('singleReviewPoint-------', singleReviewPoint); // 检查是否存在配置和pairs数组 const config = singleReviewPoint.config as { logic?: string; pairs?: Array<{ sourceField: Record; targetField: Record; - result: boolean; + res: boolean; compareMethod?: string; }>; selectedFields?: string[] @@ -791,7 +645,8 @@ export function ReviewPointsList({ page: number; value: string }; - result: boolean + res: boolean; + compareMethod?: string; }; const chains: Array> = []; @@ -804,7 +659,7 @@ export function ReviewPointsList({ source: { key: string; page: number; value: string }; target: { key: string; page: number; value: string }; }; - result: boolean; + res: boolean; compareMethod?: string; }>>(); @@ -823,7 +678,7 @@ export function ReviewPointsList({ source: { key: sourceFieldKey, ...pair.sourceField[sourceFieldKey] }, target: { key: targetFieldKey, ...pair.targetField[targetFieldKey] } }, - result: pair.result, + res: pair.res, compareMethod: pair.compareMethod }); }); @@ -874,7 +729,8 @@ export function ReviewPointsList({ tempChain.push({ field: currentField, data: nextTarget.data.source, - result: nextTarget.result + res: nextTarget.res, + compareMethod: nextTarget.compareMethod }); } @@ -882,7 +738,8 @@ export function ReviewPointsList({ tempChain.push({ field: nextTarget.targetField, data: nextTarget.data.target, - result: nextTarget.result + res: nextTarget.res, + compareMethod: nextTarget.compareMethod }); // 标记为已访问 @@ -909,7 +766,7 @@ export function ReviewPointsList({ // 检查当前元素与前一个元素的连接是否为false // 当前元素为tempChain[i],前一个元素为tempChain[i-1] // 连接结果存储在当前元素(tempChain[i])的result中 - const connectionResult = tempChain[i].result; + const connectionResult = tempChain[i].res; // 如果连接为false,或已到达起始位置,拆分链条 if (!connectionResult) { @@ -965,12 +822,12 @@ export function ReviewPointsList({ { field: sourceFieldKey, data: { key: sourceFieldKey, ...pair.sourceField[sourceFieldKey] }, - result: pair.result + res: pair.res }, { field: targetFieldKey, data: { key: targetFieldKey, ...pair.targetField[targetFieldKey] }, - result: pair.result + res: pair.res } ]; @@ -990,19 +847,50 @@ export function ReviewPointsList({
{chains.map((chain, chainIndex) => { const isLongChain = chain.length > 2; - const result = chain[1].result; + const res = chain[1].res; + // 获取compareMethod + // const compareMethod = chain[1].compareMethod || ''; + // 转换为友好的显示文本 + // const compareMethodText = getCompareMethodText(compareMethod); // 确定样式类名 - const itemClassName = result + const itemClassName = res ? "comparison-item match" : "comparison-item mismatch"; // 如果是长链(3个或以上元素) if (isLongChain) { + console.log('currentlongchain-------', chain); return (
{ + e.stopPropagation(); + // 遍历chain找到第一个有效的page + for (const item of chain) { + if (item.data.page && typeof onReviewPointSelect === 'function') { + onReviewPointSelect(reviewPoint.id, Number(item.data.page)); + break; + } + } + }} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + // 遍历chain找到第一个有效的page + for (const item of chain) { + if (item.data.page && typeof onReviewPointSelect === 'function') { + onReviewPointSelect(reviewPoint.id, Number(item.data.page)); + break; + } + } + } + }} + role="button" + tabIndex={0} >
@@ -1011,7 +899,12 @@ export function ReviewPointsList({ {item.field} {idx < chain.length - 1 && ( - + + {typeof chain[idx+1].compareMethod === 'object' + ? '' + : getCompareMethodText(chain[idx+1].compareMethod)} + + )} ))} @@ -1020,31 +913,34 @@ export function ReviewPointsList({ {chain.map((item, idx) => ( ))}
-
- {result ? ( - +
+ {res ? ( + ) : ( - + )}
@@ -1053,20 +949,23 @@ export function ReviewPointsList({ } // 如果是标准的成对比较(2个元素) + // console.log('currentpairchain-------', chain); return (
{chain[0].field.split('-').pop()}
-
- {result ? ( + {res ? ( ) : ( @@ -1111,12 +1011,501 @@ export function ReviewPointsList({ ); }; + + /** + * 渲染评查点有无判断,格式判断,逻辑判断,正则表达式的规则的样式 + * @param otherRule 评查点规则数据 + * @param reviewPoint 关联的评查点 + * @returns 评查点有无判断,格式判断,逻辑判断,正则表达式的规则的样式 + */ + const renderOtherRule = (otherRule: Record, reviewPoint: ReviewPoint) => { + const fieldKey = otherRule.fieldKey as string; + const fieldValue = otherRule.fieldValue as { + type: Record; + }; + + // 获取res的综合结果 + // 如果存在res=false,则整体结果为false,否则为true + const hasFailure = Object.values(fieldValue?.type || {}).some(item => item.res === false); + const overallResult = !hasFailure; + + // 找到res为false的条目,用于主要显示 + const failedTypeEntry = Object.entries(fieldValue?.type || {}).find(([, item]) => item.res === false); + + // 如果没有失败的条目,则使用第一个条目 + const mainTypeEntry = failedTypeEntry || Object.entries(fieldValue?.type || {})[0]; + + // 如果没有任何条目,则返回空 + if (!mainTypeEntry) return null; + + const [, mainTypeValue] = mainTypeEntry; + + return ( + + ))} +
+ )} */} + + {/* 主要值显示 */} + {mainTypeValue.value && ( + + )} +
+
+ {overallResult ? ( + + ) : ( + + )} + + {/* 悬停提示框 - 横向布局 */} +
+
+ {/*
规则检查结果
*/} +
+ {Object.entries(fieldValue?.type || {}).map(([typeKey, typeValue]) => ( +
+
{typeKey}
+
+ {typeValue.res ? '通过' : '不通过'} +
+
+ ))} +
+
+
+
+
+ + ); + }; + + + + /** + * 渲染评查点大模型判断的规则的样式 + * @param aiRule 评查点大模型判断的规则 + * @param reviewPoint 关联的评查点 + * @returns 评查点大模型判断的规则的样式 + */ + const renderModelRule = (aiRule: Record, reviewPoint: ReviewPoint) => { + // console.log('aiRule-------', aiRule); + const config = aiRule.config as { + model?: string; + fields?: Record; + message?: string; + res?: boolean; + } | undefined; + + if (!config) return null; + + // 创建一个数组来存储需要渲染的JSX元素 + const fieldElements: JSX.Element[] = []; + + // 先存放一条粗的横线 + fieldElements.push( +
+ ); + + // 遍历fields,获取每个字段的值并生成对应的JSX元素 + if (config.fields) { + Object.entries(config.fields).forEach(([key, value], index) => { + const res = value.value.trim() !== ''; + fieldElements.push( + + )} +
+
+ {res ? ( + + ) : ( + + )} +
+ + ); + }); + } + + // 后处理message + if (config.message) { + // 检查message是否为对象,如果是则转换为字符串 + const messageContent = typeof config.message === 'object' + ? JSON.stringify(config.message) + : String(config.message); + + fieldElements.push( +
+
+ +

{messageContent}

+
+
+ ); + } + + // 返回包含所有元素的React片段 + return <>{fieldElements}; + }; + + + + /** + * 过滤评查点中的规则,把type是exist、format、logic、regex的规则中重复的进行去重 + * @param reviewPoint 评查点 + * @returns 合并后的规则数组 + */ + const filterOtherRule = (reviewPoint: ReviewPoint) => { + // 遍历这些评查点中的规则evaluatedPointResultsLog,把type是exist、format、logic、regex的规则添加到allRule中 + interface RuleFieldValue { + page?: number | string; + value?: string; + type: Record; + } + + const allRule: Array<{ + fieldKey: string; + fieldValue: RuleFieldValue; + }> = []; + + for (const rule of reviewPoint.evaluatedPointResultsLog?.rules || []) { + if (rule.type === 'exists') { + // 使用类型断言获取config对象的具体结构 + const config = rule.config as { + res: boolean; + fields: Record; + logic?: string; + }; + + // 如果res为true,则遍历fields,提取不为空的字段 + if (config.res) { + // 遍历fields对象的每个属性 + Object.entries(config.fields).forEach(([key, fieldValue]) => { + // 只处理值不为空的字段 + if (fieldValue.value && fieldValue.value.trim() !== '') { + // 创建新对象并添加type标记 + const newItem = { + fieldKey: key, + fieldValue: { + ...fieldValue, + type: { exists: true } + } + }; + + allRule.push(newItem); + } + }); + } else { + // 如果res为false,则遍历fields,提取所有字段 + Object.entries(config.fields).forEach(([key, fieldValue]) => { + // 根据值是否为空添加不同的type标记 + const isValueEmpty = !fieldValue.value || fieldValue.value.trim() === ''; + + // 创建新对象并添加type标记 + const newItem = { + fieldKey: key, + fieldValue: { + ...fieldValue, + type: { exists: isValueEmpty ? false : true } + } + }; + + allRule.push(newItem); + }); + } + } + if (rule.type === 'format') { + // 使用类型断言获取config对象的具体结构 + const config = rule.config as { + res: boolean; + field: Record; + formatType?: string; + parameters?: string; + }; + + // 从config中获取field对象 + // 注意:根据示例,format类型中是field而不是fields + if (config.field) { + // 获取field中唯一的键值对 + const entries = Object.entries(config.field); + if (entries.length > 0) { + const [key, fieldValue] = entries[0]; + + // 创建新对象并添加type标记 + const newItem = { + fieldKey: key, + fieldValue: { + ...fieldValue, + type: { format: config.res } + } + }; + + allRule.push(newItem); + } + } + } + if (rule.type === 'logic') { + // 使用类型断言获取config对象的具体结构 + const config = rule.config as { + logic: string; + conditions: Array<{ + field: Record; + value: string; + operator: string; + res: boolean; + }>; + }; + + // 遍历conditions数组 + if (config.conditions && Array.isArray(config.conditions)) { + config.conditions.forEach(condition => { + // 从condition中获取field对象 + const entries = Object.entries(condition.field); + if (entries.length > 0) { + const [key, fieldValue] = entries[0]; + + // 创建新对象并添加type标记 + const newItem = { + fieldKey: key, + fieldValue: { + ...fieldValue, + type: { logic: condition.res } + } + }; + + allRule.push(newItem); + } + }); + } + } + if (rule.type === 'regex') { + // 使用类型断言获取config对象的具体结构 + const config = rule.config as { + res: boolean; + field: Record; + pattern?: string; + matchType?: string; + selectedFields?: string[]; + }; + if (config.field) { + const entries = Object.entries(config.field); + if (entries.length > 0) { + const [key, fieldValue] = entries[0]; + + // 创建新对象并添加type标记 + const newItem = { + fieldKey: key, + fieldValue: { + ...fieldValue, + type: { regex: config.res } + } + }; + + allRule.push(newItem); + } + } + } + } + // console.log('allRule-------', allRule); + + + // 对allRule进行去重和合并 + const mergedRules: Array<{ + fieldKey: string; + fieldValue: { + type: Record; + }; + }> = []; + + // 使用对象存储相同fieldKey的项 + const fieldKeyMap: Record; + }; + }> = {}; + + // 第一步:按fieldKey分组 + allRule.forEach(item => { + const fieldKey = item.fieldKey; + const fieldValue = item.fieldValue; + const typeKey = Object.keys(fieldValue.type)[0]; // 获取类型名称(exists/logic/regex/format) + const typeValue = fieldValue.type[typeKey]; // 获取类型值(true/false) + + // 提取页码和值 + const page = fieldValue.page; + const value = fieldValue.value; + + // 如果是第一次遇到这个fieldKey + if (!fieldKeyMap[fieldKey]) { + // 创建新的结构 + fieldKeyMap[fieldKey] = { + fieldKey, + fieldValue: { + type: {} + } + }; + } + + // 将类型信息添加到type对象中 + fieldKeyMap[fieldKey].fieldValue.type[typeKey] = { + res: typeValue, + page, + value + }; + }); + + // 将合并后的对象转换为数组 + for (const key in fieldKeyMap) { + mergedRules.push(fieldKeyMap[key]); + } + + // console.log('合并后的规则:', mergedRules); + // setOtherRule(mergedRules); + return mergedRules; + }; + + + /** * 渲染评查点内容与建议 * @param reviewPoint 评查点 * @returns 评查点内容与建议组件 */ const renderReviewPointContent = (reviewPoint: ReviewPoint) => { + + const mergedRules = filterOtherRule(reviewPoint); + // console.log('mergedRules1-------', mergedRules); const handleManualReviewNotesChange = (reviewPointId: string, text: string) => { setManualReviewNotes(prev => ({ @@ -1149,20 +1538,20 @@ export function ReviewPointsList({

该评查点无法找到索引内容,无法自动定位到对应页面。

)}
- {reviewPoint.suggestion && ( + {/* {reviewPoint.suggestion && (

{reviewPoint.suggestion}

- )} + )} */} {/* 评查点内容显示区域 */} {reviewPoint.content && Object.entries(reviewPoint.content).length > 0 && (
{/* 修改评查结果的结构之后,显示新的结构 */} - {renderContent(reviewPoint, true)} + {renderContent(reviewPoint, mergedRules)}
)} @@ -1219,7 +1608,7 @@ export function ReviewPointsList({ {reviewPoint.content && Object.entries(reviewPoint.content).length > 0 && (
{/* 修改评查结果的结构之后,显示新的结构 */} - {renderContent(reviewPoint, true)} + {renderContent(reviewPoint, mergedRules)}
)} @@ -1286,7 +1675,7 @@ export function ReviewPointsList({
{/* 修改评查结果的结构之后,显示新的结构 */} - {renderContent(reviewPoint,false)} + {renderContent(reviewPoint, mergedRules)}
@@ -1398,23 +1787,23 @@ export function ReviewPointsList({ // 如果评查点存在 if (reviewPoint) { - // 使用checkContentPage方法获取页码和key - const { pageIndex, key } = checkContentPage(reviewPoint); + // // 使用checkContentPage方法获取页码和key + // const { pageIndex, key } = checkContentPage(reviewPoint); - // 如果有有效页码,传递ID和页码 - if (pageIndex > 0) { - console.log(`跳转到页面 ${pageIndex},对应内容 ${key || '未知'}`); - onReviewPointSelect(id, pageIndex); - return; - } + // // 如果有有效页码,传递ID和页码 + // if (pageIndex > 0) { + // console.log(`跳转到页面 ${pageIndex},对应内容 ${key || '未知'}`); + // onReviewPointSelect(id, pageIndex); + // return; + // } - // 没有有效页码,只传递ID + // // 没有有效页码,只传递ID onReviewPointSelect(id); - console.log(`没有有效页码---评查点ID:${reviewPoint.pointId},评查点结果ID:${id}`); + // console.log(`没有有效页码---评查点ID:${reviewPoint.pointId},评查点结果ID:${id}`); } else { - // 没有找到评查点,只传递ID + // // 没有找到评查点,只传递ID onReviewPointSelect(id); - console.log(`没有找到评查点---评查点结果ID:${id}`); + // console.log(`没有找到评查点---评查点结果ID:${id}`); } }; @@ -1465,46 +1854,49 @@ export function ReviewPointsList({ filteredReviewPoints.map(reviewPoint => (
handleReviewPointClick(reviewPoint.id)} + className={`rounded-md review-point-item ${activeReviewPointResultId === reviewPoint.id ? 'active border-l-4 border-l-[#00684a] shadow-md' : 'border-l-4 border-l-transparent'} + transition-all duration-300 ease-in-out + hover:shadow-lg hover:-translate-x-0.5 hover:bg-[rgba(0,0,0,0.02)]`} + role="button" + tabIndex={0} + style={{ userSelect: 'text' }} + onClick={() => { + console.log('reviewPoint', reviewPoint); + handleReviewPointClick(reviewPoint.id); + }} onKeyDown={(e) => { if (e.key === 'Enter') { handleReviewPointClick(reviewPoint.id); } }} - role="button" - tabIndex={0} - style={{ userSelect: 'text' }} > {/* 评查点标题和状态 */} {/* 评查点名称 pointName*/} -
{reviewPoint.pointName}
-
-
{reviewPoint.title}
- {/* 评查点所属分组 */} - {/*
- - - {reviewPoint.groupName} - -
*/} +
+
+
{reviewPoint.pointName}
+
+
{reviewPoint.title}
+ {/* 评查点所属分组 */} + {/*
+ + + {reviewPoint.groupName} + +
*/} +
+
{renderStatusBadge(reviewPoint.status, reviewPoint.result)} {renderHumanReviewBadge(reviewPoint)}
- {/* 人工审核注释 */} - {renderHumanReviewNote(reviewPoint)} - - {/* 评查点一致性的规则的样式渲染 */} - {renderConsistencyRule(reviewPoint.evaluatedPointResultsLog?.[0] || {})} - {/* 评查点内容和操作 */} {renderReviewPointContent(reviewPoint)}
diff --git a/app/routes/reviews.tsx b/app/routes/reviews.tsx index 44ad887..5c051ee 100644 --- a/app/routes/reviews.tsx +++ b/app/routes/reviews.tsx @@ -593,7 +593,7 @@ export default function ReviewDetails() { {activeTab === 'preview' && (
{/* 左侧:文件预览 */} -
+
{/* 右侧:评查结果 */} -
+
-
+
法定代表人