appendCapabilityAssessment

dev-tmp1
luotaiqian 2026-08-19 09:02:19 +08:00
parent 8e9d91c50a
commit 73d01a0a28
3 changed files with 117 additions and 54 deletions

View File

@ -12,6 +12,7 @@ import com.zcloud.gbscommon.utils.MD5;
import com.zcloud.gbscommon.utils.Sm2Util; import com.zcloud.gbscommon.utils.Sm2Util;
import org.qinan.safetyeval.client.co.OrgPersonnelImportErrorCO; import org.qinan.safetyeval.client.co.OrgPersonnelImportErrorCO;
import org.qinan.safetyeval.client.co.OrgPersonnelImportResultCO; 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.QualificationLevelEnum;
import org.qinan.safetyeval.domain.constant.basic.IndustryEnum; import org.qinan.safetyeval.domain.constant.basic.IndustryEnum;
import org.qinan.safetyeval.domain.constant.basic.ProfessionalCapabilityEnum; 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.major.model.BasicDisciplineMajorE;
import org.qinan.safetyeval.domain.service.OrgPersonnelDomainService; import org.qinan.safetyeval.domain.service.OrgPersonnelDomainService;
import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter; 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.remote.SystemRemote;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -73,6 +76,9 @@ public class OrgPersonnelExcelImporter {
@Resource @Resource
private BasicDisciplineMajorGateway basicDisciplineMajorGateway; private BasicDisciplineMajorGateway basicDisciplineMajorGateway;
@Resource
private BasicDisciplineMajorDoConvertor basicDisciplineMajorDoConvertor;
@Resource @Resource
private OrgPersonnelDomainService orgPersonnelDomainService; private OrgPersonnelDomainService orgPersonnelDomainService;
@ -124,7 +130,7 @@ public class OrgPersonnelExcelImporter {
return result; return result;
} }
// 3. 批量校验并回填所学专业ID // 3. 批量校验所学专业、系列/专业(两个字段名称合并为一次 in 查询基础学科专业对照表)
validateAndFillMajor(rows, errors); validateAndFillMajor(rows, errors);
rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList()); rows = rows.stream().filter(it -> !it.isValidateFail()).collect(Collectors.toList());
if (rows.isEmpty()) { if (rows.isEmpty()) {
@ -136,9 +142,32 @@ public class OrgPersonnelExcelImporter {
Set<String> existingAccounts = batchQueryExistingAccounts(rows, orgId); Set<String> existingAccounts = batchQueryExistingAccounts(rows, orgId);
// 5. 逐行转换、落库 // 5. 逐行转换、落库
int successCount = saveRows(rows, orgId, existingAccounts, errors);
result.setSuccessCount(successCount);
result.setErrors(errors);
return result;
}
/**
*
* <ul>
* <li> -> </li>
* <li>/buildOrgPersonnel null-> </li>
* <li> -> </li>
* <li> -> </li>
* </ul>
*
* @param rows
* @param orgId ID
* @param existingAccounts
* @param errors
* @return
*/
private int saveRows(List<OrgPersonnelImportRow> rows, Long orgId, Set<String> existingAccounts
, List<OrgPersonnelImportErrorCO> errors) {
int successCount = 0; int successCount = 0;
for (OrgPersonnelImportRow row : rows) { for (OrgPersonnelImportRow row : rows) {
String account = trim(row.getBasic().getAccount()); String account = trim(row.getBasic().getAccount());
@ -168,9 +197,7 @@ public class OrgPersonnelExcelImporter {
} }
} }
result.setSuccessCount(successCount); return successCount;
result.setErrors(errors);
return result;
} }
/** /**
@ -259,9 +286,9 @@ public class OrgPersonnelExcelImporter {
OrgPersonnelImportRow row = new OrgPersonnelImportRow(); OrgPersonnelImportRow row = new OrgPersonnelImportRow();
basic.setRowIndex(i + 2); basic.setRowIndex(i + 2);
row.setBasic(basic); row.setBasic(basic);
Pair<Boolean, OrgPersonnelImportRow.CapabilityRow> capabilityRow = matchCapability(basic, capabilityMap, errors); boolean validate = matchCapability(basic, capabilityMap, errors);
// 能力信息未匹配或存在多条,已记录异常,剔除该行 // 能力信息未匹配或存在多条,已记录异常,剔除该行
if (!capabilityRow.getKey()) { if (!validate) {
continue; continue;
} }
@ -312,26 +339,24 @@ public class OrgPersonnelExcelImporter {
* null * null
* </p> * </p>
*/ */
private Pair<Boolean, OrgPersonnelImportRow.CapabilityRow> matchCapability(OrgPersonnelImportRow.BasicRow basic private Boolean matchCapability(OrgPersonnelImportRow.BasicRow basic
, Map<String, List<OrgPersonnelImportRow.CapabilityRow>> capabilityMap, List<OrgPersonnelImportErrorCO> errors) { , Map<String, List<OrgPersonnelImportRow.CapabilityRow>> capabilityMap, List<OrgPersonnelImportErrorCO> errors) {
List<OrgPersonnelImportRow.CapabilityRow> capabilityList = capabilityMap.get(trim(basic.getIdCardNo())); List<OrgPersonnelImportRow.CapabilityRow> capabilityList = capabilityMap.get(trim(basic.getIdCardNo()));
if (CollectionUtils.isEmpty(capabilityList)) { if (CollectionUtils.isEmpty(capabilityList)) {
return Pair.of(true, null); return true;
} }
if (capabilityList.size() > 1) { if (capabilityList.size() > 1) {
errors.add(new OrgPersonnelImportErrorCO(basic.getRowIndex(), trim(basic.getAccount()), trim(basic.getUserName()), 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); OrgPersonnelImportRow.CapabilityRow capabilityRow = capabilityList.get(0);
// 校验基础信息 // 校验基础信息
// 2. sheet2 能力信息校验(未匹配到能力信息时跳过),行号取 sheet2 行号,消息加前缀便于区分来源 // 2. sheet2 能力信息校验(未匹配到能力信息时跳过),行号取 sheet2 行号,消息加前缀便于区分来源
Set<ConstraintViolation<OrgPersonnelImportRow.CapabilityRow>> capabilityViolations = Set<ConstraintViolation<OrgPersonnelImportRow.CapabilityRow>> capabilityViolations = validator.validate(capabilityRow);
validator.validate(capabilityRow);
if (!capabilityViolations.isEmpty()) { if (!capabilityViolations.isEmpty()) {
capabilityViolations.stream() capabilityViolations.stream()
.collect(Collectors.toMap( .collect(Collectors.toMap(
@ -341,35 +366,35 @@ public class OrgPersonnelExcelImporter {
.values() .values()
.forEach(v -> errors.add(new OrgPersonnelImportErrorCO(capabilityRow.getRowIndex(), .forEach(v -> errors.add(new OrgPersonnelImportErrorCO(capabilityRow.getRowIndex(),
capabilityRow.getUserName(), capabilityRow.getIdCardNo(), "能力信息:" + v.getMessage()))); capabilityRow.getUserName(), capabilityRow.getIdCardNo(), "能力信息:" + v.getMessage())));
return Pair.of(false, null); return false;
} }
// 能力认证一/二:认证行业、专业能力、来源 有值时校验枚举并回填,不通过记录异常 // 能力认证一/二:认证行业、专业能力、来源 有值时校验枚举并回填,不通过记录异常
if (!validateAndFillCertEnums(basic, capabilityRow, errors)) { if (!validateAndFillCertEnums(basic, capabilityRow, errors)) {
return Pair.of(false, null); return false;
} }
// 是否注册安全工程师:为[是]时 注安专业类别/注安等级/证书编号/执业证书编号 必填并校验枚举,通过后写入证书实体 // 是否注册安全工程师:为[是]时 注安专业类别/注安等级/证书编号/执业证书编号 必填并校验枚举,通过后写入证书实体
if (!validateAndFillRegisterEngineerCert(basic, capabilityRow, errors)) { if (!validateAndFillRegisterEngineerCert(basic, capabilityRow, errors)) {
return Pair.of(false, null); return false;
} }
// 是否评价师:为[是]时 评价师等级/证书编号 必填并校验枚举,通过后写入证书实体 // 是否评价师:为[是]时 评价师等级/证书编号 必填并校验枚举,通过后写入证书实体
if (!validateAndFillEvaluatorCert(basic, capabilityRow, errors)) { if (!validateAndFillEvaluatorCert(basic, capabilityRow, errors)) {
return Pair.of(false, null); return false;
} }
// 职称:有值时校验枚举并回填,查询不到记录异常 // 职称:有值时校验枚举并回填,查询不到记录异常
if (!validateAndFillTitle(basic, capabilityRow, errors)) { if (!validateAndFillTitle(basic, capabilityRow, errors)) {
return Pair.of(false, null); return false;
} }
// 学历类型、毕业院校、学历层次、所学专业 回填到基础信息行(@ExcelIgnore 字段Excel原始值忽略
basic.setEducationType(capabilityRow.getEducationType()); basic.setEducationType(capabilityRow.getEducationType());
basic.setGraduateSchool(capabilityRow.getGraduateSchool()); basic.setGraduateSchool(capabilityRow.getGraduateSchool());
basic.setEducationLevel(capabilityRow.getEducationLevel()); basic.setEducationLevel(capabilityRow.getEducationLevel());
basic.setMajor(capabilityRow.getMajor()); basic.setMajor(capabilityRow.getMajor());
return Pair.of(true, capabilityRow); return true;
} }
/** /**
@ -391,12 +416,6 @@ public class OrgPersonnelExcelImporter {
String userName = trim(basic.getUserName()); String userName = trim(basic.getUserName());
Integer rowIndex = capability.getRowIndex(); 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()); String cert1Industry = trim(capability.getCert1Industry());
IndustryEnum cert1IndustryEnum = IndustryEnum.ofName(cert1Industry); IndustryEnum cert1IndustryEnum = IndustryEnum.ofName(cert1Industry);
@ -462,8 +481,6 @@ public class OrgPersonnelExcelImporter {
} }
appendCapabilityAssessment(basic, cert2IndustryEnum, cert2AbilityEnum, cert2SourceEnum); appendCapabilityAssessment(basic, cert2IndustryEnum, cert2AbilityEnum, cert2SourceEnum);
} }
return true; return true;
} }
@ -541,7 +558,7 @@ public class OrgPersonnelExcelImporter {
// 校验通过 -> 组装注安证书实体写入基础信息行 // 校验通过 -> 组装注安证书实体写入基础信息行
basic.getPersonnelCertEntities().add( basic.getPersonnelCertEntities().add(
buildRegisterEngineerCert(categoryEnum, levelEnum, certNo, practiceCertNo)); buildRegisterEngineerCert(categoryEnum, levelEnum, certNo, practiceCertNo, basic));
return true; return true;
} }
@ -550,16 +567,16 @@ public class OrgPersonnelExcelImporter {
* / * /
*/ */
private OrgPersonnelCertEntity buildRegisterEngineerCert(SafetyCategoryEnum categoryEnum private OrgPersonnelCertEntity buildRegisterEngineerCert(SafetyCategoryEnum categoryEnum
, QualificationLevelEnum levelEnum, String certNo, String practiceCertNo) { , QualificationLevelEnum levelEnum, String certNo, String practiceCertNo, OrgPersonnelImportRow.BasicRow basic) {
OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity(); OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity();
cert.setCertName("注册安全工程师");
// 注安专业类别 // 注安专业类别
cert.setCertCategoryCode(categoryEnum.getValue()); cert.setCertTypeCode(CertTypeCodeEnum.REGISTERED_SAFETY_ENGINEER.getCode());
cert.setCertCategoryName(categoryEnum.getLabel());
// 注安等级编码同证书等级SENIOR/MIDDLE/JUNIOR // 注安等级编码同证书等级SENIOR/MIDDLE/JUNIOR
cert.setCertLevel(levelEnum.getCode()); cert.setCertLevel(levelEnum.getCode());
cert.setCertCategoryCode(categoryEnum.getIndustry().getCode());
cert.setCertNo(certNo); cert.setCertNo(certNo);
cert.setPractisingCertCode(practiceCertNo); cert.setPractisingCertCode(practiceCertNo);
InsertFieldDefaults.applyIgnoreOrgId(cert);
return cert; return cert;
} }
@ -614,10 +631,12 @@ public class OrgPersonnelExcelImporter {
*/ */
private OrgPersonnelCertEntity buildEvaluatorCert(QualificationLevelEnum levelEnum, String certNo) { private OrgPersonnelCertEntity buildEvaluatorCert(QualificationLevelEnum levelEnum, String certNo) {
OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity(); OrgPersonnelCertEntity cert = new OrgPersonnelCertEntity();
cert.setCertName("安全评价师"); // 注安专业类别
// 评价师等级编码同证书等级SENIOR/MIDDLE/JUNIOR cert.setCertTypeCode(CertTypeCodeEnum.REGISTERED_SAFETY_ENGINEER.getCode());
// 注安等级编码同证书等级SENIOR/MIDDLE/JUNIOR
cert.setCertLevel(levelEnum.getCode()); cert.setCertLevel(levelEnum.getCode());
cert.setCertNo(certNo); cert.setCertNo(certNo);
InsertFieldDefaults.applyIgnoreOrgId(cert);
return cert; return cert;
} }
@ -936,16 +955,33 @@ public class OrgPersonnelExcelImporter {
} }
/** /**
* basic_discipline_major.professional_name * major /seriesMajor
* basicDisciplineMajorId validateFail * basic_discipline_major.professional_name in
* <p></p> * validateFail
* <p>
* -> basicDisciplineMajorId {@link OrgPersonnelImportRow.CapabilityRow#setBdmMajor}
* / -> {@link OrgPersonnelImportRow.CapabilityRow#setBdmSeriesMajor}
* </p>
*/ */
private void validateAndFillMajor(List<OrgPersonnelImportRow> rows, List<OrgPersonnelImportErrorCO> errors) { private void validateAndFillMajor(List<OrgPersonnelImportRow> rows, List<OrgPersonnelImportErrorCO> errors) {
Set<String> majorNames = rows.stream() // 所学专业、系列/专业 两个字段名称合并收集,一次 in 查询
.map(r -> r.getCapability() == null ? null : trim(r.getCapability().getMajor())) Set<String> majorNames = new LinkedHashSet<>();
.filter(StringUtils::hasText) for (OrgPersonnelImportRow row : rows) {
.collect(Collectors.toCollection(LinkedHashSet::new)); 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<String, BasicDisciplineMajorE> majorMap = new HashMap<>(); Map<String, BasicDisciplineMajorE> majorMap = new HashMap<>();
if (!majorNames.isEmpty()) { if (!majorNames.isEmpty()) {
for (BasicDisciplineMajorE major : basicDisciplineMajorGateway.listByProfessionalNames(majorNames)) { for (BasicDisciplineMajorE major : basicDisciplineMajorGateway.listByProfessionalNames(majorNames)) {
@ -955,20 +991,36 @@ public class OrgPersonnelExcelImporter {
} }
} }
// 逐行校验:专业名称为空的行跳过对照表中不存在的行记录异常并标记校验通过则回填专业ID // 逐行校验:字段为空跳过;对照表中不存在的记录异常并标记;校验通过则回填
for (OrgPersonnelImportRow row : rows) { for (OrgPersonnelImportRow row : rows) {
String name = row.getCapability() == null ? null : trim(row.getCapability().getMajor()); OrgPersonnelImportRow.CapabilityRow capability = row.getCapability();
if (!StringUtils.hasText(name)) {
continue; // 所学专业:查询不到记录异常;查询到回填 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) { // 系列/专业:查询不到记录异常;查询到回填 bdmSeriesMajor
errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), String seriesMajorName = trim(capability.getSeriesMajor());
ErrorCode.ORG_PERSONNEL_IMPORT_MAJOR_NOT_FOUND.getMessage() + "" + name)); if (StringUtils.hasText(seriesMajorName)) {
row.setValidateFail(true); BasicDisciplineMajorE seriesMajor = majorMap.get(seriesMajorName);
continue; 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());
} }
} }

View File

@ -5,9 +5,11 @@ import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Range; 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.CapabilityAssessmentDTO;
import org.qinan.safetyeval.domain.entity.OrgPersonnelCertEntity; import org.qinan.safetyeval.domain.entity.OrgPersonnelCertEntity;
import org.qinan.safetyeval.domain.entity.TitleCodeCo; import org.qinan.safetyeval.domain.entity.TitleCodeCo;
import org.qinan.safetyeval.infrastructure.persistence.domainobject.BasicDisciplineMajorDO;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
@ -270,6 +272,9 @@ public class OrgPersonnelImportRow {
@NotBlank(message = "所学专业不能为空") @NotBlank(message = "所学专业不能为空")
private String major; private String major;
@ExcelIgnore
private BasicDisciplineMajorDO bdmMajor;
@ExcelProperty(value = "是否注册安全工程师", index = 12) @ExcelProperty(value = "是否注册安全工程师", index = 12)
@Pattern(regexp = "^([是否])?$", message = "是否注册安全工程师仅允许:是、否") @Pattern(regexp = "^([是否])?$", message = "是否注册安全工程师仅允许:是、否")
@NotBlank(message = "是否注册安全工程师不能为空") @NotBlank(message = "是否注册安全工程师不能为空")
@ -312,6 +317,9 @@ public class OrgPersonnelImportRow {
@Size(max = 64, message = "评价师证书编号长度不能超过64个字符") @Size(max = 64, message = "评价师证书编号长度不能超过64个字符")
private String seriesMajor; private String seriesMajor;
@ExcelIgnore
private BasicDisciplineMajorDO bdmSeriesMajor;
@ExcelIgnore @ExcelIgnore
private Integer rowIndex; private Integer rowIndex;
} }

View File

@ -41,6 +41,9 @@ public enum SafetyCategoryEnum {
} }
return null; return null;
} }
public IndustryEnum getIndustry(){
return getIndustry(this);
}
public static IndustryEnum getIndustry(SafetyCategoryEnum safetyCategoryEnum) { public static IndustryEnum getIndustry(SafetyCategoryEnum safetyCategoryEnum) {
switch (safetyCategoryEnum) { switch (safetyCategoryEnum) {