「简记往来」开发历程系列:邀请码机制设计——有效期控制的完整方案

一、为什么需要有效期?

简记往来的多人协作功能,通过邀请码让用户加入账本。

如果邀请码永久有效,会有什么问题?

  1. 安全风险:很久以前发出的邀请码可能被意外使用
  2. 管理混乱:创建者不知道哪些邀请码还有效
  3. 权限过期:当初设定的"临时帮忙"权限,可能被长期使用

所以,邀请码必须有有效期。

二、邀请码生成方案

邀请码的生成规则:

javascript 复制代码
function generateInviteCode() {
    // 6位随机字符(字母+数字)
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    let code = ''
    for (let i = 0; i < 6; i++) {
        code += chars[Math.floor(Math.random() * chars.length)]
    }
    return code
}

6位字符的组合数约568亿(62^6),足够保证唯一性。如果生成时发现重复,重新生成即可。

三、有效期存储

邀请码的数据库结构:

json 复制代码
{
  "code": "aB3xZ9",
  "bookId": "book_xxx",
  "role": "editor",
  "createdAt": "2026-06-20T10:00:00Z",
  "expiresAt": "2026-06-23T10:00:00Z",
  "used": false,
  "usedAt": null,
  "usedBy": null
}
  • expiresAt:过期时间,创建时根据用户选择计算
  • used:是否已被使用
  • usedAt:使用时间
  • usedBy:使用者的用户ID

四、过期校验逻辑

用户输入邀请码时,进行三重校验:

javascript 复制代码
function validateInviteCode(code) {
    const invite = await db.invites.findOne({ code })
    
    // 校验1:邀请码是否存在
    if (!invite) return { valid: false, reason: '邀请码不存在' }
    
    // 校验2:是否已被使用
    if (invite.used) return { valid: false, reason: '邀请码已被使用' }
    
    // 校验3:是否已过期
    if (new Date() > new Date(invite.expiresAt)) {
        return { valid: false, reason: '邀请码已过期' }
    }
    
    return { valid: true, invite }
}

五、定时清理

过期的邀请码不需要立即删除,但需要定期清理,减少数据库存储。

简记往来的清理策略:

javascript 复制代码
// 每天凌晨2点执行
async function cleanExpiredInvites() {
    const result = await db.invites.deleteMany({
        expiresAt: { $lt: new Date() }
    })
    console.log(`清理了 ${result.deletedCount} 个过期邀请码`)
}

也可以使用MongoDB的TTL索引自动清理:

javascript 复制代码
db.invites.createIndex(
    { expiresAt: 1 },
    { expireAfterSeconds: 0 }
)

六、用户体验设计

过期校验失败时,给用户清晰的提示:

  • "邀请码已过期,请联系创建者重新生成"
  • "邀请码已被使用"
  • "邀请码不存在,请检查是否输入正确"

而不是统一的"邀请码无效"。

七、总结

邀请码机制的设计要点:

  1. 生成唯一码:6位随机字符,足够唯一
  2. 设置有效期:1-3天,过期自动失效
  3. 三重校验:存在性、使用状态、有效期
  4. 自动清理:减少数据库存储

这套方案已经在简记往来中稳定运行,可以直接复用。