import React, { useState, useEffect } from "react";
import { Form, Button, Flex, Typography, Steps, Tag, Card, Table, message } from "antd";
import { CheckCircleFilled, DownloadOutlined } from "@ant-design/icons";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { tools } from "@cqsjjb/jjb-common-lib";
import AttachmentUpload from "~/components/AttachmentUpload";
import "./index.less";
const { router } = tools;
const STAGES = [
{ key: "notice", index: "01", label: "从业告知" },
{ key: "inspection", index: "02", label: "现场勘查" },
{ key: "rectification", index: "03", label: "整改通知" },
{ key: "enterprise", index: "04", label: "企业整改" },
{ key: "review", index: "05", label: "整改复查" },
];
const ATTACH_TYPE = {
notice: "PRACTICE_NOTIFICATION",
inspection: "SITE_INSPECTION_FORM",
rectification: "RECTIFICATION_NOTICE",
enterprise: "ENTERPRISE_RECTIFICATION",
review: "RECTIFICATION_REVIEW",
};
const downloadTemplate = async () => {
try {
const res = await fetch("https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a608cb30dc53ed98d0b13ae.pdf");
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "从业告知书模板.pdf";
a.click();
URL.revokeObjectURL(url);
} catch {
message.error("下载失败,请重试");
}
};
const NoticePanel = () => (
01
安全评价检测检验机构从业告知书
支持在线填写后打印;阶段试行期间,以机构盖章版上传归档作为完成依据。
办理方式
在线填写用于生成、打印标准告知书
打印盖章后上传扫描件或清晰照片
完成节点必须留存盖章件
📄
从业告知书模板
PDF 格式,可下载后在线填写并打印盖章
} onClick={downloadTemplate}>
下载模板
);
const InspectionPanel = () => (
02
现场人员打卡与检查表
主要核验项目组人员是否真实到场,留存APP人脸、GPS、签到签退、现场照片及本人签字记录。
打卡与检查表完整
{v} },
{ title: "GPS定位", dataIndex: "gps", render: (v) => {v} },
{ title: "签到时间", dataIndex: "signIn" },
{ title: "签退时间", dataIndex: "signOut" },
{ title: "在场时长", dataIndex: "duration" },
{ title: "现场照片", dataIndex: "photos", render: (v) => },
{ title: "本人签字", dataIndex: "sign", render: (v) => {v} },
]}
rowKey="name"
pagination={false}
size="small"
/>
打卡企业地址:重庆市渝北区化工园区东路18号
允许打卡范围:企业地址周边500米
签到日期:2026-07-15
);
const SimpleUploadPanel = ({ index, title, desc }) => (
);
const STEP_PANELS = {
notice: () => ,
inspection: () => ,
rectification: () => (
),
enterprise: () => (
),
review: () => (
),
};
const SurveyContent = (props) => {
const [form] = Form.useForm();
const [activeStage, setActiveStage] = useState("notice");
const [attachMap, setAttachMap] = useState({});
const { evalSurveyListLoading, evalSurveySaveAttachLoading } = props.safetyEvalBusiness;
const projectId = router.query?.id;
const currentIdx = STAGES.findIndex((s) => s.key === activeStage);
const isFirst = currentIdx === 0;
const isLast = currentIdx === STAGES.length - 1;
const loadAttachments = async () => {
if (!projectId) return;
const res = await props.evalSurveyList({ projectId });
if (res?.success !== false) {
const map = {};
(res?.data || []).forEach((item) => {
const key = item.attachTypeCode;
try {
const parsed = JSON.parse(item.fileUrl);
map[key] = Array.isArray(parsed) ? parsed : [];
} catch {
map[key] = [];
}
});
setAttachMap(map);
// 回填所有步骤的附件到表单
const values = {};
Object.entries(ATTACH_TYPE).forEach(([, typeCode]) => {
values[typeCode] = map[typeCode] || [];
});
form.setFieldsValue(values);
}
};
useEffect(() => {
loadAttachments();
}, []);
const goPrev = () => {
if (currentIdx > 0) setActiveStage(STAGES[currentIdx - 1].key);
};
const goNext = () => {
if (currentIdx < STAGES.length - 1) setActiveStage(STAGES[currentIdx + 1].key);
};
const handleSave = async () => {
const values = form.getFieldsValue();
const payload = [];
for (const [key, typeCode] of Object.entries(ATTACH_TYPE)) {
const fileList = values[typeCode] || [];
const validFiles = fileList.filter((f) => f.status === "done" && f.url);
if (validFiles.length === 0) {
setActiveStage(key);
message.warning(`请先在"${STAGES.find((s) => s.key === key).label}"步骤上传附件`);
return;
}
payload.push({
projectId,
attachTypeCode: typeCode,
fileUrl: JSON.stringify(fileList),
});
}
const res = await props.evalSurveySaveAttach(payload);
if (res?.success !== false) {
message.success("保存成功");
props.getDetail();
}
};
return (
setActiveStage(STAGES[idx].key)}
style={{ marginBottom: 16 }}
items={STAGES.map((s) => ({ title: s.label }))}
/>
{STEP_PANELS[activeStage]()}
{!isFirst && }
{isLast ? (
) : (
)}
);
};
export default Connect(
[NS_SAFETY_EVAL_BUSINESS],
true,
)(SurveyContent);