抽奖方案实现原理

前一段时间需要公司网站需要做一个活动的抽奖页面,要求后台可以对奖品设置概率。几番周折,终于搞了出来。

假设一个活动的所有奖品总概率为1,最小中奖概率可以设置到为0.000001(百万分之一),实现的方案如下:

奖品名称中奖概率中奖开始范围中奖结束范围
奖品10.11100000
奖品20.5100001600000
奖品30.000012600001600012
奖品40-1-1

如上表格所示:

1、在新增、修改商品的时候我们只需要往数据库表里面插入中奖概率即可,注意插入之前判断下中概率不能超过1

2、每次新增修改完调用一个方法,自动计算并更新中奖范围。计算方式是:得到该活动下的所有奖品数据,循环到第一条数据时开始范围设置为1,

      结束范围=开始范围+100W*中奖概率,更新表。

      然后循环到第一条以后的数据时候:开始范围=上个奖品的结束范围+1,结束范围=本次开始范围+100W*中奖概率-1,更新表。

      如果概率是0,直接开始和结束范围插入-1就行了。

3、抽奖的时候随机1-100W数字,然后判断下是几等奖就行了。

4、中奖概率之和可以不用等于1,但是不能大于1。

计算中将范围的代码:

        /**
	 * 按照改每个活动下的每个奖品概率重新计算并更新上下限
	 * PS:这段代码只有我和上帝能看懂,不要试图修改它。。。
	 */
	@Override
	public void updateLuckyGoodsStartAndEnd(String cust_id, String lucky_draw_activity_id) {
		List<Map<String, Object>> l = luckyDrawGoodsDao.getLuckyGoodsList(cust_id, lucky_draw_activity_id);
		String prize_start_number = "";
		String prize_end_number = "";
		for (int i = 0; i < l.size(); i++) {
			HashMap<String, String> luckyGoodsMap = new HashMap<String, String>();
			HashMap<String, String> wheremap = new HashMap<String, String>();
			
			String lucky_draw_goods_info_id = StringUtil.nvl(l.get(i).get("lucky_draw_goods_info_id"));
			float prize_percent = Float.parseFloat(StringUtil.nvl(l.get(i).get("prize_percent")));
			
			if (prize_percent == 0) {
				//如果概率是0 直接复制-1  不参与下面的计算
				luckyGoodsMap.put("prize_start_number", "-1");
				luckyGoodsMap.put("prize_end_number", "-1");
				
				wheremap.put("lucky_draw_goods_info_id", lucky_draw_goods_info_id);
				baseDao.updateSelective("lucky_draw_goods_info", luckyGoodsMap, wheremap,"jdbcTemplate_mysql_jscy_goods");
				continue;
			}
			
			//处理第一条数据
			if ("".equals(prize_start_number) && "".equals(prize_end_number)) {
				prize_start_number = "1";
				prize_end_number = (int)(prize_percent * 100 * 10000) + "";
			}
			else {
				prize_start_number = Integer.parseInt(prize_end_number) + 1 + "";
				prize_end_number = (int)(Integer.parseInt(prize_start_number) + prize_percent * 100 * 10000 -1) + "";
			}
			
			luckyGoodsMap.put("prize_start_number", prize_start_number);
			luckyGoodsMap.put("prize_end_number", prize_end_number);
			
			wheremap.put("lucky_draw_goods_info_id", lucky_draw_goods_info_id);
			
			baseDao.updateSelective("lucky_draw_goods_info", luckyGoodsMap, wheremap,"jdbcTemplate_mysql_jscy_goods");
		}		
	}


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值