抽奖功能实现

作者: 刺風 | 来源:发表于2017-10-31 21:39 被阅读52次
    一、实现原理:
    1. 获取所有的奖品信息;
    2. 遍历奖品,获取每个奖品的中奖率,注意:所有的奖品中奖率加起来不能超过100,最小值为0.01;
    3. 根据奖品中奖率计算奖品中奖区间(区间+=中奖率 x 10000),注意:10000越大中奖率越精确;
    4. 设置随机数,控制在 (100 x 10000)内去生成,注意: 100乘的数和上面的中奖率乘的数一致;
    5. 循环区间集合,如果随机数在某个区间内,返回具体的奖品,因为计算的区间集合和奖品集合是一致的,
      所以可以根据当前循环的次数找到对应的奖品集合中的奖品。
    6. 配合分布式锁更好用哦!
    二、实现代码
       /**
         * @Title getLotteryPrize
         * @Description 计算抽奖概率,并随机进行抽奖 概率算法:每个奖品的中奖率*10000  区间算法
         * @author 刺风
         * @param prizes 奖品列表集合对象
         * @return LotteryPrizeEntity 中奖则返回奖品对象,未中奖或者奖品已被抽完则返回null
         */
        private LotteryPrizeEntity getLotteryPrize(List<LotteryPrizeEntity> prizes) {
            LotteryPrizeEntity lotteryPrizeEntity=null;  //声明要返回的奖品对象
            Long times = System.currentTimeMillis();     //获取当前时间
            int totalPro = 0;                            //总的概率区间
            //用于存储每个奖品新的概率区间
            List<Integer> proSection = new ArrayList<Integer>();
            proSection.add(0);                           //设置初始值
            //遍历每个奖品,设置概率区间,总的概率区间为每个概率区间的总和
            for (LotteryPrizeEntity p : prizes) {
                //每个概率区间为奖品概率乘以10000(把概率放大一万倍)
                totalPro += (p.getProbability() * 10000);
                log.info("【用户抽奖】各个奖品区间值PrizeName:"+p.getPrizeName() + "     totalPro:" + totalPro);
                proSection.add(totalPro);
            }
            log.info(("【用户抽奖】奖品的总区间为  totalPro:" + totalPro));
            if (totalPro == 0) {
                return null;
            }
            //获取总的概率区间中的随机数
            Random random = new Random();
            int randomPro = random.nextInt(100*10000);//获取100万内随机产生的数
            //判断取到的随机数在哪个奖品的概率区间中
            log.info("【用户抽奖】 本次获取区间随机数为:" + randomPro);
            int count= (proSection.size()- 1);
            for (int i = 0; i <count; i++) {
                if (i ==count) {
                    if (randomPro >= proSection.get(i)) {
                        log.info("【用户抽奖】 获得的奖品为LotteryPrizeEntity:" + Jackson2Helper.toJsonString(prizes.get(i)));
                        lotteryPrizeEntity=prizes.get(i);
                        break;
                    }
                } else {
                    if (randomPro >= proSection.get(i) && randomPro < proSection.get(i + 1)) {
                        log.info("【用户抽奖】 获得的奖品为LotteryPrizeEntity:" + Jackson2Helper.toJsonString(prizes.get(i)));
                        lotteryPrizeEntity=prizes.get(i);
                        break;
                    }
                }
            }
            //验证奖品中奖数量是否大于奖品数量
            if(Utils.isNotNull(lotteryPrizeEntity)){
                //如果奖品总数-中奖数量-当前奖品 的结果大于0表示中奖数量未超出,可以返回奖品,否则
                int num=lotteryPrizeEntity.getPrizeNum()-lotteryPrizeEntity.getLotteryNum()-1;
                if(num>=0){
                    return lotteryPrizeEntity;
                }else{
                    //奖品已被抽光
                    log.info("【用户抽奖】奖品已被抽光,返回空的奖品信息,按未中奖处理");
                }
            }else{
                //如果超出实际奖品区间范围则表示未中奖
                log.info("【用户抽奖】中奖概率计算,随机数为:    "+randomPro+"    未在奖品区间内,未中奖");
            }
    
            return null;
        }
    

    贴一下LotteryPrizeEntity实体类(奖品实体类)的代码:

    package com.wtoip.platform.porsche.entity.lottery;
    
    import com.wtoip.platform.porsche.entity.BaseEntity;
    
    import java.util.Date;
    import java.util.List;
    
    public class LotteryPrizeEntity extends BaseEntity {
        //主键
        private Integer id;
        //奖品名称
        private String prizeName;
        //奖品类型
        private String prizeType;
        //奖品数量
        private Integer prizeNum;
        //中奖率
        private Double probability;
        //奖品图片地址
        private String prizeUrl;
        //创建时间
        private Date createTime;
        //修改时间
        private Date updateTime;
        //抽奖活动主键
        private Integer lotteryInfoId;
        //是否允许重复抽奖
        private String prizeManyYn;
        //中奖数量
        private Integer lotteryNum;
        //描述信息
        private String description;
        //奖品级别
        private String prizeLevel;
        //优惠券ID
        private String couponId;
        //位置排序
        private String sortNum;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getPrizeName() {
            return prizeName;
        }
    
        public void setPrizeName(String prizeName) {
            this.prizeName = prizeName == null ? null : prizeName.trim();
        }
    
        public String getPrizeType() {
            return prizeType;
        }
    
        public void setPrizeType(String prizeType) {
            this.prizeType = prizeType == null ? null : prizeType.trim();
        }
    
        public Integer getPrizeNum() {
            return prizeNum;
        }
    
        public void setPrizeNum(Integer prizeNum) {
            this.prizeNum = prizeNum;
        }
    
        public Double getProbability() {
            return probability;
        }
    
        public void setProbability(Double probability) {
            this.probability = probability;
        }
    
    
        public String getPrizeUrl() {
            return prizeUrl;
        }
    
        public void setPrizeUrl(String prizeUrl) {
            this.prizeUrl = prizeUrl == null ? null : prizeUrl.trim();
        }
    
        public Date getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    
        public Date getUpdateTime() {
            return updateTime;
        }
    
        public void setUpdateTime(Date updateTime) {
            this.updateTime = updateTime;
        }
    
        public Integer getLotteryInfoId() {
            return lotteryInfoId;
        }
    
        public void setLotteryInfoId(Integer lotteryInfoId) {
            this.lotteryInfoId = lotteryInfoId;
        }
    
        public String getPrizeManyYn() {
            return prizeManyYn;
        }
    
        public void setPrizeManyYn(String prizeManyYn) {
            this.prizeManyYn = prizeManyYn == null ? null : prizeManyYn.trim();
        }
    
        public Integer getLotteryNum() {
            return lotteryNum;
        }
    
        public void setLotteryNum(Integer lotteryNum) {
            this.lotteryNum = lotteryNum;
        }
    
        public String getDescription() {
            return description;
        }
    
        public void setDescription(String description) {
            this.description = description == null ? null : description.trim();
        }
    
        public String getPrizeLevel() {
            return prizeLevel;
        }
    
        public void setPrizeLevel(String prizeLevel) {
            this.prizeLevel = prizeLevel;
        }
    
        public String getCouponId() {
            return couponId;
        }
    
        public void setCouponId(String couponId) {
            this.couponId = couponId;
        }
    
        public String getSortNum() {
            return sortNum;
        }
    
        public void setSortNum(String sortNum) {
            this.sortNum = sortNum;
        }
    }
    

    相关文章

      网友评论

        本文标题:抽奖功能实现

        本文链接:https://www.haomeiwen.com/subject/ugripxtx.html