feat(mine): 我的 Tab 全量实现 (#5~#13)
从 im-client-ios-swift-demo 搬运 Settings 逻辑,对齐 Gitea issue #5–#13 ## 基础设施 - AuthNotifier 新增 currentUid 字段,login() 接受 uid 参数 (#5) - LoginViewModel 登录成功后传入 user.uid - ApiPaths 补充 account/block/store 系列路径 - Tab 重命名"设置"→"我的",icon 改为 person_outline (#5) - AppRouteName 新增5条子路由 (edit-profile/blocklist/language/network-diagnostics/about) - app_router + auth_guard 同步注册新路由 ## Settings Feature - SettingsViewModel 重写为 NotifierProvider(去除 @riverpod 依赖) - build() 自动触发 loadProfile() - logout() 完整流程:API → WS 断开 → DB 关闭 → AuthNotifier - 6 个 navigateTo* 方法 - SettingsPage 完整 UI:资料卡 / 偏好设置 / 工具 / 关于 / 退出登录按钮 (#5 #7) - FetchProfileUseCase: GET /app/api/user/profile (#5) - LogoutUseCase: logout + disconnect + closeDatabase (#7) - UpdateProfileUseCase + UpdateProfileRequest: POST /app/api/user/update-profile (#6) - EditProfilePage + EditProfileViewModel: 昵称/bio 编辑 (#6) - LanguagePage: 语言选择 UI 框架,l10n_sdk 待接入 (#9) - BlocklistPage: 黑名单框架,API 待实现 (#10) - NetworkDiagnosticsPage + ViewModel: 四步诊断(连通/TCP/DNS/HTTPS)(#12) - AboutPage: 版本号 + 服务条款/隐私政策入口 (#13) - settings_providers.dart: 扩展 DI 装配 ## 文档 - Doc/mine_tab_architecture.md: 架构说明、数据流、路由、待完成事项 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
164
Doc/mine_tab_architecture.md
Normal file
164
Doc/mine_tab_architecture.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 我的(Mine)Tab — 架构文档
|
||||
|
||||
> 对应 Gitea issues #5–#13
|
||||
> 参考实现:`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. 待完成事项
|
||||
|
||||
- **#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
|
||||
```
|
||||
Reference in New Issue
Block a user