tp5实现每日签到功能

数据库设计

要求:

    每个用户可以签到7天,连续签到7天或者中途断签都重新开始计算签到天数,签到会获取对应奖励

分析

    1、连续签到
    2、签到7天或者断签重新开始计算天数
    3、签到获取奖励

设计

    1、每个用户可以连续签到,这就需要一个字段来记录连续签到天数
    2、因为有连续签到7天或者断签重新开始计算的需求,所以需要一个字段来记录签到时间,来判断是否是连续签到从而改变连续签到天数,签到时判断表里的签到时间与现在的时间差是否为1天,为1天则连续签到,天数+1,反之则为断签,天数重置为1
    3、签到获取奖励,需要记录签到天数对应的奖励(签到奖励表)

实现

1、创建签到表(sign_in)

CREATE TABLE `sign_in`  (
  `id` int(11) NOT NULL COMMENT '主键',
  `userId` int(11) NULL DEFAULT NULL COMMENT '用户id',
  `num` int(11) NULL DEFAULT NULL COMMENT '签到天数',
  `signTime` datetime(0) NULL DEFAULT NULL COMMENT '签到时间',
  PRIMARY KEY (`id`)
);

2、创建奖励表(sign_in_reward)

CREATE TABLE `sign_in_reward`  (
  `id` int(11) NOT NULL COMMENT '主键',
  `coin` int(11) NOT NULL COMMENT '金币',
  PRIMARY KEY (`id`)
);

 3、用户表

CREATE TABLE `user`  (
  `id` int(11) NOT NULL COMMENT '主键',
  `userId` int(11) NOT NULL COMMENT '用户id',
  `coin` int(11) NOT NULL COMMENT '金币',
  PRIMARY KEY (`id`)
);

 

代码实现

签到:

/**
     * @api {post} /minwx/sign/signIn 签到
     * @apiName signIn
     * @apiParam {string} userId 用户id
     * @apiGroup 签到
     */
    public function signIn()
    {
        try {
            $userId = $this->request->param('userId');
            $signIn = new ModelSignIn();
            $res = $signIn->get(['userId' => $userId]);
            // 判断用户是否签到过
            if ($res) {
                // 更新用户数据
                if ($this->diffBetweenTwoDays(date('Y-m-d', time()), substr($res['signTime'], 0, 10)) == 1) {
                    // 连续签到,更新签到时间,签到天数+1
                    $num = $res['num'] + 1;
                } else {
                    // 没有连续签到,更新签到时间,签到次数初始化为1
                    $num = 1;
                }
                $signIn->where(['userId' => $userId])->update(['signTime' => date('Y-m-d H:i:s', time()), 'num' => $num]);
            } else {
                // 添加用户数据
                $signIn->data([
                    'userId' => $this->request->param('userId'),
                    'num' => 1,
                    'signTime' => date('Y-m-d H:i:s', time())
                ]);
                $signIn->save();
            }
            // 获取签到奖励
            $reward = Db::table('sign_in_reward')->where(['id'=> $num % 7 == 0 ? 7 : $num % 7])->find();
            // 给予用户奖励
            $user = new User();
            $userInfo = $user->where(['userId' => $userId])->setInc('coin', $reward['coin']);
            return json(['code'=>1,'msg'=>'签到成功','data'=>'']);
        } catch (Exception $e) {
            return json(['code'=>-1,'msg'=>'系统错误','err'=>$e->getMessage()]);
        }
    }
    
	//两个日期之间相差的天数
    public function diffBetweenTwoDays($day1, $day2)
    {
        $second1 = strtotime($day1);
        $second2 = strtotime($day2);

        if ($second1 < $second2) {
            $tmp = $second2;
            $second2 = $second1;
            $second1 = $tmp;
        }
        return ($second1 - $second2) / 86400;
    }

获取签到:

/**
     * @api {post} /minwx/sign/getSignIn 获取签到
     * @apiName getSignIn
     * @apiParam {string} userId 用户id
     * @apiGroup 签到
     */
    public function getSignIn()
    {
        Db::startTrans();
        try {
            $userId= $this->request->param('userId');
            // 获取用户信息
            $user = new User();
            $userInfo = $user->get(['userId' => $userId]);
            // 获取签到日期
            $signIn = new ModelSignIn();
            $arr = $signIn->get(['userId' => $userId]);
            // 判断是否签到过
            if ($arr) {
            	// 计算天数
                $differDay = $this->diffBetweenTwoDays(date('Y-m-d', time()), substr($arr['signTime'], 0, 10));
                // 0今日签到,1昨日已签到
                if ($differDay == 0 || $differDay == 1) {
                	// 这里不对数据库的签到天数做处理,可以一直记录连续签到的天数,方便后面需求的拓展
                	// 而在逻辑上连续签到7天需重置签到天数,所以对签到天数做7求余(具体天数看实际项目需求更改求余),得出逻辑需求里的连续签到天数
                    $num = $arr['num'] % 7 == 0 ? 7 : $arr['num'] % 7;
                } else {
                	// 断签,重置签到天数,因为是获取签到而不是签到,所以num重置为0
                    $num = 0;
                    $signIn->where(['userId' => $userId])->update(['num' => $num]);
                }
                // 判断今日是否签到
                if ($differDay == 0) {
                    // 今天已签到
                    $today = 1;
                } else {
                    // 今日未签到
                    $today = 0;
                }
            } else {
            	// 未签到,插入数据,签到天数为0
                $num = 0;
                $today = 0;
                $signIn->where(['userId' => $userId])->update(['num' => $num]);
            }
            // 获取签到奖励
            $reward = Db::table('sign_in_reward')->order('id')->select();
            $res = [
                'coin' => $userInfo['coin'],	// 用户金币
                'signIn' => $num,	// 签到天数
                'reward' => $reward,	// 签到奖励
                'today' => $today	// 今天是否签到(0没有、1有)
            ];
            Db::commit();
            return json(['code'=>1,'msg'=>'获取成功','data'=>$res]);
        } catch (Exception $e) {
            Db::rollback();
            return json(['code'=>-1,'msg'=>'系统错误','err'=>$e->getMessage()]);
        }
    }

你可能感兴趣的:(PHP,#,API,sql)