[开发]每日签到(daily_checkin)插件说明

👑Lv.11 元老 🌞 骨干会员
2026-10-25 01:33:51

本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/update/39/plugins/daily_checkin/说明.md。

每日签到(daily_checkin)插件说明

版本:1.0.0 | 作者:SoSite | 状态:✅ 启用(plugin.json activated: true)

功能:用户每日签到获取积分,支持连续签到奖励(连签天数加成)


一、功能简介

  • 用户每日可签到一次,签到获得基础积分(checkin_points_base,默认 2)
  • 连续签到奖励:连续签到天数加成(checkin_points_bonus,默认 1/天)
  • 数据表 UNIQUE(user_id, checkin_date) 天然去重,一天只能签一次
  • 三个入口:
  1. 右栏「本周签到」面板(right_sidebar_after 钩子,用户栏下方、与用户栏同级)
  2. 前台导航"应用"下拉(nav_plugin_links)
  3. 顶部导航(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 格(周一 → 周日)+ 状态区 + 底部提示
  • 已签到的日子:主色实心圆 + 勾
  • 今日未签到:立即签到 按钮(htmx hx-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)

  1. 校验登录 + CSRF
  2. 查今日是否已签(UNIQUE(user_id, checkin_date) + 前置查询)→ 已签返回提示
  3. 计算连续天数:昨日有签 → 连续 +1;否则重置为 1
  4. 写入签到记录 → Points::award 发放积分(基础 + 连签加成)
  5. 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);(尚未修)

轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| Views 3 | Replies 0

All Replies (0)

No replies yet

Please Log in