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:
*
- * - 名称在机构下不存在的部门视为异常;
- * - 任一相邻层级的 parentId 关系不匹配视为异常;
+ * - 名称在机构下不存在(或上级部门下不存在同名子部门)-> 自动新增该部门;
+ * - 一级部门名称在机构下重复 -> 视为异常(无法确定挂载位置);
* - 全部校验通过后,取最底层(最深一级)不为空的部门 ID 作为 deptId 回填。
*
*/
@@ -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", "人员证书不存在"),