35 KiB
API-01 用户系统(AUTH + USER)
共 18 个接口:AUTH-01~08 + USER-01~10
图片字段约定:本文件中的
avatar等图片类字段,后端当前返回的是老司机/CDN 绝对地址。H5 渲染前需先走媒体 helper 转成同源代理地址,不要直接把原始 URL 塞进<img src>、<video poster>、canvasnew Image()或 CSSbackground-image。
认证链路设备与归因参数约定:为支持登录/注册埋点、设备归因与推广归因,
AUTH-01/02/03/04建议客户端统一透传X-Device-ID和X-Platform。其中X-Platform支持ios / android / h5 / web / pc,后端会将web / pc统一按h5处理;AUTH-01/02/07额外支持在 Body 中传可选affCodeJSON 字符串(形如{"dc":"渠道A","pc":"12345","channel":"landingA","traceId":"trace-xxx"}),用于渠道/推广归因;AUTH-01/02原有X-Track-Channel仍可继续透传,但在新实现中仅作为affCode.dc / affCode.channel都未提供时的 fallback;AUTH-07继续使用 Body 中的deviceId / deviceType,并可同时带affCode;AUTH-08继续要求 Body 中传deviceId。
AUTH-01 账号密码注册
| 项目 | 说明 |
|---|---|
| 接口路径 | POST /client/api/v1/auth/register |
| 接口用途 | 新用户通过用户名+密码创建账号 |
| 权限要求 | 公开 |
| 涉及表 | user, wallet, user_device |
接口逻辑:
- 校验用户名格式(2-20字符,中英文/数字/下划线,不允许纯数字)
- 查询
user表 检查用户名唯一性(不区分大小写,读) - 校验密码规则(≥8位含字母+数字),confirmPassword 一致性
- 密码加密(bcrypt)
- 写入
user表(含嵌套 profile、privacy_setting、notification_setting 默认值) - 写入
wallet表(初始 balance=0) - 如请求 Body 传
affCode,则解析其中的dc / pc / channel / traceId:dc优先作为渠道号,channel次之,二者都没有时才回退使用 HeaderX-Track-Channel;pc按推广 clickId 解释;traceId用于注册埋点trace_id - 签发 JWT Token(access_token + refresh_token),写入
user_device表;若请求 Header 带X-Device-ID,则同时写入user_device.device_id,user_device.device_type取服务端现有设备识别结果(X-Platform→User-Agent→ 默认h5),其中X-Platform=web/pc会归并为h5;注册成功埋点以及注册后自动补发的登录埋点会透传上一步归一化后的渠道值 - 返回用户信息和Token
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| username | string | 是 | 用户名,2-20字符,中英文/数字/下划线,不允许纯数字,不区分大小写 |
| password | string | 是 | 密码,≥8位,需含字母+数字 |
| confirmPassword | string | 是 | 确认密码,需与password一致 |
| affCode | string | 否 | 剪切板归因 JSON 字符串,支持字段 dc / pc / channel / traceId;dc 优先作为渠道号,pc 按推广 clickId 解释,traceId 仅影响注册埋点 trace_id |
请求 Header(可选):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| X-Device-ID | string | 否 | 客户端设备唯一标识;注册时若提供,后端会写入 user_device.device_id |
| X-Platform | string | 否 | 设备平台标识:ios / android / h5 / web / pc;用于推断 user_device.device_type 和埋点 device |
| X-Track-Channel | string | 否 | 渠道号/渠道标识;当 affCode.dc 与 affCode.channel 都未提供时,后端会回退使用该值作为注册成功埋点及注册后自动补发登录埋点的 channel |
设备字段说明:
device_type不通过 Body 显式传参,后端按现有请求识别逻辑推断:X-Platform→User-Agent→ 默认h5X-Platform支持ios / android / h5 / web / pc,其中web / pc会统一按h5处理- 未显式传
X-Platform时,后端仅通过User-Agent继续识别ios / android;仍无法识别时默认写h5 X-Device-ID未提供时,user_device.device_id置空affCode为可选 Body 字段,不影响注册主流程;解析失败时接口仍按正常注册逻辑执行,只忽略本次归因信息affCode的渠道优先级为dc > channel > X-Track-Channel;其中pc按推广 clickId 解释,不再兼作邀请码语义X-Track-Channel为 Header fallback 字段,不走 Body;当前用于注册成功后的渠道埋点,不写入user_device/user等业务表- 设备类型无法识别时,按当前后端现有识别结果写入;本接口不新增单独的设备类型协议字段
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID (UUID) |
| username | string | 用户名 |
| isGuest | boolean | 是否为游客账号;注册返回固定 false |
| token | string | 访问令牌 |
| refreshToken | string | 刷新令牌 |
| expiresAt | timestamp | Token过期时间 |
AUTH-02 账号密码登录
| 项目 | 说明 |
|---|---|
| 接口路径 | POST /client/api/v1/auth/login |
| 接口用途 | 已有用户通过用户名+密码登录 |
| 权限要求 | 公开 |
| 涉及表 | user, user_device |
接口逻辑:
- 查询
user表 根据用户名查找用户(读) - 检查 user.status 是否为 3(已注销)→ 拒绝登录
- 检查 user.login_locked_until 是否未过期 → 账号锁定中
- 校验密码(bcrypt compare),失败则更新
user表 的 login_fail_count+1(更新) - 连续5次错误 → 更新
user表 设置 login_locked_until = 当前时间+15分钟(更新) - 密码正确 → 重置 login_fail_count=0,更新 last_login_at(更新
user) - 踢旧设备:将
user_device表 中该用户所有 is_active=1 的记录更新为 is_active=0(更新) - 如请求 Body 传
affCode,则解析其中的dc / pc / channel / traceId:dc优先作为渠道号,channel次之,二者都没有时才回退使用 HeaderX-Track-Channel;pc按推广 clickId 解释;traceId在登录链路不新增响应字段,仅供归因上下文使用 - 签发新 JWT Token,写入
user_device表(写);若请求 Header 带X-Device-ID,后端会同时读取该值和当前设备识别结果,用于平台登录埋点上报;登录成功埋点会透传上一步归一化后的渠道值 - 读取 user 嵌套的 profile 子文档,组装响应
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| account | string | 是 | 用户名 |
| password | string | 是 | 密码 |
| affCode | string | 否 | 剪切板归因 JSON 字符串,支持字段 dc / pc / channel / traceId;dc 优先作为渠道号,pc 按推广 clickId 解释 |
请求 Header(可选):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| X-Device-ID | string | 否 | 客户端设备唯一标识;登录时若提供,后端会用于平台登录埋点上报 |
| X-Platform | string | 否 | 设备平台标识:ios / android / h5 / web / pc;用于平台登录埋点中的 device |
| X-Track-Channel | string | 否 | 渠道号/渠道标识;当 affCode.dc 与 affCode.channel 都未提供时,后端会回退使用该值作为登录成功埋点的 channel |
设备字段说明:
- 登录接口会继续读取现有设备识别信息(
X-Platform→User-Agent→ 默认h5),用于平台登录埋点中的device X-Platform支持ios / android / h5 / web / pc,其中web / pc会统一按h5处理- 未显式传
X-Platform时,后端仅通过User-Agent继续识别ios / android;仍无法识别时,平台埋点默认按H5上报 affCode为可选 Body 字段,不影响登录主流程;解析失败时接口仍按正常登录逻辑执行,只忽略本次归因信息affCode的渠道优先级为dc > channel > X-Track-Channel;其中pc按推广 clickId 解释X-Track-Channel为 Header fallback 字段,不走 Body;当前用于登录成功后的渠道埋点,不写入user_device/user等业务表- 本期登录链路不额外承诺把
device_id / device_type回写到user_device,当前仅用于下游平台上报
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID |
| username | string | 用户名 |
| nickname | string | 昵称(user.profile.display_name) |
| avatar | url | 头像URL(user.profile.avatar_url) |
| isGuest | boolean | 是否为游客账号(user.is_guest=1) |
| 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 |
接口逻辑:
- 向苹果服务器验证 identityToken 有效性
- 解析 identityToken 获取 provider_user_id
- 查询
user_auth表 检查该 provider=apple + provider_user_id 是否已绑定(读) - 已绑定(老用户):根据 user_auth.user_id 查询
user表(读) - 未绑定(新用户):
- 自动生成用户名,写入
user表(含嵌套 profile、privacy_setting、notification_setting) - 写入
wallet表(初始 balance=0) - 写入
user_auth表(provider=apple)
- 自动生成用户名,写入
- 踢旧设备:更新
user_device表 中旧记录 is_active=0(更新) - 签发 JWT Token,写入
user_device表(写) - 返回用户信息 + isNewUser 标记
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| identityToken | string | 是 | 苹果返回的 identityToken |
| authorizationCode | string | 是 | 苹果返回的 authorizationCode |
| fullName | string | 否 | 苹果首次授权返回的用户全名 |
请求 Header(建议传入):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| X-Device-ID | string | 否 | 客户端设备唯一标识;若提供,后端会随登录设备信息与埋点一并透传 |
| X-Platform | string | 否 | 设备平台标识:ios / android / h5 / web / pc;用于设备类型识别与埋点上报 |
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID |
| userNo | string | 9 位用户编号,供前端展示/搜索使用 |
| username | string | 用户名 |
| nickname | string | 昵称 |
| avatar | url | 头像URL |
| isGuest | boolean | 是否为游客账号;第三方登录返回固定 false |
| 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 |
接口逻辑:
- 向 Google 服务器验证 idToken 有效性
- 解析 idToken 获取 provider_user_id 和邮箱
- 查询
user_auth表 检查该 provider=google + provider_user_id 是否已绑定(读) - 已绑定(老用户):根据 user_auth.user_id 查询
user表(读) - 未绑定(新用户):
- 自动生成用户名,写入
user表(含嵌套 profile、privacy_setting、notification_setting) - 写入
wallet表(初始 balance=0) - 写入
user_auth表(provider=google)
- 自动生成用户名,写入
- 踢旧设备:更新
user_device表 中旧记录 is_active=0(更新) - 签发 JWT Token,写入
user_device表(写) - 返回用户信息 + isNewUser 标记
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| idToken | string | 是 | Google返回的 ID Token |
请求 Header(建议传入):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| X-Device-ID | string | 否 | 客户端设备唯一标识;若提供,后端会随登录设备信息与埋点一并透传 |
| X-Platform | string | 否 | 设备平台标识:ios / android / h5 / web / pc;用于设备类型识别与埋点上报 |
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID |
| username | string | 用户名 |
| nickname | string | 昵称 |
| avatar | url | 头像URL |
| isGuest | boolean | 是否为游客账号;Google 登录返回固定 false |
| isCreator | boolean | 是否为创作者 |
| isNewUser | boolean | 是否为新注册用户 |
| token | string | 访问令牌 |
| refreshToken | string | 刷新令牌 |
| expiresAt | timestamp | Token过期时间 |
AUTH-05 Token 刷新
| 项目 | 说明 |
|---|---|
| 接口路径 | POST /client/api/v1/auth/refresh |
| 接口用途 | 刷新过期的认证Token |
| 权限要求 | 公开(需有效refreshToken) |
| 涉及表 | user_device |
接口逻辑:
- 查询
user_device表 根据 refresh_token 查找记录(读) - 校验 refresh_token 是否过期(refresh_token_expired_at)和是否有效(is_active=1)
- 签发新的 access_token 和 refresh_token
- 更新
user_device表 的 access_token、refresh_token 及对应过期时间(更新) - 返回新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 |
接口逻辑:
- 从请求 Header 中解析当前 access_token
- 查询
user_device表 找到对应记录,取出device_id(读) - 更新该记录的 is_active=0(更新
user_device) - 防僵尸游客号:若当前用户为正式账号(
is_guest=0)且设备有device_id:- 查询
user_deviceJOINuser表,检查该device_id是否已有is_guest=1的游客账号(读) - 有:不再创建,直接结束
- 无:自动预建一条游客账号(同 AUTH-07 首次访问逻辑),绑定该
device_id写入user_device,供客户端下次调用 AUTH-07 时直接复用,不再新增僵尸账号
- 查询
- 返回成功
请求参数: 无
响应数据: null
AUTH-07 游客登录
| 项目 | 说明 |
|---|---|
| 接口路径 | POST /client/api/v1/auth/guest |
| 接口用途 | 未注册用户通过设备指纹获取可用 Token,无需提供账号密码;同一设备重复调用会复用历史游客账号 |
| 权限要求 | 公开 |
| 涉及表 | user, user_profile, user_privacy_setting, user_notification_setting, user_device |
接口逻辑:
- 校验 deviceId(必填,≤128 字符),其它可选字段长度限制:deviceType ≤16、deviceName ≤64、appVersion ≤32
- 查询
user_deviceJOINuser表,条件device_id=$1 AND user.is_guest=1 AND user.deleted_at IS NULL AND user.status=1,按user_device.id DESC取最新一条(读) - 命中(同设备老游客):
- 再次校验
user.status,异常则拒绝 - 进入第 5 步签发流程,复用原
userId
- 再次校验
- 未命中(首次访问):
- 生成随机用户名
guest_<12 位十六进制>,插入失败重试 1 次 - 写入
user表(is_guest=1, password_hash=NULL, role=1) - 写入默认
user_profile/user_privacy_setting/user_notification_setting - 回读完整
user行
- 生成随机用户名
- 签发 JWT Token(access_token + refresh_token,与正式用户同一把 secret 和 uid claim)
- 如请求 Body 传
affCode,则解析其中的dc / pc / channel / traceId:dc优先作为渠道号,channel次之;pc按推广 clickId 解释;首次创建游客账号时,traceId会透传到游客注册埋点,后续复用老游客仅影响登录归因上下文 - 写入
user_device表,带上device_id / device_type / device_name / app_version - 读取
user_profile子资料组装响应
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| deviceId | string | 是 | 设备唯一标识(≤128 字符),用于反查历史游客身份 |
| deviceType | string | 否 | 设备平台:ios / android / web(≤16 字符) |
| deviceName | string | 否 | 机型或浏览器标识(≤64 字符) |
| appVersion | string | 否 | 客户端版本号(≤32 字符) |
| affCode | string | 否 | 剪切板归因 JSON 字符串,支持字段 dc / pc / channel / traceId;dc 优先作为渠道号,pc 按推广 clickId 解释,traceId 仅在首次创建游客账号时影响注册埋点 trace_id |
设备字段说明:
deviceId为游客身份复用主键,必须稳定透传;同一设备重复调用会复用历史游客账号deviceType建议透传真实平台值;web / pc会在后端埋点口径中统一按h5处理deviceName / appVersion主要用于设备排查与埋点维度,不影响游客账号复用规则affCode为可选 Body 字段;解析失败时接口仍按正常游客登录逻辑执行,只忽略本次归因信息affCode的渠道优先级为dc > channel;AUTH-07不依赖X-Track-Channel作为主传参
响应数据: 结构同 AUTH-02 AuthResp
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID(同设备复用) |
| username | string | 随机生成的游客用户名,如 guest_a1b2c3d4e5f6 |
| nickname | string | 昵称(首次为空,前端可 fallback 到"游客XXXX") |
| avatar | url | 头像URL(首次为空) |
| isGuest | boolean | 固定为 true |
| 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 |
接口逻辑:
-
从 Token 解析
uid,校验deviceId(必填,≤128 字符) -
校验 username 格式(2-20字符,中英文/数字/下划线,不允许纯数字)
-
校验 password(≥8位含字母+数字)
-
查询
user表 加载当前用户,校验user.is_guest == 1,否则返回 40901 -
按用户名查找正式账号(
user表,不区分大小写,is_guest=0):─ 场景1:用户名已存在(登录已有账号)─
- 校验目标账号未被封禁(否则 40301)
- bcrypt 校验 password,失败返回 40101 "账号或密码错误"
- 踢掉游客账号和目标账号的所有
is_active=1设备记录(更新user_device) - 签发新 JWT Token,以目标账号
userId写入user_device(带device_id) - 返回目标账号的
AuthResp
─ 场景2:用户名不存在(注册新账号)─
- 查询
user_deviceJOINuser,检查device_id是否已关联正式账号(is_guest=0)→ 有则返回 40901 "该设备已关联正式账号,无法注册新账号"(防止同一设备注册多个账号) - 校验
confirmPassword与password一致性 - 检测设备号是否变更(与该游客最近
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 AuthResp,token / 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 |
接口逻辑:
- 从Token中解析 user_id
- 查询
user表 获取用户基本信息(读) - 查询
user_profile表 获取昵称、头像、简介、城市、性别、生日等资料(读) - 查询
wallet表 获取余额(读) - 查询
creator_application表 获取最新申请记录,计算 creatorStatus(读) - 查询
creator_profile表 获取聚合档案(follower_count/following_count/content_count/total_likes),作为缺省统计来源(读) - 查询
user_follow表 实时统计 followingCount(COUNT WHERE follower_id=me)和 followerCount(COUNT WHERE followee_id=me)(读) - 查询
post表 统计已发布内容数 postCount(COUNT WHERE author_id=me AND status=published)(读) - 若
user.role=2,则creatorStatus兜底返回approved,避免与isCreator=true冲突 - 组装响应数据返回
请求参数: 无
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | string | 用户ID |
| username | string | 用户名 |
| nickname | string | 昵称 |
| avatar | url | 头像URL |
| avatarStatus | string | 头像审核状态:none/reviewing/approved/rejected |
| bio | string | 个人简介 |
| location | object/null | 地理位置 {name, code};当前实现返回 name,code 为空 |
| gender | number | 性别:1男 2女 3其他,null未设置 |
| birthday | string | 生日(YYYY-MM-DD) |
| isGuest | boolean | 是否为游客账号(user.is_guest=1) |
| isCreator | boolean | 是否为创作者(user.role=2) |
| creatorStatus | string | 创作者状态:none/pending/approved/rejected;若 isCreator=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 |
接口逻辑:
- 从Token中解析 user_id
- 如果修改 username:
- 查询
user表 检查 username_changed_at 距今是否≥30天(读) - 查询
user表 检查新用户名唯一性(读) - 更新
user表 的 username 和 username_changed_at(更新)
- 查询
- 如果修改 avatar:
- 优先读取
avatarMediaId,查询media表校验媒体存在、归属当前用户、已处理完成且为图片(读) - 若未传
avatarMediaId,兼容读取旧字段avatar - 最终更新
user_profile.avatar_url和user_profile.avatar_status=1(审核中)
- 优先读取
- 如果修改
location:- 校验
location.name长度 ≤64、location.code长度 ≤20 - 当前首版将
location.name持久化到user_profile.city
- 校验
- 其他字段(nickname/bio/gender/birthday)直接更新
user_profile - 若当前用户为创作者,创作者主页
CREATOR-02中相关字段会同步更新:nickname←user_profile.display_nameavatar←user_profile.avatar_urlcity←user_profile.city- 当本次请求显式传入
bio时,同步写入creator_profile.description
- 返回更新后的用户资料
请求参数(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};当前实现返回 name,code 为空 |
| gender | number | 性别 |
| birthday | string | 生日 |
USER-03 获取通知设置
| 项目 | 说明 |
|---|---|
| 接口路径 | GET /client/api/v1/users/me/notification-setting |
| 接口用途 | 获取当前用户的通知开关配置 |
| 权限要求 | 需登录 |
| 涉及表 | user_notification_setting |
接口逻辑:
- 从 Token 中解析 user_id
- 确保
user_notification_setting默认行存在 - 读取
enable_push / enable_system / enable_interaction / enable_subscription - 返回设置值
请求参数: 无
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| enablePush | boolean | 私信消息通知 |
| enableSystem | boolean | 系统通知 |
| enableInteraction | boolean | 点赞与评论通知 |
| enableSubscription | boolean | 订阅与上新通知 |
USER-04 更新通知设置
| 项目 | 说明 |
|---|---|
| 接口路径 | PUT /client/api/v1/users/me/notification-setting |
| 接口用途 | 更新当前用户的通知开关配置 |
| 权限要求 | 需登录 |
| 涉及表 | user_notification_setting |
接口逻辑:
- 从 Token 中解析 user_id
- 读取当前
user_notification_setting - 对请求中传入的字段做局部覆盖,未传字段保持原值
- upsert 写回
user_notification_setting - 返回更新后的设置值
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| enablePush | boolean | 否 | 私信消息通知 |
| enableSystem | boolean | 否 | 系统通知 |
| enableInteraction | boolean | 否 | 点赞与评论通知 |
| enableSubscription | boolean | 否 | 订阅与上新通知 |
响应数据: 同 USER-03
USER-05 获取隐私设置
| 项目 | 说明 |
|---|---|
| 接口路径 | GET /client/api/v1/users/me/privacy-setting |
| 接口用途 | 获取当前用户的隐私设置 |
| 权限要求 | 需登录 |
| 涉及表 | user_privacy_setting |
接口逻辑:
- 从 Token 中解析 user_id
- 确保
user_privacy_setting默认行存在 - 读取
allow_dm / show_online_status / show_activity_status - 按兼容映射返回:
hideLikedFeed = !showActivityStatusprivateAccount / 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 |
接口逻辑:
- 从 Token 中解析 user_id
- 读取当前
user_privacy_setting - 对请求中传入的字段做局部覆盖
- 当前实际持久化字段只有:
allowDm -> allow_dmshowOnlineStatus -> show_online_statusshowActivityStatus -> show_activity_status
- 若请求未传
showActivityStatus但传了hideLikedFeed,则按showActivityStatus = !hideLikedFeed兼容映射 privateAccount / hideFollowingList当前仅兼容接收,不落库- 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 |
接口逻辑:
- 从 Token 中解析 user_id
- 查询
user_auth表 当前用户已绑定 provider 列表 - 固定返回
google / apple两项,并标记bound
请求参数: 无
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| list | array | 绑定状态列表 |
| list[].provider | string | 第三方类型,目前固定为 google / apple |
| list[].bound | boolean | 是否已绑定 |
说明:设置页前端临时稿里提到的
/client/api/v1/auth/oauth/google、/client/api/v1/auth/oauth/appleWeb 绑定跳转接口,当前后端未纳入正式契约;现阶段仅支持 App 端 Apple/Google 登录,以及本接口返回绑定状态。
USER-08 修改密码
| 项目 | 说明 |
|---|---|
| 接口路径 | PUT /client/api/v1/users/me/password |
| 接口用途 | 用户修改登录密码 |
| 权限要求 | 需登录 |
| 涉及表 | user |
接口逻辑:
- 从Token中解析 user_id
- 查询
user表 获取 password_hash(读) - 验证 oldPassword 与 password_hash 是否匹配(bcrypt compare)
- 校验 newPassword 规则(≥8位含字母+数字),confirmPassword 一致性
- 新密码加密(bcrypt),更新
user表 的 password_hash(更新) - 返回成功
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| oldPassword | string | 是 | 旧密码 |
| newPassword | string | 是 | 新密码,≥8位含字母+数字 |
| confirmPassword | string | 是 | 确认新密码 |
响应数据: null
USER-09 注销账号
| 项目 | 说明 |
|---|---|
| 接口路径 | DELETE /client/api/v1/users/me |
| 接口用途 | 用户申请注销账号(苹果审核要求"删除账号") |
| 权限要求 | 需登录 |
| 涉及表 | user, wallet, creator_profile, user_device |
接口逻辑:
- 从Token中解析 user_id
- 校验 confirmPassword(读
user表 的 password_hash + bcrypt compare) - 查询
wallet表 检查 balance 是否为 0(读)→ 不为0则拒绝 - 查询
user表 检查 role 是否为 2(创作者)→ 是创作者则检查creator_profile是否已停用(读) - 更新
user表 的 status=3(已注销),释放用户名(更新) - 将
user_device表 中该用户所有记录的 is_active=0(更新) - 返回成功
请求参数(Body):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| confirmPassword | string | 是 | 输入密码确认注销操作 |
响应数据: null
USER-10 获取用户主页分享链接
| 项目 | 说明 |
|---|---|
| 接口路径 | GET /client/api/v1/users/:userId/share |
| 接口用途 | 获取用户主页的统一 H5 分享链接,供 Android / iOS 发起系统分享前调用 |
| 权限要求 | 公开 |
| 涉及表 | user, platform_config |
接口逻辑:
- 读取路径参数
userId - 查询
user表 校验用户存在;创作者与普通用户都支持返回成功 - 读取后台配置
promotionLandingBaseUrl - 若未配置 H5 分享基准 URL,则返回配置错误
- 统一拼接分享链接:
{promotionLandingBaseUrl}/user/{userId} - 返回完整 URL;不附加
from=promotion、promo等参数
请求参数: 无
响应数据:
| 字段 | 类型 | 说明 |
|---|---|---|
| url | string | 统一 H5 用户主页分享链接,例如 https://h5.txagent.cc/user/{userId} |
说明:
- 本接口只负责返回分享链接,不改变 H5 当前页面实现。
- H5 端仍可继续直接复制当前浏览器地址;Android / iOS 建议统一先调本接口获取分享 URL。