dev-tmp1
tangjie 2026-08-18 18:42:55 +08:00
parent 58d0253691
commit 616be6c8d8
4 changed files with 338 additions and 328 deletions

View File

@ -12,9 +12,9 @@ module.exports = {
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095
//API_HOST: "http://localhost:80", //API_HOST: "http://localhost:80",
API_HOST: "http://192.168.0.134", // API_HOST: "http://192.168.0.134",
// API_HOST: "http://192.168.0.150", //太浅 // API_HOST: "http://192.168.0.150", //太浅
// API_HOST: "https://gbs-gateway.qhdsafety.com", API_HOST: "https://gbs-gateway.qhdsafety.com",
//API_HOST: "http://192.168.0.103", //huwei //API_HOST: "http://192.168.0.103", //huwei
}, },
production: { production: {

View File

@ -16,6 +16,7 @@ import {
TreeSelect, TreeSelect,
Upload, Upload,
Tag, Tag,
Divider
} from "antd"; } from "antd";
import { InboxOutlined } from "@ant-design/icons"; import { InboxOutlined } from "@ant-design/icons";
import { Get } from "@cqsjjb/jjb-common-lib/http"; import { Get } from "@cqsjjb/jjb-common-lib/http";
@ -1075,332 +1076,332 @@ function StaffFormModal({
)} )}
</Form.List> </Form.List>
</Form.Item> </Form.Item>
</div>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<div className="register-engineer-section">
<div className="register-engineer-section-title">学历信息</div>
<Row gutter={16}> <Row gutter={16}>
<Col span={12}> <Col span={24}>
<Form.Item name="educationTypeCode" label="学历类型"> <Divider plain >学历信息</Divider>
<Select
placeholder="请选择学历类型" <Row gutter={16}>
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}>
<Col span={24}>
<div className="register-engineer-section">
<div className="register-engineer-section-title">注安信息</div>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="registerEngineerFlag"
label="是否注册安全工程师"
initialValue={2}
>
<Select
placeholder="请选择"
options={REGISTER_ENGINEER_OPTIONS}
onChange={() => {
form.setFieldsValue({
registeredSafetyEngineerCert: null,
})
}}
/>
</Form.Item>
</Col>
{watchedRegisterEngineerFlag === 1 && (
<>
<Col span={12}> <Col span={12}>
<Form.Item <Form.Item name="educationTypeCode" label="学历类型">
name={[
"registeredSafetyEngineerCert",
"certCategoryCode",
]}
label="注安专业类别"
rules={[
{ required: true, message: "请选择注安专业类别" },
]}
>
<Select <Select
placeholder="请选择注安专业类别" placeholder="请选择学历类型"
allowClear allowClear
showSearch options={EDUCATION_TYPE_OPTIONS}
optionFilterProp="label" onChange={(_val, option) => {
options={REGISTER_ENGINEER_CATEGORY_OPTIONS} form.setFieldValue(
"educationTypeName",
option?.label || undefined,
);
}}
/> />
</Form.Item> </Form.Item>
<Form.Item name="educationTypeName" noStyle />
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item <Form.Item
name={["registeredSafetyEngineerCert", "certLevel"]} name="graduateSchool"
label="注安等级" label="毕业院校"
rules={[{ required: true, message: "请选择注安等级" }]}
>
<Select
placeholder="请选择注安等级"
allowClear
options={TITLE_LEVEL_OPTIONS.filter((o) => o.value !== "JUNIOR")}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name={["registeredSafetyEngineerCert", "certNo"]}
label="证书编号"
rules={[ rules={[
{ required: true, message: "请输入证书编号" }, { max: 200, message: "毕业院校不能超过200个字符" },
{ max: 50, message: "证书编号不能超过50个字符" },
]}
>
<Input placeholder="请输入证书编号" maxLength={50} />
</Form.Item>
</Col>
<Col span={12}>
<AttachmentUpload
name={[
"registeredSafetyEngineerCert",
"certAttachmentUrl",
]}
label="注安证书"
extra="最多上传10个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={10}
rules={[{ required: true, message: "请上传注安证书" }]}
/>
</Col>
<Col span={12}>
<Form.Item
name={[
"registeredSafetyEngineerCert",
"practisingCertCode",
]}
label="执业证书编号"
rules={[
{ required: true, message: "请输入执业证书编号" },
{
max: 50,
message: "执业证书编号不能超过50个字符",
},
]} ]}
> >
<Input <Input
placeholder="请输入执业证书编号" placeholder="请输入毕业院校"
maxLength={50} maxLength={200}
showCount
/> />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<AttachmentUpload <Form.Item name="educationLevelCode" label="学历层次">
name={[ <Select
"registeredSafetyEngineerCert", placeholder="请选择学历层次"
"practisingCertUrl", allowClear
]} options={EDUCATION_LEVEL_OPTIONS}
label="注安执业证书" onChange={(val, option) => {
extra="最多上传10个pdf,doc,docx,图片格式文件" form.setFieldValue(
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp" "educationLevelName",
maxCount={10} option?.label || undefined,
rules={[ );
{ required: true, message: "请上传注安执业证书" }, }}
]} />
/> </Form.Item>
<Form.Item name="educationLevelName" noStyle />
</Col> </Col>
</>
)}
</Row>
</div>
</Col>
</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="evaluatorFlag"
label="是否评价师"
initialValue={2}
>
<Select placeholder="请选择" options={EVALUATOR_OPTIONS} onChange={() => {
form.setFieldsValue({
evaluatorCert: null,
})
}} />
</Form.Item>
</Col>
{watchedEvaluatorFlag === 1 && (
<>
<Col span={12}> <Col span={12}>
<Form.Item <Form.Item
name={["evaluatorCert", "certLevel"]} name="basicDisciplineMajorId"
label="评价师等级" label="基础学科专业"
rules={[
{ required: true, message: "请选择评价师等级" },
]}
> >
<Select <Select
placeholder="请选择评价师等级" placeholder="请选择基础学科专业"
allowClear allowClear
options={CERT_LEVEL_OPTIONS_BY_TYPE.evaluator} 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>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Divider plain >注安信息</Divider>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="registerEngineerFlag"
label="是否注册安全工程师"
initialValue={2}
>
<Select
placeholder="请选择"
options={REGISTER_ENGINEER_OPTIONS}
onChange={() => {
form.setFieldsValue({
registeredSafetyEngineerCert: null,
})
}}
/>
</Form.Item>
</Col>
{watchedRegisterEngineerFlag === 1 && (
<>
<Col span={12}>
<Form.Item
name={[
"registeredSafetyEngineerCert",
"certCategoryCode",
]}
label="注安专业类别"
rules={[
{ required: true, message: "请选择注安专业类别" },
]}
>
<Select
placeholder="请选择注安专业类别"
allowClear
showSearch
optionFilterProp="label"
options={REGISTER_ENGINEER_CATEGORY_OPTIONS}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name={["registeredSafetyEngineerCert", "certLevel"]}
label="注安等级"
rules={[{ required: true, message: "请选择注安等级" }]}
>
<Select
placeholder="请选择注安等级"
allowClear
options={TITLE_LEVEL_OPTIONS.filter((o) => o.value !== "JUNIOR")}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name={["registeredSafetyEngineerCert", "certNo"]}
label="证书编号"
rules={[
{ required: true, message: "请输入证书编号" },
{ max: 50, message: "证书编号不能超过50个字符" },
]}
>
<Input placeholder="请输入证书编号" maxLength={50} />
</Form.Item>
</Col>
<Col span={12}>
<AttachmentUpload
name={[
"registeredSafetyEngineerCert",
"certAttachmentUrl",
]}
label="注安证书"
extra="最多上传10个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={10}
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>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Divider plain >评价师信息</Divider>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="evaluatorFlag"
label="是否评价师"
initialValue={2}
>
<Select placeholder="请选择" options={EVALUATOR_OPTIONS} onChange={() => {
form.setFieldsValue({
evaluatorCert: null,
})
}} />
</Form.Item>
</Col>
{watchedEvaluatorFlag === 1 && (
<>
<Col span={12}>
<Form.Item
name={["evaluatorCert", "certLevel"]}
label="评价师等级"
rules={[
{ required: true, message: "请选择评价师等级" },
]}
>
<Select
placeholder="请选择评价师等级"
allowClear
options={CERT_LEVEL_OPTIONS_BY_TYPE.evaluator}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name={["evaluatorCert", "certNo"]}
label="证书编号"
rules={[
{ required: true, message: "请输入证书编号" },
{ max: 50, message: "证书编号不能超过50个字符" },
]}
>
<Input placeholder="请输入证书编号" maxLength={50} />
</Form.Item>
</Col>
<Col span={24}>
<AttachmentUpload
name={["evaluatorCert", "certAttachmentUrl"]}
label="评价师证书"
extra="最多上传10个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={10}
rules={[
{ required: true, message: "请上传评价师证书" },
]}
/>
</Col>
</>
)}
</Row>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Divider plain >职称信息</Divider>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="titleCode"
label="职称"
rules={[{ required: true, message: "请选择职称" }]}
>
<Select
placeholder="请选择职称"
allowClear
options={TITLE_LEVEL_OPTIONS}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item <Form.Item
name={["evaluatorCert", "certNo"]} name="industryCode"
label="证书编号" label="专业"
rules={[ rules={[{ required: true, message: "请选择专业" }]}
{ required: true, message: "请输入证书编号" },
{ max: 50, message: "证书编号不能超过50个字符" },
]}
> >
<Input placeholder="请输入证书编号" maxLength={50} /> <Select
placeholder="请选择专业"
allowClear
options={PROFESSIONAL_MAJOR_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={12}>
<AttachmentUpload <AttachmentUpload
name={["evaluatorCert", "certAttachmentUrl"]} name="proveUrl"
label="评价师证书" label="证明材料"
extra="最多上传10个pdf,doc,docx,图片格式文件" extra="最多上传1个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp" accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={10} maxCount={1}
rules={[ rules={[{ required: true, message: "请上传证明材料" }]}
{ required: true, message: "请上传评价师证书" },
]}
/> />
</Col> </Col>
</> </Row>
)}
</Col>
</Row> </Row>
</div> </div>
</Col> </Col>
</Row> </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="titleCode"
label="职称"
rules={[{ required: true, message: "请选择职称" }]}
>
<Select
placeholder="请选择职称"
allowClear
options={TITLE_LEVEL_OPTIONS}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="industryCode"
label="专业"
rules={[{ required: true, message: "请选择专业" }]}
>
<Select
placeholder="请选择专业"
allowClear
options={PROFESSIONAL_MAJOR_OPTIONS}
/>
</Form.Item>
</Col>
<Col span={12}>
<AttachmentUpload
name="proveUrl"
label="证明材料"
extra="最多上传1个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={1}
rules={[{ required: true, message: "请上传证明材料" }]}
/>
</Col>
</Row>
</div>
</Col>
</Row>
</Form> </Form>
</Modal> </Modal>
); );

View File

@ -318,8 +318,8 @@ function CertFormModal({
const handleSubmit = async (values) => { const handleSubmit = async (values) => {
try { try {
setSubmitting(true); setSubmitting(true);
values.validStartDate = values.validDate?.[0]; values.validStartDate = values.validDate?.[0]?.format("YYYY-MM-DD");
values.validEndDate = values.validDate?.[1]; values.validEndDate = values.validDate?.[1]?.format("YYYY-MM-DD");
values.certImageUrl = Array.isArray(values.certImageUrl) ? values.certImageUrl.map((item) => item.url).join(",") : values.certImageUrl; values.certImageUrl = Array.isArray(values.certImageUrl) ? values.certImageUrl.map((item) => item.url).join(",") : values.certImageUrl;
if (currentId) values.id = currentId; if (currentId) values.id = currentId;

View File

@ -7,6 +7,7 @@ import {
Input, Input,
Flex, Flex,
Typography, Typography,
Image,
message, message,
Collapse, Collapse,
} from "antd"; } from "antd";
@ -176,13 +177,13 @@ const ControlContent = ({ readOnly, ...props }) => {
{ key: 2, label: "机构负责人签发" }, { key: 2, label: "机构负责人签发" },
]; ];
const reviewerSignatureTaskStatusMap={ const reviewerSignatureTaskStatusMap = {
dispatched: "已下发", dispatched: "已下发",
non_dispatched: "过程控制签字提交", non_dispatched: "过程控制签字提交",
completed: "已完成", completed: "已完成",
} }
const OrgHeadSignatureTaskStatusMap={ const OrgHeadSignatureTaskStatusMap = {
dispatched: "已下发", dispatched: "已下发",
non_dispatched: "下发APP签字", non_dispatched: "下发APP签字",
completed: "已完成", completed: "已完成",
@ -229,6 +230,12 @@ const ControlContent = ({ readOnly, ...props }) => {
pagination={false} pagination={false}
size="small" size="small"
/> />
{processControl?.reviewerSignatureUrl && <div style={{ marginTop: 12 }}>
<div style={{ marginBottom: 4, fontSize: 14, color: "#475569" }}>
签字图片
</div>
<Image src={processControl?.reviewerSignatureUrl} width={120} height={80} />
</div>}
<Collapse <Collapse
style={{ marginTop: 12 }} style={{ marginTop: 12 }}
items={[ items={[
@ -323,42 +330,44 @@ const ControlContent = ({ readOnly, ...props }) => {
/> />
</div> </div>
<Flex
justify="space-between" <Flex gap={8} align="flex-end" style={{ marginBottom: 16 }}>
align="center" <Typography.Text type="secondary">
style={{ paddingBottom: 16 }} 评价机构负责人
> </Typography.Text>
<Flex gap={8} align="center"> <Select
<Typography.Text type="secondary"> placeholder="请选择评价机构负责人"
评价机构负责人 size="small"
</Typography.Text> allowClear
<Select style={{ width: 180 }}
placeholder="请选择评价机构负责人" disabled={isDispatched || isOrgHeadSignature || readOnly}
size="small" value={selectPeople?.value}
allowClear onChange={(value, option) => {
style={{ width: 180 }} setSelectPeople(option);
disabled={isDispatched || isOrgHeadSignature || readOnly} }}
value={selectPeople?.value} options={(orgHeads || []).map((r) => ({
onChange={(value, option) => { value: r.personnelId,
setSelectPeople(option); label: r.personnelName,
}} }))}
options={(orgHeads || []).map((r) => ({ />
value: r.personnelId, <Button
label: r.personnelName, size="small"
}))} onClick={handleAssign}
/> loading={
<Button props.safetyEvalBusiness?.processControlAssignLoading
size="small" }
onClick={handleAssign} disabled={isDispatched || isOrgHeadSignature || !selectPeople?.value || readOnly}
loading={ >
props.safetyEvalBusiness?.processControlAssignLoading {isDispatched ? "过程控制审核暂未完成" : OrgHeadSignatureTaskStatusMap[processControl?.orgHeadSignatureTaskStatus]}
} </Button>
disabled={isDispatched || isOrgHeadSignature || !selectPeople?.value || readOnly} {processControl?.orgHeadSignatureUrl&& <Flex align="flex-end" gap={3}>
> <span >
{isDispatched ? "过程控制审核暂未完成" : OrgHeadSignatureTaskStatusMap[processControl?.orgHeadSignatureTaskStatus]} 签字图片
</Button> </span>
</Flex> <Image src={processControl?.orgHeadSignatureUrl} width={120} height={80} />
</Flex>}
</Flex> </Flex>
</div> </div>
</Card> </Card>
)} )}
@ -368,7 +377,7 @@ const ControlContent = ({ readOnly, ...props }) => {
<Flex justify="flex-end" gap={8}> <Flex justify="flex-end" gap={8}>
<Button <Button
type="primary" type="primary"
disabled={ ["dispatched", 'completed'].includes(processControl?.reviewerSignatureTaskStatus)} disabled={["dispatched", 'completed'].includes(processControl?.reviewerSignatureTaskStatus)}
onClick={() => handleConfirm("passed")} onClick={() => handleConfirm("passed")}
loading={props.safetyEvalBusiness?.processControlConfirmLoading} loading={props.safetyEvalBusiness?.processControlConfirmLoading}
> >