徐善通的随笔

千里之行, 始于足下



thinkphp3.2签到送积分新版


好久前发过一个thinkphp签到送积分的代码, 那个时候的水平有点菜, 发现还有许多人看,所以就更新了下

<?php
namespace Home\Controller;

use Think\Controller;

/**
 * Class SignInController
 * 用户签到类, 签到送积分
 * 表结构如下:
    CREATE TABLE `tbl_user_sign_in` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `user_id` int(10) NOT NULL DEFAULT '0' COMMENT '用户ID',
    `username` varchar(30) NOT NULL DEFAULT '' COMMENT '用户名称',
    `continuous_days` smallint(5) NOT NULL DEFAULT '0' COMMENT '连续签到天数',
    `integral` smallint(5) NOT NULL DEFAULT '0' COMMENT '本次签到获取积分数',
    `sign_in_at` int(10) NOT NULL DEFAULT '0' COMMENT '签到时间, 时间戳',
    `created_at` int(10) NOT NULL DEFAULT '0' COMMENT '记录创建时间',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COMMENT='用户签到表';
 *
 */
class SignInController extends Controller {

    /**
     * Ajax 返回状态标识
     */
    const CODE_SUCCESS = 0;
    const CODE_FAILURE = 1;

    /**
     * 签到方法
     * 1.验证是否登录
     * 2.验证今日是否已签到
     * 3.签到
     */
    public function index()
    {
        $result = array(
            'code' => self::CODE_SUCCESS,
            'message' => '签到成功',
        );

        try {
            // 1.验证是否登录
            if (!$this->checkLogin()) {
                throw new \Exception('请先登录');
            }

            // 获取用户信息
            $userInfo = $this->getUserInfo();

            /**
             * 2.验证今日是否已签到
             * 获取今日凌晨时间戳, 通过查询 sign_in_at 字段来判断
             */
            $signIn = M('user_sign_in');
            $todayAt = strtotime(date('Y-m-d'));

            // 查询条件
            $where = array(
                'user_id' => $userInfo['user_id'],
                'sign_in_at' => array('EGT', $todayAt)
            );
            // 查询今日是否已签到
            $exist = $signIn->where($where)->count();
            if ($exist > 0) {
                throw new \Exception('今天已经签到过啦!');
            }

            /**
             * 3.开始签到逻辑
             * 先查询昨天的签到记录
             *   如果查到, 则说明是连续签到, 连续签到天数加1
             *   未查到, 连续签到天数为1
             * 根据连续签到天数, 获取相应的积分
             */
            $yesterdayAt = $todayAt - 86400;
            $where['sign_in_at'] = array('EGT', $yesterdayAt);
            // 昨天的签到记录
            $yesterdayRecord = $signIn->where($where)->find();
            // 连续签到天数
            $continuousDays = 1;
            if (!empty($yesterdayRecord)) {
                // 更新连续签到天数
                $continuousDays += $yesterdayRecord['continuous_days'];
            }
            $integral = 0; // 积分数
            $config = $this->getConfig();
            // 通过连续签到天数, 获取相应的积分
            foreach ($config as $day => $integralItem) {
                if ($day > $continuousDays) {
                    break;
                }
                $integral = $integralItem;
            }
            // 插入数据
            $insertData = array(
                'user_id' => $userInfo['user_id'],
                'username' => $userInfo['username'],
                'integral' => $integral,
                'continuous_days' => $continuousDays,
                'sign_in_at' => time(),
                'created_at' => time(),
            );
            // todo: 得到了连续签到天数, 和应得的积分, 此处可以添加 额外获取积分的逻辑

            $insertRet = $signIn->add($insertData);
            if (!$insertRet) {
                throw new \Exception('签到失败');
            }
            // todo: 更新用户积分数

            // 修改提示
            $result['message'] = sprintf('签到成功, 连续签到%d天, 获得%d积分', $continuousDays, $integral);

        } catch (\Exception $e) {
            $result['code'] = self::CODE_FAILURE;
            $result['message'] = $e->getMessage();
        }

        $this->ajaxReturn($result);
    }

    /**
     * 检查是否登录, 替换成实际的代码
     * @return bool
     */
    private function checkLogin()
    {
        return true;
    }

    /**
     * 获取用户信息, 替换成实际的代码
     * @return array
     */
    private function getUserInfo()
    {
        return array(
            'user_id' => 1,
            'username' => 'shantong',
        );
    }

    /**
     * 签到获取积分规则
     * @return array
     */
    private function getConfig()
    {
        /**
         * 基础积分
         * 如: 第一天5积分, 连续签到每天多5积分, n天及以上每天m积分, 此处n=8, m=40
         */
        $config = array(
            1 => 5, // 第一天5积分
            2 => 10,
            3 => 15,
            4 => 20,
            5 => 25,
            6 => 30,
            7 => 35,
            8 => 40,
        );

        /**
         * 还可以这样设置
         */
//        $config = array(
//            1 => 5, // 每天都是5积分
//        );

//        $config = array(
//            1 => 5, // 一天以上5积分
//            3 => 10, // 三天以上10积分
//            5 => 20, // 五天以上20积分
//            10 => 50, // 10天以上50积分
//        );

        return $config;
    }
}

作者: 徐善通
地址: https://www.xstnet.com/article-133.html
声明: 除非本文有注明出处,否则转载请注明本文地址


我有话说



最新回复


正在加载中....

Copyrights © 2016-2019 醉丶春风 , All rights reserved. 皖ICP备15015582号-1