Files
leaudit-platform-frontend/app/api/evaluation_points/reviews.ts
T
2025-04-18 15:41:43 +08:00

423 lines
14 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { postgrestGet, type PostgrestParams, postgrestPut } 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;
}
}
/**
* 从不同格式的 API 响应中提取数据
* @param responseData API 响应数据
* @returns 提取后的数据或 null
*/
function extractApiData<T>(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 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;
}
/**
* 获取当前评查文件的所有评查点结果
* @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<EvaluationResult[]>(evaluationResultsResponse.data);
if (!evaluationResultsData || !Array.isArray(evaluationResultsData)) {
return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } };
}
// 收集所有评查点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 } };
}
// 步骤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<EvaluationPoint[]>(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<EvaluationPointGroup[]>(groupsResponse.data);
if (!groupsData || !Array.isArray(groupsData)) {
return { data: [], stats: { total: 0, success: 0, warning: 0, error: 0, score: 0 } };
}
// 创建映射关系以便快速查找
const pointsMap = new Map<string | number, EvaluationPoint>();
evaluationPointsData.forEach(point => {
pointsMap.set(point.id, point);
});
// console.log('pointsMap-------', pointsMap);
const groupsMap = new Map<string | number, EvaluationPointGroup>();
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;
// 从 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: number[] = [];
console.log('datacontent-------', data);
if (data && typeof data === 'object') {
try {
const dataObj = data as Record<string, string>;
// 检查是否是预期的格式 {'立案报告表-完整性检查''缺失部分内容'}
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: Record<string, any> = documentData.data.ocrResult as Record<string, any>;
// 检查是否有嵌套的ocr_result对象
if ('ocr_result' in ocrData &&
ocrData.ocr_result &&
typeof ocrData.ocr_result === 'object') {
ocrData = ocrData.ocr_result as Record<string, any>;
}
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)) {
contentPage = pages;
}
break;
}
}
}
}
}
} catch (e) {
console.error('解析评查点data失败:', e);
contentPage = [];
}
}
return {
id: result.id,
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));
return { data: resultData, stats, reviewInfo, document: documentData.data };
}
/**
* 更新评查结果
* @param resultId 评查结果ID
* @param result 评查结果 (true/false)
* @param message 评查意见
* @returns 更新后的评查结果
*/
export async function updateReviewResult(resultId: string, result: boolean, 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<EvaluationResult[]>(currentResultResponse.data);
if (!currentResultData || !Array.isArray(currentResultData) || currentResultData.length === 0) {
return { error: '未找到评查结果数据', status: 404 };
}
const currentResult = currentResultData[0];
const currentEvaluatedResults = currentResult.evaluated_results || {};
// 构建要更新的数据,保留原有字段,只更新result和message
const updatedEvaluatedResults = {
...currentEvaluatedResults,
result: result,
message: message
};
const updatedData = {
evaluated_results: updatedEvaluatedResults
};
// 调用 API 更新数据
const response = await postgrestPut<unknown, typeof updatedData>(
'evaluation_results',
updatedData,
{ id: resultId }
);
if (response.error) {
return { error: response.error, status: response.status };
}
const extractedData = extractApiData<unknown>(response.data);
if (!extractedData) {
return { error: '更新评查结果失败', status: 500 };
}
return { data: extractedData };
} catch (error) {
console.error('更新评查结果失败:', error);
return {
error: error instanceof Error ? error.message : '更新评查结果失败',
status: 500
};
}
}