safety-eval-service-frontend/src/pages/Container/QualApplication/filingVerify.js

113 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/** 资质申请前置条件核验(提交前展示,对齐原型) */
/** 人员相关三项暂不校验(机构库数据不足),恢复时改为 false */
const SKIP_PERSONNEL_VERIFY = true;
const KEY_POSITIONS = ["负责人", "技术负责人", "质量负责人"];
function ratio(count, total) {
if (!total) {
return 0;
}
return count / total;
}
function includesSeniorTitle(titleName = "") {
return String(titleName).includes("高级");
}
function includesMidTitle(titleName = "") {
return String(titleName).includes("中级") || includesSeniorTitle(titleName);
}
function isRegisterEngineer(record = {}) {
const flag = record.registerEngineerFlag;
return flag === 1 || flag === true || flag === "1";
}
export function verifyFilingPrerequisites(detail = {}) {
const items = [];
const fixedAsset = Number(detail.fixedAssetAmount) || 0;
items.push({
key: "entity",
label: "主体资格",
desc: "独立法人资格,固定资产不少于一千万元",
passed: fixedAsset >= 1000,
});
const workplaceArea = Number(detail.workplaceArea) || 0;
const equipmentCount = (detail.equipmentList || []).length;
items.push({
key: "facility",
label: "场所与设备",
desc: "工作场所建筑面积不少于1000㎡检测检验设施设备原值不少于800万元",
passed: workplaceArea >= 1000 && (equipmentCount > 0 || fixedAsset >= 800),
});
const personnel = detail.personnelList || [];
const total = personnel.length;
const regEngineerCount = personnel.filter(isRegisterEngineer).length;
const midTitleCount = personnel.filter((p) =>
includesMidTitle(p.titleName),
).length;
const seniorTitleCount = personnel.filter((p) =>
includesSeniorTitle(p.titleName),
).length;
items.push({
key: "personnelStructure",
label: "人员数量与结构",
desc: "专职技术人员≥25人中级注安师≥30%中级职称≥50%高级职称≥30%",
passed:
SKIP_PERSONNEL_VERIFY ||
(total >= 25 &&
ratio(regEngineerCount, total) >= 0.3 &&
ratio(midTitleCount, total) >= 0.5 &&
ratio(seniorTitleCount, total) >= 0.3),
});
const withExperience = personnel.filter((p) => {
const exp = String(p.workExperience || "");
return exp.length >= 4 || /[2-9]\s*年|[二三四五六七八九十]年/.test(exp);
}).length;
items.push({
key: "personnelExp",
label: "人员资历",
desc: "专职技术人员在本行业领域工作二年以上",
passed:
SKIP_PERSONNEL_VERIFY ||
(total >= 25 && ratio(withExperience, total) >= 0.8),
});
const keyOk = KEY_POSITIONS.every((pos) =>
personnel.some(
(p) =>
String(p.positionName || "").includes(pos) &&
includesSeniorTitle(p.titleName),
),
);
items.push({
key: "keyPosition",
label: "关键岗位要求",
desc: "负责人、技术负责人、质量负责人具有高级职称,工作八年以上",
passed: SKIP_PERSONNEL_VERIFY || keyOk,
});
const mgmtUploaded =
SKIP_PERSONNEL_VERIFY || detail.materials.every((m) => m.attachmentUrl);
items.push({
key: "mgmtSystem",
label: "管理体系",
desc: mgmtUploaded ? "管理体系文件已上传" : "尚未上传管理体系文件",
passed: mgmtUploaded,
});
return {
passed: items.every((item) => item.passed),
items,
};
}