diff --git a/common/src/main/java/com/sdm/common/service/UserNameCacheService.java b/common/src/main/java/com/sdm/common/service/UserNameCacheService.java index ed5a5e08..9056951f 100644 --- a/common/src/main/java/com/sdm/common/service/UserNameCacheService.java +++ b/common/src/main/java/com/sdm/common/service/UserNameCacheService.java @@ -71,26 +71,84 @@ public class UserNameCacheService { */ @Cacheable(value = "allUsers", key = "'userList'") public List getAllUsers() { - log.info("缓存未命中,从用户系统加载全量数据..."); + log.info("缓存未命中,从用户系统分批加载全量数据..."); long startTime = System.currentTimeMillis(); + // 存储所有分批查询到的用户数据 + List allUsers = new ArrayList<>(); + // 分页参数:当前页从1开始,单页size CID允许的最大值1000 + int current = 1; + final int pageSize = 1000; + // 总数据条数(从接口返回的total字段获取) + Long totalCount = null; + + final int MAX_QUERY_TIMES = 10; // 最大查询次数 + int queryTimes = 0; // 已查询次数 + try { - UserListReq userListReq = new UserListReq(); - userListReq.setTenantId(ThreadLocalContext.getTenantId()); - userListReq.setCurrent(1); - userListReq.setSize(9999); - SdmResponse>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq); - if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData() != null) { - List users = pageDataRespSdmResponse.getData().getData(); - if (CollectionUtils.isNotEmpty(users)) { - log.info("加载完成,用户数:{},耗时:{}ms", users.size(), System.currentTimeMillis() - startTime); - return users; + while (true) { + // 超过最大查询次数终止 + queryTimes++; + if (queryTimes > MAX_QUERY_TIMES) { + log.error("超过最大查询次数({}),终止查询", MAX_QUERY_TIMES); + break; } + + // 1. 构建分页请求参数 + UserListReq userListReq = new UserListReq(); + userListReq.setTenantId(ThreadLocalContext.getTenantId()); + userListReq.setCurrent(current); + userListReq.setSize(pageSize); + + // 2. 调用用户系统接口 + SdmResponse>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq); + + // 3. 处理响应结果:失败则终止循环 + if (!pageDataRespSdmResponse.isSuccess() || pageDataRespSdmResponse.getData() == null) { + log.error("第{}页用户数据查询失败,终止分批查询", current); + break; + } + + PageDataResp> pageData = pageDataRespSdmResponse.getData(); + List currentPageUsers = pageData.getData(); + + // 4. 首次查询时获取总数据条数(仅需获取一次) + if (totalCount == null) { + totalCount = pageData.getTotal(); // total是总数据条数(比如1200) + log.info("获取到用户总数据条数:{}", totalCount); + } + + // 5. 新增当前页数据到总列表 + if (CollectionUtils.isNotEmpty(currentPageUsers)) { + allUsers.addAll(currentPageUsers); + log.info("第{}页加载完成,新增用户数:{},累计用户数:{}", current, currentPageUsers.size(), allUsers.size()); + } + + // 6. 核心判断:是否还有下一页(基于总条数计算) + // 逻辑1:累计数据 >= 总条数 → 已加载完所有数据,终止 + if (totalCount != null && allUsers.size() >= totalCount) { + log.info("累计加载数据量({}) >= 总条数({}),终止分批查询", allUsers.size(), totalCount); + break; + } + // 逻辑2:当前页数据量 < 单页size → 已是最后一页,终止(兜底判断) + if (currentPageUsers.size() < pageSize) { + log.info("第{}页数据量({}) < 单页size({}),已是最后一页,终止分批查询", current, currentPageUsers.size(), pageSize); + break; + } + + // 7. 当前页+1,准备下一次查询 + current++; } - return Collections.emptyList(); + + // 最终统计 + log.info("全量用户加载完成,实际加载用户数:{},总数据条数:{},分批查询次数:{},耗时:{}ms", + allUsers.size(), totalCount, current - 1, System.currentTimeMillis() - startTime); + return allUsers; + } catch (Exception e) { - log.error("加载用户列表失败", e); - return Collections.emptyList(); // 返回空列表,避免缓存null + log.error("加载用户列表失败(已加载{}条数据)", allUsers.size(), e); + // 即使部分失败,也返回已加载的数据(业务可根据需求调整为返回空列表) + return CollectionUtils.isEmpty(allUsers) ? Collections.emptyList() : allUsers; } } @@ -115,7 +173,7 @@ public class UserNameCacheService { } // 3. 根据关键词过滤 - String lowerKeyword = keyword.trim().toLowerCase(); + String lowerKeyword = keyword.trim(); List keywordList = splitKeyword(lowerKeyword); List result = allUsers.parallelStream() @@ -167,29 +225,39 @@ public class UserNameCacheService { return false; } + // 预处理用户字段:去空格、判空 + String username = user.getUsername() == null ? "" : user.getUsername().trim(); + String nickname = user.getNickname() == null ? "" : user.getNickname().trim(); + Long userId = user.getUserId(); + // 遍历所有分割后的关键词,只要匹配一个就返回true for (String keyword : keywordList) { - // 场景1:关键词是数字,尝试匹配userId(精确匹配) + // 场景1:关键词是数字,尝试匹配userId if (keyword.matches("\\d+")) { try { - Long userId = Long.parseLong(keyword); - if (Objects.equals(user.getUserId(), userId)) { + Long targetUserId = Long.parseLong(keyword); + if (Objects.equals(userId, targetUserId)) { + log.debug("用户{}匹配到userId关键词{}", username, keyword); return true; } } catch (NumberFormatException e) { - // 理论上不会走到这里,因为已经通过数字正则校验 continue; } } // 场景2:关键词是非数字,匹配username/nickname - if (user.getUsername() != null && user.getUsername().toLowerCase().contains(keyword)) { - return true; - } - if (user.getNickname() != null && user.getNickname().toLowerCase().contains(keyword)) { + boolean usernameMatch = StringUtils.isNotEmpty(username) && username.contains(keyword); + boolean nicknameMatch = StringUtils.isNotEmpty(nickname) && nickname.contains(keyword); + + if (usernameMatch || nicknameMatch) { + log.debug("用户{}匹配到关键词{}(username匹配:{},nickname匹配:{})", + username, keyword, usernameMatch, nicknameMatch); return true; } } + + log.debug("用户{}未匹配到任何关键词{}(username:{},nickname:{})", + username, keywordList, username, nickname); return false; }