Merge branch 'release/3.1.2'
This commit is contained in:
commit
25b0831ddd
|
|
@ -19,7 +19,8 @@ input:
|
||||||
enabled: true
|
enabled: true
|
||||||
- url: "http://192.168.2.7:17288/swagger/v2/swagger.json"
|
- url: "http://192.168.2.7:17288/swagger/v2/swagger.json"
|
||||||
enabled: true
|
enabled: true
|
||||||
|
- url: "http://192.168.2.7:17288/swagger/v3/swagger.json"
|
||||||
|
enabled: true
|
||||||
# 验证配置
|
# 验证配置
|
||||||
validate_schema: true
|
validate_schema: true
|
||||||
strict_mode: false
|
strict_mode: false
|
||||||
|
|
|
||||||
|
|
@ -558,7 +558,7 @@ packages:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "3.0.0"
|
version: "3.1.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
||||||
|
|
@ -298,22 +298,22 @@ class ConfigRepository {
|
||||||
final generation = _config['generation'] as Map<String, dynamic>?;
|
final generation = _config['generation'] as Map<String, dynamic>?;
|
||||||
final models = generation?['models'] as Map<String, dynamic>?;
|
final models = generation?['models'] as Map<String, dynamic>?;
|
||||||
final mappings = models?['enum_key_mappings'] as Map<String, dynamic>?;
|
final mappings = models?['enum_key_mappings'] as Map<String, dynamic>?;
|
||||||
|
|
||||||
if (mappings == null) return null;
|
if (mappings == null) return null;
|
||||||
|
|
||||||
final result = <String, Map<dynamic, EnumKeyMapping>>{};
|
final result = <String, Map<dynamic, EnumKeyMapping>>{};
|
||||||
|
|
||||||
mappings.forEach((enumName, enumMappings) {
|
mappings.forEach((enumName, enumMappings) {
|
||||||
if (enumMappings is! List) return;
|
if (enumMappings is! List) return;
|
||||||
|
|
||||||
final valueMap = <dynamic, EnumKeyMapping>{};
|
final valueMap = <dynamic, EnumKeyMapping>{};
|
||||||
for (final mapping in enumMappings) {
|
for (final mapping in enumMappings) {
|
||||||
if (mapping is! Map) continue;
|
if (mapping is! Map) continue;
|
||||||
|
|
||||||
final value = mapping['value'];
|
final value = mapping['value'];
|
||||||
final name = mapping['name'] as String?;
|
final name = mapping['name'] as String?;
|
||||||
final description = mapping['description'] as String?;
|
final description = mapping['description'] as String?;
|
||||||
|
|
||||||
if (value != null && name != null) {
|
if (value != null && name != null) {
|
||||||
valueMap[value] = EnumKeyMapping(
|
valueMap[value] = EnumKeyMapping(
|
||||||
name: name,
|
name: name,
|
||||||
|
|
@ -321,12 +321,12 @@ class ConfigRepository {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueMap.isNotEmpty) {
|
if (valueMap.isNotEmpty) {
|
||||||
result[enumName.toString()] = valueMap;
|
result[enumName] = valueMap;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.isEmpty ? null : result;
|
return result.isEmpty ? null : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,11 +115,16 @@ class ApiParameter {
|
||||||
this.format,
|
this.format,
|
||||||
this.example,
|
this.example,
|
||||||
this.defaultValue,
|
this.defaultValue,
|
||||||
|
this.schemaRef,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// 从JSON创建ApiParameter
|
/// 从JSON创建ApiParameter
|
||||||
factory ApiParameter.fromJson(Map<String, dynamic> json) {
|
factory ApiParameter.fromJson(Map<String, dynamic> json) {
|
||||||
final schema = json['schema'] as Map<String, dynamic>?;
|
final schema = json['schema'] as Map<String, dynamic>?;
|
||||||
|
|
||||||
|
// 检查是否有 $ref 引用
|
||||||
|
final schemaRef = schema?[r'$ref'] as String?;
|
||||||
|
|
||||||
final type =
|
final type =
|
||||||
schema?['type'] as String? ?? json['type'] as String? ?? 'string';
|
schema?['type'] as String? ?? json['type'] as String? ?? 'string';
|
||||||
|
|
||||||
|
|
@ -132,6 +137,7 @@ class ApiParameter {
|
||||||
format: schema?['format'] as String? ?? json['format'] as String?,
|
format: schema?['format'] as String? ?? json['format'] as String?,
|
||||||
example: json['example'],
|
example: json['example'],
|
||||||
defaultValue: schema?['default'] ?? json['default'],
|
defaultValue: schema?['default'] ?? json['default'],
|
||||||
|
schemaRef: schemaRef,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
final String name;
|
final String name;
|
||||||
|
|
@ -142,6 +148,9 @@ class ApiParameter {
|
||||||
final String? format;
|
final String? format;
|
||||||
final dynamic example;
|
final dynamic example;
|
||||||
final dynamic defaultValue;
|
final dynamic defaultValue;
|
||||||
|
|
||||||
|
/// Schema 引用 (如 #/components/schemas/SysTaskTypeEnums)
|
||||||
|
final String? schemaRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// API响应信息 (OpenAPI 3.0)
|
/// API响应信息 (OpenAPI 3.0)
|
||||||
|
|
|
||||||
|
|
@ -371,7 +371,7 @@ class ApiModel {
|
||||||
final isEnum = json['enum'] != null;
|
final isEnum = json['enum'] != null;
|
||||||
final enumValues =
|
final enumValues =
|
||||||
isEnum ? (json['enum'] as List<dynamic>?) ?? <dynamic>[] : <dynamic>[];
|
isEnum ? (json['enum'] as List<dynamic>?) ?? <dynamic>[] : <dynamic>[];
|
||||||
|
|
||||||
// 解析 OpenAPI 扩展字段:x-enum-varnames 和 x-enum-descriptions
|
// 解析 OpenAPI 扩展字段:x-enum-varnames 和 x-enum-descriptions
|
||||||
final enumVarNames = json['x-enum-varnames'] != null
|
final enumVarNames = json['x-enum-varnames'] != null
|
||||||
? (json['x-enum-varnames'] as List<dynamic>?)
|
? (json['x-enum-varnames'] as List<dynamic>?)
|
||||||
|
|
@ -466,11 +466,11 @@ class ApiModel {
|
||||||
final bool isEnum;
|
final bool isEnum;
|
||||||
final List<dynamic> enumValues;
|
final List<dynamic> enumValues;
|
||||||
final PropertyType? enumType;
|
final PropertyType? enumType;
|
||||||
|
|
||||||
/// OpenAPI extension: x-enum-varnames
|
/// OpenAPI extension: x-enum-varnames
|
||||||
/// 枚举键名列表,与 enumValues 一一对应
|
/// 枚举键名列表,与 enumValues 一一对应
|
||||||
final List<String>? enumVarNames;
|
final List<String>? enumVarNames;
|
||||||
|
|
||||||
/// OpenAPI extension: x-enum-descriptions
|
/// OpenAPI extension: x-enum-descriptions
|
||||||
/// 枚举描述列表,与 enumValues 一一对应
|
/// 枚举描述列表,与 enumValues 一一对应
|
||||||
final List<String>? enumDescriptions;
|
final List<String>? enumDescriptions;
|
||||||
|
|
|
||||||
|
|
@ -30,10 +30,10 @@ String _generateEnumCodeWithoutImports(ApiModel model) {
|
||||||
|
|
||||||
for (var i = 0; i < model.enumValues.length; i++) {
|
for (var i = 0; i < model.enumValues.length; i++) {
|
||||||
final value = model.enumValues[i];
|
final value = model.enumValues[i];
|
||||||
|
|
||||||
String enumName;
|
String enumName;
|
||||||
String? description;
|
String? description;
|
||||||
|
|
||||||
// 优先级 1: 配置文件映射
|
// 优先级 1: 配置文件映射
|
||||||
if (enumMappings != null && enumMappings.containsKey(value)) {
|
if (enumMappings != null && enumMappings.containsKey(value)) {
|
||||||
final mapping = enumMappings[value]!;
|
final mapping = enumMappings[value]!;
|
||||||
|
|
@ -44,7 +44,8 @@ String _generateEnumCodeWithoutImports(ApiModel model) {
|
||||||
else if (model.enumVarNames != null && i < model.enumVarNames!.length) {
|
else if (model.enumVarNames != null && i < model.enumVarNames!.length) {
|
||||||
enumName = model.enumVarNames![i];
|
enumName = model.enumVarNames![i];
|
||||||
// 使用 x-enum-descriptions
|
// 使用 x-enum-descriptions
|
||||||
if (model.enumDescriptions != null && i < model.enumDescriptions!.length) {
|
if (model.enumDescriptions != null &&
|
||||||
|
i < model.enumDescriptions!.length) {
|
||||||
description = model.enumDescriptions![i];
|
description = model.enumDescriptions![i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -52,12 +53,12 @@ String _generateEnumCodeWithoutImports(ApiModel model) {
|
||||||
else {
|
else {
|
||||||
enumName = StringHelper.generateEnumValueName(value, i);
|
enumName = StringHelper.generateEnumValueName(value, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加描述注释
|
// 添加描述注释
|
||||||
if (description != null && description.isNotEmpty) {
|
if (description != null && description.isNotEmpty) {
|
||||||
buffer.writeln(' /// $description');
|
buffer.writeln(' /// $description');
|
||||||
}
|
}
|
||||||
|
|
||||||
final enumLine = enumType == 'integer' || enumType == 'number'
|
final enumLine = enumType == 'integer' || enumType == 'number'
|
||||||
? ' $enumName($value),'
|
? ' $enumName($value),'
|
||||||
: " $enumName('$value'),";
|
: " $enumName('$value'),";
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ mixin RetrofitApiParameterEntities {
|
||||||
..writeln('class $className {');
|
..writeln('class $className {');
|
||||||
for (final param in queryParams) {
|
for (final param in queryParams) {
|
||||||
final dartName = StringHelper.toDartPropertyName(param.name);
|
final dartName = StringHelper.toDartPropertyName(param.name);
|
||||||
final dartType = _g._getDartType(param.type);
|
final dartType = _g._getDartTypeForParameter(param);
|
||||||
final nullable = param.required ? '' : '?';
|
final nullable = param.required ? '' : '?';
|
||||||
|
|
||||||
final cleanDescription = param.description
|
final cleanDescription = param.description
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,37 @@ mixin RetrofitApiParameters {
|
||||||
|
|
||||||
String _getDartType(PropertyType type) => _typeMap[type] ?? 'dynamic';
|
String _getDartType(PropertyType type) => _typeMap[type] ?? 'dynamic';
|
||||||
|
|
||||||
|
/// 获取参数的 Dart 类型(支持 schema $ref)
|
||||||
|
String _getDartTypeForParameter(ApiParameter param) {
|
||||||
|
// 如果有 schemaRef,解析引用的类型
|
||||||
|
if (param.schemaRef != null) {
|
||||||
|
final refName = param.schemaRef!.split('/').last;
|
||||||
|
|
||||||
|
// 检查引用的 schema 是否是枚举类型
|
||||||
|
final refModel = _g.document.models[refName];
|
||||||
|
if (refModel != null) {
|
||||||
|
// 如果引用的是枚举类型,返回枚举的基础类型
|
||||||
|
if (refModel.isEnum && refModel.type != null) {
|
||||||
|
switch (refModel.type) {
|
||||||
|
case 'integer':
|
||||||
|
return 'int';
|
||||||
|
case 'number':
|
||||||
|
return 'double';
|
||||||
|
case 'string':
|
||||||
|
return 'String';
|
||||||
|
default:
|
||||||
|
return 'String';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果是其他引用类型,返回类名
|
||||||
|
return StringHelper.generateClassName(refName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则使用默认的类型映射
|
||||||
|
return _getDartType(param.type);
|
||||||
|
}
|
||||||
|
|
||||||
/// 检查是否需要请求体
|
/// 检查是否需要请求体
|
||||||
bool _needsRequestBody(ApiPath path) {
|
bool _needsRequestBody(ApiPath path) {
|
||||||
if (path.requestBody != null) {
|
if (path.requestBody != null) {
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,8 @@ class ReferenceResolver {
|
||||||
/// 解析枚举模型
|
/// 解析枚举模型
|
||||||
ApiModel _parseEnumModel(String name, Map<String, dynamic> json) {
|
ApiModel _parseEnumModel(String name, Map<String, dynamic> json) {
|
||||||
final enumValues = List<dynamic>.from((json['enum'] as List?) ?? []);
|
final enumValues = List<dynamic>.from((json['enum'] as List?) ?? []);
|
||||||
final enumType =
|
final type = json['type'] as String?;
|
||||||
PropertyType.fromString(json['type'] as String? ?? 'string');
|
final enumType = PropertyType.fromString(type ?? 'string');
|
||||||
|
|
||||||
return ApiModel(
|
return ApiModel(
|
||||||
name: name,
|
name: name,
|
||||||
|
|
@ -141,6 +141,7 @@ class ReferenceResolver {
|
||||||
isEnum: true,
|
isEnum: true,
|
||||||
enumValues: enumValues,
|
enumValues: enumValues,
|
||||||
enumType: enumType,
|
enumType: enumType,
|
||||||
|
type: type,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,17 +21,46 @@ class NamingConverter {
|
||||||
final parts = input.split('_').where((p) => p.isNotEmpty).toList();
|
final parts = input.split('_').where((p) => p.isNotEmpty).toList();
|
||||||
if (parts.isEmpty) return input;
|
if (parts.isEmpty) return input;
|
||||||
|
|
||||||
var result = parts.first.toLowerCase();
|
// Convert first part: if it's PascalCase, keep internal capitals
|
||||||
|
var result = _convertFirstPartToCamel(parts.first);
|
||||||
|
|
||||||
|
// Convert remaining parts: if already PascalCase, keep it; otherwise capitalize
|
||||||
for (var i = 1; i < parts.length; i++) {
|
for (var i = 1; i < parts.length; i++) {
|
||||||
final part = parts[i];
|
final part = parts[i];
|
||||||
if (part.isNotEmpty) {
|
if (part.isNotEmpty) {
|
||||||
result += part[0].toUpperCase() + part.substring(1).toLowerCase();
|
result += _convertPartToPascal(part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.isEmpty ? input : result;
|
return result.isEmpty ? input : result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert the first part to camelCase (preserve internal capitals)
|
||||||
|
static String _convertFirstPartToCamel(String part) {
|
||||||
|
if (part.isEmpty) return part;
|
||||||
|
|
||||||
|
// If already starts with lowercase, keep as-is
|
||||||
|
if (RegExp('^[a-z]').hasMatch(part)) {
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If PascalCase (starts with uppercase), just lowercase first letter
|
||||||
|
return part[0].toLowerCase() + part.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert a part to PascalCase (preserve internal capitals)
|
||||||
|
static String _convertPartToPascal(String part) {
|
||||||
|
if (part.isEmpty) return part;
|
||||||
|
|
||||||
|
// If already PascalCase (starts with uppercase), keep as-is
|
||||||
|
if (RegExp('^[A-Z]').hasMatch(part)) {
|
||||||
|
return part;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If starts with lowercase, capitalize first letter
|
||||||
|
return part[0].toUpperCase() + part.substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
/// Convert to PascalCase
|
/// Convert to PascalCase
|
||||||
static String toPascalCase(String input) {
|
static String toPascalCase(String input) {
|
||||||
if (input.isEmpty) return input;
|
if (input.isEmpty) return input;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,660 @@
|
||||||
|
{
|
||||||
|
"openapi": "3.0.1",
|
||||||
|
"info": {
|
||||||
|
"title": "OA移动端Api",
|
||||||
|
"version": "v3"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/api/v3/WorkStatistics/TestImToMQ": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "testIM",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "imToUserId",
|
||||||
|
"in": "query",
|
||||||
|
"description": "",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v3/WorkStatistics/WorkDataStatisticsCount": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "工作数量数据统计",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "BeginTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "开始时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EndTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "结束时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataStatisticsCountViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataStatisticsCountViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text/json": {
|
||||||
|
"schema": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataStatisticsCountViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v3/WorkStatistics/CloudSchoolWorkDataStatistics": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "各云校统计(总部长才有)",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "TaskTypeEnum",
|
||||||
|
"in": "query",
|
||||||
|
"description": "任务类型枚举",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BeginTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "开始时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EndTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "结束时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CloudSchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CloudSchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/CloudSchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v3/WorkStatistics/SchoolWorkDataStatistics": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "学校统计",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "TaskTypeEnum",
|
||||||
|
"in": "query",
|
||||||
|
"description": "任务类型枚举",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SeacherKey",
|
||||||
|
"in": "query",
|
||||||
|
"description": "学校名称搜索",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "CloudSchoolId",
|
||||||
|
"in": "query",
|
||||||
|
"description": "总部长统计页面-各云校统计页面跳转需要传",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BeginTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "开始时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EndTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "结束时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SchoolWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v3/WorkStatistics/LearningOfficerWorkDataStatistics": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "学习官统计",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "TaskTypeEnum",
|
||||||
|
"in": "query",
|
||||||
|
"description": "任务类型枚举",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SeacherKey",
|
||||||
|
"in": "query",
|
||||||
|
"description": "学习官名称搜索",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "SchoolId",
|
||||||
|
"in": "query",
|
||||||
|
"description": "学校ID",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BeginTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "开始时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EndTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "结束时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/LearningOfficerWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/LearningOfficerWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/LearningOfficerWorkDataStatisticsViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v3/WorkStatistics/WorkDataDetailsStatistics": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"WorkStatistics"
|
||||||
|
],
|
||||||
|
"summary": "统计详细",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "TaskTypeEnum",
|
||||||
|
"in": "query",
|
||||||
|
"description": "任务类型枚举",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UserId",
|
||||||
|
"in": "query",
|
||||||
|
"description": "学习官ID",
|
||||||
|
"schema": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "BeginTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "开始时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "EndTime",
|
||||||
|
"in": "query",
|
||||||
|
"description": "结束时间 格式 yyyy-MM-dd",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time",
|
||||||
|
"nullable": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"content": {
|
||||||
|
"text/plain": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataDetailsStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataDetailsStatisticsViewDto"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"text/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataDetailsStatisticsViewDto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"CloudSchoolWorkDataStatisticsDetailsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"cloudSchoolName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "云校名称"
|
||||||
|
},
|
||||||
|
"cloudSchoolId": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "云校ID",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"workCount": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "工作数量",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"CloudSchoolWorkDataStatisticsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"taskTypeEnum": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
},
|
||||||
|
"taskTypeName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "任务类型中文"
|
||||||
|
},
|
||||||
|
"beginTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计开始时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计结束时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/CloudSchoolWorkDataStatisticsDetailsViewDto"
|
||||||
|
},
|
||||||
|
"description": "云校数据"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"LearningOfficerWorkDataStatisticsDetailsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"userId": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "学习官ID",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"realName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "学习官名称"
|
||||||
|
},
|
||||||
|
"workCount": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "工作数量",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"LearningOfficerWorkDataStatisticsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"taskTypeEnum": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
},
|
||||||
|
"taskTypeName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "任务类型中文"
|
||||||
|
},
|
||||||
|
"beginTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计开始时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计结束时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"schoolName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "学校名称"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/LearningOfficerWorkDataStatisticsDetailsViewDto"
|
||||||
|
},
|
||||||
|
"description": "学习官统计数据"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"SchoolWorkDataStatisticsDetailsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"schoolName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "学校名称"
|
||||||
|
},
|
||||||
|
"schoolId": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "学校ID",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"workCount": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "工作数量",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"SchoolWorkDataStatisticsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"taskTypeEnum": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
},
|
||||||
|
"taskTypeName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "任务类型中文"
|
||||||
|
},
|
||||||
|
"beginTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计开始时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计结束时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"cloudSchoolName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "云校名称"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/SchoolWorkDataStatisticsDetailsViewDto"
|
||||||
|
},
|
||||||
|
"description": "学校统计数据"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"SysTaskTypeEnums": {
|
||||||
|
"enum": [
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
10,
|
||||||
|
11,
|
||||||
|
12,
|
||||||
|
13
|
||||||
|
],
|
||||||
|
"type": "integer",
|
||||||
|
"description": "任务类型枚举",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"WorkDataDetailsStatisticsDetailsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "任务ID",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"classesId": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "备 注:班级id(班级任务)\r\n默认值:",
|
||||||
|
"format": "int64",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"classesName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "备 注:班级名称(班级任务)\r\n默认值:",
|
||||||
|
"nullable": true
|
||||||
|
},
|
||||||
|
"startTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "备 注:任务开始时间\r\n默认值:",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "备 注:任务结束时间\r\n默认值:",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"taskTitleSuffix": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "备 注:任务标题后缀,用于展示\r\n默认值:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"WorkDataDetailsStatisticsViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"taskTypeEnum": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
},
|
||||||
|
"taskTypeName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "任务类型中文"
|
||||||
|
},
|
||||||
|
"beginTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计开始时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"endTime": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "统计结束时间 格式yyyy-MM-dd"
|
||||||
|
},
|
||||||
|
"realName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "学习官名称-统计对象"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/WorkDataDetailsStatisticsDetailsViewDto"
|
||||||
|
},
|
||||||
|
"description": "任务详细"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false
|
||||||
|
},
|
||||||
|
"WorkDataStatisticsCountViewDto": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"taskTypeEnum": {
|
||||||
|
"$ref": "#/components/schemas/SysTaskTypeEnums"
|
||||||
|
},
|
||||||
|
"taskTypeName": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "任务类型中文"
|
||||||
|
},
|
||||||
|
"workCount": {
|
||||||
|
"type": "integer",
|
||||||
|
"description": "工作数量",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"description": "工作数量数据统计结果"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {
|
||||||
|
"Bearer": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"description": "在下框中输入请求头中需要添加Jwt授权Token:Bearer {Token},注意中间有空格",
|
||||||
|
"name": "Authorization",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"Bearer": [ ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "WorkStatistics",
|
||||||
|
"description": "学习官基础工作统计"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
// 测试枚举参数生成
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
|
import 'package:swagger_generator_flutter/pipeline/parse/swagger_data_parser.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('枚举参数生成测试', () {
|
||||||
|
test('TaskTypeEnum 应该生成为 int 类型而不是 String', () async {
|
||||||
|
// 模拟 swagger_v3.json 中的结构
|
||||||
|
final swaggerJson = {
|
||||||
|
'openapi': '3.0.1',
|
||||||
|
'info': {
|
||||||
|
'title': 'Test API',
|
||||||
|
'version': '1.0',
|
||||||
|
},
|
||||||
|
'paths': {
|
||||||
|
'/api/v3/WorkStatistics/CloudSchoolWorkDataStatistics': {
|
||||||
|
'get': {
|
||||||
|
'tags': ['WorkStatistics'],
|
||||||
|
'summary': '各云校统计',
|
||||||
|
'parameters': [
|
||||||
|
{
|
||||||
|
'name': 'TaskTypeEnum',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '任务类型枚举',
|
||||||
|
'schema': {
|
||||||
|
r'$ref': '#/components/schemas/SysTaskTypeEnums',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'responses': {
|
||||||
|
'200': {
|
||||||
|
'description': 'Success',
|
||||||
|
'content': {
|
||||||
|
'application/json': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'components': {
|
||||||
|
'schemas': {
|
||||||
|
'SysTaskTypeEnums': {
|
||||||
|
'enum': [1, 2, 3, 4, 5],
|
||||||
|
'type': 'integer',
|
||||||
|
'description': '任务类型枚举',
|
||||||
|
'format': 'int32',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 解析 Swagger 文档
|
||||||
|
final parser = SwaggerDataParser();
|
||||||
|
final document = await parser.parseSwaggerDocument(
|
||||||
|
swaggerJson,
|
||||||
|
'test.json',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 验证参数解析
|
||||||
|
final path = document.paths.values.first;
|
||||||
|
expect(path.parameters.length, 1);
|
||||||
|
|
||||||
|
final param = path.parameters.first;
|
||||||
|
expect(param.name, 'TaskTypeEnum');
|
||||||
|
expect(param.schemaRef, '#/components/schemas/SysTaskTypeEnums');
|
||||||
|
|
||||||
|
// 打印调试信息
|
||||||
|
print('Available models: ${document.models.keys.toList()}');
|
||||||
|
|
||||||
|
// 验证 SysTaskTypeEnums 模型
|
||||||
|
final enumModel = document.models['SysTaskTypeEnums'];
|
||||||
|
if (enumModel != null) {
|
||||||
|
print('EnumModel type: ${enumModel.type}');
|
||||||
|
print('EnumModel isEnum: ${enumModel.isEnum}');
|
||||||
|
print('EnumModel enumValues: ${enumModel.enumValues}');
|
||||||
|
expect(enumModel.type, 'integer');
|
||||||
|
expect(enumModel.isEnum, true);
|
||||||
|
expect(enumModel.enumValues, [1, 2, 3, 4, 5]);
|
||||||
|
} else {
|
||||||
|
print('WARNING: SysTaskTypeEnums model not found!');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ void main() {
|
||||||
group('BasePageResult 包裹逻辑测试', () {
|
group('BasePageResult 包裹逻辑测试', () {
|
||||||
test('应该识别包含 total 和 items 的分页响应模型', () {
|
test('应该识别包含 total 和 items 的分页响应模型', () {
|
||||||
// 创建一个包含 total 和 items 的模型
|
// 创建一个包含 total 和 items 的模型
|
||||||
final paginationModel = ApiModel(
|
const paginationModel = ApiModel(
|
||||||
name: 'SuperiorTaskListResultPageResponse',
|
name: 'SuperiorTaskListResultPageResponse',
|
||||||
description: '分页响应实体类',
|
description: '分页响应实体类',
|
||||||
properties: {
|
properties: {
|
||||||
|
|
@ -59,7 +59,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('分页模型的 items 类型应该被正确提取', () {
|
test('分页模型的 items 类型应该被正确提取', () {
|
||||||
final itemsProperty = ApiProperty(
|
const itemsProperty = ApiProperty(
|
||||||
name: 'items',
|
name: 'items',
|
||||||
type: PropertyType.array,
|
type: PropertyType.array,
|
||||||
description: '数据列表',
|
description: '数据列表',
|
||||||
|
|
@ -77,7 +77,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('非分页模型不应该被识别为分页模型', () {
|
test('非分页模型不应该被识别为分页模型', () {
|
||||||
final normalModel = ApiModel(
|
const normalModel = ApiModel(
|
||||||
name: 'NormalResult',
|
name: 'NormalResult',
|
||||||
description: '普通响应',
|
description: '普通响应',
|
||||||
properties: {
|
properties: {
|
||||||
|
|
@ -121,4 +121,3 @@ void main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// 测试参数 schema $ref 解析
|
||||||
|
import 'package:swagger_generator_flutter/core/models.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group(r'ApiParameter $ref 解析测试', () {
|
||||||
|
test(r'应该正确解析带有 $ref 的参数', () {
|
||||||
|
final json = {
|
||||||
|
'name': 'TaskTypeEnum',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '任务类型枚举',
|
||||||
|
'schema': {
|
||||||
|
r'$ref': '#/components/schemas/SysTaskTypeEnums',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
final param = ApiParameter.fromJson(json);
|
||||||
|
|
||||||
|
expect(param.name, 'TaskTypeEnum');
|
||||||
|
expect(param.schemaRef, '#/components/schemas/SysTaskTypeEnums');
|
||||||
|
expect(param.description, '任务类型枚举');
|
||||||
|
});
|
||||||
|
|
||||||
|
test(r'应该正确解析没有 $ref 的普通参数', () {
|
||||||
|
final json = {
|
||||||
|
'name': 'pageSize',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '页面大小',
|
||||||
|
'schema': {
|
||||||
|
'type': 'integer',
|
||||||
|
'format': 'int32',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
final param = ApiParameter.fromJson(json);
|
||||||
|
|
||||||
|
expect(param.name, 'pageSize');
|
||||||
|
expect(param.schemaRef, isNull);
|
||||||
|
expect(param.type, PropertyType.integer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
// 集成测试:参数类型生成
|
||||||
|
import 'package:swagger_generator_flutter/pipeline/parse/swagger_data_parser.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('参数类型生成集成测试', () {
|
||||||
|
test('枚举类型的参数应该生成正确的 Dart 类型', () async {
|
||||||
|
// 模拟完整的 swagger 文档
|
||||||
|
final swaggerJson = {
|
||||||
|
'openapi': '3.0.1',
|
||||||
|
'info': {
|
||||||
|
'title': 'Test API',
|
||||||
|
'version': '1.0',
|
||||||
|
},
|
||||||
|
'paths': {
|
||||||
|
'/api/v3/WorkStatistics/CloudSchoolWorkDataStatistics': {
|
||||||
|
'get': {
|
||||||
|
'tags': ['WorkStatistics'],
|
||||||
|
'summary': '各云校统计',
|
||||||
|
'operationId': 'WorkStatistics_CloudSchoolWorkDataStatistics',
|
||||||
|
'parameters': [
|
||||||
|
{
|
||||||
|
'name': 'TaskTypeEnum',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '任务类型枚举',
|
||||||
|
'schema': {
|
||||||
|
r'$ref': '#/components/schemas/SysTaskTypeEnums',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'PageSize',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '页面大小',
|
||||||
|
'schema': {
|
||||||
|
'type': 'integer',
|
||||||
|
'format': 'int32',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'SearchKey',
|
||||||
|
'in': 'query',
|
||||||
|
'description': '搜索关键字',
|
||||||
|
'schema': {
|
||||||
|
'type': 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'responses': {
|
||||||
|
'200': {
|
||||||
|
'description': 'Success',
|
||||||
|
'content': {
|
||||||
|
'application/json': {
|
||||||
|
'schema': {
|
||||||
|
'type': 'object',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'components': {
|
||||||
|
'schemas': {
|
||||||
|
'SysTaskTypeEnums': {
|
||||||
|
'enum': [1, 2, 3, 4, 5, 6],
|
||||||
|
'type': 'integer',
|
||||||
|
'description': '任务类型枚举',
|
||||||
|
'format': 'int32',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// 解析文档
|
||||||
|
final parser = SwaggerDataParser();
|
||||||
|
final document = await parser.parseSwaggerDocument(
|
||||||
|
swaggerJson,
|
||||||
|
'test.json',
|
||||||
|
);
|
||||||
|
|
||||||
|
// 获取参数
|
||||||
|
final path = document.paths.values.first;
|
||||||
|
final params = path.parameters;
|
||||||
|
|
||||||
|
expect(params.length, 3);
|
||||||
|
|
||||||
|
// 验证 TaskTypeEnum 参数
|
||||||
|
final taskTypeParam = params.firstWhere((p) => p.name == 'TaskTypeEnum');
|
||||||
|
expect(taskTypeParam.schemaRef, '#/components/schemas/SysTaskTypeEnums');
|
||||||
|
|
||||||
|
// 使用生成器的方法获取 Dart 类型
|
||||||
|
// 注意: 这里我们需要通过反射或公开方法来测试
|
||||||
|
// 由于 _getDartTypeForParameter 是私有的,我们通过间接方式验证
|
||||||
|
|
||||||
|
// 验证枚举模型存在且类型正确
|
||||||
|
final enumModel = document.models['SysTaskTypeEnums'];
|
||||||
|
expect(enumModel, isNotNull);
|
||||||
|
expect(enumModel!.type, 'integer');
|
||||||
|
expect(enumModel.isEnum, true);
|
||||||
|
|
||||||
|
print('✅ 枚举参数解析正确');
|
||||||
|
print(' - TaskTypeEnum 引用: ${taskTypeParam.schemaRef}');
|
||||||
|
print(' - 枚举模型类型: ${enumModel.type}');
|
||||||
|
print(' - 应该生成为: int (而不是 String)');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -7,7 +7,7 @@ void main() {
|
||||||
test('removes newlines from text', () {
|
test('removes newlines from text', () {
|
||||||
const input = '部长新增工作任务指标\n(会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)';
|
const input = '部长新增工作任务指标\n(会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, isNot(contains('\n')));
|
expect(result, isNot(contains('\n')));
|
||||||
expect(result, isNot(contains('\r')));
|
expect(result, isNot(contains('\r')));
|
||||||
expect(result, '部长新增工作任务指标 (会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)');
|
expect(result, '部长新增工作任务指标 (会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)');
|
||||||
|
|
@ -16,7 +16,7 @@ void main() {
|
||||||
test('removes carriage returns from text', () {
|
test('removes carriage returns from text', () {
|
||||||
const input = 'Line 1\r\nLine 2\rLine 3';
|
const input = 'Line 1\r\nLine 2\rLine 3';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, isNot(contains('\n')));
|
expect(result, isNot(contains('\n')));
|
||||||
expect(result, isNot(contains('\r')));
|
expect(result, isNot(contains('\r')));
|
||||||
expect(result, 'Line 1 Line 2 Line 3');
|
expect(result, 'Line 1 Line 2 Line 3');
|
||||||
|
|
@ -25,42 +25,42 @@ void main() {
|
||||||
test('replaces multiple spaces with single space', () {
|
test('replaces multiple spaces with single space', () {
|
||||||
const input = 'Text with multiple spaces';
|
const input = 'Text with multiple spaces';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, 'Text with multiple spaces');
|
expect(result, 'Text with multiple spaces');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('removes HTML tags', () {
|
test('removes HTML tags', () {
|
||||||
const input = '<p>Text with <strong>HTML</strong> tags</p>';
|
const input = '<p>Text with <strong>HTML</strong> tags</p>';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, 'Text with HTML tags');
|
expect(result, 'Text with HTML tags');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('escapes comment end markers', () {
|
test('escapes comment end markers', () {
|
||||||
const input = 'Text with */ comment end';
|
const input = 'Text with */ comment end';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, 'Text with * / comment end');
|
expect(result, 'Text with * / comment end');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('trims leading and trailing whitespace', () {
|
test('trims leading and trailing whitespace', () {
|
||||||
const input = ' Text with spaces ';
|
const input = ' Text with spaces ';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, 'Text with spaces');
|
expect(result, 'Text with spaces');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles empty string', () {
|
test('handles empty string', () {
|
||||||
const input = '';
|
const input = '';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, '');
|
expect(result, '');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles complex Chinese text with newlines', () {
|
test('handles complex Chinese text with newlines', () {
|
||||||
const input = '获取用户信息\n包含用户的基本信息和扩展信息';
|
const input = '获取用户信息\n包含用户的基本信息和扩展信息';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
expect(result, isNot(contains('\n')));
|
expect(result, isNot(contains('\n')));
|
||||||
expect(result, '获取用户信息 包含用户的基本信息和扩展信息');
|
expect(result, '获取用户信息 包含用户的基本信息和扩展信息');
|
||||||
});
|
});
|
||||||
|
|
@ -68,7 +68,7 @@ void main() {
|
||||||
test('handles text with parentheses and newlines', () {
|
test('handles text with parentheses and newlines', () {
|
||||||
const input = '部长新增工作任务指标\n(会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)';
|
const input = '部长新增工作任务指标\n(会删除所有管理的班级任务指标-删除所有管理的学习官的通用任务指标)';
|
||||||
final result = TextCleaner.cleanDescription(input);
|
final result = TextCleaner.cleanDescription(input);
|
||||||
|
|
||||||
// Should not contain newlines
|
// Should not contain newlines
|
||||||
expect(result, isNot(contains('\n')));
|
expect(result, isNot(contains('\n')));
|
||||||
// Should preserve parentheses
|
// Should preserve parentheses
|
||||||
|
|
@ -83,33 +83,34 @@ void main() {
|
||||||
test('normalizes line endings', () {
|
test('normalizes line endings', () {
|
||||||
const input = 'Line 1\r\nLine 2\rLine 3\nLine 4';
|
const input = 'Line 1\r\nLine 2\rLine 3\nLine 4';
|
||||||
final result = TextCleaner.normalize(input);
|
final result = TextCleaner.normalize(input);
|
||||||
|
|
||||||
expect(result, 'Line 1\nLine 2\nLine 3\nLine 4');
|
expect(result, 'Line 1\nLine 2\nLine 3\nLine 4');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('removes excessive blank lines', () {
|
test('removes excessive blank lines', () {
|
||||||
const input = 'Line 1\n\n\n\nLine 2';
|
const input = 'Line 1\n\n\n\nLine 2';
|
||||||
final result = TextCleaner.normalize(input);
|
final result = TextCleaner.normalize(input);
|
||||||
|
|
||||||
expect(result, 'Line 1\n\nLine 2');
|
expect(result, 'Line 1\n\nLine 2');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('trims whitespace', () {
|
test('trims whitespace', () {
|
||||||
const input = ' Text ';
|
const input = ' Text ';
|
||||||
final result = TextCleaner.normalize(input);
|
final result = TextCleaner.normalize(input);
|
||||||
|
|
||||||
expect(result, 'Text');
|
expect(result, 'Text');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('escapeString', () {
|
group('escapeString', () {
|
||||||
test('escapes special characters', () {
|
test('escapes special characters', () {
|
||||||
const input = "Text with 'quotes' and \"double quotes\" and \n newlines";
|
const input =
|
||||||
|
"Text with 'quotes' and \"double quotes\" and \n newlines";
|
||||||
final result = TextCleaner.escapeString(input);
|
final result = TextCleaner.escapeString(input);
|
||||||
|
|
||||||
expect(result, contains("\\'"));
|
expect(result, contains(r"\'"));
|
||||||
expect(result, contains('\\"'));
|
expect(result, contains(r'\"'));
|
||||||
expect(result, contains('\\n'));
|
expect(result, contains(r'\n'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -117,7 +118,7 @@ void main() {
|
||||||
test('truncates long text', () {
|
test('truncates long text', () {
|
||||||
const input = 'This is a very long text that needs to be truncated';
|
const input = 'This is a very long text that needs to be truncated';
|
||||||
final result = TextCleaner.truncate(input, 20);
|
final result = TextCleaner.truncate(input, 20);
|
||||||
|
|
||||||
expect(result.length, lessThanOrEqualTo(20));
|
expect(result.length, lessThanOrEqualTo(20));
|
||||||
expect(result, endsWith('...'));
|
expect(result, endsWith('...'));
|
||||||
});
|
});
|
||||||
|
|
@ -125,10 +126,9 @@ void main() {
|
||||||
test('does not truncate short text', () {
|
test('does not truncate short text', () {
|
||||||
const input = 'Short text';
|
const input = 'Short text';
|
||||||
final result = TextCleaner.truncate(input, 20);
|
final result = TextCleaner.truncate(input, 20);
|
||||||
|
|
||||||
expect(result, input);
|
expect(result, input);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,363 @@
|
||||||
|
# Swagger 代码生成器配置文件模板
|
||||||
|
# 复制此文件到您的项目根目录,重命名为 generator_config.yaml,并根据需要修改
|
||||||
|
|
||||||
|
# 基本配置
|
||||||
|
generator:
|
||||||
|
name: "my_project_generator" # 修改为您的项目生成器名称
|
||||||
|
version: "1.0"
|
||||||
|
author: "Your Name" # 修改为您的名字
|
||||||
|
copyright: "Copyright (C) 2025 Your Company. All rights reserved." # 修改为您的版权信息
|
||||||
|
|
||||||
|
# 输入配置
|
||||||
|
input:
|
||||||
|
# Swagger 文档源配置(支持多版本)
|
||||||
|
swagger_urls:
|
||||||
|
# 简写形式:直接列出 URL
|
||||||
|
- "https://your-api.com/swagger/v1/swagger_v3.json"
|
||||||
|
- "https://your-api.com/swagger/v2/swagger_v3.json"
|
||||||
|
|
||||||
|
# 完整形式:可以控制每个版本的启用状态
|
||||||
|
# - url: "https://your-api.com/swagger/v1/swagger_v3.json"
|
||||||
|
# enabled: true # 可选,是否启用此版本(默认: true)
|
||||||
|
|
||||||
|
# 验证配置
|
||||||
|
validate_schema: true
|
||||||
|
strict_mode: true
|
||||||
|
|
||||||
|
# 输出配置
|
||||||
|
output:
|
||||||
|
# 输出目录(根据您的项目结构修改)
|
||||||
|
base_dir: "./lib/generated"
|
||||||
|
api_dir: "./lib/generated/api"
|
||||||
|
models_dir: "./lib/generated/api_models"
|
||||||
|
|
||||||
|
# 文件命名
|
||||||
|
api_file_suffix: "_api.dart"
|
||||||
|
model_file_suffix: ".dart"
|
||||||
|
|
||||||
|
# 是否按 tag 分组
|
||||||
|
split_by_tags: true
|
||||||
|
|
||||||
|
# 只生成指定 tags 的 API 和模型(可选)
|
||||||
|
# 如果不指定或为空,则生成所有 tags
|
||||||
|
# 如果某个 endpoint 有多个 tags,只要其中一个在列表中就会生成
|
||||||
|
included_tags:
|
||||||
|
# - "User"
|
||||||
|
# - "Pet"
|
||||||
|
# - "Store"
|
||||||
|
|
||||||
|
# 从代码生成中排除指定的 tags
|
||||||
|
# 适用于内部、废弃或不需要的 API
|
||||||
|
# 如果一个 endpoint 的所有 tags 都被排除,则该 endpoint 不会生成
|
||||||
|
excluded_tags:
|
||||||
|
# - "Internal"
|
||||||
|
# - "Deprecated"
|
||||||
|
# - "Legacy"
|
||||||
|
|
||||||
|
# 跳过的目录列表(这些目录下的文件将不会被生成)
|
||||||
|
# 支持相对路径和绝对路径,支持目录名或完整路径
|
||||||
|
ignored_directories:
|
||||||
|
# - "api/v1" # 跳过 v1 版本的 API
|
||||||
|
# - "api_models/request" # 跳过请求模型目录
|
||||||
|
# - "./lib/generated/api/v2" # 跳过特定路径
|
||||||
|
|
||||||
|
# 跳过的文件名列表(这些文件将不会被生成)
|
||||||
|
# 支持精确匹配、通配符匹配和模式匹配
|
||||||
|
ignored_files:
|
||||||
|
# 精确匹配文件名
|
||||||
|
# - "user_api.dart" # 跳过名为 user_api.dart 的文件
|
||||||
|
# - "mobile_manager_api.dart" # 跳过指定文件
|
||||||
|
|
||||||
|
# 通配符匹配(支持前缀和后缀)
|
||||||
|
# - "*_api.dart" # 跳过所有以 _api.dart 结尾的文件
|
||||||
|
# - "user*.dart" # 跳过所有以 user 开头的 .dart 文件
|
||||||
|
# - "*manager*" # 跳过所有包含 manager 的文件名
|
||||||
|
|
||||||
|
# 示例:跳过所有 v1 版本的 API 文件
|
||||||
|
# - "*_api_v1.dart"
|
||||||
|
# - "*V1*.dart"
|
||||||
|
|
||||||
|
# 代码生成配置
|
||||||
|
generation:
|
||||||
|
# API 接口配置
|
||||||
|
api:
|
||||||
|
enabled: true
|
||||||
|
use_retrofit: true
|
||||||
|
use_dio: true
|
||||||
|
parser: "JsonSerializable"
|
||||||
|
|
||||||
|
# API Client 配置
|
||||||
|
# 主 API 客户端类的名称和文件名配置
|
||||||
|
client:
|
||||||
|
class_name: "ApiClient" # API 客户端类名(默认: ApiClient)
|
||||||
|
file_name: "api_client" # API 客户端文件名(默认: api_client,不含 .dart 后缀)
|
||||||
|
|
||||||
|
# 版本提取配置(多版本支持)
|
||||||
|
version_extraction:
|
||||||
|
# 版本提取正则表达式模式
|
||||||
|
# 默认: "/api/v(\\d+)/" 匹配 /api/v1/, /api/v2/ 等
|
||||||
|
pattern: "/api/v(\\d+)/"
|
||||||
|
|
||||||
|
# 默认版本(当无法从路径提取版本时使用)
|
||||||
|
default_version: "v1"
|
||||||
|
|
||||||
|
# 基础类型配置(根据您的项目调整)
|
||||||
|
# 如果您的项目有统一的响应模型,请在此处配置
|
||||||
|
base_result_type: "BaseResult" # 基础响应模型名称
|
||||||
|
base_page_result_type: "BasePageResult" # 分页响应模型名称
|
||||||
|
|
||||||
|
# 基础模型的导入路径(可选)
|
||||||
|
# 如果提供了路径,将在 api_models/index.dart 中自动导出
|
||||||
|
# 如果留空,则不会生成导出语句
|
||||||
|
base_result_import: "" # 例如: "package:your_project/common/models/base_result.dart"
|
||||||
|
base_page_result_import: "" # 例如: "package:your_project/common/models/base_page_result.dart"
|
||||||
|
|
||||||
|
# 方法命名
|
||||||
|
method_naming: "camelCase" # camelCase, snake_case
|
||||||
|
|
||||||
|
# 数据模型配置
|
||||||
|
models:
|
||||||
|
enabled: true
|
||||||
|
use_json_serializable: true
|
||||||
|
|
||||||
|
# JsonSerializable 配置
|
||||||
|
json_serializable:
|
||||||
|
checked: true
|
||||||
|
include_if_null: false
|
||||||
|
explicit_to_json: true
|
||||||
|
|
||||||
|
# 类命名
|
||||||
|
class_naming: "PascalCase" # PascalCase, snake_case
|
||||||
|
field_naming: "camelCase" # camelCase, snake_case
|
||||||
|
|
||||||
|
# 构造函数配置
|
||||||
|
use_const_constructor: true
|
||||||
|
required_for_non_nullable: true
|
||||||
|
|
||||||
|
# 枚举键名映射配置(可选)
|
||||||
|
# 用于为枚举值定义有意义的键名和描述
|
||||||
|
# 优先级:配置文件映射 > x-enum-varnames > 智能生成
|
||||||
|
#
|
||||||
|
# 使用场景:
|
||||||
|
# 1. 后端不支持 x-enum-varnames 扩展字段
|
||||||
|
# 2. 需要覆盖 Swagger 文档中的枚举键名
|
||||||
|
# 3. 需要为枚举值添加自定义描述
|
||||||
|
#
|
||||||
|
# 格式:
|
||||||
|
# enum_key_mappings:
|
||||||
|
# 枚举名称:
|
||||||
|
# - value: 枚举值(数字或字符串)
|
||||||
|
# name: 枚举键名(大写下划线命名)
|
||||||
|
# description: 枚举描述(可选)
|
||||||
|
#
|
||||||
|
# 示例:
|
||||||
|
# enum_key_mappings:
|
||||||
|
# SysTaskTypeEnums:
|
||||||
|
# - value: 1
|
||||||
|
# name: SPOT_CHECK
|
||||||
|
# description: 抽查
|
||||||
|
# - value: 2
|
||||||
|
# name: CULTURAL
|
||||||
|
# description: 文创建设
|
||||||
|
# - value: 3
|
||||||
|
# name: CLASS_CADRE_MEETING
|
||||||
|
# description: 班干部会议
|
||||||
|
#
|
||||||
|
# UserStatus:
|
||||||
|
# - value: "active"
|
||||||
|
# name: ACTIVE
|
||||||
|
# description: 活跃用户
|
||||||
|
# - value: "inactive"
|
||||||
|
# name: INACTIVE
|
||||||
|
# description: 非活跃用户
|
||||||
|
# - value: "banned"
|
||||||
|
# name: BANNED
|
||||||
|
# description: 已封禁
|
||||||
|
#
|
||||||
|
enum_key_mappings:
|
||||||
|
# 在此处添加您的枚举映射配置
|
||||||
|
# SysTaskTypeEnums:
|
||||||
|
# - value: 1
|
||||||
|
# name: SPOT_CHECK
|
||||||
|
# description: 抽查
|
||||||
|
# - value: 2
|
||||||
|
# name: CULTURAL
|
||||||
|
# description: 文创建设
|
||||||
|
|
||||||
|
# 类型映射配置
|
||||||
|
type_mapping:
|
||||||
|
# OpenAPI -> Dart 类型映射
|
||||||
|
string: "String"
|
||||||
|
integer: "int"
|
||||||
|
number: "double"
|
||||||
|
boolean: "bool"
|
||||||
|
array: "List"
|
||||||
|
object: "Map<String, dynamic>"
|
||||||
|
|
||||||
|
# 特殊类型处理
|
||||||
|
date: "DateTime"
|
||||||
|
date-time: "DateTime"
|
||||||
|
binary: "Uint8List"
|
||||||
|
|
||||||
|
# 导入管理配置
|
||||||
|
imports:
|
||||||
|
# 按需导入
|
||||||
|
on_demand: true
|
||||||
|
|
||||||
|
# 自动排序
|
||||||
|
auto_sort: true
|
||||||
|
|
||||||
|
# 分组导入
|
||||||
|
group_imports: true
|
||||||
|
|
||||||
|
# 标准库导入
|
||||||
|
dart_imports:
|
||||||
|
- "dart:convert"
|
||||||
|
- "dart:typed_data"
|
||||||
|
|
||||||
|
# 第三方库导入
|
||||||
|
package_imports:
|
||||||
|
- "package:dio/dio.dart"
|
||||||
|
- "package:retrofit/retrofit.dart"
|
||||||
|
- "package:json_annotation/json_annotation.dart"
|
||||||
|
|
||||||
|
# 验证配置
|
||||||
|
validation:
|
||||||
|
# 严格模式
|
||||||
|
strict_mode: true
|
||||||
|
|
||||||
|
# 检查项
|
||||||
|
checks:
|
||||||
|
- "schema_exists"
|
||||||
|
- "ref_resolution"
|
||||||
|
- "type_consistency"
|
||||||
|
- "nullable_correctness"
|
||||||
|
- "required_fields"
|
||||||
|
|
||||||
|
# 错误处理
|
||||||
|
on_error: "warn" # fail, warn, ignore
|
||||||
|
|
||||||
|
# 警告处理
|
||||||
|
on_warning: "log" # fail, log, ignore
|
||||||
|
|
||||||
|
# 优化配置
|
||||||
|
optimization:
|
||||||
|
# 代码优化
|
||||||
|
remove_unused_imports: true
|
||||||
|
optimize_imports: true
|
||||||
|
|
||||||
|
# 性能优化
|
||||||
|
cache_schemas: true
|
||||||
|
parallel_generation: false
|
||||||
|
|
||||||
|
# 内存优化
|
||||||
|
lazy_loading: true
|
||||||
|
|
||||||
|
# 调试配置
|
||||||
|
debug:
|
||||||
|
# 详细日志
|
||||||
|
verbose: false
|
||||||
|
|
||||||
|
# 调试输出
|
||||||
|
debug_output: false
|
||||||
|
|
||||||
|
# 性能监控
|
||||||
|
performance_monitoring: false
|
||||||
|
|
||||||
|
# 生成统计
|
||||||
|
generation_stats: true
|
||||||
|
|
||||||
|
# 兼容性配置
|
||||||
|
compatibility:
|
||||||
|
# Dart 版本
|
||||||
|
dart_version: ">=3.0.0"
|
||||||
|
|
||||||
|
# Flutter 版本
|
||||||
|
flutter_version: ">=3.10.0"
|
||||||
|
|
||||||
|
# 依赖版本
|
||||||
|
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"
|
||||||
|
|
||||||
|
# 自定义配置
|
||||||
|
custom:
|
||||||
|
# 项目特定配置
|
||||||
|
project_name: "your_project" # 修改为您的项目名称
|
||||||
|
|
||||||
|
# 特殊处理规则
|
||||||
|
special_handling:
|
||||||
|
# 健康检查接口返回 void
|
||||||
|
health_check_paths:
|
||||||
|
- "/health"
|
||||||
|
- "/healthcheck"
|
||||||
|
- "/api/health"
|
||||||
|
|
||||||
|
# 分页接口参数名
|
||||||
|
pagination_params:
|
||||||
|
- "page"
|
||||||
|
- "size"
|
||||||
|
- "limit"
|
||||||
|
- "offset"
|
||||||
|
- "pageIndex"
|
||||||
|
- "pageSize"
|
||||||
|
|
||||||
|
# 忽略的路径
|
||||||
|
ignored_paths:
|
||||||
|
- "/swagger"
|
||||||
|
- "/docs"
|
||||||
|
|
||||||
|
# 忽略的 tags
|
||||||
|
ignored_tags:
|
||||||
|
- "Internal"
|
||||||
|
- "Debug"
|
||||||
|
|
||||||
|
# 模板配置
|
||||||
|
templates:
|
||||||
|
# 文件头模板
|
||||||
|
# 支持模板变量:
|
||||||
|
# {fileName} - 文件名(如 "user_api.dart")
|
||||||
|
# {fileType} - 文件类型描述(如 "API 接口定义"、"模型定义")
|
||||||
|
# {swaggerUrl} - Swagger 文档 URL
|
||||||
|
# {generatorName} - 生成器名称(从 generator.name 读取)
|
||||||
|
# {author} - 作者(从 generator.author 读取)
|
||||||
|
# {copyright} - 版权信息(从 generator.copyright 读取)
|
||||||
|
file_header: |
|
||||||
|
// {fileType}
|
||||||
|
// 基于 Swagger API 文档: {swaggerUrl}
|
||||||
|
// 由 {generatorName} by {author} 生成
|
||||||
|
// {copyright}
|
||||||
|
|
||||||
|
# API 类模板
|
||||||
|
# 支持模板变量:
|
||||||
|
# {tagName} - Tag 名称(如 "User"、"Task")
|
||||||
|
# {className} - 类名(如 "UserApi"、"TaskApi")
|
||||||
|
api_class: |
|
||||||
|
/// {tagName} API 接口
|
||||||
|
/// 负责处理 {tagName} 相关的接口
|
||||||
|
@RestApi(parser: Parser.JsonSerializable)
|
||||||
|
abstract class {className} {
|
||||||
|
factory {className}(Dio dio, {String? baseUrl}) = _{className};
|
||||||
|
}
|
||||||
|
|
||||||
|
# 模型类模板
|
||||||
|
# 支持模板变量:
|
||||||
|
# {className} - 类名(如 "User"、"Task")
|
||||||
|
# {constructorParams} - 构造函数参数列表
|
||||||
|
model_class: |
|
||||||
|
@JsonSerializable(checked: true, includeIfNull: false)
|
||||||
|
class {className} {
|
||||||
|
const {className}({constructorParams});
|
||||||
|
|
||||||
|
factory {className}.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_${className}FromJson(json);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _${className}ToJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue