本文由 FlintHub 开发文档归档发布。原始文档日期见标题前缀,来源:WWW/plugins/task_center/说明.md。
任务中心插件(task_center)说明
任务中心:注册 / 发帖 / 回帖 / 签到 / 完善资料 / 邀请好友 / 点赞 / 登录 八类任务,达标后手动领取积分奖励。支持每日任务(跨天重置、当日有效)与管理员自定义任务。
一、安装 / 激活
- 将
plugins/task_center/放入插件目录(本仓库已就位)。 - 手动更新
plugins/plugins_cache.json,加入task_center条目(含 12 个 hooks 清单)——否则钩子不生效。已添加。 - 后台启用插件(或确认
activated: true)。 - 首次 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 外图标回退问号)