import type { AppRole } from './user'; /** * 微信登录相关类型 * * 覆盖三种账号场景(对应后端用 code 换 openid 后的判定结果): * 1. new —— openid 不存在,第一次登录,需绑定手机号完成注册 * 2. active —— openid 存在且账号活跃,第二次及以后登录,直接进入主界面 * 3. deleted —— 账号处于注销审核期(申请注销后、彻底删除前),**不可登录** * * 关键约束一:微信授权返回的 code 是一次性的(有效期 5 分钟)。 * 用户在绑定手机号时原 code 已被首次请求消耗,后端不能再用它换 openid, * 因此后端必须在首次响应里下发可复用的临时凭证,由前端回传。 * * 关键约束二:注销审核期内账号不可登录、不可复活, * 审核期结束后数据被彻底删除。前端不提供任何复活入口。 */ /** * 微信账号在后端的状态。 * 用联合类型而非布尔 isNewUser 建模,避免「注销中」被误判为「新老用户」之外的隐式状态。 */ export type WechatAccountStatus = 'new' | 'active' | 'deleted'; /** * 等待绑定手机号时持有的临时凭证。 * 后端首次校验 code 后下发,用于绑定手机号时标识身份(此时 code 已失效)。 */ export interface WechatPendingTicket { /** 临时令牌,绑定手机号后换取正式 token */ token: string; /** 微信开放平台唯一标识 */ openid: string; } /** 微信登录后已注册用户的基本资料 */ export interface WechatUserProfile { /** 用户 id */ id: string; /** 昵称 */ nickname: string; /** 头像地址 */ avatarUri: string; /** 性别;unspecified 表示用户未授权或未填写 */ gender: 'male' | 'female' | 'unspecified'; } /** * 微信登录结果(后端 POST /api/auth/wechat 的响应)。 * * 各字段按状态可选,页面通过 status 判别后再读取对应字段: * - new:token 为临时凭证,profile 为 undefined * - active:token 为正式登录令牌,profile 有值 * - deleted:token 为临时凭证但不可用,仅用于标识账号,不得写入登录态 */ export interface WechatLoginResult { /** 账号状态 */ status: WechatAccountStatus; /** 登录令牌(active 为正式 token;new 为临时凭证;deleted 无意义) */ token: string; /** * 刷新令牌,仅 status === 'active' 时返回。 * 微信登录当前无后端契约(整体 mock),真实接入时以厂商/后端返回为准; * 这里先补齐字段,让微信登录与其他登录走**同一个会话写入入口**, * 否则微信登录的用户请求全部带不出 Bearer。 */ refreshToken?: string; /** 微信开放平台唯一标识 */ openid: string; /** 已注册用户资料,仅 status === 'active' 时返回 */ profile?: WechatUserProfile; /** 正式令牌的过期时间戳(毫秒),仅 status === 'active' 时返回 */ expiresAt?: number; /** * 已注册用户的端身份,仅 status === 'active' 时返回。 * 老用户凭此直接落地对应端;为 undefined 表示后端未记录,前端需引导选择身份。 */ role?: AppRole; } /** 微信新用户绑定手机号完成注册(第一次登录的必经步骤) */ export interface WechatBindPhonePayload { /** 临时凭证令牌(code 已失效,只能用它标识身份) */ token: string; /** 微信开放平台唯一标识 */ openid: string; /** 手机号(11 位) */ phone: string; /** 短信验证码 */ code: string; } /** 绑定注册成功后返回的正式会话 */ export interface WechatSession { /** 正式访问令牌 */ token: string; /** 刷新令牌(无契约,mock 阶段自造;真实接入时以后端返回为准) */ refreshToken: string; /** 令牌过期时间戳(毫秒) */ expiresAt: number; /** 用户资料 */ profile: WechatUserProfile; /** * 端身份。为 undefined 表示新用户尚未选择身份,前端需引导去注册流程选择。 */ role?: AppRole; }