好久前发过一个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;
}
}