關於網站簽到功能的設計


1,最近網站要上一個簽到的功能,一個多游戲的平台,每種游戲的官網都有簽到功能,設計打算把數據放到平台。

 

2,首先要設計簽到表,這里直接給出過了一遍dba,需求人員,設計人員腦子的結果:

 

 

最精彩的地方是signHistory的設計,直接存成bigint,通過轉換成二進制來記錄簽到的歷史;

 

3,預覽圖

 

4,功能抽取

非常明顯,只有三個主要的功能,第一個簽到之前的登錄;第二個,簽到;第三個,領取禮包;

功能                  功能概述 功能的具體邏輯  接口方法設計
登錄之前的查詢 通過查詢,以前簽過到的,顯示簽到歷史;沒有簽過到的,神馬也不顯示; 查詢dt_sign表,通過gid和uid查詢,如果查詢到,返回簽到信息,如果沒有查到,返回提示信息  SignMsg loginQuery(int gid,int uid)
簽到 點擊簽到,如果當天已經簽過到了,提示已經簽過到了;如果從來沒有簽過到,插入數據,把積分設置為1,連續簽到次數設置為1,最后修改時間設置為當天,歷史為1;如果今天沒有簽過到,首先計算出有多少天沒簽到了,如果是昨天簽了的,連續簽到次數加1,歷史左移一位,積分按照積分規則加上;如果超過兩天沒有簽到,連續簽到次數設置為1,歷史左移天數位,積分加上簽到單次的積分,時間為當前的修改時間; 首先查詢dt_sign,按照gid和uid,如果沒查到,插入記錄;查到了,判斷最后修改時間,做相應的處理; SignMsg todaySign(int gid,int uid)
領取禮包 點擊領取禮包,如果分數夠,減去積分,允許該用戶領取禮包;如果分數不過,提示積分不夠; 點擊領取禮包,如果分數夠,減去積分,允許該用戶領取禮包;如果分數不過,提示積分不夠; SignMsg getGiftPack(int gid,int uid,int score)

 

5,具體實現

jdbc實現:

  1 package com.sz7road.userplatform.dao.jdbc;
  2 
  3 import com.google.common.base.Strings;
  4 import com.sz7road.userplatform.dao.SignDao;
  5 import com.sz7road.userplatform.ws.sign.ScoreRuleAndMoveByte;
  6 import com.sz7road.userplatform.ws.sign.Sign;
  7 import com.sz7road.userplatform.ws.sign.SignObject;
  8 import com.sz7road.utils.CommonDateUtils;
  9 import org.apache.commons.dbutils.DbUtils;
 10 import org.slf4j.Logger;
 11 import org.slf4j.LoggerFactory;
 12 
 13 import java.sql.*;
 14 import java.text.ParseException;
 15 import java.text.SimpleDateFormat;
 16 import java.util.*;
 17 import java.util.Date;
 18 
 19 /**
 20  * Created with IntelliJ IDEA.
 21  * User: cutter.li
 22  * Date: 13-1-18
 23  * Time: 上午11:01
 24  */
 25 public class SignDaoJdbcImp extends JdbcDaoSupport<SignObject> implements SignDao {
 26 
 27     private final static Logger log = LoggerFactory.getLogger(SignDaoJdbcImp.class);
 28 
 29     private Connection conn = null;
 30 
 31     @Override
 32     public Sign querySign(int uid, int gid) {
 33         Sign sign = new Sign();
 34         ResultSet rs = null;
 35         PreparedStatement preparedStatement = null;
 36         try {
 37             conn = getQueryRunner().getDataSource().getConnection();
 38             preparedStatement = conn.prepareStatement(" select * from db_userplatform.dt_sign where userid=? and gameid=? ;");
 39 
 40             preparedStatement.setInt(1, uid);
 41             preparedStatement.setInt(2, gid);
 42 
 43             rs = preparedStatement.executeQuery();
 44             if (rs.next()) {
 45                 sign.setCode(200);
 46                 sign.setMsg("成功的查詢到簽到信息!");
 47                 sign.setContinueSignCount(rs.getInt("signCount"));
 48                 sign.setTotalScore(rs.getInt("integration"));
 49                 sign.setLastModifyDate(new Date(rs.getDate("lastModifyTime").getTime()));
 50                 sign.setSignHistory(rs.getLong("signHistory"));
 51             } else {
 52                 sign.setCode(300);
 53                 sign.setMsg("該用戶從來沒有簽過到!");
 54             }
 55 
 56         } catch (SQLException e) {
 57             sign.setCode(404);
 58             sign.setMsg("平台或者db異常!");
 59             e.printStackTrace();
 60         } finally {
 61             DbUtils.closeQuietly(rs);
 62             try {
 63                 DbUtils.close(preparedStatement);
 64             } catch (SQLException e) {
 65                 e.printStackTrace();
 66             }
 67             DbUtils.closeQuietly(conn);
 68         }
 69         return sign;
 70     }
 71 
 72 
 73     @Override
 74     public Sign signThenReturn(int uid, int gid) {
 75         Sign sign = new Sign();
 76         ResultSet rs = null;
 77         PreparedStatement preparedStatement = null, executePreparedStatement = null;
 78         try {
 79             conn = getQueryRunner().getDataSource().getConnection();
 80             preparedStatement = conn.prepareStatement(" select * from db_userplatform.dt_sign where userid=? and gameid=? ;");
 81             preparedStatement.setInt(1, uid);
 82             preparedStatement.setInt(2, gid);
 83 
 84             rs = preparedStatement.executeQuery();
 85             if (rs.next()) {//查到了更新
 86                 SignObject signObject = new SignObject();
 87                 signObject.setId(rs.getInt("id"));
 88                 signObject.setUid(rs.getInt("userid"));
 89                 signObject.setGid(rs.getInt("gameid"));
 90                 signObject.setSignCount(rs.getInt("signCount"));
 91                 signObject.setIntegration(rs.getInt("integration"));
 92                 signObject.setLastModifyTime(new Date(rs.getDate("lastModifyTime").getTime()));
 93                 signObject.setSignHistory(rs.getLong("signHistory"));
 94                 signObject.setExt(rs.getString("ext"));
 95 
 96 
 97                 Timestamp lastModifyTimeStamp = new Timestamp(signObject.getLastModifyTime().getTime());
 98                 Timestamp todayStartTimeStamp = CommonDateUtils.getTodayStartTimeStamp();
 99                 if (todayStartTimeStamp.after(lastModifyTimeStamp)) {//今天沒有簽過到
100                  final  long missDays= (System.currentTimeMillis()-signObject.getLastModifyTime().getTime())/(24*60*60*1000);
101                     int newSignCount=signObject.getSignCount();
102                     String newExt="簽到";
103                    if(missDays==1)
104                    {  //連續簽到,加分,連續簽到次數增加1 ,簽到歷史移動一位
105                      newSignCount+=1;
106                    }else
107                    {//不連續簽到,加分,連續簽到次數為1,簽到歷史移動missDays位
108                     newSignCount=1;
109                    }
110                     if(newSignCount>=91)
111                     { //簽到超過90天,連續簽到次數重置為1
112                         newSignCount=1;
113                         newExt="連續簽到天數重置為1,時間:"+CommonDateUtils.getDate(System.currentTimeMillis());
114                     }
115                    final long   newSignHistory= ScoreRuleAndMoveByte.moveByte(signObject.getSignHistory(),missDays);
116                   final int  newIntegration=signObject.getIntegration()+ScoreRuleAndMoveByte.getScoreByRule(newSignCount);
117                     executePreparedStatement = conn.prepareStatement(" update db_userplatform.dt_sign set signCount=? , integration=? , signHistory=? , lastModifyTime=? , ext=? where id=?; ");
118                     executePreparedStatement.setInt(1, newSignCount);
119                     executePreparedStatement.setInt(2, newIntegration);
120                     executePreparedStatement.setLong(3, newSignHistory);
121                     java.sql.Date signDate= new java.sql.Date(System.currentTimeMillis());

122                     executePreparedStatement.setDate(4,signDate);
123                     executePreparedStatement.setString(5,newExt);
124                     executePreparedStatement.setInt(6,signObject.getId());
125 
126                     int effectRows = executePreparedStatement.executeUpdate();
127 
128                     if (effectRows >= 1) {
129                         sign.setCode(206);
130                         sign.setMsg("簽到成功!成功更新數據!");
131                         sign.setContinueSignCount(newSignCount);
132                         sign.setLastModifyDate(signDate);
133                         sign.setTotalScore(newIntegration);
134                         sign.setSignHistory(newSignHistory);
135                     } else {
136                         sign.setCode(208);
137                         sign.setMsg("簽到失敗,更新數據失敗!");
138                     }
139                 }
140                 else
141                 {//今天已經簽過到了
142                     sign.setCode(300);
143                     sign.setMsg("該用戶今天已經簽過到了!");
144                     sign.setLastModifyDate(signObject.getLastModifyTime());
145                     sign.setContinueSignCount(signObject.getSignCount());
146                     sign.setSignHistory(signObject.getSignHistory());
147                     sign.setTotalScore(signObject.getIntegration());
148                 }
149 
150             } else {//沒查到,插入
151                 executePreparedStatement = conn.prepareStatement(" insert into db_userplatform.dt_sign(userid,gameid,signCount,integration,lastModifyTime,signHistory,ext) values(?,?,1,1,?,1,?); ");
152                 executePreparedStatement.setInt(1, uid);
153                 executePreparedStatement.setInt(2, gid);
154                final java.sql.Date insertDate= new java.sql.Date(System.currentTimeMillis());
155                 executePreparedStatement.setDate(3, insertDate);
156                  executePreparedStatement.setString(4,"首次簽到,時間:"+insertDate);
157                 int effectRows = executePreparedStatement.executeUpdate();
158 
159                 if (effectRows >= 1) {
160                     sign.setCode(200);
161                     sign.setMsg("該用戶第一次簽到!成功插入數據!");
162                     sign.setContinueSignCount(1);
163                     sign.setLastModifyDate(insertDate);
164                     sign.setTotalScore(1);
165                     sign.setSignHistory(1);
166                 } else {
167                     sign.setCode(204);
168                     sign.setMsg("該用戶第一次簽到,插入數據失敗!");
169                 }
170 
171             }
172         } catch (SQLException e) {
173             sign.setCode(404);
174             sign.setMsg("平台或者db異常!");
175             e.printStackTrace();
176         } finally {
177             DbUtils.closeQuietly(rs);
178             try {
179                 DbUtils.close(preparedStatement);
180             } catch (SQLException e) {
181                 e.printStackTrace();
182             }
183             DbUtils.closeQuietly(conn);
184         }
185         return sign;
186     }
187 
188     @Override
189     public Sign getGiftPackThenReturn(int uid, int gid, int giftPackScore) {
190         Sign sign = new Sign();
191         ResultSet rs = null;
192         PreparedStatement preparedStatement = null, executePreparedStatement = null;
193         try {
194             conn = getQueryRunner().getDataSource().getConnection();
195             preparedStatement = conn.prepareStatement(" select * from db_userplatform.dt_sign where userid=? and gameid=? and integration >=? ;");
196 
197             preparedStatement.setInt(1, uid);
198             preparedStatement.setInt(2, gid);
199             preparedStatement.setInt(3, giftPackScore);
200 
201             rs = preparedStatement.executeQuery();
202             if (rs.next()) { //如果查到了減去積分
203                 SignObject signObject = new SignObject();
204 
205                 signObject.setId(rs.getInt("id"));
206                 signObject.setUid(rs.getInt("userid"));
207                 signObject.setGid(rs.getInt("gameid"));
208                 signObject.setSignCount(rs.getInt("signCount"));
209                 signObject.setIntegration(rs.getInt("integration"));
210                 signObject.setLastModifyTime(new Date(rs.getDate("lastModifyTime").getTime()));
211                 signObject.setSignHistory(rs.getLong("signHistory"));
212                 signObject.setExt(rs.getString("ext"));
213 
214 
215                 executePreparedStatement = conn.prepareStatement(" update db_userplatform.dt_sign set integration=? where id=? ;");
216                 executePreparedStatement.setInt(1, signObject.getIntegration() - giftPackScore);
217                 executePreparedStatement.setInt(2, signObject.getId());
218 
219                 int effectRows = executePreparedStatement.executeUpdate();
220 
221                 if (effectRows >= 1) {
222                     sign.setCode(200);
223                     sign.setMsg("成功領取禮包,積分消耗" + giftPackScore);
224                     sign.setLastModifyDate(signObject.getLastModifyTime());
225                     sign.setContinueSignCount(signObject.getSignCount());
226                     sign.setSignHistory(signObject.getSignHistory());
227                     sign.setTotalScore(signObject.getIntegration() - giftPackScore);
228                 } else { //減去積分失敗
229                     sign.setCode(400);
230                     sign.setMsg("領取禮包失敗,積分沒有減去!");
231                 }
232             } else { //沒查到,說明積分不夠 返回300
233                 sign.setCode(300);
234                 sign.setMsg("積分不夠領取禮包!");
235             }
236         } catch (Exception e) {//發生異常則是404
237             sign.setCode(404);
238             sign.setMsg("平台或db異常");
239             e.printStackTrace();
240         } finally {
241             DbUtils.closeQuietly(rs);
242             try {
243                 DbUtils.close(preparedStatement);
244             } catch (SQLException e) {
245                 e.printStackTrace();
246             }
247             DbUtils.closeQuietly(conn);
248         }
249         return sign;
250     }
251 }


移位和規則類:

package com.sz7road.userplatform.ws.sign;

import java.math.BigInteger;

/**
 * Created with IntelliJ IDEA.
 * User: cutter.li
 * Date: 13-1-18
 * Time: 下午5:24
 * 移位和積分規則類
 */
public class ScoreRuleAndMoveByte {

    public static Long moveByte(long oldHistory,long moveAmonut)
    {
        long moveResult= oldHistory<<moveAmonut;
       long result=  Long.parseLong(toFullBinaryString(moveResult),2)+1;
        return result;
    }


    /**
     * 讀取
     * @param num
     * @return
     */
    private static String toFullBinaryString(long num) {
        final int size=42;
        char[] chs = new char[size];
        for(int i = 0; i < size; i++) {
            chs[size - 1 - i] = (char)(((num >> i) & 1) + '0');
        }
        return new String(chs);
    }

    /**
     * 按照積分規則,得到積分 ,
     * 積分規則如下:
     簽到功能說明
     1.每天只能簽到一次(按服務器系統時間為准)
     2.連續簽到 額外獎勵積分,同種禮包只能使用一次
     3.連續簽到10天,一次性獎勵2積分
     4.連續簽到30天,一次性獎勵10積分
     5.連續簽到60天,一次性獎勵30積分
     6.連續簽到90天,一次性獎勵100積分
     * @param signCount  連續簽到次數
     * @return 增加的積分
     */
    public static  int getScoreByRule(int signCount)
    {
        int addScore=1;

        if(signCount==10)
        {
            addScore+=2;
        }
        else if(signCount==30)
        {
            addScore+=10;
        }
        else if(signCount==60)
        {
            addScore+=30;
        }
        else if(signCount==90)
        {
            addScore+=100;
        }

        return addScore;
    }



    public static  void main(String[] args)
    {
       long result= moveByte(1,3);

        System.out.println("移位結果:"+result);

        System.out.println("連續簽到次數9:所增加的積分:"+getScoreByRule(9));
        System.out.println("連續簽到次數10:所增加的積分:"+getScoreByRule(10));
        System.out.println("連續簽到次數29:所增加的積分:"+getScoreByRule(29));
        System.out.println("連續簽到次數30:所增加的積分:"+getScoreByRule(30));
        System.out.println("連續簽到次數59:所增加的積分:"+getScoreByRule(59));
        System.out.println("連續簽到次數60:所增加的積分:"+getScoreByRule(60));
        System.out.println("連續簽到次數89:所增加的積分:"+getScoreByRule(89));
        System.out.println("連續簽到次數90:所增加的積分:"+getScoreByRule(90));
        System.out.println("連續簽到次數91:所增加的積分:"+getScoreByRule(91));
    }







}

 

  各位屌絲,有什么可以進一步優化的,歡迎聯系我,共同進步是我覺得最開心的事情!

2013-01-22  16:22:24

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM