feat
parent
94e499646e
commit
58d0253691
|
|
@ -20,14 +20,14 @@
|
|||
"test:enterprise-info:granular": "node docs/test-reports/测试用例/test-enterprise-info-granular.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.0.0",
|
||||
"@ant-design/icons": "latest",
|
||||
"@cqsjjb/jjb-common-decorator": "latest",
|
||||
"@cqsjjb/jjb-common-lib": "latest",
|
||||
"@cqsjjb/jjb-dva-runtime": "latest",
|
||||
"@cqsjjb/jjb-react-admin-component": "latest",
|
||||
"@rc-component/motion": "^1.0.0",
|
||||
"@rc-component/util": "^1.11.1",
|
||||
"antd": "^5.29.2",
|
||||
"antd": "^6.6.1",
|
||||
"dayjs": "^1.11.7",
|
||||
"docxtemplater": "latest",
|
||||
"echarts": "^6.1.0",
|
||||
|
|
|
|||
6027
pnpm-lock.yaml
6027
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -81,6 +81,7 @@ export default function StaffViewModal({
|
|||
const regCert = info.registeredSafetyEngineerCert;
|
||||
const regCertLevelMap = CERT_LEVEL_LABEL_BY_TYPE.registered_safety_engineer;
|
||||
const regCertFiles = parseFileList(regCert?.certAttachmentUrl);
|
||||
const regPractisingFiles = parseFileList(regCert?.practisingCertUrl);
|
||||
|
||||
const evaluatorCert = info.evaluatorCert;
|
||||
const evaluatorFlag = info.evaluatorFlag || (evaluatorCert ? 1 : 2);
|
||||
|
|
@ -136,16 +137,14 @@ export default function StaffViewModal({
|
|||
okButtonProps={{ style: { display: "none" } }}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }}>
|
||||
<div style={{ marginBottom: 8, fontWeight: 600 }}>基础信息</div>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }} size="small">
|
||||
<Descriptions.Item label="姓名">{info.userName}</Descriptions.Item>
|
||||
<Descriptions.Item label="性别">
|
||||
{GENDER_MAP[info.genderCode]}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="出生日期">
|
||||
{info.birthDate}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="参加工作时间">
|
||||
{info.joinWorkDate}
|
||||
<Descriptions.Item label="本行业工作年限">
|
||||
{info.workDateAge}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="账号">{info.account}</Descriptions.Item>
|
||||
<Descriptions.Item label="部门">{info.deptName}</Descriptions.Item>
|
||||
|
|
@ -159,18 +158,6 @@ export default function StaffViewModal({
|
|||
<Descriptions.Item label="办公地址">
|
||||
{info.officeAddress}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="学历类型">
|
||||
{info.educationTypeName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="毕业院校">
|
||||
{info.graduateSchool}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="学历层次">
|
||||
{info.educationLevelName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="基础学科专业">
|
||||
{info.basicDisciplineMajorName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="是否技术负责人">
|
||||
{info.technicalDirectorFlag === true
|
||||
? "是"
|
||||
|
|
@ -191,6 +178,53 @@ export default function StaffViewModal({
|
|||
<Descriptions.Item label="出版学术专著专利获奖论文等" span={2}>
|
||||
{info.publications || "-"}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
|
||||
专业能力信息
|
||||
</div>
|
||||
<Table
|
||||
size="small"
|
||||
bordered
|
||||
pagination={false}
|
||||
rowKey={(_, idx) => idx}
|
||||
dataSource={capabilityList}
|
||||
locale={{ emptyText: "暂无专业能力信息" }}
|
||||
columns={[
|
||||
{
|
||||
title: "行业",
|
||||
dataIndex: "industryCode",
|
||||
width: 220,
|
||||
ellipsis: true,
|
||||
render: (code) =>
|
||||
QUALIFICATION_INDUSTRY_OPTIONS_MAP[code] || code || "-",
|
||||
},
|
||||
{
|
||||
title: "专业能力",
|
||||
dataIndex: "capabilityName",
|
||||
width: 80,
|
||||
ellipsis: true,
|
||||
},
|
||||
{ title: "来源", dataIndex: "sourceName", width: 280 },
|
||||
]}
|
||||
/>
|
||||
|
||||
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
|
||||
学历信息
|
||||
</div>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }} size="small">
|
||||
<Descriptions.Item label="学历类型">
|
||||
{info.educationTypeName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="毕业院校">
|
||||
{info.graduateSchool}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="学历层次">
|
||||
{info.educationLevelName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="基础学科专业">
|
||||
{info.basicDisciplineMajorName || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="学历证明材料" span={2}>
|
||||
{renderFileList(proofMaterialFiles)}
|
||||
</Descriptions.Item>
|
||||
|
|
@ -199,7 +233,7 @@ export default function StaffViewModal({
|
|||
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
|
||||
注安信息
|
||||
</div>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }}>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }} size="small">
|
||||
<Descriptions.Item label="是否注册安全工程师">
|
||||
{REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"}
|
||||
</Descriptions.Item>
|
||||
|
|
@ -212,15 +246,21 @@ export default function StaffViewModal({
|
|||
<Descriptions.Item label="证书编号">
|
||||
{regCert?.certNo || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="执业证书编号">
|
||||
{regCert?.practisingCertCode || "-"}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="注安证书" span={2}>
|
||||
{renderFileList(regCertFiles)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="注安执业证书" span={2}>
|
||||
{renderFileList(regPractisingFiles)}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
|
||||
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
|
||||
评价师信息
|
||||
</div>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }}>
|
||||
<Descriptions bordered column={2} labelStyle={{ width: 120 }} size="small">
|
||||
<Descriptions.Item label="是否评价师">
|
||||
{EVALUATOR_MAP[evaluatorFlag] ?? "-"}
|
||||
</Descriptions.Item>
|
||||
|
|
@ -254,35 +294,6 @@ export default function StaffViewModal({
|
|||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
|
||||
专业能力信息
|
||||
</div>
|
||||
<Table
|
||||
size="small"
|
||||
bordered
|
||||
pagination={false}
|
||||
rowKey={(_, idx) => idx}
|
||||
dataSource={capabilityList}
|
||||
locale={{ emptyText: "暂无专业能力信息" }}
|
||||
columns={[
|
||||
{
|
||||
title: "行业",
|
||||
dataIndex: "industryCode",
|
||||
width: 220,
|
||||
ellipsis: true,
|
||||
render: (code) =>
|
||||
QUALIFICATION_INDUSTRY_OPTIONS_MAP[code] || code || "-",
|
||||
},
|
||||
{
|
||||
title: "专业能力",
|
||||
dataIndex: "capabilityName",
|
||||
width: 80,
|
||||
ellipsis: true,
|
||||
},
|
||||
{ title: "来源", dataIndex: "sourceName", width: 280 },
|
||||
]}
|
||||
/>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -588,9 +588,7 @@ function DepartmentPositionPage(props) {
|
|||
<Modal
|
||||
open={assignRoleModalOpen}
|
||||
destroyOnHidden
|
||||
mask={{
|
||||
closable: false,
|
||||
}}
|
||||
|
||||
title="分配系统角色"
|
||||
width={480}
|
||||
confirmLoading={orgPositionLoading}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
|||
import {
|
||||
Alert,
|
||||
Button,
|
||||
DatePicker,
|
||||
Form,
|
||||
Input,
|
||||
InputNumber,
|
||||
message,
|
||||
Modal,
|
||||
Row,
|
||||
|
|
@ -20,7 +20,6 @@ import {
|
|||
import { InboxOutlined } from "@ant-design/icons";
|
||||
import { Get } from "@cqsjjb/jjb-common-lib/http";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import dayjs from "dayjs";
|
||||
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
||||
import SearchForm from "~/components/SearchForm";
|
||||
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
||||
|
|
@ -45,7 +44,7 @@ import {
|
|||
PROFESSIONAL_MAJOR_OPTIONS,
|
||||
CERT_LEVEL_LABEL_BY_TYPE
|
||||
} from "~/enumerate/constant";
|
||||
import { getBirthDateFromIdCard, renderCapabilityList } from "~/utils";
|
||||
import { renderCapabilityList } from "~/utils";
|
||||
import { idCardRule, mobileRule } from "~/utils/validators";
|
||||
import AttachmentUpload from "~/components/AttachmentUpload";
|
||||
import StaffViewModal from "~/components/StaffViewModal";
|
||||
|
|
@ -219,7 +218,7 @@ function PersonnelInfoPage(props) {
|
|||
<div>
|
||||
<span>员工信息管理</span>
|
||||
<div className="pageLayout-extra">
|
||||
机构管理员在系统中为本机构的人员进行信息录入,包括姓名、性别、身份证号、出生日期等。
|
||||
机构管理员在系统中为本机构的人员进行信息录入,包括姓名、性别、身份证号等。
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
@ -327,21 +326,21 @@ function PersonnelInfoPage(props) {
|
|||
ellipsis: true,
|
||||
render: renderCapabilityList,
|
||||
},
|
||||
{
|
||||
title: "证照名称",
|
||||
dataIndex: "personnelCertFilingPageCOList",
|
||||
width: 280,
|
||||
render: (_, record) => {
|
||||
const arr = [];
|
||||
if(record.registeredSafetyEngineerCert){
|
||||
arr.push(<Tag color="blue">{TITLE_LEVEL_MAP[record.registeredSafetyEngineerCert.certLevel]}注册安全工程师</Tag>);
|
||||
}
|
||||
if(record.evaluatorCert){
|
||||
arr.push(<Tag color="green">{evalCertLevelMap[record.evaluatorCert.certLevel]}注册安全评价师</Tag>);
|
||||
}
|
||||
return <Space size={4}>{arr}</Space>;
|
||||
},
|
||||
{
|
||||
title: "证照名称",
|
||||
dataIndex: "personnelCertFilingPageCOList",
|
||||
width: 280,
|
||||
render: (_, record) => {
|
||||
const arr = [];
|
||||
if (record.registeredSafetyEngineerCert) {
|
||||
arr.push(<Tag color="blue">{TITLE_LEVEL_MAP[record.registeredSafetyEngineerCert.certLevel]}注册安全工程师</Tag>);
|
||||
}
|
||||
if (record.evaluatorCert) {
|
||||
arr.push(<Tag color="green">{evalCertLevelMap[record.evaluatorCert.certLevel]}注册安全评价师</Tag>);
|
||||
}
|
||||
return <Space size={4}>{arr}</Space>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 200,
|
||||
|
|
@ -594,9 +593,6 @@ function StaffFormModal({
|
|||
const setFields = {
|
||||
...data,
|
||||
};
|
||||
if (data.birthDate) setFields.birthDate = dayjs(data.birthDate);
|
||||
if (data.joinWorkDate)
|
||||
setFields.joinWorkDate = dayjs(data.joinWorkDate);
|
||||
|
||||
if (setFields.proofMaterialUrl) {
|
||||
setFields.proofMaterialUrl = JSON.parse(setFields.proofMaterialUrl);
|
||||
|
|
@ -606,7 +602,12 @@ function StaffFormModal({
|
|||
if (cert?.certAttachmentUrl) {
|
||||
try {
|
||||
cert.certAttachmentUrl = JSON.parse(cert.certAttachmentUrl);
|
||||
} catch {}
|
||||
} catch { }
|
||||
}
|
||||
if (cert?.practisingCertUrl) {
|
||||
try {
|
||||
cert.practisingCertUrl = JSON.parse(cert.practisingCertUrl);
|
||||
} catch { }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -665,12 +666,6 @@ function StaffFormModal({
|
|||
};
|
||||
|
||||
const onValuesChange = (changed) => {
|
||||
if ("idCardNo" in changed && changed.idCardNo) {
|
||||
const birth = getBirthDateFromIdCard(changed.idCardNo);
|
||||
if (birth) {
|
||||
form.setFieldValue("birthDate", dayjs(birth));
|
||||
}
|
||||
}
|
||||
if ("deptId" in changed) {
|
||||
form.setFieldValue("postId", undefined);
|
||||
loadPositionsByDept(changed.deptId);
|
||||
|
|
@ -687,11 +682,14 @@ function StaffFormModal({
|
|||
const stringifyCert = (cert) =>
|
||||
cert
|
||||
? {
|
||||
...cert,
|
||||
certAttachmentUrl: Array.isArray(cert.certAttachmentUrl)
|
||||
? JSON.stringify(cert.certAttachmentUrl)
|
||||
: undefined,
|
||||
}
|
||||
...cert,
|
||||
certAttachmentUrl: Array.isArray(cert.certAttachmentUrl)
|
||||
? JSON.stringify(cert.certAttachmentUrl)
|
||||
: undefined,
|
||||
practisingCertUrl: Array.isArray(cert.practisingCertUrl)
|
||||
? JSON.stringify(cert.practisingCertUrl)
|
||||
: undefined,
|
||||
}
|
||||
: undefined;
|
||||
const payload = {
|
||||
...values,
|
||||
|
|
@ -723,18 +721,12 @@ function StaffFormModal({
|
|||
: undefined,
|
||||
capabilityAssessment: Array.isArray(values.capabilityAssessment)
|
||||
? values.capabilityAssessment.filter(
|
||||
(item) =>
|
||||
item?.professionalCapabilityCode ||
|
||||
item?.professionalCapabilitySourceCode,
|
||||
)
|
||||
(item) =>
|
||||
item?.professionalCapabilityCode ||
|
||||
item?.professionalCapabilitySourceCode,
|
||||
)
|
||||
: undefined,
|
||||
};
|
||||
if (payload.birthDate && typeof payload.birthDate !== "string") {
|
||||
payload.birthDate = payload.birthDate.format("YYYY-MM-DD");
|
||||
}
|
||||
if (payload.joinWorkDate && typeof payload.joinWorkDate !== "string") {
|
||||
payload.joinWorkDate = payload.joinWorkDate.format("YYYY-MM-DD");
|
||||
}
|
||||
if (currentId) payload.id = currentId;
|
||||
|
||||
const request = currentId ? staffInfoEdit : staffInfoAdd;
|
||||
|
|
@ -771,220 +763,406 @@ function StaffFormModal({
|
|||
onFinish={handleSubmit}
|
||||
>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="userName"
|
||||
label="姓名"
|
||||
rules={[
|
||||
{ required: true, message: "请输入姓名" },
|
||||
{ max: 50, message: "姓名不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入姓名" maxLength={50} showCount />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="genderCode"
|
||||
label="性别"
|
||||
rules={[{ required: true, message: "请选择性别" }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择性别"
|
||||
options={[
|
||||
{ label: "男", value: 1 },
|
||||
{ label: "女", value: 2 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="birthDate"
|
||||
label="出生日期"
|
||||
rules={[{ required: true, message: "请选择出生日期" }]}
|
||||
>
|
||||
<DatePicker style={{ width: "100%" }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="joinWorkDate"
|
||||
label="参加工作时间"
|
||||
rules={[{ required: true, message: "请选择参加工作时间" }]}
|
||||
>
|
||||
<DatePicker style={{ width: "100%" }} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="account"
|
||||
label="账号"
|
||||
rules={[mobileRule("账号", true)]}
|
||||
>
|
||||
<Input placeholder="请输入账号" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="deptId"
|
||||
label="部门"
|
||||
rules={[{ required: true, message: "请选择部门" }]}
|
||||
>
|
||||
<TreeSelect
|
||||
placeholder="请选择部门"
|
||||
treeData={orgDepartmentTreeData}
|
||||
allowClear
|
||||
fieldNames={{
|
||||
label: "deptName",
|
||||
value: "id",
|
||||
key: "id",
|
||||
}}
|
||||
treeDefaultExpandAll
|
||||
showSearch
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="postId"
|
||||
label="岗位"
|
||||
rules={[{ required: true, message: "请选择岗位" }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择岗位"
|
||||
options={deptPositionOptions}
|
||||
loading={positionLoading}
|
||||
disabled={!watchedDeptId}
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="idCardNo"
|
||||
label="身份证号"
|
||||
rules={[
|
||||
idCardRule(true),
|
||||
{ max: 18, message: "身份证号不能超过18个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入身份证号" maxLength={18} />
|
||||
</Form.Item>
|
||||
<Col span={24}>
|
||||
<div className="register-engineer-section">
|
||||
<div className="register-engineer-section-title">基础信息</div>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="userName"
|
||||
label="姓名"
|
||||
rules={[
|
||||
{ required: true, message: "请输入姓名" },
|
||||
{ max: 50, message: "姓名不能超过50个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入姓名" maxLength={50} showCount />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="genderCode"
|
||||
label="性别"
|
||||
rules={[{ required: true, message: "请选择性别" }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择性别"
|
||||
options={[
|
||||
{ label: "男", value: 1 },
|
||||
{ label: "女", value: 2 },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="workDateAge"
|
||||
label="本行业工作年限"
|
||||
rules={[
|
||||
{ required: true, message: "请输入本行业工作年限" },
|
||||
]}
|
||||
>
|
||||
<InputNumber
|
||||
min={0}
|
||||
precision={0}
|
||||
placeholder="请输入本行业工作年限"
|
||||
max={100}
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="account"
|
||||
label="账号"
|
||||
rules={[mobileRule("账号", true)]}
|
||||
>
|
||||
<Input placeholder="请输入账号" />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="deptId"
|
||||
label="部门"
|
||||
rules={[{ required: true, message: "请选择部门" }]}
|
||||
>
|
||||
<TreeSelect
|
||||
placeholder="请选择部门"
|
||||
treeData={orgDepartmentTreeData}
|
||||
allowClear
|
||||
fieldNames={{
|
||||
label: "deptName",
|
||||
value: "id",
|
||||
key: "id",
|
||||
}}
|
||||
treeDefaultExpandAll
|
||||
showSearch
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="postId"
|
||||
label="岗位"
|
||||
rules={[{ required: true, message: "请选择岗位" }]}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择岗位"
|
||||
options={deptPositionOptions}
|
||||
loading={positionLoading}
|
||||
disabled={!watchedDeptId}
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="idCardNo"
|
||||
label="身份证号"
|
||||
rules={[
|
||||
idCardRule(true),
|
||||
{ max: 18, message: "身份证号不能超过18个字符" },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入身份证号" maxLength={18} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="currentAddress"
|
||||
label="现住地址"
|
||||
rules={[
|
||||
{ max: 300, message: "现住地址不能超过300个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入现住地址"
|
||||
maxLength={300}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="officeAddress"
|
||||
label="办公地址"
|
||||
rules={[
|
||||
{ max: 300, message: "办公地址不能超过300个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入办公地址"
|
||||
maxLength={300}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="technicalDirectorFlag"
|
||||
label="是否技术负责人"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "是", value: true },
|
||||
{ label: "否", value: false },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="processControlLeaderFlag"
|
||||
label="是否过程控制负责人"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "是", value: true },
|
||||
{ label: "否", value: false },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item name="workExperience" label="主要学习工作经历">
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
placeholder="请输入"
|
||||
maxLength={500}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
name="publications"
|
||||
label="出版学术专著专利获奖论文等"
|
||||
rules={[
|
||||
{
|
||||
max: 1000,
|
||||
message: "出版学术专著等长度不能超过1000个字符",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
placeholder="请输入"
|
||||
maxLength={1000}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={24}>
|
||||
<div className="register-engineer-section">
|
||||
<Form.Item label="专业能力信息">
|
||||
<Form.List name="capabilityAssessment" initialValue={[{}]}>
|
||||
{(fields, { add, remove }) => (
|
||||
<>
|
||||
<Table
|
||||
dataSource={fields}
|
||||
rowKey={(field) => field.key}
|
||||
pagination={false}
|
||||
size="small"
|
||||
bordered
|
||||
columns={[
|
||||
{
|
||||
title: "行业",
|
||||
width: 200,
|
||||
render: (_, field) => (
|
||||
<Form.Item
|
||||
name={[field.name, "industryCode"]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择行业"
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
options={QUALIFICATION_INDUSTRY_OPTIONS}
|
||||
onChange={(code) => {
|
||||
if (code) loadCapOptions(code);
|
||||
form.setFieldValue(
|
||||
["capabilityAssessment", field.name, "professionalCapabilityCode"],
|
||||
undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "专业能力",
|
||||
render: (_, field) => {
|
||||
const rowIndustryCode =
|
||||
watchedCapList?.[field.name]?.industryCode;
|
||||
const rowOptions = rowIndustryCode
|
||||
? capOptionsCache[rowIndustryCode] || []
|
||||
: [];
|
||||
return (
|
||||
<Form.Item
|
||||
name={[field.name, "professionalCapabilityCode"]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择专业能力"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
allowClear
|
||||
options={rowOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "来源",
|
||||
width: 280,
|
||||
render: (_, field) => (
|
||||
<Form.Item
|
||||
name={[
|
||||
field.name,
|
||||
"professionalCapabilitySourceCode",
|
||||
]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择来源"
|
||||
allowClear
|
||||
options={ABILITY_SOURCE_OPTIONS}
|
||||
/>
|
||||
</Form.Item>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 80,
|
||||
render: (_, field) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
size="small"
|
||||
disabled={fields.length <= 1}
|
||||
onClick={() => remove(field.name)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{fields.length < 2 && (
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => add()}
|
||||
block
|
||||
style={{ marginTop: 12 }}
|
||||
>
|
||||
添加专业能力信息
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Form.List>
|
||||
</Form.Item>
|
||||
</div>
|
||||
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="currentAddress"
|
||||
label="现住地址"
|
||||
rules={[{ max: 300, message: "现住地址不能超过300个字符" }]}
|
||||
>
|
||||
<Input placeholder="请输入现住地址" maxLength={300} showCount />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="officeAddress"
|
||||
label="办公地址"
|
||||
rules={[{ max: 300, message: "办公地址不能超过300个字符" }]}
|
||||
>
|
||||
<Input placeholder="请输入办公地址" maxLength={300} showCount />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="educationTypeCode" label="学历类型">
|
||||
<Select
|
||||
placeholder="请选择学历类型"
|
||||
allowClear
|
||||
options={EDUCATION_TYPE_OPTIONS}
|
||||
onChange={(_val, option) => {
|
||||
form.setFieldValue(
|
||||
"educationTypeName",
|
||||
option?.label || undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="educationTypeName" noStyle />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="graduateSchool"
|
||||
label="毕业院校"
|
||||
rules={[{ max: 200, message: "毕业院校不能超过200个字符" }]}
|
||||
>
|
||||
<Input placeholder="请输入毕业院校" maxLength={200} showCount />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="educationLevelCode" label="学历层次">
|
||||
<Select
|
||||
placeholder="请选择学历层次"
|
||||
allowClear
|
||||
options={EDUCATION_LEVEL_OPTIONS}
|
||||
onChange={(val, option) => {
|
||||
form.setFieldValue(
|
||||
"educationLevelName",
|
||||
option?.label || undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="educationLevelName" noStyle />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="basicDisciplineMajorId" label="基础学科专业">
|
||||
<Select
|
||||
placeholder="请先选择资质范围"
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
options={(staffInfo?.basicDisciplineMajorList || []).map(
|
||||
(item) => ({
|
||||
label: `${item.professionalName}`,
|
||||
value: item.id,
|
||||
}),
|
||||
)}
|
||||
loading={staffInfo?.staffInfoLoading}
|
||||
disabled={!staffInfo?.basicDisciplineMajorList?.length}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<AttachmentUpload
|
||||
name="proofMaterialUrl"
|
||||
label="学历证明材料"
|
||||
extra={"最多上传5个pdf,doc,docx,图片格式文件"}
|
||||
accept={".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"}
|
||||
maxCount={5}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="technicalDirectorFlag" label="是否技术负责人">
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "是", value: true },
|
||||
{ label: "否", value: false },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="processControlLeaderFlag" label="是否过程控制负责人">
|
||||
<Select
|
||||
placeholder="请选择"
|
||||
allowClear
|
||||
options={[
|
||||
{ label: "是", value: true },
|
||||
{ label: "否", value: false },
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
<Col span={24}>
|
||||
<div className="register-engineer-section">
|
||||
<div className="register-engineer-section-title">学历信息</div>
|
||||
<Row gutter={16}>
|
||||
<Col span={12}>
|
||||
<Form.Item name="educationTypeCode" label="学历类型">
|
||||
<Select
|
||||
placeholder="请选择学历类型"
|
||||
allowClear
|
||||
options={EDUCATION_TYPE_OPTIONS}
|
||||
onChange={(_val, option) => {
|
||||
form.setFieldValue(
|
||||
"educationTypeName",
|
||||
option?.label || undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="educationTypeName" noStyle />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="graduateSchool"
|
||||
label="毕业院校"
|
||||
rules={[
|
||||
{ max: 200, message: "毕业院校不能超过200个字符" },
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入毕业院校"
|
||||
maxLength={200}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item name="educationLevelCode" label="学历层次">
|
||||
<Select
|
||||
placeholder="请选择学历层次"
|
||||
allowClear
|
||||
options={EDUCATION_LEVEL_OPTIONS}
|
||||
onChange={(val, option) => {
|
||||
form.setFieldValue(
|
||||
"educationLevelName",
|
||||
option?.label || undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="educationLevelName" noStyle />
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name="basicDisciplineMajorId"
|
||||
label="基础学科专业"
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择基础学科专业"
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
options={(staffInfo?.basicDisciplineMajorList || []).map(
|
||||
(item) => ({
|
||||
label: `${item.professionalName}`,
|
||||
value: item.id,
|
||||
}),
|
||||
)}
|
||||
loading={staffInfo?.staffInfoLoading}
|
||||
disabled={!staffInfo?.basicDisciplineMajorList?.length}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<AttachmentUpload
|
||||
name="proofMaterialUrl"
|
||||
label="学历证明材料"
|
||||
extra={"最多上传5个pdf,doc,docx,图片格式文件"}
|
||||
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
|
||||
maxCount={5}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row gutter={16}>
|
||||
|
|
@ -1001,7 +1179,7 @@ function StaffFormModal({
|
|||
<Select
|
||||
placeholder="请选择"
|
||||
options={REGISTER_ENGINEER_OPTIONS}
|
||||
onChange={()=>{
|
||||
onChange={() => {
|
||||
form.setFieldsValue({
|
||||
registeredSafetyEngineerCert: null,
|
||||
})
|
||||
|
|
@ -1056,7 +1234,7 @@ function StaffFormModal({
|
|||
<Input placeholder="请输入证书编号" maxLength={50} />
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Col span={12}>
|
||||
<AttachmentUpload
|
||||
name={[
|
||||
"registeredSafetyEngineerCert",
|
||||
|
|
@ -1069,6 +1247,43 @@ function StaffFormModal({
|
|||
rules={[{ required: true, message: "请上传注安证书" }]}
|
||||
/>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Form.Item
|
||||
name={[
|
||||
"registeredSafetyEngineerCert",
|
||||
"practisingCertCode",
|
||||
]}
|
||||
label="执业证书编号"
|
||||
rules={[
|
||||
{ required: true, message: "请输入执业证书编号" },
|
||||
{
|
||||
max: 50,
|
||||
message: "执业证书编号不能超过50个字符",
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input
|
||||
placeholder="请输入执业证书编号"
|
||||
maxLength={50}
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
|
||||
<Col span={12}>
|
||||
<AttachmentUpload
|
||||
name={[
|
||||
"registeredSafetyEngineerCert",
|
||||
"practisingCertUrl",
|
||||
]}
|
||||
label="注安执业证书"
|
||||
extra="最多上传10个pdf,doc,docx,图片格式文件"
|
||||
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
|
||||
maxCount={10}
|
||||
rules={[
|
||||
{ required: true, message: "请上传注安执业证书" },
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
</>
|
||||
)}
|
||||
</Row>
|
||||
|
|
@ -1086,7 +1301,7 @@ function StaffFormModal({
|
|||
label="是否评价师"
|
||||
initialValue={2}
|
||||
>
|
||||
<Select placeholder="请选择" options={EVALUATOR_OPTIONS} onChange={()=>{
|
||||
<Select placeholder="请选择" options={EVALUATOR_OPTIONS} onChange={() => {
|
||||
form.setFieldsValue({
|
||||
evaluatorCert: null,
|
||||
})
|
||||
|
|
@ -1185,144 +1400,6 @@ function StaffFormModal({
|
|||
</Row>
|
||||
</div>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item label="专业能力信息">
|
||||
<Form.List name="capabilityAssessment" initialValue={[{}]}>
|
||||
{(fields, { add, remove }) => (
|
||||
<>
|
||||
<Table
|
||||
dataSource={fields}
|
||||
rowKey={(field) => field.key}
|
||||
pagination={false}
|
||||
size="small"
|
||||
bordered
|
||||
columns={[
|
||||
{
|
||||
title: "行业",
|
||||
width: 200,
|
||||
render: (_, field) => (
|
||||
<Form.Item
|
||||
name={[field.name, "industryCode"]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择行业"
|
||||
allowClear
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
options={QUALIFICATION_INDUSTRY_OPTIONS}
|
||||
onChange={(code) => {
|
||||
if (code) loadCapOptions(code);
|
||||
form.setFieldValue(
|
||||
["capabilityAssessment", field.name, "professionalCapabilityCode"],
|
||||
undefined,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "专业能力",
|
||||
render: (_, field) => {
|
||||
const rowIndustryCode =
|
||||
watchedCapList?.[field.name]?.industryCode;
|
||||
const rowOptions = rowIndustryCode
|
||||
? capOptionsCache[rowIndustryCode] || []
|
||||
: [];
|
||||
return (
|
||||
<Form.Item
|
||||
name={[field.name, "professionalCapabilityCode"]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择专业能力"
|
||||
showSearch
|
||||
optionFilterProp="label"
|
||||
allowClear
|
||||
options={rowOptions}
|
||||
/>
|
||||
</Form.Item>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "来源",
|
||||
width: 280,
|
||||
render: (_, field) => (
|
||||
<Form.Item
|
||||
name={[
|
||||
field.name,
|
||||
"professionalCapabilitySourceCode",
|
||||
]}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Select
|
||||
placeholder="请选择来源"
|
||||
allowClear
|
||||
options={ABILITY_SOURCE_OPTIONS}
|
||||
/>
|
||||
</Form.Item>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: 80,
|
||||
render: (_, field) => (
|
||||
<Button
|
||||
type="link"
|
||||
danger
|
||||
size="small"
|
||||
disabled={fields.length <= 1}
|
||||
onClick={() => remove(field.name)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{fields.length < 2 && (
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => add()}
|
||||
block
|
||||
style={{ marginTop: 12 }}
|
||||
>
|
||||
添加专业能力信息
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Form.List>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item name="workExperience" label="主要学习工作经历">
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
placeholder="请输入"
|
||||
maxLength={500}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Form.Item
|
||||
name="publications"
|
||||
label="出版学术专著专利获奖论文等"
|
||||
rules={[
|
||||
{ max: 1000, message: "出版学术专著等长度不能超过1000个字符" },
|
||||
]}
|
||||
>
|
||||
<Input.TextArea
|
||||
rows={3}
|
||||
placeholder="请输入"
|
||||
maxLength={1000}
|
||||
showCount
|
||||
/>
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@
|
|||
.register-engineer-section {
|
||||
border: 1px dashed #d9d9d9;
|
||||
border-radius: 8px;
|
||||
padding: 16px 16px 0;
|
||||
margin-bottom: 24px;
|
||||
padding: 12px 12px 0;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&-title {
|
||||
font-size: 14px;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,11 @@ export default class Container extends React.Component {
|
|||
}}
|
||||
locale={language}
|
||||
prefixCls={window.process.env.app.antd["ant-prefix"]}
|
||||
modal={{
|
||||
mask: {
|
||||
closable: false,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<App style={{ height: "100%" }}>
|
||||
<AppMiddle {...this.props} />
|
||||
|
|
|
|||
Loading…
Reference in New Issue