|
@ -293,6 +293,8 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U |
|
|
@Override |
|
|
@Override |
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
@Transactional(rollbackFor = Exception.class) |
|
|
public Result importFixUsers(MultipartFile file, Long gradeId) { |
|
|
public Result importFixUsers(MultipartFile file, Long gradeId) { |
|
|
|
|
|
//// |
|
|
|
|
|
// |
|
|
// try { |
|
|
// try { |
|
|
// // 1. 解析Excel |
|
|
// // 1. 解析Excel |
|
|
// List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream()) |
|
|
// List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream()) |
|
@ -300,134 +302,71 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U |
|
|
// .sheet() |
|
|
// .sheet() |
|
|
// .doReadSync(); |
|
|
// .doReadSync(); |
|
|
// |
|
|
// |
|
|
// // 2. 准备数据集合 |
|
|
|
|
|
// List<User> newUsers = new ArrayList<>(); // 需要新增到user表的用户 |
|
|
|
|
|
// List<User> usersToRecover = new ArrayList<>(); // 需要恢复的已删除用户 |
|
|
|
|
|
// List<UserDetail> newUserDetails = new ArrayList<>(); // 新增的userDetail |
|
|
|
|
|
// List<UserDetail> detailsToRecover = new ArrayList<>(); // 需要恢复的userDetail |
|
|
|
|
|
// |
|
|
|
|
|
// Set<String> processedCodes = new HashSet<>(); |
|
|
|
|
|
// int successCount = 0; |
|
|
// int successCount = 0; |
|
|
// int skipCount = 0; |
|
|
// int skipCount = 0; |
|
|
// |
|
|
|
|
|
// // 3. 查询所有已存在的jwcode(user表) |
|
|
|
|
|
// Set<String> existingJwCodes = adminUserMapper.selectAllUserCodes(); |
|
|
|
|
|
// |
|
|
|
|
|
// // 4. 查询所有已存在的user_detail记录(避免N+1查询) |
|
|
|
|
|
// Map<String, UserDetail> existingDetails = adminUserDetailMapper.selectList(null) |
|
|
|
|
|
// .stream() |
|
|
|
|
|
// .collect(Collectors.toMap( |
|
|
|
|
|
// detail -> adminUserMapper.selectById(detail.getUserId()).getJwcode(), |
|
|
|
|
|
// detail -> detail |
|
|
|
|
|
// )); |
|
|
|
|
|
|
|
|
// Set<String> processedCodes = new HashSet<>(); |
|
|
// |
|
|
// |
|
|
// for (int i = 0; i < userDtos.size(); i++) { |
|
|
// for (int i = 0; i < userDtos.size(); i++) { |
|
|
// UserImportDto dto = userDtos.get(i); |
|
|
// UserImportDto dto = userDtos.get(i); |
|
|
// try { |
|
|
// try { |
|
|
// validateUser(dto, i + 2, processedCodes); |
|
|
// validateUser(dto, i + 2, processedCodes); |
|
|
|
|
|
// processedCodes.add(dto.getJwcode()); |
|
|
// |
|
|
// |
|
|
// // 检查是否已在当前文件中处理过 |
|
|
|
|
|
// if (processedCodes.contains(dto.getJwcode())) { |
|
|
|
|
|
// throw new IllegalArgumentException("精网号在当前文件中重复: " + dto.getJwcode()); |
|
|
|
|
|
|
|
|
// // 2. 查询用户是否存在(按jwcode) |
|
|
|
|
|
// User user = adminUserMapper.selectUserByJwcode(dto.getJwcode()); |
|
|
|
|
|
// if (user == null) { |
|
|
|
|
|
// // 新增用户 |
|
|
|
|
|
// user = convertToEntity(dto); |
|
|
|
|
|
// adminUserMapper.insert(user); |
|
|
|
|
|
// } else if (user.getIsDel() == 1) { |
|
|
|
|
|
// // 恢复已删除用户 |
|
|
|
|
|
// user.setIsDel(0); |
|
|
|
|
|
// adminUserMapper.updateById(user); |
|
|
// } |
|
|
// } |
|
|
// processedCodes.add(dto.getJwcode()); |
|
|
|
|
|
// |
|
|
// |
|
|
// // 处理逻辑 |
|
|
|
|
|
// if (existingJwCodes.contains(dto.getJwcode())) { |
|
|
|
|
|
// // --- 用户已存在 --- |
|
|
|
|
|
// User existingUser = adminUserMapper.selectUserByJwcode(dto.getJwcode()); |
|
|
|
|
|
|
|
|
// // 3. 检查用户是否已经是其他等级的内定用户(全局检查) |
|
|
|
|
|
// LambdaQueryWrapper<UserDetail> globalCheckWrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
// globalCheckWrapper.eq(UserDetail::getUserId, user.getId()) |
|
|
|
|
|
// .eq(UserDetail::getIsFixed, 1) |
|
|
|
|
|
// .eq(UserDetail::getIsDel, 0) |
|
|
|
|
|
// .ne(UserDetail::getGradeId, gradeId); // 排除当前等级 |
|
|
// |
|
|
// |
|
|
// // 检查user表状态 |
|
|
|
|
|
// if (existingUser.getIsDel() == 1) { |
|
|
|
|
|
// // user表已删除,恢复用户 |
|
|
|
|
|
// existingUser.setIsDel(0); |
|
|
|
|
|
// usersToRecover.add(existingUser); |
|
|
|
|
|
|
|
|
// if (adminUserDetailMapper.selectCount(globalCheckWrapper) > 0) { |
|
|
|
|
|
// throw new IllegalArgumentException("用户已是其他等级的内定用户,无法重复内定: " + dto.getJwcode()); |
|
|
// } |
|
|
// } |
|
|
// |
|
|
// |
|
|
//// // 检查user_detail状态 |
|
|
|
|
|
//// UserDetail existingDetail = existingDetails.get(dto.getJwcode()); |
|
|
|
|
|
//// if (existingDetail != null) { |
|
|
|
|
|
//// if (existingDetail.getIsDel() == 1) { |
|
|
|
|
|
//// // user_detail已删除,恢复记录 |
|
|
|
|
|
//// existingDetail.setIsDel(0); |
|
|
|
|
|
//// existingDetail.setGradeId(gradeId); |
|
|
|
|
|
//// detailsToRecover.add(existingDetail); |
|
|
|
|
|
//// } else { |
|
|
|
|
|
//// // user_detail已存在且未删除,跳过 |
|
|
|
|
|
//// throw new IllegalArgumentException("用户已存在且未删除: " + dto.getJwcode()); |
|
|
|
|
|
//// } |
|
|
|
|
|
//// } else { |
|
|
|
|
|
//// // user_detail不存在,新增 |
|
|
|
|
|
//// newUserDetails.add(createUserDetail(existingUser.getId(), gradeId)); |
|
|
|
|
|
//// } |
|
|
|
|
|
//// } else { |
|
|
|
|
|
//// // --- 全新用户 --- |
|
|
|
|
|
//// User newUser = convertToEntity(dto); |
|
|
|
|
|
//// newUsers.add(newUser); |
|
|
|
|
|
//// } |
|
|
|
|
|
//// successCount++; |
|
|
|
|
|
//// } catch (IllegalArgumentException e) { |
|
|
|
|
|
//// LOGGER.warn("导入数据校验失败: {}", e.getMessage()); |
|
|
|
|
|
//// skipCount++; |
|
|
|
|
|
//// } |
|
|
|
|
|
//// } |
|
|
|
|
|
// // 检查用户是否已经是其他等级的内定用户 |
|
|
|
|
|
// UserDetail existingFixedDetail = existingDetails.get(existingUser.getId()); |
|
|
|
|
|
// if (existingFixedDetail != null) { |
|
|
|
|
|
// if (existingFixedDetail.getGradeId().equals(gradeId)) { |
|
|
|
|
|
// // 已经是当前等级的内定用户 |
|
|
|
|
|
// if (existingFixedDetail.getIsDel() == 1) { |
|
|
|
|
|
// // 恢复已删除的记录 |
|
|
|
|
|
// existingFixedDetail.setIsDel(0); |
|
|
|
|
|
// detailsToRecover.add(existingFixedDetail); |
|
|
|
|
|
// } else { |
|
|
|
|
|
|
|
|
// // 3. 检查是否已是当前gradeId的内定用户 |
|
|
|
|
|
// LambdaQueryWrapper<UserDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
// wrapper.eq(UserDetail::getUserId, user.getId()) |
|
|
|
|
|
// .eq(UserDetail::getGradeId, gradeId) |
|
|
|
|
|
// .eq(UserDetail::getIsFixed, 1); |
|
|
|
|
|
// |
|
|
|
|
|
// UserDetail existingDetail = adminUserDetailMapper.selectOne(wrapper); |
|
|
|
|
|
// if (existingDetail != null) { |
|
|
|
|
|
// if (existingDetail.getIsDel() == 0) { |
|
|
// throw new IllegalArgumentException("用户已是当前等级的内定用户: " + dto.getJwcode()); |
|
|
// throw new IllegalArgumentException("用户已是当前等级的内定用户: " + dto.getJwcode()); |
|
|
// } |
|
|
|
|
|
// } else { |
|
|
// } else { |
|
|
// // 已经是其他等级的内定用户 |
|
|
|
|
|
// throw new IllegalArgumentException("用户已是其他等级的内定用户,无法添加到本等级: " + dto.getJwcode()); |
|
|
|
|
|
|
|
|
// // 物理删除旧记录,再新增一条 |
|
|
|
|
|
// adminUserDetailMapper.deleteById(existingDetail.getId()); |
|
|
// } |
|
|
// } |
|
|
// } else { |
|
|
|
|
|
// // 不是任何等级的内定用户,可以添加 |
|
|
|
|
|
// newUserDetails.add(createUserDetail(existingUser.getId(), gradeId)); |
|
|
|
|
|
// } |
|
|
|
|
|
// } else { |
|
|
|
|
|
// // --- 全新用户 --- |
|
|
|
|
|
// User newUser = convertToEntity(dto); |
|
|
|
|
|
// newUsers.add(newUser); |
|
|
|
|
|
// } |
|
|
// } |
|
|
|
|
|
// |
|
|
|
|
|
// // 4. 新增内定记录 |
|
|
|
|
|
// UserDetail newDetail = createUserDetail(user.getId(), gradeId); |
|
|
|
|
|
// adminUserDetailMapper.insert(newDetail); |
|
|
// successCount++; |
|
|
// successCount++; |
|
|
|
|
|
// |
|
|
// } catch (IllegalArgumentException e) { |
|
|
// } catch (IllegalArgumentException e) { |
|
|
// LOGGER.warn("导入数据校验失败: {}", e.getMessage()); |
|
|
|
|
|
|
|
|
// LOGGER.warn("导入失败(行{}): {}", i + 2, e.getMessage()); |
|
|
// skipCount++; |
|
|
// skipCount++; |
|
|
// } |
|
|
// } |
|
|
// } |
|
|
// } |
|
|
// // 5. 批量操作数据库 |
|
|
|
|
|
// if (!newUsers.isEmpty()) { |
|
|
|
|
|
// adminUserService.saveBatch(newUsers); |
|
|
|
|
|
// // 为新用户创建userDetail |
|
|
|
|
|
// newUsers.forEach(user -> |
|
|
|
|
|
// newUserDetails.add(createUserDetail(user.getId(), gradeId))); |
|
|
|
|
|
// } |
|
|
|
|
|
// |
|
|
|
|
|
// if (!usersToRecover.isEmpty()) { |
|
|
|
|
|
// adminUserService.updateBatchById(usersToRecover); |
|
|
|
|
|
// } |
|
|
|
|
|
// |
|
|
|
|
|
// if (!detailsToRecover.isEmpty()) { |
|
|
|
|
|
// this.updateBatchById(detailsToRecover); |
|
|
|
|
|
// } |
|
|
|
|
|
// |
|
|
|
|
|
// if (!newUserDetails.isEmpty()) { |
|
|
|
|
|
// this.saveBatch(newUserDetails); |
|
|
|
|
|
// } |
|
|
|
|
|
// |
|
|
// |
|
|
// return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount)); |
|
|
// return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount)); |
|
|
// } catch (Exception e) { |
|
|
// } catch (Exception e) { |
|
|
// LOGGER.error("导入用户失败", e); |
|
|
|
|
|
|
|
|
// LOGGER.error("导入失败", e); |
|
|
// return Result.failure("导入失败: " + e.getMessage()); |
|
|
// return Result.failure("导入失败: " + e.getMessage()); |
|
|
// } |
|
|
// } |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
// 1. 解析Excel |
|
|
// 1. 解析Excel |
|
|
List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream()) |
|
|
List<UserImportDto> userDtos = EasyExcel.read(file.getInputStream()) |
|
@ -435,56 +374,57 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U |
|
|
.sheet() |
|
|
.sheet() |
|
|
.doReadSync(); |
|
|
.doReadSync(); |
|
|
|
|
|
|
|
|
|
|
|
// 2. 检查数据量是否超过限制 |
|
|
|
|
|
if (userDtos.size() > 2000) { |
|
|
|
|
|
return Result.failure("单次导入最多支持2000条数据"); |
|
|
|
|
|
} |
|
|
|
|
|
// 3. 提取所有精网号并去重 |
|
|
|
|
|
List<String> jwcodes = userDtos.stream() |
|
|
|
|
|
.map(UserImportDto::getJwcode) |
|
|
|
|
|
.distinct() |
|
|
|
|
|
.collect(Collectors.toList()); |
|
|
|
|
|
|
|
|
|
|
|
// 4. 批量检查member表中存在的精网号(优化为单次查询) |
|
|
|
|
|
Set<String> existingMemberCodes = adminUserMapper.selectExistingJwCodes(jwcodes) |
|
|
|
|
|
.stream() |
|
|
|
|
|
.collect(Collectors.toSet()); |
|
|
|
|
|
|
|
|
|
|
|
// 5. 处理导入逻辑 |
|
|
int successCount = 0; |
|
|
int successCount = 0; |
|
|
int skipCount = 0; |
|
|
int skipCount = 0; |
|
|
Set<String> processedCodes = new HashSet<>(); |
|
|
Set<String> processedCodes = new HashSet<>(); |
|
|
|
|
|
List<String> invalidJwCodes = new ArrayList<>(); |
|
|
|
|
|
|
|
|
for (int i = 0; i < userDtos.size(); i++) { |
|
|
for (int i = 0; i < userDtos.size(); i++) { |
|
|
UserImportDto dto = userDtos.get(i); |
|
|
UserImportDto dto = userDtos.get(i); |
|
|
try { |
|
|
try { |
|
|
|
|
|
// 基础校验 |
|
|
validateUser(dto, i + 2, processedCodes); |
|
|
validateUser(dto, i + 2, processedCodes); |
|
|
processedCodes.add(dto.getJwcode()); |
|
|
processedCodes.add(dto.getJwcode()); |
|
|
|
|
|
|
|
|
// 2. 查询用户是否存在(按jwcode) |
|
|
|
|
|
|
|
|
// 检查精网号是否存在于member表 |
|
|
|
|
|
if (!existingMemberCodes.contains(dto.getJwcode())) { |
|
|
|
|
|
invalidJwCodes.add(dto.getJwcode()); |
|
|
|
|
|
throw new IllegalArgumentException("精网号不存在于会员系统: " + dto.getJwcode()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 查询或创建用户 |
|
|
User user = adminUserMapper.selectUserByJwcode(dto.getJwcode()); |
|
|
User user = adminUserMapper.selectUserByJwcode(dto.getJwcode()); |
|
|
if (user == null) { |
|
|
if (user == null) { |
|
|
// 新增用户 |
|
|
|
|
|
user = convertToEntity(dto); |
|
|
user = convertToEntity(dto); |
|
|
adminUserMapper.insert(user); |
|
|
adminUserMapper.insert(user); |
|
|
} else if (user.getIsDel() == 1) { |
|
|
} else if (user.getIsDel() == 1) { |
|
|
// 恢复已删除用户 |
|
|
|
|
|
user.setIsDel(0); |
|
|
user.setIsDel(0); |
|
|
adminUserMapper.updateById(user); |
|
|
adminUserMapper.updateById(user); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 3. 检查用户是否已经是其他等级的内定用户(全局检查) |
|
|
|
|
|
LambdaQueryWrapper<UserDetail> globalCheckWrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
globalCheckWrapper.eq(UserDetail::getUserId, user.getId()) |
|
|
|
|
|
.eq(UserDetail::getIsFixed, 1) |
|
|
|
|
|
.eq(UserDetail::getIsDel, 0) |
|
|
|
|
|
.ne(UserDetail::getGradeId, gradeId); // 排除当前等级 |
|
|
|
|
|
|
|
|
|
|
|
if (adminUserDetailMapper.selectCount(globalCheckWrapper) > 0) { |
|
|
|
|
|
throw new IllegalArgumentException("用户已是其他等级的内定用户,无法重复内定: " + dto.getJwcode()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 检查是否已是其他等级的内定用户 |
|
|
|
|
|
checkGlobalFixedUser(user.getId(), gradeId, dto.getJwcode()); |
|
|
|
|
|
|
|
|
// 3. 检查是否已是当前gradeId的内定用户 |
|
|
|
|
|
LambdaQueryWrapper<UserDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
wrapper.eq(UserDetail::getUserId, user.getId()) |
|
|
|
|
|
.eq(UserDetail::getGradeId, gradeId) |
|
|
|
|
|
.eq(UserDetail::getIsFixed, 1); |
|
|
|
|
|
|
|
|
// 处理当前等级的内定记录 |
|
|
|
|
|
processGradeFixedUser(user.getId(), gradeId); |
|
|
|
|
|
|
|
|
UserDetail existingDetail = adminUserDetailMapper.selectOne(wrapper); |
|
|
|
|
|
if (existingDetail != null) { |
|
|
|
|
|
if (existingDetail.getIsDel() == 0) { |
|
|
|
|
|
throw new IllegalArgumentException("用户已是当前等级的内定用户: " + dto.getJwcode()); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 物理删除旧记录,再新增一条 |
|
|
|
|
|
adminUserDetailMapper.deleteById(existingDetail.getId()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4. 新增内定记录 |
|
|
|
|
|
|
|
|
// 新增内定记录 |
|
|
UserDetail newDetail = createUserDetail(user.getId(), gradeId); |
|
|
UserDetail newDetail = createUserDetail(user.getId(), gradeId); |
|
|
adminUserDetailMapper.insert(newDetail); |
|
|
adminUserDetailMapper.insert(newDetail); |
|
|
successCount++; |
|
|
successCount++; |
|
@ -495,13 +435,51 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return Result.success(String.format("导入成功%d条,跳过%d条", successCount, skipCount)); |
|
|
|
|
|
|
|
|
// 6. 构建结果信息 |
|
|
|
|
|
String message = String.format("导入完成: 成功%d条,跳过%d条", successCount, skipCount); |
|
|
|
|
|
if (!invalidJwCodes.isEmpty()) { |
|
|
|
|
|
message += String.format(",其中%d个精网号无效(示例: %s)", |
|
|
|
|
|
invalidJwCodes.size(), |
|
|
|
|
|
invalidJwCodes.stream().limit(5).collect(Collectors.joining(","))); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return successCount > 0 ? Result.success(message) : Result.failure("没有有效数据可导入"); |
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
} catch (Exception e) { |
|
|
LOGGER.error("导入失败", e); |
|
|
|
|
|
|
|
|
LOGGER.error("导入内定用户失败", e); |
|
|
return Result.failure("导入失败: " + e.getMessage()); |
|
|
return Result.failure("导入失败: " + e.getMessage()); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 检查用户是否已是其他等级的内定用户 |
|
|
|
|
|
private void checkGlobalFixedUser(Long userId, Long currentGradeId, String jwcode) { |
|
|
|
|
|
LambdaQueryWrapper<UserDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
wrapper.eq(UserDetail::getUserId, userId) |
|
|
|
|
|
.eq(UserDetail::getIsFixed, 1) |
|
|
|
|
|
.eq(UserDetail::getIsDel, 0) |
|
|
|
|
|
.ne(UserDetail::getGradeId, currentGradeId); |
|
|
|
|
|
|
|
|
|
|
|
if (adminUserDetailMapper.selectCount(wrapper) > 0) { |
|
|
|
|
|
throw new IllegalArgumentException("用户已是其他等级的内定用户,无法重复内定: " + jwcode); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 处理当前等级的内定记录 |
|
|
|
|
|
private void processGradeFixedUser(Long userId, Long gradeId) { |
|
|
|
|
|
LambdaQueryWrapper<UserDetail> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
|
|
wrapper.eq(UserDetail::getUserId, userId) |
|
|
|
|
|
.eq(UserDetail::getGradeId, gradeId) |
|
|
|
|
|
.eq(UserDetail::getIsFixed, 1); |
|
|
|
|
|
|
|
|
|
|
|
UserDetail existingDetail = adminUserDetailMapper.selectOne(wrapper); |
|
|
|
|
|
if (existingDetail != null) { |
|
|
|
|
|
if (existingDetail.getIsDel() == 0) { |
|
|
|
|
|
throw new IllegalArgumentException("用户已是当前等级的内定用户"); |
|
|
|
|
|
} else { |
|
|
|
|
|
adminUserDetailMapper.deleteById(existingDetail.getId()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
// 辅助方法:创建UserDetail |
|
|
// 辅助方法:创建UserDetail |
|
|
private UserDetail createUserDetail(Long userId, Long gradeId) { |
|
|
private UserDetail createUserDetail(Long userId, Long gradeId) { |
|
|
UserDetail detail = new UserDetail(); |
|
|
UserDetail detail = new UserDetail(); |
|
@ -555,6 +533,9 @@ public class AdminUserDetailServiceImpl extends ServiceImpl<IUserDetailMapper, U |
|
|
user.setUsername(dto.getUsername()); |
|
|
user.setUsername(dto.getUsername()); |
|
|
user.setCreateTime(new Date()); |
|
|
user.setCreateTime(new Date()); |
|
|
user.setUpdateTime(new Date()); |
|
|
user.setUpdateTime(new Date()); |
|
|
|
|
|
// 查询并设置loc_market |
|
|
|
|
|
String locMarket = adminUserMapper.selectLocMarketByJwcode(dto.getJwcode()); |
|
|
|
|
|
user.setLocMarket(locMarket != null ? locMarket : "未知"); // 默认值 |
|
|
// 密码加密 |
|
|
// 密码加密 |
|
|
user.setPassword("123456"); |
|
|
user.setPassword("123456"); |
|
|
return user; |
|
|
return user; |
|
|