- ProfileHeroCard:72pt 渐变头像(8色 uid%8 主题)、@J{uid} handle、bio 简介、掩码手机号
- AppBar:compact,右侧 QR 图标 + 编辑铅笔
- 彩色图标行(_IconBox 36pt 圆角)+ 4 卡片组对齐 iOS SettingsView
- 账户:我的钱包 / 账户安全
- 工具:收藏 / 最近呼叫 / 链接设备 / 聊天文件夹
- 偏好设置:通知和声音 / 隐私设置 / 黑名单 / 语言 / 主题
- 关于:用户协议 / 隐私政策 / 版本号
- SettingsState 增加 bio 字段(#41),loadProfile 同步赋值
- Doc/mine_tab_architecture.md 补充 UI 重设计章节(§7)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
215 lines
7.2 KiB
Markdown
215 lines
7.2 KiB
Markdown
# 我的(Mine)Tab — 架构文档
|
||
|
||
> 对应 Gitea issues #5–#13,#39–#41(UI 重设计)
|
||
> 参考实现:`im-client-ios-swift-demo` Features/Settings + Features/Profile
|
||
|
||
---
|
||
|
||
## 1. 功能范围
|
||
|
||
| Issue | 功能 | 状态 |
|
||
|-------|------|------|
|
||
| #5 | Tab 重命名 & 个人资料卡片 | ✅ 已实现 |
|
||
| #6 | 编辑个人资料(昵称/bio/头像) | ✅ 框架已建(CDN 上传待 #6 后续) |
|
||
| #7 | 退出登录 | ✅ 已实现 |
|
||
| #8 | 主题持久化 | ⏳ TODO(解开 ThemeModeNotifier 注释) |
|
||
| #9 | 语言设置 | ✅ UI 框架(l10n_sdk 待接入) |
|
||
| #10 | 黑名单管理 | ✅ 页面框架(API 待实现) |
|
||
| #11 | 聊天文件夹 | ⏳ TODO stub |
|
||
| #12 | 网络诊断 | ✅ 已实现(4步诊断) |
|
||
| #13 | 关于 / 版本 | ✅ 已实现 |
|
||
|
||
---
|
||
|
||
## 2. 目录结构
|
||
|
||
```
|
||
features/settings/
|
||
├── di/
|
||
│ └── settings_providers.dart # UseCase DI 装配
|
||
├── presentation/
|
||
│ ├── settings_view_model.dart # 我的页 ViewModel (NotifierProvider)
|
||
│ ├── edit_profile_view_model.dart # 编辑资料 ViewModel
|
||
│ ├── network_diagnostics_view_model.dart # 网络诊断 ViewModel
|
||
│ └── theme_view_model.dart # 主题 ViewModel (@riverpod)
|
||
├── usecases/
|
||
│ ├── fetch_profile_usecase.dart # GET /app/api/user/profile
|
||
│ ├── update_profile_usecase.dart # POST /app/api/user/update-profile
|
||
│ ├── logout_usecase.dart # POST /app/api/auth/logout + WS + DB
|
||
│ └── set_theme_usecase.dart # 幂等主题切换
|
||
└── view/
|
||
├── settings_page.dart # 我的主页
|
||
├── edit_profile_page.dart # 编辑资料页
|
||
├── language_page.dart # 语言选择页
|
||
├── blocklist_page.dart # 黑名单页(框架)
|
||
├── network_diagnostics_page.dart # 网络诊断页
|
||
├── about_page.dart # 关于页
|
||
├── theme_view.dart # 主题选择页
|
||
└── widgets/
|
||
├── settings_section_header.dart
|
||
└── theme_option_tile.dart
|
||
|
||
data/remote/
|
||
├── get_profile_request.dart # GET /app/api/user/profile(已有)
|
||
└── update_profile_request.dart # POST /app/api/user/update-profile(新增)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 数据流
|
||
|
||
### 3.1 资料加载
|
||
|
||
```
|
||
SettingsPage (build)
|
||
└─ ref.watch(settingsViewModelProvider)
|
||
└─ SettingsViewModel.build()
|
||
└─ Future.microtask(loadProfile)
|
||
└─ FetchProfileUseCase.execute()
|
||
└─ NetworksSdkApi.executeRequest(GetProfileRequest())
|
||
└─ GET /app/api/user/profile (JWT token in header)
|
||
└─ ProfileResponse → SettingsState {nickname, avatarUrl, maskedContact, uid}
|
||
```
|
||
|
||
### 3.2 退出登录
|
||
|
||
```
|
||
SettingsPage._confirmLogout()
|
||
└─ AlertDialog confirm
|
||
└─ SettingsViewModel.logout()
|
||
├─ LogoutUseCase.execute()
|
||
│ ├─ AuthRepository.logout() → POST /app/api/auth/logout
|
||
│ ├─ SocketManager.disconnect() → 断开 WebSocket
|
||
│ └─ StorageSdkLifecycle.closeDatabase()
|
||
└─ AuthNotifier.logout() → go_router 重定向 /login
|
||
```
|
||
|
||
### 3.3 编辑资料保存
|
||
|
||
```
|
||
EditProfilePage → 保存按钮
|
||
└─ EditProfileViewModel.save()
|
||
└─ UpdateProfileUseCase.execute(nickname, bio, profilePicUrl)
|
||
└─ NetworksSdkApi.executeRequest(UpdateProfileRequest)
|
||
└─ POST /app/api/user/update-profile
|
||
└─ SettingsViewModel.loadProfile() (刷新资料卡)
|
||
```
|
||
|
||
---
|
||
|
||
## 4. API 端点
|
||
|
||
| 操作 | Method | Path |
|
||
|------|--------|------|
|
||
| 获取当前用户资料 | GET | `/app/api/user/profile` |
|
||
| 更新用户资料 | POST | `/app/api/user/update-profile` |
|
||
| 退出登录 | POST | `/app/api/auth/logout` |
|
||
| 黑名单列表(待实现) | GET | `/app/api/account/block/list` |
|
||
| 解除拉黑(待实现) | POST | `/app/api/account/block/remove` |
|
||
| 聊天文件夹(待实现) | POST | `/app/api/account/store/get-store` |
|
||
|
||
---
|
||
|
||
## 5. Provider 设计
|
||
|
||
所有 Settings ViewModel 使用 `Notifier<T>` + 手动 `NotifierProvider`,**不使用 `@riverpod` 代码生成**,避免额外 build_runner 依赖:
|
||
|
||
```dart
|
||
class SettingsViewModel extends Notifier<SettingsState> { ... }
|
||
|
||
final settingsViewModelProvider = NotifierProvider<SettingsViewModel, SettingsState>(
|
||
SettingsViewModel.new,
|
||
);
|
||
```
|
||
|
||
DI 链路:
|
||
|
||
```
|
||
settingsViewModelProvider
|
||
└─ fetchProfileUseCaseProvider → networkSdkApiProvider
|
||
└─ logoutUseCaseProvider
|
||
├─ authRepositoryProvider → networkSdkApiProvider
|
||
├─ socketManagerProvider
|
||
└─ storageSdkProvider
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 路由
|
||
|
||
新增 Shell 外全屏路由(`parentNavigatorKey: _rootKey`),TabBar 在子页面隐藏:
|
||
|
||
```
|
||
/settings/edit-profile EditProfilePage
|
||
/settings/blocklist BlocklistPage
|
||
/settings/language LanguagePage
|
||
/settings/network-diagnostics NetworkDiagnosticsPage
|
||
/settings/about AboutPage
|
||
/settings/theme ThemeView(原有)
|
||
```
|
||
|
||
认证守卫 `auth_guard.dart` switch 已补全上述路由。
|
||
|
||
---
|
||
|
||
## 7. UI 重设计(#39 / #40 / #41)
|
||
|
||
### 7.1 ProfileHeroCard (#39 / #41)
|
||
|
||
| 元素 | 规格 |
|
||
|------|------|
|
||
| 头像 | 72pt 圆形;无头像时 8 色渐变占位(uid%8) |
|
||
| 昵称 | fontWeight w700,titleMedium |
|
||
| Handle | `@J{uid}`,bodySmall onSurfaceVariant |
|
||
| 手机号 | 掩码 `+CC ***XXXX`,bodySmall |
|
||
| Bio | 非空显示,为空显示「添加一句话简介」(斜体,半透明) |
|
||
| AppBar | compact,右侧:QR 图标 + 编辑铅笔 |
|
||
|
||
渐变色方案(`_ProfileHeroCard._gradients[uid.abs() % 8]`):
|
||
```
|
||
0: [#4776E6, #8E54E9] 1: [#11998E, #38EF7D]
|
||
2: [#FC466B, #3F5EFB] 3: [#F7971E, #FFD200]
|
||
4: [#56CCF2, #2F80ED] 5: [#EB3349, #F45C43]
|
||
6: [#1FA2FF, #12D8FA] 7: [#9D50BB, #6E48AA]
|
||
```
|
||
|
||
### 7.2 彩色图标行与分组卡片 (#40)
|
||
|
||
`_IconBox`:36pt 圆角正方形(8pt)白色图标,iOS Settings 风格。
|
||
|
||
| 卡片组 | 菜单项 | 颜色 |
|
||
|--------|--------|------|
|
||
| 账户 | 我的钱包 | #FFAA5B |
|
||
| | 账户安全 | #8A5CF6 |
|
||
| 工具 | 收藏 | #FFAF45 |
|
||
| | 最近呼叫 | #4CB050 |
|
||
| | 链接设备 | #5667FF |
|
||
| | 聊天文件夹 | #F2994A |
|
||
| 偏好设置 | 通知和声音 | #FF8B5E |
|
||
| | 隐私设置 | #0BB8A9 |
|
||
| | 黑名单 | #FF4B4B |
|
||
| | 语言 | #5667FF |
|
||
| | 主题 | #8A5CF6 |
|
||
| 关于 | 用户协议 | gray |
|
||
| | 隐私政策 | gray |
|
||
| | 版本号(静态)| gray,无 chevron |
|
||
|
||
### 7.3 SettingsState bio 字段 (#41)
|
||
|
||
- `SettingsState.bio: String`(默认 `''`)
|
||
- `SettingsViewModel.loadProfile()` 赋值 `bio: profile.bio`
|
||
- 数据来源:`ProfileResponse.bio` → `GET /app/api/user/profile`
|
||
|
||
---
|
||
|
||
## 8. 待完成事项
|
||
|
||
- **#6 头像上传**:接入 CDN upload(参考 iOS CDN 流程)
|
||
- **#8 主题持久化**:解开 `ThemeModeNotifier.build()` 和 `setMode()` 中的 TODO
|
||
- **#10 黑名单 API**:实现 `FetchBlocklistUseCase` + `UnblockUseCase`
|
||
- **#11 聊天文件夹**:`ChatCategoryViewModel` + `account/store` API
|
||
- **build_runner**:`UpdateProfileRequest` 使用 `@ApiRequest`,需执行:
|
||
```bash
|
||
cd apps/im_app && dart run build_runner build --delete-conflicting-outputs
|
||
```
|