From b4043e82384ff5c764a73eb4bd047985e3fecf84 Mon Sep 17 00:00:00 2001 From: luotaiqian <1147642922@qq.com> Date: Fri, 21 Aug 2026 15:58:40 +0800 Subject: [PATCH] PaperBasicInfo --- .../support/OrgPersonnelExcelImporter.java | 181 ++++++++++-------- .../domain/exception/ErrorCode.java | 2 - 2 files changed, 105 insertions(+), 78 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 74794208..4d94c911 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 @@ -56,7 +56,7 @@ import java.util.stream.Collectors; *

* 模板包含两个 sheet:sheet1「专职人员基础信息」、sheet2「专职人员能力信息」, * 解析后按 身份证号(为空时按姓名) 将能力信息关联到基础信息行; - * 再批量校验部门/岗位名称并回填ID -> 校验账号重复并收集异常 -> 逐行落库。 + * 再批量校验部门/岗位名称并回填ID(部门或部门下岗位不存在时自动新增) -> 校验账号重复并收集异常 -> 逐行落库。 *

* * @author safety-eval @@ -769,12 +769,12 @@ public class OrgPersonnelExcelImporter { } /** - * 批量校验部门层级是否在当前机构下存在且层级关系正确。 + * 批量校验部门层级是否在当前机构下存在且层级关系正确,不存在的部门自动新增。 *

* 三级部门 -> 二级部门 -> 一级部门 逐级校验 parentId: *

*/ @@ -796,31 +796,53 @@ public class OrgPersonnelExcelImporter { Map> nameMapList = orgDepartmentList.stream().collect(Collectors.groupingBy(OrgDepartmentEntity::getDeptName)); for (OrgPersonnelImportRow row : rows) { - Pair l1 = getL1(errors, row, nameMapList); + Pair l1 = getL1(errors, row, nameMapList, orgId); if (!l1.getKey()) { continue; } OrgDepartmentEntity l1Dept = l1.getValue(); - Pair l2 = getL2(errors, row, nameMapList, l1Dept); + Pair l2 = getL2(row, nameMapList, l1Dept, orgId); if (!l2.getKey() || l2.getValue() == null) { continue; } - getL3(errors, row, nameMapList, l2.getValue()); + getL3(row, nameMapList, l2.getValue(), orgId); } } /** + * 新增部门并注册到名称索引(nameMapList),保证同一文件中同层级同名部门仅创建一次。 * - * @param errors errors - * @param row row - * @param nameMapList nameMapList - * @param l2Dept l2Dept - * @return Pair key 是否通过 true 通过 false 不通 - * ;value (key =true ,value=null 说明没有二级部门) + * @param orgId 机构ID + * @param parentId 上级部门ID(一级部门传 0) + * @param deptName 部门名称 + * @param nameMapList 部门名称索引(key: 部门名称) + * @return 新增后的部门实体(含生成的ID) */ - private Pair getL3(List errors, OrgPersonnelImportRow row - , Map> nameMapList, OrgDepartmentEntity l2Dept) { + private OrgDepartmentEntity createDept(Long orgId, Long parentId, String deptName, + Map> nameMapList) { + OrgDepartmentEntity entity = new OrgDepartmentEntity(); + entity.setOrgId(orgId); + entity.setParentId(parentId); + entity.setDeptName(deptName); + OrgDepartmentEntity saved = orgDepartmentGateway.save(entity); + nameMapList.computeIfAbsent(deptName, k -> new ArrayList<>()).add(saved); + LOGGER.info("人员导入自动新增部门, orgId={}, parentId={}, deptName={}, deptId={}" + , orgId, parentId, deptName, saved.getId()); + return saved; + } + + /** + * 三级部门校验并回填:为空跳过;二级部门下不存在同名三级部门时自动新增。 + * + * @param row 当前行 + * @param nameMapList 部门名称索引(key: 部门名称) + * @param l2Dept 二级部门实体 + * @param orgId 机构ID + * @return Pair key 是否通过;value 三级部门实体(无三级部门时为 null) + */ + private Pair getL3(OrgPersonnelImportRow row + , Map> nameMapList, OrgDepartmentEntity l2Dept, Long orgId) { String l3 = row.getBasic().getDeptNameLevel3(); if (StrUtil.isBlank(l3)) { return Pair.of(true, null); @@ -828,40 +850,33 @@ public class OrgPersonnelExcelImporter { // l3 部门查询 List departmentEntities = nameMapList.get(l3); - if (CollectionUtils.isEmpty(departmentEntities)) { - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST.getMessage())); - row.setValidateFail(true); - return Pair.of(false, null); - } - - // 三级部门 - for (OrgDepartmentEntity departmentEntity : departmentEntities) { - if (departmentEntity.getDeptName().equals(l3) - && departmentEntity.getParentId().compareTo(l2Dept.getId()) == 0) { - row.setDeptId(departmentEntity.getId()); - return Pair.of(true, departmentEntity); + if (!CollectionUtils.isEmpty(departmentEntities)) { + for (OrgDepartmentEntity departmentEntity : departmentEntities) { + if (departmentEntity.getDeptName().equals(l3) + && departmentEntity.getParentId().compareTo(l2Dept.getId()) == 0) { + row.setDeptId(departmentEntity.getId()); + return Pair.of(true, departmentEntity); + } } } - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - l2Dept.getDeptName() + "下" - + ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST.getMessage())); - row.setValidateFail(true); - return Pair.of(false, null); + // 二级部门下不存在该三级部门 -> 自动新增 + OrgDepartmentEntity created = createDept(orgId, l2Dept.getId(), l3, nameMapList); + row.setDeptId(created.getId()); + return Pair.of(true, created); } /** + * 二级部门校验并回填:为空跳过;一级部门下不存在同名二级部门时自动新增。 * - * @param errors errors - * @param row row - * @param nameMapList nameMapList - * @param l1Dept l1Dept - * @return Pair key 是否通过 true 通过 false 不通 - * ;value (key =true ,value=null 说明没有二级部门) + * @param row 当前行 + * @param nameMapList 部门名称索引(key: 部门名称) + * @param l1Dept 一级部门实体 + * @param orgId 机构ID + * @return Pair key 是否通过;value 二级部门实体(无二级部门时为 null) */ - private Pair getL2(List errors - , OrgPersonnelImportRow row, Map> nameMapList, OrgDepartmentEntity l1Dept) { + private Pair getL2(OrgPersonnelImportRow row + , Map> nameMapList, OrgDepartmentEntity l1Dept, Long orgId) { String l2 = row.getBasic().getDeptNameLevel2(); if (StrUtil.isBlank(l2)) { return Pair.of(true, null); @@ -869,37 +884,34 @@ public class OrgPersonnelExcelImporter { // l2 部门查询 List departmentEntities = nameMapList.get(l2); - if (CollectionUtils.isEmpty(departmentEntities)) { - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST.getMessage())); - row.setValidateFail(true); - return Pair.of(false, null); - } - - // 二级部门 - for (OrgDepartmentEntity departmentEntity : departmentEntities) { - if (departmentEntity.getDeptName().equals(l2) - && departmentEntity.getParentId().compareTo(l1Dept.getId()) == 0) { - row.setDeptId(departmentEntity.getId()); - return Pair.of(true, departmentEntity); + if (!CollectionUtils.isEmpty(departmentEntities)) { + for (OrgDepartmentEntity departmentEntity : departmentEntities) { + if (departmentEntity.getDeptName().equals(l2) + && departmentEntity.getParentId().compareTo(l1Dept.getId()) == 0) { + row.setDeptId(departmentEntity.getId()); + return Pair.of(true, departmentEntity); + } } } - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - l1Dept.getDeptName() + "下" + ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST.getMessage())); - row.setValidateFail(true); - return Pair.of(false, null); + // 一级部门下不存在该二级部门 -> 自动新增 + OrgDepartmentEntity created = createDept(orgId, l1Dept.getId(), l2, nameMapList); + row.setDeptId(created.getId()); + return Pair.of(true, created); } /** + * 一级部门校验并回填:为空记录异常;机构下不存在同名部门时自动新增(parentId=0 为根); + * 同名部门重复时记录异常(无法确定挂载位置)。 * - * @param errors errors - * @param row row - * @param nameMapList nameMapList - * @return Pair key 是否通过 true 通过 false 不通 + * @param errors 异常收集列表 + * @param row 当前行 + * @param nameMapList 部门名称索引(key: 部门名称) + * @param orgId 机构ID + * @return Pair key 是否通过;value 一级部门实体 */ - private static Pair getL1(List errors, OrgPersonnelImportRow row - , Map> nameMapList) { + private Pair getL1(List errors, OrgPersonnelImportRow row + , Map> nameMapList, Long orgId) { String l1 = row.getBasic().getDeptNameLevel1(); if (StrUtil.isBlank(l1)) { errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), @@ -911,10 +923,10 @@ public class OrgPersonnelExcelImporter { // l1 部门查询 List departmentEntities = nameMapList.get(l1); if (CollectionUtils.isEmpty(departmentEntities)) { - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - ErrorCode.ORG_PERSONNEL_IMPORT_DEPT_L1_NOT_EXIST.getMessage())); - row.setValidateFail(true); - return Pair.of(false, null); + // 机构下不存在该一级部门 -> 自动新增(根节点 parentId=0) + OrgDepartmentEntity created = createDept(orgId, 0L, l1, nameMapList); + row.setDeptId(created.getId()); + return Pair.of(true, created); } // 一级部门重复 @@ -935,8 +947,8 @@ public class OrgPersonnelExcelImporter { } /** - * 批量校验岗位名称在所属部门下是否存在(dept_id + org_id),校验通过的同时回填 postId; - * 岗位名称为空或部门下岗位不存在的行,记录异常并标记 validateFail。 + * 批量校验岗位名称在所属部门下是否存在(dept_id + org_id)并回填 postId; + * 岗位名称为空的行记录异常并标记 validateFail;部门下岗位不存在时自动新增岗位。 */ private void validateAndFillPosition(List rows, Long orgId, List errors) { Set deptIds = new HashSet<>(); @@ -960,7 +972,7 @@ public class OrgPersonnelExcelImporter { } } - // 逐行校验:岗位名称为空或部门下岗位不存在 -> 记录异常并标记;校验通过则回填岗位ID + // 逐行校验:岗位名称为空 -> 记录异常并标记;部门下岗位不存在 -> 自动新增;校验通过则回填岗位ID for (OrgPersonnelImportRow row : rows) { String posName = trim(row.getBasic().getPositionName()); if (!StringUtils.hasText(posName)) { @@ -973,16 +985,33 @@ public class OrgPersonnelExcelImporter { String key = row.getDeptId() + "|" + posName; OrgPositionEntity pos = positionMap.get(key); if (pos == null) { - errors.add(new OrgPersonnelImportErrorCO(row.getBasic().getRowIndex(), row.getBasic().getAccount(), row.getBasic().getUserName(), - ErrorCode.ORG_PERSONNEL_IMPORT_POSITION_NOT_FOUND.getMessage() - + ":" + posName + "(部门:" + row.getDeptDisplayName() + ")")); - row.setValidateFail(true); - continue; + // 部门下岗位不存在 -> 自动新增并放入缓存(同文件同部门同岗位仅创建一次) + pos = createPosition(orgId, row.getDeptId(), posName); + positionMap.put(key, pos); } row.setPostId(pos.getId()); } } + /** + * 新增部门下的岗位。 + * + * @param orgId 机构ID + * @param deptId 部门ID + * @param positionName 岗位名称 + * @return 新增后的岗位实体(含生成的ID) + */ + private OrgPositionEntity createPosition(Long orgId, Long deptId, String positionName) { + OrgPositionEntity entity = new OrgPositionEntity(); + entity.setOrgId(orgId); + entity.setDeptId(deptId); + entity.setPositionName(positionName); + OrgPositionEntity saved = orgPositionGateway.save(entity); + LOGGER.info("人员导入自动新增岗位, orgId={}, deptId={}, positionName={}, postId={}" + , orgId, deptId, positionName, saved.getId()); + return saved; + } + /** * 批量校验 所学专业(major)与 系列/专业(seriesMajor)名称在基础学科专业对照表中是否存在 * (basic_discipline_major.professional_name),两个字段名称合并为一次 in 查询; diff --git a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java index 5ad0c866..6c70da4f 100644 --- a/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java +++ b/safety-eval-domain/src/main/java/org/qinan/safetyeval/domain/exception/ErrorCode.java @@ -42,8 +42,6 @@ public enum ErrorCode { ORG_PERSONNEL_IMPORT_DEPT_NOT_EXIST("01-05-013", "请填写部门名称"), ORG_PERSONNEL_IMPORT_DEPT_L1_NOT_EXIST("01-05-014", "一级部门名称不存在"), ORG_PERSONNEL_IMPORT_DEPT_L1_REPEAT("01-05-015", "一级部门名称查询到多个,请在部门目录去核验"), - ORG_PERSONNEL_IMPORT_DEPT_L2_NOT_EXIST("01-05-016", "二级部门名称不存在"), - ORG_PERSONNEL_IMPORT_DEPT_L3_NOT_EXIST("01-05-017", "三级部门名称不存在"), // ---- 人员证书 ---- ORG_PERSONNEL_CERT_NOT_FOUND("01-06-001", "人员证书不存在"),