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 {
|
|
|
|
|
PERSONNEL_POST_TYPE_MAP,
|
|
|
|
|
TITLE_LEVEL_MAP,
|
|
|
|
|
} 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,
|
|
|
|
|
}
|
|
|
|
|
: 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" },
|
|
|
|
|
{
|
|
|
|
|
title: "职务",
|
|
|
|
|
dataIndex: "personnelPositionType",
|
|
|
|
|
width: 120,
|
|
|
|
|
render: (v) => PERSONNEL_POST_TYPE_MAP[v] || "-",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
.map(
|
|
|
|
|
(item) =>
|
|
|
|
|
CAPABILITY_MAP[item.professionalCapabilityCode] ||
|
|
|
|
|
item.professionalCapabilityCode,
|
|
|
|
|
)
|
|
|
|
|
.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>
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
]}
|
|
|
|
|
/>
|
|
|
|
|
<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;
|