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 (