From 73d01a0a28372631f00a88796f56fc726a72fe45 Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Wed, 19 Aug 2026 09:02:19 +0800 Subject: [PATCH] appendCapabilityAssessment --- .../support/OrgPersonnelExcelImporter.java | 160 ++++++++++++------ .../app/support/OrgPersonnelImportRow.java | 8 + .../constant/basic/SafetyCategoryEnum.java | 3 + 3 files changed, 117 insertions(+), 54 deletions(-) diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java index e0997155..840baa59 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelExcelImporter.java @@ -12,6 +12,7 @@ import com.zcloud.gbscommon.utils.MD5; import com.zcloud.gbscommon.utils.Sm2Util; import org.qinan.safetyeval.client.co.OrgPersonnelImportErrorCO; import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; +import org.qinan.safetyeval.domain.constant.CertTypeCodeEnum; import org.qinan.safetyeval.domain.constant.QualificationLevelEnum; import org.qinan.safetyeval.domain.constant.basic.IndustryEnum; import org.qinan.safetyeval.domain.constant.basic.ProfessionalCapabilityEnum; @@ -27,7 +28,9 @@ import org.qinan.safetyeval.domain.major.gateway.BasicDisciplineMajorGateway; import org.qinan.safetyeval.domain.major.model.BasicDisciplineMajorE; import org.qinan.safetyeval.domain.service.OrgPersonnelDomainService; import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; +import org.qinan.safetyeval.infrastructure.convertor.BasicDisciplineMajorDoConvertor; import org.qinan.safetyeval.infrastructure.remote.SystemRemote; +import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -73,6 +76,9 @@ public class OrgPersonnelExcelImporter { @Resource private BasicDisciplineMajorGateway basicDisciplineMajorGateway; + @Resource + private BasicDisciplineMajorDoConvertor basicDisciplineMajorDoConvertor; + @Resource private OrgPersonnelDomainService orgPersonnelDomainService; @@ -124,7 +130,7 @@ public class OrgPersonnelExcelImporter { return result; } - // 3. 批量校验并回填所学专业ID + // 3. 批量校验所学专业、系列/专业(两个字段名称合并为一次 in 查询基础学科专业对照表) validateAndFillMajor(rows, errors); rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList()); if (rows.isEmpty()) { @@ -136,9 +142,32 @@ public class OrgPersonnelExcelImporter { Set existingAccounts = batchQueryExistingAccounts(rows, orgId); // 5. 逐行转换、落库 + int successCount = saveRows(rows, orgId, existingAccounts, errors); + + result.setSuccessCount(successCount); + result.setErrors(errors); + return result; + } + + /** + * 逐行转换、落库: + * + * + * @param rows 待导入的行(前置批量校验均已通过) + * @param orgId 机构ID + * @param existingAccounts 库中已存在的账号集合 + * @param errors 异常收集列表 + * @return 成功落库的行数 + */ + private int saveRows(List rows, Long orgId, Set existingAccounts + , List errors) { + int successCount = 0; - - for (OrgPersonnelImportRow row : rows) { String account = trim(row.getBasic().getAccount()); @@ -168,9 +197,7 @@ public class OrgPersonnelExcelImporter { } } - result.setSuccessCount(successCount); - result.setErrors(errors); - return result; + return successCount; } /** @@ -259,9 +286,9 @@ public class OrgPersonnelExcelImporter { OrgPersonnelImportRow row = new OrgPersonnelImportRow(); basic.setRowIndex(i + 2); row.setBasic(basic); - Pair capabilityRow = matchCapability(basic, capabilityMap, errors); + boolean validate = matchCapability(basic, capabilityMap, errors); // 能力信息未匹配或存在多条,已记录异常,剔除该行 - if (!capabilityRow.getKey()) { + if (!validate) { continue; } @@ -312,26 +339,24 @@ public class OrgPersonnelExcelImporter { * 任一不通过记录异常并返回 null。 *

*/ - private Pair matchCapability(OrgPersonnelImportRow.BasicRow basic + private Boolean matchCapability(OrgPersonnelImportRow.BasicRow basic , Map> capabilityMap, List errors) { List capabilityList = capabilityMap.get(trim(basic.getIdCardNo())); if (CollectionUtils.isEmpty(capabilityList)) { - return Pair.of(true, null); + return true; } if (capabilityList.size() > 1) { errors.add(new OrgPersonnelImportErrorCO(basic.getRowIndex(), trim(basic.getAccount()), trim(basic.getUserName()), "专职人员能力信息中查询到多条数据")); - return Pair.of(false, null); + return false; } OrgPersonnelImportRow.CapabilityRow capabilityRow = capabilityList.get(0); - // 校验基础信息 // 2. sheet2 能力信息校验(未匹配到能力信息时跳过),行号取 sheet2 行号,消息加前缀便于区分来源 - Set> capabilityViolations = - validator.validate(capabilityRow); + Set> capabilityViolations = validator.validate(capabilityRow); if (!capabilityViolations.isEmpty()) { capabilityViolations.stream() .collect(Collectors.toMap( @@ -341,35 +366,35 @@ public class OrgPersonnelExcelImporter { .values() .forEach(v -> errors.add(new OrgPersonnelImportErrorCO(capabilityRow.getRowIndex(), capabilityRow.getUserName(), capabilityRow.getIdCardNo(), "能力信息:" + v.getMessage()))); - return Pair.of(false, null); + return false; } // 能力认证一/二:认证行业、专业能力、来源 有值时校验枚举并回填,不通过记录异常 if (!validateAndFillCertEnums(basic, capabilityRow, errors)) { - return Pair.of(false, null); + return false; } // 是否注册安全工程师:为[是]时 注安专业类别/注安等级/证书编号/执业证书编号 必填并校验枚举,通过后写入证书实体 if (!validateAndFillRegisterEngineerCert(basic, capabilityRow, errors)) { - return Pair.of(false, null); + return false; } // 是否评价师:为[是]时 评价师等级/证书编号 必填并校验枚举,通过后写入证书实体 if (!validateAndFillEvaluatorCert(basic, capabilityRow, errors)) { - return Pair.of(false, null); + return false; } // 职称:有值时校验枚举并回填,查询不到记录异常 if (!validateAndFillTitle(basic, capabilityRow, errors)) { - return Pair.of(false, null); + return false; } - + // 学历类型、毕业院校、学历层次、所学专业 回填到基础信息行(@ExcelIgnore 字段,Excel原始值忽略) basic.setEducationType(capabilityRow.getEducationType()); basic.setGraduateSchool(capabilityRow.getGraduateSchool()); basic.setEducationLevel(capabilityRow.getEducationLevel()); basic.setMajor(capabilityRow.getMajor()); - return Pair.of(true, capabilityRow); + return true; } /** @@ -391,12 +416,6 @@ public class OrgPersonnelExcelImporter { String userName = trim(basic.getUserName()); Integer rowIndex = capability.getRowIndex(); - // 学历类型、毕业院校、学历层次、所学专业 回填到基础信息行(@ExcelIgnore 字段,Excel原始值忽略) - basic.setEducationType(trim(capability.getEducationType())); - basic.setGraduateSchool(trim(capability.getGraduateSchool())); - basic.setEducationLevel(trim(capability.getEducationLevel())); - basic.setMajor(trim(capability.getMajor())); - // 能力认证一(必填):认证行业、专业能力、来源,查询不到枚举即记录异常并返回 String cert1Industry = trim(capability.getCert1Industry()); IndustryEnum cert1IndustryEnum = IndustryEnum.ofName(cert1Industry); @@ -462,8 +481,6 @@ public class OrgPersonnelExcelImporter { } appendCapabilityAssessment(basic, cert2IndustryEnum, cert2AbilityEnum, cert2SourceEnum); } - - return true; } @@ -541,7 +558,7 @@ public class OrgPersonnelExcelImporter { // 校验通过 -> 组装注安证书实体写入基础信息行 basic.getPersonnelCertEntities().add( - buildRegisterEngineerCert(categoryEnum, levelEnum, certNo, practiceCertNo)); + buildRegisterEngineerCert(categoryEnum, levelEnum, certNo, practiceCertNo, basic)); return true; } @@ -550,16 +567,16 @@ public class OrgPersonnelExcelImporter { * 注安专业类别/注安等级 枚举均已校验通过,直接取编码与名称回填。 */ private OrgPersonnelCertEntity buildRegisterEngineerCert(SafetyCategoryEnum categoryEnum - , QualificationLevelEnum levelEnum, String certNo, String practiceCertNo) { + , QualificationLevelEnum levelEnum, String certNo, String practiceCertNo, OrgPersonnelImportRow.BasicRow basic) { OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity(); - cert.setCertName("注册安全工程师"); // 注安专业类别 - cert.setCertCategoryCode(categoryEnum.getValue()); - cert.setCertCategoryName(categoryEnum.getLabel()); + cert.setCertTypeCode(CertTypeCodeEnum.REGISTERED_SAFETY_ENGINEER.getCode()); // 注安等级(编码同证书等级:SENIOR/MIDDLE/JUNIOR) cert.setCertLevel(levelEnum.getCode()); + cert.setCertCategoryCode(categoryEnum.getIndustry().getCode()); cert.setCertNo(certNo); cert.setPractisingCertCode(practiceCertNo); + InsertFieldDefaults.applyIgnoreOrgId(cert); return cert; } @@ -614,10 +631,12 @@ public class OrgPersonnelExcelImporter { */ private OrgPersonnelCertEntity buildEvaluatorCert(QualificationLevelEnum levelEnum, String certNo) { OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity(); - cert.setCertName("安全评价师"); - // 评价师等级(编码同证书等级:SENIOR/MIDDLE/JUNIOR) + // 注安专业类别 + cert.setCertTypeCode(CertTypeCodeEnum.REGISTERED_SAFETY_ENGINEER.getCode()); + // 注安等级(编码同证书等级:SENIOR/MIDDLE/JUNIOR) cert.setCertLevel(levelEnum.getCode()); cert.setCertNo(certNo); + InsertFieldDefaults.applyIgnoreOrgId(cert); return cert; } @@ -936,16 +955,33 @@ public class OrgPersonnelExcelImporter { } /** - * 批量校验所学专业名称在基础学科专业对照表中是否存在(basic_discipline_major.professional_name), - * 校验通过的同时回填 basicDisciplineMajorId;不存在的行记录异常并标记 validateFail。 - *

专业名称为空的行不参与校验(该字段可空)。

+ * 批量校验 所学专业(major)与 系列/专业(seriesMajor)名称在基础学科专业对照表中是否存在 + * (basic_discipline_major.professional_name),两个字段名称合并为一次 in 查询; + * 有值但查询不到的记录异常并标记 validateFail,为空的字段不参与校验(字段可空)。 + *

+ * 校验通过后回填:所学专业 -> basicDisciplineMajorId 与 {@link OrgPersonnelImportRow.CapabilityRow#setBdmMajor}; + * 系列/专业 -> {@link OrgPersonnelImportRow.CapabilityRow#setBdmSeriesMajor}。 + *

*/ private void validateAndFillMajor(List rows, List errors) { - Set majorNames = rows.stream() - .map(r -> r.getCapability() == null ? null : trim(r.getCapability().getMajor())) - .filter(StringUtils::hasText) - .collect(Collectors.toCollection(LinkedHashSet::new)); + // 所学专业、系列/专业 两个字段名称合并收集,一次 in 查询 + Set majorNames = new LinkedHashSet<>(); + for (OrgPersonnelImportRow row : rows) { + OrgPersonnelImportRow.CapabilityRow capability = row.getCapability(); + if (capability == null) { + continue; + } + String majorName = trim(capability.getMajor()); + if (StringUtils.hasText(majorName)) { + majorNames.add(majorName); + } + String seriesMajorName = trim(capability.getSeriesMajor()); + if (StringUtils.hasText(seriesMajorName)) { + majorNames.add(seriesMajorName); + } + } + // SELECT id,industry_code,professional_capability_code,professional_name FROM basic_discipline_major WHERE professional_name in (...) Map majorMap = new HashMap<>(); if (!majorNames.isEmpty()) { for (BasicDisciplineMajorE major : basicDisciplineMajorGateway.listByProfessionalNames(majorNames)) { @@ -955,20 +991,36 @@ public class OrgPersonnelExcelImporter { } } - // 逐行校验:专业名称为空的行跳过;对照表中不存在的行记录异常并标记;校验通过则回填专业ID + // 逐行校验:字段为空跳过;对照表中不存在的记录异常并标记;校验通过则回填 for (OrgPersonnelImportRow row : rows) { - String name = row.getCapability() == null ? null : trim(row.getCapability().getMajor()); - if (!StringUtils.hasText(name)) { - continue; + OrgPersonnelImportRow.CapabilityRow capability = row.getCapability(); + + // 所学专业:查询不到记录异常;查询到回填 basicDisciplineMajorId、bdmMajor + String majorName = trim(capability.getMajor()); + if (StringUtils.hasText(majorName)) { + BasicDisciplineMajorE major = majorMap.get(majorName); + if (major == null) { + errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), + ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + ":" + majorName)); + row.setValidateFail(true); + } else { + row.setBasicDisciplineMajorId(major.getId()); + capability.setBdmMajor(basicDisciplineMajorDoConvertor.convertEeToDo(major)); + } } - BasicDisciplineMajorE major = majorMap.get(name); - if (major == null) { - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + ":" + name)); - row.setValidateFail(true); - continue; + + // 系列/专业:查询不到记录异常;查询到回填 bdmSeriesMajor + String seriesMajorName = trim(capability.getSeriesMajor()); + if (StringUtils.hasText(seriesMajorName)) { + BasicDisciplineMajorE seriesMajor = majorMap.get(seriesMajorName); + if (seriesMajor == null) { + errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), + ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + ":" + seriesMajorName)); + row.setValidateFail(true); + } else { + capability.setBdmSeriesMajor(basicDisciplineMajorDoConvertor.convertEeToDo(seriesMajor)); + } } - row.setBasicDisciplineMajorId(major.getId()); } } diff --git a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java index 61101e78..1366a99c 100644 --- a/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java +++ b/safety-eval-app/src/main/java/org/qinan/safetyeval/app/support/OrgPersonnelImportRow.java @@ -5,9 +5,11 @@ import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.hibernate.validator.constraints.Range; +import org.qinan.safetyeval.client.major.request.BasicDisciplineMajorAddCmd; import org.qinan.safetyeval.domain.entity.CapabilityAssessmentDTO; import org.qinan.safetyeval.domain.entity.OrgPersonnelCertEntity; import org.qinan.safetyeval.domain.entity.TitleCodeCo; +import org.qinan.safetyeval.infrastructure.persistence.domainobject.BasicDisciplineMajorDO; import org.springframework.util.StringUtils; import javax.validation.constraints.NotBlank; @@ -270,6 +272,9 @@ public class OrgPersonnelImportRow { @NotBlank(message = "所学专业不能为空") private String major; + @ExcelIgnore + private BasicDisciplineMajorDO bdmMajor; + @ExcelProperty(value = "是否注册安全工程师", index = 12) @Pattern(regexp = "^([是否])?$", message = "是否注册安全工程师仅允许:是、否") @NotBlank(message = "是否注册安全工程师不能为空") @@ -312,6 +317,9 @@ public class OrgPersonnelImportRow { @Size(max = 64, message = "评价师证书编号长度不能超过64个字符") private String seriesMajor; + @ExcelIgnore + private BasicDisciplineMajorDO bdmSeriesMajor; + @ExcelIgnore private Integer rowIndex; } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/SafetyCategoryEnum.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/SafetyCategoryEnum.java index 5f2b0ed7..28fa244d 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/SafetyCategoryEnum.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/SafetyCategoryEnum.java @@ -41,6 +41,9 @@ public enum SafetyCategoryEnum { } return null; } + public IndustryEnum getIndustry(){ + return getIndustry(this); + } public static IndustryEnum getIndustry(SafetyCategoryEnum safetyCategoryEnum) { switch (safetyCategoryEnum) {