diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingComplianceCheckResultCO.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingComplianceCheckResultCO.java index f445071..65e9841 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingComplianceCheckResultCO.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingComplianceCheckResultCO.java @@ -19,4 +19,10 @@ public class QualFilingComplianceCheckResultCO { @ApiModelProperty(value = "检查结果状态:PASS 通过 / NOT_PASS 未通过 / WARN 警告") private String status; + + @ApiModelProperty(value = "当前值") + private String currentValue; + + @ApiModelProperty(value = "来源字段") + private String sourceColumn; } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/QualFilingComplianceCheckEnum.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/QualFilingComplianceCheckEnum.java index e2d4795..fc24656 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/QualFilingComplianceCheckEnum.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/QualFilingComplianceCheckEnum.java @@ -1,7 +1,5 @@ package org.qinan.safetyeval.domain.constant; -import java.math.BigDecimal; - /** * 资质备案合规检查项枚举 * @@ -9,16 +7,17 @@ import java.math.BigDecimal; */ public enum QualFilingComplianceCheckEnum { - MAIN_QUALIFICATION("主体资格", "独立法人资格,固定资产不少于一千万元"), - WORKPLACE("场所与设备", "工作场所建筑面积不少于1000㎡"), - PERSONNEL_COUNT("人员数量与结构", "专职技术人员≥25人,中级注安师≥30%"), - PERSONNEL_EXPERIENCE("人员资历", "专职技术人员在本行业领域工作二年以上"), - KEY_POSITION("关键岗位要求", "负责人具有高级职称,工作八年以上"), - MANAGEMENT_SYSTEM("管理体系", "需核验文件化管理体系是否符合要求"), - COMMITMENT("责任承诺", "法定代表人已出具承诺书"), - INFO_DISCLOSURE("信息公开", "未检测到公示网站"), - CREDIT_RECORD("信用记录", "三年内无重大违法失信记录"), - OTHER("其他", "法律、行政法规规定的其他条件"), + INDEPENDENT_LEGAL("独立法人资格", "具有独立法人资格", "机构备案.法人类型、营业执照附件"), + FIXED_AMOUNT("固定资产", "不少于 800 万元", "财务材料.固定资产净值、审计报告"), + WORKPLACE("工作场所", "建筑面积不少于 1000 平方米,档案室不少于 100 平方米", "场所核验.建筑面积、档案室核验.面积"), + EQUIPMENT_SOFTWARE("设施设备软件", "具有与业务相适应的技术支撑条件", "设备台账.设备清单、软件授权.有效期"), + PERSONNEL_COUNT("专职技术人员数量", "单一业务范围不少于 25 人;每增加一个业务范围至少增加 5 人", "人员库.专职人员、业务范围.数量、社保比对.缴纳单位"), + PERSONNEL_RATIO("人员比例", "注册安全工程师比例不低于 30%,高级职称比例不低于 30%,二者合计不低于 60%", "人员库.注册安全工程师、人员库.职称等级"), + KEY_POSITION("负责人配备", "每个业务范围配备专职技术负责人;另配过程控制负责人", "负责人备案.技术负责人、负责人备案.过程控制负责人"), + MANAGEMENT_SYSTEM("制度与过程控制体系", "具有健全内部管理制度和安全评价过程控制体系", "制度文件.版本、过程控制.节点记录"), + COMMITMENT("承诺书/网站/报告查询", "法定代表人承诺书已出具;网站正常运行并可查询机构信息和报告", "承诺书.上传状态、网站备案.报告查询状态"), + CREDIT_RECORD("三年重大违法失信记录", "截至申请或核查日三年内无重大违法失信记录", "信用核查.重大违法失信记录"), + TERRITORIAL("属地满足情况", "在注册地所在直辖市、设区市行政区域范围内满足资质条件", "异地备案.注册地、本市社保.缴纳人数、场所核验.属地"), ; /** @@ -43,10 +42,12 @@ public enum QualFilingComplianceCheckEnum { private final String title; private final String description; + private final String sourceColumn; - QualFilingComplianceCheckEnum(String title, String description) { + QualFilingComplianceCheckEnum(String title, String description, String sourceColumn) { this.title = title; this.description = description; + this.sourceColumn = sourceColumn; } public String getTitle() { @@ -56,4 +57,8 @@ public enum QualFilingComplianceCheckEnum { public String getDescription() { return description; } + + public String getSourceColumn() { + return sourceColumn; + } } diff --git a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java index 5ed7a38..1fed328 100644 --- a/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java @@ -2,17 +2,12 @@ package org.qinan.safetyeval.infrastructure.utils; import lombok.experimental.UtilityClass; import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO; -import org.qinan.safetyeval.client.dto.AggregationSaveOrEditQualFilingCmd; -import org.qinan.safetyeval.client.dto.QualFilingAddCmd; -import org.qinan.safetyeval.client.dto.QualFilingCommitmentAddCmd; -import org.qinan.safetyeval.client.dto.QualFilingMaterialAddCmd; -import org.qinan.safetyeval.client.dto.QualFilingPersonnelAddCmd; +import org.qinan.safetyeval.client.dto.*; import org.qinan.safetyeval.domain.constant.MaterialTypeEnum; import org.qinan.safetyeval.domain.constant.QualFilingComplianceCheckEnum; import org.qinan.safetyeval.domain.constant.QualFilingMaterialUploadStatusEnum; import java.math.BigDecimal; -import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -32,112 +27,118 @@ public class ComplianceCheckUtil { List results = new ArrayList<>(); - // 1. 主体资格 + // 1. 独立法人资格 results.add(checkMainQualification(filing)); - // 2. 场所与设备 + // 2. 固定资产 + results.add(checkFixedAmount(filing)); + + // 3. 工作场所 results.add(checkWorkplace(filing)); - // 3. 人员数量与结构 + // 4. 设施设备软件(暂无法判断,标记警告) + results.add(buildResult(QualFilingComplianceCheckEnum.EQUIPMENT_SOFTWARE, + QualFilingComplianceCheckEnum.STATUS_WARN, null)); + + // 5. 专职技术人员数量 results.add(checkPersonnelCount(personnelList)); - // 4. 人员资历 - results.add(checkPersonnelExperience(personnelList)); + // 6. 人员比例 + results.add(checkPersonnelRatio(personnelList)); - // 5. 关键岗位要求(暂默认通过,标记警告) + // 7. 负责人配备(暂无法判断,标记警告) results.add(buildResult(QualFilingComplianceCheckEnum.KEY_POSITION, - QualFilingComplianceCheckEnum.STATUS_WARN)); + QualFilingComplianceCheckEnum.STATUS_WARN, null)); - // 6. 管理体系(暂无法判断,标记警告) + // 8. 制度与过程控制体系(暂无法判断,标记警告) results.add(buildResult(QualFilingComplianceCheckEnum.MANAGEMENT_SYSTEM, - QualFilingComplianceCheckEnum.STATUS_WARN)); + QualFilingComplianceCheckEnum.STATUS_WARN, null)); - // 7. 责任承诺 - results.add(checkCommitment(cmd.getQualFilingCommitmentAddCmd())); + // 9. 承诺书/网站/报告查询 + results.add(checkCommitment(cmd.getQualFilingCommitmentAddCmd(), filing)); - // 8. 信息公开 - results.add(checkInfoDisclosure(filing)); - - // 9. 信用记录 + // 10. 三年重大违法失信记录 results.add(checkCreditRecord(materialList)); - // 10. 其他 - results.add(buildResult(QualFilingComplianceCheckEnum.OTHER, - QualFilingComplianceCheckEnum.STATUS_PASS)); + // 11. 属地满足情况(暂无法判断,标记警告) + results.add(buildResult(QualFilingComplianceCheckEnum.TERRITORIAL, + QualFilingComplianceCheckEnum.STATUS_WARN, null)); return results; } /** - * 主体资格:固定资产 >= 1000万元 + * 独立法人资格(暂默认通过,标记警告) */ private QualFilingComplianceCheckResultCO checkMainQualification(QualFilingAddCmd filing) { - boolean pass = filing.getFixedAssetAmount() != null - && filing.getFixedAssetAmount() >= 800L; - return buildResult(QualFilingComplianceCheckEnum.MAIN_QUALIFICATION, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + return buildResult(QualFilingComplianceCheckEnum.INDEPENDENT_LEGAL, + QualFilingComplianceCheckEnum.STATUS_PASS, "独立法人"); } /** - * 场所与设备:工作场所建筑面积 >= 1000㎡ + * 固定资产:>= 800万元 + */ + private QualFilingComplianceCheckResultCO checkFixedAmount(QualFilingAddCmd filing) { + boolean pass = filing.getFixedAssetAmount() != null + && filing.getFixedAssetAmount() >= 800L; + return buildResult(QualFilingComplianceCheckEnum.FIXED_AMOUNT, + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL, null); + } + + /** + * 工作场所:建筑面积 >= 1000㎡ */ private QualFilingComplianceCheckResultCO checkWorkplace(QualFilingAddCmd filing) { boolean pass = filing.getWorkplaceArea() != null && filing.getWorkplaceArea() .compareTo(new BigDecimal(QualFilingComplianceCheckEnum.WORKPLACE_LOWER)) >= 0; return buildResult(QualFilingComplianceCheckEnum.WORKPLACE, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL, null); } /** - * 人员数量与结构:专职技术人员 >= 25人,中级注安师 >= 30% + * 专职技术人员数量:>= 25人 */ private QualFilingComplianceCheckResultCO checkPersonnelCount(List personnelList) { if (personnelList == null || personnelList.isEmpty()) { return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, - QualFilingComplianceCheckEnum.STATUS_FAIL); + QualFilingComplianceCheckEnum.STATUS_FAIL, null); + } + int total = personnelList.size(); + boolean pass = total >= QualFilingComplianceCheckEnum.PERSONNEL_COUNT_LOWER; + return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL, null); + } + + /** + * 人员比例:中级注安师 >= 30% + */ + private QualFilingComplianceCheckResultCO checkPersonnelRatio(List personnelList) { + if (personnelList == null || personnelList.isEmpty()) { + return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_RATIO, + QualFilingComplianceCheckEnum.STATUS_FAIL, null); } int total = personnelList.size(); long engineerCount = personnelList.stream() .filter(p -> p.getRegisterEngineerFlag() != null && p.getRegisterEngineerFlag() == 1) .count(); - boolean pass = total >= QualFilingComplianceCheckEnum.PERSONNEL_COUNT_LOWER - && engineerCount * 100 / total >= QualFilingComplianceCheckEnum.PERSONNEL_RATE; - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + boolean pass = engineerCount * 100 / total >= QualFilingComplianceCheckEnum.PERSONNEL_RATE; + return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_RATIO, + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL + , null); } /** - * 人员资历:所有专职技术人员在本行业领域工作二年以上 + * 承诺书/网站/报告查询:是否存在承诺书数据且信息公开链接已填写 */ - private QualFilingComplianceCheckResultCO checkPersonnelExperience(List personnelList) { - if (personnelList == null || personnelList.isEmpty()) { - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - QualFilingComplianceCheckEnum.STATUS_FAIL); - } - LocalDate threshold = LocalDate.now().minusYears(2); - boolean allQualified = personnelList.stream() - .noneMatch(p -> p.getJoinWorkDate() != null && p.getJoinWorkDate().isAfter(threshold)); - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - allQualified ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 责任承诺:是否存在承诺书数据 - */ - private QualFilingComplianceCheckResultCO checkCommitment(QualFilingCommitmentAddCmd commitment) { - return buildResult(QualFilingComplianceCheckEnum.COMMITMENT, - commitment != null ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 信息公开:info_disclosure_url 是否已填写 - */ - private QualFilingComplianceCheckResultCO checkInfoDisclosure(QualFilingAddCmd filing) { - boolean pass = filing.getInfoDisclosureUrl() != null + private QualFilingComplianceCheckResultCO checkCommitment(QualFilingCommitmentAddCmd commitment, QualFilingAddCmd filing) { + boolean hasCommitment = commitment != null; + boolean hasInfoDisclosure = filing.getInfoDisclosureUrl() != null && !filing.getInfoDisclosureUrl().isEmpty(); - return buildResult(QualFilingComplianceCheckEnum.INFO_DISCLOSURE, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + boolean pass = hasCommitment && hasInfoDisclosure; + return buildResult(QualFilingComplianceCheckEnum.COMMITMENT, + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL + , null); } /** @@ -150,14 +151,26 @@ public class ComplianceCheckUtil { && m.getMaterialType() != null && m.getMaterialType() == MaterialTypeEnum.NO_VIOLATION_RECORD.getCode()); return buildResult(QualFilingComplianceCheckEnum.CREDIT_RECORD, - hasRecord ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + hasRecord ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL + , null); } - private QualFilingComplianceCheckResultCO buildResult(QualFilingComplianceCheckEnum item, String status) { + /** + * buildResult + * + * @param item item + * @param status status + * @param currentValued currentValued + * @return QualFilingComplianceCheckResultCO + */ + private QualFilingComplianceCheckResultCO buildResult(QualFilingComplianceCheckEnum item + , String status, String currentValued) { QualFilingComplianceCheckResultCO co = new QualFilingComplianceCheckResultCO(); co.setTitle(item.getTitle()); co.setDescription(item.getDescription()); co.setStatus(status); + co.setSourceColumn(item.getSourceColumn()); + co.setCurrentValue(currentValued); return co; } }