PHP 基于ThinkPHP实现每日签到及奖励功能

PHP 基于ThinkPHP实现每日签到及奖励功能

数据库设计

要求:

每个用户可以签到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()]);
        }
    }
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的用户签到功能实现示例: 1. 创建一个名为 `SignController` 的控制器,然后添加一个名为 `doSign` 的方法用于处理用户签到请求。 ```php class SignController extends Controller { public function doSign() { $uid = session('uid'); // 获取当前用户的ID $signModel = M('UserSign'); // 实例化用户签到模型 $lastSign = $signModel->where('uid='.$uid)->order('sign_time desc')->find(); // 获取用户最后一次签到记录 $today = date('Y-m-d'); // 获取当前日期 if(empty($lastSign) || $lastSign['sign_time'] < $today) { // 如果用户今天还没有签到 $data['uid'] = $uid; $data['sign_time'] = $today; $signModel->add($data); // 添加签到记录 $this->success('签到成功!'); } else { // 如果用户今天已经签到过了 $this->error('今天已经签到过了!'); } } } ``` 2. 创建一个名为 `UserSignModel` 的模型,用于操作用户签到记录表。 ```php class UserSignModel extends Model { protected $tableName = 'user_sign'; } ``` 3. 创建一个名为 `user_sign` 的数据表,用于存储用户签到记录。 ```sql CREATE TABLE `user_sign` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `sign_time` date NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; ``` 4. 在用户登录成功后,将用户ID存储到Session中。例如: ```php session('uid', $user['id']); ``` 5. 在前端页面上添加一个签到按钮,并在点击按钮时向服务器发送签到请求。例如: ```html <button id="sign-btn">签到</button> <script> $('#sign-btn').on('click', function() { $.ajax({ url: '/sign/doSign', type: 'POST', success: function(res) { if(res.code == 0) { alert(res.msg); } else { alert(res.msg); } } }); }); </script> ``` 以上就是一个简单的用户签到功能实现示例,你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值