dev-tmp1
tangjie 2026-08-12 11:50:26 +08:00
parent 64eac8a544
commit fd3b1f291e
9 changed files with 106 additions and 67 deletions

View File

@ -0,0 +1,18 @@
import { useMemo } from "react";
import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
/** 根据机构 orgInfo.safetyIndustryCategoryCode 过滤行业选项 */
const useIndustryOptions = () => {
return useMemo(() => {
const orgInfo = JSON.parse(sessionStorage.getItem("orgInfo") || "{}");
const codes = orgInfo?.safetyIndustryCategoryCode;
if (Array.isArray(codes) && codes.length > 0) {
return QUALIFICATION_INDUSTRY_OPTIONS.filter((item) =>
codes.includes(item.value),
);
}
return QUALIFICATION_INDUSTRY_OPTIONS;
}, []);
};
export default useIndustryOptions;

View File

@ -42,10 +42,9 @@ import {
CERT_LEVEL_OPTIONS_BY_TYPE, CERT_LEVEL_OPTIONS_BY_TYPE,
CAPABILITY_OPTIONS, CAPABILITY_OPTIONS,
PROFESSIONAL_MAJOR_OPTIONS, PROFESSIONAL_MAJOR_OPTIONS,
CAPABILITY_MAP,
CERT_LEVEL_LABEL_BY_TYPE CERT_LEVEL_LABEL_BY_TYPE
} from "~/enumerate/constant"; } from "~/enumerate/constant";
import { getBirthDateFromIdCard } from "~/utils"; import { getBirthDateFromIdCard, renderCapabilityList } from "~/utils";
import { idCardRule, mobileRule } from "~/utils/validators"; import { idCardRule, mobileRule } from "~/utils/validators";
import AttachmentUpload from "~/components/AttachmentUpload"; import AttachmentUpload from "~/components/AttachmentUpload";
import StaffViewModal from "~/components/StaffViewModal"; import StaffViewModal from "~/components/StaffViewModal";
@ -323,12 +322,7 @@ function PersonnelInfoPage(props) {
{ {
title: "专业能力", title: "专业能力",
dataIndex: "capabilityAssessment", dataIndex: "capabilityAssessment",
render: (list) => { render: renderCapabilityList,
if (!Array.isArray(list) || !list.length) return "-";
return list
.map((item) => CAPABILITY_MAP[item.professionalCapabilityCode])
.join("、");
},
}, },
{ {
title: "证照名称", title: "证照名称",

View File

@ -1,23 +1,11 @@
import { useMemo } from "react";
import { Form, Input, InputNumber, Row, Col, Select, Checkbox } from "antd"; import { Form, Input, InputNumber, Row, Col, Select, Checkbox } from "antd";
import { import { CHONGQING_DISTRICTS } from "~/enumerate/enterpriseOptions";
CHONGQING_DISTRICTS, import useIndustryOptions from "~/hooks/useIndustryOptions";
QUALIFICATION_INDUSTRY_OPTIONS,
} from "~/enumerate/enterpriseOptions";
import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions"; import { FILING_UNIT_TYPE_OPTIONS } from "~/enumerate/qualFilingOptions";
import AttachmentUpload from "~/components/AttachmentUpload"; import AttachmentUpload from "~/components/AttachmentUpload";
export default function BasicInfoStep({ form, disabled, mode }) { export default function BasicInfoStep({ form, disabled, mode }) {
const industryOptions = useMemo(() => { const industryOptions = useIndustryOptions();
const orgInfo = JSON.parse(sessionStorage.getItem("orgInfo") || "{}");
const codes = orgInfo?.safetyIndustryCategoryCode;
if (Array.isArray(codes) && codes.length > 0) {
return QUALIFICATION_INDUSTRY_OPTIONS.filter((item) =>
codes.includes(item.value),
);
}
return QUALIFICATION_INDUSTRY_OPTIONS;
}, []);
return ( return (
<Form form={form} layout="vertical" disabled={disabled}> <Form form={form} layout="vertical" disabled={disabled}>
<Row gutter={16}> <Row gutter={16}>

View File

@ -109,14 +109,14 @@ const ReviewModal = (props) => {
return ( return (
<Modal <Modal
title="📋 审核操作" title="审核操作"
open={open} open={open}
onCancel={onCancel} onCancel={onCancel}
width={620} width={620}
footer={ footer={
<div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}> <div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
<Button onClick={onCancel}>取消</Button> <Button onClick={onCancel}>取消</Button>
<Button loading={qualReviewSubmitLoading} onClick={handlePass}> <Button loading={qualReviewSubmitLoading} onClick={handlePass} color="green" variant="solid" >
通过 通过
</Button> </Button>
<Button <Button

View File

@ -14,6 +14,7 @@ import { CloseOutlined } from "@ant-design/icons";
import { NS_STAFF_INFO, NS_ORG_DEPARTMENT } from "~/enumerate/namespace"; import { NS_STAFF_INFO, NS_ORG_DEPARTMENT } from "~/enumerate/namespace";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { QUALIFICATION_INDUSTRY_OPTIONS_MAP, TITLE_LEVEL_MAP } from "~/enumerate/enterpriseOptions"; import { QUALIFICATION_INDUSTRY_OPTIONS_MAP, TITLE_LEVEL_MAP } from "~/enumerate/enterpriseOptions";
import { renderCapabilityList } from "~/utils";
@ -122,8 +123,9 @@ const StaffPickerModal = (props) => {
{ {
title: "能力", title: "能力",
dataIndex: "abilityNames", dataIndex: "capabilityAssessment",
ellipsis: true, ellipsis: true,
render: renderCapabilityList,
}, },

View File

@ -18,7 +18,7 @@ import { tools } from "@cqsjjb/jjb-common-lib";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace";
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions"; import useIndustryOptions from "~/hooks/useIndustryOptions";
import BaiduMapPicker from "~/components/BaiduMapPicker"; import BaiduMapPicker from "~/components/BaiduMapPicker";
import { district } from "~/enumerate/constant"; import { district } from "~/enumerate/constant";
import { phoneRule } from "~/utils/validators"; import { phoneRule } from "~/utils/validators";
@ -45,12 +45,12 @@ const EvalProjectCreate = (props) => {
evalProjectSaveLoading, evalProjectSaveLoading,
evalProjectDetailLoading, evalProjectDetailLoading,
customerPage: customerList, customerPage: customerList,
orgIndustryCodeList: industryCodes,
} = props.safetyEvalBusiness; } = props.safetyEvalBusiness;
const industryOptions = useIndustryOptions();
useEffect(() => { useEffect(() => {
props.customerPage({ current: 1, size: 999 }); props.customerPage({ current: 1, size: 999 });
props.orgIndustryCodeList();
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -309,13 +309,11 @@ const EvalProjectCreate = (props) => {
label="所属行业" label="所属行业"
rules={[{ required: true, message: "请选择所属行业" }]} rules={[{ required: true, message: "请选择所属行业" }]}
> >
<Select placeholder="请选择" allowClear> <Select
{(industryCodes || []).map((code) => ( placeholder="请选择"
<Select.Option key={code} value={code}> allowClear
{QUALIFICATION_INDUSTRY_OPTIONS_MAP[code] || code} options={industryOptions}
</Select.Option> />
))}
</Select>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>

View File

@ -15,16 +15,16 @@
line-height: 1.6; line-height: 1.6;
} }
/* 顶栏汇总 原型 .report-library-summary>div { border-radius: 6px } */ /* 顶栏汇总 - 原型 .report-library-summary>div { border-radius: 6px } */
.erl-summary { .erl-summary {
display: grid; display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr)); grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 0.7rem; gap: 11px;
margin-bottom: 1rem; margin-bottom: 16px;
} }
.erl-summary-item { .erl-summary-item {
padding: 0.8rem; padding: 13px;
background: #fff; background: #fff;
border: 1px solid #dce4ec; border: 1px solid #dce4ec;
border-radius: 6px; border-radius: 6px;
@ -36,23 +36,23 @@
} }
.erl-summary-item span { .erl-summary-item span {
font-size: 0.65rem; font-size: 10px;
color: #64748b; color: #64748b;
} }
.erl-summary-item strong { .erl-summary-item strong {
font-size: 1.18rem; font-size: 19px;
margin-top: 0.15rem; margin-top: 2px;
color: #0f172a; color: #0f172a;
font-weight: 600; font-weight: 600;
line-height: 1.2; line-height: 1.2;
} }
/* 报告名称文件图标 原型 .report-file-cell i { border-radius: 4px } */ /* 报告名称文件图标 - 原型 .report-file-cell i { border-radius: 4px } */
.erl-file-cell { .erl-file-cell {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.45rem; gap: 7px;
min-width: 0; min-width: 0;
} }
@ -66,7 +66,7 @@
border-radius: 4px; border-radius: 4px;
background: #fff1f2; background: #fff1f2;
color: #dc2626; color: #dc2626;
font-size: 0.55rem; font-size: 9px;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
} }
@ -90,7 +90,7 @@
.erl-action-btns { .erl-action-btns {
display: flex; display: flex;
gap: 0.35rem; gap: 6px;
flex-wrap: wrap; flex-wrap: wrap;
} }
@ -99,7 +99,7 @@
display: inline-block; display: inline-block;
padding: 2px 8px; padding: 2px 8px;
border-radius: 999px; border-radius: 999px;
font-size: 0.75rem; font-size: 12px;
font-weight: 500; font-weight: 500;
line-height: 1.4; line-height: 1.4;
background: #f1f5f9; background: #f1f5f9;
@ -126,13 +126,13 @@
color: #991b1b; color: #991b1b;
} }
/* 上传弹窗 原型 .modal { border-radius: var(--radius-lg)=12px } */ /* 上传弹窗 - 原型 .modal { border-radius: var(--radius-lg)=12px } */
.erl-modal-title { .erl-modal-title {
line-height: 1.3; line-height: 1.3;
} }
.erl-modal-subtitle { .erl-modal-subtitle {
margin-top: 0.2rem; margin-top: 3px;
font-size: 12px; font-size: 12px;
color: #64748b; color: #64748b;
font-weight: 400; font-weight: 400;
@ -147,9 +147,7 @@
.micro-temp-modal-body { .micro-temp-modal-body {
max-height: 72vh; max-height: 72vh;
overflow-y: auto; overflow-y: auto;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
@ -160,7 +158,7 @@
/* 原型单层虚线框,避免 Dragger 内外双边框 */ /* 原型单层虚线框,避免 Dragger 内外双边框 */
.erl-upload-box { .erl-upload-box {
margin-bottom: 1rem; margin-bottom: 16px;
border: 1px dashed #78aee8; border: 1px dashed #78aee8;
border-radius: 7px; border-radius: 7px;
background: #f4f9ff; background: #f4f9ff;
@ -202,8 +200,8 @@
display: grid; display: grid;
grid-template-columns: 54px 1fr auto; grid-template-columns: 54px 1fr auto;
align-items: center; align-items: center;
gap: 0.8rem; gap: 13px;
padding: 1rem; padding: 16px;
text-align: left; text-align: left;
} }
@ -217,7 +215,7 @@
border-radius: 6px; border-radius: 6px;
background: #fff1f2; background: #fff1f2;
color: #dc2626; color: #dc2626;
font-size: 0.7rem; font-size: 11px;
font-weight: 700; font-weight: 700;
} }
@ -228,19 +226,19 @@
} }
.erl-upload-text strong { .erl-upload-text strong {
font-size: 0.8rem; font-size: 13px;
color: #0f172a; color: #0f172a;
} }
.erl-upload-text p { .erl-upload-text p {
margin: 0.18rem 0; margin: 3px 0;
font-size: 0.64rem; font-size: 10px;
color: #64748b; color: #64748b;
line-height: 1.5; line-height: 1.5;
} }
.erl-upload-text span { .erl-upload-text span {
font-size: 0.65rem; font-size: 10px;
color: #2563eb; color: #2563eb;
} }
@ -248,25 +246,25 @@
.erl-upload-tip { .erl-upload-tip {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.45rem; gap: 7px;
flex-wrap: wrap; flex-wrap: wrap;
margin-top: 0.8rem; margin-top: 13px;
padding: 0.65rem 0.75rem; padding: 10px 12px;
border-radius: 6px; border-radius: 6px;
background: #f3f6f9; background: #f3f6f9;
} }
.erl-upload-tip strong { .erl-upload-tip strong {
font-size: 0.68rem;
color: #334155; color: #334155;
} }
.erl-upload-tip span { .erl-upload-tip span {
padding: 0.2rem 0.42rem; padding: 3px 7px;
border-radius: 10px; border-radius: 10px;
background: #fff; background: #fff;
color: #64748b; color: #64748b;
font-size: 0.58rem;
} }
.erl-detail-actions { .erl-detail-actions {

View File

@ -80,12 +80,43 @@ const buildProcessTabs = (projectNode, archiveFlag) => {
return true; return true;
}; };
const isNodeDone = (tabIdx) => {
const tabKey = PROCESS_TABS[tabIdx].key;
const tabType = Object.keys(TYPE_TO_TAB_KEY).find(
(k) => TYPE_TO_TAB_KEY[k] === tabKey,
);
const n = tabType ? nodeMap[tabType] : null;
return !!n && n.state === 1;
};
return PROCESS_TABS.map((item, idx) => { return PROCESS_TABS.map((item, idx) => {
const type = Object.keys(TYPE_TO_TAB_KEY).find( const type = Object.keys(TYPE_TO_TAB_KEY).find(
(k) => TYPE_TO_TAB_KEY[k] === item.key, (k) => TYPE_TO_TAB_KEY[k] === item.key,
); );
const node = type ? nodeMap[type] : null; const node = type ? nodeMap[type] : null;
if (idx === 2) {
// 项目组:业务合同完成后才解锁
const unlocked = isNodeDone(1);
return {
...item,
state: unlocked ? (node?.state === 1 ? "已完成" : "待办理") : "前置未完成",
stateType: unlocked ? (node?.state === 1 ? "success" : "default") : "warning",
locked: !unlocked,
};
}
if (idx === 3) {
// 现场踏勘:业务合同、项目组均完成后才解锁(串联)
const unlocked = isNodeDone(1) && isNodeDone(2);
return {
...item,
state: unlocked ? (node?.state === 1 ? "已完成" : "待办理") : "前置未完成",
stateType: unlocked ? (node?.state === 1 ? "success" : "default") : "warning",
locked: !unlocked,
};
}
if (idx === 7) { if (idx === 7) {
// 过程控制前7个全部完成才解锁 // 过程控制前7个全部完成才解锁
const unlocked = allPrevDone(7); const unlocked = allPrevDone(7);

View File

@ -1,4 +1,14 @@
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { CAPABILITY_MAP } from "~/enumerate/constant";
/** 渲染专业能力列表,供表格 column render 使用 */
export function renderCapabilityList(list) {
if (!Array.isArray(list) || !list.length) return "-";
return list
.map((item) => CAPABILITY_MAP[item.professionalCapabilityCode])
.filter(Boolean)
.join("、") || "-";
}
/** /**
* 根据身份证号计算年龄 * 根据身份证号计算年龄