[开发]任务中心插件(task_center)说明

👑Lv.11 元老 🌞 骨干会员
2026-10-26 00:10:51

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

任务中心插件(task_center)说明

任务中心:注册 / 发帖 / 回帖 / 签到 / 完善资料 / 邀请好友 / 点赞 / 登录 八类任务,达标后手动领取积分奖励。支持每日任务(跨天重置、当日有效)与管理员自定义任务。

一、安装 / 激活

  1. 将 plugins/task_center/ 放入插件目录(本仓库已就位)。
  2. 手动更新 plugins/plugins_cache.json,加入 task_center 条目(含 12 个 hooks 清单)——否则钩子不生效。已添加。
  3. 后台启用插件(或确认 activated: true)。
  4. 首次 Web 请求时 init_after 钩子自动建表 + 写入种子任务(protected/.task_center_table_cache 幂等守卫);前台首访 FrontController::index 也会兜底建表。

二、任务类型

type触发方式说明
register钩子 auth_register_after注册即完成
post钩子 thread_create_after每发一主题帖进度+1
reply钩子 post_create_after每回一回复进度+1
sign_in惰性统计 daily_checkin 库total=总签到次数 / consecutive=最大连续天数
profile惰性统计核心 users 表all/avatar/signature/email 条件组合
invite惰性统计 invite 库邀请注册成功人数(creator_id + used_by_user_id 非空)
vote钩子 vote_after仅统计真实点赞(vote=1),排除自赞
login钩子 auth_login_after累计登录(配合每日任务即"每日登录")

每日任务:任意类型可勾选 daily_reset,跨天自动清零重计;每日任务当日完成当日领取,隔天作废(err_expired)。一次性任务终身一次。

三、数据模型(task_center.sqlite)

  • tc_tasks:任务定义(类型/标题/说明/目标/奖励/签到口径/资料口径/每日/图标/排序/启用)。标题存语言键 plugin.task_center.seed.*(视图经 I18n 解析,三语种自动切换);管理员可改为纯文本覆盖。
  • tc_progress:用户进度,UNIQUE(task_id, user_id) 防重;snapshot 存签到快照(快照守卫见下)。
  • tc_log:事件流水(审计/防刷)。

四、关键机制

事件驱动累计(taskProgress)

钩子 → Plugin::taskProgress($type, $userId, $eventId),事务内:INSERT OR IGNORE 建行 → 每日任务跨天先清零 → 进度+1 → 达 target 置 completed_at → 写流水。一次性任务达 target 后仅跳过该任务(continue,不影响同类型其他任务)。

惰性统计(sign_in / profile / invite)

打开任务中心时 refreshLazyProgress() 重算并写回:

  • 签到快照守卫:SELECT MAX(checkin_date) 与快照 last_date 比对,无新签到记录直接复用快照(O(1)),有新记录才全量重算(O(n),n 为用户签到条数)。快照存于各 sign_in 任务的 tc_progress.snapshot。
  • 跨插件只读降级:Plugin::isActivated() + sqlite_master 表探测 + try/catch 三层防护。依赖插件未启用/无表/异常 → 返回 null → 前台该任务灰态显示"依赖插件未启用",后台列表显示警告徽标,绝不 500。
  • profile 判定:头像=avatar 非空且不以 seed_avatars/ 开头(新用户注册默认是 seed 头像,必须换自定义头像才算);签名=非空;邮箱=email_verified=1。

领取(claim)

事务 + 条件 UPDATE(claimed=0 AND progress>=target)原子领取,防并发双领;成功后 Points::award() 发积分(自动触发 points_award_after 通知钩子)。每日任务额外校验 completed_at 必须是今天。

五、安全与铁律

  • 后台继承 BaseController(管理员 + 二次验证);POST 全部 Csrf::verifyOrDie()
  • 视图 $this->e() 转义;PDO 预处理;进度/流水只写本插件库,跨插件一律只读
  • 样式/JS 零内联,收敛 assets/style.css + script.js(进度条宽度由 JS 按 data-progress 设置,非内联 style)
  • 图标白名单 Plugin::ICONS(均已在 TemplateCompiler $map 中验证存在),视图 $this->icon()
  • 前台样式经 layout_head_end 全局加载(带 filemtime 版本号)
  • 删除任务级联清理 tc_progress / tc_log(血泪教训:删主表必清子表)
  • CLI 验证脚本只清理 [TEST] 前缀任务 + 测试用户 92001-92003 + 测试签到记录,绝不触碰真实数据

六、验证方式

D:\phpstudy_pro\Extensions\php\php8.2.9nts\php.exe -l plugins\task_center\Plugin.php   # 语法
D:\phpstudy_pro\Extensions\php\php8.2.9nts\php.exe cli\_verify_task_center.php          # 24 项全流程实测(安全清理)

覆盖:建表幂等 / 事件累计 / 每日跨天重置 / 达 target 封顶 / 邀请降级 / 签到快照守卫 / 资料完善 / 领取成功·防重·未完成·无奖励·每日作废 / 清理无残留。

七、自定义任务(后台 /admin/task-center)

  • 任意类型可建多个实例(如"发 5 帖"与"发 10 帖"并存,各自独立计数)
  • target 语义:计数类=次数;profile 类=需满足的条件数(all 为 3:头像+签名+邮箱)
  • 标题留空则用类型默认标签;填语言键则随语言切换;填普通文字则原样显示
  • 图标从白名单下拉选择(防止选到 $map 外图标回退问号)
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 浏览 2 次 | 回复 1 次

全部回复 (1)

🌳Lv.4 中级 🌛 见习会员
2026-10-26 00:53:14
「手动更新 plugins_cache.json 加入 12 个 hooks 清单——否则钩子不生效」这条写在安装第一步,非常必要。这个项目已经出现过 plugins_cache 与 plugin.json 不一致导致钩子静默失效的问题,明确写出来能省掉大量排查时间。

三点:

1. 八类任务(注册/发帖/回帖/签到/完善资料/邀请好友/点赞/登录)里有几个是「事件型」(登录、点赞),有几个是「统计型」(发帖数达标)。事件型需要在钩子里即时累进,统计型可以查询时算。混在一起用同一张进度表时,重置逻辑要区分:每日任务跨天重置,管理员自定义的长期任务不能重置。
2. 「达标后手动领取」比自动发放好——自动发放会让用户无感知,手动领取有成就感,也能减少误发。但建议给「可领取」状态一个角标提醒。
3. 种子任务写入用 protected/.task_center_table_cache 做幂等守卫,这个文件名要确认在 Web 不可达路径下。

12 个 hooks 的数量偏多,建议在文档里列一张「钩子 → 作用」对照表,排查时能快速定位。
#1 楼

请 登录