12 KiB
12 KiB
枚举键名配置使用指南
功能说明
生成器支持两种方式生成有意义的枚举键名和注释:
- 通过 Swagger 扩展字段(推荐):使用 OpenAPI 扩展字段
x-enum-varnames和x-enum-descriptions - 通过配置文件映射(备选):在
generator_config.yaml中配置枚举映射
优先级:配置文件映射 > Swagger 扩展字段 > 智能生成
使用方法
方法 1: 在 Swagger 文档中添加扩展字段(推荐)
在枚举定义中添加 x-enum-varnames 和 x-enum-descriptions 字段:
{
"components": {
"schemas": {
"SysTaskTypeEnums": {
"enum": [1, 2, 3, 4, 5],
"type": "integer",
"description": "任务类型枚举",
"x-enum-varnames": [
"SPOT_CHECK",
"CULTURAL",
"CLASS_CADRE_MEETING",
"STUDENT_TALK",
"FOLLOW_CLASS"
],
"x-enum-descriptions": [
"抽查",
"文创建设",
"班干部会议",
"学生谈话",
"双师跟课"
]
}
}
}
}
生成结果
有扩展字段时:
/// 任务类型枚举
@JsonEnum()
enum SysTaskTypeEnums {
/// 抽查
SPOT_CHECK(1),
/// 文创建设
CULTURAL(2),
/// 班干部会议
CLASS_CADRE_MEETING(3),
/// 学生谈话
STUDENT_TALK(4),
/// 双师跟课
FOLLOW_CLASS(5),
/// 未知值
UNKNOWN(-9999);
const SysTaskTypeEnums(this.value);
final int value;
static SysTaskTypeEnums fromValue(dynamic value) {
for (final enumValue in SysTaskTypeEnums.values) {
if (enumValue.value == value) {
return enumValue;
}
}
return SysTaskTypeEnums.UNKNOWN;
}
factory SysTaskTypeEnums.fromJson(dynamic json) {
return fromValue(json);
}
dynamic toJson() => value;
}
没有扩展字段时(向后兼容):
/// 任务类型枚举
@JsonEnum()
enum SysTaskTypeEnums {
value1(1),
value2(2),
value3(3),
value4(4),
value5(5),
/// 未知值
UNKNOWN(-9999);
// ... 其余代码相同
}
字段说明
x-enum-varnames
- 类型:
string[] - 必需: 否
- 说明: 枚举键名列表,必须与
enum数组一一对应 - 要求: 必须是有效的 Dart 标识符(大写字母、下划线)
x-enum-descriptions
- 类型:
string[] - 必需: 否
- 说明: 枚举描述列表,必须与
enum数组一一对应 - 要求: 可以是任何字符串,会生成为注释
示例
示例 1: 整数枚举
{
"SysRoleEnum": {
"enum": [1, 2, 3, 4],
"type": "integer",
"description": "系统角色枚举",
"x-enum-varnames": ["ADMIN", "TEACHER", "STUDENT", "PARENT"],
"x-enum-descriptions": ["系统管理员", "教师", "学生", "家长"]
}
}
生成结果:
/// 系统角色枚举
@JsonEnum()
enum SysRoleEnum {
/// 系统管理员
ADMIN(1),
/// 教师
TEACHER(2),
/// 学生
STUDENT(3),
/// 家长
PARENT(4),
/// 未知值
UNKNOWN(-9999);
const SysRoleEnum(this.value);
final int value;
// ... 其余代码
}
示例 2: 字符串枚举
{
"ClassTypeEnum": {
"enum": ["PRIMARY", "MIDDLE", "HIGH"],
"type": "string",
"description": "班级类型枚举",
"x-enum-varnames": ["PRIMARY_SCHOOL", "MIDDLE_SCHOOL", "HIGH_SCHOOL"],
"x-enum-descriptions": ["小学", "初中", "高中"]
}
}
生成结果:
/// 班级类型枚举
@JsonEnum()
enum ClassTypeEnum {
/// 小学
PRIMARY_SCHOOL('PRIMARY'),
/// 初中
MIDDLE_SCHOOL('MIDDLE'),
/// 高中
HIGH_SCHOOL('HIGH'),
/// 未知值
UNKNOWN('UNKNOWN');
const ClassTypeEnum(this.value);
final String value;
// ... 其余代码
}
示例 3: 只使用 x-enum-varnames
{
"StatusEnum": {
"enum": [0, 1, 2],
"type": "integer",
"x-enum-varnames": ["PENDING", "ACTIVE", "INACTIVE"]
}
}
生成结果:
@JsonEnum()
enum StatusEnum {
PENDING(0),
ACTIVE(1),
INACTIVE(2),
/// 未知值
UNKNOWN(-9999);
// ... 代码
}
后端实现示例
.NET (Swashbuckle)
public enum SysTaskTypeEnums
{
[EnumMember(Value = "1")]
[Description("抽查")]
SPOT_CHECK = 1,
[EnumMember(Value = "2")]
[Description("文创建设")]
CULTURAL = 2,
// ... 更多枚举值
}
// 在 Startup.cs 中配置
services.AddSwaggerGen(c =>
{
c.SchemaFilter<EnumSchemaFilter>();
});
// EnumSchemaFilter.cs
public class EnumSchemaFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext context)
{
if (context.Type.IsEnum)
{
var enumNames = new List<string>();
var enumDescriptions = new List<string>();
foreach (var value in Enum.GetValues(context.Type))
{
enumNames.Add(value.ToString());
var memberInfo = context.Type.GetMember(value.ToString()).FirstOrDefault();
var descAttr = memberInfo?.GetCustomAttribute<DescriptionAttribute>();
enumDescriptions.Add(descAttr?.Description ?? "");
}
schema.Extensions["x-enum-varnames"] = new OpenApiArray();
schema.Extensions["x-enum-varnames"].AddRange(
enumNames.Select(n => new OpenApiString(n))
);
schema.Extensions["x-enum-descriptions"] = new OpenApiArray();
schema.Extensions["x-enum-descriptions"].AddRange(
enumDescriptions.Select(d => new OpenApiString(d))
);
}
}
}
Java (SpringDoc/Swagger)
@Schema(description = "任务类型枚举")
public enum SysTaskTypeEnums {
@Schema(description = "抽查")
SPOT_CHECK(1),
@Schema(description = "文创建设")
CULTURAL(2),
// ... 更多枚举值
private final int value;
SysTaskTypeEnums(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
// 配置 SchemaCustomizer
@Bean
public OpenApiCustomizer enumCustomizer() {
return openApi -> {
openApi.getComponents().getSchemas().forEach((name, schema) -> {
if (schema.getEnum() != null) {
try {
Class<?> enumClass = Class.forName("com.example.enums." + name);
if (enumClass.isEnum()) {
List<String> varNames = new ArrayList<>();
List<String> descriptions = new ArrayList<>();
for (Object constant : enumClass.getEnumConstants()) {
varNames.add(constant.toString());
Field field = enumClass.getField(constant.toString());
Schema annotation = field.getAnnotation(Schema.class);
descriptions.add(annotation != null ? annotation.description() : "");
}
schema.addExtension("x-enum-varnames", varNames);
schema.addExtension("x-enum-descriptions", descriptions);
}
} catch (Exception e) {
// Handle exception
}
}
});
};
}
注意事项
-
数组长度必须匹配:
x-enum-varnames的长度必须与enum数组长度相同x-enum-descriptions的长度必须与enum数组长度相同
-
键名命名规范:
- 使用大写字母和下划线(UPPER_SNAKE_CASE)
- 必须是有效的 Dart 标识符
- 不能以数字开头
- 不能使用 Dart 关键字
-
向后兼容:
- 如果没有提供扩展字段,会自动生成
value1,value2等 - 不影响现有项目
- 如果没有提供扩展字段,会自动生成
-
OpenAPI 标准:
x-前缀表示扩展字段,符合 OpenAPI 规范- 不会影响其他工具对 Swagger 文档的解析
相关资源
常见问题
Q: 如果只提供部分枚举值的键名怎么办?
A: 系统会检查索引是否在范围内。如果某个枚举值没有对应的键名,会使用默认的 valueN 格式。
Q: 可以混用中文和英文吗?
A: x-enum-varnames 必须是有效的 Dart 标识符(推荐使用英文大写+下划线)。
x-enum-descriptions 可以使用任何语言,会生成为注释。
Q: 后端不支持怎么办?
A: 可以:
- 使用配置文件映射(推荐):在
generator_config.yaml中配置枚举映射 - 在生成的 Swagger JSON 文件中手动添加扩展字段
- 使用中间处理脚本添加扩展字段
- 暂时接受
value1,value2的命名方式
方法 2: 通过配置文件映射(备选)
如果后端不支持 x-enum-varnames 扩展字段,或者您需要覆盖 Swagger 文档中的枚举定义,可以使用配置文件映射。
配置方式
在 generator_config.yaml 中添加 enum_key_mappings 配置:
generation:
models:
# 枚举键名映射配置
enum_key_mappings:
SysTaskTypeEnums:
- value: 1
name: SPOT_CHECK
description: 抽查
- value: 2
name: CULTURAL
description: 文创建设
- value: 3
name: CLASS_CADRE_MEETING
description: 班干部会议
SysRoleEnum:
- value: 1
name: ADMIN
description: 系统管理员
- value: 2
name: TEACHER
description: 教师
- value: 3
name: STUDENT
description: 学生
StatusEnum:
- value: "active"
name: ACTIVE
description: 活跃状态
- value: "inactive"
name: INACTIVE
description: 非活跃状态
配置说明
- 枚举名称: 必须与 Swagger 文档中的枚举名称完全匹配
- value: 枚举值,可以是数字或字符串,必须与 Swagger 文档中的枚举值匹配
- name: 枚举键名,必须是有效的 Dart 标识符(大写字母+下划线)
- description: 枚举描述(可选),会生成为注释
生成结果
使用上述配置后,生成的代码:
/// 任务类型枚举
@JsonEnum()
enum SysTaskTypeEnums {
/// 抽查
SPOT_CHECK(1),
/// 文创建设
CULTURAL(2),
/// 班干部会议
CLASS_CADRE_MEETING(3);
const SysTaskTypeEnums(this.value);
final int value;
// ... 其余代码
}
优先级说明
如果同时存在配置文件映射和 Swagger 扩展字段,优先级为:
- 配置文件映射(最高优先级)
- x-enum-varnames 扩展字段
- 智能生成
valueN格式
这意味着您可以使用配置文件来覆盖 Swagger 文档中的枚举定义。
使用场景
配置文件映射适用于以下场景:
- ✅ 后端不支持 OpenAPI 扩展字段
- ✅ 需要快速修改枚举键名,无需等待后端修改
- ✅ 需要临时覆盖 Swagger 文档中的枚举定义
- ✅ 团队内部统一枚举命名规范
- ✅ 多个项目共享同一个 Swagger 文档,但需要不同的枚举键名
注意事项
- 维护成本: 配置文件需要手动维护,当后端枚举值变化时需要同步更新
- 推荐方式: 如果后端支持,仍然推荐使用 Swagger 扩展字段,保持单一数据源
- 部分映射: 您可以只为部分枚举值配置映射,未配置的枚举值会使用智能生成
更新日期: 2025-11-24
版本: v2.0