项目中福袋模块的流程案例(仅供参考)

概要

        流程涉及到主播发放福袋,用户参与福袋,以及福袋的开奖,案例涉及到redis

   然后福袋开奖结果类似于某音,每个人获得的虚拟币相差不会太大,不会出现一家独大的情况

整体流程

        以下是流程的service层代码案例

        创建福袋:

        BoundHashOperations bag = redisTemplate.boundHashOps("blessingBag");
        //设置福袋状态
        tbBlessingBagVo.setBstatus("0");
        bag.put(tbBlessingBagVo.getAid(),tbBlessingBagVo);
        TbBlessingBag tbBlessingBag = new TbBlessingBag();
        BeanUtils.copyProperties(tbBlessingBagVo,tbBlessingBag);
        tbBlessingBagMapper.insert(tbBlessingBag);
        //往对应的主播账户扣除虚拟币  api(vo.aid,vo.money)
        tbAncthorApi.updatePurse(tbBlessingBagVo.getAid(),tbBlessingBagVo.getMoney());

        用户参与福袋:

        

        //根据主播的bid去redis创建set用来存放参与的用户的uid
        BoundSetOperations<Serializable, Integer> join = redisTemplate.boundSetOps(bid);
        join.add(uid);

        福袋开奖:

                 这里写到如果参与人数达不到中奖人数,会把福袋金额分成参与人数的份数去分配

        BoundHashOperations bag = redisTemplate.boundHashOps("blessingBag");
        //福袋数据
        TbBlessingBag tbBlessingBag = (TbBlessingBag) bag.get(aid);
        //获取福袋金额
        Long a = tbBlessingBag.getMoney();
        //获取福袋中奖人数
        Integer participants = tbBlessingBag.getNum();
        //根据福袋id从redis中取出set集合
        BoundSetOperations<java.io.Serializable, Integer> setOps = redisTemplate.boundSetOps(bid);
        Set<Integer> members = setOps.members();
        Integer num = members.size();
        //修改福袋状态
        tbBlessingBag.setBstatus("1");
        tbBlessingBagMapper.updateById(tbBlessingBag);
        //如果参与人数小于中奖人数
        if (participants > num){
            //随机找出的中奖人的id集合
            Set<Integer> randomValues = getRandomValues(members, num);
            randomValues = randomValues.stream()
                    .map(i -> i + 1)
                    .collect(Collectors.toSet());
            //随机金额数组
            int[] allocations = distributeVirtualCoins(totalCoins, num);
            List<TbUser> list = new ArrayList<>();
            int i = 0;
            for (Integer randomValue : randomValues) {
                TbUser tbUser = new TbUser();
                tbUser.setUid(Long.valueOf(randomValue));
                tbUser.setPurse(BigDecimal.valueOf(allocations[i]));
                list.add(tbUser);
                TbBlessingBagWinRecord winRecord = new TbBlessingBagWinRecord();
                winRecord.setBid(Long.valueOf(bid));
                winRecord.setUid(Long.valueOf(randomValue));
                winRecord.setWinMoney((long) allocations[i]);
                tbspBagWinRecordMapper.insert(winRecord);
                i++;
            }
            tbUserApi.addMoney1(list);
            return JsonResult.SUCCESS().setData(list);
        }else{
            //随机找出的中奖人的id集合
            Set<Integer> randomValues = getRandomValues(members, participants);
            randomValues = randomValues.stream()
                    .map(i -> i + 1)
                    .collect(Collectors.toSet());
            //随机金额数组
            int[] allocations = distributeVirtualCoins(totalCoins, participants);
            List<TbUser> list = new ArrayList<>();
            int i = 0;
            for (Integer randomValue : randomValues) {
                TbUser tbUser = new TbUser();
                tbUser.setUid(Long.valueOf(randomValue));
                tbUser.setPurse(BigDecimal.valueOf(allocations[i]));
                list.add(tbUser);
                TbBlessingBagWinRecord winRecord = new TbBlessingBagWinRecord();
                winRecord.setBid(Long.valueOf(bid));
                winRecord.setUid(Long.valueOf(randomValue));
                winRecord.setWinMoney((long) allocations[i]);
                tbspBagWinRecordMapper.insert(winRecord);
                i++;
            }
                tbUserApi.addMoney1(list);
                return JsonResult.SUCCESS().setData(list);
        }

 

    //算随机金额
    private static int[] distributeVirtualCoins(int totalCoins, int participants) {
        Random random = new Random();
        int[] allocations = new int[participants];

        // 初始平均分配
        int baseAllocation = totalCoins / participants;
        int remainder = totalCoins % participants; // 计算不能平均分配的余数

        // 将余数随机加到分配中去
        for (int i = 0; i < participants; i++) {
            if (i < remainder) {
                allocations[i] = baseAllocation + 1;
            } else {
                allocations[i] = baseAllocation;
            }
        }

        // 随机调整分配,但确保调整幅度小
        for (int i = 0; i < allocations.length; i++) {
            adjustAllocationWithinRange(allocations, i, 1); // 这里假设最大调整幅度为1
        }

        return allocations;
    }

    private static void adjustAllocationWithinRange(int[] allocations, int index, int range) {
        Random random = new Random();
        // 确保调整在[-range, range]内,并排除0,以实现实际的调整
        int adjustment = random.nextInt(2 * range + 1) - range;
        // 调整当前索引处的分配,同步调整另一随机选中的分配,以保持总和不变
        if (adjustment != 0 && allocations[index] + adjustment >= 0) {
            int adjustIndex = (index + random.nextInt(allocations.length - 1) + 1) % allocations.length;
            if (allocations[adjustIndex] - adjustment >= 0) { // 确保调整后不会出现负数
                allocations[index] += adjustment;
                allocations[adjustIndex] -= adjustment;
            }
        }
    }
    //算随机人
    public static Set<Integer> getRandomValues(Set<Integer> set, int count) {
        List<Integer> valuesList = new ArrayList<>(set);
        Collections.shuffle(valuesList); // 打乱集合顺序

        Set<Integer> randomValues = new HashSet<>();
        for (int i = 0; i < Math.min(count, valuesList.size()); i++) {
            randomValues.add(valuesList.get(i));
        }

        return randomValues;
    }

小结

        在使用redis的时候,记得存进去的数据类型要和取出来的数据类型保持一致.

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值