抽奖 概率抽奖逻辑新增

This commit is contained in:
tianfeng 2025-10-20 20:27:04 +08:00
parent a7dc52bb90
commit 6420fb8d1d

View File

@ -23,7 +23,6 @@ import com.red.circle.tool.core.date.TimestampUtils;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.List;
@ -210,7 +209,7 @@ public class LotteryDrawExe {
}
/**
* 判断奖品池阶段.
* 判断奖品池阶段新方案前期给大奖中期消耗后期凑整.
*/
private String determinePrizePool(LotteryUserProgress progress, LotteryActivity activity) {
int drawCount = progress.getTotalDrawCount();
@ -220,25 +219,25 @@ public class LotteryDrawExe {
: new BigDecimal("10");
// 默认阶段配置
int earlyMax = activity.getEarlyStageMaxCount() != null ? activity.getEarlyStageMaxCount() : 20;
int earlyMax = activity.getEarlyStageMaxCount() != null ? activity.getEarlyStageMaxCount() : 15;
int middleMax = activity.getMiddleStageMaxCount() != null ? activity.getMiddleStageMaxCount() : 50;
BigDecimal lateTrigger = activity.getLateStageTriggerAmount() != null
? activity.getLateStageTriggerAmount()
: new BigDecimal("2");
: new BigDecimal("6");
// 后期池抽奖次数多 接近门槛
// 前期池1-15次
if (drawCount < earlyMax) {
return "EARLY";
}
// 后期池次数>=50 距离门槛<=6美元
BigDecimal gap = threshold.subtract(totalAmount);
if (drawCount >= middleMax && gap.compareTo(lateTrigger) <= 0) {
if (drawCount >= middleMax || gap.compareTo(lateTrigger) <= 0) {
return "LATE";
}
// 中期池抽奖次数中等
if (drawCount >= earlyMax) {
return "MIDDLE";
}
// 前期池
return "EARLY";
// 中期池16-49次
return "MIDDLE";
}
/**
@ -258,7 +257,7 @@ public class LotteryDrawExe {
}
/**
* 过滤会超过门槛的奖品.
* 过滤会超过门槛的奖品新增前期拿大奖后的慢速模式.
*/
private List<LotteryPrize> filterOverThresholdPrizes(List<LotteryPrize> prizes,
LotteryUserProgress progress,
@ -268,14 +267,30 @@ public class LotteryDrawExe {
}
BigDecimal currentAmount = progress.getTotalAmount();
int drawCount = progress.getTotalDrawCount();
// 如果已经达到门槛本周不再发放任何奖
// 如果已经达到门槛只允许发虚拟物
if (currentAmount.compareTo(threshold) >= 0) {
log.info("User reached threshold, no more prizes this week. userId: {}, amount: {}",
progress.getUserId(), currentAmount);
return new ArrayList<>();
// 只允许发虚拟物品
return prizes.stream()
.filter(prize -> prize.getPrizeValue().compareTo(BigDecimal.ZERO) == 0)
.collect(Collectors.toList());
}
// 特殊情况前期<50次已经拿到>=5美元进入"慢速模式"
if (currentAmount.compareTo(new BigDecimal("5.0")) >= 0 && drawCount < 50) {
log.info("User got big prize early, entering slow mode. userId: {}, amount: {}, count: {}",
progress.getUserId(), currentAmount, drawCount);
// 只允许0.1美元和虚拟物品prize_value<=0.15
return prizes.stream()
.filter(prize -> prize.getPrizeValue().compareTo(new BigDecimal("0.15")) <= 0)
.collect(Collectors.toList());
}
// 正常防超额过滤
return prizes.stream()
.filter(prize -> {
// 过滤掉会让用户超过门槛的大奖