Files
leaudit-platform-frontend/app/components/cross-checking/DocumentListModal.tsx
T

289 lines
8.7 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 { 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 type { ReviewFileUI } from '~/api/evaluation_points/rules-files';
// import { updateDocumentAuditStatus } from '~/api/evaluation_points/rules-files';
import { toastService } from '../ui/Toast';
// 导出样式链接
export const links = () => [];
interface DocumentListModalProps {
isOpen: boolean;
onClose: () => void;
title: string;
files: ReviewFileUI[];
onViewFile?: (fileId: string) => void;
loading?: boolean;
// 分页相关属性
currentPage?: number;
pageSize?: number;
total?: number;
onPageChange?: (page: number) => void;
onPageSizeChange?: (size: number) => void;
}
export function DocumentListModal({
isOpen,
onClose,
title,
files,
onViewFile,
loading = false,
// 分页属性,使用默认值
currentPage = 1,
pageSize = 10,
total = 0,
onPageChange,
onPageSizeChange
}: DocumentListModalProps) {
// 查看评查文件
const handleReviewFileClick = async (fileId: string, auditStatus: number | null) => {
// 检查audit_status是否为0,如果是则更新为2
if (auditStatus === 0 || auditStatus === null) {
try {
// TODO: 这里需要从父组件传递 userId,或者重新设计这个函数的调用方式
// 暂时跳过状态更新,直接进入查看
// const response = await updateDocumentAuditStatus(fileId, 2, userId);
// if (response.error) {
// throw new Error(response.error);
// }
console.warn('DocumentListModal: 跳过审核状态更新,需要传递 userId 参数');
} catch (error) {
console.error('更新文件审核状态时出错:', error);
toastService.error(`更新文件审核状态时出错:${error instanceof Error ? error.message : '未知错误'}`);
return;
}
}
// 如果有自定义的查看处理函数,则调用它
if (onViewFile) {
onViewFile(fileId);
}
};
// 渲染问题摘要
const renderIssues = (file: ReviewFileUI) => {
// 如果文件状态为完成
if (file.status === 'Processed') {
// 如果没有问题,显示"所有评查点均通过"
if (file.warningCount <= 0 && file.failCount <= 0) {
return (
<div className="text-sm text-success">
<i className="ri-check-double-line mr-1"></i>
</div>
);
}
// 显示问题列表
if (file.issues && file.issues.length > 0) {
// 最多显示2个问题
const displayIssues = file.issues.slice(0, 2);
return (
<div className="text-sm">
{displayIssues.map((issue, index) => (
<div key={index} className="mb-1">
<i className="ri-circle-fill mr-1 text-yellow-400"></i>
{issue.message}
</div>
))}
{file.issues.length > 2 && (
<div className="text-secondary mt-1">
{file.issues.length - 2} ...
</div>
)}
</div>
);
}
}
// 其他状态显示占位符
return <div className="text-sm text-secondary">-</div>;
};
// 定义表格列配置
const columns = [
{
title: "文件名称",
key: "fileName",
width: "30%",
render: (_: unknown, file: ReviewFileUI) => (
<div className="flex">
<div className="flex-shrink-0 flex items-center self-center">
<FileIcon fileName={file.fileName} className="text-lg w-10 h-10" />
</div>
<div className="min-w-0 flex-1 flex flex-col py-2 ml-2">
<div className="font-normal text-base break-words whitespace-normal leading-normal" title={file.fileName}>{file.fileName}</div>
<div className="text-xs text-secondary mt-2">
{file.fileCode}
</div>
</div>
</div>
)
},
{
title: "文件类型",
key: "fileType",
width: "12%",
render: (_: unknown, file: ReviewFileUI) => (
<FileTypeTag
type="other"
typeName={file.fileType}
text={file.fileType}
size="sm"
showIcon={false}
colorMode="light"
/>
)
},
{
title: "上传时间",
key: "uploadTime",
width: "12%",
render: (_: unknown, file: ReviewFileUI) => {
const [date, time] = file.uploadTime.split(' ');
return (
<div>
<span className="text-base">{date}</span>
<br />
<span className="text-xs text-secondary">{time}</span>
</div>
);
}
},
{
title: "评查统计",
key: "reviewStatus",
width: "12%",
render: (_: unknown, file: ReviewFileUI) =>
// 要文件切分处理完之后,再显示评查统计
file.status === 'Processed' ? (
<div>
{file.passCount > 0 && (
<StatusBadge
status="pass"
text={`通过(${file.passCount})`}
showIcon={true}
className="my-2"
/>
)}
{file.warningCount > 0 && (
<StatusBadge
status="warning"
text={`警告(${file.warningCount})`}
showIcon={true}
className="my-2"
/>
)}
{file.failCount > 0 && (
<StatusBadge
status="fail"
text={`不通过(${file.failCount})`}
showIcon={true}
className="my-2"
/>
)}
</div>
) : (
<div className="text-sm">
-
</div>
)
},
{
title: "问题摘要",
key: "issues",
width: "20%",
render: (_: unknown, file: ReviewFileUI) => renderIssues(file)
},
{
title: "操作",
key: "operation",
width: "14%",
render: (_: unknown, file: ReviewFileUI) => (
<>
<Button
type="default"
size="small"
icon="ri-eye-line"
onClick={() => handleReviewFileClick(file.id, file.auditStatus)}
disabled={file.status !== 'Processed'}
className="mr-2"
>
</Button>
</>
)
}
];
return (
<Modal
isOpen={isOpen}
onClose={onClose}
title={title}
size="full"
className="document-list-modal"
>
<div className="px-6 py-4">
{loading ? (
// 显示loading状态
<div className="py-8">
<LoadingIndicator text="正在加载文档列表..." />
</div>
) : files.length === 0 ? (
// 无数据状态
<div className="text-center py-8 text-gray-500">
</div>
) : (
// 有数据时显示表格和分页
<>
<div className="mb-4 flex items-center">
<i className="ri-file-list-3-line text-primary text-lg mr-2"></i>
<span className="text-sm text-secondary"></span>
<span className="text-base font-normal text-primary ml-1 mr-1">{total || files.length}</span>
<span className="text-sm text-secondary"></span>
</div>
<Table
columns={columns}
dataSource={files}
rowKey="id"
emptyText="暂无文件数据"
className="files-table table-auto-height"
/>
{/* 分页组件 - 只有在提供了分页回调函数且总数大于每页大小时才显示 */}
{(onPageChange || onPageSizeChange) && total > pageSize ? (
<Pagination
currentPage={currentPage}
total={total}
pageSize={pageSize}
onChange={onPageChange || (() => {})}
onPageSizeChange={onPageSizeChange}
showTotal={true}
showPageSizeChanger={!!onPageSizeChange}
pageSizeOptions={[10, 20, 30, 50]}
/>
) : (
<div className="text-sm text-gray-500 mt-4 text-center">
{total} {pageSize}
{total <= pageSize && " (无需分页)"}
</div>
)}
</>
)}
</div>
</Modal>
);
}