diff --git a/rc-service/rc-service-other/other-start/src/test/java/AnchorTargetTest.java b/rc-service/rc-service-other/other-start/src/test/java/AnchorTargetTest.java index 4e83b023..8dd7ac04 100644 --- a/rc-service/rc-service-other/other-start/src/test/java/AnchorTargetTest.java +++ b/rc-service/rc-service-other/other-start/src/test/java/AnchorTargetTest.java @@ -16,7 +16,7 @@ import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.test.context.junit4.SpringRunner; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; @SpringBootTest(classes = OtherServiceApplication.class) @@ -106,6 +106,155 @@ public class AnchorTargetTest { } } + /** + * 批量扣除主播目标 + */ + @Test + public void batchAnchorTargetDeduct() { + // 定义批量扣除的用户和金额列表 + Map batchDeductMap = new HashMap<>(); + batchDeductMap.put(1957345312961527809L, 1L); + batchDeductMap.put(1989287471839113218L, 1L); + // 可以继续添加更多用户... + + System.out.println("========== 开始批量扣除 =========="); + System.out.println("批量扣除总数: " + batchDeductMap.size()); + System.out.println(); + + // 统计数据 + int successCount = 0; // 成功扣除的数量 + int failCount = 0; // 失败的数量 + int skipCount = 0; // 跳过的数量(目标值不足) + long totalDeductValue = 0L; // 总扣除金额 + List failedUsers = new ArrayList<>(); // 失败的用户列表 + + // 循环批量扣除 + for (Map.Entry entry : batchDeductMap.entrySet()) { + Long userId = entry.getKey(); + Long deductValue = entry.getValue(); + + System.out.println("---------- 处理用户: " + userId + " ----------"); + System.out.println("扣除金额: " + deductValue); + + try { + boolean result = deductSingleAnchorTarget(userId, deductValue); + if (result) { + successCount++; + totalDeductValue += deductValue; + System.out.println("✓ 用户 " + userId + " 扣除成功"); + } else { + skipCount++; + System.out.println("⊘ 用户 " + userId + " 跳过(目标值不足或无未结算工单)"); + } + } catch (Exception e) { + failCount++; + failedUsers.add(userId + " (错误: " + e.getMessage() + ")"); + System.out.println("✗ 用户 " + userId + " 扣除失败: " + e.getMessage()); + e.printStackTrace(); + } + + System.out.println(); + } + + // 打印统计结果 + System.out.println("========== 批量扣除完成 =========="); + System.out.println("总处理数: " + batchDeductMap.size()); + System.out.println("成功数: " + successCount); + System.out.println("跳过数: " + skipCount); + System.out.println("失败数: " + failCount); + System.out.println("总扣除金额: " + totalDeductValue); + System.out.println("成功率: " + String.format("%.2f%%", (successCount * 100.0 / batchDeductMap.size()))); + + if (!failedUsers.isEmpty()) { + System.out.println("\n失败用户列表:"); + failedUsers.forEach(user -> System.out.println(" - " + user)); + } + + System.out.println("========================================"); + } + + /** + * 单个主播目标扣除(从原方法提取出来) + * @param userId 用户ID + * @param deductValue 扣除金额 + * @return true-成功扣除, false-跳过(目标值不足或无未结算工单) + */ + private boolean deductSingleAnchorTarget(Long userId, Long deductValue) { + TeamMemberWorkQryCmd cmd = new TeamMemberWorkQryCmd(); + cmd.setMemberUserId(userId); + cmd.setSysOrigin("LIKEI"); + List execute = listMemberWorkDecay.execute(cmd); + + // 1. 筛选 billStatus = UNPAID 的数据 + List unpaidList = execute.stream() + .filter(work -> "UNPAID".equals(work.getBillStatus())) + .limit(1) + .toList(); + + System.out.println("未结算的工单数量: " + unpaidList.size()); + + if (unpaidList.isEmpty()) { + return false; + } + + for (TeamMemberWorkDTO work : unpaidList) { + // 2. 统计 dailyTargets 的 acceptGiftValue 的和 + Long totalAcceptGiftValue = work.getTarget().getDailyTargets().stream() + .mapToLong(TeamMemberWorkDailyTargetDTO::getAcceptGiftValue) + .sum(); + + System.out.println("工单ID: " + work.getId() + ", 总收礼物价值: " + totalAcceptGiftValue); + + // 3. 检查目标值够不够扣 + if (totalAcceptGiftValue < deductValue) { + System.out.println("目标值不足,无法扣除。需要: " + deductValue + ", 当前: " + totalAcceptGiftValue); + return false; + } + + // 4. 从第一天开始扣除 + Long remainingDeduct = deductValue; + List dailyTargets = work.getTarget().getDailyTargets(); + boolean hasModified = false; // 标记是否有修改 + + for (int i = 0; i < dailyTargets.size(); i++) { + TeamMemberWorkDailyTargetDTO dailyTarget = dailyTargets.get(i); + Long currentValue = dailyTarget.getAcceptGiftValue(); + + if (remainingDeduct <= 0) { + break; + } + + if (currentValue > 0) { // 只有当前值大于0时才可能修改 + hasModified = true; // 标记为已修改 + + if (currentValue >= remainingDeduct) { + // 当前天的值足够扣除剩余部分 + dailyTarget.setAcceptGiftValue(currentValue - remainingDeduct); + System.out.println("日期 " + dailyTarget.getDateNumber() + " 扣除: " + remainingDeduct + ", 剩余: " + (currentValue - remainingDeduct)); + remainingDeduct = 0L; + } else { + // 当前天的值不够,全部扣除 + dailyTarget.setAcceptGiftValue(0L); + remainingDeduct -= currentValue; + System.out.println("日期 " + dailyTarget.getDateNumber() + " 扣除: " + currentValue + ", 剩余需扣除: " + remainingDeduct); + } + } + } + + // 5. 只有当有修改时才更新 MongoDB + if (hasModified) { + updateTeamMemberTarget(work.getId(), dailyTargets); + System.out.println("工单 " + work.getId() + " 扣除完成,已更新到MongoDB"); + return true; + } else { + System.out.println("工单 " + work.getId() + " 无需修改,跳过更新"); + return false; + } + } + + return false; + } + /** * 更新 MongoDB 中的 TeamMemberTarget * @param timeId 工单ID