|
|
@@ -197,11 +197,11 @@ public class UserService {
|
|
|
"FROM t_user " +
|
|
|
"WHERE is_effective = 1 AND referrer_id IS NOT NULL " +
|
|
|
"GROUP BY referrer_id HAVING COUNT(id) > 0";
|
|
|
- AppConfig.LOGGER.info("执行 SQL 查询推荐人统计: {}", queryReferrerStatsSql);
|
|
|
+// AppConfig.LOGGER.info("执行 SQL 查询推荐人统计: {}", queryReferrerStatsSql);
|
|
|
List<Record> referrerStatsRecords = Db.find(queryReferrerStatsSql);
|
|
|
|
|
|
if (referrerStatsRecords.isEmpty()) {
|
|
|
- AppConfig.LOGGER.info("没有符合条件的推荐人。");
|
|
|
+// AppConfig.LOGGER.info("没有符合条件的推荐人。");
|
|
|
return MyRet.fail("还没人推荐过任何人是有效用户。");
|
|
|
}
|
|
|
|
|
|
@@ -210,7 +210,7 @@ public class UserService {
|
|
|
.map(record -> record.getLong("referrer_id"))
|
|
|
.distinct() // 确保唯一,虽然 Set 已经保证了
|
|
|
.collect(Collectors.toList());
|
|
|
- AppConfig.LOGGER.info("符合条件的推荐人ID数量: {}", eligibleReferrerIdsList.size());
|
|
|
+// AppConfig.LOGGER.info("符合条件的推荐人ID数量: {}", eligibleReferrerIdsList.size());
|
|
|
|
|
|
// 转换为 Map,方便通过 referrer_id 查找 valid_user_count (这个 Map 仍然需要)
|
|
|
Map<Long, Integer> referrerValidUserCountMap = referrerStatsRecords.stream()
|
|
|
@@ -223,7 +223,7 @@ public class UserService {
|
|
|
final int BATCH_QUERY_SIZE = 1000;
|
|
|
List<User> finalReferrerList = new ArrayList<>(eligibleReferrerIdsList.size()); // 最终的推荐人 User 对象列表
|
|
|
|
|
|
- AppConfig.LOGGER.info("开始分批查询推荐人 User 对象并整合 valid_referred_count...");
|
|
|
+// AppConfig.LOGGER.info("开始分批查询推荐人 User 对象并整合 valid_referred_count...");
|
|
|
for (int i = 0; i < eligibleReferrerIdsList.size(); i += BATCH_QUERY_SIZE) {
|
|
|
List<Long> subListReferrerIds = eligibleReferrerIdsList.subList(i, Math.min(i + BATCH_QUERY_SIZE, eligibleReferrerIdsList.size()));
|
|
|
String subInSql = subListReferrerIds.stream().map(String::valueOf).collect(Collectors.joining(","));
|
|
|
@@ -238,12 +238,12 @@ public class UserService {
|
|
|
}
|
|
|
}
|
|
|
finalReferrerList.addAll(currentBatchUsers);
|
|
|
- AppConfig.LOGGER.debug("已查询推荐人批次 {} 总已查询用户数: {}", i, finalReferrerList.size());
|
|
|
+// AppConfig.LOGGER.debug("已查询推荐人批次 {} 总已查询用户数: {}", i, finalReferrerList.size());
|
|
|
}
|
|
|
- AppConfig.LOGGER.info("推荐人 User 对象查询并整合完毕,共查询到 {} 个推荐人。", finalReferrerList.size());
|
|
|
+// AppConfig.LOGGER.info("推荐人 User 对象查询并整合完毕,共查询到 {} 个推荐人。", finalReferrerList.size());
|
|
|
|
|
|
// ******** 3. 分批查询所有被推荐用户(下级用户),并按推荐人 ID 分组 ********
|
|
|
- AppConfig.LOGGER.info("开始分批查询所有被推荐用户(下级用户)并分组...");
|
|
|
+// AppConfig.LOGGER.info("开始分批查询所有被推荐用户(下级用户)并分组...");
|
|
|
// 存储所有被推荐用户的数据,Key为referrer_id,Value为该referrer_id推荐的User的Map列表
|
|
|
Map<Long, List<Map<String, Object>>> allReferredUsersByReferrerId = new HashMap<>();
|
|
|
|
|
|
@@ -270,32 +270,116 @@ public class UserService {
|
|
|
allReferredUsersByReferrerId.computeIfAbsent(currentReferrerId, k -> new ArrayList<>()).add(referredUser);
|
|
|
}
|
|
|
}
|
|
|
- AppConfig.LOGGER.info("所有被推荐用户查询并分组完毕。共找到被推荐用户 {} 条。",
|
|
|
- allReferredUsersByReferrerId.values().stream().mapToInt(List::size).sum());
|
|
|
+// AppConfig.LOGGER.info("所有被推荐用户查询并分组完毕。共找到被推荐用户 {} 条。",
|
|
|
+// allReferredUsersByReferrerId.values().stream().mapToInt(List::size).sum());
|
|
|
|
|
|
// ******** 4. 将被推荐用户列表整合到推荐人 User 对象中 ********
|
|
|
- AppConfig.LOGGER.info("开始将下级用户列表整合到推荐人 User 对象...");
|
|
|
+// AppConfig.LOGGER.info("开始将下级用户列表整合到推荐人 User 对象...");
|
|
|
for (User referrer : finalReferrerList) { // 遍历已经整合了 valid_referred_count 的推荐人列表
|
|
|
Long referrerId = referrer.getId();
|
|
|
List<Map<String, Object>> referredUsers = allReferredUsersByReferrerId.getOrDefault(referrerId, Collections.emptyList()); // 使用 getOrDefault 避免 NPE
|
|
|
|
|
|
referrer.put("referred_users", referredUsers); // put 进去一个 List<Map<String, Object>>
|
|
|
- AppConfig.LOGGER.info("推荐人: {}", referrer.toJson());
|
|
|
- AppConfig.LOGGER.debug("推荐人 {} 已关联 {} 个被推荐用户。", referrerId, referredUsers.size());
|
|
|
-
|
|
|
- for (Map<String, Object> ru : referredUsers) {
|
|
|
- AppConfig.LOGGER.info(" - ID:{}, 手机号:{}, 有效时间:{}", ru.get("id"), ru.get("mobile_number"), ru.get("effective_time"));
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
- AppConfig.LOGGER.info("直推网络查询与构建完成。");
|
|
|
+// AppConfig.LOGGER.info("直推网络查询与构建完成。");
|
|
|
// ******** 分批查询 User 对象结束 ********
|
|
|
+
|
|
|
+ // 筛选出直推人数大于等于10人的组,每个用户按第10位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
+ List<User> tenList = filterAndSortReferrersByNthReferralTime(finalReferrerList, 10);
|
|
|
+ // 筛选出直推人数大于等于5人的组,每个用户按第5位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
+ List<User> fiveList = filterAndSortReferrersByNthReferralTime(finalReferrerList, 5);
|
|
|
+ // 筛选出直推人数大于等于2人的组,每个用户按第2位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
+ List<User> twoList = filterAndSortReferrersByNthReferralTime(finalReferrerList, 2);
|
|
|
+
|
|
|
+// for (User referrer : tenList) {
|
|
|
+// Long referrerId = referrer.getId();
|
|
|
+// AppConfig.LOGGER.info("推荐人: {}", referrer.toJson());
|
|
|
+// List<Map<String, Object>> referredUsers = allReferredUsersByReferrerId.getOrDefault(referrerId, Collections.emptyList()); // 使用 getOrDefault 避免 NPE
|
|
|
+// AppConfig.LOGGER.debug("推荐人 {} 已关联 {} 个被推荐用户。", referrerId, referredUsers.size());
|
|
|
+//
|
|
|
+// for (Map<String, Object> ru : referredUsers) {
|
|
|
+// AppConfig.LOGGER.info(" - ID:{}, 手机号:{}, 有效时间:{}", ru.get("id"), ru.get("mobile_number"), ru.get("effective_time"));
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ Map<String, Object> rst = new HashMap<>();
|
|
|
+ rst.put("referrer_list", finalReferrerList);
|
|
|
+ rst.put("ten_list", tenList);
|
|
|
+ rst.put("five_list", fiveList);
|
|
|
+ rst.put("two_list", twoList);
|
|
|
+
|
|
|
+ return MyRet.ok("查询成功").setData(rst);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 筛选出推荐人数大于等于指定阈值的推荐人,并按其第 N 位被推荐人的有效时间排序
|
|
|
+ *
|
|
|
+ * @param finalReferrerList 包含所有推荐人数据的 List<User>
|
|
|
+ * @param threshold 筛选阈值,例如10,表示referred_users数量大于等于10的推荐人
|
|
|
+ * @return 筛选并排序后的 List<User>
|
|
|
+ */
|
|
|
+ public List<User> filterAndSortReferrersByNthReferralTime(List<User> finalReferrerList, int threshold) {
|
|
|
+ // @param nthIndex 排序依据的下级用户的索引(从0开始),例如9表示第10个被推荐人
|
|
|
+ int nthIndex = threshold - 1;
|
|
|
+// AppConfig.LOGGER.info("开始筛选并排序推荐人列表,阈值: {},排序依据的索引: {}", threshold, nthIndex);
|
|
|
+
|
|
|
+ // 1. 筛选出 valid_referred_count 大于等于 threshold 的推荐人
|
|
|
+ List<User> filteredList = finalReferrerList.stream()
|
|
|
+ .filter(referrer -> {
|
|
|
+ Integer referredCount = referrer.get("valid_referred_count");
|
|
|
+ // 确保 referredCount 不为 null 且大于等于阈值
|
|
|
+ return referredCount != null && referredCount >= threshold;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
|
- // 筛选出直推人数大于10人的组,每个用户按第10位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
+ AppConfig.LOGGER.info("筛选后,推荐人数大于等于 {} 的推荐人有 {} 位。", threshold, filteredList.size());
|
|
|
|
|
|
- // 筛选出直推人数大于5人的组,每个用户按第5位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
- // 筛选出直推人数大于2人的组,每个用户按第2位被推荐人(下级)的有效时间进行从小到大排序
|
|
|
+ if (filteredList.isEmpty()) {
|
|
|
+ AppConfig.LOGGER.info("没有符合筛选条件的推荐人。");
|
|
|
+ return filteredList;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 对筛选后的推荐人进行排序
|
|
|
+ // 排序规则:按第 nthIndex 位被推荐人的 effective_time 升序
|
|
|
+ try {
|
|
|
+ filteredList.sort((referrer1, referrer2) -> {
|
|
|
+ // 获取 referrer1 的第 nthIndex 位被推荐人的 effective_time
|
|
|
+ List<Map<String, Object>> referredUsers1 = referrer1.get("referred_users");
|
|
|
+ Long effectiveTime1 = null;
|
|
|
+ if (referredUsers1 != null && referredUsers1.size() > nthIndex) {
|
|
|
+ Map<String, Object> nthUser1 = referredUsers1.get(nthIndex);
|
|
|
+ effectiveTime1 = (Long) nthUser1.get("effective_time");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取 referrer2 的第 nthIndex 位被推荐人的 effective_time
|
|
|
+ List<Map<String, Object>> referredUsers2 = referrer2.get("referred_users");
|
|
|
+ Long effectiveTime2 = null;
|
|
|
+ if (referredUsers2 != null && referredUsers2.size() > nthIndex) {
|
|
|
+ Map<String, Object> nthUser2 = referredUsers2.get(nthIndex);
|
|
|
+ effectiveTime2 = (Long) nthUser2.get("effective_time");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理 null 值的情况:null 视为最大,排在最后
|
|
|
+ if (effectiveTime1 == null && effectiveTime2 == null) {
|
|
|
+ return 0; // 都为null,视为相等
|
|
|
+ } else if (effectiveTime1 == null) {
|
|
|
+ return 1; // referrer1 的时间为null,referrer2 不为null,referrer1 排在后面
|
|
|
+ } else if (effectiveTime2 == null) {
|
|
|
+ return -1; // referrer2 的时间为null,referrer1 不为null,referrer2 排在后面
|
|
|
+ } else {
|
|
|
+ return effectiveTime1.compareTo(effectiveTime2); // 升序排列
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (ClassCastException e) {
|
|
|
+ AppConfig.LOGGER.error("排序时发生类型转换错误,请检查 'effective_time' 字段的类型是否为 Long。", e);
|
|
|
+ // 可以选择抛出异常或返回未排序的列表
|
|
|
+ } catch (Exception e) {
|
|
|
+ AppConfig.LOGGER.error("排序时发生未知错误。", e);
|
|
|
+ // 可以选择抛出异常或返回未排序的列表
|
|
|
+ }
|
|
|
|
|
|
- return MyRet.ok("查询成功");
|
|
|
+// AppConfig.LOGGER.info("筛选并排序完成,结果列表大小: {}", filteredList.size());
|
|
|
+ return filteredList;
|
|
|
}
|
|
|
}
|