- 添加根目录 AGENTS.md 定义全仓工程总览及各端开发规范 - 添加 webrtc_controller_flutter/AGENTS.md 定义 Flutter 项目技术栈、架构与编码规范 - 修正 WebRTCController app/build.gradle 中 appName 返回值
5.0 KiB
5.0 KiB
Flutter 项目规范
严格遵循本文档定义的架构模式、状态管理标准和代码风格。未经授权不得引入新的第三方包或架构模式。优先组合而非继承,业务逻辑不进入 UI 组件。
1. 技术栈
- 语言: Dart(SDK >=3.0.0,严格空安全)
- 框架: Flutter(最新稳定通道)
- 状态管理:
flutter_riverpod(v2.x,注解 + 代码生成) - 路由:
go_router - 网络请求:
dio(配合json_annotation+freezed进行 JSON 序列化) - 数据模型:
freezed+build_runner - 本地存储:
hive/shared_preferences - 依赖注入: Riverpod Providers(不使用 GetIt)
- 国际化:
flutter_localizations(l10n / ARB 格式)
2. 目录结构
采用 特性优先架构(Feature-First),特性内部结合 整洁架构(Clean Architecture) 分层:
lib/
├── app/ # 全局应用配置
│ ├── app.dart # MaterialApp 入口
│ ├── router/ # 路由定义(GoRouter)
│ ├── theme/ # 主题、颜色、排版
│ └── constants/ # 全局常量、API 端点
│
├── core/ # 跨特性共享代码
│ ├── network/ # Dio 客户端、拦截器、错误处理
│ ├── storage/ # 本地存储辅助工具
│ ├── utils/ # 辅助函数、扩展方法
│ └── widgets/ # 共享 UI 组件(按钮、输入框)
│
├── features/ # 特性模块
│ ├── auth/ # 示例:认证模块
│ │ ├── data/ # 数据源、API 端点、DTO
│ │ ├── domain/ # 领域模型、仓库接口
│ │ └── presentation/ # UI 页面、组件、控制器
│ │ ├── controllers/
│ │ ├── pages/
│ │ └── widgets/
│ └── home/ # 示例:首页模块
│ ├── data/
│ ├── domain/
│ └── presentation/
│
├── l10n/ # 国际化(.arb 文件)
└── main.dart # 应用入口
3. 分层职责
表示层(presentation/)
UI 组件 + Riverpod Notifier / AsyncNotifier 控制器。
- 只能通过
ref.watch或ref.listen消费状态。 - 禁止在
onPressed或build()中直接调用 API 或编写业务逻辑。
领域层(domain/)
纯 Dart 领域实体(@freezed)和仓库接口定义。
- 零 Flutter/UI 依赖。
数据层(data/)
实现仓库接口,通过 Dio 处理 API 请求,将 JSON DTO 映射为领域实体。
4. 编码规范
状态管理(Riverpod)
- 使用
@riverpod注解 +build_runner代码生成。 - 异步操作优先使用
AsyncNotifierProvider,配合AsyncValue(Loading / Data / Error)。
@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),
);
}
}
数据建模(freezed)
所有数据类/实体必须用 freezed 实现不可变,并配置嵌套 JSON 映射:
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;
factory UserModel.fromJson(Map<String, dynamic> json) =>
_$UserModelFromJson(json);
}
UI 组件
- 尽可能使用
const构造函数,避免不必要的重建。 - 复杂子树提取为独立私有/公有无状态组件,不要写冗长的内联辅助方法(如
_buildHeader())。 - 响应式适配使用
LayoutBuilder/MediaQuery或项目统一的屏幕适配工具。
5. 命名约定
| 类别 | 规范 | 示例 |
|---|---|---|
| 文件/文件夹 | snake_case.dart |
user_profile.dart |
| 类/枚举 | PascalCase |
UserProfilePage |
| 变量/方法 | camelCase |
getUserData() |
| Provider | 以 Provider 结尾 |
userRepositoryProvider |
| 私有成员 | _ 前缀 |
_handleTap() |
6. 代码生成
修改或新增带代码生成的模型/控制器后,运行:
# 一次性生成
flutter pub run build_runner build --delete-conflicting-outputs
# 监听模式
flutter pub run build_runner watch --delete-conflicting-outputs
7. 完成标准
- 新文件遵循特性优先结构。
- 代码为空安全、完全类型化,并进行
const优化。 - 对应创建数据层、领域层和表示层组件。
- 不存在原始
setState(状态统一由 Riverpod 管理)。