import { postgrestGet, postgrestPut, type PostgrestParams } from '../postgrest-client'; import dayjs from 'dayjs'; import { getDocumentTypes } from '../document-types/document-types'; import type { DocumentTypeUI } from '../document-types/document-types'; import weekday from 'dayjs/plugin/weekday'; import updateLocale from 'dayjs/plugin/updateLocale'; // 配置 dayjs dayjs.extend(weekday); dayjs.extend(updateLocale); // 设置一周的第一天为周一 dayjs.updateLocale('en', { weekStart: 1 }); // 文档数据库表接口 export interface Document { id: number; user_id: number | null; type_id: number; name: string; document_number: string; path: string; storage_type: string; file_size: number; upload_time: string; is_test_document: boolean; evaluation_level: string; status: string; ocr_result: Record; extracted_results: Record | null; sumary: string | null; remark: string; created_at: string; updated_at: string; evaluations_status: number | null; audit_status: number | null; } // 文档类型接口 export interface DocumentType { id: number; name: string; description: string | null; status: number; created_at: string; updated_at: string; } // 评查文件UI接口 export interface ReviewFileUI { id: string; fileName: string; fileCode: string; fileType: string; fileTypeId: number; fileSize: number; uploadTime: string; reviewStatus: string; reviewStatusCode: number; issueCount: number; issues: Array<{ severity: 'info' | 'warning' | 'error' | 'critical'; message: string; }>; createdBy: string; } // 文件列表搜索参数 export interface DocumentSearchParams { fileType?: string; // 文件类型ID reviewStatus?: string; // 评查状态 dateRange?: string; // 日期范围 keyword?: string; // 搜索关键字 sortOrder?: string; // 排序方式 page?: number; // 当前页码 pageSize?: number; // 每页条数 } /** * 格式化日期 * @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(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; } /** * 将评查状态代码映射到UI状态 * @param status 评查状态代码 * @returns UI状态 */ export function mapReviewStatusToUI(status: number | null): string { switch(status) { case 1: return 'pass'; case 2: return 'warning'; case -1: return 'fail'; case 0: return 'pending'; default: return 'pending'; } } /** * 将UI状态映射到评查状态代码 * @param status UI状态 * @returns 评查状态代码 */ export function mapUIToReviewStatus(status: string): number { switch(status) { case 'pass': return 1; case 'warning': return 2; case 'fail': return -1; case 'pending': return 0; default: return 0; } } /** * 获取文件扩展名 * @param fileName 文件名 * @returns 文件扩展名 */ export function getFileExtension(fileName: string): string { return fileName.split('.').pop()?.toLowerCase() || ''; } /** * 将数据库文档转换为UI文件对象 * @param document 数据库文档 * @param documentTypeName 文档类型名称 * @returns UI文件对象 */ export function convertToReviewFileUI(document: Document, documentTypeName: string): ReviewFileUI { const reviewStatus = mapReviewStatusToUI(document.evaluations_status); const reviewFileUI: ReviewFileUI = { id: document.id.toString(), fileName: document.name, fileCode: document.document_number, fileType: documentTypeName, fileTypeId: document.type_id, fileSize: document.file_size, uploadTime: formatDate(document.created_at), reviewStatus: reviewStatus, reviewStatusCode: document.evaluations_status || 0, issueCount: 0, issues: [], createdBy: document.user_id?.toString() || '系统' }; // console.log('reviewFileUI-----',reviewFileUI); return reviewFileUI; } /** * 获取评查文件列表 * @param searchParams 搜索参数 * @returns 评查文件列表和总数 */ export async function getReviewFiles(searchParams: DocumentSearchParams = {}): Promise<{ data?: { files: ReviewFileUI[], total: number }; error?: string; status?: number; }> { try { const page = searchParams.page || 1; const pageSize = searchParams.pageSize || 10; // 构建查询参数 const params: PostgrestParams = { select: '*', order: 'created_at.desc', headers: { 'Prefer': 'count=exact' }, limit: pageSize, offset: (page - 1) * pageSize, filter: {} as Record }; // 根据排序方式设置排序 if (searchParams.sortOrder) { switch (searchParams.sortOrder) { case 'upload_time_desc': params.order = 'created_at.desc'; break; case 'upload_time_asc': params.order = 'created_at.asc'; break; // 其他排序方式可以在这里添加 } } // 添加筛选条件 const filter: Record = {}; if (searchParams.fileType) { filter['type_id'] = `eq.${searchParams.fileType}`; } if (searchParams.reviewStatus) { const statusValue = mapUIToReviewStatus(searchParams.reviewStatus); filter['evaluations_status'] = `eq.${statusValue}`; } if (searchParams.keyword) { filter['or'] = `(name.ilike.%${searchParams.keyword}%,document_number.ilike.%${searchParams.keyword}%)`; } // 处理日期范围筛选 if (searchParams.dateRange) { const now = dayjs(); const today = now.startOf('day').format('YYYY-MM-DD HH:mm:ss'); switch (searchParams.dateRange) { case 'today': filter['created_at'] = `gte.${today}`; break; case 'week': { const weekStart = now.startOf('week').format('YYYY-MM-DD HH:mm:ss'); filter['created_at'] = `gte.${weekStart}`; break; } case 'month': { const monthStart = now.startOf('month').format('YYYY-MM-DD HH:mm:ss'); filter['created_at'] = `gte.${monthStart}`; break; } } } // console.log('filter-----',filter); params.filter = filter; // 发送API请求获取文档列表 const response = await postgrestGet('documents', params); if (response.error) { return { error: response.error, status: response.status }; } // 提取API返回的数据 const extractedDocuments = extractApiData(response.data); if (!extractedDocuments) { return { error: '获取评查文件数据失败', status: 500 }; } // 从响应头中获取总数 let totalCount = 0; const responseWithHeaders = response as { data: Document[]; headers: Record }; if(responseWithHeaders.headers){ const rangeHeader = responseWithHeaders.headers['content-range']; if(rangeHeader){ const total = rangeHeader.split('/')[1]; if(total !== '*'){ totalCount = parseInt(total, 10); } } } // 获取文档类型数据,用于查找文档类型名称 const documentTypesResponse = await getDocumentTypes({pageSize: 500}); const documentTypes = documentTypesResponse.data?.types || []; // 创建文档类型ID到名称的映射 const typeNameMap: Record = {}; documentTypes.forEach((type: DocumentTypeUI) => { typeNameMap[type.id] = type.name; }); // 将文档数据转换为UI文件对象 const reviewFiles = extractedDocuments.map(doc => { const typeName = typeNameMap[doc.type_id] || '未知类型'; return convertToReviewFileUI(doc, typeName); }); return { data: { files: reviewFiles, total: totalCount } }; } catch (error) { console.error('获取评查文件列表失败:', error); return { error: error instanceof Error ? error.message : '获取评查文件列表失败', status: 500 }; } } /** * 更新文件的评查状态 * @param id 文件ID * @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 }; } const statusValue = mapUIToReviewStatus(status); const response = await postgrestPut>( 'documents', { evaluations_status: statusValue }, { id: parseInt(id) } ); if (response.error) { return { error: response.error, status: response.status }; } const extractedData = extractApiData(response.data); if (!extractedData) { return { error: '更新评查状态失败', status: 500 }; } // 获取文档类型,用于查找文档类型名称 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 : '未知类型'; return { data: convertToReviewFileUI(extractedData, typeName) }; } catch (error) { console.error('更新评查状态失败:', error); return { error: error instanceof Error ? error.message : '更新评查状态失败', status: 500 }; } }