tianfeng be7f7d7c05 新增 BZIZI 平台支持,去除业务代码中硬编码的 LIKEI 关键字
- SysOriginPlatformEnum 新增 BZIZI("Bzizi", 12) 枚举值
- GameSysOriginEnum 新增 BZIZI("Bzizi")
- FreightGoldToUsdRatioEnum 新增 BZIZI(10000)
- 将主业务代码及测试代码中所有写死的 LIKEI 替换为 BZIZI(共 65 个文件)
- 保留枚举定义中的 LIKEI 值及日志消息不变

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 10:24:30 +08:00

308 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import com.red.circle.OtherServiceApplication;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.infra.common.team.decay.ListMemberWorkDecay;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMemberTarget;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberTargetService;
import com.red.circle.other.inner.model.cmd.team.TeamMemberWorkQryCmd;
import com.red.circle.other.inner.model.dto.agency.agency.TeamMemberWorkDTO;
import com.red.circle.other.inner.model.dto.agency.agency.TeamMemberWorkDailyTargetDTO;
import com.red.circle.tool.core.date.TimestampUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
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.*;
import java.util.stream.Collectors;
@SpringBootTest(classes = OtherServiceApplication.class)
@RunWith(SpringRunner.class)
public class AnchorTargetTest {
@Autowired
private TeamMemberTargetService teamMemberTargetService;
@Autowired
private ListMemberWorkDecay listMemberWorkDecay;
@Autowired
private MongoTemplate mongoTemplate;
@Autowired
private UserProfileGateway userProfileGateway;
/**
* 扣除主播目标
*/
@Test
public void AnchorTargetTest(){
Long userId = 1987522531364773890L;
Long deductValue = 300000L; // 要扣除的目标值
TeamMemberWorkQryCmd cmd = new TeamMemberWorkQryCmd();
cmd.setMemberUserId(userId);
cmd.setSysOrigin("BZIZI");
List<TeamMemberWorkDTO> execute = listMemberWorkDecay.execute(cmd);
// 1. 筛选 billStatus = UNPAID 的数据
List<TeamMemberWorkDTO> unpaidList = execute.stream()
.filter(work -> "UNPAID".equals(work.getBillStatus()))
.limit(1)
.toList();
System.out.println("未结算的工单数量: " + unpaidList.size());
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);
continue;
}
// 4. 从第一天开始扣除
Long remainingDeduct = deductValue;
List<TeamMemberWorkDailyTargetDTO> 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");
} else {
System.out.println("工单 " + work.getId() + " 无需修改,跳过更新");
}
}
}
/**
* 批量扣除主播目标
*/
@Test
public void batchAnchorTargetDeduct() {
Map<Long, Long> map = Map.ofEntries(
Map.entry(22222L, 3750000L),
Map.entry(8846195L, 1125000L),
Map.entry(8846188L, 150000L),
Map.entry(8846174L, 750000L),
Map.entry(8846185L, 750000L),
Map.entry(8848862L, 6000000L),
Map.entry(8849422L, 300000L),
Map.entry(8846353L, 300000L)
);
// 将account转换为userId并构建batchDeductMap
Map<Long, Long> batchDeductMap = new HashMap<>();
map.forEach((account, amount) -> {
UserProfile userProfile = userProfileGateway.getByAccount("BZIZI", String.valueOf(account));
if (Objects.nonNull(userProfile)) {
batchDeductMap.put(userProfile.getId(), amount);
} else {
throw new RuntimeException("账号不存在:" + account);
}
});
// 定义批量扣除的用户和金额列表
// Map<Long, Long> 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<String> failedUsers = new ArrayList<>(); // 失败的用户列表
// 循环批量扣除
for (Map.Entry<Long, Long> 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("BZIZI");
List<TeamMemberWorkDTO> execute = listMemberWorkDecay.execute(cmd);
// 1. 筛选 billStatus = UNPAID 的数据
List<TeamMemberWorkDTO> 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<TeamMemberWorkDailyTargetDTO> 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
* @param dailyTargets 更新后的每日目标列表
*/
private void updateTeamMemberTarget(Long timeId, List<TeamMemberWorkDailyTargetDTO> dailyTargets) {
Query query = new Query(Criteria.where("timeId").is(timeId));
// 更新 target.dailyTargets 数组
for (int i = 0; i < dailyTargets.size(); i++) {
TeamMemberWorkDailyTargetDTO dailyTarget = dailyTargets.get(i);
mongoTemplate.updateFirst(query,
new Update()
.set("updateTime", TimestampUtils.now())
.set("dailyTargets.$[i].acceptGiftValue", dailyTarget.getAcceptGiftValue())
.set("dailyTargets.$[i].updateTime", TimestampUtils.now())
.filterArray(Criteria.where("i.dateNumber").is(dailyTarget.getDateNumber())),
TeamMemberTarget.class);
}
}
}