txagent-y/docs/dev/api/API-01-用户系统.md

26 KiB
Raw Blame History

API-01 用户系统AUTH + USER

共 17 个接口AUTH-01~08 + USER-01~09


AUTH-01 账号密码注册

项目 说明
接口路径 POST /client/api/v1/auth/register
接口用途 新用户通过用户名+密码创建账号
权限要求 公开
涉及表 user, wallet, user_device

接口逻辑:

  1. 校验用户名格式2-20字符中英文/数字/下划线,不允许纯数字)
  2. 查询 user 表 检查用户名唯一性(不区分大小写,读)
  3. 校验密码规则≥8位含字母+数字confirmPassword 一致性
  4. 密码加密bcrypt
  5. 写入 user 表(含嵌套 profile、privacy_setting、notification_setting 默认值)
  6. 写入 wallet 表(初始 balance=0
  7. 签发 JWT Tokenaccess_token + refresh_token写入 user_device
  8. 返回用户信息和Token

请求参数Body

字段 类型 必选 说明
username string 用户名2-20字符中英文/数字/下划线,不允许纯数字,不区分大小写
password string 密码≥8位需含字母+数字
confirmPassword string 确认密码需与password一致

响应数据:

字段 类型 说明
userId string 用户ID (UUID)
username string 用户名
token string 访问令牌
refreshToken string 刷新令牌
expiresAt timestamp Token过期时间

AUTH-02 账号密码登录

项目 说明
接口路径 POST /client/api/v1/auth/login
接口用途 已有用户通过用户名+密码登录
权限要求 公开
涉及表 user, user_device

接口逻辑:

  1. 查询 user 表 根据用户名查找用户(读)
  2. 检查 user.status 是否为 3已注销→ 拒绝登录
  3. 检查 user.login_locked_until 是否未过期 → 账号锁定中
  4. 校验密码bcrypt compare失败则更新 user 表 的 login_fail_count+1更新
  5. 连续5次错误 → 更新 user 表 设置 login_locked_until = 当前时间+15分钟更新
  6. 密码正确 → 重置 login_fail_count=0更新 last_login_at更新 user
  7. 踢旧设备:将 user_device 表 中该用户所有 is_active=1 的记录更新为 is_active=0更新
  8. 签发新 JWT Token写入 user_device 表(写)
  9. 读取 user 嵌套的 profile 子文档,组装响应

请求参数Body

字段 类型 必选 说明
account string 用户名
password string 密码

响应数据:

字段 类型 说明
userId string 用户ID
username string 用户名
nickname string 昵称user.profile.display_name
avatar url 头像URLuser.profile.avatar_url
isCreator boolean 是否为创作者user.role=2
token string 访问令牌
refreshToken string 刷新令牌
expiresAt timestamp Token过期时间

AUTH-03 苹果登录

项目 说明
接口路径 POST /client/api/v1/auth/apple
接口用途 通过 Apple Sign In 登录/注册
权限要求 公开
涉及表 user, user_auth, wallet, user_device

接口逻辑:

  1. 向苹果服务器验证 identityToken 有效性
  2. 解析 identityToken 获取 provider_user_id
  3. 查询 user_auth 表 检查该 provider=apple + provider_user_id 是否已绑定(读)
  4. 已绑定(老用户):根据 user_auth.user_id 查询 user 表(读)
  5. 未绑定(新用户)
    • 自动生成用户名,写入 user 表(含嵌套 profile、privacy_setting、notification_setting
    • 写入 wallet 表(初始 balance=0
    • 写入 user_authprovider=apple
  6. 踢旧设备:更新 user_device 表 中旧记录 is_active=0更新
  7. 签发 JWT Token写入 user_device 表(写)
  8. 返回用户信息 + isNewUser 标记

请求参数Body

字段 类型 必选 说明
identityToken string 苹果返回的 identityToken
authorizationCode string 苹果返回的 authorizationCode
fullName string 苹果首次授权返回的用户全名

响应数据:

字段 类型 说明
userId string 用户ID
userNo string 9 位用户编号,供前端展示/搜索使用
username string 用户名
nickname string 昵称
avatar url 头像URL
isCreator boolean 是否为创作者
isNewUser boolean 是否为新注册用户
token string 访问令牌
refreshToken string 刷新令牌
expiresAt timestamp Token过期时间

AUTH-04 谷歌登录

项目 说明
接口路径 POST /client/api/v1/auth/google
接口用途 通过 Google Sign In 登录/注册
权限要求 公开
涉及表 user, user_auth, wallet, user_device

接口逻辑:

  1. 向 Google 服务器验证 idToken 有效性
  2. 解析 idToken 获取 provider_user_id 和邮箱
  3. 查询 user_auth 表 检查该 provider=google + provider_user_id 是否已绑定(读)
  4. 已绑定(老用户):根据 user_auth.user_id 查询 user 表(读)
  5. 未绑定(新用户)
    • 自动生成用户名,写入 user 表(含嵌套 profile、privacy_setting、notification_setting
    • 写入 wallet 表(初始 balance=0
    • 写入 user_authprovider=google
  6. 踢旧设备:更新 user_device 表 中旧记录 is_active=0更新
  7. 签发 JWT Token写入 user_device 表(写)
  8. 返回用户信息 + isNewUser 标记

请求参数Body

字段 类型 必选 说明
idToken string Google返回的 ID Token

响应数据:

字段 类型 说明
userId string 用户ID
username string 用户名
nickname string 昵称
avatar url 头像URL
isCreator boolean 是否为创作者
isNewUser boolean 是否为新注册用户
token string 访问令牌
refreshToken string 刷新令牌
expiresAt timestamp Token过期时间

AUTH-05 Token 刷新

项目 说明
接口路径 POST /client/api/v1/auth/refresh
接口用途 刷新过期的认证Token
权限要求 公开需有效refreshToken
涉及表 user_device

接口逻辑:

  1. 查询 user_device 表 根据 refresh_token 查找记录(读)
  2. 校验 refresh_token 是否过期refresh_token_expired_at和是否有效is_active=1
  3. 签发新的 access_token 和 refresh_token
  4. 更新 user_device 表 的 access_token、refresh_token 及对应过期时间(更新)
  5. 返回新Token

请求参数Body

字段 类型 必选 说明
refreshToken string 刷新令牌

响应数据:

字段 类型 说明
token string 新的访问令牌
refreshToken string 新的刷新令牌
expiresAt timestamp 新Token过期时间

AUTH-06 退出登录

项目 说明
接口路径 POST /client/api/v1/auth/logout
接口用途 用户主动退出登录
权限要求 需登录
涉及表 user_device, user, user_profile, user_privacy_setting, user_notification_setting

接口逻辑:

  1. 从请求 Header 中解析当前 access_token
  2. 查询 user_device 表 找到对应记录,取出 device_id(读)
  3. 更新该记录的 is_active=0更新 user_device
  4. 防僵尸游客号:若当前用户为正式账号(is_guest=0)且设备有 device_id
    • 查询 user_device JOIN user 表,检查该 device_id 是否已有 is_guest=1 的游客账号(读)
    • :不再创建,直接结束
    • :自动预建一条游客账号(同 AUTH-07 首次访问逻辑),绑定该 device_id 写入 user_device,供客户端下次调用 AUTH-07 时直接复用,不再新增僵尸账号
  5. 返回成功

请求参数:

响应数据: null


AUTH-07 游客登录

项目 说明
接口路径 POST /client/api/v1/auth/guest
接口用途 未注册用户通过设备指纹获取可用 Token无需提供账号密码同一设备重复调用会复用历史游客账号
权限要求 公开
涉及表 user, user_profile, user_privacy_setting, user_notification_setting, user_device

接口逻辑:

  1. 校验 deviceId必填≤128 字符其它可选字段长度限制deviceType ≤16、deviceName ≤64、appVersion ≤32
  2. 查询 user_device JOIN user 表,条件 device_id=$1 AND user.is_guest=1 AND user.deleted_at IS NULL AND user.status=1,按 user_device.id DESC 取最新一条(读)
  3. 命中(同设备老游客)
    • 再次校验 user.status,异常则拒绝
    • 进入第 5 步签发流程,复用原 userId
  4. 未命中(首次访问)
    • 生成随机用户名 guest_<12 位十六进制>,插入失败重试 1 次
    • 写入 user 表(is_guest=1, password_hash=NULL, role=1
    • 写入默认 user_profile / user_privacy_setting / user_notification_setting
    • 回读完整 user
  5. 签发 JWT Tokenaccess_token + refresh_token与正式用户同一把 secret 和 uid claim
  6. 写入 user_device 表,带上 device_id / device_type / device_name / app_version
  7. 读取 user_profile 子资料组装响应

请求参数Body

字段 类型 必选 说明
deviceId string 设备唯一标识≤128 字符),用于反查历史游客身份
deviceType string 设备平台ios / android / web≤16 字符)
deviceName string 机型或浏览器标识≤64 字符)
appVersion string 客户端版本号≤32 字符)

响应数据: 结构同 AUTH-02 AuthResp

字段 类型 说明
userId string 用户ID同设备复用
username string 随机生成的游客用户名,如 guest_a1b2c3d4e5f6
nickname string 昵称(首次为空,前端可 fallback 到"游客XXXX"
avatar url 头像URL首次为空
isCreator boolean 始终为 false
token string 访问令牌
refreshToken string 刷新令牌
expiresAt timestamp Token过期时间

安全约束:

  • 查询严格过滤 is_guest=1不会将其他用户绑定过该 deviceId 的正式账号误返给游客登录调用者
  • 游客账号会被算作普通用户消费各业务模块钱包、订阅、PPV 等),升级为正式账号后原 userId 保持不变

AUTH-08 游客升级 / 登录正式账号

项目 说明
接口路径 POST /client/api/v1/auth/upgrade
接口用途 游客切换正式账号,支持两种场景:①登录已有账号;②注册新账号。升级后原 userId 与所有关联数据profile / 钱包 / 关注 / 订阅 / PPV全部保留
权限要求 需登录(必须是游客账号)
涉及表 user, user_device

接口逻辑:

  1. 从 Token 解析 uid,校验 deviceId必填≤128 字符)

  2. 校验 username 格式2-20字符中英文/数字/下划线,不允许纯数字)

  3. 校验 password≥8位含字母+数字)

  4. 查询 user 表 加载当前用户,校验 user.is_guest == 1,否则返回 40901

  5. 按用户名查找正式账号user 表,不区分大小写,is_guest=0

    ─ 场景1用户名已存在登录已有账号

    • 校验目标账号未被封禁(否则 40301
    • bcrypt 校验 password失败返回 40101 "账号或密码错误"
    • 踢掉游客账号和目标账号的所有 is_active=1 设备记录(更新 user_device
    • 签发新 JWT Token以目标账号 userId 写入 user_device(带 device_id
    • 返回目标账号的 AuthResp

    ─ 场景2用户名不存在注册新账号

    • 查询 user_device JOIN user,检查 device_id 是否已关联正式账号(is_guest=0)→ 有则返回 40901 "该设备已关联正式账号,无法注册新账号"(防止同一设备注册多个账号)
    • 校验 confirmPasswordpassword 一致性
    • 检测设备号是否变更(与该游客最近 user_device 记录对比),变更则记录日志(预留风控 TODO
    • bcrypt 加密 password
    • 原子更新 user 表:SET username, password_hash, is_guest=0, username_changed_at=NOW() WHERE id=$uid AND is_guest=1,受影响行数为 0 返回 40901
    • 踢旧设备,签发新 JWT Token以游客原 userId 写入 user_device(带 device_id
    • 回读最新 user 行 + user_profile,返回 AuthResp

请求参数Body

字段 类型 必选 说明
deviceId string 设备唯一标识≤128 字符)
username string 用户名2-20字符中英文/数字/下划线,不允许纯数字
password string 密码≥8位需含字母+数字
confirmPassword string 确认密码,场景2注册新账号时必须与 password 一致场景1登录已有账号时可不传

响应数据: 结构同 AUTH-02 AuthResptoken / refreshToken 为新发放。

注意事项:

  • 旧的 access_token 与 refresh_token 全部失效,客户端必须使用新 Token 继续请求
  • 场景1游客账号的 userId 不再使用,关联数据保留在原正式账号下
  • 场景2游客账号的 userId 直接升级为正式账号原有数据profile / 钱包 / 关注 / 订阅 / PPV全部保留
  • 同一设备只能注册一个正式账号如需切换账号请用场景1输入已有账号的用户名密码
  • 本次仅实现用户名/密码路径Apple / Google 第三方升级未实现

USER-01 获取当前用户信息

项目 说明
接口路径 GET /client/api/v1/users/me
接口用途 获取登录用户的个人资料
权限要求 需登录
涉及表 user, user_profile, wallet, creator_application, creator_profile, user_follow, post

接口逻辑:

  1. 从Token中解析 user_id
  2. 查询 user 表 获取用户基本信息(读)
  3. 查询 user_profile 表 获取昵称、头像、简介、城市、性别、生日等资料(读)
  4. 查询 wallet 表 获取余额(读)
  5. 查询 creator_application 表 获取最新申请记录,计算 creatorStatus
  6. 查询 creator_profile 表 获取聚合档案(follower_count / following_count / content_count / total_likes),作为缺省统计来源(读)
  7. 查询 user_follow 表 实时统计 followingCountCOUNT WHERE follower_id=me和 followerCountCOUNT WHERE followee_id=me
  8. 查询 post 表 统计已发布内容数 postCountCOUNT WHERE author_id=me AND status=published
  9. user.role=2,则 creatorStatus 兜底返回 approved,避免与 isCreator=true 冲突
  10. 组装响应数据返回

请求参数:

响应数据:

字段 类型 说明
userId string 用户ID
username string 用户名
nickname string 昵称
avatar url 头像URL
avatarStatus string 头像审核状态none/reviewing/approved/rejected
bio string 个人简介
location object/null 地理位置 {name, code};当前实现返回 namecode 为空
gender number 性别1男 2女 3其他null未设置
birthday string 生日YYYY-MM-DD
isCreator boolean 是否为创作者user.role=2
creatorStatus string 创作者状态none/pending/approved/rejectedisCreator=true 则至少返回 approved
followerCount number 粉丝数
followingCount number 关注数
postCount number 已发布内容数
totalLikes number 累计获赞数;优先读取 creator_profile.total_likes,无创作者档案时返回 0
balance number 糖心币余额
isOnline boolean 在线状态(运行时计算)
createdAt timestamp 注册时间
usernameLastChangedAt timestamp 用户名上次修改时间

USER-02 修改个人资料

项目 说明
接口路径 PUT /client/api/v1/users/me
接口用途 修改昵称、头像、简介、地理位置等
权限要求 需登录
涉及表 user, user_profile, creator_profile

接口逻辑:

  1. 从Token中解析 user_id
  2. 如果修改 username
    • 查询 user 表 检查 username_changed_at 距今是否≥30天
    • 查询 user 表 检查新用户名唯一性(读)
    • 更新 user 表 的 username 和 username_changed_at更新
  3. 如果修改 avatar
    • 优先读取 avatarMediaId,查询 media 表校验媒体存在、归属当前用户、已处理完成且为图片(读)
    • 若未传 avatarMediaId,兼容读取旧字段 avatar
    • 最终更新 user_profile.avatar_urluser_profile.avatar_status=1(审核中)
  4. 如果修改 location
    • 校验 location.name 长度 ≤64、location.code 长度 ≤20
    • 当前首版将 location.name 持久化到 user_profile.city
  5. 其他字段nickname/bio/gender/birthday直接更新 user_profile
  6. 若当前用户为创作者,创作者主页 CREATOR-02 中相关字段会同步更新:
    • nicknameuser_profile.display_name
    • avataruser_profile.avatar_url
    • cityuser_profile.city
    • 当本次请求显式传入 bio 时,同步写入 creator_profile.description
  7. 返回更新后的用户资料

请求参数Body

字段 类型 必选 说明
username string 用户名2-20字符30天限改1次
nickname string 昵称2-20字符
avatarMediaId string 新字段,头像图片媒体 ID优先于 avatar 生效
avatar url 旧字段头像URL兼容保留deprecated
bio string 个人简介最多200字
location object 地理位置 {name, code},当前实现持久化 name
location.name string 地点显示名最长64字
location.code string 地点编码最长20字
gender number 性别1男 2女 3其他
birthday string 生日YYYY-MM-DD

响应数据:

字段 类型 说明
userId string 用户ID
username string 用户名
nickname string 昵称
avatar url 头像URL
avatarStatus string 头像审核状态
bio string 个人简介
location object/null 地理位置 {name, code};当前实现返回 namecode 为空
gender number 性别
birthday string 生日

USER-03 获取通知设置

项目 说明
接口路径 GET /client/api/v1/users/me/notification-setting
接口用途 获取当前用户的通知开关配置
权限要求 需登录
涉及表 user_notification_setting

接口逻辑:

  1. 从 Token 中解析 user_id
  2. 确保 user_notification_setting 默认行存在
  3. 读取 enable_push / enable_system / enable_interaction / enable_subscription
  4. 返回设置值

请求参数:

响应数据:

字段 类型 说明
enablePush boolean 私信消息通知
enableSystem boolean 系统通知
enableInteraction boolean 点赞与评论通知
enableSubscription boolean 订阅与上新通知

USER-04 更新通知设置

项目 说明
接口路径 PUT /client/api/v1/users/me/notification-setting
接口用途 更新当前用户的通知开关配置
权限要求 需登录
涉及表 user_notification_setting

接口逻辑:

  1. 从 Token 中解析 user_id
  2. 读取当前 user_notification_setting
  3. 对请求中传入的字段做局部覆盖,未传字段保持原值
  4. upsert 写回 user_notification_setting
  5. 返回更新后的设置值

请求参数Body

字段 类型 必选 说明
enablePush boolean 私信消息通知
enableSystem boolean 系统通知
enableInteraction boolean 点赞与评论通知
enableSubscription boolean 订阅与上新通知

响应数据: 同 USER-03


USER-05 获取隐私设置

项目 说明
接口路径 GET /client/api/v1/users/me/privacy-setting
接口用途 获取当前用户的隐私设置
权限要求 需登录
涉及表 user_privacy_setting

接口逻辑:

  1. 从 Token 中解析 user_id
  2. 确保 user_privacy_setting 默认行存在
  3. 读取 allow_dm / show_online_status / show_activity_status
  4. 按兼容映射返回:
    • hideLikedFeed = !showActivityStatus
    • privateAccount / hideFollowingList 当前固定返回 false

请求参数:

响应数据:

字段 类型 说明
privateAccount boolean 私密账号;当前固定返回 false
showOnlineStatus boolean 是否展示在线状态
hideFollowingList boolean 是否隐藏关注列表;当前固定返回 false
hideLikedFeed boolean 是否隐藏获赞动态,兼容映射自 showActivityStatus
showActivityStatus boolean 是否展示动态状态
allowDm boolean 是否允许私信

USER-06 更新隐私设置

项目 说明
接口路径 PUT /client/api/v1/users/me/privacy-setting
接口用途 更新当前用户的隐私设置
权限要求 需登录
涉及表 user_privacy_setting

接口逻辑:

  1. 从 Token 中解析 user_id
  2. 读取当前 user_privacy_setting
  3. 对请求中传入的字段做局部覆盖
  4. 当前实际持久化字段只有:
    • allowDm -> allow_dm
    • showOnlineStatus -> show_online_status
    • showActivityStatus -> show_activity_status
  5. 若请求未传 showActivityStatus 但传了 hideLikedFeed,则按 showActivityStatus = !hideLikedFeed 兼容映射
  6. privateAccount / hideFollowingList 当前仅兼容接收,不落库
  7. upsert 写回并返回最新设置

请求参数Body

字段 类型 必选 说明
privateAccount boolean 兼容字段,当前不落库
showOnlineStatus boolean 是否展示在线状态
hideFollowingList boolean 兼容字段,当前不落库
hideLikedFeed boolean 兼容字段,可推导 showActivityStatus
showActivityStatus boolean 是否展示动态状态
allowDm boolean 是否允许私信

响应数据: 同 USER-05


USER-07 获取第三方绑定状态

项目 说明
接口路径 GET /client/api/v1/users/me/oauth-bindings
接口用途 获取当前用户的 Apple / Google 绑定状态
权限要求 需登录
涉及表 user_auth

接口逻辑:

  1. 从 Token 中解析 user_id
  2. 查询 user_auth 表 当前用户已绑定 provider 列表
  3. 固定返回 google / apple 两项,并标记 bound

请求参数:

响应数据:

字段 类型 说明
list array 绑定状态列表
list[].provider string 第三方类型,目前固定为 google / apple
list[].bound boolean 是否已绑定

说明:设置页前端临时稿里提到的 /client/api/v1/auth/oauth/google/client/api/v1/auth/oauth/apple Web 绑定跳转接口,当前后端未纳入正式契约;现阶段仅支持 App 端 Apple/Google 登录,以及本接口返回绑定状态。


USER-08 修改密码

项目 说明
接口路径 PUT /client/api/v1/users/me/password
接口用途 用户修改登录密码
权限要求 需登录
涉及表 user

接口逻辑:

  1. 从Token中解析 user_id
  2. 查询 user 表 获取 password_hash
  3. 验证 oldPassword 与 password_hash 是否匹配bcrypt compare
  4. 校验 newPassword 规则≥8位含字母+数字confirmPassword 一致性
  5. 新密码加密bcrypt更新 user 表 的 password_hash更新
  6. 返回成功

请求参数Body

字段 类型 必选 说明
oldPassword string 旧密码
newPassword string 新密码≥8位含字母+数字
confirmPassword string 确认新密码

响应数据: null


USER-09 注销账号

项目 说明
接口路径 DELETE /client/api/v1/users/me
接口用途 用户申请注销账号(苹果审核要求"删除账号"
权限要求 需登录
涉及表 user, wallet, creator_profile, user_device

接口逻辑:

  1. 从Token中解析 user_id
  2. 校验 confirmPassworduser 表 的 password_hash + bcrypt compare
  3. 查询 wallet 表 检查 balance 是否为 0→ 不为0则拒绝
  4. 查询 user 表 检查 role 是否为 2创作者→ 是创作者则检查 creator_profile 是否已停用(读)
  5. 更新 user 表 的 status=3已注销释放用户名更新
  6. user_device 表 中该用户所有记录的 is_active=0更新
  7. 返回成功

请求参数Body

字段 类型 必选 说明
confirmPassword string 输入密码确认注销操作

响应数据: null