diff --git a/Doc/IM_App_架构设计.html b/Doc/IM_App_架构设计.html
index 3b7bfa0..a4fc829 100644
--- a/Doc/IM_App_架构设计.html
+++ b/Doc/IM_App_架构设计.html
@@ -330,6 +330,20 @@
font-size: 28px;
}
}
+
+ /* 章节最后更新时间标签 */
+ .updated-tag {
+ font-size: 11px;
+ font-weight: 400;
+ color: #999;
+ background: #f3f4f6;
+ border: 1px solid #e0e3e8;
+ padding: 1px 8px;
+ border-radius: 20px;
+ margin-left: 10px;
+ vertical-align: middle;
+ letter-spacing: 0;
+ }
@@ -2674,9 +2688,15 @@ final authRepositoryProvider = Provider<AuthRepository>((ref) {
);
});
-/// 4. UseCase(按需)
+/// 4. UseCase(登录有多步编排 — 校验 + 登录 + WS 连接 + DB 开库 + 用户持久化)
final loginUseCaseProvider = Provider<LoginUseCase>((ref) {
- return LoginUseCase(authRepository: ref.read(authRepositoryProvider));
+ return LoginUseCase(
+ authRepository: ref.read(authRepositoryProvider),
+ socketManager: ref.read(socketManagerProvider),
+ apiConfig: ref.read(apiConfigProvider),
+ storageApi: ref.read(storageSdkProvider),
+ userRepository: ref.read(userRepositoryProvider),
+ );
});
@@ -2977,7 +2997,7 @@ flowchart TD
style CoreUI fill:#fff4e6,stroke:#f57c00
-
2.2 整体目录图
+2.2 整体目录图最后更新 2026-03-10-10-17
图表说明
@@ -2996,10 +3016,13 @@ flowchart TD
│ │ └── guards/
│ │ └── auth_guard.dart # 登录守卫(switch AppRouteName,穷举防漏路由)
│ │
-│ └── di/ # 全局 DI — 手动装配的 Provider
-│ ├── network_provider.dart # NetworkMonitor + ApiConfig + NetworksSdkApi + SocketConfig + SocketClient + SocketManager
-│ ├── db_provider.dart # StorageSdkApi(注入 AppDatabase factory)
-│ └── app_providers.dart # AppInitializer + ThemeModeNotifier + AuthNotifier
+│ ├── di/ # 全局 DI — 手动装配的 Provider
+│ │ ├── network_provider.dart # NetworkMonitor + ApiConfig + NetworksSdkApi + SocketConfig + SocketClient + SocketManager
+│ │ ├── db_provider.dart # storageSdkProvider + storageSdkLifecycleProvider
+│ │ ├── app_providers.dart # AppInitializer + ThemeModeNotifier + AuthNotifier
+│ │ └── user_provider.dart # userRepositoryProvider / CRUD UseCase Providers / users + allUsers Stream
+│ └── notifiers/ # 全局 Notifier(@riverpod,跨模块共用)
+│ └── user_notifier.dart # UserNotifier — 单用户状态(family per-uid,含 watch + CRUD)
│
├── features/ # 功能模块(垂直切片):Feature 间禁止直接 import
│ │
@@ -3012,18 +3035,33 @@ flowchart TD
│ │ │ └── auth_providers.dart # authRepositoryProvider / loginUseCaseProvider
│ │ ├── presentation/
│ │ │ ├── login_view_model.dart # @riverpod ViewModel(生成 login_view_model.g.dart)
-│ │ │ └── login_state.dart # @freezed State(生成 login_state.freezed.dart)
+│ │ │ └── login_state.dart # @freezed State(step / contact / isLoading / error)
│ │ ├── usecases/
-│ │ │ └── login_usecase.dart # 格式校验 → Repository → User Entity
+│ │ │ └── login_usecase.dart # 校验 → OTP → 登录 → WS 连接 → DB 开库 → 用户持久化
│ │ └── view/
-│ │ └── login_page.dart # 登录页
+│ │ ├── login_page.dart # 登录页(装配 + 控制器 + 回调)
+│ │ └── widgets/
+│ │ ├── login_phone_step.dart # 手机号输入步骤(纯展示)
+│ │ └── login_otp_step.dart # 验证码输入步骤(纯展示)
│ │
│ ├── chat/ # 聊天 ── 开发中
+│ │ ├── di/
+│ │ │ └── chat_bot_provider.dart # chatBotRepositoryProvider / allChatBots / chatBot(id)
+│ │ ├── call/ # 通话子模块
+│ │ │ └── di/
+│ │ │ └── call_log_provider.dart # callLogRepositoryProvider / allCallLogs / callLog(id)
│ │ ├── presentation/
-│ │ │ └── chat_view_model.dart # @riverpod ViewModel
+│ │ │ ├── chat_view_model.dart # @riverpod ViewModel(会话列表)
+│ │ │ ├── chat_db_test_state.dart # Drift DB 测试 State(手写,含分页字段)
+│ │ │ └── chat_db_test_view_model.dart # Drift DB 测试 ViewModel(startTest / loadMore)
+│ │ ├── usecases/
+│ │ │ ├── insert_users_use_case.dart # 批量插入用户(200 条/批,去重)
+│ │ │ ├── update_users_use_case.dart # 更新前 10 条用户昵称
+│ │ │ └── delete_users_use_case.dart # 删除前 10 条用户
│ │ └── view/
│ │ ├── chat_page.dart # 会话列表页(Tab 1)
-│ │ └── chat_detail_page.dart # 聊天详情页
+│ │ ├── chat_detail_page.dart # 聊天详情页
+│ │ └── chat_db_test_page.dart # Drift DB 测试页
│ │
│ ├── contact/ # 通讯录 ── 骨架
│ │ └── view/
@@ -3031,12 +3069,12 @@ flowchart TD
│ │
│ └── settings/ # 设置 ── 已实现(主题切换)
│ ├── di/
-│ │ └── settings_providers.dart # settingsRepositoryProvider(待 storage_sdk 接入)
+│ │ └── settings_providers.dart # setThemeUseCaseProvider
│ ├── presentation/
│ │ ├── settings_view_model.dart # @riverpod ViewModel(设置页导航)
-│ │ └── theme_view_model.dart # @riverpod ViewModel(生成 theme_view_model.g.dart)
+│ │ └── theme_view_model.dart # @riverpod ViewModel(主题切换)
│ ├── usecases/
-│ │ └── set_theme_usecase.dart # 主题切换用例
+│ │ └── set_theme_usecase.dart # 主题切换用例(幂等校验,防重复切换)
│ └── view/
│ ├── settings_page.dart # 设置主页(Tab 3)
│ ├── theme_view.dart # 主题选择页
@@ -3045,34 +3083,60 @@ flowchart TD
│ └── theme_option_tile.dart
│
├── domain/ # Domain 层(纯 Dart,零 Flutter / 零网络依赖)
-│ ├── entities/
-│ │ └── user.dart # 用户实体
-│ │ # message / conversation / contact 待开发
-│ └── repositories/
-│ └── auth_repository.dart # abstract interface
-│ # message / chat / contact_repository 待开发
+│ ├── entities/ # 21 个实体(每实体一文件)
+│ │ ├── user.dart # 用户
+│ │ ├── message.dart # 消息
+│ │ ├── chat.dart # 会话
+│ │ ├── call_log.dart # 通话记录
+│ │ ├── chat_bot.dart # 聊天机器人
+│ │ ├── chat_category.dart # 会话分类
+│ │ ├── group.dart # 群组
+│ │ ├── group_member.dart # 群成员
+│ │ ├── workspace.dart # 工作区
+│ │ ├── company_member.dart # 企业成员
+│ │ ├── favourite.dart / favourite_detail.dart
+│ │ ├── sound.dart / tag.dart / retry.dart
+│ │ ├── pending_friend_request_history.dart
+│ │ ├── user_request_history.dart
+│ │ └── {discover,explore,favorite,recent}_mini_app.dart
+│ └── repositories/ # 4 个抽象接口
+│ ├── auth_repository.dart # sendOtp / verifyOtp / login / logout
+│ ├── user_repository.dart # watch / get / insert / update / upsert / delete
+│ ├── call_log_repository.dart # 通话记录 CRUD + watch
+│ └── chat_bot_repository.dart # 聊天机器人 CRUD + watch
│
├── data/ # Data 层(implements domain 接口)
-│ ├── repositories/
-│ │ └── auth_repository_impl.dart # 认证仓库
-│ │ # message / chat / contact 待开发
+│ ├── repositories/ # 4 个实现类
+│ │ ├── auth_repository_impl.dart # 认证(登录 / 登出 / Token 回调)
+│ │ ├── user_repository_impl.dart # 用户(Drift CRUD + Stream watch)
+│ │ ├── call_log_repository_impl.dart # 通话记录
+│ │ └── chat_bot_repository_impl.dart # 聊天机器人
│ ├── local/
│ │ └── drift/ # Drift 本地数据库
-│ │ ├── app_database.dart # @DriftDatabase 定义 + onUpgrade 自动补列
-│ │ # database_connection.dart 已迁移至 storage_sdk(数据库生命周期统一在 SDK 层管理)
+│ │ ├── app_database.dart # @DriftDatabase(19 张表)+ onUpgrade 自动补列
│ │ ├── mapper/
│ │ │ └── drift_path_mapper.dart # Drift 路径映射工具
-│ │ └── tables/
-│ │ └── users.dart # Users 表定义
+│ │ └── tables/ # 19 个表定义(每表一文件)
+│ │ ├── users.dart / messages.dart / chats.dart / call_logs.dart
+│ │ ├── chat_bots.dart / chat_categories.dart / groups.dart / workspaces.dart
+│ │ ├── favourites.dart / favourite_details.dart
+│ │ ├── sounds.dart / tags.dart / retries.dart
+│ │ ├── pending_friend_request_histories.dart / user_request_histories.dart
+│ │ └── {discover,explore,favorite,recent}_mini_apps.dart
│ ├── remote/ # Request 文件(一个端点一个文件)
+│ │ ├── send_otp_request.dart # 发送验证码
+│ │ ├── verify_otp_request.dart # 校验验证码
│ │ ├── login_request.dart # 登录
│ │ ├── logout_request.dart # 登出
│ │ ├── get_profile_request.dart # 获取用户信息
│ │ └── upload_file_request.dart # 文件上传
-│ │ # send_message / 其他业务端点 待开发
-│ └── models/ # 持久化 DTO(@JsonSerializable)
-│ └── user_dto.dart # 用户持久化 DTO
-│ # message / conversation / contact_dto 待开发
+│ └── models/ # 持久化 DTO(17 个,与表一一对应)
+│ ├── user_dto.dart / message_dto.dart / chat_dto.dart
+│ ├── chat_bot_dto.dart / chat_category_dto.dart / group_dto.dart / workspace_dto.dart
+│ ├── favourite_dto.dart / favourite_detail_dto.dart
+│ ├── sound_dto.dart / tag_dto.dart / retry_dto.dart
+│ ├── pending_friend_request_history_dto.dart / user_request_history_dto.dart
+│ └── {discover,explore,favorite,recent}_mini_app_dto.dart
│
└── core/ # Core 层:零业务逻辑,禁止反向依赖 features / domain / data
├── foundation/ # 基础配置(各为单独文件,非子目录)
@@ -3097,7 +3161,7 @@ flowchart TD
│ ├── icons.dart # 图标常量(AppIcons:导航 / 操作 / 聊天 / 用户 / 状态)
│ ├── app_theme.dart # ThemeData 组装(Light / Dark)
│ ├── colors.dart # 颜色体系(品牌色 / 语义色 / 灰阶)
- │ ├── context_theme_ext.dart # BuildContext 主题扩展(context.theme / context.colors)
+ │ ├── context_theme_ext.dart # BuildContext 扩展(context.colors / context.styles / context.shadows)
│ └── font.dart # 字体(TextStyle 定义 + textTheme(brightness))
├── components/ # 原子组件
│ └── app_button.dart # 按钮
@@ -3106,7 +3170,7 @@ flowchart TD
# app_dialog / app_toast / app_empty_state 等
-2.3 整体分层图(MVVM + Riverpod 数据流)
+2.3 整体分层图(MVVM + Riverpod 数据流)最后更新 2026-03-10-10-17
图表说明
@@ -3211,7 +3275,7 @@ flowchart LR
-两大核心逻辑:
+三大核心逻辑:
1. MVVM 分层职责:View(view/)只负责渲染和用户交互,ViewModel(presentation/)持有状态并处理业务逻辑,Model(model/ + entities/)定义数据结构 —— 三者通过 Riverpod Provider 连接,职责严格分离。
2. Riverpod 单向数据流:用户操作 → ref.read(vm.notifier).action() → ViewModel 处理逻辑 → state = newState → ref.watch(vm) 检测变化 → View 自动 rebuild。数据永远单向流动,UI 永远是状态的函数。
3. Widget 纯展示原则:build() 只做一件事——把 State 属性映射成 Widget 树,不允许出现任何计算或逻辑。
@@ -5178,19 +5242,19 @@ flowchart TD
flowchart TD
- UI[UI Layer] -->|用户操作: vm.method()| VM[ViewModel]
- VM -->|调用| Repo[Repository]
- VM -.复杂场景.-> UC[UseCase(按需)]
+ UI["UI Layer"] -->|"用户操作 vm.method"| VM["ViewModel"]
+ VM -->|"调用"| Repo["Repository"]
+ VM -.->|"复杂场景"| UC["UseCase(按需)"]
UC -.-> Repo
- Repo -->|返回 Entity| VM
- VM -->|state = newState| State[UI State]
- State -->|ref.watch 自动刷新| UI
+ Repo -->|"返回 Entity"| VM
+ VM -->|"state = newState"| UIState["UI State"]
+ UIState -->|"ref.watch 自动刷新"| UI
style UI fill:#e1f5ff,stroke:#0288d1
style VM fill:#fff4e6,stroke:#f57c00
style Repo fill:#e8f5e9,stroke:#388e3c
- style UC fill:#f3e5f5,stroke:#7b1fa2,stroke-dasharray: 5 5
- style State fill:#fff4e6,stroke:#f57c00
+ style UC fill:#f3e5f5,stroke:#7b1fa2
+ style UIState fill:#fff4e6,stroke:#f57c00
Riverpod ViewModel 实现方式
@@ -6206,9 +6270,15 @@ final authRepositoryProvider = Provider<AuthRepository>((ref) {
);
});
-// UseCase(按需 — 登录有多步编排,所以需要 UseCase)
+// UseCase(登录有多步编排 — 校验 + 登录 + WS 连接 + DB 开库 + 用户持久化)
final loginUseCaseProvider = Provider<LoginUseCase>((ref) {
- return LoginUseCase(authRepository: ref.read(authRepositoryProvider));
+ return LoginUseCase(
+ authRepository: ref.read(authRepositoryProvider),
+ socketManager: ref.read(socketManagerProvider),
+ apiConfig: ref.read(apiConfigProvider),
+ storageApi: ref.read(storageSdkProvider),
+ userRepository: ref.read(userRepositoryProvider),
+ );
});
@@ -6877,7 +6947,7 @@ final user = await db.selectFirst(appDb.users, (t) => t.uid.equals(uid));
为什么独立 Package:国际化服务于 core/ui(组件内置文案)和 Feature 层(页面文案、错误提示展示),作为独立 SDK 可跨项目复用翻译基础设施。注意:foundation 本身不依赖 l10n_sdk —— 错误映射仅产出错误码/错误键,由 Presentation / UI 层通过 l10n_sdk 转为本地化文案,从而避免 foundation ↔ l10n 双向依赖。
-7.5 Core UI(core/ui/)
+7.5 Core UI(core/ui/)最后更新 2026-03-10-10-17
UI 基础设施,为所有 Feature 提供统一的视觉规范和可复用组件。三层结构自底向上构建:
@@ -9836,7 +9906,7 @@ flowchart TD
本章定义颜色、字体、组件、弹框、图标的命名与使用规则,明确设计与研发的协作约定。Figma 按此命名,代码按此封装,两端名称一一对应。
-8.0 核心约定
+8.0 核心约定最后更新 2026-03-10-10-17
全局只有一份
@@ -9863,7 +9933,7 @@ flowchart TD
图片和组件是重灾区:没有统一来源时,不同研发各自导出同一张图,文件名不同、尺寸不同,最终项目里堆满重复文件。Figma 统一命名、代码统一注册,才能从源头堵住。
-8.1 颜色体系
+8.1 颜色体系最后更新 2026-03-10-10-17
颜色采用 5 层架构:ColorBases(颜色常量)→ AppColors(语义接口)→ LightColors/DarkColors(亮暗实现)→ AppTheme._build(AppColors c)(主题组装)→ context.colors(Widget 消费)。AppTheme 内部零 isDark 分支,亮暗差异完全由实现类决定。