From cd2f060d87b4e47d943a55d1ea7287344bed1d59 Mon Sep 17 00:00:00 2001 From: yorn <1057707203@qq.com> Date: Mon, 21 Apr 2025 23:02:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E7=9A=84=E6=95=88=E6=9E=9C=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/evaluation_points/reviews.ts | 170 ++++++-- app/api/evaluation_points/rules-files.ts | 123 ++++-- app/api/files/documents.ts | 7 +- app/api/postgrest-client.ts | 117 +----- app/components/reviews/FileInfo.tsx | 16 +- app/components/reviews/FilePreview.tsx | 90 +++- app/components/reviews/ReviewPointsList.tsx | 444 ++++++++------------ app/components/rules/new/ActionButtons.tsx | 2 +- app/routes/documents.edit.tsx | 167 ++++++-- app/routes/files.upload.tsx | 54 ++- app/routes/reviews.tsx | 33 +- app/routes/rules-files.tsx | 49 ++- app/routes/rules-new.tsx | 5 + app/styles/pages/documents_edit.css | 2 +- app/styles/reviews.css | 4 +- 15 files changed, 718 insertions(+), 565 deletions(-) diff --git a/app/api/evaluation_points/reviews.ts b/app/api/evaluation_points/reviews.ts index b65f6e5..7f9ceae 100644 --- a/app/api/evaluation_points/reviews.ts +++ b/app/api/evaluation_points/reviews.ts @@ -1,21 +1,6 @@ -import { postgrestGet, type PostgrestParams, postgrestPut } from "../postgrest-client"; +import { postgrestGet, type PostgrestParams, postgrestPut, postgrestPost } from "../postgrest-client"; import {getDocument} from "~/api/files/documents"; -import dayjs from 'dayjs'; - -/** - * 格式化日期 - * @param dateString 日期字符串 - * @returns 格式化后的日期字符串 - */ -function formatDate(dateString: string): string { - if (!dateString) return ''; - try { - return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss'); - } catch (error) { - console.error('日期格式化失败:', error); - return dateString; - } - } +import { formatDate } from "~/utils"; /** * 从不同格式的 API 响应中提取数据 @@ -62,6 +47,15 @@ interface EvaluationPoint { [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; @@ -185,6 +179,47 @@ export async function getReviewPoints(fileId: string) { 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 => { @@ -204,6 +239,7 @@ export async function getReviewPoints(fileId: string) { 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 = ''; @@ -268,6 +304,10 @@ 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 || '', @@ -356,18 +396,19 @@ export async function getReviewPoints(fileId: string) { 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, result: boolean, message: string): Promise<{ +export async function updateReviewResult(resultId: string, editAuditStatusId: string | number, result: string, message: string): Promise<{ data?: unknown; error?: string; status?: number; @@ -396,29 +437,72 @@ export async function updateReviewResult(resultId: string, result: boolean, mess const currentResult = currentResultData[0]; const currentEvaluatedResults = currentResult.evaluated_results || {}; - // 构建要更新的数据,保留原有字段,只更新result和message + // 判断是否是重新审核操作 + const isReview = result === 'review'; + console.log('isReview-------', result); + + // 构建要更新的数据,保留原有字段 const updatedEvaluatedResults = { ...currentEvaluatedResults, - result: result, - message: message + // 如果是重新审核操作,不更新result,只更新message + ...(isReview ? { message } : { result: result === 'true' ? true : false, message }), }; const updatedData = { evaluated_results: updatedEvaluatedResults }; - // 调用 API 更新数据 - const response = await postgrestPut( + // 调用 API 更新评查点结果数据 + const resultResponse = await postgrestPut( 'evaluation_results', updatedData, { id: resultId } ); - if (response.error) { - return { error: response.error, status: response.status }; + if (resultResponse.error) { + return { error: resultResponse.error, status: resultResponse.status }; } - const extractedData = extractApiData(response.data); + // 处理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 }; @@ -435,12 +519,12 @@ export async function updateReviewResult(resultId: string, result: boolean, mess } /** - * 确认评查结果并更新文档审核状态 + * 确认评查结果并更新文档审核状态 只更新文档的审核状态为通过 * @param documentId 文档ID * @returns 更新结果 */ export async function confirmReviewResults(documentId: string): Promise<{ - data?: { auditStatus: number; score: number }; + data?: { auditStatus: number; }; error?: string; status?: number; }> { @@ -450,26 +534,26 @@ export async function confirmReviewResults(documentId: string): Promise<{ } // 获取该文档的所有评查点结果 - const reviewPointsResponse = await getReviewPoints(documentId); + // const reviewPointsResponse = await getReviewPoints(documentId); - if ('error' in reviewPointsResponse && reviewPointsResponse.error) { - return { error: reviewPointsResponse.error, status: reviewPointsResponse.status }; - } + // 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 }; - } + // if (!('data' in reviewPointsResponse) || !reviewPointsResponse.data || !Array.isArray(reviewPointsResponse.data)) { + // return { error: '获取评查点数据失败', status: 500 }; + // } - // 计算总分数 - const totalScore = reviewPointsResponse.stats?.score || 0; + // // 计算总分数 + // const totalScore = reviewPointsResponse.stats?.score || 0; - // 根据总分确定审核状态 - // <80分:不通过(-1),>=80分:通过(1) - const auditStatus = totalScore < 80 ? -1 : 1; + // // 根据总分确定审核状态 + // // <80分:不通过(-1),>=80分:通过(1) + // const auditStatus = totalScore < 80 ? -1 : 1; // 更新文档的审核状态 const updateDocumentParams = { - audit_status: auditStatus + audit_status: 1 }; // 调用API更新文档审核状态 @@ -483,7 +567,7 @@ export async function confirmReviewResults(documentId: string): Promise<{ return { error: response.error, status: response.status }; } - return { data: { auditStatus, score: totalScore } }; + return { data: { auditStatus: 1} }; } catch (error) { console.error('确认评查结果失败:', error); return { diff --git a/app/api/evaluation_points/rules-files.ts b/app/api/evaluation_points/rules-files.ts index 64dfeb3..699561b 100644 --- a/app/api/evaluation_points/rules-files.ts +++ b/app/api/evaluation_points/rules-files.ts @@ -69,6 +69,10 @@ export interface ReviewFileUI { message: string; }>; createdBy: string; + passCount: number; + warningCount: number; + failCount: number; + manualCount: number; } // 文件列表搜索参数 @@ -109,6 +113,10 @@ interface EvaluationPoint { interface DocumentReviewResult { status: number; issueCount: number; + passCount: number; + warningCount: number; + failCount: number; + manualCount: number; } /** @@ -177,6 +185,7 @@ export function getFileExtension(fileName: string): string { * @returns UI文件对象 */ export function convertToReviewFileUI(document: Document, documentTypeName: string): ReviewFileUI { + // 将评查状态转换为UI状态(这个评查状态后续可能不需要,这里先预留) const reviewStatus = mapReviewStatusToUI(document.evaluations_status); const reviewFileUI: ReviewFileUI = { @@ -195,7 +204,11 @@ export function convertToReviewFileUI(document: Document, documentTypeName: stri score: 0, auditStatus: document.audit_status, issues: [], - createdBy: document.user_id?.toString() || '系统' + createdBy: document.user_id?.toString() || '系统', + passCount: 0, + warningCount: 0, + failCount: 0, + manualCount: 0 }; // console.log('reviewFileUI-----',reviewFileUI); @@ -396,6 +409,9 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P let totalScore = 0; let totalPoints = 0; let totalPassPoints = 0; + let totalWarningPoints = 0; + let totalFailPoints = 0; + let totalManualPoints = 0; // 存储该文档的问题消息 const issuesList: Array<{severity: 'info' | 'warning' | 'error' | 'critical', message: string}> = []; @@ -406,9 +422,10 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P const pointId = result.evaluation_point_id; const point = pointsMap.get(pointId); - // 检查是否需要人工审核 - if (resultValue === false && point && point.post_action === 'manual') { + // 统计需要人工审核的评查点 + if (point && point.post_action === 'manual') { hasManualReviewPoint = true; + totalManualPoints++; } // 检查是否有不通过的结果 @@ -422,6 +439,14 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P message: evaluatedResults.message as string }); } + + // 统计不通过而且评查点是警告的评查点 + if (point && point.suggestion_message_type === 'warning') { + totalWarningPoints++; + }else if (point && point.suggestion_message_type === 'error') { + totalFailPoints++; + } + }else{ totalPassPoints++; } @@ -464,14 +489,20 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P documentStatusMap.set(docId, { status, + passCount: totalPassPoints, + warningCount: totalWarningPoints, + failCount: totalFailPoints, + manualCount: totalManualPoints, issueCount: results.filter(r => r.evaluated_results?.result === false).length }); }); + + // console.log("documentStatusMap-----",documentStatusMap); // 将文档数据转换为UI文件对象,同时应用评查状态 const reviewFiles = extractedDocuments.map(doc => { const typeName = typeNameMap[doc.type_id] || '未知类型'; - const reviewResult = documentStatusMap.get(doc.id) || { status: doc.evaluations_status || 0, issueCount: 0 }; + const reviewResult = documentStatusMap.get(doc.id) || { status: doc.evaluations_status || 0, issueCount: 0, passCount: 0, warningCount: 0, failCount: 0, manualCount: 0 }; const issues = documentIssuesMap.get(doc.id) || []; const score = documentScoreMap.get(doc.id) || 100; // 获取计算后的分数,默认为100 @@ -490,14 +521,20 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P reviewFile.reviewStatusCode = reviewResult.status; reviewFile.reviewStatus = mapReviewStatusToUI(reviewResult.status); reviewFile.issueCount = reviewResult.issueCount; + + reviewFile.passCount = reviewResult.passCount; + reviewFile.warningCount = reviewResult.warningCount; + reviewFile.failCount = reviewResult.failCount; + reviewFile.manualCount = reviewResult.manualCount; + reviewFile.score = score; // 添加分数 // 添加问题列表 reviewFile.issues = issues; - + return reviewFile; }); - console.log('reviewFiles-----',reviewFiles); + // console.log('reviewFiles-----',reviewFiles); return { data: { files: reviewFiles, @@ -519,51 +556,51 @@ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): P * @param status 评查状态 * @returns 更新后的文件信息 */ -export async function updateReviewStatus(id: string, status: string): Promise<{ - data?: ReviewFileUI; - error?: string; - status?: number; -}> { - try { - if (!id) { - return { error: '文件ID不能为空', status: 400 }; - } +// export async function updateReviewStatus(id: string, status: string): Promise<{ +// data?: ReviewFileUI; +// error?: string; +// status?: number; +// }> { +// try { +// if (!id) { +// return { error: '文件ID不能为空', status: 400 }; +// } - const statusValue = mapUIToReviewStatus(status); +// const statusValue = mapUIToReviewStatus(status); - const response = await postgrestPut>( - 'documents', - { evaluations_status: statusValue }, - { id: parseInt(id) } - ); +// const response = await postgrestPut>( +// 'documents', +// { evaluations_status: statusValue }, +// { id: parseInt(id) } +// ); - if (response.error) { - return { error: response.error, status: response.status }; - } +// if (response.error) { +// return { error: response.error, status: response.status }; +// } - const extractedData = extractApiData(response.data); +// const extractedData = extractApiData(response.data); - if (!extractedData) { - return { error: '更新评查状态失败', status: 500 }; - } +// if (!extractedData) { +// return { error: '更新评查状态失败', status: 500 }; +// } - // 获取文档类型,用于查找文档类型名称 - const documentTypesResponse = await getDocumentTypes({pageSize: 500}); - const documentTypes = documentTypesResponse.data?.types || []; +// // 获取文档类型,用于查找文档类型名称 +// const documentTypesResponse = await getDocumentTypes({pageSize: 500}); +// const documentTypes = documentTypesResponse.data?.types || []; - // 查找文档类型名称 - const docType = documentTypes.find((type: DocumentTypeUI) => type.id === extractedData.type_id); - const typeName = docType ? docType.name : '未知类型'; +// // 查找文档类型名称 +// const docType = documentTypes.find((type: DocumentTypeUI) => type.id === extractedData.type_id); +// const typeName = docType ? docType.name : '未知类型'; - return { data: convertToReviewFileUI(extractedData, typeName) }; - } catch (error) { - console.error('更新评查状态失败:', error); - return { - error: error instanceof Error ? error.message : '更新评查状态失败', - status: 500 - }; - } -} +// return { data: convertToReviewFileUI(extractedData, typeName) }; +// } catch (error) { +// console.error('更新评查状态失败:', error); +// return { +// error: error instanceof Error ? error.message : '更新评查状态失败', +// status: 500 +// }; +// } +// } /** * 更新文件的审核状态 diff --git a/app/api/files/documents.ts b/app/api/files/documents.ts index 222d15d..8170bf6 100644 --- a/app/api/files/documents.ts +++ b/app/api/files/documents.ts @@ -1,5 +1,4 @@ import { postgrestGet, postgrestDelete, postgrestPut, type PostgrestParams } from '../postgrest-client'; -import dayjs from 'dayjs'; import { getDocumentTypes } from '../document-types/document-types'; import { formatDate } from '../../utils'; @@ -433,9 +432,9 @@ export async function updateDocument(id: string, document: Partial & apiDocument.document_number = document.documentNumber; } - if (document.type !== undefined) { - apiDocument.type_id = parseInt(document.type); - } + // if (document.type !== undefined) { + // apiDocument.type_id = parseInt(document.type); + // } if (document.auditStatus !== undefined) { apiDocument.audit_status = document.auditStatus; diff --git a/app/api/postgrest-client.ts b/app/api/postgrest-client.ts index 053105d..c1a560c 100644 --- a/app/api/postgrest-client.ts +++ b/app/api/postgrest-client.ts @@ -42,123 +42,12 @@ function logPostgrestQuery(endpoint: string, params?: QueryParams, method: strin // 以可读格式单独打印每个参数 Object.entries(params).forEach(([key, value]) => { if (value !== undefined) { - if (key === 'select' && typeof value === 'string') { - // 美化 select 参数,使其看起来像 SQL 查询 - console.log(` - ${key}:`); - const fields = value.replace(/\s+/g, ' ').trim().split(','); - fields.forEach(field => { - console.log(` ${field.trim()}`); - }); - } else if (key === 'order' && typeof value === 'string') { - // 格式化排序参数 - console.log(` - ${key}: ${value.replace(/\./g, ' ')}`); // 例如:created_at desc - } else if (key === 'or' && typeof value === 'string') { - // 格式化OR条件 - console.log(` - ${key}: ${value.replace(/\./g, ' -> ').replace(/,/g, ' 或 ')}`); - } else { - console.log(` - ${key}: ${JSON.stringify(value)}`); - } + console.log(` - ${key}: ${JSON.stringify(value)}`); } }); - - // 构建人类可读的简化URL - const readableQueryString = Object.entries(params) - .filter(([, value]) => value !== undefined) - .map(([key, value]) => { - if (key === 'select' && typeof value === 'string') { - // 简化select查询 - return `${key}=...`; - } - return `${key}=${value}`; - }) - .join('&'); - - console.log(`\n📦 可读URL: ${baseUrl}/${normalizedEndpoint}${readableQueryString ? '?' + readableQueryString : ''}`); - - // 格式化查询为 PostgreSQL 风格的查询 - let postgrestQuery = `${method.toUpperCase()} `; - - if (params.select && typeof params.select === 'string') { - postgrestQuery += params.select.replace(/\s+/g, ' ').trim(); - } else { - postgrestQuery += '*'; - } - - postgrestQuery += ` FROM ${normalizedEndpoint}`; - - const conditions: string[] = []; - - // 添加过滤条件 - if (params.filter) { - Object.entries(params.filter).forEach(([key, value]) => { - if (value !== undefined && typeof value === 'string') { - // 解析 eq.X, neq.X, gt.X 等 - const parts = value.toString().split('.'); - if (parts.length >= 2) { - const operator = parts[0]; - const operatorMap: Record = { - 'eq': '=', - 'neq': '!=', - 'gt': '>', - 'gte': '>=', - 'lt': '<', - 'lte': '<=', - 'like': 'LIKE', - 'ilike': 'ILIKE' - }; - - const sqlOperator = operatorMap[operator] || operator; - const value = parts.slice(1).join('.'); - conditions.push(`${key} ${sqlOperator} '${value}'`); - } - } - }); - } - - // 添加 OR 条件 - if (params.or) { - if (typeof params.or === 'string') { - if (params.or.startsWith('(') && params.or.endsWith(')')) { - // 处理 or=(cond1,cond2) 格式 - const orConditions = params.or.slice(1, -1).split(',').map(cond => { - const [field, operator] = cond.split('.'); - return `${field} ${operator.replace(/ilike/i, 'ILIKE')}`; - }); - - if (orConditions.length > 0) { - conditions.push(`(${orConditions.join(' OR ')})`); - } - } else { - // 简单 or 条件 - conditions.push(params.or); - } - } - } - - // 添加WHERE子句 - if (conditions.length > 0) { - postgrestQuery += ` WHERE ${conditions.join(' AND ')}`; - } - - // 添加ORDER BY - if (params.order && typeof params.order === 'string') { - const [field, direction] = params.order.split('.'); - postgrestQuery += ` ORDER BY ${field} ${direction.toUpperCase()}`; - } - - // 添加LIMIT和OFFSET - if (params.limit !== undefined) { - postgrestQuery += ` LIMIT ${params.limit}`; - } - - if (params.offset !== undefined) { - postgrestQuery += ` OFFSET ${params.offset}`; - } - - console.log('\n📦 等效SQL查询:'); - console.log(postgrestQuery); - console.log('=========================================\n'); } + + console.log('=========================================\n'); } } diff --git a/app/components/reviews/FileInfo.tsx b/app/components/reviews/FileInfo.tsx index 966fde1..2bed241 100644 --- a/app/components/reviews/FileInfo.tsx +++ b/app/components/reviews/FileInfo.tsx @@ -1,4 +1,4 @@ - +import { useNavigate } from "@remix-run/react"; interface FileInfoProps { fileInfo: { fileName: string; @@ -15,6 +15,7 @@ interface FileInfoProps { } export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { + const navigate = useNavigate(); const handleDownloadFile = async () => { try { const urlBefore = 'http://172.18.0.100:9000/docauditai/'; @@ -79,20 +80,27 @@ export function FileInfo({ fileInfo, onConfirmResults }: FileInfoProps) { )}
+ {/* 返回上一级 */} + - + */}
); @@ -288,7 +331,14 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointId, ta 文件预览 -
+
+ + {/* 页码跳转控件 */} +
+ + + {numPages && / {numPages}} +
{/* */} - {"比例:"+zoomLevel+"%"} + {"比例:"+zoomLevel+"%"}
; + content: Record; suggestion: string; needsHumanReview?: boolean; humanReviewNote?: string; @@ -65,7 +70,7 @@ interface ReviewPointsListProps { statistics: Statistics; activeReviewPointId: string | null; onReviewPointSelect: (id: string, page?: number) => void; - onStatusChange: (id: string, status: string, message: string) => void; + onStatusChange: (id: string, editAuditStatusId: string | number, status: string, message: string) => void; } export function ReviewPointsList({ @@ -79,7 +84,7 @@ export function ReviewPointsList({ const [editingReviewPoint, setEditingReviewPoint] = useState(null); // 当前正在编辑的评查点ID const [searchText, setSearchText] = useState(''); // 搜索文本 const [statusFilter, setStatusFilter] = useState(null); // 状态过滤 - // eslint-disable-next-line no-unused-vars + const [suggestionTexts, setSuggestionTexts] = useState>({}); // 存储每个评查点的建议文本 // 添加重新审核意见的状态/ 用户输入的修改内容 / 用户提前写好的修改内容 @@ -116,25 +121,34 @@ export function ReviewPointsList({ /** * 处理评查点审核操作 * @param reviewPointResultId 评查点结果ID - * @param action 操作类型: 'approve' 通过 / 'reject' 不通过 + * @param editAuditStatusId 审核状态记录ID + * @param action 操作类型: 'approve' 通过 / 'reject' 不通过 / 'review' 重新审核 * @param message 用户输入的审核内容 */ - const handleReviewAction = (reviewPointResultId: string, action: 'approve' | 'reject', message: string) => { + const handleReviewAction = (reviewPointResultId: string, editAuditStatusId: string | number | undefined, action: 'approve' | 'reject' | 'review', message: string) => { // 更新评查点状态 - onStatusChange(reviewPointResultId, action === 'approve' ? 'true' : 'false', message); + // console.log('handleReviewAction-------', reviewPointResultId, editAuditStatusId, action, message); + if (action === 'review') { + // 重新审核时,不更新结果状态,只更新审核意见和审核状态 + // console.log('重新审核-------', reviewPointResultId, editAuditStatusId || '', 'review', message); + onStatusChange(reviewPointResultId, editAuditStatusId || '', 'review', message); + } else { + // 通过/不通过时,更新结果状态和审核意见 + // console.log('通过/不通过-------', reviewPointResultId, editAuditStatusId || '', action === 'approve' ? 'true' : 'false', message); + onStatusChange(reviewPointResultId, editAuditStatusId || '', action === 'approve' ? 'true' : 'false', message); + } // 将参数输出到控制台 - console.log('评查点审核通过不通过操作', { + console.log('评查点审核操作', { id: reviewPointResultId, + editAuditStatusId: editAuditStatusId, action: action, content: message, - status: action === 'approve' ? 'true' : 'false' + status: action === 'approve' ? 'true' : (action === 'reject' ? 'false' : 'review') }); // 清除编辑状态 setEditingReviewPoint(null); - - // alert(`${action === 'approve' ? '通过' : '不通过'}了评查点 ${reviewPointResultId},审核内容: ${message}`); }; /** @@ -147,7 +161,6 @@ export function ReviewPointsList({ point.pointName.toLowerCase().includes(searchText.toLowerCase()) || point.title.toLowerCase().includes(searchText.toLowerCase()) || point.groupName.toLowerCase().includes(searchText.toLowerCase()) || - (typeof point.content === 'string' && point.content.toLowerCase().includes(searchText.toLowerCase())) || (typeof point.content === 'object' && point.content !== null && Object.values(point.content).some(value => typeof value === 'string' && value.toLowerCase().includes(searchText.toLowerCase()) @@ -291,7 +304,8 @@ export function ReviewPointsList({
setSearchText(e.target.value)} @@ -434,35 +448,24 @@ export function ReviewPointsList({ // 根据result和status决定渲染哪种样式 if (reviewPoint.result === true ){ // 已通过的评查点只显示基本信息和人工审核注释 delete - if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { - return ( -
-
-

已处理

- {reviewPoint.suggestion && ( -
-

{reviewPoint.suggestion}

-
- )} -
-
- ); - } + // if (reviewPoint.needsHumanReview && reviewPoint.humanReviewNote) { + // return ( + //
+ //
+ //

已处理

+ // {reviewPoint.suggestion && ( + //
+ //

{reviewPoint.suggestion}

+ //
+ // )} + //
+ //
+ // ); + // } // 处理 result=true 且 postAction=manual 的情况 if (reviewPoint.postAction === 'manual') { - // 处理重新审核意见的提交 - const handleReReview = (reviewPointId: string, status: string) => { - const note = manualReviewNotes[reviewPointId] || ''; - if (!note.trim()) { - alert('请输入审核意见'); - return; - } - // 在实际应用中,这里应该调用API提交审核意见 - onStatusChange(reviewPointId, status, note); - alert(`提交重新审核意见: ${note}`); - // 可以添加提交成功后的状态更新等操作 - }; + const note = manualReviewNotes[reviewPoint.id] || ''; // 处理重新审核意见的输入 const handleNoteChange = (reviewPointId: string, text: string) => { @@ -483,7 +486,6 @@ export function ReviewPointsList({
)} - {/* 额外的文本输入框区域 */}
-
- - -
-
-
- ); }; /** @@ -912,7 +802,7 @@ export function ReviewPointsList({ // 处理评查点点击事件 const handleReviewPointClick = (id: string) => { // 找到被点击的评查点 - const reviewPoint = reviewPoints.find(point => point.id === id); + const reviewPoint = reviewPoints.find(result => result.id === id); // 如果评查点存在 if (reviewPoint) { @@ -928,9 +818,11 @@ export function ReviewPointsList({ // 没有有效页码,只传递ID onReviewPointSelect(id); + console.log(`没有有效页码---评查点ID:${reviewPoint.pointId},评查点结果ID:${id}`); } else { // 没有找到评查点,只传递ID onReviewPointSelect(id); + console.log(`没有找到评查点---评查点结果ID:${id}`); } }; @@ -981,11 +873,17 @@ export function ReviewPointsList({
{filteredReviewPoints.length > 0 ? ( filteredReviewPoints.map(reviewPoint => ( - +
)) ) : ( renderEmptyState() diff --git a/app/components/rules/new/ActionButtons.tsx b/app/components/rules/new/ActionButtons.tsx index f680f8c..0de9c4f 100644 --- a/app/components/rules/new/ActionButtons.tsx +++ b/app/components/rules/new/ActionButtons.tsx @@ -18,7 +18,7 @@ export function ActionButtons({ onSave, onSaveDraft, isEditMode }: ActionButtons -
-
- -

预览功能暂不可用

-

点击"在新窗口打开"查看完整文档

- -
-
+ {/* 预览窗口 */} + {loadError ?(
+ {loadError} +
):( + renderDocumentContent() + )} diff --git a/app/routes/files.upload.tsx b/app/routes/files.upload.tsx index 5a307fc..360eebb 100644 --- a/app/routes/files.upload.tsx +++ b/app/routes/files.upload.tsx @@ -8,6 +8,7 @@ import { UploadArea, UploadAreaRef } from "~/components/ui/UploadArea"; import { FileProgress} from "~/components/ui/FileProgress"; import { ProcessingSteps, Step } from "~/components/ui/ProcessingSteps"; import uploadStyles from "~/styles/pages/files_upload.css?url"; +import { messageService } from "~/components/ui/MessageModal"; import { getTodayDocuments, getDocumentTypes, @@ -323,6 +324,18 @@ export default function FilesUpload() { // 获取action返回的数据 const actionData = useActionData(); + // 添加一个本地状态来跟踪文件类型错误 + const [fileTypeError, setFileTypeError] = useState( + actionData?.errors?.fileType || null + ); + + // 监听actionData变化,当有fileType错误时更新fileTypeError状态 + useEffect(() => { + if (actionData?.errors?.fileType) { + setFileTypeError(actionData.errors.fileType); + } + }, [actionData]); + // 状态检查定时器引用 const statusCheckIntervalRef = useRef(null); @@ -402,6 +415,8 @@ export default function FilesUpload() { // 确保只有选择了有效的文件类型才进行设置 if (value) { setFileType(value as FileType); + // 立即清除错误状态 + setFileTypeError(null); // 如果已经有选中的文件,且选择了文件类型,则开始上传 if (currentFiles.length > 0) { @@ -409,6 +424,8 @@ export default function FilesUpload() { } } else { setFileType(""); + // 如果用户选择了空选项,显示错误信息 + setFileTypeError("上传文件之前请选择文件类型"); } }; @@ -535,6 +552,7 @@ export default function FilesUpload() { const errorSteps = [...processingSteps]; errorSteps[0].status = "error"; errorSteps[0].description = `上传文件失败: ${error instanceof Error ? error.message : '未知错误'}`; + setProcessingSteps(errorSteps); // 清除进度定时器 @@ -542,7 +560,13 @@ export default function FilesUpload() { clearInterval(progressIntervalRef.current); } - alert(`文件上传失败: ${error instanceof Error ? error.message : '未知错误'}`); + // 显示错误提示 + messageService.error('文件上传失败:只能上传pdf文件。', { + title: '文件上传失败', + onConfirm: () => { + resetUpload(); + } + }); resetUpload(); } }; @@ -924,7 +948,7 @@ export default function FilesUpload() {