feat
parent
0bc60e970e
commit
273cb8d6ec
|
|
@ -301,10 +301,10 @@ export const evalProcessControlFiles = declareRequest(
|
||||||
"processControlFiles: [] | res.data || []",
|
"processControlFiles: [] | res.data || []",
|
||||||
);
|
);
|
||||||
|
|
||||||
/** 项目档案文件列表-机构端分页(分页参数 pageIndex/pageSize,总数 totalCount) */
|
/** 项目档案文件列表-机构端 */
|
||||||
export const evalProjectArchiveFileOrgPage = declareRequest(
|
export const evalProjectArchiveFileOrgPage = declareRequest(
|
||||||
"evalProjectArchiveFileOrgLoading",
|
"evalProjectArchiveFileOrgLoading",
|
||||||
"Get > /safetyEval/eval-project-archive-file/org/page",
|
"Get > /safetyEval/eval-project-archive-file/org/list",
|
||||||
);
|
);
|
||||||
|
|
||||||
/** 新增项目档案文件(机构补充上传) */
|
/** 新增项目档案文件(机构补充上传) */
|
||||||
|
|
|
||||||
|
|
@ -444,11 +444,11 @@ export const WARING_STATUS_OPTIONS = [
|
||||||
|
|
||||||
export const NODE_LABELS = {
|
export const NODE_LABELS = {
|
||||||
RISK_ANALYSIS: "风险分析",
|
RISK_ANALYSIS: "风险分析",
|
||||||
BUSINESS_CONTRACT: "商务合同",
|
BUSINESS_CONTRACT: "业务合同",
|
||||||
PROJECT_GROUP: "项目组",
|
PROJECT_GROUP: "项目组",
|
||||||
SITE_SURVEY: "现场勘查",
|
SITE_SURVEY: "现场踏勘",
|
||||||
REPORT_PREPARATION: "报告编制",
|
REPORT_PREPARATION: "报告编制",
|
||||||
INTERNAL_REVIEW: "内审",
|
INTERNAL_REVIEW: "内部审核",
|
||||||
TECHNICAL_REVIEW: "技术审核",
|
TECHNICAL_REVIEW: "技术审核",
|
||||||
PROCESS_CONTROL: "过程控制",
|
PROCESS_CONTROL: "过程控制",
|
||||||
ARCHIVE: "项目归档",
|
ARCHIVE: "项目归档",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect, useMemo } from "react";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Table,
|
Table,
|
||||||
|
|
@ -9,6 +9,7 @@ import {
|
||||||
Col,
|
Col,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
Form,
|
Form,
|
||||||
|
Modal,
|
||||||
message,
|
message,
|
||||||
} from "antd";
|
} from "antd";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
@ -20,7 +21,7 @@ import LayoutFooterPortal from "~/components/LayoutFooterPortal";
|
||||||
import PreviewUrlButton from "~/components/PreviewUrlButton";
|
import PreviewUrlButton from "~/components/PreviewUrlButton";
|
||||||
import ArchiveSupplementModal from "./ArchiveSupplementModal";
|
import ArchiveSupplementModal from "./ArchiveSupplementModal";
|
||||||
import {
|
import {
|
||||||
|
NODE_LABELS,
|
||||||
ARCHIVE_RECORD_SOURCE_OPTIONS,
|
ARCHIVE_RECORD_SOURCE_OPTIONS,
|
||||||
ARCHIVE_RECORD_SOURCE_BADGE_MAP,
|
ARCHIVE_RECORD_SOURCE_BADGE_MAP,
|
||||||
} from "~/enumerate/constant";
|
} from "~/enumerate/constant";
|
||||||
|
|
@ -35,13 +36,10 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
|
|
||||||
const [archiveForm] = Form.useForm();
|
const [archiveForm] = Form.useForm();
|
||||||
const [archiveFiles, setArchiveFiles] = useState([]);
|
const [archiveFiles, setArchiveFiles] = useState([]);
|
||||||
const [archiveTotal, setArchiveTotal] = useState(0);
|
const [sourceFilter, setSourceFilter] = useState("");
|
||||||
const [archiveQuery, setArchiveQuery] = useState({
|
const [keyword, setKeyword] = useState("");
|
||||||
pageIndex: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
recordSource: "",
|
|
||||||
});
|
|
||||||
const [supplementOpen, setSupplementOpen] = useState(false);
|
const [supplementOpen, setSupplementOpen] = useState(false);
|
||||||
|
const [viewRecord, setViewRecord] = useState(null);
|
||||||
|
|
||||||
const fetchDetail = () => {
|
const fetchDetail = () => {
|
||||||
props.evalProcessControlDetail({ projectId });
|
props.evalProcessControlDetail({ projectId });
|
||||||
|
|
@ -67,25 +65,32 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
}, [processControlDetail]);
|
}, [processControlDetail]);
|
||||||
|
|
||||||
const fetchArchiveFiles = () => {
|
const fetchArchiveFiles = () => {
|
||||||
props
|
props.evalProjectArchiveFileOrgPage({ projectId }).then((res) => {
|
||||||
.evalProjectArchiveFileOrgPage({
|
if (res?.success !== false) {
|
||||||
projectId,
|
setArchiveFiles(res?.data || []);
|
||||||
pageIndex: archiveQuery.pageIndex,
|
}
|
||||||
pageSize: archiveQuery.pageSize,
|
});
|
||||||
recordSource: archiveQuery.recordSource || undefined,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res?.success !== false) {
|
|
||||||
setArchiveFiles(res?.data || []);
|
|
||||||
setArchiveTotal(res?.totalCount || 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!projectId) return;
|
if (!projectId) return;
|
||||||
fetchArchiveFiles();
|
fetchArchiveFiles();
|
||||||
}, [projectId, archiveQuery]);
|
}, [projectId]);
|
||||||
|
|
||||||
|
/** 本地筛选:来源 + 文件名称/档案类型关键字 */
|
||||||
|
const filteredArchiveFiles = useMemo(() => {
|
||||||
|
const kw = keyword.trim().toLowerCase();
|
||||||
|
return archiveFiles.filter((item) => {
|
||||||
|
const matchSource = !sourceFilter || item.recordSource === sourceFilter;
|
||||||
|
const matchKeyword =
|
||||||
|
!kw ||
|
||||||
|
(item.files || []).some((f) =>
|
||||||
|
(f.name || "").toLowerCase().includes(kw),
|
||||||
|
) ||
|
||||||
|
(item.archiveType || "").toLowerCase().includes(kw);
|
||||||
|
return matchSource && matchKeyword;
|
||||||
|
});
|
||||||
|
}, [archiveFiles, sourceFilter, keyword]);
|
||||||
|
|
||||||
const isSignatureCompleted =
|
const isSignatureCompleted =
|
||||||
processControl?.reviewerSignatureTaskStatus === "completed";
|
processControl?.reviewerSignatureTaskStatus === "completed";
|
||||||
|
|
@ -109,35 +114,54 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
return /^https?:\/\//i.test(u) ? u : `${window.fileUrl || ""}${u}`;
|
return /^https?:\/\//i.test(u) ? u : `${window.fileUrl || ""}${u}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDownload = (file) => {
|
/** 单文件下载:跨域地址下 a.download 无效,fetch 转 blob 后再触发下载 */
|
||||||
const url = resolveFileUrl(file.fileUrl);
|
const downloadArchiveFile = async (f) => {
|
||||||
|
const url = resolveFileUrl(f.url);
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const a = document.createElement("a");
|
const res = await fetch(url);
|
||||||
a.href = url;
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||||
a.download = file.fileName || "";
|
const blobUrl = window.URL.createObjectURL(await res.blob());
|
||||||
a.target = "_blank";
|
const link = document.createElement("a");
|
||||||
document.body.appendChild(a);
|
link.href = blobUrl;
|
||||||
a.click();
|
link.download = f.name || "";
|
||||||
document.body.removeChild(a);
|
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 archiveColumns = [
|
const archiveColumns = [
|
||||||
{
|
{
|
||||||
title: "序号",
|
title: "序号",
|
||||||
width: 60,
|
width: 60,
|
||||||
render: (_, __, index) =>
|
render: (_, __, index) => index + 1,
|
||||||
(archiveQuery.pageIndex - 1) * archiveQuery.pageSize + index + 1,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "文件名称",
|
title: "文件名称",
|
||||||
dataIndex: "fileName",
|
dataIndex: "files",
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (v) => v || "-",
|
render: (v) => {
|
||||||
|
if(Array.isArray(v)){
|
||||||
|
return v.map(v=>v.name).join(',')
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "档案类型",
|
title: "档案类型",
|
||||||
dataIndex: "archiveType",
|
dataIndex: "archiveType",
|
||||||
width: 130,
|
width: 180,
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +176,7 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
>
|
>
|
||||||
{ARCHIVE_RECORD_SOURCE_BADGE_MAP[v] || v || "-"}
|
{ARCHIVE_RECORD_SOURCE_BADGE_MAP[v] || v || "-"}
|
||||||
</span>
|
</span>
|
||||||
<span className="pf-archive__node">{r.businessNode || "-"}</span>
|
<span className="pf-archive__node">{NODE_LABELS[r.businessNode] || "-"}</span>
|
||||||
</Flex>
|
</Flex>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -165,8 +189,7 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
{
|
{
|
||||||
title: "形成时间",
|
title: "形成时间",
|
||||||
dataIndex: "createTime",
|
dataIndex: "createTime",
|
||||||
width: 160,
|
width: 200,
|
||||||
align: "right",
|
|
||||||
render: (v) => v || "-",
|
render: (v) => v || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -174,12 +197,19 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
width: 110,
|
width: 110,
|
||||||
render: (_, r) => (
|
render: (_, r) => (
|
||||||
<TableAction>
|
<TableAction>
|
||||||
<PreviewUrlButton url={r.fileUrl}>查看</PreviewUrlButton>
|
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
disabled={!r.fileUrl}
|
disabled={!r.files?.length}
|
||||||
onClick={() => handleDownload(r)}
|
onClick={() => setViewRecord(r)}
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
disabled={!r.files?.length}
|
||||||
|
onClick={() => handleBatchDownload(r.files)}
|
||||||
>
|
>
|
||||||
下载
|
下载
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -194,12 +224,17 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
<Flex justify="flex-end" className="pf-archive__toolbar">
|
<Flex justify="space-between" className="pf-archive__toolbar">
|
||||||
|
<Input.Search
|
||||||
|
placeholder="搜索文件名称或档案类型"
|
||||||
|
allowClear
|
||||||
|
onChange={(e) => setKeyword(e.target.value)}
|
||||||
|
onSearch={setKeyword}
|
||||||
|
className="pf-archive__keyword-input"
|
||||||
|
/>
|
||||||
<Select
|
<Select
|
||||||
value={archiveQuery.recordSource}
|
value={sourceFilter}
|
||||||
onChange={(v) =>
|
onChange={setSourceFilter}
|
||||||
setArchiveQuery((q) => ({ ...q, recordSource: v, pageIndex: 1 }))
|
|
||||||
}
|
|
||||||
options={[
|
options={[
|
||||||
{ label: "全部来源", value: "" },
|
{ label: "全部来源", value: "" },
|
||||||
...ARCHIVE_RECORD_SOURCE_OPTIONS,
|
...ARCHIVE_RECORD_SOURCE_OPTIONS,
|
||||||
|
|
@ -211,18 +246,10 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
<Table
|
<Table
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
size="small"
|
size="small"
|
||||||
dataSource={archiveFiles}
|
dataSource={filteredArchiveFiles}
|
||||||
columns={archiveColumns}
|
columns={archiveColumns}
|
||||||
loading={props.safetyEvalBusiness?.evalProjectArchiveFileOrgLoading}
|
loading={props.safetyEvalBusiness?.evalProjectArchiveFileOrgLoading}
|
||||||
pagination={{
|
pagination={false}
|
||||||
total: archiveTotal,
|
|
||||||
current: archiveQuery.pageIndex,
|
|
||||||
pageSize: archiveQuery.pageSize,
|
|
||||||
showQuickJumper: true,
|
|
||||||
showTotal: (t) => `共 ${t} 条`,
|
|
||||||
onChange: (page, pageSize) =>
|
|
||||||
setArchiveQuery((q) => ({ ...q, pageIndex: page, pageSize })),
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Form form={archiveForm} layout="vertical" disabled={readOnly} scrollToFirstError>
|
<Form form={archiveForm} layout="vertical" disabled={readOnly} scrollToFirstError>
|
||||||
|
|
@ -281,6 +308,23 @@ const ArchiveContent = ({ readOnly, ...props }) => {
|
||||||
fetchArchiveFiles();
|
fetchArchiveFiles();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
open={!!viewRecord}
|
||||||
|
title="查看档案文件"
|
||||||
|
width={640}
|
||||||
|
footer={null}
|
||||||
|
destroyOnHidden
|
||||||
|
onCancel={() => setViewRecord(null)}
|
||||||
|
>
|
||||||
|
<Flex gap={8}>
|
||||||
|
{(viewRecord?.files || []).map((f, i) => (
|
||||||
|
<PreviewUrlButton key={f.url || i} url={f.url}>
|
||||||
|
{f.name || "查看文件"}
|
||||||
|
</PreviewUrlButton>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ function ArchiveSupplementModal({
|
||||||
|
|
||||||
const handleOk = async () => {
|
const handleOk = async () => {
|
||||||
const values = await form.validateFields();
|
const values = await form.validateFields();
|
||||||
const fileList = values.file || [];
|
const fileList = values.files || [];
|
||||||
if (fileList.some((f) => f.status === "uploading")) {
|
if (fileList.some((f) => f.status === "uploading")) {
|
||||||
message.warning("文件正在上传中,请等待上传完成");
|
message.warning("文件正在上传中,请等待上传完成");
|
||||||
return;
|
return;
|
||||||
|
|
@ -34,7 +34,7 @@ function ArchiveSupplementModal({
|
||||||
businessNode: "文档上传",
|
businessNode: "文档上传",
|
||||||
recordSource: "upload_additional_files",
|
recordSource: "upload_additional_files",
|
||||||
remark: values.remark,
|
remark: values.remark,
|
||||||
file: doneFiles,
|
files: doneFiles,
|
||||||
});
|
});
|
||||||
if (res?.success === false) return;
|
if (res?.success === false) return;
|
||||||
message.success("补充档案已上传");
|
message.success("补充档案已上传");
|
||||||
|
|
@ -72,7 +72,7 @@ function ArchiveSupplementModal({
|
||||||
<TextArea rows={3} placeholder="填写资料内容或补充说明" maxLength={500} />
|
<TextArea rows={3} placeholder="填写资料内容或补充说明" maxLength={500} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<AttachmentUpload
|
<AttachmentUpload
|
||||||
name="file"
|
name="files"
|
||||||
label="资料上传"
|
label="资料上传"
|
||||||
rules={[{ required: true, message: "请选择需要上传的文件" }]}
|
rules={[{ required: true, message: "请选择需要上传的文件" }]}
|
||||||
extra="支持上传多个文件"
|
extra="支持上传多个文件"
|
||||||
|
|
|
||||||
|
|
@ -298,6 +298,10 @@
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__keyword-input {
|
||||||
|
width: 260px;
|
||||||
|
}
|
||||||
|
|
||||||
&__source-select {
|
&__source-select {
|
||||||
width: 140px;
|
width: 140px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { Button, Input, Modal, Table, Tag } from "antd";
|
import { Button, Flex, Input, Modal, Table, Tag, message } from "antd";
|
||||||
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
||||||
import PreviewUrlButton from "~/components/PreviewUrlButton";
|
import PreviewUrlButton from "~/components/PreviewUrlButton";
|
||||||
import {
|
import {
|
||||||
|
NODE_LABELS,
|
||||||
ARCHIVE_TYPE_MAP,
|
ARCHIVE_TYPE_MAP,
|
||||||
ARCHIVE_RECORD_SOURCE_MAP,
|
ARCHIVE_RECORD_SOURCE_MAP,
|
||||||
} from "~/enumerate/constant";
|
} from "~/enumerate/constant";
|
||||||
|
|
@ -19,6 +20,7 @@ function ArchiveModal({ record, loading, fetchFiles, onClose }) {
|
||||||
const [query, setQuery] = useState({ pageIndex: 1, pageSize: 10, fileName: "" });
|
const [query, setQuery] = useState({ pageIndex: 1, pageSize: 10, fileName: "" });
|
||||||
const [list, setList] = useState([]);
|
const [list, setList] = useState([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
const [viewRecord, setViewRecord] = useState(null);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -32,16 +34,32 @@ function ArchiveModal({ record, loading, fetchFiles, onClose }) {
|
||||||
});
|
});
|
||||||
}, [record?.id, query]);
|
}, [record?.id, query]);
|
||||||
|
|
||||||
const handleDownload = (file) => {
|
/** 单文件下载:跨域地址下 a.download 无效,fetch 转 blob 后再触发下载 */
|
||||||
const url = resolveFileUrl(file.fileUrl);
|
const downloadArchiveFile = async (f) => {
|
||||||
|
const url = resolveFileUrl(f.url);
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const a = document.createElement("a");
|
const res = await fetch(url);
|
||||||
a.href = url;
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
||||||
a.download = file.fileName || "";
|
const blobUrl = window.URL.createObjectURL(await res.blob());
|
||||||
a.target = "_blank";
|
const link = document.createElement("a");
|
||||||
document.body.appendChild(a);
|
link.href = blobUrl;
|
||||||
a.click();
|
link.download = f.name || "";
|
||||||
document.body.removeChild(a);
|
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 = [
|
const columns = [
|
||||||
|
|
@ -53,17 +71,17 @@ function ArchiveModal({ record, loading, fetchFiles, onClose }) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "文件名称",
|
title: "文件名称",
|
||||||
dataIndex: "fileName",
|
dataIndex: "files",
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
render: (v, r) => (
|
render: (v, r) => (
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div>{v || "-"}</div>
|
{Array.isArray(v) && v.length
|
||||||
<div className="epd-archive__file-source">
|
? v.map((f) => f.name).join(",")
|
||||||
{r.recordSource === "upload_additional_files"
|
: "-"}
|
||||||
? "评价机构补充上传"
|
|
||||||
: "业务节点自动归集"}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -89,19 +107,26 @@ function ArchiveModal({ record, loading, fetchFiles, onClose }) {
|
||||||
title: "业务节点",
|
title: "业务节点",
|
||||||
dataIndex: "businessNode",
|
dataIndex: "businessNode",
|
||||||
width: 130,
|
width: 130,
|
||||||
render: (v) => v || "-",
|
render: (v) => NODE_LABELS[v] || v || "-",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "操作",
|
title: "操作",
|
||||||
width: 120,
|
width: 120,
|
||||||
render: (_, r) => (
|
render: (_, r) => (
|
||||||
<TableAction>
|
<TableAction>
|
||||||
<PreviewUrlButton url={r.fileUrl}>查看</PreviewUrlButton>
|
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
size="small"
|
size="small"
|
||||||
disabled={!r.fileUrl}
|
disabled={!r.files?.length}
|
||||||
onClick={() => handleDownload(r)}
|
onClick={() => setViewRecord(r)}
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
disabled={!r.files?.length}
|
||||||
|
onClick={() => handleBatchDownload(r.files)}
|
||||||
>
|
>
|
||||||
下载
|
下载
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -178,6 +203,23 @@ function ArchiveModal({ record, loading, fetchFiles, onClose }) {
|
||||||
setQuery((q) => ({ ...q, pageIndex: page, pageSize })),
|
setQuery((q) => ({ ...q, pageIndex: page, pageSize })),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
open={!!viewRecord}
|
||||||
|
title="查看档案文件"
|
||||||
|
width={640}
|
||||||
|
footer={null}
|
||||||
|
destroyOnHidden
|
||||||
|
onCancel={() => setViewRecord(null)}
|
||||||
|
>
|
||||||
|
<Flex gap={8}>
|
||||||
|
{(viewRecord?.files || []).map((f, i) => (
|
||||||
|
<PreviewUrlButton key={f.url || i} url={f.url}>
|
||||||
|
{f.name || "查看文件"}
|
||||||
|
</PreviewUrlButton>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue