diff --git a/jjb.config.js b/jjb.config.js index 054f850..b95671a 100644 --- a/jjb.config.js +++ b/jjb.config.js @@ -10,9 +10,9 @@ module.exports = { javaGitBranch: "dev", // 本地联调 safetyEval-service(context-path: /safetyEval,默认端口 8095) // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 - API_HOST: "https://gbs-gateway.qhdsafety.com", + // API_HOST: "https://gbs-gateway.qhdsafety.com", - //API_HOST: "http://192.168.0.152", + API_HOST: "http://192.168.0.134", //API_HOST: "http://192.168.0.150", //太浅 // API_HOST: "http://192.168.0.152", //API_HOST: "http://192.168.0.103", //huwei diff --git a/src/components/StaffViewModal/index.js b/src/components/StaffViewModal/index.js index cef0107..5eb3290 100644 --- a/src/components/StaffViewModal/index.js +++ b/src/components/StaffViewModal/index.js @@ -9,7 +9,10 @@ import { fetchStaffCertListByPersonnelId, } from "~/api/staffCertificate"; import { fetchOrgPersonnelDetail } from "~/utils/qualFiling/personnelHelper"; -import { QUALIFICATION_INDUSTRY_OPTIONS_MAP, TITLE_LEVEL_MAP } from "~/enumerate/enterpriseOptions"; +import { + QUALIFICATION_INDUSTRY_OPTIONS_MAP, + TITLE_LEVEL_MAP, +} from "~/enumerate/enterpriseOptions"; const GENDER_MAP = { 1: "男", 2: "女" }; const REGISTER_ENGINEER_MAP = { 1: "是", 2: "否" }; @@ -182,45 +185,30 @@ export default function StaffViewModal({ {info.account} {info.deptName} {info.postName} - - {QUALIFICATION_INDUSTRY_OPTIONS_MAP[info.qualScope] || info.qualScope || "-"} - + {info.educationTypeName || "-"} {info.educationLevelName || "-"} - - {titleCodeArr.length ? ( - idx} - dataSource={titleCodeArr} - columns={[ - { title: "行业", dataIndex: "industryName", width: 150 }, - { title: "职称", dataIndex: "titleName", width: 100 }, - { - title: "证明材料", - dataIndex: "proveUrlList", - render: renderFileList, - }, - ]} - /> - ) : ( - "-" - )} - + {REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"} - {info.technicalDirectorFlag === true ? "是" : info.technicalDirectorFlag === false ? "否" : "-"} + {info.technicalDirectorFlag === true + ? "是" + : info.technicalDirectorFlag === false + ? "否" + : "-"} - {info.processControlLeaderFlag === true ? "是" : info.processControlLeaderFlag === false ? "否" : "-"} + {info.processControlLeaderFlag === true + ? "是" + : info.processControlLeaderFlag === false + ? "否" + : "-"} {info.idCardNo} @@ -235,7 +223,7 @@ export default function StaffViewModal({ {info.graduateSchool} - + +
+ 职称信息 +
+
idx} + dataSource={titleCodeArr} + columns={[ + { title: "行业", dataIndex: "industryName", width: 150 }, + { title: "职称", dataIndex: "titleName", width: 100 }, + { + title: "证明材料", + dataIndex: "proveUrlList", + render: renderFileList, + }, + ]} + />
证照信息 @@ -289,10 +296,10 @@ export default function StaffViewModal({ dataSource={certificates} locale={{ emptyText: "暂无证照信息" }} columns={[ - { title: "证照名称", dataIndex: "certName",ellipsis: true }, - { title: "证书编号", dataIndex: "certNo",ellipsis: true }, - { title: "证书类别", dataIndex: "certTypeName",ellipsis: true }, - { title: "发证机关", dataIndex: "issueOrg",ellipsis: true }, + { title: "证照名称", dataIndex: "certName", ellipsis: true }, + { title: "证书编号", dataIndex: "certNo", ellipsis: true }, + { title: "证书类别", dataIndex: "certTypeName", ellipsis: true }, + { title: "发证机关", dataIndex: "issueOrg", ellipsis: true }, { title: "有效开始日期", dataIndex: "validStartDate", width: 120 }, { title: "有效结束日期", dataIndex: "validEndDate", width: 120 }, { @@ -372,11 +379,16 @@ export default function StaffViewModal({ {certPreviewInfo.certAttachmentUrl && certPreviewInfo.certAttachmentUrl.split(",").map((item) => { - const isImage = /\.(png|jpe?g|gif|bmp|webp|svg)(\?|#|$)/i.test(item); + const isImage = + /\.(png|jpe?g|gif|bmp|webp|svg)(\?|#|$)/i.test(item); return (
{isImage ? ( - + ) : ( window.open(item)}>{item} )} diff --git a/src/enumerate/constant/index.js b/src/enumerate/constant/index.js index adc1d11..74d8704 100644 --- a/src/enumerate/constant/index.js +++ b/src/enumerate/constant/index.js @@ -482,34 +482,4 @@ export const NATIONAL_COUNTIES = (() => { return result; })(); -/** 专业学科 */ -export const DISCIPLINE_OPTIONS = [ - { label: "安全", value: "SAFETY" }, - { label: "机械", value: "MECHANICAL" }, - { label: "电气", value: "ELECTRICAL" }, - { label: "采矿", value: "MINING" }, - { label: "通风", value: "VENTILATION" }, - { label: "矿建", value: "MINE_CONSTRUCTION" }, - { label: "地质", value: "GEOLOGY" }, - { label: "水工结构", value: "HYDRAULIC_STRUCTURE" }, - { label: "采油", value: "OIL_PRODUCTION" }, - { label: "储运", value: "STORAGE_AND_TRANSPORT" }, - { label: "油气储运", value: "OIL_GAS_STORAGE_TRANSPORT" }, - { label: "工艺设备与控制", value: "PROCESS_EQUIPMENT_CONTROL" }, - { label: "自动化(仪表)", value: "AUTOMATION_INSTRUMENT" }, - { label: "防腐", value: "ANTICORROSION" }, - { label: "化工工艺", value: "CHEMICAL_PROCESS" }, - { label: "化工机械", value: "CHEMICAL_MECHANICAL" }, - { label: "自动化", value: "AUTOMATION" }, - { label: "火炸药", value: "EXPLOSIVES" }, - { label: "爆炸技术", value: "EXPLOSION_TECHNOLOGY" }, - { label: "冶金", value: "METALLURGY" }, - { label: "有色金属", value: "NONFERROUS_METAL" }, - { label: "设备", value: "EQUIPMENT" }, - { label: "仪表", value: "INSTRUMENT" }, -]; -export const DISCIPLINE_MAP = DISCIPLINE_OPTIONS.reduce((acc, cur) => { - acc[cur.value] = cur.label; - return acc; -}, {}); diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js index 22a56f4..c6a35c1 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js @@ -1,5 +1,6 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { + Alert, Button, DatePicker, Form, @@ -9,9 +10,12 @@ import { Row, Col, Select, + Space, Table, TreeSelect, + Upload, } from "antd"; +import { InboxOutlined } from "@ant-design/icons"; import { Get } from "@cqsjjb/jjb-common-lib/http"; import { useEffect, useRef, useState } from "react"; import dayjs from "dayjs"; @@ -29,17 +33,18 @@ import { REGISTER_ENGINEER_OPTIONS, TITLE_LEVEL_OPTIONS, } from "~/enumerate/enterpriseOptions"; -import { DISCIPLINE_MAP } from "~/enumerate/constant"; import { getBirthDateFromIdCard } from "~/utils"; import { idCardRule, mobileRule } from "~/utils/validators"; import AttachmentUpload from "~/components/AttachmentUpload"; import StaffViewModal from "~/components/StaffViewModal"; const { router } = tools; +const API_HOST = window.process?.env?.app?.API_HOST || ""; function PersonnelInfoPage(props) { const [formModalOpen, setFormModalOpen] = useState(false); const [viewModalOpen, setViewModalOpen] = useState(false); + const [importModalOpen, setImportModalOpen] = useState(false); const [currentId, setCurrentId] = useState(""); const [searchForm] = Form.useForm(); const [deptOptions, setDeptOptions] = useState([]); @@ -135,15 +140,18 @@ function PersonnelInfoPage(props) {
} extra={ - + + + + } > )} + {importModalOpen && ( + setImportModalOpen(false)} + onSuccess={handleSearch} + /> + )} ); } @@ -378,13 +393,14 @@ function StaffFormModal({ } }; - const loadBasicDisciplineMajors = async (industryCode) => { - if (!industryCode) return; - await queryBasicDisciplineMajor({ industryCode, pageSize: 999 }); + const loadBasicDisciplineMajors = async () => { + + await queryBasicDisciplineMajor({ pageSize: 999 }); }; useEffect(() => { if (open && !wasOpenRef.current) { + loadBasicDisciplineMajors(); if (!currentId) { form.resetFields(); setDeptPositionOptions([]); @@ -434,7 +450,7 @@ function StaffFormModal({ } form.setFieldsValue(setFields); - loadBasicDisciplineMajors(data.qualScope); + }) .finally(() => { if (!cancelled) setDetailLoading(false); @@ -463,7 +479,7 @@ function StaffFormModal({ } if ("qualScope" in changed) { form.setFieldValue("basicDisciplineMajorId", undefined); - loadBasicDisciplineMajors(changed.qualScope); + loadBasicDisciplineMajors(); } }; @@ -629,15 +645,7 @@ function StaffFormModal({ -
- - ({ - label: `${item.professionalName}(${DISCIPLINE_MAP[item.professionalCapabilityCode]})`, + label: `${item.professionalName}`, value: item.id, }), )} @@ -909,6 +917,151 @@ function StaffFormModal({ ); } +function StaffImportModal({ open, onCancel, onSuccess }) { + const [result, setResult] = useState(null); + const [errorMsg, setErrorMsg] = useState(""); + const [uploading, setUploading] = useState(false); + + const handleDownloadTemplate = async () => { + try { + const res = await Get("/safetyEval/org-personnel/import/template"); + const url = res?.data ; + if (!url) { + message.warning("未获取到模板下载地址"); + return; + } + const resolved = /^https?:\/\//i.test(url) + ? url + : `${window.fileUrl || API_HOST}${url}`; + const response = await fetch(resolved); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const blob = await response.blob(); + const blobUrl = window.URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = blobUrl; + link.download = "人员导入模板.xlsx"; + link.style.display = "none"; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + window.URL.revokeObjectURL(blobUrl); + } catch (err) { + message.error(err?.message || "下载模板失败"); + } + }; + + const customRequest = async (options) => { + const { file, onSuccess: onDone, onError } = options; + setUploading(true); + setResult(null); + setErrorMsg(""); + try { + const formData = new FormData(); + formData.append("file", file); + const headers = { token: sessionStorage.getItem("token") || "" }; + const orgInfoId = sessionStorage.getItem("orgInfoId"); + if (orgInfoId) headers.orgInfoId = String(orgInfoId); + const resp = await fetch( + `${API_HOST}/safetyEval/org-personnel/import`, + { method: "POST", headers, body: formData }, + ); + const json = await resp.json(); + if (json && json.success !== false) { + onDone(json.data, file); + setResult(json.data || {}); + if ((json.data?.successCount || 0) > 0) onSuccess?.(); + } else { + onError(new Error(json?.errMessage || json?.message || "导入失败")); + setErrorMsg(json?.errMessage || json?.message || "导入失败"); + } + } catch (err) { + onError(err); + setErrorMsg(err?.message || "导入失败"); + } finally { + setUploading(false); + } + }; + + const errorList = result?.errors || []; + + return ( + 关闭} + > +
+ +
+ { + const ext = + "." + (file.name.split(".").pop() || "").toLowerCase(); + if (![".xlsx", ".xls"].includes(ext)) { + message.error("仅支持 .xlsx / .xls 格式文件"); + return Upload.LIST_IGNORE; + } + return true; + }} + onRemove={() => { + setResult(null); + setErrorMsg(""); + return true; + }} + > +

+ +

+

点击或拖拽文件到此区域上传

+

仅支持 .xlsx / .xls 格式文件

+
+ + {errorMsg && ( + + )} + {result && ( + 0 ? "warning" : "success"} + showIcon + message={`成功导入 ${result.successCount || 0} 条,失败 ${result.failCount || 0} 条`} + /> + )} + {errorList.length > 0 && ( +
i} + pagination={false} + scroll={{ y: 240 }} + dataSource={errorList} + columns={[ + { title: "行号", dataIndex: "rowIndex", width: 70 }, + { title: "账号", dataIndex: "account", ellipsis: true }, + { title: "姓名", dataIndex: "userName", ellipsis: true }, + { title: "异常原因", dataIndex: "errorMessage", ellipsis: true }, + ]} + /> + )} + + ); +} + export default Connect( [NS_STAFF_INFO, NS_ORG_DEPARTMENT], true,