根据权重抽奖模块

业务中不少地方用到根据权重来抽奖的逻辑,封装出公用的逻辑。
@Service
public class GeneratePrizeByWeightService {

    private static final Logger LOG = LoggerFactory.getLogger(GeneratePrizeByWeightService.class);

    public String getReward(String rewardStr) {
        if(StringUtils.isEmpty(rewardStr)) {
            return "";
        }
        List<ActiveTaskConfValueDto> rewardList = JSON.parseArray(rewardStr, ActiveTaskConfValueDto.class);
        if(rewardList == null || rewardList.size() == 0) {
            return "";
        }
        return getRewardByWeight(rewardList);
    }

    public String getRewardByWeight(List<ActiveTaskConfValueDto> prizes) {

        int random = -1;
        try {
            //计算总权重
            double sumWeight = 0;
            for (ActiveTaskConfValueDto prize : prizes) {
                sumWeight += prize.getWeight();
            }

            //产生随机数
            double randomNumber;
            randomNumber = Math.random();

            //根据随机数在所有奖品分布的区域并确定所抽奖品
            double beginRange = 0;
            double endRange = 0;
            for (int i = 0; i < prizes.size(); i++) {
                endRange += Double.parseDouble(String.valueOf(prizes.get(i).getWeight())) / sumWeight;
                if (i == 0) {
                    beginRange = 0;
                } else {
                    beginRange += Double.parseDouble(String.valueOf(prizes.get(i - 1).getWeight())) / sumWeight;
                }
                if (randomNumber >= beginRange && randomNumber <= endRange) {
                    random = i;
                    break;
                }
            }
        } catch (Exception e) {
            LOG.info("[GeneratePrizeByWeightService.getRewardByWeight] 根据权重获取奖励异常,e:{}", e);
            return "";
        }
        return prizes.get(random).getRpCode();
    }
}
public class ActiveTaskConfValueDto {

    private String rpCode;

    private int  weight;

    public String getRpCode() {
        return rpCode;
    }

    public void setRpCode(String rpCode) {
        this.rpCode = rpCode;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }
}

 

 

测试数据{
    "memberId" : "123",
    "prizesConfig" : "[{\"rpCode\":\"HYYXJ_tongyong_10\",\"weight\":40},{\"rpCode\":\"HYYXJ_dianyin_10\",\"weight\":20},{\"rpCode\":\"HYYXJ_huafei_10\",\"weight\":20},{\"rpCode\":\"HYYXJ_yingyin_10\",\"weight\":20}]"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值