swagger_generator_flutter/ENUM_KEY_NAMES_PROPOSAL.md

385 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 枚举键名生成优化方案
## 问题描述
当前生成的枚举使用通用的键名(`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<String>? enumVarNames; // 新增
final List<String>? enumDescriptions; // 新增
factory ApiModel.fromJson(...) {
// 解析 x-enum-varnames
final enumVarNames = json['x-enum-varnames'] as List<dynamic>?;
final enumDescriptions = json['x-enum-descriptions'] as List<dynamic>?;
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<String, Map<dynamic, EnumKeyMapping>>? 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