safety-eval-service-frontend/src/pages/Container/QualApplication/FilingForm/components/PersonnelStep.jsx

222 lines
6.9 KiB
React
Raw Normal View History

2026-06-30 17:32:29 +08:00
import { Button, Modal, Space, Table } from "antd";
2026-08-08 17:52:31 +08:00
import { useState } from "react";
import { CAPABILITY_MAP, CERT_LEVEL_LABEL_BY_TYPE } from "~/enumerate/constant";
import {
TITLE_LEVEL_MAP,
2026-08-14 14:40:46 +08:00
QUALIFICATION_INDUSTRY_OPTIONS_MAP,
2026-08-08 17:52:31 +08:00
} from "~/enumerate/enterpriseOptions";
2026-07-09 09:23:22 +08:00
import StaffViewModal from "~/components/StaffViewModal";
2026-06-30 17:32:29 +08:00
import OrgPersonnelSelectModal from "./OrgPersonnelSelectModal";
2026-08-08 17:52:31 +08:00
const PersonnelStep = ({ personnelList = [], disabled, onAdd, onRemove, managementFlag }) => {
2026-06-30 17:32:29 +08:00
const [selectOpen, setSelectOpen] = useState(false);
const [viewId, setViewId] = useState("");
2026-07-15 16:13:07 +08:00
const [selectedRowKeys, setSelectedRowKeys] = useState([]);
2026-06-30 17:32:29 +08:00
2026-08-08 17:52:31 +08:00
const existingIds = personnelList.map((item) =>
String(item.sourcePersonnelId || item.id || ""),
2026-08-05 09:11:32 +08:00
);
2026-07-15 16:13:07 +08:00
const handleBatchRemove = () => {
const records = selectedRowKeys
2026-08-08 17:52:31 +08:00
.map((key) =>
personnelList.find(
(item) => String(item.sourcePersonnelId || item.id) === key,
),
)
2026-07-15 16:13:07 +08:00
.filter(Boolean);
if (records.length > 0) {
onRemove?.(records);
}
};
2026-06-30 17:32:29 +08:00
return (
<>
2026-08-08 17:52:31 +08:00
<div
style={{
display: "flex",
justifyContent: "space-between",
marginBottom: 12,
}}
>
2026-06-30 17:32:29 +08:00
<span style={{ fontWeight: 600 }}>
备案人员信息
2026-08-08 17:52:31 +08:00
<span
style={{
marginLeft: 8,
color: "rgba(0,0,0,0.45)",
fontWeight: 400,
}}
>
2026-06-30 17:32:29 +08:00
当前 {personnelList.length}
</span>
</span>
{!disabled && (
2026-07-15 16:13:07 +08:00
<Space size="small">
2026-08-08 17:52:31 +08:00
<Button
type="primary"
size="small"
onClick={() => setSelectOpen(true)}
>
添加人员信息
</Button>
2026-07-15 16:13:07 +08:00
{selectedRowKeys.length > 0 && (
2026-08-08 17:52:31 +08:00
<Button danger size="small" onClick={handleBatchRemove}>
批量删除
</Button>
2026-07-15 16:13:07 +08:00
)}
</Space>
2026-06-30 17:32:29 +08:00
)}
</div>
<Table
size="small"
2026-07-15 16:13:07 +08:00
rowKey={(record) => String(record.sourcePersonnelId || record.id)}
2026-06-30 17:32:29 +08:00
pagination={false}
2026-08-05 09:11:32 +08:00
scroll={{ x: 1200, y: 400 }}
2026-08-08 17:52:31 +08:00
dataSource={personnelList}
rowSelection={
!disabled
? {
selectedRowKeys,
onChange: setSelectedRowKeys,
2026-08-10 17:15:41 +08:00
fixed: "left",
2026-08-08 17:52:31 +08:00
}
: undefined
}
2026-06-30 17:32:29 +08:00
columns={[
{ title: "序号", width: 60, render: (_, __, index) => index + 1 },
2026-08-08 17:52:31 +08:00
{ title: "姓名", dataIndex: "personName" },
2026-08-10 10:10:11 +08:00
managementFlag&&{
2026-08-08 17:52:31 +08:00
title: "职务",
width: 120,
2026-08-10 09:45:05 +08:00
render: (_, record) => {
const roles = [];
if (record.technicalDirectorFlag === true) roles.push("技术负责人");
if (record.processControlLeaderFlag === true) roles.push("过程控制负责人");
return roles.length ? roles.join("、") : "-";
},
2026-08-08 17:52:31 +08:00
},
2026-08-10 10:10:11 +08:00
!managementFlag&&{
2026-08-08 17:52:31 +08:00
title: "职称",
dataIndex: "titleCodeArr",
width: 100,
render: (list) => {
if (!Array.isArray(list) || !list.length) return "-";
return list
.map(
(item) => TITLE_LEVEL_MAP[item.titleCode] || item.titleCode,
)
.join("、");
},
},
2026-08-05 09:11:32 +08:00
{
2026-08-08 16:44:49 +08:00
title: "专业能力",
2026-08-08 17:52:31 +08:00
dataIndex: "capabilityAssessment",
render: (list) => {
if (!Array.isArray(list) || !list.length) return "-";
return list
2026-08-14 14:40:46 +08:00
.map((item) => {
const cap =
2026-08-08 17:52:31 +08:00
CAPABILITY_MAP[item.professionalCapabilityCode] ||
2026-08-14 14:40:46 +08:00
item.professionalCapabilityCode;
if (!cap) return null;
const industry = item.industryCode
? QUALIFICATION_INDUSTRY_OPTIONS_MAP[item.industryCode]
: null;
return industry ? `${industry}${cap}` : cap;
})
.filter(Boolean)
2026-08-08 17:52:31 +08:00
.join("、");
},
},
{
title: "职业资格等级及证书编号",
dataIndex: "personnelCertFilingPageCOList",
width: 200,
render: (_, record) => {
const cert = (record.personnelCertFilingPageCOList || []).find(
(item) => item.certTypeCode === "evaluator",
);
if (!cert) return "否";
const levelMap = CERT_LEVEL_LABEL_BY_TYPE.evaluator || {};
return (
<div>
<div>{levelMap[cert.certLevel] || cert.certLevel || "-"}</div>
<div style={{ color: "rgba(0,0,0,0.45)" }}>
{cert.certNo || "-"}
</div>
</div>
);
},
},
{
title: "是否具有注册安全工程师资格",
width: 200,
2026-08-05 09:11:32 +08:00
render: (_, record) => {
2026-08-08 17:52:31 +08:00
const cert = (record.personnelCertFilingPageCOList || []).find(
(item) => item.certTypeCode === "registered_safety_engineer",
);
if (!cert) return "否";
const levelMap =
CERT_LEVEL_LABEL_BY_TYPE.registered_safety_engineer || {};
return (
<div>
<div>{levelMap[cert.certLevel] || cert.certLevel || "-"}</div>
<div style={{ color: "rgba(0,0,0,0.45)" }}>
{cert.certNo || "-"}
</div>
</div>
);
2026-08-05 09:11:32 +08:00
},
},
2026-06-30 17:32:29 +08:00
{
title: "操作",
width: 140,
2026-08-05 09:11:32 +08:00
fixed: "right",
2026-06-30 17:32:29 +08:00
render: (_, record) => (
<Space size="small">
<Button
type="link"
size="small"
2026-08-08 17:52:31 +08:00
onClick={() =>
setViewId(record.sourcePersonnelId || record.id)
}
2026-06-30 17:32:29 +08:00
>
查看
</Button>
{!disabled && (
2026-08-08 17:52:31 +08:00
<Button
type="link"
size="small"
danger
onClick={() => onRemove?.(record)}
>
删除
</Button>
2026-06-30 17:32:29 +08:00
)}
</Space>
),
},
2026-08-10 10:10:11 +08:00
].filter(Boolean)}
2026-06-30 17:32:29 +08:00
/>
<OrgPersonnelSelectModal
open={selectOpen}
existingIds={existingIds}
2026-08-08 17:52:31 +08:00
managementFlag={managementFlag}
2026-06-30 17:32:29 +08:00
onCancel={() => setSelectOpen(false)}
onConfirm={(ids, rows) => {
onAdd?.(ids, rows);
setSelectOpen(false);
}}
/>
<StaffViewModal
open={!!viewId}
currentId={viewId}
2026-08-08 17:52:31 +08:00
2026-06-30 17:32:29 +08:00
onCancel={() => setViewId("")}
/>
</>
);
2026-08-08 17:52:31 +08:00
};
2026-07-10 14:38:17 +08:00
export default PersonnelStep;