更改批量设置mealcard逻辑、导入数据加密、数据映射
This commit is contained in:
parent
2770ff5cf9
commit
49dddc4aaf
|
@ -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<T, S extends IService<T>> {
|
|||
* @param response
|
||||
* @return
|
||||
*/
|
||||
// protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
|
||||
// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
// Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
// for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// // 获取上传文件对象
|
||||
// MultipartFile file = entity.getValue();
|
||||
// ImportParams params = new ImportParams();
|
||||
// params.setTitleRows(2);
|
||||
// params.setHeadRows(1);
|
||||
// params.setNeedSave(true);
|
||||
// try {
|
||||
// List<T> 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<T> clazz) {
|
||||
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
|
||||
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
|
||||
|
||||
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
|
||||
// 获取上传文件对象
|
||||
MultipartFile file = entity.getValue();
|
||||
ImportParams params = new ImportParams();
|
||||
params.setTitleRows(2);
|
||||
params.setHeadRows(1);
|
||||
params.setNeedSave(true);
|
||||
|
||||
try {
|
||||
List<T> 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());
|
||||
return Result.error("文件导入失败:" + msg);
|
||||
}
|
||||
//update-end-author:taoyan date:20211124 for: 导入数据重复增加提示
|
||||
} finally {
|
||||
try {
|
||||
file.getInputStream().close();
|
||||
|
@ -332,4 +439,28 @@ public class JeecgController<T, S extends IService<T>> {
|
|||
}
|
||||
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<String, Integer> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -412,18 +412,18 @@ public class CeesWaiTeacherServiceImpl extends ServiceImpl<CeesWaiTeacherMapper,
|
|||
throw new IllegalArgumentException("max 参数类型错误");
|
||||
}
|
||||
|
||||
// 获取所有已有的 mealCard,构建占用集合
|
||||
// 获取所有已有的 mealCard 数据
|
||||
List<CeesWaiTeacher> allTeachers = ceesWaiTeacherMapper.selectList(null);
|
||||
Set<String> usedCards = allTeachers.stream()
|
||||
.map(CeesWaiTeacher::getMealCard)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 获取已存在 mealCard 的用户 ID
|
||||
Set<String> alreadyHasCardIds = allTeachers.stream()
|
||||
Map<String, String> 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<String, String> cardToTeacherId = allTeachers.stream()
|
||||
.filter(t -> t.getMealCard() != null && !t.getMealCard().trim().isEmpty())
|
||||
.collect(Collectors.toMap(CeesWaiTeacher::getMealCard, CeesWaiTeacher::getId));
|
||||
|
||||
Set<String> usedCards = new HashSet<>(cardToTeacherId.keySet());
|
||||
|
||||
int totalUpdatedLocal = 0;
|
||||
List<String> failedIdsLocal = new ArrayList<>();
|
||||
|
@ -432,18 +432,27 @@ public class CeesWaiTeacherServiceImpl extends ServiceImpl<CeesWaiTeacherMapper,
|
|||
int currentCard = min;
|
||||
|
||||
for (String id : ids) {
|
||||
// 如果用户已有 mealCard,跳过
|
||||
if (alreadyHasCardIds.contains(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean assigned = false;
|
||||
|
||||
// 查找下一个未被占用的卡号
|
||||
while (currentCard <= max) {
|
||||
String formattedCard = String.format("%03d", currentCard);
|
||||
if (!usedCards.contains(formattedCard)) {
|
||||
|
||||
// 如果已被占用,则从原用户手中夺取
|
||||
if (usedCards.contains(formattedCard)) {
|
||||
String previousHolderId = cardToTeacherId.get(formattedCard);
|
||||
if (!Objects.equals(previousHolderId, id)) {
|
||||
// 夺卡逻辑:把旧用户的卡号置空
|
||||
LambdaUpdateWrapper<CeesWaiTeacher> clearWrapper = new LambdaUpdateWrapper<>();
|
||||
clearWrapper.eq(CeesWaiTeacher::getId, previousHolderId)
|
||||
.set(CeesWaiTeacher::getMealCard, null);
|
||||
ceesWaiTeacherMapper.update(null, clearWrapper);
|
||||
usedCards.remove(formattedCard);
|
||||
cardToTeacherId.remove(formattedCard);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// 分配卡号给当前用户(无论其是否已有)
|
||||
LambdaUpdateWrapper<CeesWaiTeacher> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(CeesWaiTeacher::getId, id)
|
||||
.set(CeesWaiTeacher::getMealCard, formattedCard);
|
||||
|
@ -452,15 +461,15 @@ public class CeesWaiTeacherServiceImpl extends ServiceImpl<CeesWaiTeacherMapper,
|
|||
if (affectedRows > 0) {
|
||||
totalUpdatedLocal++;
|
||||
usedCards.add(formattedCard);
|
||||
cardToTeacherId.put(formattedCard, id);
|
||||
assigned = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// 忽略异常,进入失败处理
|
||||
}
|
||||
currentCard++;
|
||||
break;
|
||||
// 异常处理
|
||||
}
|
||||
|
||||
currentCard++;
|
||||
break; // 成功或失败后跳出当前循环
|
||||
}
|
||||
|
||||
if (!assigned) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue