本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/update/39/plugins/daily_checkin/说明.md。
每日签到(daily_checkin)插件说明
版本:1.0.0 | 作者:SoSite | 状态:✅ 启用(
plugin.jsonactivated: true)功能:用户每日签到获取积分,支持连续签到奖励(连签天数加成)
一、功能简介
- 用户每日可签到一次,签到获得基础积分(
checkin_points_base,默认 2) - 连续签到奖励:连续签到天数加成(
checkin_points_bonus,默认 1/天) - 数据表
UNIQUE(user_id, checkin_date)天然去重,一天只能签一次 - 三个入口:
- 右栏「本周签到」面板(
right_sidebar_after钩子,用户栏下方、与用户栏同级) - 前台导航"应用"下拉(
nav_plugin_links) - 顶部导航(
nav_main_links)
- 签到页
/checkin:积分概览 + 奖励规则 + 本月日历(可翻月)
二、目录结构
plugins/daily_checkin/
├── plugin.json # 插件清单(hooks: init_after / route_register / right_sidebar_after / nav_plugin_links / nav_user_menu_items)
├── Plugin.php # 生命周期(activate 建表 + 签到奖励配置)
├── CheckinController.php # 签到控制器(index / buildAreaData / doCheckin)
├── hook/
│ ├── init_after.php # 懒建表 + checkin_date 字段类型迁移
│ ├── route_register.php # 路由注册(/checkin)
│ ├── right_sidebar_after.php # ★ 右栏「本周签到」面板(自取数据,渲染 _sidebar.php)
│ ├── nav_plugin_links.php # 前台"应用"下拉入口
│ ├── nav_user_menu_items.php # 用户下拉菜单入口(当前文件已禁用内容)
│ └── nav_main_links.php # 顶部导航入口
├── assets/style.css # 签到样式(dc-modern-* 签到页 / dc-week-* 右栏面板)
└── views/
├── index.php # 签到页面
├── _area.php # 签到页主体(积分概览 + 奖励规则 + 本月日历)
└── _sidebar.php # ★ 右栏「本周签到」面板(钩子 + htmx 回包共用)三、数据表
| 表 | 用途 |
|---|---|
daily_checkin | 签到记录(user_id / checkin_date / points / consecutive_days / created_at,UNIQUE(user_id, checkin_date)) |
activate()建表 + 写入默认奖励配置(settings 表)uninstall()删除表- 卸载后
users.points字段保留(不删除,防误删其他积分逻辑)
四、Hooks
| Hook | 用途 |
|---|---|
init_after | 懒建表 + 迁移 |
route_register | 前台路由(/checkin) |
right_sidebar_after | 右栏「本周签到」面板(用户栏下方、与用户栏同级) |
nav_plugin_links | "应用"下拉签到入口 |
nav_user_menu_items | 用户菜单入口(当前文件已禁用) |
⚠️ 已移除
controller_view_before:它原先把checkin_today/checkin_today_points/
checkin_consecutive/checkin_points注入视图,而唯一的消费方是核心右栏里那段硬编码的签到代码(
right_sidebar.php的include('plugins/daily_checkin/_sidebar')+#checkinHint)。2026-09-27 核心完成解耦、那段代码被删除后,该注入再无消费方,故连同钩子一并移除。
现在面板由
right_sidebar_after自己查库(每次渲染 1 次查询;右栏被隐藏时零查询)。
五、右栏「本周签到」面板(right_sidebar_after)
- 位置:
app/Views/_components/right_sidebar.php:210—— 用户面板之后、站点统计之前 - 形态:独立
.mn-panel,与排行榜 / 最新会员 / 站点统计一致 - 内容:标题(带跳转
/checkin的右箭头)+ 本周 7 格(周一 → 周日)+ 状态区 + 底部提示 - 已签到的日子:主色实心圆 + 勾
- 今日未签到:
立即签到按钮(htmxhx-post="/checkin",hx-target="#checkinWeek"原地替换) - 今日已签到:绿胶囊「今日已签到」
- 底部灰字:未签到显示副标题;已签到显示「明天见」
- 只对登录用户显示;游客直接
return,不输出任何内容 - 数据:
SELECT checkin_date, points, consecutive_days ... WHERE checkin_date BETWEEN 本周一 AND 本周日
(1 次查询同时得出 7 格状态 + 今日积分/连续天数)
- 图标:一律
<i class="fa mn-fs-12">,不用$view->icon()(后者带内联style,违反插件零内联) - 渲染钩子红线:闭包作用域内
$this不可用 → 钩子里用htmlspecialchars()/Csrf::token()
⚠️ 已知差异:两处日历的「周起始日」不同
| 位置 | 起始日 | 表头顺序 |
|---|---|---|
右栏「本周签到」面板(_sidebar.php) | 周一 | 一 二 三 四 五 六 日 |
签到页「本月日历」(_area.php) | 周日 | 日 一 二 三 四 五 六 |
右栏面板对齐参考设计(M T W T F S S);_area.php 的月份日历未改动。
两处刻意保留各自口径,不是 bug,改动前请先确认。
⚠️ 模板取数红线
_sidebar.php 有两个入口,取数方式必须统一为普通变量($week_days / $checkin_today):
| 入口 | 路径 | `$this->getData()` | 普通变量 |
|---|---|---|---|
| 右栏钩子 | $GLOBALS['__view']->include($tpl, $extra) | ❌ 取不到 | ✅ |
| htmx 回包 | viewRaw($tpl, $data) → display() 会 extract | ✅ | ✅ |
原因:TemplateCompiler::include($tpl, $extra) 是 array_merge($this->data, $extra) 后 extract,
不会把 $extra 写回 $this->data → 钩子路径下 getData() 拿到的是默认值。
所以模板里禁止 $this->getData()。($this->e() / $this->url() / $this->t() 两条路径都可用。)
六、路由
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /checkin | 签到页面(积分概览 + 奖励规则 + 本月日历,支持 ?month=YYYY-MM 翻月) |
| POST | /checkin | 执行签到。htmx 请求(HX-Request)返回局部 HTML;普通表单提交 302 回 /checkin |
七、核心逻辑(doCheckin)
- 校验登录 + CSRF
- 查今日是否已签(
UNIQUE(user_id, checkin_date)+ 前置查询)→ 已签返回提示 - 计算连续天数:昨日有签 → 连续 +1;否则重置为 1
- 写入签到记录 →
Points::award发放积分(基础 + 连签加成) - htmx:
viewRaw()重渲染(widget=sidebar→_sidebar.php,否则_area.php);普通表单:302 回/checkin
八、注意事项
- 签到记录按
checkin_date TEXT(Y-m-d)去重,跨时区以服务器日期为准 - 连续天数判断依赖昨日记录,跨天未签则断签重置
- 入口
nav_user_menu_items文件当前为空实现(作者禁用),实际入口走"应用"下拉 + 右栏面板 - ⚠️ 目录名含下划线(
daily_checkin),核心用目录名硬拼类名\Plugin\{目录名}\Plugin
(app/Helpers/Plugin.php:699/750/846),而本插件实际命名空间是 Plugin\DailyCheckin
→ class_exists() 恒为 false,activate() / deactivate() / uninstall() 会被静默跳过。
目前建表靠 hook/init_after.php 的惰性兜底,所以功能正常;但卸载不会删表。
修法:Plugin.php 末尾加 class_alias(Plugin::class, 'Plugin\daily_checkin\Plugin', false);(尚未修)