import { Modal } from '../ui/Modal'; import { Table } from '../ui/Table'; import { Button } from '../ui/Button'; import { FileIcon } from '../ui/FileIcon'; import { FileTypeTag } from '../ui/FileTypeTag'; import { StatusBadge } from '../ui/StatusBadge'; import { Pagination } from '../ui/Pagination'; import { LoadingIndicator } from '../ui/SkeletonScreen'; import { updateDocumentAuditStatus, type TaskDocument } from '~/api/cross-checking/cross-files'; // 更新导入 import { toastService } from '../ui/Toast'; import { formatDate } from '~/utils'; import {useRef, useState} from "react"; // 导出样式链接 export const links = () => []; interface DocumentListModalProps { isOpen: boolean; onClose: () => void; title: string; files: TaskDocument[]; // 更新类型 onViewFile?: (fileId: string) => void; loading?: boolean; // 分页相关属性 currentPage?: number; pageSize?: number; total?: number; onPageChange?: (page: number) => void; onPageSizeChange?: (size: number) => void; frontendJWT?: string; // 新增JWT参数 } export function DocumentListModal({ isOpen, onClose, title, files, onViewFile, loading = false, // 分页属性,使用默认值 currentPage = 1, pageSize = 10, total = 0, onPageChange, onPageSizeChange, frontendJWT }: DocumentListModalProps) { // 查看按钮防抖 const [isnavigating,setIsnavigating] = useState(false) const viewDebounceRef = useRef(null) const handleViewClickDebounced = (fileId: string, auditStatus: number | null) => { if(viewDebounceRef.current) return; viewDebounceRef.current = window.setTimeout(()=>{ viewDebounceRef.current = null; },1000); void handleReviewFileClick(fileId, auditStatus); } // 查看评查文件 const handleReviewFileClick = async (fileId: string, auditStatus: number | null) => { // 检查audit_status是否为0,如果是则更新为2 if (auditStatus === 0 || auditStatus === null) { try { // 更新文档状态,传递JWT const updatedFile = await updateDocumentAuditStatus(fileId, 2, frontendJWT); console.log('更新后的文档状态:', updatedFile); } catch (error) { console.error('更新文件审核状态时出错:', error); toastService.error(`更新文件审核状态时出错:${error instanceof Error ? error.message : '未知错误'}`); return; } } // 如果有自定义的查看处理函数,则调用它 if (onViewFile) { setIsnavigating(true) onViewFile(fileId); } }; // 审核状态选项及样式 - 与documents._index.tsx保持一致 const auditStatusMapping: Record = { "-1": { label: "不通过", color: "red", icon: "ri-close-line" }, "-2": { label: "警告", color: "yellow", icon: "ri-alert-line" }, "0": { label: "待审核", color: "blue", icon: "ri-time-line" }, "1": { label: "通过", color: "green", icon: "ri-check-line" }, "2": { label: "审核中", color: "purple", icon: "ri-search-line" }, }; // 渲染审核状态 const renderAuditStatus = (file: TaskDocument) => { // 处理audit_status为null或undefined的情况,默认为0(待审核) const auditStatus = file.audit_status != null ? file.audit_status : 0; const statusKey = auditStatus.toString(); const statusInfo = auditStatusMapping[statusKey] || auditStatusMapping["0"]; return (
{statusInfo.label}
); }; // 获取文件大小的友好显示 const formatFileSize = (bytes: number) => { if (bytes === 0) return '0 B'; const k = 1024; const sizes = ['B', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; }; // 定义表格列配置 const columns = [ { title: "文件名称", key: "fileName", width: "30%", render: (_: unknown, file: TaskDocument) => (
{file.file_name}
文件编号:{file.file_code}
大小:{formatFileSize(file.file_size)}
) }, { title: "文件类型", key: "fileType", width: "8%", render: (_: unknown, file: TaskDocument) => ( ) }, { title: "上传时间", key: "uploadTime", width: "8%", render: (_: unknown, file: TaskDocument) => { const uploadTime = formatDate(file.upload_time).split(' '); const date = uploadTime[0]; const time = uploadTime[1]; return (
{date} {/* 2025-07-22 */}
{time} {/* 10:00:00 */}
); } }, { title: "评查统计", key: "reviewStatus", width: "10%", render: (_: unknown, file: TaskDocument) => // 要文件切分处理完之后,再显示评查统计 file.status === 'Processed' ? (
{file.pass_count > 0 && ( )} {file.warning_count > 0 && ( )} {file.fail_count > 0 && ( )} {/* {file.manual_count > 0 && ( )} */}
) : (
-
) }, { title: "评查分数", key: "score", width: "8%", render: (_: unknown, file: TaskDocument) => (
{file.final_score ? ( {file.score_summary} ) : ( - )}
) }, { title: "评查分数百分化", key: "scorePercent", width: "10%", render: (_: unknown, file: TaskDocument) => { const value: number | null | undefined = file.score_percent as number | null | undefined; if (value === null || value === undefined || Number.isNaN(value)) { return -; } const numericValue = typeof value === 'string' ? Number(value) : value; const normalized = numericValue <= 1 ? numericValue * 100 : numericValue; const display = `${Number(normalized.toFixed(1))}%`; return {display}; } }, { title: '审核状态', key: 'auditStatus', width: '8%', render: (_: unknown, file: TaskDocument) => renderAuditStatus(file) }, { title: "操作", key: "operation", width: "auto", render: (_: unknown, file: TaskDocument) => ( <> ) } ]; return (
{loading ? ( // 显示loading状态
) : files.length === 0 ? ( // 无数据状态
暂无文档数据
) : ( // 有数据时显示表格和分页 <>
{total || files.length} 个文档
{/* 分页组件 - 只有在提供了分页回调函数且总数大于每页大小时才显示 */} {onPageChange && total > 0 && ( {})} onPageSizeChange={onPageSizeChange} showTotal={true} showPageSizeChanger={!!onPageSizeChange} pageSizeOptions={[10, 20, 30, 50]} /> )} )} ); }