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 7e4dc6dc..19041028 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 @@ -208,7 +208,7 @@ public class OrgPersonnelExcelImporter { /** * 解析 Excel:分别读取 sheet1「专职人员基础信息」与 sheet2「专职人员能力信息」, - * 能力信息按 身份证号(为空时按姓名) 关联到基础信息行; + * 能力信息按 身份证号 关联到基础信息行(未匹配或多条均记录异常并剔除该行); * 过滤空行并回填物理行号(从1开始,含表头,首条数据为第2行)。 *

* 文件内手机号重复的行在此剔除,并生成提示放入 errors(空账号不参与去重)。 @@ -238,7 +238,7 @@ public class OrgPersonnelExcelImporter { return new ArrayList<>(); } - Map capabilityMap = indexCapabilityRows(capabilityRaw); + Map> capabilityMap = indexCapabilityRows(capabilityRaw); List rows = new ArrayList<>(basicRaw.size()); Set seenAccounts = new HashSet<>(); @@ -254,7 +254,11 @@ public class OrgPersonnelExcelImporter { OrgPersonnelImportRow row = new OrgPersonnelImportRow(); basic.setRowIndex(i + 2); row.setBasic(basic); - row.setCapability(matchCapability(basic, capabilityMap)); + row.setCapability(matchCapability(basic, capabilityMap, errors)); + // 能力信息未匹配或存在多条,已记录异常,剔除该行 + if (row.getCapability() == null) { + continue; + } // 字段校验:JSR-303 注解(必填、长度、手机号格式)+ 身份证号 if (!validateRowFields(row, errors)) { @@ -270,11 +274,11 @@ public class OrgPersonnelExcelImporter { } /** - * sheet2 能力信息建立索引:优先身份证号,身份证号为空时按姓名;重复时保留首条并告警。 + * sheet2 能力信息建立索引:按身份证号分组。 */ - private Map indexCapabilityRows( + private Map> indexCapabilityRows( List capabilityRaw) { - Map map = new LinkedHashMap<>(); + Map> map = new LinkedHashMap<>(); if (capabilityRaw == null || capabilityRaw.isEmpty()) { return map; } @@ -289,39 +293,30 @@ public class OrgPersonnelExcelImporter { continue; } capability.setRowIndex(i + 2); - String key = capabilityKey(capability.getIdCardNo(), capability.getUserName()); - if (map.putIfAbsent(key, capability) != null) { - LOGGER.warn("人员导入能力信息重复,key={},sheet2行号={},仅保留首条", key, capability.getRowIndex()); - } + map.computeIfAbsent(trim(capability.getIdCardNo()), k -> new ArrayList<>()).add(capability); } return map; } /** - * 基础信息行匹配能力信息:优先身份证号,其次姓名;未匹配返回 null。 + * 基础信息行按身份证号匹配能力信息: + * 未匹配到或多条均记录异常并返回 null,仅唯一匹配时返回该行。 */ private OrgPersonnelImportRow.CapabilityRow matchCapability(OrgPersonnelImportRow.BasicRow basic, - Map capabilityMap) { - if (capabilityMap.isEmpty()) { + 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; } - OrgPersonnelImportRow.CapabilityRow capability = - capabilityMap.get(capabilityKey(basic.getIdCardNo(), null)); - if (capability != null) { - return capability; + if (capabilityList.size() > 1) { + errors.add(new OrgPersonnelImportErrorCO(basic.getRowIndex(), trim(basic.getAccount()), trim(basic.getUserName()), + "专职人员能力信息中查询到多条数据")); + return null; } - return capabilityMap.get(capabilityKey(null, basic.getUserName())); - } - - /** - * 能力信息索引键:身份证号优先(前缀 ID:),为空时使用姓名(前缀 NAME:)。 - */ - private String capabilityKey(String idCardNo, String userName) { - String idCard = trim(idCardNo); - if (StringUtils.hasText(idCard)) { - return "ID:" + idCard; - } - return "NAME:" + trim(userName); + return capabilityList.get(0); } /**