import React, { useEffect, useState } from "react"; import { Button, Flex, Input, Modal, Table, Tag, message } from "antd"; import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction"; import PreviewUrlButton from "~/components/PreviewUrlButton"; import { NODE_LABELS, ARCHIVE_TYPE_MAP, ARCHIVE_RECORD_SOURCE_MAP, } from "~/enumerate/constant"; /** 解析文件地址:相对路径拼接 window.fileUrl(与 PreviewUrlButton 保持一致) */ const resolveFileUrl = (raw) => { if (!raw) return ""; const u = String(raw); return /^https?:\/\//i.test(u) ? u : `${window.fileUrl || ""}${u}`; }; /** 项目档案查看弹窗(原型 modal-reg-project-archive) */ function ArchiveModal({ record, loading, fetchFiles, onClose }) { const [query, setQuery] = useState({ pageIndex: 1, pageSize: 10, fileName: "" }); const [list, setList] = useState([]); const [total, setTotal] = useState(0); const [viewRecord, setViewRecord] = useState(null); useEffect(() => { if (!record?.id) return; fetchFiles({ projectId: record.id, ...query }).then((res) => { if (res?.success !== false) { setList(res?.data || []); setTotal(res?.totalCount || 0); } }); }, [record?.id, query]); /** 单文件下载:跨域地址下 a.download 无效,fetch 转 blob 后再触发下载 */ const downloadArchiveFile = async (f) => { const url = resolveFileUrl(f.url); if (!url) return; const res = await fetch(url); if (!res.ok) throw new Error(`HTTP ${res.status}`); const blobUrl = window.URL.createObjectURL(await res.blob()); const link = document.createElement("a"); link.href = blobUrl; link.download = f.name || ""; link.style.display = "none"; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(blobUrl); }; /** 批量下载 files 数组(逐个串行下载,失败不影响其余文件) */ const handleBatchDownload = async (files) => { for (const f of files || []) { try { await downloadArchiveFile(f); } catch { message.error(`文件下载失败:${f.name || f.url}`); } } }; const columns = [ { title: "序号", width: 60, render: (_, __, index) => (query.pageIndex - 1) * query.pageSize + index + 1, }, { title: "文件名称", dataIndex: "files", ellipsis: true, render: (v, r) => (
{Array.isArray(v) && v.length ? v.map((f) => f.name).join(",") : "-"}
), }, { title: "档案类型", dataIndex: "archiveType", width: 130, }, { title: "来源", dataIndex: "recordSource", width: 120, render: (v) => v ? ( {ARCHIVE_RECORD_SOURCE_MAP[v]} ) : ( "-" ), }, { title: "业务节点", dataIndex: "businessNode", width: 130, render: (v) => NODE_LABELS[v] || v || "-", }, { title: "操作", width: 120, render: (_, r) => ( ), }, ]; const processCount = record?.processFileCount ?? 0; const additionalCount = record?.additionalFileCount ?? 0; return (
项目档案查看
查看项目执行过程中由系统形成及机构补充上传的档案资料
} width={1000} footer={} destroyOnHidden onCancel={onClose} className="epd-archive" >
项目名称 {record?.projectName || "-"} {record?.projectNo}
评价机构 {record?.orgName || "-"}
评价类型 {record?.evalTypeName || "-"}
档案数量 {processCount + additionalCount} 份 流程文档 {processCount} / 补充文件 {additionalCount}
setQuery((q) => ({ ...q, fileName: v, pageIndex: 1 }))} className="epd-archive__search" /> `共 ${t} 条`, onChange: (page, pageSize) => setQuery((q) => ({ ...q, pageIndex: page, pageSize })), }} /> setViewRecord(null)} > {(viewRecord?.files || []).map((f, i) => ( {f.name || "查看文件"} ))} ); } export default ArchiveModal;