diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java index 722fb93cd2..ee23c3f7d1 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java @@ -75,10 +75,17 @@ import java.util.stream.Collectors; @Service public class IcResiUserImportServiceImpl implements IcResiUserImportService, ResultDataResolver { + public static final List controlGroup1 = Arrays.asList("input", "textarea", "datepicker", "daterange"); + public static final List controlGroup2 = Arrays.asList("select", "radio"); + /** * 身份证号列序号 */ public static final Integer ID_CARD_COLUMN_NO = 9; + /** + * 姓名列序号 + */ + public static final Integer ID_NAME_COLUMN_NO = 6; // 错误和跳过excel行暂存 public static final ThreadLocal>> errorRows = new ThreadLocal<>(); @@ -163,9 +170,9 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res private Integer required; private List colIndex; //private List colContents; - // 单元格内容 + // 单元格内容。多选框没有该列,因为多选框对应着excel的多列 private String cellContent; - // 数据库中列的值 + // 单元格内容对应的数据库中值 private String colValue; // key:label,value:value @@ -425,11 +432,10 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res try { convertColumnWrappers2Map4Persist(itemIdAndColumnWrapper, row, currUserAgencyId, checkBoxOptionColumnIdxAndLabel, columnAndValues, true); - String idCard = columnAndValues.get("ID_CARD"); - // 执行指定的检查 specifiedCheck(columnAndValues); + String idCard = columnAndValues.get("ID_CARD"); Map existingResiMap = icResiUserDao.selectResiInfoMap(idCard, null); if (existingResiMap == null) { @@ -596,7 +602,7 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res if (resiName == null) { resiName = ""; } - throw new RenException(EpmetErrorCode.IDCARDNO_ERROR.getCode(), String.format("用户【%s】身份证号未填写或格式错误", resiName)); + throw new RenException(EpmetErrorCode.IDCARDNO_ERROR.getCode(), String.format("居民【%s】身份证号未填写或格式错误", resiName)); } // 检查用户是否存在 @@ -719,111 +725,195 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res /** * 将当前行数据转化成LinkedHashMap,供后续插入 - * @param itemIdAndColumnWrappers 当前行的ColumnWrapper,每一个ColumnWrapper元素都是当前行中的一个列,key:itemId + * @param dbMetadataItemIdAndColumnWrappers 当前行的ColumnWrapper,每一条都是数据库中的一个列的源数据,对应到excel中可能是多个列(多选)。每一个ColumnWrapper元素都是当前行中的一个列,key:itemId * @param row 当前行数据 * @param currUserAgencyId 当前用户所属机构ID * @param checkBoxOptionColumnIdxAndLabel 复选框options列表。key:列号,value:复选框中文 - * @param target 要将数据放到哪个对象中 + * @param target2Insert 要用来insert到db的数据 * @param isPrimaryTable 是否是主表 */ - private void convertColumnWrappers2Map4Persist(Map itemIdAndColumnWrappers, Map row, + private void convertColumnWrappers2Map4Persist(Map dbMetadataItemIdAndColumnWrappers, Map row, String currUserAgencyId, Map checkBoxOptionColumnIdxAndLabel, - LinkedHashMap target, boolean isPrimaryTable) { + LinkedHashMap target2Insert, boolean isPrimaryTable) { - boolean interupt = false; + // 本行中是否有必填但未填,或者填了但填错了系统中找不到的列,那后面的数据可能就没办法通过前面填写的值去关联查询,因此只做必填检查,提示出来就行了,仁至义尽 + boolean hasError = false; - List errorColumnNames = new LinkedList<>(); + String notFoundColumnName = null; + List emptyColumnNames = new ArrayList<>(); - for (Map.Entry itemIdAndColumnWrapper : itemIdAndColumnWrappers.entrySet()) { + // 这两列要提前放进去,因为有的列未填写的话,会抛异常出去,需要用这两列来做描述 + target2Insert.put("ID_CARD", row.get(ID_CARD_COLUMN_NO)); + target2Insert.put("NAME", row.get(ID_NAME_COLUMN_NO)); - String itemId = itemIdAndColumnWrapper.getKey(); - ColumnWrapper columnWrapper = itemIdAndColumnWrapper.getValue(); + for (Map.Entry dbColumnMetadata : dbMetadataItemIdAndColumnWrappers.entrySet()) { - if ("input".equals(columnWrapper.getItemType()) - || "textarea".equals(columnWrapper.getItemType()) - || "datepicker".equals(columnWrapper.getItemType()) - || "daterange".equals(columnWrapper.getItemType()) - ) { + String currentItemId = dbColumnMetadata.getKey(); + ColumnWrapper columnWrapper = dbColumnMetadata.getValue(); + // "input", "textarea", "datepicker", "daterange" + if (controlGroup1.contains(columnWrapper.getItemType())) { + + // 输入的控件,不会横跨多个单元格,所以只取一列就可以了 String cellContent = row.get(columnWrapper.getColIndex().get(0)); + columnWrapper.setCellContent(cellContent); columnWrapper.setColValue(cellContent); - } else if ("select".equals(columnWrapper.getItemType()) - || "radio".equals(columnWrapper.getItemType())){ + // 必填检查 + boolean hasEmptyError = requiredButEmptyCheck(isPrimaryTable, columnWrapper); + if (hasEmptyError) { + emptyColumnNames.add(columnWrapper.combinedLabel); + hasError = true; + continue; + } + + if (hasError) { + continue; + } + + // "select", "radio" + } else if (controlGroup2.contains(columnWrapper.getItemType())){ - String optionSourceType = columnWrapper.getOptionSourceType(); // 取单元格的内容 String cellContent = row.get(columnWrapper.getColIndex().get(0)); columnWrapper.setCellContent(cellContent); - if ("local".equals(optionSourceType)) { + // 必填检查 + boolean hasEmptyError = requiredButEmptyCheck(isPrimaryTable, columnWrapper); + if (hasEmptyError) { + emptyColumnNames.add(columnWrapper.combinedLabel); + hasError = true; + continue; + } + + if (hasError) { + continue; + } + + if ("local".equals(columnWrapper.getOptionSourceType())) { // 根据单元格内容,取到指定的option - Map options = columnWrapper.getOptions(); - String colValue = options.get(cellContent); + Map itemOptions = columnWrapper.getOptions(); + String colValue = itemOptions.get(cellContent); columnWrapper.setColValue(colValue); } else { - // remote类型。优先从缓存取 String fullUri = columnWrapper.getOptionSourceValue(); String[] uriParts = splitOptionSourceUrl(fullUri); String pureUri = uriParts[0]; String superItemId = uriParts[1]; - String superColumValue; + String superColumnValue; + // 获取父item的值 if (StringUtils.isNotBlank(superItemId)) { - superColumValue = itemIdAndColumnWrappers.get(superItemId).getColValue(); + superColumnValue = dbMetadataItemIdAndColumnWrappers.get(superItemId).getColValue(); } else { - superColumValue = "-"; + superColumnValue = "-"; } - Map> superOptions = itemIdAndOptionsCache.getIfPresent(itemId); + // 通过接口调用,计算出colValue,放到columnWrapper中 + Map> superOptions = itemIdAndOptionsCache.getIfPresent(currentItemId); if (superOptions != null && superOptions.size() > 0) { - Map options = superOptions.get(superColumValue); + Map options = superOptions.get(superColumnValue); if (options == null || options.size() == 0) { - options = listRemoteOptions(pureUri, superItemId, itemIdAndColumnWrappers, currUserAgencyId, "saveorupdate"); - superOptions.put(superColumValue, options); + options = listRemoteOptions(pureUri, superItemId, dbMetadataItemIdAndColumnWrappers, currUserAgencyId, "saveorupdate"); + superOptions.put(superColumnValue, options); } String colValue = options.get(cellContent); columnWrapper.setColValue(colValue); } else { - Map options = listRemoteOptions(pureUri, superItemId, itemIdAndColumnWrappers, currUserAgencyId, "saveorupdate"); + // 父item的options。例如当前遍历的是小区列,那查出来的就是网格下的小区 + // 然后把 > 放到缓存里 + Map options = listRemoteOptions(pureUri, superItemId, dbMetadataItemIdAndColumnWrappers, currUserAgencyId, "saveorupdate"); superOptions = new HashMap<>(); - superOptions.put(superColumValue, options); - itemIdAndOptionsCache.put(itemId, superOptions); + superOptions.put(superColumnValue, options); + itemIdAndOptionsCache.put(currentItemId, superOptions); String colValue = options.get(cellContent); columnWrapper.setColValue(colValue); } } } else if ("checkbox".equals(columnWrapper.getItemType())) { + //多选框没有具体的cellContent,因为多选框对应着excel的多列。并且复选框,为空就是否,所以不需要做必填检查 String checkBoxColValue = getCheckBoxColValue(columnWrapper, row, checkBoxOptionColumnIdxAndLabel); columnWrapper.setColValue(checkBoxColValue); - } - // requiredColumns中的值不在排除字段中 && 是必填 && 未填写 - if (isPrimaryTable) { - // 主表没有需要排除的列 - if (columnWrapper.getRequired() == 1 && StringUtils.isBlank(columnWrapper.colValue)) { - interupt = true; - errorColumnNames.add(columnWrapper.combinedLabel); - } - } else { - // 从表需要排除掉一些不必要校验的列 - if (!subTableNeedlessColumns.contains(columnWrapper.columnName) - && columnWrapper.getRequired() == 1 - && StringUtils.isBlank(columnWrapper.colValue)) { - interupt = true; - errorColumnNames.add(columnWrapper.combinedLabel); + if (hasError) { + continue; } } - target.put(columnWrapper.columnName, columnWrapper.colValue); + // 填了,但找不到对应数据的检查 + boolean hasNotFoundError = notFoundCheck(isPrimaryTable, columnWrapper); + if (hasNotFoundError) { + notFoundColumnName = columnWrapper.combinedLabel; + hasError = true; + } + + target2Insert.put(columnWrapper.columnName, columnWrapper.colValue); + } + + if (hasError) { + StringBuilder sb = new StringBuilder(); + + // 组织报错信息 + if (CollectionUtils.isNotEmpty(emptyColumnNames)) { + sb.append(String.join(",", emptyColumnNames)).append("的值未填写;"); + } + + if (StringUtils.isNotBlank(notFoundColumnName)) { + sb.append(notFoundColumnName).append("填写的值在系统中未找到"); + } + + throw new EpmetException(sb.toString()); + } + } + + /** + * 必填,但是用户没填的,放到list中 + * @param isPrimaryTable 是否是主表。true:是主表,false:从表 + * @param columnWrapper 数据库列包装对象 + */ + public boolean requiredButEmptyCheck(Boolean isPrimaryTable, ColumnWrapper columnWrapper) { + // requiredColumns中的值不在排除字段中 && 是必填 && 未填写 + if (isPrimaryTable) { + // 主表没有需要排除的列 + if (columnWrapper.getRequired() == 1 && StringUtils.isBlank(columnWrapper.cellContent)) { + return true; + } + } else { + // 从表需要排除掉一些不必要校验的列 + if (!subTableNeedlessColumns.contains(columnWrapper.columnName) + && columnWrapper.getRequired() == 1 + && StringUtils.isBlank(columnWrapper.cellContent)) { + return true; + } } - if (interupt) { - throw new RenException(String.join(",", errorColumnNames) + "的值未填写,或者所填写信息在系统中未找到"); + return false; + } + + /** + * 必填,并且在系统中没找到值的,放到list中 + * @param isPrimaryTable 是否是主表。true:是主表,false:从表 + * @param columnWrapper 数据库列包装对象 + */ + public boolean notFoundCheck(Boolean isPrimaryTable, ColumnWrapper columnWrapper) { + // requiredColumns中的值不在排除字段中 && 是必填 && 未填写 + if (isPrimaryTable) { + // 主表没有需要排除的列 + if (columnWrapper.getRequired() == 1 && StringUtils.isBlank(columnWrapper.colValue)) { + return true; + } + } else { + // 从表需要排除掉一些不必要校验的列 + if (!subTableNeedlessColumns.contains(columnWrapper.columnName) + && columnWrapper.getRequired() == 1 + && StringUtils.isBlank(columnWrapper.colValue)) { + return true; + } } + return false; } /**