# 枚举键名生成优化方案 ## 问题描述 当前生成的枚举使用通用的键名(`value1`, `value2`, `value3`...),不够语义化。 ### 当前生成结果 ```dart enum SysTaskTypeEnums { value1(1), // 实际应该是 SPOT_CHECK (抽查) value2(2), // 实际应该是 CULTURAL (文创建设) value3(3), // 实际应该是 CLASS_CADRE_MEETING (班干部会议) ... } ``` ### 期望结果 ```dart enum SysTaskTypeEnums { /// 抽查 SPOT_CHECK(1), /// 文创建设 CULTURAL(2), /// 班干部会议 CLASS_CADRE_MEETING(3), /// 学生谈话 STUDENT_TALK(4), ... } ``` ## 根本原因 Swagger 文档中的枚举定义只包含值(numbers),没有提供键名映射: ```json { "SysTaskTypeEnums": { "enum": [1, 2, 3, 4, 5, ...], "type": "integer", "description": "任务类型枚举" } } ``` ## 解决方案 ### 方案 1: 使用 OpenAPI 扩展字段 (推荐) 在 Swagger 文档中添加 `x-enum-varnames` 和 `x-enum-descriptions` 扩展字段: ```json { "SysTaskTypeEnums": { "enum": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], "type": "integer", "description": "任务类型枚举", "format": "int32", "x-enum-varnames": [ "SPOT_CHECK", "CULTURAL", "CLASS_CADRE_MEETING", "STUDENT_TALK", "FOLLOW_CLASS", "TEACHER_BEHAVIOR_OBSERVATION", "MEETING", "COACH_SUBJECT", "DATA_COLLECTION", "CLASS_MEETING", "TEACHER_TALK", "OTHER_WORK", "CLASS_ACTIVITY" ], "x-enum-descriptions": [ "抽查", "文创建设", "班干部会议", "学生谈话", "双师跟课", "教师行为观察", "参加会议", "学科辅助", "数据采集", "召开班会", "教师谈话", "其他工作", "班级活动" ] } } ``` **优点**: - ✅ 标准的 OpenAPI 扩展方式 - ✅ 枚举定义和键名在同一处 - ✅ 易于维护 **缺点**: - ⚠️ 需要修改后端 Swagger 文档 - ⚠️ 需要后端配合 ### 方案 2: 配置文件映射 在 `generator_config.yaml` 中添加枚举键名映射: ```yaml # generator_config.yaml generation: models: # 枚举键名映射配置 enum_key_mappings: SysTaskTypeEnums: 1: name: SPOT_CHECK description: 抽查 2: name: CULTURAL description: 文创建设 3: name: CLASS_CADRE_MEETING description: 班干部会议 4: name: STUDENT_TALK description: 学生谈话 5: name: FOLLOW_CLASS description: 双师跟课 # ... 其他映射 SysRoleEnum: 1: name: ADMIN description: 管理员 2: name: USER description: 普通用户 # ... 其他映射 ``` **优点**: - ✅ 不需要修改后端 - ✅ 灵活配置 - ✅ 支持批量管理 **缺点**: - ⚠️ 配置文件可能很大 - ⚠️ 需要手动维护映射 ### 方案 3: 智能命名策略(备选) 如果 Swagger 文档中枚举的 description 字段包含中文说明,可以尝试智能转换: ``` "抽查" -> SPOT_CHECK (通过翻译API或预定义映射) "文创建设" -> CULTURAL "班干部会议" -> CLASS_CADRE_MEETING ``` **优点**: - ✅ 自动化程度高 - ✅ 不需要额外配置 **缺点**: - ⚠️ 翻译质量不稳定 - ⚠️ 需要外部服务或大量预定义映射 ## 推荐实施方案 ### 阶段 1: 支持 OpenAPI 扩展字段(立即实施) 修改枚举解析逻辑,支持读取 `x-enum-varnames` 和 `x-enum-descriptions`: ```dart // lib/core/models/api_schema.dart class ApiModel { final List? enumVarNames; // 新增 final List? enumDescriptions; // 新增 factory ApiModel.fromJson(...) { // 解析 x-enum-varnames final enumVarNames = json['x-enum-varnames'] as List?; final enumDescriptions = json['x-enum-descriptions'] as List?; return ApiModel( enumVarNames: enumVarNames?.map((e) => e.toString()).toList(), enumDescriptions: enumDescriptions?.map((e) => e.toString()).toList(), ... ); } } ``` 修改枚举生成逻辑: ```dart // lib/pipeline/generate/impl/model/model_content_builders.dart String _generateEnumCodeWithoutImports(ApiModel model) { ... for (var i = 0; i < model.enumValues.length; i++) { final value = model.enumValues[i]; // 优先使用 x-enum-varnames final enumName = model.enumVarNames != null && i < model.enumVarNames!.length ? model.enumVarNames![i] : StringHelper.generateEnumValueName(value, i); // 添加描述注释 if (model.enumDescriptions != null && i < model.enumDescriptions!.length) { buffer.writeln(' /// ${model.enumDescriptions![i]}'); } final enumLine = enumType == 'integer' || enumType == 'number' ? ' $enumName($value),' : " $enumName('$value'),"; buffer.writeln(enumLine); } ... } ``` ### 阶段 2: 支持配置文件映射 ✅ 已实现配置支持: ```dart // lib/core/config_repository.dart class EnumKeyMapping { final String name; final String? description; const EnumKeyMapping({required this.name, this.description}); } class ConfigRepository { /// 获取枚举键名映射配置 /// 返回格式: { "EnumName": { value: { "name": "KEY_NAME", "description": "描述" } } } Map>? get enumKeyMappings { ... } } ``` 配置文件格式(`generator_config.yaml`): ```yaml generation: models: enum_key_mappings: SysTaskTypeEnums: - value: 1 name: SPOT_CHECK description: 抽查 - value: 2 name: CULTURAL description: 文创建设 ``` ## 实施步骤 ### Step 1: 修改数据模型 ✅ 1. 在 `ApiModel` 中添加 `enumVarNames` 和 `enumDescriptions` 字段 2. 在 `fromJson` 中解析扩展字段 ### Step 2: 修改生成逻辑 ✅ 1. 修改 `_generateEnumCodeWithoutImports` 方法 2. 实现三级优先级:配置文件 > x-enum-varnames > 智能生成 3. 支持配置文件覆盖 Swagger 文档定义 ### Step 3: 配置文件支持 ✅ 1. 在 `ConfigRepository` 中添加 `enumKeyMappings` 解析 2. 在 `SwaggerConfig` 中暴露配置 3. 在枚举生成逻辑中使用配置 4. 更新配置模板文件 ### Step 4: 文档和示例 ✅ 1. 更新使用文档 2. 提供 Swagger 文档示例 3. 提供配置文件示例 4. 创建测试配置和测试文档 ### Step 5: 测试 ✅ 1. 创建测试 Swagger 文档 2. 创建测试配置文件 3. 运行生成器验证功能 4. 确认生成的枚举键名和描述正确 ## 使用示例 ### 后端 Swagger 文档(推荐) ```json { "components": { "schemas": { "SysTaskTypeEnums": { "enum": [1, 2, 3], "type": "integer", "description": "任务类型枚举", "x-enum-varnames": ["SPOT_CHECK", "CULTURAL", "CLASS_CADRE_MEETING"], "x-enum-descriptions": ["抽查", "文创建设", "班干部会议"] } } } } ``` ### 配置文件映射(备选) ```yaml # generator_config.yaml generation: models: enum_key_mappings: SysTaskTypeEnums: 1: { name: "SPOT_CHECK", description: "抽查" } 2: { name: "CULTURAL", description: "文创建设" } 3: { name: "CLASS_CADRE_MEETING", description: "班干部会议" } ``` ### 生成结果 ```dart /// 任务类型枚举 @JsonEnum() enum SysTaskTypeEnums { /// 抽查 SPOT_CHECK(1), /// 文创建设 CULTURAL(2), /// 班干部会议 CLASS_CADRE_MEETING(3); const SysTaskTypeEnums(this.value); final int value; static SysTaskTypeEnums fromValue(dynamic value) { for (final enumValue in SysTaskTypeEnums.values) { if (enumValue.value == value) { return enumValue; } } throw ArgumentError('Unknown enum value: $value'); } factory SysTaskTypeEnums.fromJson(dynamic json) { return fromValue(json); } dynamic toJson() => value; } ``` ## 兼容性 - ✅ 向后兼容:如果没有提供扩展字段或配置,仍使用 `value1`, `value2` 等 - ✅ 灵活配置:支持全局配置或单个枚举配置 - ✅ 标准支持:使用标准的 OpenAPI 扩展字段 ## 相关资源 - [OpenAPI Extensions](https://swagger.io/docs/specification/openapi-extensions/) - [x-enum-varnames Extension](https://github.com/OpenAPITools/openapi-generator/blob/master/docs/templating.md#enum) --- **提案日期**: 2025-11-24 **状态**: 待实施 **优先级**: Medium