项目中竞猜模块的流程

概要

竞猜模块的流程涉及到主播开启竞猜,用户参与竞猜,以及用户参与一方之后就不能再参与另一方,还有竞猜的结算,竞猜结算要考虑到平局和流局的情况

整体架构流程

下面是创建竞猜的代码案例

        hash存储,大key是guessing,小key是主播id,value是竞猜对象数据,同时会创建两个hash奖池用来存储红蓝方的参与人的id及下注的金额

        //hash存竞猜信息
        BoundHashOperations guessing = redisTemplate.boundHashOps("guessing");
        tbGuessingVo.setGuessStatus("0");
        guessing.put(tbGuessingVo.getAid(),tbGuessingVo);
        TbGuessing tbGuessing = new TbGuessing();
        BeanUtils.copyProperties(tbGuessingVo,tbGuessing);
        tbGuessingMapper.insert(tbGuessing);
        //hash存竞猜选项1
        TbGuessingOptions options = new TbGuessingOptions();
        options.setGuessId(tbGuessing.getGuessId());
        options.setAttr1(0);
        options.setOnum(0L);
        options.setOmoney(0L);
        BoundHashOperations guessing1 = redisTemplate.boundHashOps(tbGuessing.getGuessId()+":"+options.getAttr1());
        guessing1.put(options.getOnum(),options.getOmoney());
        tbGuessingOptionsMapper.insert(options);
        //hash存竞猜选项2
        TbGuessingOptions options1 = new TbGuessingOptions();
        options1.setGuessId(tbGuessing.getGuessId());
        options1.setAttr1(1);
        options1.setOnum(0L);
        options1.setOmoney(0L);
        BoundHashOperations guessing2 = redisTemplate.boundHashOps(tbGuessing.getGuessId()+":"+options1.getAttr1());
        guessing2.put(options1.getOnum(),options1.getOmoney());
        tbGuessingOptionsMapper.insert(options1);

然后是用户参与竞猜

        一开始会判断前端传来的竞猜选项是红蓝哪一方,然后判断该用户是否在另一方下过注,如果下过就直接报错,然后向前端提示已经在另一方下过注,否则就查出该用户选择的阵营然后判断该用户是否在改阵营下过注,如果下过就在原基础上进行一个追加,没有就创建一个该用户的记录,最后远程调用用户服务对用户的金额进行一个扣减. 

        //判断用户选择的竞猜选项
        if (tbGuessingVo.getAttr1() == 0){
            //判断是否在另一个奖池下过注没
            BoundHashOperations hashOps1 = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 1);
            if (hashOps1.get(uid) != null){
                throw new RuntimeException("竞猜选项已存在");
            }
            //查出对应的竞猜选项,然后进行追加竞猜选项的人数和分数
            BoundHashOperations hashOps = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + tbGuessingVo.getAttr1());
            //判断用户是否竞猜过
            if (hashOps.get(uid) != null){
                Long o =  (Long)hashOps.get(uid);
                o += (long)tbGuessingVo.getNum();
                hashOps.put(uid,o);
                hashOps.delete(0L);
            }else{
                hashOps.put(uid,(long)tbGuessingVo.getNum());
                hashOps.delete(0L);
            }
        }else{
            //判断是否在另一个奖池下过注没
            BoundHashOperations hashOps1 = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 0);
            if (hashOps1.get(uid) != null){
                throw new RuntimeException("竞猜选项已存在");
            }
            //查出对应的竞猜选项,然后进行追加竞猜选项的分数
            BoundHashOperations hashOps = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + tbGuessingVo.getAttr1());
            //判断用户是否竞猜过
            if (hashOps.get(uid) != null){
                Long o = (Long) hashOps.get(uid);
                o += (long)tbGuessingVo.getNum();
                hashOps.put(uid,o);
                hashOps.delete(0L);
            }else{
                hashOps.put(uid,(long)tbGuessingVo.getNum());
                hashOps.delete(0L);
            }
        }
        tbUserApi.subtractMoney(uid,(long)tbGuessingVo.getNum());

最后是竞猜的结算

        首先判断竞猜状态是结束还是流盘,如果是结束就把竞猜记录入库然后查寻redis,查出胜利方和失败方的全部人的id,以及下注金额,然后进行一个入库,我们是通过向胜利方,算出他们每个人下注的占比进行瓜分失败方的总奖池,然后他们下注的金额会原路返回.通过把用户id和赢得的金额进行封装存入list,最后远程调用用户服务进行用户的金额添加.如果是流盘就把用户下注的金额进行原路返还(平局和流盘是一样的).
 

        TbGuessing tbGuessing = new TbGuessing();
        BeanUtils.copyProperties(tbGuessingVo,tbGuessing);
        //结束竞猜
       if (tbGuessingVo.getGuessStatus().equals("3")){
           tbGuessingMapper.updateById(tbGuessing);
           //存入竞猜记录表
           TbGuessingHistory history = new TbGuessingHistory();
           history.setUid(uid);
           history.setGuessId(tbGuessingVo.getGuessId());
           history.setLid(tbGuessingVo.getLid());
           tbspHistoryMapper.insert(history);
           //从redis取出竞猜选项总金额和猜对的人数
           if (tbGuessingVo.getAttr1() == 0){
               //查出失败方奖池中的金额
               BoundHashOperations ops1 = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 1);
               Set keys1 = ops1.keys();
               AtomicReference<Long> num1 = new AtomicReference<>((long) 0);
               keys1.forEach(key -> {
                   num1.updateAndGet(v -> v + 1);
               });
               List<Long> values1 = ops1.values();
               Long sum1 = Long.valueOf(0);
               for (Long intValue : values1) {
                   sum1 += intValue;
               }
               //入库数据
               TbGuessingOptions options1 = new TbGuessingOptions();
               options1.setGuessId(tbGuessingVo.getGuessId());
               options1.setOnum(num1.get());
               options1.setOmoney(sum1);
               options1.setAttr1(1);
               tbGuessingOptionsMapper.updateByGuessIdAndAttr1(options1);
               //获取胜利方奖池总额
               BoundHashOperations ops = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + tbGuessingVo.getAttr1());
               Set keys = ops.keys();
               AtomicReference<Long> num = new AtomicReference<>((long) 0);
               keys.forEach(key -> {
                   num.updateAndGet(v -> v + 1);
               });
               List<Long> values = ops.values();
               Long sum = Long.valueOf(0);
               for (Long intValue : values) {
                   sum += intValue;
               }
               //入库数据
               TbGuessingOptions options = new TbGuessingOptions();
               options.setGuessId(tbGuessingVo.getGuessId());
               options.setOnum(num.get());
               options.setOmoney(sum);
               options.setAttr1(0);
               tbGuessingOptionsMapper.updateByGuessIdAndAttr1(options);
               List<TbUser> list = new ArrayList<>();
               //向胜利方发放虚拟币
               for (Object key : keys) {
                   //获取每个人的押注
                   Object value = ops.get(key);
                   //计算用户赢得的虚拟币
                   Long money =  (sum1 / sum * (Long) value + (Long) value);
                   //远程调用给用户增加金额
                   TbUser tbUser = new TbUser();
                   tbUser.setUid((Long) key);
                   tbUser.setPurse(BigDecimal.valueOf(money));
                   list.add(tbUser);
               }
               tbUserApi.addMoney1(list);
           } else if (tbGuessingVo.getAttr1() == 1) {
               //查出失败方奖池中的金额
               BoundHashOperations ops1 = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 0);
               Set keys1 = ops1.keys();
               AtomicReference<Long> num1 = new AtomicReference<>((long) 0);
               keys1.forEach(key -> {
                   num1.updateAndGet(v -> v + 1);
               });
               List<Long> values1 = ops1.values();
               Long sum1 = Long.valueOf(0);
               for (Long intValue : values1) {
                   sum1 += intValue;
               }
               //入库数据
               TbGuessingOptions options1 = new TbGuessingOptions();
               options1.setGuessId(tbGuessingVo.getGuessId());
               options1.setOnum(num1.get());
               options1.setOmoney(sum1);
               options1.setAttr1(0);
               tbGuessingOptionsMapper.updateByGuessIdAndAttr1(options1);
               //获取胜利方奖池总额
               BoundHashOperations ops = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + tbGuessingVo.getAttr1());
               Set keys = ops.keys();
               AtomicReference<Long> num = new AtomicReference<>((long) 0);
               keys.forEach(key -> {
                   num.updateAndGet(v -> v + 1);
               });
               List<Long> values = ops.values();
               Long sum = Long.valueOf(0);
               for (Long intValue : values) {
                   sum += intValue;
               }
               //入库数据
               TbGuessingOptions options = new TbGuessingOptions();
               options.setGuessId(tbGuessingVo.getGuessId());
               options.setOnum(num.get());
               options.setOmoney(sum);
               options.setAttr1(1);
               tbGuessingOptionsMapper.updateByGuessIdAndAttr1(options);
               //向胜利方发放虚拟币
               List<TbUser> list = new ArrayList<>();
               for (Object key : keys) {
                   //获取每个人的押注
                   Object value = ops.get(key);
                   //计算用户赢得的虚拟币
                   Long money =  (sum1 / sum * (Long) value + (Long) value);
                   //远程调用给用户增加金额
                   TbUser tbUser = new TbUser();
                   tbUser.setUid((Long) key);
                   tbUser.setPurse(BigDecimal.valueOf(money));
                   list.add(tbUser);
               }
               tbUserApi.addMoney1(list);
           }
       }else if (tbGuessingVo.getGuessStatus().equals("4")){
           //流盘
           tbGuessingMapper.updateById(tbGuessing);
           List<TbUser> list = new ArrayList<>();
           BoundHashOperations ops = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 0);
           Set keys = ops.keys();
           for (Object key : keys) {
               Long value = (long)ops.get(key);
               TbUser tbUser = new TbUser();
               tbUser.setUid((Long) key);
               tbUser.setPurse( BigDecimal.valueOf(value));
           }
           BoundHashOperations ops1 = redisTemplate.boundHashOps(tbGuessingVo.getGuessId() + ":" + 1);
           Set keys1 = ops1.keys();
           for (Object key : keys1) {
               Long value = (long)ops1.get(key);
               TbUser tbUser = new TbUser();
               tbUser.setUid((Long) key);
               tbUser.setPurse(BigDecimal.valueOf(value));
           }
           tbUserApi.addMoney1(list);
       }

小结

结算代码没有优化,使用redis的时候注意存入数据的类型要和取出来的一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值