import { postgrestGet, type PostgrestParams, postgrestPut, postgrestPost } from "../postgrest-client"; import {getDocument} from "~/api/files/documents"; 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; }; [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; [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; } // 定义统计数据类型 interface StatsData { total: number; success: number; warning: number; error: number; score: number; } // 在文件顶部添加的类型定义,在interface区块前添加 interface OcrDataResult { pages?: number[]; [key: string]: unknown; } interface OcrData { [key: string]: OcrDataResult | unknown; ocr_result?: Record; } /** * 获取当前评查文件的所有评查点结果 * @param fileId 评查文件ID * @returns 评查点结果列表和统计数据 */ export async function getReviewPoints(fileId: string) { // 首先先获取这个文档的数据 const documentData = await getDocument(fileId); if (documentData.error) { console.error("获取文档数据错误:", documentData.error); return Response.json({ error: documentData.error }, { status: documentData.status || 500 }); } // 步骤1:根据fileId查询evaluation_results表 const evaluationResultsParams: PostgrestParams = { select: '*', filter: { 'document_id': `eq.${fileId}` } }; const evaluationResultsResponse = await postgrestGet('evaluation_results', evaluationResultsParams); 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(',')})` } }; 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 } }; } // 查询评查点组 const groupsParams: PostgrestParams = { select: '*', filter: { 'id': `in.(${groupIds.join(',')})` } }; 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 } }; } // 从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(',')})` } }; 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}); } }); } // 为没有对应audit_status记录的manual类型评查点设置默认值0 if (manualReviewPointsIds.length > 0) { manualReviewPointsIds.forEach(pointId => { if (!editAuditStatusMap.has(pointId)) { editAuditStatusMap.set(pointId, {id: '', status: 0}); } }); } // 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); // 构建前端所需的数据格式 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}; // 从 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); if (data && typeof data === 'object') { // try { // const dataObj = data as Record; // // 检查是否是预期的格式 {'立案报告表-完整性检查':'缺失部分内容'} // for (const key in dataObj) { // if (Object.prototype.hasOwnProperty.call(dataObj, key)) { // // 使用'-'分割获取前缀(如'立案报告表') // const prefix = key.split('-')[0]; // // console.log('prefix-------', prefix); // // 检查document.data中的ocrResult是否存在这个key // if (documentData.data?.ocrResult && // typeof documentData.data.ocrResult === 'object') { // // ocrResult可能有嵌套的ocr_result属性 // let ocrData: OcrData = documentData.data.ocrResult as OcrData; // // 检查是否有嵌套的ocr_result对象 // if ('ocr_result' in ocrData && // ocrData.ocr_result && // typeof ocrData.ocr_result === 'object') { // ocrData = ocrData.ocr_result as OcrData; // } // for (const ocrKey in ocrData) { // // 如果找到匹配的key // if (ocrKey === prefix && // ocrData[ocrKey] && // typeof ocrData[ocrKey] === 'object' && // 'pages' in ocrData[ocrKey]) { // // 获取pages数组 // const pages = ocrData[ocrKey].pages; // if (Array.isArray(pages)) { // // 存储每个key对应的页码数组 // contentPage[key] = pages; // } // break; // } // } // } // } // } // } // 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)) { contentPage[key] = dataObj[key].page.toString(); } } } catch (e) { console.error('解析评查点data失败:', e); contentPage = {}; } } return { 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', //评查点的评查结果状态 content: data, contentPage: contentPage, suggestion: point.suggestion_message || '', // suggestion: '只是给建议的修改内容', result: result.evaluated_results?.result, // 记录评查结果,用于统计 score: point.score || 0, postAction: point.post_action || '', // postAction: 'manual', actionContent: point.action_config || '', // actionContent: '用户提前在评查点输入过的修改内容', legalBasis: point.references_laws || {} // legalBasis: { // name: '中华人民共和国食品安全法', // content: '中华人民共和国食品安全法', // article: [ // { // name: '中华人民共和国食品安全法', // content: '中华人民共和国食品安全法' // } // ] // } }; }); // 统计数据 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: formatDate(latestUpdatedAt), 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 return { data: resultData, stats, reviewInfo, document: documentData.data }; } /** * 更新评查结果 * @param resultId 评查结果ID * @param editAuditStatusId 审核状态ID * @param result 评查结果 (true/false) * @param message 评查意见 * @returns 更新后的评查结果 */ export async function updateReviewResult(resultId: string, editAuditStatusId: string | number, result: string, message: string): Promise<{ data?: unknown; error?: string; status?: number; }> { try { if (!resultId) { return { error: '评查结果ID不能为空', status: 400 }; } // 首先获取当前评查结果数据 const currentResultResponse = await postgrestGet('evaluation_results', { select: '*', filter: { id: `eq.${resultId}` } }); 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 ? { message } : { result: result === 'true' ? true : false, message }), }; const updatedData = { evaluated_results: updatedEvaluatedResults }; // 调用 API 更新评查点结果数据 const resultResponse = await postgrestPut( 'evaluation_results', updatedData, { id: resultId } ); 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 }, { id: editAuditStatusId } ); 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 }; // 使用postgrestPost创建新记录 const postResponse = await postgrestPost('audit_status', newAuditStatus); 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 * @returns 更新结果 */ export async function confirmReviewResults(documentId: string): Promise<{ data?: { auditStatus: number; }; error?: string; status?: number; }> { try { 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 } ); 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 }; } }