|
|
@ -75,10 +75,17 @@ import java.util.stream.Collectors; |
|
|
|
@Service |
|
|
|
public class IcResiUserImportServiceImpl implements IcResiUserImportService, ResultDataResolver { |
|
|
|
|
|
|
|
public static final List<String> controlGroup1 = Arrays.asList("input", "textarea", "datepicker", "daterange"); |
|
|
|
public static final List<String> 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<Map<String, List<ErrorRow>>> errorRows = new ThreadLocal<>(); |
|
|
@ -163,9 +170,9 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res |
|
|
|
private Integer required; |
|
|
|
private List<Integer> colIndex; |
|
|
|
//private List<String> 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<String, String> 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<String, ColumnWrapper> itemIdAndColumnWrappers, Map<Integer, String> row, |
|
|
|
private void convertColumnWrappers2Map4Persist(Map<String, ColumnWrapper> dbMetadataItemIdAndColumnWrappers, Map<Integer, String> row, |
|
|
|
String currUserAgencyId, Map<Integer, String> checkBoxOptionColumnIdxAndLabel, |
|
|
|
LinkedHashMap<String, String> target, boolean isPrimaryTable) { |
|
|
|
LinkedHashMap<String, String> target2Insert, boolean isPrimaryTable) { |
|
|
|
|
|
|
|
boolean interupt = false; |
|
|
|
// 本行中是否有必填但未填,或者填了但填错了系统中找不到的列,那后面的数据可能就没办法通过前面填写的值去关联查询,因此只做必填检查,提示出来就行了,仁至义尽
|
|
|
|
boolean hasError = false; |
|
|
|
|
|
|
|
List<String> errorColumnNames = new LinkedList<>(); |
|
|
|
String notFoundColumnName = null; |
|
|
|
List<String> emptyColumnNames = new ArrayList<>(); |
|
|
|
|
|
|
|
for (Map.Entry<String, ColumnWrapper> 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<String, ColumnWrapper> 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<String, String> options = columnWrapper.getOptions(); |
|
|
|
String colValue = options.get(cellContent); |
|
|
|
Map<String, String> 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<String, Map<String, String>> superOptions = itemIdAndOptionsCache.getIfPresent(itemId); |
|
|
|
// 通过接口调用,计算出colValue,放到columnWrapper中
|
|
|
|
Map<String, Map<String, String>> superOptions = itemIdAndOptionsCache.getIfPresent(currentItemId); |
|
|
|
if (superOptions != null && superOptions.size() > 0) { |
|
|
|
Map<String, String> options = superOptions.get(superColumValue); |
|
|
|
Map<String, String> 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<String, String> options = listRemoteOptions(pureUri, superItemId, itemIdAndColumnWrappers, currUserAgencyId, "saveorupdate"); |
|
|
|
// 父item的options。例如当前遍历的是小区列,那查出来的就是网格下的小区
|
|
|
|
// 然后把 <currentItemId:<superItem:usperOptions>> 放到缓存里
|
|
|
|
Map<String, String> 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; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|