赞
踩
注:需求不一样则业务逻辑不一样
不说废话,直接干!!!!
Mysql:
CREATE TABLE `t_user_sign` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '用户ID',
`days` int(11) NOT NULL COMMENT '累计签到天数',
`year` int(11) NOT NULL COMMENT '年',
`month` tinyint(4) NOT NULL COMMENT '月',
`sign_record` varchar(255) NOT NULL COMMENT '签到记录',
`last_sign_time` char(19) NOT NULL COMMENT '上次签到时间',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '0-无效,1-有效',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8mb4;
1、控制器代码
/** * 页面初始化,返回结果给前端 */ public function index() { $user_id = Request::input('user_id'); $year = date('Y'); $month = date('n'); $signKey = 'sign_' . $year . '_' . $month . '_' . $user_id; $data = UserSignService::signDays($user_id,$signKey); $data['year'] = $year; $data['month'] = $month; return Utils::success($data); } /** * 签到/补签 这里使用了两种Redis数据类型,bitmap、hash */ public function sign() { $user_id = Request::input('user_id'); $type = Request::input('type',1); // 1、签到 , 2、补签 $day = Request::input('day',0); if (!Utils::isValue($user_id)){ return Utils::fail('无效user_id'); } if ($type == 2){ if (!Utils::isValue($day)){ return Utils::fail('无效day'); } }else{ $day = Utils::getNowDay(); } if ($day > Utils::getNowDay()){ return Utils::fail('补签的日期不能大于等于今天'); } $year = date('Y'); $month = date('n'); $signKey = 'sign_' . $year . '_' . $month . '_' . $user_id; $sign = Redis::getbit($signKey,$day); if ($type == 2){ if (Utils::isValue($sign)){ return Utils::success('您已补签,无需补签'); } }else{ if (Utils::isValue($sign)){ return Utils::success('您今天已签到'); } } Redis::setbit($signKey,0,1); Redis::setbit($signKey,$day,1); $data = UserSignService::signDays($user_id,$signKey); $datas = [ 'user_id' => $user_id, 'days' => Utils::getValue($data,'days'), 'year' => $year, 'month' => $month, 'sign_record' => Utils::getValue($data,'signDay'), 'last_sign_time' => date('Y-m-d H:i:s') ]; // 将用户的记录存放hash,到下个月初跑一次记录放进DB。注:需求不一样则业务逻辑不一样 Redis::hset('sign_record',$user_id,json_encode($datas)); // 缓存过期时间 Redis::expire($signKey,3024000); Redis::expire('sign_record',3024000); if ($type == 2){ return Utils::success('补签成功'); }else{ return Utils::success('签到成功'); } }
2、Service 代码
class UserSignService { /** * 获取用户哪一天签到的? 和 签到总天数 * @param $user_id '用户ID' * @param $signKey 'key' * @return array */ public static function signDays($user_id,$signKey): array { $bitmap_bin_str = self::strToBin(Redis::get($signKey)); //调试使用,输出本月每天签到情况 $month = date('t'); $signDay = 0; for($i=1;$i<=$month;$i++) { if (empty($bitmap_bin_str[$i])) { $bitmap_bin_str[$i] = 0; } if ($bitmap_bin_str[$i] != 1) { // echo "$i 日未签到"; // echo "<br>"; } else { $signDay += 1; // echo "$i 日签到"; // echo "<br>"; } } return [ 'signDay' => substr($bitmap_bin_str,1), 'days' => $signDay ]; } /** * 转化数据 * @param $str * @return string */ public static function strToBin($str) { $arr = preg_split('/(?<!^)(?!$)/u', $str); foreach($arr as &$v){ $temp = unpack('H*', $v); $v = base_convert($temp[1], 16, 2); unset($temp); } return join(' ',$arr); } }
3、脚本command
public function handle() { $datas = Redis::hgetall('sign_record'); foreach ($datas as $data){ $data = json_decode($data); $user_id = Utils::getValue($data,'user_id'); $where = [ 'user_id' => $user_id, 'year' => date('Y'), 'month' => date('n'), ]; $userSignModel = UserSign::where($where)->first(); if (Utils::isValue($userSignModel)){ $userSignModel->toArray(); } $userSignRecord = [ 'days' => Utils::getValue($data,'days'), 'sign_record' => Utils::getValue($data,'sign_record'), 'last_sign_time' => Utils::getValue($data,'last_sign_time') ]; if (Utils::isValue($userSignModel)){ DB::table('user_sign')->where($where)->update($userSignRecord); }else{ $userSignRecord['user_id'] = Utils::getValue($data,'user_id'); $userSignRecord['year'] = Utils::getValue($data,'year'); $userSignRecord['month'] = Utils::getValue($data,'month'); DB::table('user_sign')->insert($userSignRecord); } } echo '执行成功'; }
如有Command脚本不会的,自己私下百度。
列出执行命令:php artisan list
发现存在,即可执行,php artisan lesson:sign
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。