diff --git a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java index 7317b8a..9768889 100644 --- a/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java +++ b/safety-eval-adapter/src/main/java/org/qinan/safetyeval/adapter/web/QualFilingChangeController.java @@ -6,7 +6,7 @@ import io.swagger.annotations.ApiParam; import org.qinan.safetyeval.client.api.QualFilingChangeApi; import org.qinan.safetyeval.client.co.QualFilingChangeAggregationCO; import org.qinan.safetyeval.client.co.QualFilingChangeCO; -import org.qinan.safetyeval.client.co.QualFilingChangeComplianceCheckResultCO; +import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO; import org.qinan.safetyeval.client.co.QualFilingChangeOrgCO; import org.qinan.safetyeval.client.dto.*; import org.qinan.safetyeval.domain.constant.QualFilingStatusEnum; @@ -70,7 +70,7 @@ public class QualFilingChangeController { @ApiOperation("合规检查") @GetMapping("/compliance-check") - public SingleResponse> complianceCheck(@ApiParam("主键ID") @RequestParam Long id) { + public SingleResponse> complianceCheck(@ApiParam("主键ID") @RequestParam Long id) { return qualFilingChangeApi.complianceCheck(id); } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingChangeCmdConvertor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingChangeCmdConvertor.java index c0a2b66..94a27dd 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingChangeCmdConvertor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingChangeCmdConvertor.java @@ -5,6 +5,7 @@ import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Named; import org.qinan.safetyeval.client.co.QualFilingChangeAggregationCO; +import org.qinan.safetyeval.client.dto.QualFilingAddCmd; import org.qinan.safetyeval.client.dto.QualFilingChangeAddCmd; import org.qinan.safetyeval.domain.entity.QualFilingChangeEntity; import org.qinan.safetyeval.domain.entity.QualFilingEntity; @@ -58,4 +59,21 @@ public interface QualFilingChangeCmdConvertor { default List jsonStringToList(String json) { return json == null || json.isEmpty() ? null : JSON.parseArray(json, String.class); } + + /** + * 变更Cmd转备案Cmd(用于合规性校验) + */ + @Mapping(target = "filingReviewId", ignore = true) + @Mapping(target = "applyTypeCode", ignore = true) + @Mapping(target = "applyTypeName", ignore = true) + QualFilingAddCmd convertChangeCmdToFilingCmd(QualFilingChangeAddCmd qualFilingChangeAddCmd); + + /** + * 变更实体转备案Cmd(用于合规性校验) + */ + @Mapping(target = "businessScope", source = "businessScope", qualifiedByName = "jsonStringToList") + @Mapping(target = "filingReviewId", ignore = true) + @Mapping(target = "applyTypeCode", ignore = true) + @Mapping(target = "applyTypeName", ignore = true) + QualFilingAddCmd convertChangeEToFilingCmd(QualFilingChangeEntity changeEntity); } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingCommitmentChangeCmdConvertor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingCommitmentChangeCmdConvertor.java index 5ea84a2..e9d41da 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingCommitmentChangeCmdConvertor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingCommitmentChangeCmdConvertor.java @@ -5,9 +5,13 @@ import org.mapstruct.Mapping; import org.qinan.safetyeval.client.change.request.QualFilingCommitmentChangeAddCmd; import org.qinan.safetyeval.client.change.request.QualFilingCommitmentChangeUpdateCmd; import org.qinan.safetyeval.client.co.QualFilingCommitmentCO; +import org.qinan.safetyeval.client.dto.QualFilingCommitmentAddCmd; import org.qinan.safetyeval.domain.change.model.QualFilingCommitmentChangeE; import org.qinan.safetyeval.domain.entity.QualFilingCommitmentEntity; +import java.time.LocalDate; +import java.time.LocalDateTime; + /** * 法定代人承诺书-变更转换 * @@ -48,4 +52,18 @@ public interface QualFilingCommitmentChangeCmdConvertor { */ @Mapping(source = "filingChangeId", target = "filingId") QualFilingCommitmentCO convertChangeEToCO(QualFilingCommitmentChangeE changeE); + + /** + * 变更Cmd转备案Cmd(用于合规性校验) + */ + QualFilingCommitmentAddCmd convertChangeCmdToCmd(QualFilingCommitmentChangeAddCmd changeAddCmd); + + /** + * 变更实体转备案Cmd(用于合规性校验) + */ + QualFilingCommitmentAddCmd convertChangeEToCmd(QualFilingCommitmentChangeE changeE); + + default LocalDate map(LocalDateTime dateTime) { + return dateTime == null ? null : dateTime.toLocalDate(); + } } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingMaterialChangeCmdConvertor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingMaterialChangeCmdConvertor.java index 146c1d7..13326c1 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingMaterialChangeCmdConvertor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingMaterialChangeCmdConvertor.java @@ -5,6 +5,7 @@ import org.mapstruct.Mapping; import org.qinan.safetyeval.client.change.request.QualFilingMaterialChangeAddCmd; import org.qinan.safetyeval.client.change.request.QualFilingMaterialChangeUpdateCmd; import org.qinan.safetyeval.client.co.QualFilingMaterialCO; +import org.qinan.safetyeval.client.dto.QualFilingMaterialAddCmd; import org.qinan.safetyeval.domain.change.model.QualFilingMaterialChangeE; import org.qinan.safetyeval.domain.entity.QualFilingMaterialEntity; @@ -59,4 +60,24 @@ public interface QualFilingMaterialChangeCmdConvertor { * 批量转换变更材料为CO */ List convertChangeEListToCOList(List changeEs); + + /** + * 变更Cmd转备案Cmd(用于合规性校验) + */ + QualFilingMaterialAddCmd convertChangeCmdToCmd(QualFilingMaterialChangeAddCmd changeAddCmd); + + /** + * 批量转换变更Cmd为备案Cmd + */ + List convertChangeCmdListToCmdList(List changeAddCmds); + + /** + * 变更实体转备案Cmd(用于合规性校验) + */ + QualFilingMaterialAddCmd convertChangeEToCmd(QualFilingMaterialChangeE changeE); + + /** + * 批量转换变更实体为备案Cmd + */ + List convertChangeEListToCmdList(List changeEs); } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingPersonnelChangeCmdConvertor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingPersonnelChangeCmdConvertor.java index 8ed2f24..dc3cfcc 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingPersonnelChangeCmdConvertor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/change/convertor/QualFilingPersonnelChangeCmdConvertor.java @@ -5,9 +5,12 @@ import org.mapstruct.Mapping; import org.qinan.safetyeval.client.change.request.QualFilingPersonnelChangeAddCmd; import org.qinan.safetyeval.client.change.request.QualFilingPersonnelChangeUpdateCmd; import org.qinan.safetyeval.client.co.QualFilingPersonnelCO; +import org.qinan.safetyeval.client.dto.QualFilingPersonnelAddCmd; import org.qinan.safetyeval.domain.change.model.QualFilingPersonnelChangeE; import org.qinan.safetyeval.domain.entity.QualFilingPersonnelEntity; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; /** @@ -60,4 +63,28 @@ public interface QualFilingPersonnelChangeCmdConvertor { * 批量转换变更人员为CO */ List convertChangeEListToCOList(List changeEs); + + /** + * 变更Cmd转备案Cmd(用于合规性校验) + */ + QualFilingPersonnelAddCmd convertChangeCmdToCmd(QualFilingPersonnelChangeAddCmd changeAddCmd); + + /** + * 批量转换变更Cmd为备案Cmd + */ + List convertChangeCmdListToCmdList(List changeAddCmds); + + /** + * 变更实体转备案Cmd(用于合规性校验) + */ + QualFilingPersonnelAddCmd convertChangeEToCmd(QualFilingPersonnelChangeE changeE); + + /** + * 批量转换变更实体为备案Cmd + */ + List convertChangeEListToCmdList(List changeEs); + + default LocalDate map(LocalDateTime dateTime) { + return dateTime == null ? null : dateTime.toLocalDate(); + } } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/convertor/QualFilingCmdConvertor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/convertor/QualFilingCmdConvertor.java new file mode 100644 index 0000000..176dc34 --- /dev/null +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/convertor/QualFilingCmdConvertor.java @@ -0,0 +1,41 @@ +package org.qinan.safetyeval.app.convertor; + +import com.alibaba.fastjson.JSON; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +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.domain.entity.QualFilingCommitmentEntity; +import org.qinan.safetyeval.domain.entity.QualFilingEntity; +import org.qinan.safetyeval.domain.entity.QualFilingMaterialEntity; +import org.qinan.safetyeval.domain.entity.QualFilingPersonnelEntity; + +import java.util.List; + +/** + * 备案实体转Cmd转换(用于合规性校验) + */ +@Mapper(componentModel = "spring") +public interface QualFilingCmdConvertor { + + @Mapping(target = "businessScope", source = "businessScope", qualifiedByName = "jsonStringToList") + QualFilingAddCmd convertEntityToCmd(QualFilingEntity entity); + + QualFilingCommitmentAddCmd convertEntityToCmd(QualFilingCommitmentEntity entity); + + QualFilingPersonnelAddCmd convertEntityToCmd(QualFilingPersonnelEntity entity); + + List convertEntityListPersonToCmdList(List entities); + + QualFilingMaterialAddCmd convertEntityToCmd(QualFilingMaterialEntity entity); + + List convertEntityListToCmdList(List entities); + + @Named("jsonStringToList") + default List jsonStringToList(String json) { + return json == null || json.isEmpty() ? null : JSON.parseArray(json, String.class); + } +} diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java index 24d4a79..93f4ba6 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/executor/QualFilingChangeExecutor.java @@ -27,6 +27,7 @@ import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter; import org.qinan.safetyeval.infrastructure.dataobject.QualFilingChangeCountDO; import org.qinan.safetyeval.infrastructure.mapper.QualFilingChangeMapper; +import org.qinan.safetyeval.infrastructure.utils.ComplianceCheckUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Lazy; @@ -247,7 +248,7 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { } @Override - public SingleResponse> complianceCheck(Long id) { + public SingleResponse> complianceCheck(Long id) { return SingleResponse.success(qualFilingOrchestrator.complianceCheckChange(id)); } @@ -256,6 +257,20 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { public SingleResponse aggregationSaveOrEdit(AggregationSaveOrEditQualFilingChangeCmd cmd) { validateBeforeSaveOrEdit(cmd); + // 合规性校验:只要有一项未通过则抛出异常 + if (reviewEnable) { + AggregationSaveOrEditQualFilingCmd qualFilingCmd = convertToQualFilingCmd(cmd); + List complianceResults = ComplianceCheckUtil.complianceCheck(qualFilingCmd); + List failedItems = complianceResults.stream() + .filter(r -> QualFilingComplianceCheckEnum.STATUS_FAIL.equals(r.getStatus())) + .map(QualFilingComplianceCheckResultCO::getTitle) + .collect(Collectors.toList()); + if (!failedItems.isEmpty()) { + throw new BizException(ErrorCode.QUAL_FILING_COMPLIANCE_CHECK_FAIL, + "合规性校验未通过:" + String.join("、", failedItems)); + } + } + // 变更基本信息 QualFilingChangeEntity entity = qualFilingChangeCmdConvertor.convertCmdToE(cmd.getQualFilingChangeAddCmd()); entity.setOrgId(ThreadLocalUserInfoAdapter.getOrgId() == null ? entity.getOrgId() : ThreadLocalUserInfoAdapter.getOrgId()); @@ -309,19 +324,6 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { Long id = qualFilingChangeDomainService.aggregationSaveOrEdit(entity, commitmentEntity , equipmentEntities, materialEntities, personnelEntities, personnelCertEntities); - // 合规性校验:只要有一项未通过则抛出异常 - if (reviewEnable) { - List complianceResults = qualFilingOrchestrator.complianceCheckChange(id); - List failedItems = complianceResults.stream() - .filter(r -> QualFilingComplianceCheckEnum.STATUS_FAIL.equals(r.getStatus())) - .map(QualFilingChangeComplianceCheckResultCO::getTitle) - .collect(Collectors.toList()); - if (!failedItems.isEmpty()) { - throw new BizException(ErrorCode.QUAL_FILING_COMPLIANCE_CHECK_FAIL, - "合规性校验未通过:" + String.join("、", failedItems)); - } - } - QualFilingChangeCO co = new QualFilingChangeCO(); co.setId(id); return SingleResponse.success(co); @@ -378,22 +380,22 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { // 查询并转换装备清单 List equipmentChangeEs = qualFilingEquipmentChangeGateway.listByFilingId(changeFilingId); List equipmentEntities = qualFilingEquipmentChangeCmdConvertor.convertChangeEListToEntityList(equipmentChangeEs); - equipmentEntities.forEach(e -> e.setFilingId(changeEntity.getChangeFilingId())); + equipmentEntities.forEach(e -> e.setFilingId(changeEntity.getFilingId())); // 查询并转换材料清单 List materialChangeEs = qualFilingMaterialChangeGateway.listByFilingId(changeFilingId); List materialEntities = qualFilingMaterialChangeCmdConvertor.convertChangeEListToEntityList(materialChangeEs); - materialEntities.forEach(e -> e.setFilingId(changeEntity.getChangeFilingId())); + materialEntities.forEach(e -> e.setFilingId(changeEntity.getFilingId())); // 查询并转换人员 List personnelChangeEs = qualFilingPersonnelChangeGateway.listByFilingId(changeFilingId); List personnelEntities = qualFilingPersonnelChangeCmdConvertor.convertChangeEListToEntityList(personnelChangeEs); - personnelEntities.forEach(e -> e.setFilingId(changeEntity.getChangeFilingId())); + personnelEntities.forEach(e -> e.setFilingId(changeEntity.getFilingId())); // 查询并转换人员证书 List personnelCertChangeEs = qualFilingPersonnelCertChangeGateway.listByFilingId(changeFilingId); List personnelCertEntities = qualFilingPersonnelCertChangeCmdConvertor.convertChangeEListToEntityList(personnelCertChangeEs); - personnelCertEntities.forEach(e -> e.setFilingId(changeEntity.getChangeFilingId())); + personnelCertEntities.forEach(e -> e.setFilingId(changeEntity.getFilingId())); // 调用聚合保存,将变更数据写入正式备案表 qualFilingDomainService.aggregationSaveOrEdit(entity, commitmentEntity, equipmentEntities, materialEntities, personnelEntities, personnelCertEntities); @@ -451,6 +453,36 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi { return SingleResponse.success(detail); } + /** + * 将变更聚合Cmd转换为备案聚合Cmd,用于合规性校验 + */ + private AggregationSaveOrEditQualFilingCmd convertToQualFilingCmd(AggregationSaveOrEditQualFilingChangeCmd changeCmd) { + AggregationSaveOrEditQualFilingCmd cmd = new AggregationSaveOrEditQualFilingCmd(); + + // 基本信息 + cmd.setQualFilingAddCmd(qualFilingChangeCmdConvertor.convertChangeCmdToFilingCmd(changeCmd.getQualFilingChangeAddCmd())); + + // 承诺书 + if (changeCmd.getQualFilingCommitmentChangeAddCmd() != null) { + cmd.setQualFilingCommitmentAddCmd( + qualFilingCommitmentChangeCmdConvertor.convertChangeCmdToCmd(changeCmd.getQualFilingCommitmentChangeAddCmd())); + } + + // 人员 + if (!CollectionUtils.isEmpty(changeCmd.getQualFilingPersonnelChangeAddCmds())) { + cmd.setQualFilingPersonnelAddCmds( + qualFilingPersonnelChangeCmdConvertor.convertChangeCmdListToCmdList(changeCmd.getQualFilingPersonnelChangeAddCmds())); + } + + // 材料清单 + if (!CollectionUtils.isEmpty(changeCmd.getQualFilingMaterialChangeAddCmds())) { + cmd.setQualFilingMaterialAddCmds( + qualFilingMaterialChangeCmdConvertor.convertChangeCmdListToCmdList(changeCmd.getQualFilingMaterialChangeAddCmds())); + } + + return cmd; + } + /** * 聚合保存或编辑前的状态校验 *
    diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/orchestrator/QualFilingOrchestrator.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/orchestrator/QualFilingOrchestrator.java index c508889..f13c604 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/orchestrator/QualFilingOrchestrator.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/orchestrator/QualFilingOrchestrator.java @@ -4,9 +4,19 @@ import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.alibaba.fastjson.JSON; import org.qinan.safetyeval.app.support.*; +import org.qinan.safetyeval.app.change.convertor.QualFilingChangeCmdConvertor; +import org.qinan.safetyeval.app.change.convertor.QualFilingCommitmentChangeCmdConvertor; +import org.qinan.safetyeval.app.change.convertor.QualFilingMaterialChangeCmdConvertor; +import org.qinan.safetyeval.app.change.convertor.QualFilingPersonnelChangeCmdConvertor; +import org.qinan.safetyeval.app.convertor.QualFilingCmdConvertor; import org.qinan.safetyeval.client.co.*; +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.QualFilingModifyCmd; import org.qinan.safetyeval.client.dto.QualFilingPageQuery; +import org.qinan.safetyeval.client.dto.QualFilingPersonnelAddCmd; import org.qinan.safetyeval.client.dto.QualificationMonitoringQuery; import org.qinan.safetyeval.domain.change.gateway.QualFilingCommitmentChangeGateway; import org.qinan.safetyeval.domain.change.gateway.QualFilingMaterialChangeGateway; @@ -23,6 +33,7 @@ import org.qinan.safetyeval.domain.support.QualFilingExpertCheckSupport; import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter; import org.qinan.safetyeval.infrastructure.mapper.QualFilingMapper; import org.qinan.safetyeval.infrastructure.support.OrgContextResolver; +import org.qinan.safetyeval.infrastructure.utils.ComplianceCheckUtil; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -112,6 +123,17 @@ public class QualFilingOrchestrator { @Value("${safety-eval.public-api.tenant-id:0}") private Long fallbackTenantId; + @Resource + private QualFilingChangeCmdConvertor qualFilingChangeCmdConvertor; + @Resource + private QualFilingCommitmentChangeCmdConvertor qualFilingCommitmentChangeCmdConvertor; + @Resource + private QualFilingPersonnelChangeCmdConvertor qualFilingPersonnelChangeCmdConvertor; + @Resource + private QualFilingMaterialChangeCmdConvertor qualFilingMaterialChangeCmdConvertor; + @Resource + private QualFilingCmdConvertor qualFilingCmdConvertor; + @Transactional public QualFilingCO createDraft(Integer applyTypeCode) { QualFilingApplyTypeEnum applyType = QualFilingApplyTypeEnum.ofCode(applyTypeCode); @@ -821,274 +843,61 @@ public class QualFilingOrchestrator { throw new BizException(ErrorCode.QUAL_FILING_NOT_FOUND); } - List results = new ArrayList<>(); + AggregationSaveOrEditQualFilingCmd cmd = new AggregationSaveOrEditQualFilingCmd(); - // 1. 主体资格 - results.add(checkMainQualification(filing)); + // 基本信息 + cmd.setQualFilingAddCmd(qualFilingCmdConvertor.convertEntityToCmd(filing)); - // 2. 场所与设备 - results.add(checkWorkplace(filing)); - - // 3. 人员数量与结构 - results.add(checkPersonnelCount(id)); - - // 4. 人员资历 - results.add(checkPersonnelExperience(id)); - - // 5. 关键岗位要求(暂默认通过,标记警告) - results.add(buildResult(QualFilingComplianceCheckEnum.KEY_POSITION, - QualFilingComplianceCheckEnum.STATUS_WARN)); - - // 6. 管理体系(暂无法判断,标记警告) - results.add(buildResult(QualFilingComplianceCheckEnum.MANAGEMENT_SYSTEM, - QualFilingComplianceCheckEnum.STATUS_WARN)); - - // 7. 责任承诺 - results.add(checkCommitment(id)); - - // 8. 信息公开 - results.add(checkInfoDisclosure(filing)); - - // 9. 信用记录 - results.add(checkCreditRecord(id)); - - // 10. 其他 - results.add(buildResult(QualFilingComplianceCheckEnum.OTHER, - QualFilingComplianceCheckEnum.STATUS_PASS)); - - return results; - } - - /** - * 主体资格:固定资产 >= 1000万元 - */ - private QualFilingComplianceCheckResultCO checkMainQualification(QualFilingEntity filing) { - // 1000万元 = 10,000,000元 = 1,000,000,000分 - boolean pass = filing.getFixedAssetAmount() != null - && filing.getFixedAssetAmount() >= 800L; - return buildResult(QualFilingComplianceCheckEnum.MAIN_QUALIFICATION, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 场所与设备:工作场所建筑面积 >= 1000㎡ - */ - private QualFilingComplianceCheckResultCO checkWorkplace(QualFilingEntity 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); - } - - /** - * 人员数量与结构:专职技术人员 >= 25人,中级注安师 >= 30% - */ - private QualFilingComplianceCheckResultCO checkPersonnelCount(Long filingId) { - int total = qualFilingPersonnelGateway.countByFilingId(filingId); - if (total == 0) { - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, - QualFilingComplianceCheckEnum.STATUS_FAIL); + // 备案承诺书 + QualFilingCommitmentEntity commitment = qualFilingCommitmentGateway.getByFilingId(id); + if (commitment != null) { + cmd.setQualFilingCommitmentAddCmd(qualFilingCmdConvertor.convertEntityToCmd(commitment)); } - int engineerCount = qualFilingPersonnelGateway.countByFilingIdAndRegisterEngineerFlag(filingId, 1); - 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); - } - /** - * 人员资历:所有专职技术人员在本行业领域工作二年以上 - */ - private QualFilingComplianceCheckResultCO checkPersonnelExperience(Long filingId) { - int total = qualFilingPersonnelGateway.countByFilingId(filingId); - if (total == 0) { - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - QualFilingComplianceCheckEnum.STATUS_FAIL); - } - LocalDate threshold = LocalDate.now().minusYears(2); - boolean allQualified = qualFilingPersonnelGateway.countByFilingIdAndJoinWorkDateAfter(filingId, threshold) == 0; - return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - allQualified ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } + // 备案人员 + cmd.setQualFilingPersonnelAddCmds( + qualFilingCmdConvertor.convertEntityListPersonToCmdList(qualFilingPersonnelGateway.listByFilingId(id))); - /** - * 责任承诺:qual_filing_commitment 表是否有数据 - */ - private QualFilingComplianceCheckResultCO checkCommitment(Long filingId) { - QualFilingCommitmentEntity commitment = - qualFilingCommitmentGateway.getByFilingId(filingId); - return buildResult(QualFilingComplianceCheckEnum.COMMITMENT, - commitment != null ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } + // 备案材料清单 + cmd.setQualFilingMaterialAddCmds( + qualFilingCmdConvertor.convertEntityListToCmdList(qualFilingMaterialGateway.listByFilingId(id))); - /** - * 信息公开:info_disclosure_url 是否已填写 - */ - private QualFilingComplianceCheckResultCO checkInfoDisclosure(QualFilingEntity filing) { - boolean pass = filing.getInfoDisclosureUrl() != null - && !filing.getInfoDisclosureUrl().isEmpty(); - return buildResult(QualFilingComplianceCheckEnum.INFO_DISCLOSURE, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 信用记录:qual_filing_material 表 upload_status_code=2 且 material_type=4 - */ - private QualFilingComplianceCheckResultCO checkCreditRecord(Long filingId) { - int count = qualFilingMaterialGateway.countByFilingIdAndUploadStatusCodeAndMaterialType( - filingId, - QualFilingMaterialUploadStatusEnum.UPLOADED.getCode(), - MaterialTypeEnum.NO_VIOLATION_RECORD.getCode()); - return buildResult(QualFilingComplianceCheckEnum.CREDIT_RECORD, - count > 0 ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - private QualFilingComplianceCheckResultCO buildResult(QualFilingComplianceCheckEnum item, String status) { - QualFilingComplianceCheckResultCO co = new QualFilingComplianceCheckResultCO(); - co.setTitle(item.getTitle()); - co.setDescription(item.getDescription()); - co.setStatus(status); - return co; + return ComplianceCheckUtil.complianceCheck(cmd); } /** * 备案变更合规检查:根据变更ID逐项检查是否满足法规要求 */ - public List complianceCheckChange(Long changeId) { + public List complianceCheckChange(Long changeId) { QualFilingChangeEntity change = qualFilingChangeGateway.get(changeId); if (change == null) { throw new BizException(ErrorCode.QUAL_FILING_NOT_FOUND); } - List results = new ArrayList<>(); + // 查询变更数据,转换为备案聚合Cmd后复用ComplianceCheckUtil + AggregationSaveOrEditQualFilingCmd qualFilingCmd = new AggregationSaveOrEditQualFilingCmd(); - // 1. 主体资格 - results.add(checkMainQualificationChange(change)); + // 基本信息 + qualFilingCmd.setQualFilingAddCmd(qualFilingChangeCmdConvertor.convertChangeEToFilingCmd(change)); - // 2. 场所与设备 - results.add(checkWorkplaceChange(change)); - - // 3. 人员数量与结构 - results.add(checkPersonnelCountChange(changeId)); - - // 4. 人员资历 - results.add(checkPersonnelExperienceChange(changeId)); - - // 5. 关键岗位要求(暂默认通过,标记警告) - results.add(buildChangeResult(QualFilingComplianceCheckEnum.KEY_POSITION, - QualFilingComplianceCheckEnum.STATUS_WARN)); - - // 6. 管理体系(暂无法判断,标记警告) - results.add(buildChangeResult(QualFilingComplianceCheckEnum.MANAGEMENT_SYSTEM, - QualFilingComplianceCheckEnum.STATUS_WARN)); - - // 7. 责任承诺 - results.add(checkCommitmentChange(changeId)); - - // 8. 信息公开 - results.add(checkInfoDisclosureChange(change)); - - // 9. 信用记录 - results.add(checkCreditRecordChange(changeId)); - - // 10. 其他 - results.add(buildChangeResult(QualFilingComplianceCheckEnum.OTHER, - QualFilingComplianceCheckEnum.STATUS_PASS)); - - return results; - } - - /** - * 主体资格:固定资产 >= 1000万元 - */ - private QualFilingChangeComplianceCheckResultCO checkMainQualificationChange(QualFilingChangeEntity change) { - boolean pass = change.getFixedAssetAmount() != null - && change.getFixedAssetAmount() >= 800L; - return buildChangeResult(QualFilingComplianceCheckEnum.MAIN_QUALIFICATION, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 场所与设备:工作场所建筑面积 >= 1000㎡ - */ - private QualFilingChangeComplianceCheckResultCO checkWorkplaceChange(QualFilingChangeEntity change) { - boolean pass = change.getWorkplaceArea() != null - && change.getWorkplaceArea() - .compareTo(new BigDecimal(QualFilingComplianceCheckEnum.WORKPLACE_LOWER)) >= 0; - return buildChangeResult(QualFilingComplianceCheckEnum.WORKPLACE, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 人员数量与结构:专职技术人员 >= 25人,中级注安师 >= 30% - */ - private QualFilingChangeComplianceCheckResultCO checkPersonnelCountChange(Long filingId) { - int total = qualFilingPersonnelChangeGateway.countByFilingId(filingId); - if (total == 0) { - return buildChangeResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, - QualFilingComplianceCheckEnum.STATUS_FAIL); + // 承诺书 + QualFilingCommitmentChangeE commitmentChange = qualFilingCommitmentChangeGateway.getByFilingId(changeId); + if (commitmentChange != null) { + qualFilingCmd.setQualFilingCommitmentAddCmd( + qualFilingCommitmentChangeCmdConvertor.convertChangeEToCmd(commitmentChange)); } - int engineerCount = qualFilingPersonnelChangeGateway.countByFilingIdAndRegisterEngineerFlag(filingId, 1); - boolean pass = total >= QualFilingComplianceCheckEnum.PERSONNEL_COUNT_LOWER - && engineerCount * 100 / total >= QualFilingComplianceCheckEnum.PERSONNEL_RATE; - return buildChangeResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - /** - * 人员资历:所有专职技术人员在本行业领域工作二年以上 - */ - private QualFilingChangeComplianceCheckResultCO checkPersonnelExperienceChange(Long filingId) { - int total = qualFilingPersonnelChangeGateway.countByFilingId(filingId); - if (total == 0) { - return buildChangeResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - QualFilingComplianceCheckEnum.STATUS_FAIL); - } - LocalDate threshold = LocalDate.now().minusYears(2); - boolean allQualified = qualFilingPersonnelChangeGateway.countByFilingIdAndJoinWorkDateAfter(filingId, threshold) == 0; - return buildChangeResult(QualFilingComplianceCheckEnum.PERSONNEL_EXPERIENCE, - allQualified ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } + // 人员 + qualFilingCmd.setQualFilingPersonnelAddCmds( + qualFilingPersonnelChangeCmdConvertor.convertChangeEListToCmdList( + qualFilingPersonnelChangeGateway.listByFilingId(changeId))); - /** - * 责任承诺:qual_filing_commitment_change 表是否有数据 - */ - private QualFilingChangeComplianceCheckResultCO checkCommitmentChange(Long filingId) { - QualFilingCommitmentChangeE commitment = - qualFilingCommitmentChangeGateway.getByFilingId(filingId); - return buildChangeResult(QualFilingComplianceCheckEnum.COMMITMENT, - commitment != null ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } + // 材料清单 + qualFilingCmd.setQualFilingMaterialAddCmds( + qualFilingMaterialChangeCmdConvertor.convertChangeEListToCmdList( + qualFilingMaterialChangeGateway.listByFilingId(changeId))); - /** - * 信息公开:info_disclosure_url 是否已填写 - */ - private QualFilingChangeComplianceCheckResultCO checkInfoDisclosureChange(QualFilingChangeEntity change) { - boolean pass = change.getInfoDisclosureUrl() != null - && !change.getInfoDisclosureUrl().isEmpty(); - return buildChangeResult(QualFilingComplianceCheckEnum.INFO_DISCLOSURE, - pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - /** - * 信用记录:qual_filing_material_change 表 upload_status_code=2 且 material_type=4 - */ - private QualFilingChangeComplianceCheckResultCO checkCreditRecordChange(Long filingId) { - int count = qualFilingMaterialChangeGateway.countByFilingIdAndUploadStatusCodeAndMaterialType( - filingId, - QualFilingMaterialUploadStatusEnum.UPLOADED.getCode(), - String.valueOf(MaterialTypeEnum.NO_VIOLATION_RECORD.getCode())); - return buildChangeResult(QualFilingComplianceCheckEnum.CREDIT_RECORD, - count > 0 ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); - } - - private QualFilingChangeComplianceCheckResultCO buildChangeResult(QualFilingComplianceCheckEnum item, String status) { - QualFilingChangeComplianceCheckResultCO co = new QualFilingChangeComplianceCheckResultCO(); - co.setTitle(item.getTitle()); - co.setDescription(item.getDescription()); - co.setStatus(status); - return co; + return ComplianceCheckUtil.complianceCheck(qualFilingCmd); } private Long resolveOrgId() { diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/QualFilingChangeApi.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/QualFilingChangeApi.java index 38179cb..65965ba 100644 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/QualFilingChangeApi.java +++ b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/api/QualFilingChangeApi.java @@ -1,7 +1,7 @@ package org.qinan.safetyeval.client.api; import org.qinan.safetyeval.client.co.QualFilingChangeAggregationCO; -import org.qinan.safetyeval.client.co.QualFilingChangeComplianceCheckResultCO; +import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO; import org.qinan.safetyeval.client.co.QualFilingChangeHistoryCO; import org.qinan.safetyeval.client.co.QualFilingChangeCO; import org.qinan.safetyeval.client.co.QualFilingChangeOrgCO; @@ -44,7 +44,7 @@ public interface QualFilingChangeApi { SingleResponse reject(QualFilingRejectCmd cmd); - SingleResponse> complianceCheck(Long id); + SingleResponse> complianceCheck(Long id); SingleResponse aggregationSaveOrEdit(AggregationSaveOrEditQualFilingChangeCmd cmd); diff --git a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeComplianceCheckResultCO.java b/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeComplianceCheckResultCO.java deleted file mode 100644 index 08af30d..0000000 --- a/safety-eval-client/src/main/java/org/qinan/safetyeval/client/co/QualFilingChangeComplianceCheckResultCO.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.qinan.safetyeval.client.co; - -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -/** - * 备案变更合规检查结果CO - * - * @author safety-eval - */ -@Data -public class QualFilingChangeComplianceCheckResultCO { - - @ApiModelProperty(value = "检查项标题") - private String title; - - @ApiModelProperty(value = "检查项描述") - private String description; - - @ApiModelProperty(value = "检查结果状态:PASS 通过 / NOT_PASS 未通过 / WARN 警告") - private String status; -} 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 new file mode 100644 index 0000000..5ed7a38 --- /dev/null +++ b/safety-eval-infrastructure/src/main/java/org/qinan/safetyeval/infrastructure/utils/ComplianceCheckUtil.java @@ -0,0 +1,163 @@ +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.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; + +/** + * 资质备案合规检查工具类 + */ +@UtilityClass +public class ComplianceCheckUtil { + + /** + * 合规检查:根据聚合命令对象逐项检查是否满足法规要求 + */ + public List complianceCheck(AggregationSaveOrEditQualFilingCmd cmd) { + QualFilingAddCmd filing = cmd.getQualFilingAddCmd(); + List personnelList = cmd.getQualFilingPersonnelAddCmds(); + List materialList = cmd.getQualFilingMaterialAddCmds(); + + List results = new ArrayList<>(); + + // 1. 主体资格 + results.add(checkMainQualification(filing)); + + // 2. 场所与设备 + results.add(checkWorkplace(filing)); + + // 3. 人员数量与结构 + results.add(checkPersonnelCount(personnelList)); + + // 4. 人员资历 + results.add(checkPersonnelExperience(personnelList)); + + // 5. 关键岗位要求(暂默认通过,标记警告) + results.add(buildResult(QualFilingComplianceCheckEnum.KEY_POSITION, + QualFilingComplianceCheckEnum.STATUS_WARN)); + + // 6. 管理体系(暂无法判断,标记警告) + results.add(buildResult(QualFilingComplianceCheckEnum.MANAGEMENT_SYSTEM, + QualFilingComplianceCheckEnum.STATUS_WARN)); + + // 7. 责任承诺 + results.add(checkCommitment(cmd.getQualFilingCommitmentAddCmd())); + + // 8. 信息公开 + results.add(checkInfoDisclosure(filing)); + + // 9. 信用记录 + results.add(checkCreditRecord(materialList)); + + // 10. 其他 + results.add(buildResult(QualFilingComplianceCheckEnum.OTHER, + QualFilingComplianceCheckEnum.STATUS_PASS)); + + 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); + } + + /** + * 场所与设备:工作场所建筑面积 >= 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); + } + + /** + * 人员数量与结构:专职技术人员 >= 25人,中级注安师 >= 30% + */ + private QualFilingComplianceCheckResultCO checkPersonnelCount(List personnelList) { + if (personnelList == null || personnelList.isEmpty()) { + return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_COUNT, + QualFilingComplianceCheckEnum.STATUS_FAIL); + } + 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); + } + + /** + * 人员资历:所有专职技术人员在本行业领域工作二年以上 + */ + 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 + && !filing.getInfoDisclosureUrl().isEmpty(); + return buildResult(QualFilingComplianceCheckEnum.INFO_DISCLOSURE, + pass ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + } + + /** + * 信用记录:upload_status_code=2 且 material_type=4 的材料是否存在 + */ + private QualFilingComplianceCheckResultCO checkCreditRecord(List materialList) { + boolean hasRecord = materialList != null && materialList.stream().anyMatch(m -> + m.getUploadStatusCode() != null + && m.getUploadStatusCode() == QualFilingMaterialUploadStatusEnum.UPLOADED.getCode() + && m.getMaterialType() != null + && m.getMaterialType() == MaterialTypeEnum.NO_VIOLATION_RECORD.getCode()); + return buildResult(QualFilingComplianceCheckEnum.CREDIT_RECORD, + hasRecord ? QualFilingComplianceCheckEnum.STATUS_PASS : QualFilingComplianceCheckEnum.STATUS_FAIL); + } + + private QualFilingComplianceCheckResultCO buildResult(QualFilingComplianceCheckEnum item, String status) { + QualFilingComplianceCheckResultCO co = new QualFilingComplianceCheckResultCO(); + co.setTitle(item.getTitle()); + co.setDescription(item.getDescription()); + co.setStatus(status); + return co; + } +}