您的位置:首页 > 编程语言 > Java开发

Java抽奖抢购算法

2016-08-03 14:19 429 查看

本文示例为大家分享了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 抽奖 抢购