diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java index 9992db56..b9942cd7 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/controller/JeecgController.java @@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Field; import java.util.*; +import java.util.function.Function; /** * @Description: Controller基类 @@ -292,36 +293,142 @@ public class JeecgController> { * @param response * @return */ +// protected Result importExcel(HttpServletRequest request, HttpServletResponse response, Class clazz) { +// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; +// Map fileMap = multipartRequest.getFileMap(); +// for (Map.Entry entity : fileMap.entrySet()) { +// // 获取上传文件对象 +// MultipartFile file = entity.getValue(); +// ImportParams params = new ImportParams(); +// params.setTitleRows(2); +// params.setHeadRows(1); +// params.setNeedSave(true); +// try { +// List list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params); +// //update-begin-author:taoyan date:20190528 for:批量插入数据 +// long start = System.currentTimeMillis(); +// service.saveBatch(list); +// //400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒 +// //1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒 +// log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒"); +// //update-end-author:taoyan date:20190528 for:批量插入数据 +// return Result.ok("文件导入成功!数据行数:" + list.size()); +// } catch (Exception e) { +// //update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示 +// String msg = e.getMessage(); +// log.error(msg, e); +// if(msg!=null && msg.indexOf("Duplicate entry")>=0){ +// return Result.error("文件导入失败:有重复数据!"); +// }else{ +// return Result.error("文件导入失败:" + e.getMessage()); +// } +// //update-end-author:taoyan date:20211124 for: 导入数据重复增加提示 +// } finally { +// try { +// file.getInputStream().close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// return Result.error("文件导入失败!"); +// } protected Result importExcel(HttpServletRequest request, HttpServletResponse response, Class clazz) { MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { - // 获取上传文件对象 MultipartFile file = entity.getValue(); ImportParams params = new ImportParams(); params.setTitleRows(2); params.setHeadRows(1); params.setNeedSave(true); + try { List list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params); - //update-begin-author:taoyan date:20190528 for:批量插入数据 + + // === 加密敏感字段 === + for (T item : list) { + try { + // 银行卡字段加密 + Field pyCardField = null; + try { + pyCardField = item.getClass().getDeclaredField("pyCard"); + } catch (NoSuchFieldException ignored) {} + if (pyCardField != null) { + pyCardField.setAccessible(true); + String value = (String) pyCardField.get(item); + if (value != null && !value.isEmpty()) { + String encryptedValue = JasyptUtil.encrypt(value, "bigdata"); + pyCardField.set(item, encryptedValue); + } + } + + // 身份证字段加密 + Field identityIdField = null; + try { + identityIdField = item.getClass().getDeclaredField("identityId"); + } catch (NoSuchFieldException ignored) {} + if (identityIdField != null) { + identityIdField.setAccessible(true); + String value = (String) identityIdField.get(item); + if (value != null && !value.isEmpty()) { + String encryptedValue = JasyptUtil.encrypt(value, "bigdata"); + identityIdField.set(item, encryptedValue); + } + } + + // ===== 状态描述反向映射 ===== + + // 性别反向映射 + applyReverseMapping(item, "sexDescription", "sex", StatusMappingUtil::reverseMapSex); + + // 车辆状态反向映射 + applyReverseMapping(item, "carStatusDescription", "carStatus", StatusMappingUtil::reverseMapCarStatus); + + // 住宿状态反向映射 + applyReverseMapping(item, "dormitoryStatusDescription", "dormitoryStatus", StatusMappingUtil::reverseMapDormitoryStatus); + + // 一般状态反向映射 + applyReverseMapping(item, "statusDescription", "status", StatusMappingUtil::reverseMapStatus); + + // 宿舍名称反查 ID +// Field dormNameField = getField(item, "dormitoryName"); +// Field dormIdField = getField(item, "dormitoryId"); +// if (dormNameField != null && dormIdField != null) { +// String dormName = (String) dormNameField.get(item); +// if (dormName != null && !dormName.isEmpty()) { +// dormIdField.set(item, nameResolverService.getDormitoryId(dormName)); +// } +// } +// +// // 组名称反查 ID +// Field groupNameField = getField(item, "groupName"); +// Field groupIdField = getField(item, "groupId"); +// if (groupNameField != null && groupIdField != null) { +// String groupName = (String) groupNameField.get(item); +// if (groupName != null && !groupName.isEmpty()) { +// groupIdField.set(item, nameResolverService.getGroupId(groupName)); +// } +// } + } catch (IllegalAccessException e) { + throw new RuntimeException("加密字段处理失败", e); + } + } + long start = System.currentTimeMillis(); service.saveBatch(list); - //400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒 - //1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒 log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒"); - //update-end-author:taoyan date:20190528 for:批量插入数据 + return Result.ok("文件导入成功!数据行数:" + list.size()); } catch (Exception e) { - //update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示 String msg = e.getMessage(); log.error(msg, e); - if(msg!=null && msg.indexOf("Duplicate entry")>=0){ + if (msg != null && msg.contains("Duplicate entry")) { return Result.error("文件导入失败:有重复数据!"); - }else{ - return Result.error("文件导入失败:" + e.getMessage()); + } else { + return Result.error("文件导入失败:" + msg); } - //update-end-author:taoyan date:20211124 for: 导入数据重复增加提示 } finally { try { file.getInputStream().close(); @@ -332,4 +439,28 @@ public class JeecgController> { } return Result.error("文件导入失败!"); } + + private Field getField(Object obj, String fieldName) { + try { + Field field = obj.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return field; + } catch (NoSuchFieldException e) { + return null; + } + } + + private void applyReverseMapping(Object item, String descFieldName, String codeFieldName, Function mapper) throws IllegalAccessException { + Field descField = getField(item, descFieldName); + Field codeField = getField(item, codeFieldName); + if (descField != null && codeField != null) { + String desc = (String) descField.get(item); + if (desc != null && !desc.isEmpty()) { + Integer code = mapper.apply(desc); + codeField.set(item, code); + } + } + } + + } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/NameResolverService.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/NameResolverService.java index bfa87e7a..e2b01518 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/NameResolverService.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/base/service/NameResolverService.java @@ -3,4 +3,8 @@ package org.jeecg.common.system.base.service; public interface NameResolverService { String getDormitoryName(String dormitoryId); String getGroupName(String groupId); + + Object getDormitoryId(String dormName); + + Object getGroupId(String groupName); } diff --git a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/StatusMappingUtil.java b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/StatusMappingUtil.java index b3a8780e..912fd9d7 100644 --- a/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/StatusMappingUtil.java +++ b/jeecg-boot-base-core/src/main/java/org/jeecg/common/system/util/StatusMappingUtil.java @@ -24,4 +24,30 @@ public class StatusMappingUtil { if (status == null) return ""; return status == 0 ? "已报到" : "未报到"; } + +// ===== 反向映射 ===== + + public static Integer reverseMapSex(String desc) { + if ("男".equals(desc)) return 0; + if ("女".equals(desc)) return 1; + return null; + } + + public static Integer reverseMapCarStatus(String desc) { + if ("是".equals(desc)) return 1; + if ("否".equals(desc)) return 0; + return null; + } + + public static Integer reverseMapDormitoryStatus(String desc) { + if ("是".equals(desc)) return 1; + if ("否".equals(desc)) return 0; + return null; + } + + public static Integer reverseMapStatus(String desc) { + if ("已报到".equals(desc)) return 0; + if ("未报到".equals(desc)) return 1; + return null; + } } diff --git a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/CeesWaiTeacherServiceImpl.java b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/CeesWaiTeacherServiceImpl.java index 9fe069a8..d98d3762 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/CeesWaiTeacherServiceImpl.java +++ b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/CeesWaiTeacherServiceImpl.java @@ -412,18 +412,18 @@ public class CeesWaiTeacherServiceImpl extends ServiceImpl allTeachers = ceesWaiTeacherMapper.selectList(null); - Set usedCards = allTeachers.stream() - .map(CeesWaiTeacher::getMealCard) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - // 获取已存在 mealCard 的用户 ID - Set alreadyHasCardIds = allTeachers.stream() + Map teacherIdToCard = allTeachers.stream() .filter(t -> t.getMealCard() != null && !t.getMealCard().trim().isEmpty()) - .map(CeesWaiTeacher::getId) - .collect(Collectors.toSet()); + .collect(Collectors.toMap(CeesWaiTeacher::getId, CeesWaiTeacher::getMealCard)); + + // 卡号 -> 人员ID 的映射,方便夺卡 + Map cardToTeacherId = allTeachers.stream() + .filter(t -> t.getMealCard() != null && !t.getMealCard().trim().isEmpty()) + .collect(Collectors.toMap(CeesWaiTeacher::getMealCard, CeesWaiTeacher::getId)); + + Set usedCards = new HashSet<>(cardToTeacherId.keySet()); int totalUpdatedLocal = 0; List failedIdsLocal = new ArrayList<>(); @@ -432,35 +432,44 @@ public class CeesWaiTeacherServiceImpl extends ServiceImpl updateWrapper = new LambdaUpdateWrapper<>(); - updateWrapper.eq(CeesWaiTeacher::getId, id) - .set(CeesWaiTeacher::getMealCard, formattedCard); - int affectedRows = ceesWaiTeacherMapper.update(null, updateWrapper); - if (affectedRows > 0) { - totalUpdatedLocal++; - usedCards.add(formattedCard); - assigned = true; - } - } catch (Exception e) { - // 忽略异常,进入失败处理 + // 如果已被占用,则从原用户手中夺取 + if (usedCards.contains(formattedCard)) { + String previousHolderId = cardToTeacherId.get(formattedCard); + if (!Objects.equals(previousHolderId, id)) { + // 夺卡逻辑:把旧用户的卡号置空 + LambdaUpdateWrapper clearWrapper = new LambdaUpdateWrapper<>(); + clearWrapper.eq(CeesWaiTeacher::getId, previousHolderId) + .set(CeesWaiTeacher::getMealCard, null); + ceesWaiTeacherMapper.update(null, clearWrapper); + usedCards.remove(formattedCard); + cardToTeacherId.remove(formattedCard); } - currentCard++; - break; } + + try { + // 分配卡号给当前用户(无论其是否已有) + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.eq(CeesWaiTeacher::getId, id) + .set(CeesWaiTeacher::getMealCard, formattedCard); + + int affectedRows = ceesWaiTeacherMapper.update(null, updateWrapper); + if (affectedRows > 0) { + totalUpdatedLocal++; + usedCards.add(formattedCard); + cardToTeacherId.put(formattedCard, id); + assigned = true; + } + } catch (Exception e) { + // 异常处理 + } + currentCard++; + break; // 成功或失败后跳出当前循环 } if (!assigned) { diff --git a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/NameResolverImpl.java b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/NameResolverImpl.java index eff1bc5d..42c315a7 100644 --- a/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/NameResolverImpl.java +++ b/jeecg-module-system/jeecg-system-start/src/main/java/org/jeecg/modules/service/impl/NameResolverImpl.java @@ -32,4 +32,14 @@ public class NameResolverImpl implements NameResolverService { CeesGroup group = groupService.getById(groupId); return group != null ? group.getName() : ""; } + + @Override + public Object getDormitoryId(String dormName) { + return null; + } + + @Override + public Object getGroupId(String groupName) { + return null; + } }