import { Button, Descriptions, Image, Modal, Table, Upload } from "antd"; import { useEffect, useRef, useState } from "react"; import FilePreviewModal, { FilePreviewContent, } from "~/components/FilePreviewModal"; import { resolvePreviewSrc } from "~/components/CertPreviewImg"; import { fetchStaffCertDetail, fetchStaffCertListByPersonnelId, } from "~/api/staffCertificate"; import { fetchOrgPersonnelDetail } from "~/utils/qualFiling/personnelHelper"; import { QUALIFICATION_INDUSTRY_OPTIONS_MAP, TITLE_LEVEL_MAP } from "~/enumerate/enterpriseOptions"; const GENDER_MAP = { 1: "男", 2: "女" }; const REGISTER_ENGINEER_MAP = { 1: "是", 2: "否" }; export default function StaffViewModal({ open, currentId, requestDetails = fetchOrgPersonnelDetail, requestCertList = fetchStaffCertListByPersonnelId, requestCertDetails = fetchStaffCertDetail, onCancel, }) { const [info, setInfo] = useState({}); const [certificates, setCertificates] = useState([]); const [detailLoading, setDetailLoading] = useState(false); const [attachmentPreview, setAttachmentPreview] = useState(null); const [certPreview, setCertPreview] = useState(null); const [certPreviewLoading, setCertPreviewLoading] = useState(false); const [certPreviewInfo, setCertPreviewInfo] = useState(null); const requestDetailsRef = useRef(requestDetails); const requestCertListRef = useRef(requestCertList); const requestCertDetailsRef = useRef(requestCertDetails); requestDetailsRef.current = requestDetails; requestCertListRef.current = requestCertList; requestCertDetailsRef.current = requestCertDetails; useEffect(() => { if (!open || !currentId) { setInfo({}); setCertificates([]); return; } let cancelled = false; setDetailLoading(true); const loadCertList = requestCertListRef.current; Promise.all([ Promise.resolve(requestDetailsRef.current({ id: currentId })).catch( (err) => { console.warn("[StaffViewModal] load detail failed:", err); return { data: {} }; }, ), typeof loadCertList === "function" ? Promise.resolve(loadCertList(currentId)).catch((err) => { console.warn("[StaffViewModal] load certificates failed:", err); return []; }) : Promise.resolve([]), ]) .then(([detailRes, certList]) => { if (!cancelled) { setInfo(detailRes?.data || {}); setCertificates(Array.isArray(certList) ? certList : []); } }) .finally(() => { if (!cancelled) { setDetailLoading(false); } }); return () => { cancelled = true; }; }, [open, currentId]); const openCertPreview = async (record) => { setCertPreview(record); setCertPreviewInfo(null); if (typeof requestCertDetailsRef.current !== "function") { setCertPreviewInfo(record); return; } setCertPreviewLoading(true); try { const res = await requestCertDetailsRef.current({ id: record.id }); setCertPreviewInfo(res?.data || record); } catch (err) { console.warn("[StaffViewModal] load cert detail failed:", err); setCertPreviewInfo(record); } finally { setCertPreviewLoading(false); } }; const proofMaterialUrl = info.proofMaterialUrl ? JSON.parse(info.proofMaterialUrl) : []; const titleCodeArr = Array.isArray(info.titleCodeArr) ? info.titleCodeArr.map((item) => { let proveUrlList = []; if (item.proveUrl) { try { proveUrlList = typeof item.proveUrl === "string" ? JSON.parse(item.proveUrl) : item.proveUrl; } catch { proveUrlList = []; } } return { industryName: QUALIFICATION_INDUSTRY_OPTIONS_MAP[item.industryCode] || item.industryCode || "-", titleName: TITLE_LEVEL_MAP[item.titleCode] || item.titleCode || "-", proveUrlList, }; }) : []; const renderFileList = (files) => { if (!files?.length) return "-"; return files.map((item) => { const isImage = /\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?.*)?$/i.test( item.url, ); return (
{isImage ? ( ) : ( )}
); }); }; const certPreviewFiles = certPreviewInfo?.certImgs?.length ? certPreviewInfo.certImgs : certPreviewInfo?.certImgFiles || []; const certPreviewUrl = resolvePreviewSrc(certPreviewFiles[0]); const certPreviewName = certPreviewFiles[0]?.fileName || certPreviewFiles[0]?.name || certPreviewInfo?.certName; return ( <> {info.userName} {GENDER_MAP[info.genderCode]} {info.birthDate} {info.joinWorkDate} {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.processControlLeaderFlag === true ? "是" : info.processControlLeaderFlag === false ? "否" : "-"} {info.idCardNo} {info.currentAddress} {info.officeAddress} {info.graduateSchool} {info.publications || "-"} {info.abilityDeclaration || "-"} {info.workExperience || "-"} {proofMaterialUrl.length ? proofMaterialUrl.map((item) => { const isImage = /\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?.*)?$/i.test(item.url); return (
{isImage ? ( ) : ( )}
); }) : "-"}
证照信息
( ), }, ]} /> setAttachmentPreview(null)} /> { setCertPreview(null); setCertPreviewInfo(null); }} onOk={() => { if (certPreviewUrl) { window.open(certPreviewUrl, "_blank"); } setCertPreview(null); setCertPreviewInfo(null); }} > {certPreviewInfo && (
{certPreviewInfo.certName} {certPreviewInfo.certNo} {certPreviewInfo.certTypeName || "-"} {certPreviewInfo.issueOrg || "-"} {certPreviewInfo.validStartDate || "-"} {certPreviewInfo.validEndDate || "-"} {certPreviewInfo.certAttachmentUrl && certPreviewInfo.certAttachmentUrl.split(",").map((item) => { const isImage = /\.(png|jpe?g|gif|bmp|webp|svg)(\?|#|$)/i.test(item); return (
{isImage ? ( ) : ( window.open(item)}>{item} )}
); })}
)}
); }