dev_1.0.1
luotaiqian 2026-07-16 14:14:25 +08:00
parent 6ce1c1e50a
commit b313663589
6 changed files with 114 additions and 13 deletions

View File

@ -255,7 +255,6 @@ public class QualFilingChangeExecutor implements QualFilingChangeApi {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public SingleResponse<QualFilingChangeCO> aggregationSaveOrEdit(AggregationSaveOrEditQualFilingChangeCmd cmd) { public SingleResponse<QualFilingChangeCO> aggregationSaveOrEdit(AggregationSaveOrEditQualFilingChangeCmd cmd) {
validateBeforeSaveOrEdit(cmd); validateBeforeSaveOrEdit(cmd);
// 合规性校验:只要有一项未通过则抛出异常 // 合规性校验:只要有一项未通过则抛出异常
if (reviewEnable) { if (reviewEnable) {
AggregationSaveOrEditQualFilingCmd qualFilingCmd = convertToQualFilingCmd(cmd); AggregationSaveOrEditQualFilingCmd qualFilingCmd = convertToQualFilingCmd(cmd);

View File

@ -20,4 +20,9 @@ public class IndustryProfessionalPersonCo {
* *
*/ */
private Long personNum; private Long personNum;
/**
* id
*/
private Long sourcePersonnelId;
} }

View File

@ -0,0 +1,32 @@
package org.qinan.safetyeval.client.co;
import lombok.Data;
/**
*
*
* @author safety-eval
*/
@Data
public class OrgPersonnelCertCapabilityComplianceCheckCO {
/**
* id
*/
private Long personnelId;
/**
*
*/
private String businessScope;
/**
*
*/
private String professionalCapabilityCode;
/**
* ID
*/
private Long professionalCapabilityId;
}

View File

@ -2,8 +2,19 @@ package org.qinan.safetyeval.infrastructure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.qinan.safetyeval.infrastructure.dataobject.OrgPersonnelCertDO; import org.qinan.safetyeval.infrastructure.dataobject.OrgPersonnelCertDO;
import java.util.List;
@Mapper @Mapper
public interface OrgPersonnelCertMapper extends BaseMapper<OrgPersonnelCertDO> { public interface OrgPersonnelCertMapper extends BaseMapper<OrgPersonnelCertDO> {
/**
* id
*
* @param personnelIds id
* @return
*/
List<org.qinan.safetyeval.client.co.OrgPersonnelCertCapabilityComplianceCheckCO> selectCapabilityByPersonnelIds(@Param("personnelIds") List<Long> personnelIds);
} }

View File

@ -6,11 +6,13 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.qinan.safetyeval.client.co.IndustryProfessionalPersonCo; import org.qinan.safetyeval.client.co.IndustryProfessionalPersonCo;
import org.qinan.safetyeval.client.co.OrgPersonnelCertCapabilityComplianceCheckCO;
import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO; import org.qinan.safetyeval.client.co.QualFilingComplianceCheckResultCO;
import org.qinan.safetyeval.client.dto.*; import org.qinan.safetyeval.client.dto.*;
import org.qinan.safetyeval.domain.constant.*; import org.qinan.safetyeval.domain.constant.*;
import org.qinan.safetyeval.domain.exception.BizException; import org.qinan.safetyeval.domain.exception.BizException;
import org.qinan.safetyeval.infrastructure.convertor.QualFilingPersonnelCoConvertor; import org.qinan.safetyeval.infrastructure.convertor.QualFilingPersonnelCoConvertor;
import org.qinan.safetyeval.infrastructure.mapper.OrgPersonnelCertMapper;
import org.qinan.safetyeval.infrastructure.mapper.OrgPersonnelMapper; import org.qinan.safetyeval.infrastructure.mapper.OrgPersonnelMapper;
import org.qinan.safetyeval.infrastructure.persistence.domainobject.IndustryProfessionalStandardsDO; import org.qinan.safetyeval.infrastructure.persistence.domainobject.IndustryProfessionalStandardsDO;
import org.qinan.safetyeval.infrastructure.persistence.domainobject.OrgPersonnelLeaderCountDO; import org.qinan.safetyeval.infrastructure.persistence.domainobject.OrgPersonnelLeaderCountDO;
@ -40,6 +42,10 @@ public class ComplianceCheckUtil {
List<QualFilingComplianceCheckResultCO> results = new ArrayList<>(); List<QualFilingComplianceCheckResultCO> results = new ArrayList<>();
// 0. 查询人员证书专业能力信息
List<OrgPersonnelCertCapabilityComplianceCheckCO>
certCapabilityList = queryOrgPersonnelCertCapability(personnelList);
// 1. 独立法人资格 // 1. 独立法人资格
results.add(checkMainQualification(filing)); results.add(checkMainQualification(filing));
@ -57,7 +63,7 @@ public class ComplianceCheckUtil {
results.add(checkPersonnelCount(filing, personnelList)); results.add(checkPersonnelCount(filing, personnelList));
// 6. 人员比例 // 6. 人员比例
results.add(checkPersonnelRatio(filing.getBusinessScope(), personnelList)); results.add(checkPersonnelRatio(filing.getBusinessScope(), personnelList, certCapabilityList));
// 7. 负责人配备 // 7. 负责人配备
results.add(checkKeyPosition(filing, personnelList)); results.add(checkKeyPosition(filing, personnelList));
@ -79,6 +85,31 @@ public class ComplianceCheckUtil {
return results; return results;
} }
/**
*
* <p>
* sourcePersonnelId org_personnel_cert.personnel_id
* org_personnel_cert business_scopeprofessional_capability_codeprofessional_capability_id
*
* @param personnelList
* @return
*/
private List<OrgPersonnelCertCapabilityComplianceCheckCO> queryOrgPersonnelCertCapability(List<QualFilingPersonnelAddCmd> personnelList) {
if (CollectionUtils.isEmpty(personnelList)) {
return Collections.emptyList();
}
List<Long> sourcePersonnelIds = personnelList.stream()
.map(QualFilingPersonnelAddCmd::getSourcePersonnelId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
if (sourcePersonnelIds.isEmpty()) {
return Collections.emptyList();
}
OrgPersonnelCertMapper mapper = SpringUtil.getBean(OrgPersonnelCertMapper.class);
return mapper.selectCapabilityByPersonnelIds(sourcePersonnelIds);
}
/** /**
* *
*/ */
@ -132,7 +163,7 @@ public class ComplianceCheckUtil {
* >= 30% >= 30% >= 60% * >= 30% >= 30% >= 60%
*/ */
private QualFilingComplianceCheckResultCO checkPersonnelRatio(List<String> businessScope private QualFilingComplianceCheckResultCO checkPersonnelRatio(List<String> businessScope
, List<QualFilingPersonnelAddCmd> personnelList) { , List<QualFilingPersonnelAddCmd> personnelList, List<OrgPersonnelCertCapabilityComplianceCheckCO> personnelCertCoList) {
if (personnelList == null || personnelList.isEmpty()) { if (personnelList == null || personnelList.isEmpty()) {
return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_RATIO, return buildResult(QualFilingComplianceCheckEnum.PERSONNEL_RATIO,
QualFilingComplianceCheckEnum.STATUS_FAIL, "无人员数据"); QualFilingComplianceCheckEnum.STATUS_FAIL, "无人员数据");
@ -153,9 +184,10 @@ public class ComplianceCheckUtil {
String currentValue = "注册安全工程师 " + engineerRate + "%,高级职称 " + seniorTitleRate + "%,合计 " + sumRate + "%"; String currentValue = "注册安全工程师 " + engineerRate + "%,高级职称 " + seniorTitleRate + "%,合计 " + sumRate + "%";
List<IndustryProfessionalPersonCo> industryProfessionalPersonCos = SpringUtil.getBean(QualFilingPersonnelCoConvertor.class) List<IndustryProfessionalPersonCo> personnelCoList = SpringUtil.getBean(QualFilingPersonnelCoConvertor.class)
.convertCmdsToCos(personnelList); .convertCmdsToCos(personnelList);
Pair<Boolean, String> booleanStringPair = industryProfessionalStandardsValid(businessScope, industryProfessionalPersonCos); Pair<Boolean, String> booleanStringPair = industryProfessionalStandardsValid(
businessScope, personnelCoList, personnelCertCoList);
if (Boolean.FALSE.equals(booleanStringPair.getKey())) { if (Boolean.FALSE.equals(booleanStringPair.getKey())) {
throw new BizException(PERSON_NOT_ENOUGH, booleanStringPair.getValue()); throw new BizException(PERSON_NOT_ENOUGH, booleanStringPair.getValue());
} }
@ -266,12 +298,14 @@ public class ComplianceCheckUtil {
/** /**
* industryProfessionalStandardsValid * industryProfessionalStandardsValid
* *
* @param industryCodeList industryCodeList * @param industryCodeList industryCodeList
* @param industryProfessionalPersonCos industryProfessionalPersonCos * @param personnelCoList industryProfessionalPersonCos
* @param personnelCertCoList certCapabilityList
* @return Pair<Boolean, String> key value null * @return Pair<Boolean, String> key value null
*/ */
public static Pair<Boolean, String> industryProfessionalStandardsValid(List<String> industryCodeList public static Pair<Boolean, String> industryProfessionalStandardsValid(List<String> industryCodeList
, List<IndustryProfessionalPersonCo> industryProfessionalPersonCos) { , List<IndustryProfessionalPersonCo> personnelCoList
, List<OrgPersonnelCertCapabilityComplianceCheckCO> personnelCertCoList) {
if (CollectionUtils.isEmpty(industryCodeList)) { if (CollectionUtils.isEmpty(industryCodeList)) {
return Pair.of(false, "没有业务范围"); return Pair.of(false, "没有业务范围");
} }
@ -290,10 +324,16 @@ public class ComplianceCheckUtil {
// 按 industryCode 分组后循环调用 doIndustryProfessionalStandardsValid // 按 industryCode 分组后循环调用 doIndustryProfessionalStandardsValid
Map<String, List<IndustryProfessionalStandardsDO>> standardsGroupByIndustry = standardsDOList.stream() Map<String, List<IndustryProfessionalStandardsDO>> standardsGroupByIndustry = standardsDOList.stream()
.collect(Collectors.groupingBy(IndustryProfessionalStandardsDO::getIndustryCode)); .collect(Collectors.groupingBy(IndustryProfessionalStandardsDO::getIndustryCode));
Map<String, List<IndustryProfessionalPersonCo>> personnelCoGroupByIndustry = personnelCoList.stream()
.collect(Collectors.groupingBy(IndustryProfessionalPersonCo::getIndustryCode));
Map<String, List<OrgPersonnelCertCapabilityComplianceCheckCO>> personnelCertCoGroupByIndustry = personnelCertCoList.stream()
.collect(Collectors.groupingBy(OrgPersonnelCertCapabilityComplianceCheckCO::getBusinessScope));
StringJoiner failureMsg = new StringJoiner(";"); StringJoiner failureMsg = new StringJoiner(";");
for (Map.Entry<String, List<IndustryProfessionalStandardsDO>> entry : standardsGroupByIndustry.entrySet()) { for (Map.Entry<String, List<IndustryProfessionalStandardsDO>> entry : standardsGroupByIndustry.entrySet()) {
Pair<Boolean, String> result = doIndustryProfessionalStandardsValid(entry.getValue(), industryProfessionalPersonCos); Pair<Boolean, String> result = doIndustryProfessionalStandardsValid(
entry.getValue(), personnelCoGroupByIndustry.getOrDefault(entry.getKey(), new ArrayList<>())
, personnelCertCoGroupByIndustry.getOrDefault(entry.getKey(), new ArrayList<>()));
if (Boolean.FALSE.equals(result.getKey()) && result.getValue() != null) { if (Boolean.FALSE.equals(result.getKey()) && result.getValue() != null) {
failureMsg.add(result.getValue()); failureMsg.add(result.getValue());
} }
@ -306,18 +346,17 @@ public class ComplianceCheckUtil {
* *
* @param standardsDOList code + code * @param standardsDOList code + code
* @param industryProfessionalPersonCos code + code * @param industryProfessionalPersonCos code + code
* @param certCapabilityList certCapabilityList
* @return Pair<Boolean, String> key value null * @return Pair<Boolean, String> key value null
*/ */
public static Pair<Boolean, String> doIndustryProfessionalStandardsValid(List<IndustryProfessionalStandardsDO> standardsDOList public static Pair<Boolean, String> doIndustryProfessionalStandardsValid(List<IndustryProfessionalStandardsDO> standardsDOList
, List<IndustryProfessionalPersonCo> industryProfessionalPersonCos) { , List<IndustryProfessionalPersonCo> industryProfessionalPersonCos, List<OrgPersonnelCertCapabilityComplianceCheckCO> certCapabilityList) {
if (CollectionUtils.isEmpty(standardsDOList)) { if (CollectionUtils.isEmpty(standardsDOList)) {
return Pair.of(true, null); return Pair.of(true, null);
} }
List<IndustryProfessionalPersonCo> currentList =
industryProfessionalPersonCos == null ? Collections.emptyList() : industryProfessionalPersonCos;
// 当前人员数按 行业code + 专业能力code 分类汇总 // 当前人员数按 行业code + 专业能力code 分类汇总
Map<String, Long> currentCountMap = currentList.stream() Map<String, Long> currentCountMap = industryProfessionalPersonCos.stream()
.collect(Collectors.groupingBy( .collect(Collectors.groupingBy(
c -> groupKey(c.getIndustryCode(), c.getProfessionalCapabilityCode()), c -> groupKey(c.getIndustryCode(), c.getProfessionalCapabilityCode()),
Collectors.summingLong(c -> c.getPersonNum() == null ? 0L : c.getPersonNum()))); Collectors.summingLong(c -> c.getPersonNum() == null ? 0L : c.getPersonNum())));

View File

@ -41,4 +41,19 @@
`id`, `org_id`, `personnel_id`, `cert_name`, `cert_type_code`, `cert_type_name`, `cert_category_code`, `cert_category_name`, `operation_category_code`, `operation_category_name`, `cert_no`, `issue_org`, `valid_start_date`, `valid_end_date`, `review_date`, `cert_attachment_url`, `business_scope`, `professional_capability_code`, `professional_capability_id`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env` `id`, `org_id`, `personnel_id`, `cert_name`, `cert_type_code`, `cert_type_name`, `cert_category_code`, `cert_category_name`, `operation_category_code`, `operation_category_name`, `cert_no`, `issue_org`, `valid_start_date`, `valid_end_date`, `review_date`, `cert_attachment_url`, `business_scope`, `professional_capability_code`, `professional_capability_id`, `delete_enum`, `remarks`, `create_name`, `update_name`, `tenant_id`, `version`, `create_time`, `update_time`, `create_id`, `update_id`, `env`
</sql> </sql>
<!-- 根据人员id列表查询证书专业能力信息 -->
<select id="selectCapabilityByPersonnelIds"
resultType="org.qinan.safetyeval.client.co.OrgPersonnelCertCapabilityComplianceCheckCO">
SELECT personnel_id,
business_scope,
professional_capability_code,
professional_capability_id
FROM org_personnel_cert
WHERE delete_enum = 'false'
AND personnel_id IN
<foreach collection="personnelIds" item="personnelId" open="(" separator="," close=")">
#{personnelId}
</foreach>
</select>
</mapper> </mapper>