import { postgrestGet, type PostgrestParams, postgrestPut, postgrestPost } from "../postgrest-client"; import {getDocumentWithNoUserId} from "~/api/files/documents"; import dayjs from "dayjs"; import { getUserSession } from "~/api/login/auth.server"; // import { formatDate } from "~/utils"; /** * 从不同格式的 API 响应中提取数据 * @param responseData API 响应数据 * @returns 提取后的数据或 null */ function extractApiData(responseData: unknown): T | null { if (!responseData) return null; // 格式1: { code: number, msg: string, data: T } if (typeof responseData === 'object' && responseData !== null && 'code' in responseData && 'data' in responseData && (responseData as { data: unknown }).data) { return (responseData as { data: T }).data; } // 格式2: 直接是数据对象 return responseData as T; } // 定义评查结果类型 interface EvaluationResult { id: string | number; document_id: string | number; evaluation_point_id: string | number; evaluated_results?: { result?: boolean; message?: string; data?: string; [key: string]: unknown; }; evaluated_point_results_log?: { rules?: unknown[]; [key: string]: unknown; }; [key: string]: unknown; } // 定义评查点类型 interface EvaluationPoint { id: string | number; evaluation_point_groups_id: string | number; suggestion_message_type?: string; suggestion_message?: string; score?: number; updated_at?: string; [key: string]: unknown; } // 定义审核状态类型 interface AuditStatus { id: string | number; document_id: string | number; evaluation_point_id: string | number; edit_audit_status: number; message: string; [key: string]: unknown; } // 定义评查点组类型 interface EvaluationPointGroup { id: string | number; name?: string; [key: string]: unknown; } // 定义前端使用的评查点结果类型 interface ReviewPointResult { id: string | number; title: string; groupName: string; status: string; content: string; suggestion: string; result?: boolean; score: number; // evaluatedPointResultsLog: Record>>; evaluatedPointResultsLog: Record; } // 定义统计数据类型 interface StatsData { total: number; success: number; warning: number; error: number; score: number; } // 在文件顶部添加的类型定义,在interface区块前添加 interface OcrDataResult { pages?: number[]; [key: string]: unknown; } interface OcrData { ocr_result?: Record; [key: string]: unknown; } interface ContractStructureComparison { id: string | number; document_id: string | number; [key: string]: unknown; } // 定义评分提案数据接口 interface ScoringProposal { id: string | number; evaluation_result_id: string | number; proposer_id: string | number; proposed_score: number; reason: string; status: string; created_at: string; updated_at: string; document_id: string | number; } /** * 获取当前评查文件的所有评查点结果 * @param fileId 评查文件ID * @param request Remix请求对象,用于获取用户会话 * @returns 评查点结果列表和统计数据 */ export async function getReviewPoints(fileId: string, request: Request) { // 获取用户会话信息 const { userInfo, frontendJWT } = await getUserSession(request); if (!userInfo?.user_id) { console.error("用户身份验证失败"); return { error: '用户身份验证失败', status: 401 }; } // const userId = userInfo.user_id.toString(); // 首先先获取这个文档的数据 const documentData = await getDocumentWithNoUserId(fileId, frontendJWT); if (documentData.error) { console.error("获取文档数据错误:", documentData.error); return Response.json({ error: documentData.error }, { status: documentData.status || 500 }); } // 其次需要查询这个文档关联的文档附件,查询contract_structure_comparison表 const contractStructureComparisonParams: PostgrestParams = { select: '*', filter: { 'document_id': `eq.${fileId}` }, order: 'id.desc', limit: 1, token: frontendJWT }; const contractStructureComparisonResponse = await postgrestGet('contract_structure_comparison', contractStructureComparisonParams); if (contractStructureComparisonResponse.error) { console.error("获取文档附件数据错误:", contractStructureComparisonResponse.error); return Response.json({ error: contractStructureComparisonResponse.error }, { status: contractStructureComparisonResponse.status || 500 }); } const contractStructureComparisonData = extractApiData(contractStructureComparisonResponse.data); // console.log('文档附件的数据', JSON.stringify(contractStructureComparisonData, null, 2)); // 解析比对结果 let comparisonDocument = null; if (contractStructureComparisonData && contractStructureComparisonData.length > 0) { comparisonDocument = contractStructureComparisonData[0]; // 测试:将合同封面中的status改为abnormal // (comparisonDocument.comparison_results as Record>)['合同封面'][0]['status'] = 'abnormal'; // 如果 comparison_results 是字符串,尝试解析为 JSON if (comparisonDocument.comparison_results && typeof comparisonDocument.comparison_results === 'string') { try { comparisonDocument.comparison_results = JSON.parse(comparisonDocument.comparison_results); } catch (e) { console.error('解析比对结果失败:', e); comparisonDocument.comparison_results = null; } } }else{ comparisonDocument = { template_contract_path: '', } } // console.log('documentData-------', documentData); // 步骤1:根据fileId查询evaluation_results表 const evaluationResultsParams: PostgrestParams = { select: '*', filter: { 'document_id': `eq.${fileId}` }, token: frontendJWT }; const evaluationResultsResponse = await postgrestGet('evaluation_results', evaluationResultsParams); // console.log('evaluationResultsResponse-------', evaluationResultsResponse,); if (evaluationResultsResponse.error) { return { error: evaluationResultsResponse.error, status: evaluationResultsResponse.status }; } // 评查结果数据 const evaluationResultsData = extractApiData(evaluationResultsResponse.data) || []; if (Array.isArray(evaluationResultsData) && evaluationResultsData.length <= 0) { return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 },error: '获取评查结果数据失败' }; } // 收集所有评查点ID,用于查询评查点详情 const evaluationPointIds = evaluationResultsData.map(item => item.evaluation_point_id).filter(Boolean); if (evaluationPointIds.length === 0) { return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 },error: '获取评查点ID失败' }; } // 步骤2:根据evaluation_point_id查询evaluation_points表 const evaluationPointsParams: PostgrestParams = { select: '*', filter: { 'id': `in.(${evaluationPointIds.join(',')})` }, token: frontendJWT }; const evaluationPointsResponse = await postgrestGet('evaluation_points', evaluationPointsParams); if (evaluationPointsResponse.error) { return { error: evaluationPointsResponse.error, status: evaluationPointsResponse.status }; } const evaluationPointsData = extractApiData(evaluationPointsResponse.data); if (!evaluationPointsData || !Array.isArray(evaluationPointsData)) { return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } }; } // 收集所有评查点组ID,用于查询评查点组详情 const groupIds = evaluationPointsData.map(item => item.evaluation_point_groups_id).filter(Boolean); if (groupIds.length === 0) { return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } }; } // 步骤3:查询评查点组 const groupsParams: PostgrestParams = { select: '*', filter: { 'id': `in.(${groupIds.join(',')})` }, token: frontendJWT }; const groupsResponse = await postgrestGet('evaluation_point_groups', groupsParams); if (groupsResponse.error) { return { error: groupsResponse.error, status: groupsResponse.status }; } const groupsData = extractApiData(groupsResponse.data); if (!groupsData || !Array.isArray(groupsData)) { return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } }; } // 步骤4:从audit_status表中 获取 需人工审核 的那些评查点的数据 // console.log('evaluationPointsData1112------', evaluationPointsData.find(point => point.post_action === 'manual')); const manualReviewPoints = evaluationPointsData.filter(point => point.post_action === 'manual'); const manualReviewPointsIds = manualReviewPoints.map(point => point.id); const manualReviewPointsParams: PostgrestParams = { select: '*', filter: { 'document_id': `eq.${fileId}`, 'evaluation_point_id': `in.(${manualReviewPointsIds.join(',')})` }, token: frontendJWT }; const manualReviewPointsResponse = await postgrestGet('audit_status', manualReviewPointsParams); if (manualReviewPointsResponse.error) { return { error: manualReviewPointsResponse.error, status: manualReviewPointsResponse.status }; } const manualReviewPointsData = extractApiData(manualReviewPointsResponse.data); // 构建评查点ID到editAuditStatus的映射 const editAuditStatusMap = new Map(); // 如果有查询结果,则根据evaluation_point_id索引到对应数据 if (manualReviewPointsData && Array.isArray(manualReviewPointsData)) { manualReviewPointsData.forEach(auditStatus => { if (auditStatus.evaluation_point_id && auditStatus.edit_audit_status !== undefined) { editAuditStatusMap.set(auditStatus.evaluation_point_id, {id: auditStatus.id, status: auditStatus.edit_audit_status, message: auditStatus.message}); } }); } // 为没有对应audit_status记录的manual类型评查点设置默认值0 if (manualReviewPointsIds.length > 0) { manualReviewPointsIds.forEach(pointId => { if (!editAuditStatusMap.has(pointId)) { editAuditStatusMap.set(pointId, {id: '', status: 0, message: ''}); } }); } // console.log('manualReviewPoints-------', manualReviewPoints); // 创建映射关系以便快速查找 const pointsMap = new Map(); evaluationPointsData.forEach(point => { pointsMap.set(point.id, point); }); // console.log('pointsMap-------', pointsMap); const groupsMap = new Map(); groupsData.forEach(group => { groupsMap.set(group.id, group); }); // console.log('groupsMap-------', groupsMap); //从cross_scoring_proposals表中获取评分提案数据,用于交叉评查 const scoringProposalsParams: PostgrestParams = { select: '*', filter: { 'document_id': `eq.${fileId}`, 'deleted_at': `is.null` }, token: frontendJWT }; const scoringProposalsResponse = await postgrestGet('cross_scoring_proposals', scoringProposalsParams); if (scoringProposalsResponse.error) { return { error: scoringProposalsResponse.error, status: scoringProposalsResponse.status }; } const scoringProposalsData = extractApiData(scoringProposalsResponse.data) || []; // 构建前端所需的数据格式 const resultData: ReviewPointResult[] = evaluationResultsData.map(result => { const point = pointsMap.get(result.evaluation_point_id) || {} as EvaluationPoint; const group = groupsMap.get(point.evaluation_point_groups_id || 0) || {} as EvaluationPointGroup; const editAuditStatus = editAuditStatusMap.get(result.evaluation_point_id) || {id: '', status: 0, message: ''}; // 评查结果内容改成由evaluated_point_results_log中获取 const evaluatedPointResultsLog = result.evaluated_point_results_log || {}; // console.log('evaluatedPointResultsLog-------', evaluatedPointResultsLog); // 从 evaluated_results 中提取数据 let message = ''; let data = ''; if (result.evaluated_results && typeof result.evaluated_results === 'object') { message = result.evaluated_results.message || ''; data = result.evaluated_results.data || ''; } // 提取页码数组 let contentPage: Record = {}; // console.log('result-------', result.evaluated_results?.result); // console.log('datacontent-------', data); // console.log('documentData-------', documentData); if (data && typeof data === 'object') { // 4-22 更改数据结构:通过拿到的data数据(每一个key对应一个object),将object中的page提取出来 try{ const dataObj = data as Record; for (const key in dataObj) { if (Object.prototype.hasOwnProperty.call(dataObj, key)) { let newPage = dataObj[key].page.toString(); // 如果newPage里面有文本,则把文本去掉 if(newPage.match(/\d+/g)){ newPage = newPage.match(/^\d+/g)?.map(Number).join('') || ''; } contentPage[key] = newPage; } // 如果contentPage[key]为空,则需要根据这个key去ocrResult中找到对应的key,然后根据ocrResult中的pages数组,找到对应的页码 if(!contentPage[key]){ // 分割key获取数组的第一位 const keyArray = key.split('-'); const ocrResult = documentData?.data?.ocrResult as OcrData; const pages = ocrResult?.ocr_result?.[keyArray[0]]?.pages; contentPage[key] = pages?.[0]?.toString() || ''; } } } catch (e) { console.error('解析评查点data失败:', e); contentPage = {}; } } return { id: result.id, documentId: fileId, pointId: point.id, editAuditStatusId: editAuditStatus.id, editAuditStatus: editAuditStatus.status, editAuditStatusMessage: editAuditStatus.message, title: message, pointName: point.name || '', groupName: group.name || '', status: point.suggestion_message_type || '', //评查点的评查结果状态 // status: 'error', //评查点的评查结果状态 content: data, contentPage: contentPage, suggestion: point.suggestion_message || '', // suggestion: '只是给建议的修改内容', result: result.evaluated_results?.result, // 记录评查结果,用于统计 // score是评查点设置的满分的分数 score: point.score || 0, // finalScore是评查点对应评查结果最终所得的分数 用户交叉评查时使用,可能为null finalScore: result.final_score, // machineScore是评查点对应评查结果机器进行的评分,交叉评查时使用,实际上对应的是评查点设置好的分数 machineScore: result.machine_score, postAction: point.post_action || '', // postAction: 'manual', actionContent: point.action_config || '', // actionContent: '用户提前在评查点输入过的修改内容', legalBasis: point.references_laws || {}, // legalBasis: { // name: '中华人民共和国食品安全法', // content: '中华人民共和国食品安全法', // article: [ // { // name: '中华人民共和国食品安全法', // content: '中华人民共和国食品安全法' // } // ] // } // 评查配置: point.evaluation_config evaluationConfig: point.evaluation_config || {}, // 评查点evaluation_point中的fail_message和pass_message 用于交叉评查的提出意见 failMessage: point.fail_message || '', passMessage: point.pass_message || '', evaluatedPointResultsLog: evaluatedPointResultsLog || {} // evaluatedPointResultsLog: { // rules:[ // { // "id": "0", // "type": "consistency", // "res": true, // "config": { // "logic": "all", // "pairs": [ // { // "sourceField": {"证据先行登记保存批准书-负责人意见并签名-时间": {page: 1,value: ''}}, // "targetField": {"证据先行登记保存批准书-负责人意见并签名-签名": {page: 2,value: '有无判断类型'}}, // "compareMethod": "exact", // "res": true // } // ] // } // }, // { // "id": "1", // "type": "consistency", // "res": false, // "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", // "res": true, // "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": [] // } // } // ]} }; }); // 统计数据 const stats: StatsData = { total: evaluationResultsData.length, success: 0, warning: 0, error: 0, score: 0 }; // 计算统计数据 resultData.forEach(item => { // 成功数量统计 if (item.result === true) { stats.success += 1; } else if (item.result === false) { // 警告和错误数量统计 if (item.status === 'warning') { stats.warning += 1; } else if (item.status === 'error') { stats.error += 1; } } // 分数统计 stats.score += item.score || 0; }); // 构建文件信息-评查信息的数据 // 找出最新的评查时间 let latestUpdatedAt = ''; evaluationResultsData.forEach(result => { if (result.updated_at && (!latestUpdatedAt || result.updated_at > latestUpdatedAt)) { latestUpdatedAt = result.updated_at.toString(); } }); // 提取不重复的规则组名称 const uniqueGroups = Array.from(new Set(resultData.map(item => item.groupName))).filter(Boolean); // 计算问题数量 const issueCount = stats.warning + stats.error; // 构建评查信息对象 const reviewInfo = { reviewTime: dayjs.utc(latestUpdatedAt).format('YYYY-MM-DD HH:mm:ss'), reviewModel: 'DeepSeek', ruleGroup: uniqueGroups.join('、'), result: issueCount > 0 ? 'warning' : 'success', issueCount: issueCount }; // console.log("reviewInfo-------",JSON.stringify(reviewInfo,null,2)); // data->reviewPoints stats->statistics reviewInfo->reviewInfo document->document scoring_proposals->scoringProposalsData return { data: resultData, stats, reviewInfo, document: documentData.data, comparison_document: comparisonDocument, scoring_proposals: scoringProposalsData }; } /** * 更新评查结果 * @param resultId 评查结果ID * @param editAuditStatusId 审核状态ID * @param result 评查结果 (true/false) * @param message 评查意见 * @param request Remix请求对象,用于获取用户会话 * @returns 更新后的评查结果 */ export async function updateReviewResult( resultId: string, editAuditStatusId: string | number, result: string, message: string, request: Request ): Promise<{ data?: unknown; error?: string; status?: number; }> { try { // 获取用户会话信息 const { userInfo, frontendJWT } = await getUserSession(request); if (!userInfo?.user_id) { console.error("用户身份验证失败"); return { error: '用户身份验证失败', status: 401 }; } const userId = userInfo.user_id; if (!resultId) { return { error: '评查结果ID不能为空', status: 400 }; } // 首先获取当前评查结果数据 const currentResultResponse = await postgrestGet('evaluation_results', { select: '*', filter: { id: `eq.${resultId}` }, token: frontendJWT }); if (currentResultResponse.error) { return { error: currentResultResponse.error, status: currentResultResponse.status }; } const currentResultData = extractApiData(currentResultResponse.data); if (!currentResultData || !Array.isArray(currentResultData) || currentResultData.length === 0) { return { error: '未找到评查结果数据', status: 404 }; } const currentResult = currentResultData[0]; const currentEvaluatedResults = currentResult.evaluated_results || {}; // 判断是否是重新审核操作 const isReview = result === 'review'; // console.log('isReview-------', result); // 构建要更新的数据,保留原有字段 const updatedEvaluatedResults = { ...currentEvaluatedResults, // 如果是重新审核操作,不更新result和message ...(isReview ? {} : { result: result === 'true' ? true : false, message }), }; const updatedData = { evaluated_results: updatedEvaluatedResults }; // 调用 API 更新评查点结果数据 const resultResponse = await postgrestPut( 'evaluation_results', updatedData, { id: resultId }, frontendJWT ); if (resultResponse.error) { return { error: resultResponse.error, status: resultResponse.status }; } // 处理audit_status表的更新或新增 // 确定edit_audit_status的值: // 如果是重新审核操作,值为0;否则值为1 const editAuditStatusValue = isReview ? 0 : 1; // console.log('editAuditStatusValue-------', editAuditStatusValue); // console.log('editAuditStatusId-------', editAuditStatusId); if (editAuditStatusId && editAuditStatusId !== '') { // 更新现有审核状态记录 const auditStatusResponse = await postgrestPut( 'audit_status', { edit_audit_status: editAuditStatusValue, // 重新审核时不更新message ...(isReview ? {} : { message }) }, { id: editAuditStatusId, user_id: userId // 添加用户ID条件,确保只能更新自己的记录 }, frontendJWT ); if (auditStatusResponse.error) { return { error: auditStatusResponse.error, status: auditStatusResponse.status || 500 }; } } else { // 如果没有editAuditStatusId,则创建新记录 // 首先获取文档ID和评查点ID const documentId = currentResult.document_id; const evaluationPointId = currentResult.evaluation_point_id; // 创建新的审核状态记录 const newAuditStatus = { document_id: documentId, evaluation_point_id: evaluationPointId, evaluation_result_id: resultId, edit_audit_status: editAuditStatusValue, message: isReview ? '' : message, user_id: userId // 添加用户ID }; // 使用postgrestPost创建新记录 const postResponse = await postgrestPost('audit_status', newAuditStatus, frontendJWT); if (postResponse.error) { return { error: postResponse.error, status: postResponse.status || 500 }; } } const extractedData = extractApiData(resultResponse.data); if (!extractedData) { return { error: '更新评查结果失败', status: 500 }; } return { data: extractedData }; } catch (error) { console.error('更新评查结果失败:', error); return { error: error instanceof Error ? error.message : '更新评查结果失败', status: 500 }; } } /** * 确认评查结果并更新文档审核状态 只更新文档的审核状态为通过 * @param documentId 文档ID * @param request Remix请求对象,用于获取用户会话 * @returns 更新结果 */ export async function confirmReviewResults(documentId: string, request: Request): Promise<{ data?: { auditStatus: number; }; error?: string; status?: number; }> { try { // 获取用户会话信息 const { userInfo, frontendJWT } = await getUserSession(request); if (!userInfo?.user_id) { console.error("用户身份验证失败"); return { error: '用户身份验证失败', status: 401 }; } const userId = userInfo.user_id; if (!documentId) { return { error: '文档ID不能为空', status: 400 }; } // 获取该文档的所有评查点结果 // const reviewPointsResponse = await getReviewPoints(documentId); // if ('error' in reviewPointsResponse && reviewPointsResponse.error) { // return { error: reviewPointsResponse.error, status: reviewPointsResponse.status }; // } // if (!('data' in reviewPointsResponse) || !reviewPointsResponse.data || !Array.isArray(reviewPointsResponse.data)) { // return { error: '获取评查点数据失败', status: 500 }; // } // // 计算总分数 // const totalScore = reviewPointsResponse.stats?.score || 0; // // 根据总分确定审核状态 // // <80分:不通过(-1),>=80分:通过(1) // const auditStatus = totalScore < 80 ? -1 : 1; // 更新文档的审核状态 const updateDocumentParams = { audit_status: 1 }; // 调用API更新文档审核状态 const response = await postgrestPut<{ id: string }, typeof updateDocumentParams>( 'documents', updateDocumentParams, { id: documentId, user_id: userId // 添加用户ID条件,确保只能更新自己的文档 }, frontendJWT ); if (response.error) { return { error: response.error, status: response.status }; } return { data: { auditStatus: 1} }; } catch (error) { console.error('确认评查结果失败:', error); return { error: error instanceof Error ? error.message : '确认评查结果失败', status: 500 }; } }