项目开发中经常会有抽奖这样的营销活动的需求,例如:积分大转盘、刮刮乐、老虎机等等多种形式,其实后台的实现方法是一样的,本文介绍一种常用的抽奖实现方法,今天小编就来说说关于java抽奖程序代码?下面更多详细答案一起来看看吧!
java抽奖程序代码
概述
项目开发中经常会有抽奖这样的营销活动的需求,例如:积分大转盘、刮刮乐、老虎机等等多种形式,其实后台的实现方法是一样的,本文介绍一种常用的抽奖实现方法。
整个抽奖过程包括以下几个方面:
- 奖品
- 奖品池
- 抽奖算法
- 奖品限制
- 奖品发放
奖品
奖品包括奖品、奖品概率和限制、奖品记录。
奖品表:
CREATE TABLE `points_luck_draw_prize` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL COMMENT '奖品名称', `url` varchar(50) DEFAULT NULL COMMENT '图片地址', `value` varchar(20) DEFAULT NULL, `type` tinyint(4) DEFAULT NULL COMMENT '类型1:红包2:积分3:体验金4:谢谢惠顾5:自定义', `status` tinyint(4) DEFAULT NULL COMMENT '状态', `is_del` bit(1) DEFAULT NULL COMMENT '是否删除', `position` int(5) DEFAULT NULL COMMENT '位置', `phase` int(10) DEFAULT NULL COMMENT '期数', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=164 DEFAULT CHARSET=utf8mb4 COMMENT='奖品表';
奖品概率限制表:
CREATE TABLE `points_luck_draw_probability` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `points_prize_id` bigint(20) DEFAULT NULL COMMENT '奖品ID', `points_prize_phase` int(10) DEFAULT NULL COMMENT '奖品期数', `probability` float(4,2) DEFAULT NULL COMMENT '概率', `frozen` int(11) DEFAULT NULL COMMENT '商品抽中后的冷冻次数', `prize_day_max_times` int(11) DEFAULT NULL COMMENT '该商品平台每天最多抽中的次数', `user_prize_month_max_times` int(11) DEFAULT NULL COMMENT '每位用户每月最多抽中该商品的次数', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COMMENT='抽奖概率限制表';
奖品记录表:
CREATE TABLE `points_luck_draw_record` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `member_id` bigint(20) DEFAULT NULL COMMENT '用户ID', `member_mobile` varchar(11) DEFAULT NULL COMMENT '中奖用户手机号', `points` int(11) DEFAULT NULL COMMENT '消耗积分', `prize_id` bigint(20) DEFAULT NULL COMMENT '奖品ID', `result` smallint(4) DEFAULT NULL COMMENT '1:中奖 2:未中奖', `month` varchar(10) DEFAULT NULL COMMENT '中奖月份', `daily` date DEFAULT NULL COMMENT '中奖日期(不包括时间)', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=3078 DEFAULT CHARSET=utf8mb4 COMMENT='抽奖记录表';
奖品池
奖品池是根据奖品的概率和限制组装成的抽奖用的池子。主要包括奖品的总池值和每个奖品所占的池值(分为开始值和结束值)两个维度。最新面试题整理好了,点击Java面试库小程序在线刷题。
- 奖品的总池值:所有奖品池值的总和。
- 每个奖品的池值:算法可以变通,常用的有以下两种方式 :
- 奖品的概率*10000(保证是整数)
- 奖品的概率10000奖品的剩余数量
奖品池bean:
public class PrizePool implements Serializable{ /** * 总池值 */ private int total; /** * 池中的奖品 */ private List<PrizePoolBean> poolBeanList;}
池中的奖品bean:
public class PrizePoolBean implements Serializable{ /** * 数据库中真实奖品的ID */ private Long id; /** * 奖品的开始池值 */ private int begin; /** * 奖品的结束池值 */ private int end;}
奖品池的组装代码:
/** * 获取超级大富翁的奖品池 * @param zillionaireProductMap 超级大富翁奖品map * @param flag true:有现金 false:无现金 * @return */ private PrizePool getZillionairePrizePool(Map<Long, ActivityProduct> zillionaireProductMap, boolean flag) { //总的奖品池值 int total = 0; List<PrizePoolBean> poolBeanList = new ArrayList<>(); for(Entry<Long, ActivityProduct> entry : zillionaireProductMap.entrySet()){ ActivityProduct product = entry.getValue(); //无现金奖品池,过滤掉类型为现金的奖品 if(!flag && product.getCategoryId() == ActivityPrizeTypeEnums.XJ.getType()){ continue; } //组装奖品池奖品 PrizePoolBean prizePoolBean = new PrizePoolBean(); prizePoolBean.setId(product.getProductDescriptionId()); prizePoolBean.setBengin(total); total = total + product.getEarnings().multiply(new BigDecimal("10000")).intValue(); prizePoolBean.setEnd(total); poolBeanList.add(prizePoolBean); } PrizePool prizePool = new PrizePool(); prizePool.setTotal(total); prizePool.setPoolBeanList(poolBeanList); return prizePool; }
抽奖算法
整个抽奖算法为:
- 随机奖品池总池值以内的整数
- 循环比较奖品池中的所有奖品,随机数落到哪个奖品的池区间即为哪个奖品中奖。
推荐一个 Spring Boot 基础教程及实战示例: