本文示例为大家分享了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> 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;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。
希望与广大网友互动??
点此进行留言吧!