From 091886bf2eab49ae5ffbe61b3a8879491f85b317 Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Tue, 18 Aug 2026 20:48:23 +0800 Subject: [PATCH] appendCapabilityAssessment --- .../support/OrgPersonnelExcelImporter.java | 149 ++++++++++++++++-- .../app/support/OrgPersonnelImportRow.java | 10 +- .../domain/constant/basic/IndustryEnum.java | 12 ++ .../basic/ProfessionalCapabilityEnum.java | 12 ++ .../ProfessionalCapabilitySourceEnum.java | 12 ++ 5 files changed, 184 insertions(+), 11 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 19041028..8f5a68f7 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,10 @@ 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.basic.IndustryEnum; +import org.qinan.safetyeval.domain.constant.basic.ProfessionalCapabilityEnum; +import org.qinan.safetyeval.domain.constant.basic.ProfessionalCapabilitySourceEnum; +import org.qinan.safetyeval.domain.entity.CapabilityAssessmentDTO; import org.qinan.safetyeval.domain.entity.OrgDepartmentEntity; import org.qinan.safetyeval.domain.entity.OrgPersonnelCertEntity; import org.qinan.safetyeval.domain.entity.OrgPersonnelEntity; @@ -181,6 +185,9 @@ public class OrgPersonnelExcelImporter { */ private List buildOrgPersonnelCert(OrgPersonnelImportRow row , Long orgId, List errors, OrgPersonnelEntity personnelEntity) { + if (row.getCapability() == null) { + return Collections.emptyList(); + } return null; } @@ -254,9 +261,10 @@ public class OrgPersonnelExcelImporter { OrgPersonnelImportRow row = new OrgPersonnelImportRow(); basic.setRowIndex(i + 2); row.setBasic(basic); - row.setCapability(matchCapability(basic, capabilityMap, errors)); + Pair capabilityRow = matchCapability(basic, capabilityMap, errors); + row.setCapability(capabilityRow.getValue()); // 能力信息未匹配或存在多条,已记录异常,剔除该行 - if (row.getCapability() == null) { + if (!capabilityRow.getKey()) { continue; } @@ -301,22 +309,142 @@ public class OrgPersonnelExcelImporter { /** * 基础信息行按身份证号匹配能力信息: * 未匹配到或多条均记录异常并返回 null,仅唯一匹配时返回该行。 + *

+ * 匹配成功后校验能力认证一/二的 认证行业、专业能力、来源: + * 有值才校验,通过则把枚举回填到 {@link OrgPersonnelImportRow.CapabilityRow}(@ExcelIgnore 字段,Excel原始值忽略), + * 任一不通过记录异常并返回 null。 + *

*/ - private OrgPersonnelImportRow.CapabilityRow matchCapability(OrgPersonnelImportRow.BasicRow basic, - Map> capabilityMap, - List errors) { + private Pair matchCapability(OrgPersonnelImportRow.BasicRow basic + , Map> capabilityMap, List errors) { + List capabilityList = capabilityMap.get(trim(basic.getIdCardNo())); if (CollectionUtils.isEmpty(capabilityList)) { - errors.add(new OrgPersonnelImportErrorCO(basic.getRowIndex(), trim(basic.getAccount()), trim(basic.getUserName()), - "没有在专职人员能力信息中查询到数据")); - return null; + return Pair.of(true, null); } if (capabilityList.size() > 1) { errors.add(new OrgPersonnelImportErrorCO(basic.getRowIndex(), trim(basic.getAccount()), trim(basic.getUserName()), "专职人员能力信息中查询到多条数据")); - return null; + return Pair.of(false, null); } - return capabilityList.get(0); + OrgPersonnelImportRow.CapabilityRow capabilityRow = capabilityList.get(0); + + // 能力认证一/二:认证行业、专业能力、来源 有值时校验枚举并回填,不通过记录异常 + if (!validateAndFillCertEnums(basic, capabilityRow, errors)) { + return Pair.of(false, null); + } + + return Pair.of(true, capabilityRow); + } + + /** + * 能力认证一/二枚举校验并回填: + *
    + *
  • 认证行业 -> {@link IndustryEnum#ofName};
  • + *
  • 专业能力 -> {@link ProfessionalCapabilityEnum#ofName};
  • + *
  • 来源 -> {@link ProfessionalCapabilitySourceEnum#ofName}。
  • + *
+ * 能力认证一 认证行业/专业能力/来源 均为必填,查询不到枚举即记录异常并返回; + * 能力认证二 可空,有值才校验,查询不到枚举同样记录异常并返回; + * 通过后把枚举存入 {@link OrgPersonnelImportRow.CapabilityRow}(@ExcelIgnore 字段,忽略Excel原始值),行号取 sheet2 行号。 + * + * @return true 全部通过,false 存在不通过字段(已记录异常) + */ + private boolean validateAndFillCertEnums(OrgPersonnelImportRow.BasicRow basic + , OrgPersonnelImportRow.CapabilityRow capability, List errors) { + String account = trim(basic.getAccount()); + String userName = trim(basic.getUserName()); + Integer rowIndex = capability.getRowIndex(); + + // 能力认证一(必填):认证行业、专业能力、来源,查询不到枚举即记录异常并返回 + String cert1Industry = trim(capability.getCert1Industry()); + IndustryEnum cert1IndustryEnum = IndustryEnum.ofName(cert1Industry); + if (cert1IndustryEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证一-认证行业[" + cert1Industry + "]无法识别")); + return false; + } + + String cert1Ability = trim(capability.getCert1Ability()); + ProfessionalCapabilityEnum cert1AbilityEnum = ProfessionalCapabilityEnum.ofName(cert1Ability); + if (cert1AbilityEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证一-专业能力[" + cert1Ability + "]无法识别")); + return false; + } + + String cert1Source = trim(capability.getCert1Source()); + ProfessionalCapabilitySourceEnum cert1SourceEnum = ProfessionalCapabilitySourceEnum.ofName(cert1Source); + if (cert1SourceEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证一-来源[" + cert1Source + "]无法识别")); + return false; + } + // 有能力认证(三项枚举齐全)-> 组装能力认定回填到基础信息行 + appendCapabilityAssessment(basic, cert1IndustryEnum, cert1AbilityEnum, cert1SourceEnum); + + + // 能力认证二(可空,但认证行业/专业能力/来源为一组):必须整组全空或整组全填,仅部分填写视为异常 + String cert2Industry = trim(capability.getCert2Industry()); + String cert2Ability = trim(capability.getCert2Ability()); + String cert2Source = trim(capability.getCert2Source()); + boolean cert2IndustryHasText = StringUtils.hasText(cert2Industry); + boolean cert2AbilityHasText = StringUtils.hasText(cert2Ability); + boolean cert2SourceHasText = StringUtils.hasText(cert2Source); + if (cert2IndustryHasText || cert2AbilityHasText || cert2SourceHasText) { + if (!cert2IndustryHasText || !cert2AbilityHasText || !cert2SourceHasText) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证二的认证行业、专业能力、来源必须同时填写")); + return false; + } + + // 整组都有值:逐项校验枚举,查询不到即记录异常并返回 + IndustryEnum cert2IndustryEnum = IndustryEnum.ofName(cert2Industry); + if (cert2IndustryEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证二-认证行业[" + cert2Industry + "]无法识别")); + return false; + } + + ProfessionalCapabilityEnum cert2AbilityEnum = ProfessionalCapabilityEnum.ofName(cert2Ability); + if (cert2AbilityEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证二-专业能力[" + cert2Ability + "]无法识别")); + return false; + } + + ProfessionalCapabilitySourceEnum cert2SourceEnum = ProfessionalCapabilitySourceEnum.ofName(cert2Source); + if (cert2SourceEnum == null) { + errors.add(new OrgPersonnelImportErrorCO(rowIndex, account, userName, + "能力认证二-来源[" + cert2Source + "]无法识别")); + return false; + } + appendCapabilityAssessment(basic, cert2IndustryEnum, cert2AbilityEnum, cert2SourceEnum); + } + + + + return true; + } + + /** + * 能力认证 认证行业/专业能力/来源 三项枚举均齐全时,组装 {@link CapabilityAssessmentDTO} + * 追加到 {@link OrgPersonnelImportRow.BasicRow#getCapabilityAssessment()};任一项为空(未填写或校验未通过)不添加。 + */ + private void appendCapabilityAssessment(OrgPersonnelImportRow.BasicRow basic, IndustryEnum industry, + ProfessionalCapabilityEnum ability, ProfessionalCapabilitySourceEnum source) { + if (industry == null || ability == null || source == null) { + return; + } + CapabilityAssessmentDTO assessment = new CapabilityAssessmentDTO(); + assessment.setIndustryCode(industry.getCode()); + assessment.setProfessionalCapabilityCode(ability.getCode()); + // 来源枚举编码即 value + assessment.setProfessionalCapabilitySourceCode(source.getValue()); + if (basic.getCapabilityAssessment() == null) { + basic.setCapabilityAssessment(new ArrayList<>()); + } + basic.getCapabilityAssessment().add(assessment); } /** @@ -748,6 +876,7 @@ public class OrgPersonnelExcelImporter { entity.setTechnicalDirectorFlag(YES.equals(basic.getTechnicalDirector())); entity.setProcessControlLeaderFlag(YES.equals(basic.getProcessControlLeader())); // 能力认证一/二、注安证书、评价师证书、高级工程师等 + entity.setCapabilityAssessment(basic.getCapabilityAssessment()); return entity; } 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 ef7e86ca..a77794e8 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 @@ -4,12 +4,15 @@ import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import org.hibernate.validator.constraints.Range; +import org.qinan.safetyeval.domain.entity.CapabilityAssessmentDTO; import org.springframework.util.StringUtils; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; +import java.util.ArrayList; +import java.util.List; /** * 人员导入 Excel 行模型(按列下标映射,避免表头存在重名列,如 sheet2 两列「证书编号」)。 @@ -168,6 +171,11 @@ public class OrgPersonnelImportRow { */ @ExcelIgnore private Integer rowIndex; + /** + * 能力 + */ + @ExcelIgnore + private List capabilityAssessment = new ArrayList<>(2); } /** @@ -219,7 +227,7 @@ public class OrgPersonnelImportRow { @ExcelProperty(value = "学历类型", index = 8) @NotBlank(message = "学历类型不能为空") - @Size(max = 64, message ="学历类型最多64个字符") + @Size(max = 64, message = "学历类型最多64个字符") private String educationType; @ExcelProperty(value = "毕业院校", index = 9) diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/IndustryEnum.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/IndustryEnum.java index 8e69e6ef..e0d5d492 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/IndustryEnum.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/IndustryEnum.java @@ -45,6 +45,18 @@ public enum IndustryEnum { return null; } + public static IndustryEnum ofName(String name) { + if (name == null) { + return null; + } + for (IndustryEnum item : values()) { + if (item.getValue().equals(name)) { + return item; + } + } + return null; + } + public static String getValueByCode(String code) { if (code == null) { return null; diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilityEnum.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilityEnum.java index 2d7a42ef..dd344307 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilityEnum.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilityEnum.java @@ -56,4 +56,16 @@ public enum ProfessionalCapabilityEnum { } return null; } + + public static ProfessionalCapabilityEnum ofName(String name) { + if (name == null) { + return null; + } + for (ProfessionalCapabilityEnum item : values()) { + if (item.getValue().equals(name)) { + return item; + } + } + return null; + } } diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilitySourceEnum.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilitySourceEnum.java index 606507e6..7b89ab9f 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilitySourceEnum.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/constant/basic/ProfessionalCapabilitySourceEnum.java @@ -23,4 +23,16 @@ public enum ProfessionalCapabilitySourceEnum { "EDUCATION=>学历;" + "PROFESSIONAL_TITLE=>职称;" + "ACADEMIC_ACHIEVEMENT=>出版学术专著、专利、获奖、发表学术论文等"; + + public static ProfessionalCapabilitySourceEnum ofName(String name) { + if (name == null) { + return null; + } + for (ProfessionalCapabilitySourceEnum item : values()) { + if (item.getValue().equals(name)) { + return item; + } + } + return null; + } }