docs(webrtc_controller_flutter): 更新项目文档以反映重构后的架构
AGENTS.md 与 README.md 同步更新:根据实际代码结构重写目录树、技术栈、架构分层及编码规范,移除旧版内联示例并补充新的开发约定与代码生成命令。
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
- **路由:** `go_router`
|
||||
- **网络请求:** `dio`(配合 `json_annotation` + `freezed` 进行 JSON 序列化)
|
||||
- **数据模型:** `freezed` + `build_runner`
|
||||
- **本地存储:** `hive` / `shared_preferences`
|
||||
- **本地存储:** `shared_preferences`(非敏感偏好)+ `flutter_secure_storage`(令牌)
|
||||
- **依赖注入:** Riverpod Providers(不使用 GetIt)
|
||||
- **国际化:** `flutter_localizations`(l10n / ARB 格式)
|
||||
|
||||
@@ -24,33 +24,28 @@
|
||||
|
||||
```text
|
||||
lib/
|
||||
├── main.dart # 应用程序入口(ProviderScope + runApp)
|
||||
├── app/ # 全局应用配置
|
||||
│ ├── app.dart # MaterialApp 入口
|
||||
│ ├── app.dart # CupertinoApp.router 入口
|
||||
│ ├── router/ # 路由定义(GoRouter)
|
||||
│ ├── theme/ # 主题、颜色、排版
|
||||
│ └── constants/ # 全局常量、API 端点
|
||||
│
|
||||
│ └── constants/ # 全局常量、API 端点、ICE 配置
|
||||
├── core/ # 跨特性共享代码
|
||||
│ ├── network/ # Dio 客户端、拦截器、错误处理
|
||||
│ ├── network/ # dio 客户端、错误处理
|
||||
│ ├── proto/ # Protobuf 生成代码(控制指令协议)
|
||||
│ ├── storage/ # 本地存储辅助工具
|
||||
│ ├── utils/ # 辅助函数、扩展方法
|
||||
│ └── widgets/ # 共享 UI 组件(按钮、输入框)
|
||||
│
|
||||
│ └── widgets/ # 共享 UI 组件(触摸层)
|
||||
├── features/ # 特性模块
|
||||
│ ├── auth/ # 示例:认证模块
|
||||
│ │ ├── data/ # 数据源、API 端点、DTO
|
||||
│ │ ├── domain/ # 领域模型、仓库接口
|
||||
│ │ └── presentation/ # UI 页面、组件、控制器
|
||||
│ │ ├── controllers/
|
||||
│ │ ├── pages/
|
||||
│ │ └── widgets/
|
||||
│ └── home/ # 示例:首页模块
|
||||
│ ├── data/
|
||||
│ ├── domain/
|
||||
│ └── presentation/
|
||||
│
|
||||
├── l10n/ # 国际化(.arb 文件)
|
||||
└── main.dart # 应用入口
|
||||
│ ├── auth/ # 登录 / 令牌 / 绑定列表
|
||||
│ │ ├── data/ # Repository 实现(dio)
|
||||
│ │ ├── domain/ # 仓库接口、状态模型(freezed)
|
||||
│ │ └── presentation/ # 控制器、登录对话框
|
||||
│ └── connection/ # 信令 / WebRTC / 控制面板
|
||||
│ ├── data/ # 信令客户端、WebRTC、编排器、解码器、录制器
|
||||
│ ├── domain/ # 信令消息、会话状态(freezed)
|
||||
│ └── presentation/ # 控制器、设置页、控制页、鉴权对话框
|
||||
└── l10n/ # 国际化(.arb 文件)
|
||||
```
|
||||
|
||||
---
|
||||
@@ -63,16 +58,18 @@ UI 组件 + Riverpod Notifier / AsyncNotifier 控制器。
|
||||
|
||||
- 只能通过 `ref.watch` 或 `ref.listen` 消费状态。
|
||||
- 禁止在 `onPressed` 或 `build()` 中直接调用 API 或编写业务逻辑。
|
||||
- 一次性提示通过状态中的 `alert` 字段传递,UI 展示后调用 `consumeAlert()` 消费。
|
||||
|
||||
### 领域层(`domain/`)
|
||||
|
||||
纯 Dart 领域实体(`@freezed`)和仓库接口定义。
|
||||
纯 Dart 实体(`freezed`)和仓库接口定义。
|
||||
|
||||
- 零 Flutter/UI 依赖。
|
||||
- 零 Flutter/UI 依赖(协议模型除外)。
|
||||
- 状态类命名避免与 Flutter SDK 冲突(如用 `ConnectionSessionState` 而非 `ConnectionState`)。
|
||||
|
||||
### 数据层(`data/`)
|
||||
|
||||
实现仓库接口,通过 Dio 处理 API 请求,将 JSON DTO 映射为领域实体。
|
||||
实现仓库接口,通过 dio 处理 API 请求,将 JSON DTO 映射为领域实体。
|
||||
|
||||
---
|
||||
|
||||
@@ -81,52 +78,36 @@ UI 组件 + Riverpod Notifier / AsyncNotifier 控制器。
|
||||
### 状态管理(Riverpod)
|
||||
|
||||
- 使用 `@riverpod` 注解 + `build_runner` 代码生成。
|
||||
- 会话级控制器(如登录、连接)使用 `@Riverpod(keepAlive: true)`,避免页面切换时销毁。
|
||||
- 异步操作优先使用 `AsyncNotifierProvider`,配合 `AsyncValue`(Loading / Data / Error)。
|
||||
|
||||
```dart
|
||||
@riverpod
|
||||
class UserProfileController extends _$UserProfileController {
|
||||
@override
|
||||
FutureOr<User?> build() async {
|
||||
return _fetchUser();
|
||||
}
|
||||
|
||||
Future<void> updateName(String newName) async {
|
||||
state = const AsyncValue.loading();
|
||||
state = await AsyncValue.guard(
|
||||
() => ref.read(userRepositoryProvider).updateName(newName),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
- 业务回调(信令/WebRTC 事件)统一在控制器内映射到状态,不在 UI 层直接持有控制器实例。
|
||||
|
||||
### 数据建模(freezed)
|
||||
|
||||
所有数据类/实体必须用 `freezed` 实现不可变,并配置嵌套 JSON 映射:
|
||||
所有数据类/实体必须用 `freezed` 实现不可变,并配置 JSON 序列化:
|
||||
|
||||
```dart
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'user_model.freezed.dart';
|
||||
part 'user_model.g.dart';
|
||||
|
||||
@freezed
|
||||
class UserModel with _$UserModel {
|
||||
const factory UserModel({
|
||||
required String id,
|
||||
required String email,
|
||||
String? name,
|
||||
}) = _UserModel;
|
||||
class SignalMessage with _$SignalMessage {
|
||||
const SignalMessage._();
|
||||
|
||||
factory UserModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$UserModelFromJson(json);
|
||||
const factory SignalMessage({
|
||||
String? type,
|
||||
String? payload,
|
||||
}) = _SignalMessage;
|
||||
|
||||
factory SignalMessage.fromJson(Map<String, dynamic> json) =>
|
||||
_$SignalMessageFromJson(json);
|
||||
|
||||
@override
|
||||
String toString() => jsonEncode(toJson());
|
||||
}
|
||||
```
|
||||
|
||||
### UI 组件
|
||||
|
||||
- 尽可能使用 `const` 构造函数,避免不必要的重建。
|
||||
- 复杂子树提取为独立私有/公有无状态组件,不要写冗长的内联辅助方法(如 `_buildHeader()`)。
|
||||
- 复杂子树提取为独立私有/公有无状态组件,不要写冗长的内联辅助方法。
|
||||
- 响应式适配使用 `LayoutBuilder` / `MediaQuery` 或项目统一的屏幕适配工具。
|
||||
|
||||
---
|
||||
@@ -135,11 +116,11 @@ class UserModel with _$UserModel {
|
||||
|
||||
| 类别 | 规范 | 示例 |
|
||||
|---|---|---|
|
||||
| 文件/文件夹 | `snake_case.dart` | `user_profile.dart` |
|
||||
| 类/枚举 | `PascalCase` | `UserProfilePage` |
|
||||
| 变量/方法 | `camelCase` | `getUserData()` |
|
||||
| Provider | 以 `Provider` 结尾 | `userRepositoryProvider` |
|
||||
| 私有成员 | `_` 前缀 | `_handleTap()` |
|
||||
| 文件/文件夹 | `snake_case.dart` | `connection_controller.dart` |
|
||||
| 类/枚举 | `PascalCase` | `ConnectionSessionState` |
|
||||
| 变量/方法 | `camelCase` | `sendResolutionChange()` |
|
||||
| Provider | 以 `Provider` 结尾 | `authRepositoryProvider` |
|
||||
| 私有成员 | `_` 前缀 | `_handleSignalMessage()` |
|
||||
|
||||
---
|
||||
|
||||
@@ -148,18 +129,22 @@ class UserModel with _$UserModel {
|
||||
修改或新增带代码生成的模型/控制器后,运行:
|
||||
|
||||
```bash
|
||||
# 一次性生成
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
# 一次性生成(freezed / json_serializable / riverpod_generator)
|
||||
dart run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# 监听模式
|
||||
flutter pub run build_runner watch --delete-conflicting-outputs
|
||||
dart run build_runner watch --delete-conflicting-outputs
|
||||
|
||||
# 生成国际化(l10n.yaml 已配置)
|
||||
flutter gen-l10n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 完成标准
|
||||
|
||||
- 新文件遵循特性优先结构。
|
||||
- 新文件遵循特性优先结构(app / core / features / l10n)。
|
||||
- 代码为空安全、完全类型化,并进行 `const` 优化。
|
||||
- 对应创建数据层、领域层和表示层组件。
|
||||
- 不存在原始 `setState`(状态统一由 Riverpod 管理)。
|
||||
- 提交前 `flutter analyze` 无 issue;`flutter test` 通过。
|
||||
- 协议(`.proto` / 信令 JSON)变更需同步 Android / iOS / Web 各端。
|
||||
|
||||
Reference in New Issue
Block a user