签到,打卡领取积分,记录连续签到,获取签到排名。

原创 2015年11月20日 12:13:24

签到,打卡领取积分,记录连续签到,获取签到排名。

1、签到表的设计

CREATE TABLE `signin` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userId` int(11) DEFAULT NULL COMMENT '用户ID',
  `signCount` int(11) DEFAULT NULL COMMENT '连续签到次数',
  `beforRank` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '前天签到排名',
  `yesRank` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '昨天签到排名',
  `todayRank` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '今天签到排名',
  `signHistory` bigint(4) DEFAULT NULL COMMENT '签到历史,bit位数表示历史签到',
  `modifyTime` datetime DEFAULT NULL COMMENT '签到时间(也即修改时间)',
  `ext` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '预留字段',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=gbk;

2、签到功能
2.1 签到

    /**
     * 签到
     */
    public void sign(){
        int userId=getParaToInt("id");
        Integer signCount=0;//连续签到次数
        long signHistory=0; //最精彩的设计之处:用bit位表示历史签到
        Date modifyTime=null;//最后签到时间
        Integer vantages=0; //用户表中积分
        String userName="";
        String msg=null;
        //获取用户积分
        String userSql="SELECT id,vantages FROM users WHERE id="+userId;
        Record user=Db.findFirst(userSql);
        if(user==null){
            msg="没有用户id";
            System.out.print("没有用户id");
            return ;
        }
        vantages=user.getInt("vantages");
        if(vantages==null){
            vantages=0;
        }
        //查询用户的签到表
        String signSql="SELECT id,userId,signCount,signHistory,modifyTime,beforRank,yesRank,todayRank "
                     + "FROM signIn WHERE userId="+userId;
        Record userSign=Db.findFirst(signSql);
        //现在时间应该是当天起始时间。
        Date todayStartTime=getTodayStartTime();
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String startTime=df.format(todayStartTime);
        if(userSign==null){//没有签到过,第一次签到,执行插入
            msg="欢迎您第一次签到";
            System.out.print("欢迎第一次签到");
            signHistory=moveByte(signHistory,1);
            signCount=1;
            vantages=vantages+1;
            modifyTime=new Date();//时间精度?timestamp
            SignIn signIn=new SignIn();
            signIn.set("userId", userId);
            signIn.set("signHistory",signHistory);
            signIn.set("signCount",signCount);
            signIn.set("modifyTime",modifyTime);
            //积分的修改
            user.set("vantages", vantages);
            //记录保存
            Db.update("users", user);
            String rankSql="SELECT COUNT(0)+1 signRank FROM signIn WHERE modifyTime <= NOW() AND modifyTime>='"+startTime+"'";
            Record rank=Db.findFirst(rankSql);
            signIn.set("todayRank", rank.get("signRank"));
            signIn.save();
        }else{
            signHistory=userSign.get("signHistory");
            signCount=userSign.get("signCount");
            modifyTime=userSign.getDate("modifyTime");//上次签到时间
            if(todayStartTime.after(modifyTime)){//今天没有签到
                //查询排名
                String rankSql="SELECT COUNT(0)+1 signRank FROM signIn WHERE modifyTime <= NOW() AND modifyTime>='"+startTime+"'";
                Record rank=Db.findFirst(rankSql);
                userSign.set("beforRank", userSign.get("yesRank"));
                userSign.set("yesRank", userSign.get("todayRank"));
                userSign.set("todayRank", rank.get("signRank"));
                //计算是否为连续签到
                final long missDays=(System.currentTimeMillis()-modifyTime.getTime())/(24*60*60*1000);
                if(missDays==1){//连续签到
                    signCount++;
                    vantages=vantages+getScoreByRule(signCount);
                    msg="您已连续签到"+signCount+"天,请再接再励";
                }else{//不连续签到
                    signCount=1;
                    vantages=vantages+1;
                    msg="恭喜您已签到成功";
                }
                modifyTime=new Date();
                signHistory=moveByte(signHistory,missDays);
                userSign.set("signCount", signCount);
                userSign.set("signHistory",signHistory);    
                userSign.set("modifyTime", modifyTime);
                user.set("vantages", vantages);
                Db.update("users", user);
                Db.update("signIn",userSign);
            }else{
                msg="您今天已经签到过了";
            }
        }
        setAttr("msg",msg);
        setAttr("vantages",vantages);
        renderJson();
    }

2.2 查看签到排名

    /**
     * 查看签到排名
     */
    public void rank(){
        //查询个人签到排名记录
        Integer userId=getParaToInt();
        String signSql="SELECT s.id,s.userId,realname,beforRank,yesRank,todayRank "
                 + "FROM signIn s JOIN users u ON s.userId=u.id "
                 + " WHERE userId="+userId;
        Record userSign=Db.findFirst(signSql);
        //签到排名表
        Date todayStartTime=getTodayStartTime();
        DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String today=df.format(todayStartTime);
        String rankSql="SELECT s.id,u.realname,u.areaname,s.modifyTime,t.truckNum "
                + "FROM (signin s  JOIN users u ON u.id=s.userId) JOIN truck t ON s.userId=t.usersId "
                + "WHERE s.modifyTime >'"+today+"'"+" ORDER BY s.modifyTime ASC";
        List<Record> rankList=Db.find(rankSql);
        setAttr("userSign", userSign);
        setAttr("rankList", rankList);
        render("/front/driver/sign/rank.jsp");
    }

2.3 积分兑换奖品

    /**
     * 兑换奖品,返回兑换码.
     * 目前奖品只是虚拟奖品,现场发放,不通过商家端领取。
     * 用户表的积分,奖品表的库存,兑换表:手机,userId,time
     */
    public void exchange(){
        Integer awardId=getParaToInt("awardId");//奖品的ID
        Integer userId =getParaToInt("userId");
        Integer awardVantages=null;
        Integer stock=null;
        String exchangeCode=null;
        Integer userVantages=null;
        String mobile=null;
        String msg=null;
        Record award=Db.findById("award", awardId);
        stock=award.get("stock");
        awardVantages=award.get("vantages");
        //获取用户的积分
        String userSql="SELECT id,vantages,mobile FROM users WHERE id="+userId;
        Record user=Db.findFirst(userSql); 
        mobile=user.getStr("mobile");
        //获取兑换表
        String exchangeSql="SELECT id,awardId,userId,exchangeCode,exchangeTime FROM awardexchange "
                + "WHERE userId is NULL AND awardId="+awardId;
        Record awardExchange=Db.findFirst(exchangeSql);
        if(user==null){
            msg="用户不存在";
            return ;
        }
        if(award==null||awardExchange==null){
            msg="您所要兑换的奖品不存在";
        }else{
            userVantages=user.getInt("vantages");
            if(stock>0){
                if(userVantages>=awardVantages){
                    exchangeCode=awardExchange.get("exchangeCode");
                    user.set("vantages", userVantages-awardVantages);
                    award.set("stock",stock-1);
                    //兑换表的更新
                    awardExchange.set("userId", userId);
                    awardExchange.set("exchangeTime",new Date());
                    awardExchange.set("mobile",mobile);              
                    {//后续添加事物管理
                        Db.update("users", user);
                        Db.update("award",award);
                        Db.update("awardexchange",awardExchange);
                    }
                    msg="恭喜您已兑换成功,兑换码:"+exchangeCode;
                }else{
                    msg="对不起,您的积分不足,无法兑换该奖品";
                }
            }else{
                msg="对不起,您所选择的奖品,库存不足";
            }
        }
        setAttr("msg", msg);
        renderJson();
    }

2.4 工具方法

/**
     * 移位
     * @param oldHistory
     * @param moveAmount
     * @return
     */
    public static long moveByte(long oldHistory,long moveAmount){
        long moveResult = oldHistory<<moveAmount;
        long result=Long.parseLong(toFullBinaryString(moveResult), 2)+1;
        return result;
    }

    public 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.连续签到1天,奖励1积分
     4.连续签到2天,奖励2积分
     5.连续签到3及以上天数,奖励3积分
     * @param signCount  连续签到次数
     * @return 增加的积分
     */
    public static  int getScoreByRule(int signCount)
    {
        int addScore=0;
        if(signCount==1){
            addScore=1;
        }else if(signCount==2){
            addScore=2;
        }else{
            addScore=3;
        }
        return addScore;
    }

    /**
     * 获取当天的起始时间
     * @param oldTime
     * @param newTime
     */
    public Date getTodayStartTime(){
        Date now=new Date();
        Calendar calendar=Calendar.getInstance();
        calendar.setTime(now);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        Date startTime=calendar.getTime();
        return startTime;
    }
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

PHP简单签到功能实现

思路:前台ajax到后台,获取到当前年月已签到过的日期并返回显示。 效果图如: {CSDN:CODE:1859447}...

关于Java积分签到接口的编写总结

JAVA编程习惯: 利用逆向工程提高开发效率。 把影响结构的代码封装起来,让主方法的结构一目了然。 把经常调用的方法接口封装到tools工具类中。 把所有的业务都在service层编写,而da...

连续签到奖励 数据库如何设计?

用户连续签到7天 7天均有不同的奖励 如果有中间则会从第一天重新开始签到 7天一个周期完成后恢复到第一天开始重新签到 考虑到用户数大概在200W,数据库如何设计更加合理? 添加评论...

redis 主从 如何限制用户签到一次

最近有个每日签到的活动 用户每天只能签到一次。 一开始考虑用 get set 但是万一并发情况下 刚刚set 为1 然后再去get 数据的时候 从库数据 延迟还没同步过来 还岂不是又可以签到一下 ge...

redis bitmap实现签到

Bitmap 对于一些特定类型的计算非常有效。 假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户A上线了多少天,用户B上 线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加...
  • czh0423
  • czh0423
  • 2015年11月06日 14:29
  • 1142

日历签到demo 实现记录

Android日历签到

使用java编程,实现论坛自动登录、签到、领奖、摇一摇

java实现论坛自动登录、签到等功能

连续签到奖励 数据库如何设计?

用户连续签到7天 7天均有不同的奖励 如果有中间则会从第一天重新开始签到 7天一个周期完成后恢复到第一天开始重新签到 考虑到用户数大概在200W,数据库如何设计更加合理? 添加评论...

MYSQL实现连续签到功能,断签一天从头开始

1,创建测试表 CREATE TABLE `testsign` ( `userid` int(5) DEFAULT NULL, `username` varchar(20) DEFAULT ...

Python requests 自动登录某财BBS,自动签到打卡领铜钱,最后再配个plist,每天自动执行

Python自动登录某财BBS,自动回帖打卡领铜钱,最后再配个plist,每天自动执行(mac)...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:签到,打卡领取积分,记录连续签到,获取签到排名。
举报原因:
原因补充:

(最多只允许输入30个字)