需求说明
- 用户有两种角色,会员or非会员
- 成为会员的途径:
- 分享给好友,并且好友点击该链接
- 点击好友分享的链接,并且该好友有解锁名额
- 别的渠道
- 每个人最多给3个人解锁
设计
记邀请者为A,被邀请者为B
数据库设计
解锁记录vip_unlock_event
字段名 | 类型 | 备注 |
---|---|---|
openid | varchar | 本次会被解锁的用户openid |
relate_openid | varchar | 关联用户的openid,关联用户不一定会被解锁 |
CREATE_DATE | DateTime | 时间 |
开通会员记录vip_record
字段名 | 类型 | 备注 |
---|---|---|
openid | varchar | openid |
type | varchar | 开通类型:被邀请,邀请,付费 |
expire_date | int | 会员到期的时间戳 |
CREATE_DATE | DateTime | 时间 |
流程
1. 生成分享链接
用户ID
2. 插入数据的时机
- 当检测用户B打开小程序的路径为 /empty/empty?invite=jwt时,
- 如果B不为会员,则插入一条A邀请B的记录
- 如果B为会员,不插入邀请记录(防止占用名额)
- 如果A不为会员,则插入A开通会员记录(类型:邀请),且插入一条B邀请A的记录(占用B一个邀请名额)
- 如果B不为会员,且A的邀请记录<3,则插入B开通会员记录(类型:被邀请)
- 返回状态:正常解锁、B本身是会员、A无名额
0表示:非会员;未满;不新增;
不可能存在的状态 01xx 、 xx01 七种
用户A | A额度 | 用户B | B额度 | A解锁别人 | B解锁别人 | 会员A | 会员B | B的返回值 |
---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 你和他都开通了会员 |
0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 你为他解锁了 |
0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 你没额度了 |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 你已解锁 |
1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 你和他都已开通,无需解锁 |
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 你和他都已开通,无需解锁 |
1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 他额度满了,没法给你解锁;他已经是会员了,无需你帮他解锁 |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 你和他都已开通,无需解锁 |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 你和他都已开通,无需解锁 |
A解锁别人 = B开通会员 = 用户B不是会员 && A有额度
B解锁别人 = A开通会员 = 用户A不是会员 && B有额度
3. 怎么判断是否为会员
开通会员记录 > 0 且 MAX(expire_date) > NOW()
接口
- 获取邀请链接
genInviteUrl - 判断角色vip状态
- url:
/user/auth/info
- resp:
{
"role" : "user | vip",
"expireDate" : "时间戳",
"unlockCount" : "0"
}
- 判断链接
- url :
/user/invite/check
- resp:
error("非有效链接")
{
"othersName" : "邀请者昵称",
}
- 接受邀请
- url :
/user/invite/accept
- resp:
{
"success":true,
"msg" : "成功解锁",
}
{
"success":false,
"msg" : "抱歉,对方的解锁额度已经用完。你可以邀请其他人已完成解锁",
}