# Augment 代码生成规范 ## 基于 OpenAPI 3.0 标准的 Flutter API 代码生成规范 ### 📋 **核心原则** #### 1. **OpenAPI 3.0 标准优先** - **严格遵循 OpenAPI 3.0 规范** - **swagger.json 是唯一真实来源** - **不进行主观推断或猜测** - **有问题与服务器端沟通完善文档** #### 2. **类型安全第一** - **所有类型必须从 schema 定义中提取** - **禁止硬编码类型映射** - **使用强类型,避免 dynamic** - **严格的可空性控制** #### 3. **一致性保证** - **统一的命名规范** - **统一的文件结构** - **统一的代码风格** - **统一的注释格式** --- ## 🏗️ **项目结构规范** ### **目录结构** ``` generator/ ├── api/ # API 接口文件 │ ├── api_client.dart # 主 API 客户端 │ ├── login_api.dart # 按 tag 分组的 API │ └── ... ├── api_models/ # 数据模型 │ ├── index.dart # 统一导出文件 │ ├── user_result.dart # 具体模型类 │ └── ... ├── api_paths.dart # API 路径常量 ├── build.yaml # 构建配置 └── pubspec.yaml # 依赖配置 ``` ### **文件命名规范** - **API 文件**: `{tag_name}_api.dart` (snake_case) - **模型文件**: `{schema_name}.dart` (snake_case) - **参数文件**: `{operation_id}_parameters.dart` - **类名**: `PascalCase` - **方法名**: `camelCase` - **常量**: `UPPER_SNAKE_CASE` --- ## 🔧 **代码生成规范** ### **1. API 接口生成** #### **基本结构** ```dart // {Tag} API 接口定义 // 基于 Swagger API 文档: {swagger_url} // 由 xy_swagger_generator by max 生成 // Copyright (C) 2025 YuanXuan. All rights reserved. import 'package:dio/dio.dart'; import 'package:retrofit/retrofit.dart'; import 'package:learning_officer_oa/common/models/common/base_result.dart'; // 按需导入分页类型 import 'package:learning_officer_oa/common/models/common/base_page_result.dart'; part '{tag_name}_api.g.dart'; /// {Tag} API 接口 /// 负责处理 {Tag} 相关的接口 @RestApi(parser: Parser.JsonSerializable) abstract class {Tag}Api { factory {Tag}Api(Dio dio, {String? baseUrl}) = _{Tag}Api; } ``` #### **方法生成规则** ```dart /// {summary} @{HTTP_METHOD}('{path}') Future<{ReturnType}> {methodName}( // 路径参数 @Path('{param}') {Type} param, // 查询参数 @Query('{param}') {Type}? param, // 请求体(仅当 swagger 中明确定义时) @Body() {Type} request ); ``` ### **2. 返回类型规范** #### **类型提取优先级** 1. **从 responses.200.content.application/json.schema 提取** 2. **从 responses.200.content.text/plain.schema 提取** 3. **特殊处理**: 健康检查接口返回 `BaseResult` 4. **默认**: `BaseResult>` #### **分页类型判断** ```dart // 当返回类型包含分页结构时使用 BasePageResult BasePageResult<{ItemType}> // 判断依据: // 1. schema 中包含 pageIndex, pageSize, totalCount 等字段 // 2. 查询参数中包含分页参数 (page, size, limit 等) ``` ### **3. 请求体生成规范** #### **添加 @Body() 的条件** ```dart // 仅在以下情况添加 @Body() 参数: // 1. requestBody 在 swagger 中明确定义 // 2. parameters 中存在 in: "body" 的参数 // 3. 其他情况一律不添加 ``` #### **请求体类型提取** ```dart // 优先级: // 1. requestBody.content.application/json.schema // 2. requestBody.content.text/plain.schema // 3. 默认: Map ``` --- ## 📝 **数据模型生成规范** ### **1. 模型类结构** #### **基本模板** ```dart // {schemaName} 模型定义 // 基于 Swagger API 文档: {swagger_url} // 由 xy_swagger_generator by max 生成 // Copyright (C) 2025 YuanXuan. All rights reserved. import 'package:json_annotation/json_annotation.dart'; import 'index.dart'; part '{schema_name}.g.dart'; @JsonSerializable(checked: true, includeIfNull: false) class {SchemaName} { // 属性定义 const {SchemaName}({ // 构造函数参数 }); factory {SchemaName}.fromJson(Map json) => _${SchemaName}FromJson(json); Map toJson() => _${SchemaName}ToJson(this); } ``` ### **2. 属性生成规则** #### **可空性判断** ```dart // 严格按照 OpenAPI 规范: // 1. 有 "nullable": true -> 可空类型 (Type?) // 2. 没有 "nullable": true -> 非空类型 (Type) // 3. 忽略 required 字段,只看 nullable final String name; // 非空 final String? nickname; // 可空 (nullable: true) ``` #### **类型映射** ```dart // OpenAPI -> Dart 类型映射 "string" -> String "integer" -> int "number" -> double "boolean" -> bool "array" -> List "object" -> Map 或具体类型 "$ref" -> 引用的具体类型 ``` #### **构造函数规则** ```dart const {ClassName}({ required this.nonNullableField, // 非空字段必须 required this.nullableField, // 可空字段不需要 required }); ``` ### **3. 导入管理** #### **按需导入原则** ```dart // 只导入实际使用的类型 // 分页相关 import 'package:learning_officer_oa/common/models/common/base_page_result.dart'; // 基础响应 import 'package:learning_officer_oa/common/models/common/base_result.dart'; // 模型类型 import '../../api_models/{model_name}.dart'; ``` --- ## 🚫 **禁止事项** ### **1. 硬编码推断** ```dart // ❌ 禁止基于路径关键词推断类型 if (path.contains('login')) return 'UserLoginResult'; // ❌ 禁止基于 tag 推断类型 if (tag.contains('task')) return 'TaskInfoResult'; // ❌ 禁止基于操作推断请求体 if (method == 'POST') addBody(); ``` ### **2. 不存在的类型** ```dart // ❌ 禁止生成 swagger 中不存在的类型 Future> // TaskInfoResult 不存在 // ✅ 使用通用类型或实际存在的类型 Future>> Future> ``` ### **3. 主观判断** ```dart // ❌ 禁止主观添加参数 @Body() Map request // swagger 中没有定义 // ❌ 禁止主观修改类型 List -> List // 没有明确的 items schema ``` --- ## ✅ **质量保证** ### **1. 生成前检查** - **验证 swagger.json 格式正确性** - **检查所有 $ref 引用完整性** - **确认 components/schemas 定义完整** ### **2. 生成后验证** - **所有生成的类型在 swagger 中都有定义** - **没有硬编码的类型映射** - **导入语句按需生成** - **代码通过 dart analyze 检查** ### **3. 错误处理** ```dart // 当 swagger 定义不完整时的处理策略: // 1. 记录警告日志 // 2. 使用安全的默认类型 // 3. 提示完善 swagger 文档 // 4. 不进行主观推断 ``` --- ## 📞 **沟通机制** ### **文档问题反馈** 1. **发现 swagger 定义缺失** -> 联系后端完善 2. **类型定义不明确** -> 要求明确 schema 3. **响应结构不一致** -> 统一响应格式 4. **参数定义缺失** -> 补充参数说明 ### **版本管理** - **swagger.json 版本控制** - **生成代码版本标记** - **变更日志记录** - **向后兼容性检查** --- ## 🛠️ **工具配置规范** ### **1. 生成器配置** ```yaml # pubspec.yaml dependencies: dio: ^5.0.0 retrofit: ^4.0.0 json_annotation: ^4.8.0 dev_dependencies: build_runner: ^2.3.0 retrofit_generator: ^8.0.0 json_serializable: ^6.6.0 ``` ### **2. 构建配置** ```yaml # build.yaml targets: $default: builders: json_serializable: options: checked: true include_if_null: false explicit_to_json: true ``` ### **3. 分析配置** ```yaml # analysis_options.yaml analyzer: strong-mode: implicit-casts: false implicit-dynamic: false linter: rules: - prefer_const_constructors - prefer_final_fields - avoid_dynamic_calls ``` --- ## 📚 **最佳实践示例** ### **1. 标准 API 接口** ```dart /// 用户登录 @POST('/api/v1/Login/userLogin') Future> userLogin( @Body() LoginRequest request ); /// 获取用户列表(分页) @GET('/api/v1/User/GetUserList') Future> getUserList( @Query('page') int page, @Query('size') int size, @Query('keyword') String? keyword ); /// 健康检查 @GET('/health') Future> healthCheck(); /// 无明确 schema 的接口 @POST('/api/v1/Action/DoSomething') Future>> doSomething(); ``` ### **2. 标准数据模型** ```dart @JsonSerializable(checked: true, includeIfNull: false) class UserResult { /// 用户ID final int id; /// 用户名 final String username; /// 昵称(可空) final String? nickname; /// 头像URL(可空) final String? avatarUrl; /// 是否激活 final bool isActive; const UserResult({ required this.id, required this.username, this.nickname, this.avatarUrl, required this.isActive, }); factory UserResult.fromJson(Map json) => _$UserResultFromJson(json); Map toJson() => _$UserResultToJson(this); } ``` ### **3. 参数类生成** ```dart @JsonSerializable(checked: true, includeIfNull: false) class GetUserListParameters { final int page; final int size; final String? keyword; const GetUserListParameters({ required this.page, required this.size, this.keyword, }); factory GetUserListParameters.fromJson(Map json) => _$GetUserListParametersFromJson(json); Map toJson() => _$GetUserListParametersToJson(this); } ``` --- ## 🔍 **代码审查清单** ### **生成代码检查项** - [ ] 所有类型都在 swagger.json 中有定义 - [ ] 没有硬编码的类型推断 - [ ] 可空性严格按照 nullable 字段 - [ ] 导入语句按需生成 - [ ] 方法参数与 swagger 定义一致 - [ ] 返回类型正确提取 - [ ] 注释信息完整 - [ ] 代码格式规范 ### **swagger.json 检查项** - [ ] 所有接口都有明确的 responses 定义 - [ ] 所有 schema 都有完整的属性定义 - [ ] 所有 $ref 引用都存在 - [ ] 参数定义完整(name, in, schema) - [ ] requestBody 定义明确 - [ ] 版本信息正确 --- ## 📖 **参考资源** ### **官方文档** - [OpenAPI 3.0 规范](https://swagger.io/specification/) - [Retrofit for Dart](https://pub.dev/packages/retrofit) - [JSON Serializable](https://pub.dev/packages/json_serializable) ### **项目相关** - [项目 README](./README.md) - [API 参考文档](./docs/API_REFERENCE.md) - [贡献指南](./CONTRIBUTING.md) --- **最后更新**: 2025-01-24 **版本**: v2.0 **维护者**: Augment Team