Merge remote-tracking branch 'origin/dev-tmp1' into dev-tmp1

dev-tmp1
huwei 2026-08-28 19:17:14 +08:00
commit c2d83f6adf
9 changed files with 234 additions and 187 deletions

View File

@ -0,0 +1,49 @@
评价人员任命及专家聘用书
根据市场部下达的评价项目为: {projectName} {evalTypeText} 评价任务,结合项目的特性,现任命 {projectLeader} 担任该安全评价项目组长(负责人), {compiler} 担任该项目报告编制人。
根据评价部项目组组建原则及风险分析记录情况,项目组成员如下:
人员组成
姓名
专业
项目负责人
{projectLeaderName}
{projectLeaderCapacity}
项目组成员
{firstMemberName}
{firstMemberMajor}
{#memberRows}{name}
{major}{/memberRows}
报告编制人
{firstCompilerName}
{firstCompilerCapacity}
{#compilerRows}{compilerName}
{compilerCapacity}{/compilerRows}
内审人员
{firstAuditorName}
{firstAuditorCapacity}
{#auditorRows}{auditorName}
{auditorCapacity}{/auditorRows}
技术负责人
{firstTechLeadName}
{firstTechLeadCapacity}
{#techLeadRows}{techLeadName}
{techLeadCapacity}{/techLeadRows}
过程控制负责人
{processControlLeadName}
{processControlLeadCapacity}
聘用专家组成员
评价部经理:
年 月 日

View File

@ -181,7 +181,7 @@ export const evalProjectMemberPage = declareRequest(
export const evalProjectEstablishedAttachSave = declareRequest( export const evalProjectEstablishedAttachSave = declareRequest(
"projectEstablishedAttachSaveLoading", "projectEstablishedAttachSaveLoading",
"Post > /safetyEval/institution/eval-project-member/saveProjectEstablishedAttach", "Post > @/safetyEval/institution/eval-project-member/saveProjectEstablishedAttach",
); );
export const evalProjectEstablishedAttachGet = declareRequest( export const evalProjectEstablishedAttachGet = declareRequest(

View File

@ -8,6 +8,12 @@ export const staffInfoList = declareRequest(
"staffInfoList: [] | res.data || [] & staffInfoTotal: 0 | res.total || 0", "staffInfoList: [] | res.data || [] & staffInfoTotal: 0 | res.total || 0",
); );
export const staffInfoRegulationPage = declareRequest(
"staffInfoLoading",
"Get > /safetyEval/org-personnel/regulationPage",
"staffInfoList: [] | res.data || [] & staffInfoTotal: 0 | res.total || 0",
);
export const staffInfoDeptPersonCount = declareRequest( export const staffInfoDeptPersonCount = declareRequest(
"staffInfoLoading", "staffInfoLoading",
"Get > /safetyEval/org-personnel/deptPersonCount", "Get > /safetyEval/org-personnel/deptPersonCount",
@ -46,4 +52,4 @@ export const queryBasicDisciplineMajor = declareRequest(
"staffInfoLoading", "staffInfoLoading",
"Get > /safetyEval/basic-discipline-major", "Get > /safetyEval/basic-discipline-major",
"basicDisciplineMajorList: [] | res.data || []", "basicDisciplineMajorList: [] | res.data || []",
); );

View File

@ -600,6 +600,17 @@ export const CAPABILITY_MAP = CAPABILITY_OPTIONS.reduce((acc, cur) => {
return acc; return acc;
}, {}); }, {});
/** 业务范围与所需专业能力配备标准对照依据《安全评价机构资质条件》应急202660号附件 */
export const INDUSTRY_REQUIRED_CAPABILITIES = {
COAL_MINING: ["SAFETY", "MECHANICAL", "ELECTRICAL", "MINING", "VENTILATION", "GEOLOGY", "MINE_CONSTRUCTION"],
METAL_NONMETAL_MINING: ["SAFETY", "MECHANICAL", "ELECTRICAL", "MINING", "VENTILATION", "GEOLOGY", "HYDRAULIC_STRUCTURE"],
ONSHORE_OIL_GAS: ["SAFETY", "MECHANICAL", "ELECTRICAL", "OIL_PRODUCTION", "STORAGE_AND_TRANSPORT"],
ONSHORE_OIL_GAS_PIPELINE: ["OIL_GAS_STORAGE_TRANSPORT", "EQUIPMENT", "INSTRUMENT", "ELECTRICAL", "ANTICORROSION", "SAFETY"],
PETROCHEMICAL_CHEMICAL_PHARMACEUTICAL: ["CHEMICAL_PROCESS", "CHEMICAL_MECHANICAL", "AUTOMATION_INSTRUMENT", "ELECTRICAL", "SAFETY"],
FIREWORKS_FIRECRACKERS: ["EXPLOSIVES", "EXPLOSION_TECHNOLOGY", "MECHANICAL", "ELECTRICAL", "SAFETY"],
METAL_SMELTING: ["SAFETY", "MECHANICAL", "ELECTRICAL", "METALLURGY", "NONFERROUS_METAL"],
};
/** 专业(职称信息) */ /** 专业(职称信息) */
export const PROFESSIONAL_MAJOR_OPTIONS = [ export const PROFESSIONAL_MAJOR_OPTIONS = [
{ label: "安全工程", value: "SAFETY_ENGINEERING" }, { label: "安全工程", value: "SAFETY_ENGINEERING" },

View File

@ -21,7 +21,7 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime";
import useIndustryOptions from "~/hooks/useIndustryOptions"; 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 {REGISTER_ENGINEER_CATEGORY_OPTIONS} from '~/enumerate/enterpriseOptions'; import {QUALIFICATION_INDUSTRY_OPTIONS} from '~/enumerate/enterpriseOptions';
import { phoneRule } from "~/utils/validators"; import { phoneRule } from "~/utils/validators";
import { renderCapabilityList } from "~/utils"; import { renderCapabilityList } from "~/utils";
import StaffPickerModal from "./StaffPickerModal"; import StaffPickerModal from "./StaffPickerModal";
@ -29,6 +29,7 @@ import StaffPickerModal from "./StaffPickerModal";
import { import {
EVAL_TYPE_OPTIONS, EVAL_TYPE_OPTIONS,
CHECKIN_RADIUS_OPTIONS, CHECKIN_RADIUS_OPTIONS,
INDUSTRY_REQUIRED_CAPABILITIES,
} from "~/enumerate/constant"; } from "~/enumerate/constant";
const { router } = tools; const { router } = tools;
@ -102,9 +103,27 @@ const EvalProjectCreate = (props) => {
setMapPickerVisible(false); setMapPickerVisible(false);
}; };
/** 按所选业务范围(配备标准)筛选人员能力,仅提交范围内所需的专业能力条目 */
const filterCapacityByIndustry = (item, industryCodes) => {
const requiredCaps = industryCodes.flatMap(
(code) => INDUSTRY_REQUIRED_CAPABILITIES[code] || [],
);
const capabilityAssessment= (item.capabilityAssessment || []).filter(item=>item.industryCode === industryCodes[0]) || [];
if (!requiredCaps.length || !Array.isArray(capabilityAssessment)) {
return capabilityAssessment?.length
? renderCapabilityList(capabilityAssessment, {capFlag: true})
: item.capacity;
}
const matched = capabilityAssessment.filter((cap) =>
requiredCaps.includes(cap.professionalCapabilityCode),
);
return matched.length ? renderCapabilityList(matched, {capFlag: true}) : item.capacity;
};
const handleSubmit = () => { const handleSubmit = () => {
form.validateFields().then(async (values) => { form.validateFields().then(async (values) => {
const { planStartDate, planEndDate, ...rest } = values; const { planStartDate, planEndDate, ...rest } = values;
const industryCodes = String(values.industryCode || "").split(",");
const params = { const params = {
...rest, ...rest,
planStartDate: planStartDate?.format("YYYY-MM-DD"), planStartDate: planStartDate?.format("YYYY-MM-DD"),
@ -114,9 +133,7 @@ const EvalProjectCreate = (props) => {
name: item.userName, name: item.userName,
deptName: item.deptName, deptName: item.deptName,
posName: item.postName, posName: item.postName,
capacity: item.capabilityAssessment capacity: filterCapacityByIndustry(item, industryCodes),
? renderCapabilityList(item.capabilityAssessment)
: item.capacity,
})), })),
}; };
if (projectId) { if (projectId) {
@ -357,18 +374,18 @@ const EvalProjectCreate = (props) => {
} }
> >
<Select <Select
mode="multiple"
placeholder="请选择" placeholder="请选择"
allowClear allowClear
options={isStatutory?industryOptions:REGISTER_ENGINEER_CATEGORY_OPTIONS} options={isStatutory?industryOptions:QUALIFICATION_INDUSTRY_OPTIONS}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> {/* <Col span={12}>
<Form.Item name="controlledNumber" label="受控编号" rules={[{ required: true, message: "请选择受控编号" }]}> <Form.Item name="controlledNumber" label="受控编号" rules={[{ required: true, message: "请选择受控编号" }]}>
<Input placeholder="请输入" maxLength={20} /> <Input placeholder="请输入" maxLength={20} />
</Form.Item> </Form.Item>
</Col> </Col> */}
</Row> </Row>
</Card> </Card>

View File

@ -304,7 +304,7 @@ const RiskAnalysisContent = ({ readOnly, ...props }) => {
Array.isArray(value) ? value.join(",") : value Array.isArray(value) ? value.join(",") : value
} }
> >
<Select mode="multiple" placeholder="请选择所属行业" allowClear> <Select placeholder="请选择所属行业" allowClear>
{QUALIFICATION_INDUSTRY_OPTIONS.map((opt) => ( {QUALIFICATION_INDUSTRY_OPTIONS.map((opt) => (
<Select.Option key={opt.value} value={opt.value}> <Select.Option key={opt.value} value={opt.value}>
{opt.label} {opt.label}

View File

@ -25,7 +25,9 @@ import { fillDocxTemplate } from "~/utils/fillDocxTemplate";
const { router } = tools; const { router } = tools;
const TEAM_TEMPLATE_URL = "https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a86d2b2e4b072649bfb8a93.docx"; const TEAM_TEMPLATE_URL = encodeURI(
"https://gbs-cqaqpj.oss-cn-beijing.aliyuncs.com/jjb/6a9165e2e4b0b3767a786858.docx",
);
const TeamContent = ({ readOnly, ...props }) => { const TeamContent = ({ readOnly, ...props }) => {
const { const {
@ -268,28 +270,57 @@ const TeamContent = ({ readOnly, ...props }) => {
setSigners((prev) => prev.filter((s) => s.personnelId !== personnelId)); setSigners((prev) => prev.filter((s) => s.personnelId !== personnelId));
}; };
// 导出Word按当前项目组配置填充模板聘请所需技术专家、备注事项、部门经理或负责人、年月日保留空白) // 导出Word按当前项目组配置填充模板任命语句用"姓名(能力)",表格姓名/专业分列展示;聘用专家、评价部经理、年月日留白)
const handleExport = async () => { const handleExport = async () => {
/** 人员展示文本:姓名后追加能力,如"张三(化工)" */ /** 人员展示文本:姓名后追加能力,如"张三(化工)" */
const personText = (m) => const personText = (m) =>
`${m.personnelName}${m.capacity ? `${m.capacity}` : ""}`; `${m.personnelName}${m.capacity ? `${m.capacity}` : ""}`;
const roleMembers = (role) =>
teamMembers.filter((m) => m.roles.some((r) => r.role === role));
const sentenceByRole = (role) =>
roleMembers(role).map(personText).join("、");
const namesByRole = (role) => const namesByRole = (role) =>
teamMembers roleMembers(role).map((m) => m.personnelName).join("、");
.filter((m) => m.roles.some((r) => r.role === role)) const capsByRole = (role) =>
.map(personText) roleMembers(role).map((m) => m.capacity).filter(Boolean).join("、");
.join("、"); const auditorList = roleMembers("INTERNAL_AUDITOR").map((m) => ({
auditorName: m.personnelName,
auditorCapacity: m.capacity || "",
}));
const techLeadList = roleMembers("TECHNICAL_LEAD").map((m) => ({
techLeadName: m.personnelName,
techLeadCapacity: m.capacity || "",
}));
const compilerList = roleMembers("REPORT_COMPILER").map((m) => ({
compilerName: m.personnelName,
compilerCapacity: m.capacity || "",
}));
const memberList = teamMembers
.filter((m) => !m.roles.some((r) => r.role === "PROJECT_LEAD"))
.map((m) => ({ name: m.personnelName, major: m.capacity || "" }));
const data = { const data = {
projectName: evalProjectDetailData?.projectName || "", projectName: evalProjectDetailData?.projectName || "",
evalTypeText: EVAL_TYPE_MAP[evalProjectDetailData?.evalTypeCode] || "", evalTypeText: EVAL_TYPE_MAP[evalProjectDetailData?.evalTypeCode] || "",
projectLeader: namesByRole("PROJECT_LEAD"), projectLeader: sentenceByRole("PROJECT_LEAD"),
membersText: teamMembers compiler: sentenceByRole("REPORT_COMPILER"),
.filter((m) => !m.roles.some((r) => r.role === "PROJECT_LEAD")) projectLeaderName: namesByRole("PROJECT_LEAD"),
.map(personText) projectLeaderCapacity: capsByRole("PROJECT_LEAD"),
.join("、"), // 标签合并分组首行固定放第一人循环行continue逐人一行
compiler: namesByRole("REPORT_COMPILER"), firstAuditorName: auditorList[0]?.auditorName || "",
auditor: namesByRole("INTERNAL_AUDITOR"), firstAuditorCapacity: auditorList[0]?.auditorCapacity || "",
techLead: namesByRole("TECHNICAL_LEAD"), auditorRows: auditorList.slice(1),
processControlLead: namesByRole("PROCESS_CONTROL_LEAD"), firstTechLeadName: techLeadList[0]?.techLeadName || "",
firstTechLeadCapacity: techLeadList[0]?.techLeadCapacity || "",
techLeadRows: techLeadList.slice(1),
processControlLeadName: namesByRole("PROCESS_CONTROL_LEAD"),
processControlLeadCapacity: capsByRole("PROCESS_CONTROL_LEAD"),
// 模板中标签列已纵向合并restart 行放第一名成员循环行continue逐人一行
firstMemberName: memberList[0]?.name || "",
firstMemberMajor: memberList[0]?.major || "",
memberRows: memberList.slice(1),
firstCompilerName: compilerList[0]?.compilerName || "",
firstCompilerCapacity: compilerList[0]?.compilerCapacity || "",
compilerRows: compilerList.slice(1),
}; };
try { try {
await fillDocxTemplate( await fillDocxTemplate(
@ -613,7 +644,9 @@ const TeamContent = ({ readOnly, ...props }) => {
{ ( { (
<LayoutFooterPortal slotId="pf-footer-slot"> <LayoutFooterPortal slotId="pf-footer-slot">
<Flex justify="flex-end" gap={8}> <Flex justify="flex-end" gap={8}>
<Button onClick={handleExport}>导出人员任命书</Button> <Button onClick={handleExport}>
导出人员任命书
</Button>
{!readOnly &&<Button {!readOnly &&<Button
type="primary" type="primary"
loading={memberSaveLoading || memberParticipantSaveLoading} loading={memberSaveLoading || memberParticipantSaveLoading}

View File

@ -1,82 +1,86 @@
import { Button, Descriptions, Form, Modal, Tag, Tooltip, Table } from "antd"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Form, Space, Table, Tag } from "antd";
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd"; import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper"; import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import SearchForm from "~/components/SearchForm"; import SearchForm from "~/components/SearchForm";
import StaffResumeModal from "~/components/StaffResumeModal";
import { NS_ORG_INFO, NS_STAFF_INFO } from "~/enumerate/namespace";
import {
REGISTER_ENGINEER_OPTIONS,
TITLE_LEVEL_MAP,
} from "~/enumerate/enterpriseOptions";
import { CERT_LEVEL_LABEL_BY_TYPE } from "~/enumerate/constant";
import { getEvaluatorDetail, queryEvaluatorPage } from "~/mock/regulator/basicInfo"; const EMPLOYMENT_STATUS_OPTIONS = [
{ label: "在职", value: 1 },
const YES_NO_OPTIONS = [ { label: "离职", value: 2 },
{ label: "是", value: 1 },
{ label: "否", value: 0 },
]; ];
const STATUS_OPTIONS = [ const REGISTER_ENGINEER_MAP = { 1: "是", 2: "否" };
{ label: "正常", value: "normal" }, const PERSONNEL_STATUS_MAP = { 1: "正常", 2: "异常" };
{ label: "异常", value: "abnormal" }, const evalCertLevelMap = CERT_LEVEL_LABEL_BY_TYPE.evaluator;
];
const CERT_STATUS_COLOR = {
normal: "success",
expiring: "warning",
expired: "error",
};
function EvaluatorInfoPage(props) { function EvaluatorInfoPage(props) {
const [searchForm] = Form.useForm(); const [searchForm] = Form.useForm();
const [viewOpen, setViewOpen] = useState(false); const [resumeOpen, setResumeOpen] = useState(false);
const [detail, setDetail] = useState(null); const [currentId, setCurrentId] = useState("");
const [detailLoading, setDetailLoading] = useState(false); const [orgOptions, setOrgOptions] = useState([]);
const [certPreview, setCertPreview] = useState(null);
const [dataSource, setDataSource] = useState([]); const [dataSource, setDataSource] = useState([]);
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const [pageIndex, setPageIndex] = useState(1); const [pageIndex, setPageIndex] = useState(1);
const [pageSize, setPageSize] = useState(10); const [pageSize, setPageSize] = useState(10);
const loading = props.staffInfo?.staffInfoLoading;
const fetchData = async (page = 1, size = 10) => { const fetchData = async (page = 1, size = 10) => {
setLoading(true); const formData = searchForm.getFieldsValue();
try { const res = await props.staffInfoRegulationPage({
const formData = searchForm.getFieldsValue(); ...formData,
const res = await queryEvaluatorPage({ ...formData, pageIndex: page, pageSize: size }); current: page,
size,
});
if (res?.success !== false) {
setDataSource(res?.data || []); setDataSource(res?.data || []);
setTotal(res?.totalCount || 0); setTotal(res?.total || 0);
setPageIndex(page);
setPageSize(size);
} }
catch { };
setDataSource([]);
setTotal(0); const loadOrgOptions = async () => {
} try {
finally { const res = await props.registeredOrgList({ current: 1, size: 200 });
setLoading(false); const list = res?.data || [];
setOrgOptions(
list.map((item) => ({
label:
item.unitName ||
item.orgName ||
item.name ||
item.enterpriseName ||
String(item.id),
value: String(item.id),
})),
);
} catch {
setOrgOptions([]);
} }
}; };
useEffect(() => { useEffect(() => {
fetchData(); fetchData();
loadOrgOptions();
}, []); }, []);
const openDetail = async (id) => {
setViewOpen(true);
setDetailLoading(true);
const res = await getEvaluatorDetail(id);
setDetail(res?.data || null);
setDetailLoading(false);
};
const closeDetail = () => {
setViewOpen(false);
setDetail(null);
setCertPreview(null);
};
return ( return (
<PageLayout <PageLayout
title={ title={
<div> <div>
<span>评价师信息管理</span> <span>评价师信息管理</span>
<div className="pageLayout-extra"> <div className="pageLayout-extra">
监管端查看辖区内评价师备案及资质状态当前为 Mock 数据 监管端查看辖区内评价师备案及资质状态
</div> </div>
</div> </div>
} }
@ -85,28 +89,44 @@ function EvaluatorInfoPage(props) {
form={searchForm} form={searchForm}
loading={loading} loading={loading}
formLine={[ formLine={[
<Form.Item key="evaluatorName" name="evaluatorName"> <Form.Item key="userName" name="userName">
<ControlWrapper.Input label="评价师名称" allowClear placeholder="关键字搜索" /> <ControlWrapper.Input label="评价师名称" allowClear placeholder="关键字搜索" />
</Form.Item>, </Form.Item>,
<Form.Item key="orgName" name="orgName"> <Form.Item key="orgId" name="orgId">
<ControlWrapper.Input label="机构名称" allowClear placeholder="关键字搜索" /> <ControlWrapper.Select
label="机构名称"
allowClear
showSearch
optionFilterProp="label"
placeholder="请选择"
options={orgOptions}
/>
</Form.Item>, </Form.Item>,
<Form.Item key="employmentStatus" name="employmentStatus"> <Form.Item key="employmentStatusCode" name="employmentStatusCode">
<ControlWrapper.Select label="是否在职" allowClear placeholder="请选择" options={YES_NO_OPTIONS} /> <ControlWrapper.Select
label="是否在职"
allowClear
placeholder="请选择"
options={EMPLOYMENT_STATUS_OPTIONS}
/>
</Form.Item>, </Form.Item>,
<Form.Item key="registerEngineerFlag" name="registerEngineerFlag"> <Form.Item key="registerEngineerFlag" name="registerEngineerFlag">
<ControlWrapper.Select label="是否注册安全工程师" allowClear placeholder="请选择" options={YES_NO_OPTIONS} /> <ControlWrapper.Select
</Form.Item>, label="是否注册安全工程师"
<Form.Item key="status" name="status"> allowClear
<ControlWrapper.Select label="状态" allowClear placeholder="请选择" options={STATUS_OPTIONS} /> placeholder="请选择"
options={REGISTER_ENGINEER_OPTIONS}
/>
</Form.Item>, </Form.Item>,
]} ]}
onFinish={() => fetchData(1, 10)} onFinish={() => fetchData(1, pageSize)}
onReset={() => fetchData(1, pageSize)}
style={{ style={{
marginBottom: '16px' marginBottom: "16px",
}} }}
/> />
<Table <Table
rowKey="id"
dataSource={dataSource} dataSource={dataSource}
loading={loading} loading={loading}
pagination={{ pagination={{
@ -117,129 +137,86 @@ function EvaluatorInfoPage(props) {
showTotal: (t) => `${t}`, showTotal: (t) => `${t}`,
}} }}
onChange={(pag) => { onChange={(pag) => {
setPageIndex(pag.current);
setPageSize(pag.pageSize);
fetchData(pag.current, pag.pageSize); fetchData(pag.current, pag.pageSize);
}} }}
scroll={{ y: props.scrollY }} scroll={{ y: props.scrollY }}
columns={[ columns={[
{ title: "机构名称", dataIndex: "orgName", ellipsis: true }, { title: "机构名称", dataIndex: "orgName", ellipsis: true },
{ title: "评价师名称", dataIndex: "evaluatorName", width: 120 }, { title: "评价师名称", dataIndex: "userName", width: 120 },
{ {
title: "是否注册安全工程师", title: "是否注册安全工程师",
dataIndex: "registerEngineerLabel", dataIndex: "registerEngineerFlag",
width: 160, width: 160,
render: (val) => REGISTER_ENGINEER_MAP[val] || "-",
},
{
title: "证照名称",
dataIndex: "personnelCertFilingPageCOList",
width: 280,
render: (_, record) => {
const arr = [];
if (record.registeredSafetyEngineerCert) {
arr.push(
<Tag color="blue" key="reg">
{TITLE_LEVEL_MAP[record.registeredSafetyEngineerCert.certLevel]}
注册安全工程师
</Tag>,
);
}
if (record.evaluatorCert) {
arr.push(
<Tag color="green" key="eval">
{evalCertLevelMap[record.evaluatorCert.certLevel]}
注册安全评价师
</Tag>,
);
}
return arr.length ? <Space size={4}>{arr}</Space> : "-";
},
}, },
{ title: "资格证书", dataIndex: "certificatesSummary", ellipsis: true },
{ {
title: "状态", title: "状态",
dataIndex: "personnelStatus",
width: 90, width: 90,
render: (_, record) => { render: (val) => (
const tag = ( <Tag color={val === 2 ? "error" : "success"}>
<Tag color={record.status === "normal" ? "success" : "error"}> {PERSONNEL_STATUS_MAP[val] || "正常"}
{record.statusLabel} </Tag>
</Tag> ),
);
return record.statusTip ? <Tooltip title={record.statusTip}>{tag}</Tooltip> : tag;
},
}, },
{ {
title: "操作", title: "操作",
width: 80, width: 80,
render: (_, record) => ( render: (_, record) => (
<Button type="link" onClick={() => openDetail(record.id)}>查看</Button> <Button
type="link"
onClick={() => {
setCurrentId(record.id);
setResumeOpen(true);
}}
>
查看
</Button>
), ),
}, },
]} ]}
/> />
<Modal {resumeOpen && (
open={viewOpen} <StaffResumeModal
destroyOnHidden open={resumeOpen}
title="评价师详细信息" currentId={currentId}
width={900} onCancel={() => {
loading={detailLoading} setResumeOpen(false);
cancelText="关闭" setCurrentId("");
okButtonProps={{ style: { display: "none" } }} }}
onCancel={closeDetail} />
> )}
{detail && (
<>
<Descriptions title="个人信息" bordered column={2} size="small" style={{ marginBottom: 16 }}>
<Descriptions.Item label="姓名">{detail.name}</Descriptions.Item>
<Descriptions.Item label="性别">{detail.gender}</Descriptions.Item>
<Descriptions.Item label="出生日期">{detail.birthDate}</Descriptions.Item>
<Descriptions.Item label="身份证号">{detail.idCard}</Descriptions.Item>
<Descriptions.Item label="学历">{detail.education}</Descriptions.Item>
<Descriptions.Item label="毕业院校">{detail.graduateSchool}</Descriptions.Item>
<Descriptions.Item label="专业">{detail.major}</Descriptions.Item>
</Descriptions>
<Descriptions title="机构信息" bordered column={2} size="small" style={{ marginBottom: 16 }}>
<Descriptions.Item label="所在机构">{detail.orgName}</Descriptions.Item>
<Descriptions.Item label="部门">{detail.deptName}</Descriptions.Item>
<Descriptions.Item label="岗位">{detail.positionName}</Descriptions.Item>
<Descriptions.Item label="账号">{detail.account}</Descriptions.Item>
</Descriptions>
<div style={{ marginBottom: 8, fontWeight: 600 }}>资质证照</div>
<Table
size="small"
bordered
rowKey="id"
pagination={false}
dataSource={detail.certificates || []}
columns={[
{ title: "证书名称", dataIndex: "certName" },
{ title: "证书编号", dataIndex: "certNo" },
{ title: "发证日期", dataIndex: "issueDate", width: 110 },
{ title: "有效期至", dataIndex: "expireDate", width: 110 },
{
title: "状态",
width: 90,
render: (_, record) => {
const tag = (
<Tag color={CERT_STATUS_COLOR[record.status] || "default"}>
{record.statusLabel}
</Tag>
);
return record.statusTip ? <Tooltip title={record.statusTip}>{tag}</Tooltip> : tag;
},
},
{
title: "操作",
width: 90,
render: (_, record) => (
<Button type="link" size="small" onClick={() => setCertPreview(record)}>
查看证书
</Button>
),
},
]}
/>
</>
)}
</Modal>
<Modal
open={!!certPreview}
destroyOnHidden
title="证书预览"
width={520}
cancelText="关闭"
okButtonProps={{ style: { display: "none" } }}
onCancel={() => setCertPreview(null)}
>
{certPreview && (
<Descriptions bordered column={1} size="small">
<Descriptions.Item label="证书名称">{certPreview.certName}</Descriptions.Item>
<Descriptions.Item label="证书编号">{certPreview.certNo}</Descriptions.Item>
<Descriptions.Item label="发证日期">{certPreview.issueDate}</Descriptions.Item>
<Descriptions.Item label="有效期至">{certPreview.expireDate}</Descriptions.Item>
<Descriptions.Item label="状态">{certPreview.statusLabel}</Descriptions.Item>
</Descriptions>
)}
</Modal>
</PageLayout> </PageLayout>
); );
} }
export default AntdTableFuncControl(EvaluatorInfoPage); export default Connect(
[NS_STAFF_INFO, NS_ORG_INFO],
true,
)(AntdTableFuncControl(EvaluatorInfoPage));

View File

@ -3,20 +3,23 @@ import { CAPABILITY_MAP } from "~/enumerate/constant";
import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions"; import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions";
/** 渲染专业能力列表,供表格 column render 使用 */ /** 渲染专业能力列表,供表格 column render 使用 */
export function renderCapabilityList(list) { export function renderCapabilityList(list, option) {
if (!Array.isArray(list) || !list.length) return "-"; if (!Array.isArray(list) || !list.length) return "-";
return ( return (
list list
.map((item) => { .map((item) => {
const cap = CAPABILITY_MAP[item.professionalCapabilityCode]; const cap = CAPABILITY_MAP[item.professionalCapabilityCode];
if (!cap) return null; if (!cap) return null;
if(option.capFlag){
return cap;
}
const industry = item.industryCode const industry = item.industryCode
? QUALIFICATION_INDUSTRY_OPTIONS_MAP[item.industryCode] ? QUALIFICATION_INDUSTRY_OPTIONS_MAP[item.industryCode]
: null; : null;
return industry ? `${industry}${cap}` : cap; return industry ? `${industry}${cap}` : cap;
}) })
.filter(Boolean) .filter(Boolean)
.join("") || "-" .join(";") || "-"
); );
} }