import React, { useState, useMemo } from "react"; import { Button, Image, Input, Modal, Select, Table, Tabs, Tag } from "antd"; import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { NS_QUAL_REVIEW } from "~/enumerate/namespace"; import StaffViewModal from "~/components/StaffViewModal"; import PreviewUrlButton from "~/components/PreviewUrlButton/index"; import { QUALIFICATION_INDUSTRY_OPTIONS, QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions"; import { CAPABILITY_MAP } from "~/enumerate/constant"; import { getCalibrationTag } from "../mockData"; const { TextArea } = Input; /** * 共享组件:资质备案初审 6 个标签页(详情 / 审核共用) * 对应原型 mod-qual-review-form / mod-qual-review-detail: * 1. 申请基本信息 2. 管理人员 3. 专职安全评价师 * 4. 申请材料 5. 设备清单 6. 机构负责人签字 * @param {Object} props * @param {Object} props.detail - 备案详情数据 * @param {boolean} [props.isReview=false] - 审核模式(材料表格开启"符合性"列) * @param {Object} [props.compliance={}] - 审核模式下的符合性状态 * @param {Function} [props.onComplianceChange] - 符合性变动回调 */ function calcAge(birthDate) { if (!birthDate) return "-"; const birth = new Date(birthDate); if (isNaN(birth.getTime())) return "-"; const now = new Date(); let age = now.getFullYear() - birth.getFullYear(); const m = now.getMonth() - birth.getMonth(); if (m < 0 || (m === 0 && now.getDate() < birth.getDate())) age--; return age >= 0 ? age : "-"; } const gridStyle = { display: "grid", gridTemplateColumns: "1fr 1fr", gap: "0.6rem 1rem", }; const fieldStyle = { display: "flex", flexDirection: "column", gap: "0.3rem" }; const labelStyle = { fontSize: "0.8rem", color: "#64748b", fontWeight: 500 }; const inputStyle = { background: "#f8fafc" }; const fullSpan = { gridColumn: "1 / -1" }; /** 只读字段 */ function ReadonlyField({ label, value, span }) { return (
); } /** * 设备详情弹窗(原型 modal-equip-view 缺失,按列表字段补全) */ function EquipViewModal({ record, onCancel }) { const open = !!record; const calibration = record ? getCalibrationTag(record) : null; const rows = record ? [ { label: "装备名称", value: record.deviceName }, { label: "规格型号", value: record.deviceModel }, { label: "生产厂家", value: record.manufacturer }, { label: "设备价值(元)", value: record.equipmentValue }, { label: "计量检定情况", value: null }, ] : []; return ( 关闭 } > {record && (
{rows.map((row) => row.value != null ? ( ) : (
{calibration && ( {calibration.label} )}
), )}
{record.calibrationReportUrl ? ( 预览检定报告 ) : ( 未上传 )}
)}
); } const FilingTabs = ({ detail = {}, isReview = false, compliance = {}, onComplianceChange, }) => { const [viewId, setViewId] = useState(""); const [equipRecord, setEquipRecord] = useState(null); const [previewImage, setPreviewImage] = useState(""); const personnelRows = useMemo( () => (detail.personnelList || []).map((item) => ({ ...item, age: item.age ?? calcAge(item.birthDate), })), [detail.personnelList], ); /** 管理人员:岗位含"法定代表人/负责人";无匹配时回退展示全部人员 */ const managerRows = useMemo(() => { const filtered = personnelRows.filter((item) => /法定代表人|技术负责人|过程控制负责人|负责人/.test(item.positionName || ""), ); return filtered.length ? filtered : personnelRows; }, [personnelRows]); /** 专职安全评价师:评价师证书号存在或岗位含"评价师";无匹配时回退展示全部人员 */ const evaluatorRows = useMemo(() => { const filtered = personnelRows.filter( (item) => item.evaluatorCertNo || /评价师/.test(item.positionName || ""), ); return filtered.length ? filtered : personnelRows; }, [personnelRows]); const attachmentList = useMemo(() => { const v = detail.attachmentUrl; if (!v) return []; try { const p = JSON.parse(v); return Array.isArray(p) ? p : []; } catch { return []; } }, [detail.attachmentUrl]); const businessScope = useMemo(() => { const list = Array.isArray(detail.businessScope) ? detail.businessScope : []; return QUALIFICATION_INDUSTRY_OPTIONS.map((opt) => ({ ...opt, checked: list.includes(opt.value), })); }, [detail.businessScope]); const openPreview = (file) => { const url = file?.url; if (!url) return; if (/\.(jpe?g|png|gif|webp|bmp)(\?|#|$)/i.test(`${file.name || ""} ${url}`.toLowerCase())) { setPreviewImage(url); } else { window.open(url, "_blank"); } }; /** 人员表格列(管理/评价师共用基础) */ const basePersonCols = (withScope) => [ { title: "序号", width: 60, render: (_, __, i) => i + 1 }, { title: "姓名", dataIndex: "personName", width: 110 }, { title: "岗位类别", dataIndex: "positionName", width: 140, ellipsis: true }, { title: "学历/专业", width: 160, render: (_, r) => [r.educationLevelName, r.majorName || r.educationTypeName].filter(Boolean).join(" / ") || "-", }, { title: "职称", dataIndex: "titleName", width: 120, render: (v) => v || "-" }, { title: "从业年限", width: 100, render: (_, r) => r.workYears || r.yearsOfWorking || "-", }, { title: "专业能力", width: 180, render: (_, r) => { const codes = r.professionalCapabilityCodeList || []; return codes.length ? codes.map((code) => CAPABILITY_MAP[code] || code).join("、") : "-"; }, }, ...(withScope ? [ { title: "申请业务范围", width: 200, ellipsis: true, render: (_, r) => { const scopes = r.appliedScope || r.scopeList; if (Array.isArray(scopes)) { return scopes.map((s) => QUALIFICATION_INDUSTRY_OPTIONS_MAP[s] || s).join("、"); } return scopes || "-"; }, }, ] : []), { title: "操作", width: 80, fixed: "right", render: (_, record) => ( ), }, ]; const materialCols = isReview ? [ { title: "序号", width: 60, render: (_, __, i) => i + 1 }, { title: "申请材料", dataIndex: "materialContent", ellipsis: true }, { title: "格式", dataIndex: "materialFormat", width: 80 }, { title: "状态", width: 100, render: (_, record) => record.uploadStatusCode === 2 ? ( {record.uploadStatusName || "已上传"} ) : ( {record.uploadStatusName || "待上传"} ), }, { title: "符合性", width: 110, render: (_, record) => ( ), }, { title: "操作", width: 80, render: (_, record) => ( 预览 ), }, ] : [ { title: "序号", width: 60, render: (_, __, i) => i + 1 }, { title: "申请材料", dataIndex: "materialContent", ellipsis: true }, { title: "格式", dataIndex: "materialFormat", width: 80 }, { title: "操作", width: 80, render: (_, record) => ( 预览 ), }, ]; const commitment = detail.commitment || {}; const items = [ { key: "info", label: "1. 申请基本信息", children: (
{businessScope.map((opt) => ( ))}
初次申请无需填写,已有资质备案时填写