← API | 列表 | project_structure_report
提示信息
# 同伴 App — 页面骨架迁移参考

> 本文档为 Swift 重写提供每个页面的结构骨架、弹窗内容、接口交互和缓存策略。
> 信号 / 聊天模块见独立文档 `swift_信号模块实现.md` / `swift_聊天模块实现.md`。

---

## 1. 认证与启动

### 1.1 启动页 SplashPage

**顺序状态机:**
```
checkPrivacy → loadConfig → checkUpdate → verifyAuth → 跳转
```

| 步骤 | 行为 | 失败处理 |
|---|---|---|
| checkPrivacy | 读 MMKV `PrivacyService.hasAgreed`;未同意 → 跳隐私页并中止 | — |
| loadConfig | `POST /app/start` {platform, version_code, channel} → 缓存到 MMKV | 仅日志,不阻塞 |
| checkUpdate | 读缓存的 AppStartConfig;有更新 → 弹更新弹窗 | 强制更新时挂起不跳转 |
| verifyAuth | 读 MMKV imToken + userId → IM SDK login;失败则静默刷新 token 重试 | 静默降级 |

**硬超时:** 10 秒,无论哪步未完成直接跳转。

**跳转逻辑:**
- MMKV 有 accessToken → `AppRoutes.main`
- 否则 → `AppRoutes.login`

---

### 1.2 隐私页 PrivacyPage

**结构:** 单卡片页面,无滚动列表。

**卡片内容(从上到下):**
1. 盾牌图标 + 标题"欢迎使用同伴" + 副标题
2. 两个协议链接行:《用户服务协议》《隐私政策》(点击跳 WebView)
3. 两段说明文字
4. 两个按钮:「不同意」「同意并继续」

**弹窗 — 拒绝确认:**
- 标题:"提示"
- 内容:"不同意《隐私政策》将无法使用本应用,确认退出吗?"
- 确认按钮:"确认退出"(destructive)→ 退出 App
- 取消按钮:"取消"

**同意后:** MMKV 写入 agreed → 初始化 SDK → 跳转 SplashPage 重走流程

---

### 1.3 登录页 LoginPage

**两种模式(Tab 切换):** 验证码登录 / 密码登录

**输入区域:**

| 字段 | 类型 | 限制 | 图标 |
|---|---|---|---|
| 手机号 | phone | 11 位数字 | user |
| 验证码(仅验证码模式) | number | 6 位 | shield |
| 密码(仅密码模式) | password | 非空 | lock |

**获取验证码按钮:**
- 验证手机号 11 位后才可点击
- `POST /auth/sms/send` {phone, scene: "login"}
- 响应:{expire_seconds, retry_after_seconds}
- 点击后立即开始 60 秒倒计时

**登录请求:**
```
POST /auth/login/phone
{
  phone, code 或 password,
  device_info: { deviceId, platform, model, osVersion, appVersion, pushToken }
}
```

**响应关键字段:**
```json
{
  "is_new_user": bool,
  "access_token": "", "refresh_token": "",
  "im_token": "",
  "user": { uid, nickname, avatar, gender, is_verified, bio, birth_date, mbti, residence, orientation, attribute, is_personalized, is_profile_hidden }
}
```

**登录成功后序列:**
1. MMKV 写入:accessToken / refreshToken / userId / imToken / userPhone / userProfile(JSON)
2. IM SDK login(uid, imToken)
3. 初始化缓存服务:AppCacheService / ChatCacheManager / AvatarCacheManager / SignalCacheManager
4. 跳转:is_new_user=true → `completeProfile`;否则 → `main`

---

### 1.4 完善资料页 CompleteProfilePage

**三步 PageView(不可手动滑动):**

**步骤 0 — 头像 + 昵称:**
- 头像选择器(120px,点击调起裁剪)
- 昵称输入框(2–12 字符,maxLength: 12)
- 验证:两者均必填

**步骤 1 — 性别 + 生日 + 常住地:**
- 性别:两张卡片(男/女),单选
- 生日:点击弹出 DatePicker
- 常住地:点击弹出地区选择 Sheet
- 验证:三项均必填

**步骤 2 — 偏好(可选):**
- 性取向标签(GridView 2 列)
- 属性标签(条件显示,仅特定取向时出现,GridView 4 列)
- 右上角「跳过」按钮可直接进主页

**每个字段变更时立即调用:**
```
POST /user/profile/update-field (FormData)
{ type: "avatar"|"nickname"|"gender"|"birth_date"|"residence"|"orientation"|"attribute", value: string }
```

**residence 值格式:** `{"country_name":"","province_name":"北京","city_name":"朝阳区","city_code":"110105"}`

**断点续填:** 页面加载时拉取当前 profile,自动跳到未完成的步骤。

---

### 1.5 实名认证页 VerificationPage

**四种状态视图(状态机驱动):**

| 状态 | 展示 | 操作 |
|---|---|---|
| INTRO | 盾牌图标 + 标题"实名认证" + 说明 | 「立即认证」按钮 → INPUT |
| INPUT | 姓名输入 + 身份证输入(自定义数字键盘) + 协议勾选 | 「提交」按钮 |
| PENDING | 时钟图标 + "人工审核中(1-3 工作日)" | 「撤销申请」按钮 |
| FAILED | 警告图标 + 失败原因 | 「重新认证」+ "转人工认证"链接 |
| SUCCESS | 绿色盾牌 + 脱敏身份信息卡片 | 无操作 |

**INPUT 表单:**
- 姓名:文本输入
- 身份证号:maxLength 18,自定义键盘(数字 + X)
- 勾选框 + "我已阅读并同意《实名认证协议》"
- 提交条件:已勾选 + 姓名非空 + 身份证 ≥ 15 位

**接口:**

| 接口 | 用途 |
|---|---|
| `GET /verification/status` | 页面加载时获取当前状态 |
| `POST /verification/three-elements` {real_name, id_card} | 三要素核验 |
| `POST /verification/manual` {real_name, id_card, photo_url: [3张]} | 人工审核提交 |
| `POST /verification/cancel` | 撤销人工审核 |

**人工认证 Sheet(failCount ≥ 3 或主动点击时弹出):**
- 说明:"人工审核预计 1-3 个工作日,请确保照片清晰。"
- 三个照片槽位:
  1. "身份证正面"(拍照)
  2. "身份证背面"(拍照)
  3. "手持身份证照片"(相册选取)
- 三张全部选择后才可提交
- 提交前先上传三张图片,获取 objectKey 后再调 `/verification/manual`

---

## 2. 主页与导航

### 2.1 主壳页 MainShellPage

- `IndexedStack` 保持三个 Tab 常驻内存
- 底部悬浮导航栏 `AppBottomNavBar`(3 个 Tab:首页、消息、我的)
- 消息 Tab 显示未读角标

### 2.2 首页 Tab HomeTab

**核心组件:** 居中的探索按钮(128×128 圆形)+ 两圈涟漪动画

**按钮交互:**
- 按下缩放 0.9
- 文字"探索"(18px,letter-spacing 7.2)
- 点击 → push `AppRoutes.signalInbox`

**涟漪动画参数:**
- 缩放:0.8 → 1.8,4 秒循环
- 透明度:0.6 → 0.0
- 第二圈延迟 2 秒启动

### 2.3 消息 Tab MessagesTab

**结构(从上到下):**
1. 导航栏(标题"消息",右侧清空按钮)
2. 连接状态横幅(仅断连时显示)
3. 会话列表(AppMessageTile)

**连接横幅状态:**

| IM 状态 | 显示 | 操作 |
|---|---|---|
| connecting | "正在连接消息服务器..." | 无 |
| failed / disconnected | "消息连接已断开" | 「点击重试」按钮 |
| connected | 隐藏 | — |

**列表项(AppMessageTile):**
- 头像 + 昵称 + 时间 + 未读数角标
- 副标题:优先显示草稿(红色前缀"[草稿]"),否则显示最后一条消息

**滑动操作:**
- 左滑:置顶/取消置顶、删除
- 删除确认弹窗:"删除会话?" / "将同时删除与该用户的全部聊天记录,无法恢复。"

**清空全部弹窗:**
- 标题:"清空列表?"
- 确认后调用 `clearAllConversations()`

**空状态:** `AppEmptyState(type: .noMessage, subtitle: "去发射信号,寻找志同道合的伙伴吧!")`

### 2.4 我的 Tab ProfileTab

**结构:**
1. 导航栏(左:主题切换按钮 Sun/Moon;右:编辑资料、设置入口)
2. 头像(xl 尺寸,发光边框)
3. 昵称(h3 衬线体)
4. 菜单项:发信号、组件展示(开发用)、系统日志(开发用)

**主题切换:** Light ↔ Dark,写入 MMKV `StorageKeys.themeMode`

**首次渲染:** useEffect 中调用 `profileController.fetchProfile()`

---

## 3. 社交与交互

### 3.1 用户资料页 UserProfilePage

**入参:** uid (int)

**异常状态处理:**

| 错误码 | 展示 | 操作 |
|---|---|---|
| 1008(封禁) | 盾牌 + "该账号已被封禁" | 刷新按钮 |
| 4004(被拉黑) | 锁 + "无法查看" | 刷新按钮 |
| 1004(不存在) | 问号 + "查无此人" | 无 |
| 网络错误 | AppEmptyState networkError | 刷新按钮 |

**正常页面结构(ScrollView):**
1. 头像(xl,发光边框)
2. 昵称(衬线体 32px,末尾加句号装饰)
3. 标签行(Wrap 布局):
   - 年龄 + 性别(合并标签,男蓝 #6B8AFF / 女粉 #FF7DB5)
   - 已认证徽章(如有)
   - 属性(emoji + 文字)
   - MBTI(图标 + 文字)
   - 常住地(pin 图标)
   - IP 属地
4. "关于我"引言区(如有 bio)

**右上角菜单(ActionSheet,仅非本人时显示):**
- 「拉黑」/ 「取消拉黑」
- 「举报」(destructive)

**拉黑确认弹窗:**
- 标题:"确定拉黑该用户吗?"
- 内容:"拉黑后,你将不再收到对方的消息,且对方无法在发现页看到你的信号。"
- API:`POST /user/block` {uid, block: true}

**举报跳转:** push `AppRoutes.report` 携带 `ReportArgs(relationType: 1, relationId: uid, relationUid: uid)`

**接口:** `GET /user/profile/detail?uid={uid}`

---

### 3.2 编辑资料页 EditProfilePage

**表单字段:**

| 字段 | 编辑方式 | 限制 | API type |
|---|---|---|---|
| 头像 | 选择 + 裁剪 + 上传(显示进度条) | — | `avatar` |
| 昵称 | 文本编辑页 (AppEditorPage) | 2–12 字符 | `nickname` |
| 性别 | ActionSheet(男/女) | — | `gender` (1/2) |
| 生日 | DatePicker | — | `birth_date` |
| 偏好 | 偏好选择 Sheet(性取向 + 属性) | — | JSON `{"orientation":1,"attribute":2}` |
| 常住地 | 地区选择 Sheet | — | `residence` (JSON) |
| 关于我 | 文本编辑页 | ≤200 字 | `bio` |
| MBTI | ActionSheet | — | `mbti` |

**更新策略:** 乐观更新本地状态 → API 调用 → 失败则回滚 + Toast

**接口:** `POST /user/profile/update-field` (FormData) {type, value}

**头像上传:** `uploadApiProvider.uploadFile(filePath, 'avatar')` → 返回 {url, objectKey}

---

### 3.3 举报页 ReportPage

**入参:** ReportArgs {relationType: int, relationId: string, relationUid: int}

**relationType 值:** 1=用户资料 2=信号 3=私聊

**步骤 1 — 选择原因:**
- 原因列表(单选 Radio)
- 匿名举报徽章:"匿名举报,别担心"
- 底部按钮:「下一步」(未选原因时禁用)

**原因列表数据来源:**
```
GET /user/report/config?type={relationType}
响应:{ reason_list: [{id, name}], tips, title }
```
- 缓存策略:按 relationType 分别缓存到 MMKV,当日有效;次日重新拉取,后台静默刷新

**步骤 2 — 补充说明:**
- 文本输入框(≤300 字,3-5 行,placeholder: "请详细描述违规情况")
- 图片上传(最多 6 张,88×88 缩略图)
  - 每张显示上传状态:上传中(spinner)/ 上传失败(红色覆盖 + 警告图标)
  - 右上角删除按钮

**提交流程:**
1. 依次上传未上传的图片(压缩 → upload → 获取 objectKey),任一失败则中止
2. `POST /user/report/submit` {relation_type, relation_id, relation_uid, reason_code, message, imgs: [objectKey...]}
3. 成功 → Toast "举报已提交,感谢你的反馈" + pop

---

## 4. 商店

### 4.1 商店页 ShopPage

**结构:** 按分类分组的双列网格

**接口:**
```
GET /shop/list
响应:[{ category_name, list: [{ id, title, thumb, price, type_tag, description, number }] }]
```

**加载状态:** 骨架屏 → 数据 / 空状态 / 错误重试

### 4.2 商品详情页 ProductDetailPage

**结构:**
1. 折叠图片头(SliverAppBar,300px)
2. 价格(24px)+ 标题(18px)+ 数量说明
3. "商品详情"文本区
4. 底部固定「立即购买」按钮

**购买流程:**

1. 点击「立即购买」→ 弹出支付方式 Sheet
2. Sheet 内容:商品名 + 价格 + 两个按钮(微信支付 绿色 #09B83E / 支付宝 蓝色 #1677FF)
3. 选择后创建订单:
   ```
   POST /pay/order/create
   { product_id, pay_type: "wechat"|"alipay", relation_type: 9, source: "shop" }
   响应:{ order_no, pay_params }
   ```
4. 调起支付 SDK:
   - 支付宝:pay_params 为预签名字符串,直接传入
   - 微信:pay_params 为对象 {appId, partnerId, prepayId, packageValue, nonceStr, timeStamp, sign}
5. 支付结果 → 成功 Toast + pop / 失败 Toast

---

## 5. 设置模块

### 5.1 设置主页 SettingsPage

**菜单分组:**

| 分组 | 项目 | 跳转 |
|---|---|---|
| 账号安全 | 账号与安全 | accountSecurity |
| | 实名认证 | verification |
| 通用设置 | 界面与显示 | displaySettings |
| | 青少年模式(值:"未开启") | youthMode |
| | 存储与清理 | storageCleaning |
| 隐私与权限 | 隐私设置 | privacySettings |
| 活动中心 | 同伴商城 | shop |
| 关于 | 帮助与反馈 | Toast "反馈功能即将上线" |
| | 关于同伴 | about |
| | 检查更新 | UpdateService.checkFromSettings() |
| 账户操作 | 退出登录(destructive) | 弹窗确认 → 清除 accessToken → login |

**退出登录弹窗:**
- 标题:"退出登录"
- 内容:"确定要退出当前账号吗?"
- 确认按钮:"退出"
- 确认后:清除 MMKV accessToken → `context.go(AppRoutes.login)`

---

### 5.2 账号与安全 AccountSecurityPage

**菜单项:**
1. **手机号** — 显示脱敏号码(`138****5678`),未绑定显示"未绑定"
2. **登录密码** — 显示"去修改"
3. **注销账号** — destructive,跳 cancelAccount

---

#### Sheet:绑定新手机

**输入字段:**

| 字段 | placeholder | 类型 | 限制 | 图标 |
|---|---|---|---|---|
| 验证原手机 | "请输入当前登录的手机号" | phone | 11 位 | user |
| 新手机号 | "请输入新手机号" | phone | 11 位 | user |
| 验证码 | "6 位验证码" | number | 6 位 | shield |

**验证码按钮:** 对新手机号发送,scene = `bind_phone`,60 秒倒计时

**提交验证:**
1. 原手机号必须与当前登录手机一致
2. 新手机号 ≠ 原手机号
3. 全部填写完整

**接口:** `POST /user/security/update-phone` {phone: 新手机号, code}

**成功后:**
- MMKV 更新 `userPhone`
- Riverpod 更新 `userPhoneProvider`
- Toast "手机号修改成功"
- 关闭 Sheet

---

#### Sheet:修改密码

**输入字段:**

| 字段 | placeholder | 类型 | 限制 | 图标 |
|---|---|---|---|---|
| 验证原手机 | "请输入当前登录的手机号" | phone | 11 位 | user |
| 验证码 | "6 位验证码" | number | 6 位 | shield |
| 新密码 | "请输入新密码(至少 6 位)" | password | ≥6 位 | lock |

**密码输入尾部:** 眼睛图标切换明文/密文

**验证码按钮:** 对当前手机号发送,scene = `reset_password`

**提交验证:** 原手机号必须正确 + 验证码非空 + 密码 ≥ 6 位

**接口:** `POST /user/security/update-password` {phone, code, password}

**成功后:** Toast "密码修改成功" + 关闭 Sheet

---

### 5.3 界面与显示 DisplaySettingsPage

**三个设置区域(每个区域三张选择卡片横排):**

**头像形状:**
- 圆形 circle / 圆角 rounded / 直角 square
- 存储:`StorageKeys.avatarShape`(enum index)

**界面圆角:**
- 圆角 rounded (8dp) / 方直 square (4dp) / 胶囊 pill (全圆)
- 存储:`StorageKeys.appShapeMode`(enum index)

**深色模式:**
- 跟随系统 system / 浅色 light / 深色 dark
- 图标:contrast / sun / moon
- 存储:`StorageKeys.themeMode`(enum index)

---

### 5.4 青少年模式 YouthModePage

**状态:** 由 MMKV 中 `userStatus.young_pass` 决定(有值=开启)

**未开启时:** 显示功能说明矩阵(时间管理 / 内容过滤 / 消费限制),底部「开启青少年模式」按钮

**已开启时:** 绿色盾牌图标,底部「关闭青少年模式」按钮(destructive)

---

#### PIN 设置流程(开启时)

**步骤 1:** 标题"请设置 4 位数独立密码",自定义数字键盘(1-9, 0, 删除),4 个圆点指示

**步骤 2:** 标题"确认青少年模式密码",同样键盘
- 两次不一致 → Toast "两次输入密码不一致"
- 一致 → 调接口保存

#### PIN 验证流程(关闭时)

- 标题"关闭青少年模式",输入 4 位密码
- 不正确 → Toast "密码错误"
- 正确 → 调接口清除

**接口:** `POST /user/profile/update-field` {type: "young_pass", value: "1234" 或 ""}

**存储更新:** 同时更新 MMKV 中 appStartConfig 的 `userStatus.young_pass` 和 `userStatus.young_mode`

---

### 5.5 存储与清理 CacheManagementPage

**顶部仪表盘:**
- 已用空间(大号粗体数字)+ 可用磁盘 + 总容量

**清理阈值滑块:** 1G / 5G / 10G / 20G / 不限制
- 存储:`StorageKeys.maxCacheSize`(字节数字符串)
- 变更后触发 `AppCacheService.runEviction()`

**详细分类(三个可点击项):**

| 分类 | 图标 | 清理范围 |
|---|---|---|
| 头像缓存 | profile | AvatarCacheManager |
| 信号资源 | broadcast | SignalCacheManager |
| 聊天文件 | file | ChatCacheManager + FlashCacheManager |

**一键清理按钮(destructive):** 清除所有分类

**五个 Tab 页:** 聊天(按会话列表)/ 媒体(网格缩略图)/ 文件(列表)/ 头像(网格)/ 信号(列表)

**所有清理操作均需确认弹窗,示例:**
- 清理全部:标题"确定要清理全部缓存吗?" 内容"将删除头像、信号、聊天等所有本地缓存文件,不影响您的聊天文字记录。"
- 清理聊天:标题"清理聊天文件?" 内容"将删除所有聊天图片、语音及闪照文件。清除后下次查看需重新下载。"
- 清理分类/会话:标题动态生成,内容"清除后下次访问相应内容时将自动重新下载。"

---

### 5.6 隐私设置 PrivacySettingsPage

**两个开关 + 一个导航项:**

| 项目 | 类型 | API type | 默认值 |
|---|---|---|---|
| 隐身模式 | Toggle | `is_profile_hidden` | false |
| 个性化推荐 | Toggle | `is_personalized` | true |
| 黑名单管理 | 导航 → blacklist | — | — |

**隐身模式开启确认弹窗:**
- 标题:"开启隐身模式"
- 内容:
  ```
  开启后:
  • 已发布的动态将不会被他人收取
  • 在线状态和活跃时间不会对外显示
  • 你的主页对陌生人不可见

  确定要开启隐身模式吗?
  ```
- 关闭时无需确认

**接口:** `POST /user/profile/update-field` {type, value: "true"/"false"}

---

### 5.7 黑名单 BlacklistPage

**列表项:** 头像 + 昵称 + 拉黑时间(YYYY-MM-DD)+ "移除"胶囊按钮

**移除确认弹窗:**
- 标题:"取消拉黑"
- 内容:"确定要将 {昵称} 从黑名单中移除吗?"
- 确认后 `POST /user/block` {uid, block: false} → 乐观移除列表项 + Toast "已移除"

**接口:** `GET /user/block/list` → `[{uid, nickname, avatar, blockTime}]`

**空状态:** "暂无黑名单用户"

---

### 5.8 关于页 AboutPage

- Logo(80×80)+ 标题"同伴 App" + 版本号
- 三个链接项:用户协议 / 隐私政策 / 公司信息(目前均为 Toast 占位)
- 底部版权:"© 2026 tongban.wang"

无接口调用,无缓存。

---

### 5.9 账号注销 CancelAccountPage

**步骤 1 — 注销须知:**
- 注销协议全文(glassSurface 容器)
- 核心内容:无纠纷、正常状态、数据不可恢复、金币/会员/钻石作废
- 底部两个按钮:
  - 「请阅读须知(5s)」→ 5 秒倒计时后变为「下一步」
  - 「暂不注销」→ pop

**步骤 2 — 填写原因:**
- 说明文字:"请告诉我们您要注销的原因,以维持更好的服务"
- 文本输入框(≤100 字,5 行,placeholder: "请告诉我们您的问题...")
- 「确认注销账号」按钮(destructive)

**提交前二次确认弹窗:**
- 标题:"确认注销账号?"
- 内容:"注销后账号将永久消失且无法找回,所有数据将被清空。"
- 确认按钮:"确认注销"(destructive)

**接口:** `POST /user/account/cancel` {reason}

**成功后清除 MMKV:**
- accessToken / refreshToken / userId / imToken / userProfile / userPhone
- `AppStorage.sync()`
- 跳转 `AppRoutes.login`
- Toast "账号已注销"

---

## 6. 错误页面

### 6.1 账号封禁 BannedPage(错误码 1010)

**入参:** ban_info {forbidden_type, end_at, is_permanent}

**内容:**
- 红色头部 + 红色圆形图标
- 标题:"账号已被封禁"
- 说明:"您的账户因违反《用户使用规范》已被系统封禁。"
- 封禁详情卡片:违规类型 + 解封时间(临时显示日期,永久显示"永久封禁"红色文字)
- 「申诉处理」按钮
- "更换账号"文字按钮 → 清除所有 token → login

### 6.2 设备封禁 DeviceBannedPage(错误码 1012)

- 盾牌图标 + "设备不可用"
- 说明文字 + 设备 ID 卡片(从 MMKV `StorageKeys.deviceId` 读取)

### 6.3 欺诈封禁 FraudBannedPage(错误码 1011)

- 公文风格,标题"严重违规处罚通知"+ 编号
- 卡片内容:违规主体、违规行为标签、处罚结果"永久封禁账号"(红色 20px 粗体)
- 水印 + 底部条例链接

### 6.4 维护页 MaintenancePage(错误码 1038)

- 同心圆旋转动画 + 维护图标
- "系统维护中" + 说明文字
- 进度卡片(不确定进度条)

### 6.5 服务器错误 ServerErrorPage(错误码 1039)

- 云图标浮动动画(渐变粉红背景,3 秒上下浮动循环)
- "服务器故障" + 说明
- 「重新加载」按钮 → 跳转 SplashPage

---

## 7. 乐观更新汇总

| 页面 | 操作 | 乐观行为 | 回滚 |
|---|---|---|---|
| 聊天 | 发送消息 | "发送中"状态立即上屏 | 变"发送失败" |
| 聊天 | 撤回(5 分钟内) | 本地标记已撤回 | 恢复原消息 |
| 信号收件箱 | 标记已读 | 立即清除红点 | 重新显示 |
| 信号收件箱 | 删除 | 立即移除条目 | 重新插入 |
| 信号详情 | 回复 | replySent=true + 显示回复 | 清空 + Toast |
| 编辑资料 | 更新字段 | 直接更新显示值 | 回滚 + Toast |
| 黑名单 | 解除拉黑 | 立即从列表移除 | 重新插入 |
| 会话列表 | 置顶/删除 | 立即更新列表 | 重新插入 |

---

## 8. MMKV 缓存键速查

| Key | 内容 | 写入时机 |
|---|---|---|
| `accessToken` | JWT 令牌 | 登录成功 |
| `refreshToken` | 刷新令牌 | 登录成功 |
| `userId` | 用户 UID | 登录成功 |
| `imToken` | IM 服务令牌 | 登录成功 |
| `userPhone` | 手机号 | 登录 / 修改手机号 |
| `userProfile` | LoginUser JSON | 登录 / 资料更新 |
| `deviceId` | 设备标识 | 首次启动 |
| `appStartConfig` | 启动配置 JSON(含 youth_pass) | 启动页 loadConfig |
| `themeMode` | 主题模式 index | 切换主题 |
| `avatarShape` | 头像形状 index | 切换形状 |
| `appShapeMode` | 圆角模式 index | 切换圆角 |
| `maxCacheSize` | 缓存上限字节数 | 调整滑块 |
| `reportConfig(type)` | 举报配置 JSON | 举报页加载 |
| `reportConfigDate(type)` | 举报配置日期 YYYY-MM-DD | 举报页加载 |
| `signalInboxCache` | 信号收件箱缓存 | 信号页刷新 |
| `signalFilter` | 信号筛选条件 | 筛选变更 |
| `convListCache` | 会话列表缓存(前 50 条) | 会话刷新 |

---

## 9. 核心接口索引

| 模块 | 接口 | 方法 | 用途 |
|---|---|---|---|
| 启动 | `/app/start` | POST | 获取启动配置 |
| 认证 | `/auth/sms/send` | POST | 发送验证码 |
| 认证 | `/auth/login/phone` | POST | 手机登录 |
| 资料 | `/user/profile/update-field` | POST | 更新单个字段 |
| 资料 | `/user/profile/detail` | GET | 获取他人资料 |
| 安全 | `/user/security/update-phone` | POST | 修改手机号 |
| 安全 | `/user/security/update-password` | POST | 修改密码 |
| 安全 | `/user/account/cancel` | POST | 注销账号 |
| 社交 | `/user/block` | POST | 拉黑/取消拉黑 |
| 社交 | `/user/block/list` | GET | 黑名单列表 |
| 社交 | `/user/report/config` | GET | 举报配置 |
| 社交 | `/user/report/submit` | POST | 提交举报 |
| 认证 | `/verification/status` | GET | 实名状态 |
| 认证 | `/verification/three-elements` | POST | 三要素核验 |
| 认证 | `/verification/manual` | POST | 人工审核 |
| 认证 | `/verification/cancel` | POST | 撤销审核 |
| 商店 | `/shop/list` | GET | 商品列表 |
| 支付 | `/pay/order/create` | POST | 创建订单 |