本文示例为大家分享了Java抽奖抢购算法,供大家参考,具体内容如下
应用场景
单件奖品抢购(可限时)
多件奖品按概率中奖(可限时、可不限量)
代码实现
表结构:
--抽奖设置 create table AWARD_INFO ( ID NUMBER(11) not null, ACT_ID NUMBER(11), --活动ID NUM NUMBER(11), --奖品总量(0为不限量) REST NUMBER(11), --奖品余量 ODDS NUMBER(11) default 0, --中奖概率 START_DATE DATE, --开始日期(可为空) END_DATE DATE, --结束日期(可为空) PRODUCT_ID NUMBER(11), --奖品ID STATE NUMBER(5) default 0, --状态 0-有效 1-失效 INFO_TYPE NUMBER(5) default 0 --0-正常 ); alter table AWARD_INFO add constraint PK_AWARD_INFO primary key (ID); --中奖纪录 create table AWARD_LOG ( id number(11), act_id number(11), --活动ID get_time date, --中奖时间 product_id number(11), --奖品ID num number(11) default 1, --中奖数量 person varchar2(50), --中奖人 info_id number(11), --抽奖设置ID state number(5) --状态 0-有效 1-失效 ); alter table AWARD_LOG add constraint PK_AWARD_LOG primary key (ID);
代码:
public static class AwardResult{ public int ret; //返回结果 public int logId; //AWARD_LOG id } /** * 抽奖算法 * @param actId 抽奖活动ID * @param person 抽奖人 * @param productId 奖品ID -1则为该活动ID下所有奖品 * @param excludeId 排除奖品ID -1 则不排除,与productId不能同时>0 * @param checkDate 是否检查时间 * @return -1 没有抽奖数据;-2 奖品已抽完; -3 其他错误;>=0 中奖productId; -4 排除id * @throws Exception */ public static AwardResult getAwardFull(int actId, String person, int productId, int[] excludeIds, boolean checkDate) throws SQLException{ AwardResult result = new AwardResult(); Connection conn = JDBC.getConnection(); conn.setAutoCommit(false); try{ List<Map<String,Object>> rows; String sql; String checkDateStr = ""; String baseSql = "select t.id, t.product_id, t.num, t.rest, t.odds, t.info_type from award_info t where t.act_id=? and t.state=0 "; if(checkDate){ checkDateStr = " and t.start_Date <= sysdate and t.end_Date >= sysdate "; } if(productId > 0){//抢购 sql = baseSql + " and t.product_id=? " + checkDateStr + " for update"; rows = JDBC.getRows(sql, new Object[]{actId, productId}, conn); }else{//活动所有物品抽奖 sql = baseSql + checkDateStr + " for update"; rows = JDBC.getRows(sql, new Object[]{actId}, conn); } if(rows.isEmpty()){//没有抽奖数据 log.info("没有抽奖数据 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); conn.commit(); result.ret = -1; return result; } int infoId = -1; int getProductId = -1; int num = -1; int rest = -1; if(rows.size() == 1){//抢购 num = ((Number)rows.get(0).get("NUM")).intValue(); rest = ((Number)rows.get(0).get("REST")).intValue(); infoId = ((Number)rows.get(0).get("ID")).intValue(); getProductId = ((Number)rows.get(0).get("PRODUCT_ID")).intValue(); }else{//抽奖 int[][] temp = new int[rows.size()][3]; int sum = -1; int i = 0; for(int k = 0; k < rows.size(); k++){//设置奖品池 int odds = ((BigDecimal)rows.get(k).get("ODDS")).intValue(); sum++; temp[i][0] = sum; //起始值 sum = sum + odds; temp[i][1] = sum; //结束值 temp[i][2] = k; //rows index i++; } //抽奖 Random random = new Random(); int r = random.nextInt(sum + 1); int j = 0; for(int k = 0; k < i; k++){ if(r >= temp[k][0] && r <= temp[k][1]){ j = k; break; } } infoId = ((BigDecimal)rows.get(temp[j][2]).get("ID")).intValue(); getProductId = ((BigDecimal)rows.get(temp[j][2]).get("PRODUCT_ID")).intValue(); num = ((Number)rows.get(temp[j][2]).get("NUM")).intValue(); rest = ((Number)rows.get(temp[j][2]).get("REST")).intValue(); } //判断是否排除id if(ArrayUtils.contains(excludeIds, getProductId)){ log.info("是排除ID actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); conn.commit(); result.ret = -4; return result; } //存量不足 if(num > 0 && rest <= 0){ log.info("奖品已清空 actId={} person={} productId={} excludeIds={} checkDate={}", actId, person, productId, excludeIds, checkDate); JDBC.commit(conn); result.ret = -2; return result; } //更新奖品记录 if(num > 0){//非不限量 sql = "update award_info set rest = rest - 1 where id = ?"; JDBC.update(sql, new Object[]{infoId}, conn); } //记录获奖名单 AwardLog log = new AwardLog(); log.setActId(actId); log.setNum(1); log.setPerson(person); log.setProductId(getProductId); log.setInfoId(infoId); Number logId = log.save(conn); if(logId == null){ throw new SQLException("save award_log error"); } result.logId = logId.intValue(); conn.commit(); result.ret = getProductId; return result; }catch(SQLException e){ log.error("getAward error", e); conn.rollback(); }finally{ JDBC.close(conn); } result.ret = -3; return result; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Java抽奖算法第二例,包括了Java抽奖算法第二例的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java抽奖算法,供大家参考,具体内容如下 1. 算法分析 根据概率将奖品划分区间,每个区间代表一个奖品,然后抽取随机数,反查落在那个区间上,即为所抽取的奖品。 2. 代码 核心算法 Prize bean 3. 测试 prize1概率: 5% prize2概率:
抽奖互动能够有效活跃直播间气氛,吸引更多观众参与直播互动 讲师端 说明: 1)自定义奖品名称:发起抽奖时可自定义抽奖名称,观看端进行显示 2)参与用户:可选择全部在线用户或本次直播未中奖用户参与抽奖(一场直播中,累计中奖人数不能超过2000人,否则发起抽奖时,如参与用户设置为未中奖用户则无法发起) 3)中奖人数:支持一次性抽取1-200个中奖用户 4)预设中奖用户:可基于在线用户列表提前选择中奖用
获取抽奖信息 Mudu.Room.LuckyDraw.Get(function (response) { response = JSON.parse(response) if (response.status === 'y') { console.log('获取成功,数据为:', response.data) } if (response.status === 'n') {
抽奖 调用抽奖,异步接口。若使用TidaSDK自带UI,则不用关心结果是什么,直接将结果缓存下来。调用Tida.showDrawResult时传入回调结果即可。 若需要定制化UI,有关结果数据结构见下面注释 /** * Tida.draw 抽奖接口回调 * @callback Tida~drawCallback * @param {object} result 结果数据对象 * @para
包括 抽奖接口、查询保存粉丝、抽奖记录等
Mudu.Room.LuckyDraw 抽奖组件 获取抽奖信息 Mudu.Room.LuckyDraw.Get(function (response) { response = JSON.parse(response) if (response.status === 'y') { console.log('获取成功,数据为:', response.data) } if (r