程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java抽獎搶購算法

Java抽獎搶購算法

編輯:關於JAVA

Java抽獎搶購算法。本站提示廣大學習愛好者:(Java抽獎搶購算法)文章只能為提供參考,不一定能成為您想要的結果。以下是Java抽獎搶購算法正文


本文示例為年夜家分享了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;
  }

以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved