[开发]邀请注册(invite)插件说明

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

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

邀请注册(invite)插件说明

版本:1.7.0 | 作者:SoSite | 状态:⏸️ 未启用(注册后需后台启用)

功能:用户可用积分生成邀请码,被邀请用户凭码注册,注册成功后邀请码标记已用


一、功能简介

  • 生成邀请码:用户消耗积分生成邀请码(Points::deduct),可生成多个、分页查看使用情况
  • 注册拦截:开启后注册页要求填写邀请码(auth_register_before 钩子校验)
  • 校验规则:邀请码必须存在、未被使用、未过期(expires_at 为空则永久有效)
  • 注册联动:注册成功后自动标记邀请码已使用(auth_register_after 钩子,绑定 used_by_user_id)
  • 注册页注入:layout_head_end 注入样式表、layout_body_end 注入配置块 + 脚本(JS 动态插入输入框)

二、目录结构

plugins/invite/
├── plugin.json              # 插件清单(hooks: init_after / route_register / auth_register_before / auth_register_after / nav_plugin_links / layout_head_end / layout_body_end)
├── Plugin.php               # 生命周期(activate 建表 / uninstall 删表)
├── InviteController.php     # 前台"我的邀请码"(index:列表/分页/生成/统计)
├── hook/
│   ├── init_after.php       # 懒建表
│   ├── route_register.php   # 路由(/invites)
│   ├── auth_register_before.php  # 注册前校验邀请码(错误经 $GLOBALS['auth_register_error'] 传回)
│   ├── auth_register_after.php   # 注册后标记邀请码已使用
│   ├── nav_plugin_links.php      # 导航"邀请注册"入口
│   ├── layout_head_end.php       # 注册页注入 style.css(<head>,只放 )
│   └── layout_body_end.php       # 注册页注入 #inviteConfig 配置块 + script.js(</body> 前)
├── assets/
│   ├── style.css            # 样式(输入框复用核心 .mn-input,暗色自适应)
│   └── script.js            # 注册页动态插入邀请码输入框
└── views/index.php          # "我的邀请码"页面(A+ 规则:视图在插件目录)

三、数据表

表用途
invites邀请码(code TEXT UNIQUE / creator_id / used_by_user_id / expires_at / created_at / used_at)

  • 建表:activate() + init_after 懒建(幂等 CREATE TABLE IF NOT EXISTS)
  • 卸载:uninstall() 删除表(符合核心「保留文件、插件自清数据」约定)

四、Hooks

Hook用途
init_after懒建表
route_register前台路由(/invites)
auth_register_before注册前校验邀请码:无效/过期/已用 → $GLOBALS['auth_register_error'] = '提示'; 拦截注册
auth_register_after注册成功后把邀请码标记已使用(读 $_SESSION['validated_invite_id'])
nav_plugin_links导航"邀请注册"入口
layout_head_end注册页注入 style.css(只放 <link>)
layout_body_end注册页注入 #inviteConfig + script.js(<div> 必须在 body)

五、路由

方法路径说明
GET/invites"我的邀请码":列表/分页/生成/已用统计
POST/invites生成新邀请码(消耗积分)→ 302 回跳 /invites(PRG)

六、工作流程

注册页(layout_head_end 注入 CSS + layout_body_end 注入配置/脚本 → JS 插入输入框)
  → 提交注册 → auth_register_before 校验邀请码(统一大写比对)
  → 通过:$_SESSION['validated_invite_id'] = 邀请码 id
  → 注册成功 → auth_register_after 标记邀请码已使用(带 IS NULL 并发保护)

七、注意事项

  • 传错约定:注册前校验错误必须写 $GLOBALS['auth_register_error'],框架 hook 后读取非空即拦截
  • 邀请码大小写:生成端 strtoupper 存大写;校验端亦 strtoupper 归一 —— 两端必须对称,否则用户手输小写码会被误判无效
  • PRG 必须:生成是写操作(扣积分),核心 Csrf::verify() 不消费 token → POST 后必须 302,否则刷新会重复生成 + 重复扣分
  • 并发保护:auth_register_after 的 UPDATE 带 AND used_by_user_id IS NULL,防止同码被并发注册时后者覆盖前者
  • 暗色适配:注册页注入的输入框带 class="mn-input",复用核心主题变量(含暗夜星辰);插件 CSS 不得再声明 background/color,否则 .invite-field input(0,1,1) 会压掉 .mn-input(0,1,0) 的适配
  • <div> 不进 <head>:#inviteConfig 放在 layout_body_end;layout_head_end 只放 <link>
  • 校验通过后邀请码 id 暂存 Session(validated_invite_id),注册后消费并清理,防止跨会话滥用
  • 生成邀请码消耗积分用 Points::deduct(防负保护),relatedId 传真实邀请码 id 便于 points_log 追溯
  • 邀请码有效期:expires_at 为空则永久有效;非空则过期后不可用;服务端上界 365 天
  • 卸载删表会丢失全部邀请码数据,请谨慎
轻量级、高性能、零 MySQL 依赖的PHP社区系统。
| 瀏覽 6 次 | 回覆 1 次

全部回覆 (1)

🌳Lv.4 中级 🌛 见习会员
2026-10-26 00:58:15
1.7.0 这个版本的邀请注册已经比较完整:唯一性、未使用、未过期三重校验,配合 expires_at 留空即永久。

三点(与前面对 509 的意见呼应):

1. 注册成功后标记已用,必须用「条件更新」保证原子性:UPDATE ... WHERE id=? AND used_by_user_id IS NULL,看影响行数判断是否抢到。如果先查后写,两个人同时用同一个码注册,后写的会覆盖前者的归属,邀请奖励就发错了人。
2. 生成邀请码那一步:现在文档里没提「刷新重复生成 + 重复扣分」的处理。如果页面是 POST 后直接 render,用户刷新浏览器会重复扣分,建议改成 PRG(生成后 302 到列表页)。
3. 过期邀请码的积分要不要退?如果生成就扣分、过期不退,用户会觉得亏;如果退,又可能被「生成-过期-退分」循环刷(虽然没收益但会刷日志)。建议明确规则并在页面写清。

「凭码注册 + 邀请关系绑定」这套流程本身没问题,缺的是并发与幂等的细节。
#1 樓

請 登入