VIP 拉新裂变
好的,我们来从头开始,清晰地整理数据库设计和完整的实现路径。
一、数据库设计
您需要创建以下 4 张表来支持这个裂变活动。
1. 用户表 (users)
存储用户核心信息,这是您已有的表,需要新增字段。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
id | BIGINT (主键, 自增) | 是 | 系统内部用户 ID |
openid | VARCHAR(128) (唯一索引) | 是 | 微信用户唯一标识,防刷核心 |
nickname | VARCHAR(255) | 是 | 微信昵称 |
avatar_url | VARCHAR(512) | 否 | 微信头像 |
vip_level | TINYINT (默认: 0) | 是 | 新增字段。用户等级:0-普通,1-VIP,2-SVIP |
can_invite | TINYINT (默认: 1) | 是 | 新增字段。是否可邀请:1-可邀请,0-不可邀请 |
create_time | DATETIME | 是 | 注册时间 |
2. 邀请关系表 (invitation_relations)
核心表,记录每一次成功邀请,用于计算和防刷。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
id | BIGINT (主键, 自增) | 是 | |
inviter_id | BIGINT (外键, 关联users.id) | 是 | 邀请人 ID |
invitee_id | BIGINT (外键, 关联users.id) (唯一约束) | 是 | 被邀请人 ID。唯一约束防止重复计算 |
create_time | DATETIME | 是 | 邀请时间 |
3. 用户任务进度表 (user_task_progress)
记录每个用户的邀请进度,避免频繁查询invitation_relations表计数。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
id | BIGINT (主键, 自增) | 是 | |
user_id | BIGINT (外键, 关联users.id) (唯一索引) | 是 | |
invite_count | INT (默认: 0) | 是 | 当前累计有效邀请人数 |
update_time | DATETIME | 是 | 最后更新时间 |
4. 奖励记录表 (reward_records)
记录所有奖励发放,防止重复发放。
| 字段名 | 类型 | 必填 | 描述 |
|---|---|---|---|
id | BIGINT (主键, 自增) | 是 | |
user_id | BIGINT (外键, 关联users.id) | 是 | 获得奖励的用户 ID |
reward_type | VARCHAR(50) | 是 | 奖励类型:vip_promote、svip_promote |
reward_data | JSON | 否 | 奖励内容详情(如:{"vip_days": 30}) |
create_time | DATETIME | 是 | 发放时间 |
二、完整实现路径与流程
第 1 步:用户 A 发起邀请(老用户)
- 前端:用户 A 点击小程序内的“邀请好友”按钮。
- 后端 API (
GET /api/invite/generate):- 校验用户 A 的登录状态和
can_invite权限。 - 生成一个小程序码,并在
scene参数中编码用户 A 的 ID(例如:scene=inviter_id:123)。 - 返回生成的小程序码和预设的分享文案、海报给前端。
- 校验用户 A 的登录状态和
- 前端:用户 A 将海报分享到朋友圈或微信群。
第 2 步:用户 B 接受邀请(新用户)
- 入口:用户 B 通过扫描海报上的小程序码进入小程序。
- 前端:小程序启动时,通过
wx.getLaunchOptionsSync()获取 URL 中的scene参数,解析出inviter_id(用户 A 的 ID)。 - 授权:引导用户 B 点击按钮(如“立即参与”),触发
wx.getUserProfile()获取昵称头像,并静默调用wx.login()获取code。
第 3 步:注册与绑定关系(核心防刷逻辑)
- 前端:将获取到的
inviter_id、userInfo、code发送至后端 APIPOST /api/invite/register。 - 后端 (
/api/invite/register),执行以下原子操作: a. 换取 OpenID:使用code调用微信接口换取用户 B 的openid。 b. 校验新用户:根据openid查询用户表。 _ 如果用户已存在:直接返回错误“您已注册,无法参与活动”。流程结束。 c. 创建新用户:将用户 B 的信息(openid,nickname,avatar_url)写入users表。vip_level默认为 0,can_invite默认为 1。 d. 初始化进度:在user_task_progress表为用户 B 创建一条记录,并将invite_count设置为 1。 e. 记录关系:尝试向invitation_relations表插入一条记录(inviter_id=A, invitee_id=B)。 _ 如果因invitee_id唯一约束冲突而失败,说明已处理过,直接返回成功。 f. 更新邀请人进度:为用户 A 的user_task_progress记录,将invite_count字段 +1。 g. 检查并升级用户 A:检查用户 A 最新的invite_count。 _ ifinvite_count >= 5-> 将用户 A 的vip_level更新为 2 (SVIP),并记录奖励。 _ else ifinvite_count >= 2-> 将用户 A 的vip_level更新为 1 (VIP),并记录奖励。 h. 检查并升级用户 B:检查用户 B 的invite_count(当前为 1),因 1<2 且 1<5,故不升级。 i. 返回成功:返回操作成功的结果给前端。
第 4 步:前端反馈与引导
- 前端:收到后端成功响应后,根据当前用户是 A 还是 B 显示不同页面。
- 如果是用户 A(邀请人):弹出 Toast 提示“邀请成功!”,并更新其首页的进度条显示。
- 如果是用户 B(新用户):显示一个注册成功页,内容如下:
“恭喜您成功加入! 您已自动获得 1 个邀请计数。 再邀请 1 位 好友,您即可晋升为 VIP! [立即邀请好友]”
- “立即邀请好友”按钮直接跳转到第 1 步的邀请页面。
三、关键防刷措施总结
- OpenID 唯一性:一个微信用户只能有一个 OpenID,无法伪造。
- 关系表唯一约束:一个被邀请人只能被成功记录一次,防止刷单。
- 新用户校验:只有
openid在系统中不存在的用户才算新用户,老用户点击无效。 - (可选) 行为监控:可监控异常 IP、异常频率的注册行为,自动锁定可疑用户(将其
can_invite设为 0)。
这套设计为您提供了一个完整、健壮且可扩展的“双向计数裂变”技术方案。您需要做的就是按照这个流程,实现两个核心 API (/api/invite/generate 和 /api/invite/register) 以及四张数据库表。