safety-eval-service-frontend/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ArchiveContent.js

223 lines
6.4 KiB
JavaScript
Raw Normal View History

2026-07-31 14:08:05 +08:00
import React, { useState, useEffect } from "react";
import {
Tag,
Button,
Card,
Table,
Input,
Flex,
Popover,
Image,
Row,
Col,
DatePicker,
Form,
message,
} from "antd";
import dayjs from "dayjs";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
const { router } = tools;
const ArchiveContent = ({ readOnly, ...props }) => {
const projectId = router.query?.id;
const { processControlDetail, processControlFiles, evalProjectDetailData } =
props.safetyEvalBusiness || {};
const { processControl } = processControlDetail || {};
const [files, setFiles] = useState([]);
const [archiveForm] = Form.useForm();
const fetchDetail = () => {
props.evalProcessControlDetail({ projectId });
};
const fetchFiles = () => {
props.evalProcessControlFiles({ projectId });
};
useEffect(() => {
if (projectId) {
fetchDetail();
fetchFiles();
}
}, [projectId]);
useEffect(() => {
if (processControlDetail) {
archiveForm.setFieldsValue({
projectNo: evalProjectDetailData.projectNo,
archiveTransferorName: processControlDetail.archiveTransferorName || "",
archiveArchivistName: processControlDetail.archiveArchivistName || "",
archiveDate: processControlDetail.archiveDate
? dayjs(processControlDetail.archiveDate)
: null,
});
}
}, [processControlDetail]);
useEffect(() => {
if (processControlFiles) {
setFiles(processControlFiles);
}
}, [processControlFiles]);
const isSignatureCompleted =
processControl?.reviewerSignatureTaskStatus === "completed";
const canArchive = isSignatureCompleted;
const handleArchive = async () => {
if (!projectId) return;
const values = await archiveForm.validateFields();
const res = await props.evalProcessControlArchive({ projectId, ...values });
if (res?.success !== false) {
message.success("项目已归档入库");
fetchDetail();
props.getDetail?.();
}
};
const isImage = (name) =>
/\.(jpg|jpeg|png|gif|webp|bmp|svg)$/i.test(name || "");
const fileColumns = [
{ title: "流程名称", dataIndex: "processName", ellipsis: true },
{ title: "条目名称", dataIndex: "itemName", ellipsis: true },
{
title: "文件",
dataIndex: "projectDocUrl",
render: (val) => {
let fileList = [];
if (typeof val === "string") {
try {
fileList = JSON.parse(val);
} catch {
fileList = [];
}
} else if (Array.isArray(val)) {
fileList = val;
}
if (!fileList.length) return "-";
return (
<Flex vertical gap={2}>
<Popover
title="附件列表"
content={
<Flex vertical gap={4}>
{fileList.map((f, i) => {
const url = f.url || f.response?.url;
return isImage(f.name) ? (
<Flex key={f.uid || i} align="center" gap={4}>
{<Image src={url} width={80} />}
</Flex>
) : (
<a
key={f.uid || i}
style={{ cursor: "pointer" }}
onClick={() => window.open(url)}
>
{f.name || "查看文件"}
</a>
);
})}
</Flex>
}
trigger="hover"
placement="topLeft"
>
<a
onClick={(e) => e.preventDefault()}
style={{ cursor: "pointer" }}
>
{fileList.length}个附件
</a>
</Popover>
</Flex>
);
},
},
];
return (
<Card
title="项目归档"
style={{ marginBottom: 16 }}
styles={{ body: { paddingBottom: 0 } }}
>
<div className="pf-permission">
<Tag color="blue" className="pf-tag">
项目归档
</Tag>
<span className="pf-desc">
项目过程文件清单确认签字完成后归档入库
</span>
</div>
<Table
dataSource={files}
columns={fileColumns}
rowKey={(record) =>
`${record.processName}-${record.materialName}-${record.itemName}`
}
pagination={false}
size="small"
/>
<Form form={archiveForm} layout="vertical" disabled={readOnly}>
<Row gutter={16} style={{ marginTop: 16, marginBottom: 16 }}>
<Col span={6}>
<Form.Item label="项目编号" name="projectNo">
<Input placeholder="请输入项目编号" disabled />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item label="移交人" name="archiveTransferorName" rules={[{ required: true, message: "请输入移交人" }]}>
<Input placeholder="请输入移交人" allowClear maxLength={10} />
</Form.Item>
</Col>
<Col span={6}>
<Form.Item label="档案管理员" name="archiveArchivistName" rules={[{ required: true, message: "请输入档案管理员" }]}>
<Input placeholder="请输入档案管理员" allowClear maxLength={10} />
</Form.Item>
</Col>
{processControlDetail?.archiveDate && (
<Col span={6}>
<Form.Item label="入库日期" name="archiveDate">
<DatePicker style={{ width: "100%" }} disabled />
</Form.Item>
</Col>
)}
</Row>
</Form>
<Flex
justify="space-between"
align="center"
style={{ marginTop: 12, paddingBottom: 16 }}
>
{!readOnly && (
<Button
type="primary"
onClick={handleArchive}
loading={props.safetyEvalBusiness?.processControlArchiveLoading}
disabled={!canArchive}
title={
!canArchive
? !isSignatureCompleted
? "需签字完成后才可归档"
: "需生成归档交接单后才可归档"
: ""
}
>
双方签字并确认入库
</Button>
)}
</Flex>
</Card>
);
};
export default Connect([NS_SAFETY_EVAL_BUSINESS], true)(ArchiveContent);