zoukankan      html  css  js  c++  java
  • 关于网站签到功能的设计

    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

    no pays,no gains!
  • 相关阅读:
    PAT 甲级 1115 Counting Nodes in a BST (30 分)
    PAT 甲级 1114 Family Property (25 分)
    PAT 甲级 1114 Family Property (25 分)
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2871729.html
Copyright © 2011-2022 走看看