Thinkphp5实现一周签到打卡功能
在 ThinkPHP5 中实现一周签到打卡功能,可以通过设计一个签到系统来跟踪用户的每日签到情况,并计算是否完成了七天的连续签到。以下是实现这一功能的详细步骤和示例代码。
1. 数据库设计
首先,你需要设计一个数据库表来存储用户的签到记录。可以设计如下表结构:
CREATE TABLE `user_signins` (
`id` INT(11) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
`user_id` INT(11) UNSIGNED NOT NULL,
`sign_in_date` DATE NOT NULL,
UNIQUE KEY `user_date` (`user_id`, `sign_in_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
在这个表中,user_id
表示用户的 ID,sign_in_date
表示签到日期。通过 user_id
和 sign_in_date
组合创建唯一索引,确保用户不能重复签到同一天。
2. ThinkPHP5 控制器
创建一个控制器来处理用户签到的请求。
namespace app\index\controller;
use think\Controller;
use think\Db;
use think\Request;
use think\Cache;
class SignIn extends Controller
{
// 签到方法
public function signIn(Request $request)
{
$userId = $request->post('user_id'); // 获取用户 ID
$today = date('Y-m-d'); // 获取今天的日期
// 检查 Redis 缓存中是否存在签到记录
$cacheKey = "user:{$userId}:signins";
$signIns = Cache::get($cacheKey);
if ($signIns === null) {
$signIns = Db::name('user_signins')
->where('user_id', $userId)
->column('sign_in_date');
Cache::set($cacheKey, $signIns, 3600); // 缓存1小时
}
if (in_array($today, $signIns)) {
return json(['status' => 'error', 'message' => 'You have already signed in today.']);
}
// 插入签到记录
Db::name('user_signins')->insert([
'user_id' => $userId,
'sign_in_date' => $today,
]);
// 更新 Redis 缓存
$signIns[] = $today;
Cache::set($cacheKey, $signIns, 3600);
return json(['status' => 'success', 'message' => 'Sign in successful.']);
}
// 获取连续签到天数
public function getConsecutiveDays($userId)
{
$today = date('Y-m-d');
$startDate = date('Y-m-d', strtotime('-6 days'));
$cacheKey = "user:{$userId}:signins";
$signIns = Cache::get($cacheKey);
if ($signIns === null) {
$signIns = Db::name('user_signins')
->where('user_id', $userId)
->where('sign_in_date', 'between', [$startDate, $today])
->order('sign_in_date', 'asc')
->column('sign_in_date');
Cache::set($cacheKey, $signIns, 3600); // 缓存1小时
}
$consecutiveDays = 0;
$expectedDate = $startDate;
foreach ($signIns as $signInDate) {
if ($signInDate === $expectedDate) {
$consecutiveDays++;
$expectedDate = date('Y-m-d', strtotime($expectedDate . ' +1 day'));
} else {
break;
}
}
return json(['status' => 'success', 'consecutive_days' => $consecutiveDays]);
}
}
3. 路由配置
在 route.php
中配置路由来访问签到功能:
// 签到
Route::post('sign_in', 'index/SignIn/signIn');
// 获取连续签到天数
Route::get('consecutive_days/:user_id', 'index/SignIn/getConsecutiveDays');
4. 接口测试
使用 Postman 或其他工具测试你的接口。你可以发送 POST 请求到 /sign_in
路径进行签到,并发送 GET 请求到 /consecutive_days/{user_id}
来获取用户的连续签到天数。
5. 前端实现
你可以在前端实现用户签到的界面和展示连续签到天数的功能。使用 AJAX 调用上述接口来实现签到和查询。
示例前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sign In</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<button id="signInBtn">Sign In</button>
<div id="consecutiveDays"></div>
<script>
$(document).ready(function() {
$('#signInBtn').click(function() {
$.post('/sign_in', {user_id: 1}, function(response) {
alert(response.message);
});
});
function getConsecutiveDays() {
$.get('/consecutive_days/1', function(response) {
$('#consecutiveDays').text('Consecutive Days: ' + response.consecutive_days);
});
}
getConsecutiveDays();
});
</script>
</body>
</html>
总结
以上是一个简单的 ThinkPHP5 实现一周签到打卡功能的示例。通过设计合适的数据库结构和控制器逻辑,你可以轻松实现用户签到和连续签到天数统计功能。在实际应用中,可能需要考虑更多的细节,如用户身份验证、签到奖励、接口优化等。