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
//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: "https://gbs-gateway.qhdsafety.com",
API_HOST: "https://gbs-gateway.qhdsafety.com",
//API_HOST: "http://192.168.0.103", //huwei
},
production: {

View File

@ -16,6 +16,7 @@ import {
TreeSelect,
Upload,
Tag,
Divider
} from "antd";
import { InboxOutlined } from "@ant-design/icons";
import { Get } from "@cqsjjb/jjb-common-lib/http";
@ -1075,332 +1076,332 @@ function StaffFormModal({
)}
</Form.List>
</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}>
<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}>
<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={24}>
<Divider plain >学历信息</Divider>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name={[
"registeredSafetyEngineerCert",
"certCategoryCode",
]}
label="注安专业类别"
rules={[
{ required: true, message: "请选择注安专业类别" },
]}
>
<Form.Item name="educationTypeCode" label="学历类型">
<Select
placeholder="请选择注安专业类别"
placeholder="请选择学历类型"
allowClear
showSearch
optionFilterProp="label"
options={REGISTER_ENGINEER_CATEGORY_OPTIONS}
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={["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="证书编号"
name="graduateSchool"
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个字符",
},
{ max: 200, message: "毕业院校不能超过200个字符" },
]}
>
<Input
placeholder="请输入执业证书编号"
maxLength={50}
placeholder="请输入毕业院校"
maxLength={200}
showCount
/>
</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: "请上传注安执业证书" },
]}
/>
<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>
</>
)}
</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}>
<Form.Item
name={["evaluatorCert", "certLevel"]}
label="评价师等级"
rules={[
{ required: true, message: "请选择评价师等级" },
]}
name="basicDisciplineMajorId"
label="基础学科专业"
>
<Select
placeholder="请选择评价师等级"
placeholder="请选择基础学科专业"
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>
</Col>
<Col span={12}>
<Form.Item
name={["evaluatorCert", "certNo"]}
label="证书编号"
rules={[
{ required: true, message: "请输入证书编号" },
{ max: 50, message: "证书编号不能超过50个字符" },
]}
name="industryCode"
label="专业"
rules={[{ required: true, message: "请选择专业" }]}
>
<Input placeholder="请输入证书编号" maxLength={50} />
<Select
placeholder="请选择专业"
allowClear
options={PROFESSIONAL_MAJOR_OPTIONS}
/>
</Form.Item>
</Col>
<Col span={24}>
<Col span={12}>
<AttachmentUpload
name={["evaluatorCert", "certAttachmentUrl"]}
label="评价师证书"
extra="最多上传10个pdf,doc,docx,图片格式文件"
name="proveUrl"
label="证明材料"
extra="最多上传1个pdf,doc,docx,图片格式文件"
accept=".pdf,.doc,.docx,.png,.jpg,.jpeg,.bmp,.webp"
maxCount={10}
rules={[
{ required: true, message: "请上传评价师证书" },
]}
maxCount={1}
rules={[{ required: true, message: "请上传证明材料" }]}
/>
</Col>
</>
)}
</Row>
</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="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>
</Modal>
);

View File

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

View File

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