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) => (