import React, { useState, useMemo } from "react";
import { Button, Image, Input, Select, Table, Tabs, Tag } from "antd";
import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { NS_QUAL_REVIEW, NS_EQUIP_INFO } from "~/enumerate/namespace";
import StaffViewModal from "~/components/StaffViewModal";
import PreviewUrlButton from "~/components/PreviewUrlButton/index";
import { EquipViewModal } from "~/pages/Container/EnterpriseInfo/EquipInfo";
import {
QUALIFICATION_INDUSTRY_OPTIONS,
QUALIFICATION_INDUSTRY_OPTIONS_MAP,
TITLE_LEVEL_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 : "-";
}
/**
* 职称名称:后端 QualFilingPersonnelInfoCO 返回 titleCodeArr(编码数组),
* 转中文名称展示(高级/中级/初级)。变更时间:2026-08-10(对齐后端字段)
*/
function titleNames(titleCodeArr) {
// 兼容:初审返回数组,备案变更返回字符串(可能为 "SENIOR" / "SENIOR,MIDDLE" / JSON 数组字符串)。变更时间:2026-08-10
let list = Array.isArray(titleCodeArr) ? titleCodeArr : [];
if (!Array.isArray(titleCodeArr) && typeof titleCodeArr === "string") {
try {
const parsed = JSON.parse(titleCodeArr);
list = Array.isArray(parsed) ? parsed : [titleCodeArr];
} catch {
list = String(titleCodeArr)
.split(/[,,、]/)
.map((s) => s.trim())
.filter(Boolean);
}
}
const names = list
.map((item) => {
const code = typeof item === "string" ? item : item?.titleCode || item?.title;
return item?.titleName || TITLE_LEVEL_MAP[code] || code || "";
})
.filter(Boolean);
// 空数组返回空字符串,便于调用方回退 titleName 等字段
return names.length ? names.join("、") : "";
}
/**
* 从业年限:后端返回 joinWorkDate(参加工作时间),按当前日期推算年数。
* 变更时间:2026-08-10(对齐后端字段)
*/
function workYearsText(joinWorkDate) {
if (!joinWorkDate) return "-";
const d = new Date(String(joinWorkDate).replace(/-/g, "/"));
if (Number.isNaN(d.getTime())) return "-";
const now = new Date();
let years = now.getFullYear() - d.getFullYear();
const m = now.getMonth() - d.getMonth();
if (m < 0 || (m === 0 && now.getDate() < d.getDate())) years--;
return years >= 0 ? `${years}年` : "-";
}
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 (
);
}
const FilingTabs = ({
detail = {},
isReview = false,
compliance = {},
onComplianceChange,
/**
* 额外 Tab(如机构备案详情「7. 变更记录」),数组元素与 antd Tabs items 同构。
* 不传时保持原 6 Tab,不影响初审/确认/专家核验展示。变更时间:2026-08-10
*/
extraTabs,
equipInfoGet,
}) => {
const [viewId, setViewId] = useState("");
const [equipViewOpen, setEquipViewOpen] = useState(false);
const [equipId, setEquipId] = useState("");
const personnelRows = useMemo(
() =>
(detail.personnelList || []).map((item) => ({
...item,
age: item.age ?? calcAge(item.birthDate),
})),
[detail.personnelList],
);
/**
* 管理人员判定:technicalDirectorFlag(技术负责人) 或 processControlLeaderFlag(过程控制负责人) 为 true;
* 法定代表人/负责人按岗位名兜底归入管理人员。
* 备案变更详情人员 CO(QualFilingPersonnelChangeInfoCO)暂未返回 flag 字段,靠岗位名兜底判断(待后端补充 flag)。
* 变更时间:2026-08-10(按后端人员标识字段拆分)
*/
const isManager = (item) =>
item.technicalDirectorFlag === true ||
item.processControlLeaderFlag === true ||
/法定代表人|负责人/.test(item.positionName || "");
const managerRows = useMemo(() => {
return personnelRows.filter(isManager);
}, [personnelRows]);
/** 专职安全评价师:非管理人员的其余人员 */
const evaluatorRows = useMemo(() => {
return personnelRows.filter((item) => !isManager(item));
}, [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 basePersonCols = (withScope) => [
{ title: "序号", width: 60, render: (_, __, i) => i + 1 },
{ title: "姓名", dataIndex: "personName", width: 110 },
{ title: "岗位类别", dataIndex: "positionName", width: 140, ellipsis: true },
{
title: "学历/专业",
width: 160,
// 后端字段:educationName(学历) / basicDisciplineMajorName(专业);变更时间:2026-08-10
render: (_, r) =>
[r.educationName, r.basicDisciplineMajorName].filter(Boolean).join(" / ") || "-",
},
{
title: "职称",
width: 120,
render: (_, r) => titleNames(r.titleCodeArr) || r.titleName || "-",
},
{
title: "从业年限",
width: 100,
render: (_, r) =>
r.workYears || r.yearsOfWorking || workYearsText(r.joinWorkDate),
},
{
title: "专业能力",
width: 180,
render: (_, r) => {
// 能力编码:兼容 professionalCapabilityCodeList 与后端 capabilityAssessment;变更时间:2026-08-10
// 备案变更返回 capabilityAssessment 字符串(JSON 数组),需解析后映射
let capList = r.capabilityAssessment;
if (typeof capList === "string") {
try {
const parsed = JSON.parse(capList);
capList = Array.isArray(parsed) ? parsed : [];
} catch {
capList = [];
}
}
const codes =
r.professionalCapabilityCodeList ||
(Array.isArray(capList)
? capList.map((c) => (typeof c === "string" ? c : c?.professionalCapabilityCode)).filter(Boolean)
: []) ||
[];
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: (
初次申请无需填写,已有资质备案时填写
{/* 法定代表人:后端 CO 字段为 legalRepresentative(表 legal_representative);变更时间:2026-08-10 */}
{attachmentList.length ? (
<>
查看营业执照
{attachmentList[0].name || "营业执照.pdf"}
>
) : (
—
)}
),
},
{
key: "management",
label: "2. 管理人员基本情况汇总表",
children: (
),
},
{
key: "evaluators",
label: "3. 专职安全评价师基本情况汇总表",
children: (
),
},
{
key: "materials",
label: "4. 申请材料",
children: (
),
},
{
key: "equipment",
label: "5. 设备清单",
children: (
i + 1 },
{ title: "装备名称", dataIndex: "deviceName", ellipsis: true },
{ title: "规格型号", dataIndex: "deviceModel", ellipsis: true },
{ title: "生产厂家", dataIndex: "manufacturer" },
{
title: "计量检定情况",
width: 120,
render: (_, record) => {
const tag = getCalibrationTag(record);
return (
{tag.label}
);
},
},
{
title: "操作",
width: 80,
render: (_, record) => (
),
},
]}
/>
),
},
{
key: "signature",
label: "6. 机构负责人签字",
children: (
机构负责人签字确认
机构端已完成资质申请第六项负责人签字,确认本次提交的基础信息、管理人员、专职安全评价师、申请材料和设备清单真实、准确、完整。
{commitment.legalRepSignatureUrl ? (
<>
查看签字件
已签字
>
) : (
未签字
)}
{commitment.legalRepSignatureUrl && (
)}
),
},
...(Array.isArray(extraTabs) ? extraTabs : []),
];
return (
<>
setViewId("")}
/>
{equipViewOpen && (
{
setEquipViewOpen(false);
setEquipId("");
}}
/>
)}
>
);
};
export default Connect([NS_QUAL_REVIEW, NS_EQUIP_INFO], true)(FilingTabs);