From d6a31d5a24a2645b90df7610c4575b31766f158f Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 23 Nov 2025 14:11:16 +0800 Subject: [PATCH] feat: update --- lib/index.dart | 1 - .../generate/impl/base_generator.dart | 14 ++--- .../impl/model/model_content_builders.dart | 18 +++--- .../impl/model/model_file_writers.dart | 4 +- .../impl/model/model_pagination_helpers.dart | 2 +- .../generate/impl/model_code_generator.dart | 2 +- .../retrofit_api/api_parameter_entities.dart | 14 ++--- .../impl/retrofit_api/api_parameters.dart | 6 +- .../retrofit_api/api_schema_composition.dart | 6 +- .../retrofit_api/api_schema_extraction.dart | 6 +- .../impl/retrofit_api/api_template_data.dart | 8 +-- .../generate/impl/retrofit_api_generator.dart | 6 +- .../parse/impl/swagger_data_parser.dart | 4 +- lib/swagger_cli_new.dart | 7 ++- lib/swagger_generator_flutter.dart | 2 - lib/utils/api_naming_utils.dart | 50 +++++++++++++++ lib/utils/cache_manager.dart | 4 +- .../{string_utils.dart => string_helper.dart} | 61 ++++++++----------- lib/utils/string_utils/formatting_utils.dart | 30 +++++++++ lib/utils/string_utils/index.dart | 9 +++ 20 files changed, 165 insertions(+), 89 deletions(-) create mode 100644 lib/utils/api_naming_utils.dart rename lib/utils/{string_utils.dart => string_helper.dart} (78%) create mode 100644 lib/utils/string_utils/formatting_utils.dart create mode 100644 lib/utils/string_utils/index.dart diff --git a/lib/index.dart b/lib/index.dart index 7e6ae70..f200cda 100644 --- a/lib/index.dart +++ b/lib/index.dart @@ -27,4 +27,3 @@ export 'pipeline/validate/enhanced_validator.dart'; // --- Utilities --- export 'utils/logger.dart'; export 'utils/path_resolver.dart'; -export 'utils/string_utils.dart'; diff --git a/lib/pipeline/generate/impl/base_generator.dart b/lib/pipeline/generate/impl/base_generator.dart index 37eba9e..c874144 100644 --- a/lib/pipeline/generate/impl/base_generator.dart +++ b/lib/pipeline/generate/impl/base_generator.dart @@ -1,7 +1,7 @@ import 'package:swagger_generator_flutter/core/config.dart'; import 'package:swagger_generator_flutter/core/exceptions.dart'; import 'package:swagger_generator_flutter/core/models.dart'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_helper.dart'; /// 代码生成器基类 /// 定义通用的接口和功能 @@ -16,7 +16,7 @@ abstract class BaseGenerator { /// [description] 文件描述 /// [fileName] 文件名(可选) String generateFileHeader(String description, {String? fileName}) { - final header = StringUtils.generateFileHeader( + final header = StringHelper.generateFileHeader( description, SwaggerConfig.swaggerJsonUrls.isNotEmpty ? SwaggerConfig.swaggerJsonUrls.first @@ -105,7 +105,7 @@ abstract class ModelGenerator extends BaseGenerator { throw CodeGenerationException('模型不是枚举类型', generatorType: generatorType); } - final className = StringUtils.generateClassName(model.name); + final className = StringHelper.generateClassName(model.name); final enumType = model.enumType?.value ?? 'string'; final valueType = enumType == 'integer' || enumType == 'number' ? 'int' : 'String'; @@ -116,7 +116,7 @@ abstract class ModelGenerator extends BaseGenerator { // 生成枚举类 if (model.description.isNotEmpty) { - buffer.writeln(StringUtils.generateComment(model.description)); + buffer.writeln(StringHelper.generateComment(model.description)); } buffer.writeln('enum $className {'); @@ -124,7 +124,7 @@ abstract class ModelGenerator extends BaseGenerator { // 生成枚举值 for (var i = 0; i < model.enumValues.length; i++) { final value = model.enumValues[i]; - final enumName = StringUtils.generateEnumValueName(value, i); + final enumName = StringHelper.generateEnumValueName(value, i); final enumLine = enumType == 'integer' || enumType == 'number' ? ' $enumName($value),' : " $enumName('$value'),"; @@ -226,7 +226,7 @@ abstract class ModelGenerator extends BaseGenerator { return 'Map'; case PropertyType.reference: return property.reference != null - ? StringUtils.generateClassName(property.reference!) + ? StringHelper.generateClassName(property.reference!) : 'dynamic'; case PropertyType.file: return 'dynamic'; @@ -248,7 +248,7 @@ abstract class ModelGenerator extends BaseGenerator { items.name != 'integer' && items.name != 'number' && items.name != 'boolean') { - return StringUtils.generateClassName(items.name); + return StringHelper.generateClassName(items.name); } // 如果是基本类型,转换为对应的Dart类型 diff --git a/lib/pipeline/generate/impl/model/model_content_builders.dart b/lib/pipeline/generate/impl/model/model_content_builders.dart index 3880a11..2181146 100644 --- a/lib/pipeline/generate/impl/model/model_content_builders.dart +++ b/lib/pipeline/generate/impl/model/model_content_builders.dart @@ -11,14 +11,14 @@ String _generateModelCodeWithoutImports( } String _generateEnumCodeWithoutImports(ApiModel model) { - final className = StringUtils.generateClassName(model.name); + final className = StringHelper.generateClassName(model.name); final enumType = model.enumType?.value ?? 'string'; final valueType = enumType == 'integer' || enumType == 'number' ? 'int' : 'String'; final buffer = StringBuffer(); if (model.description.isNotEmpty) { - buffer.writeln(StringUtils.generateComment(model.description)); + buffer.writeln(StringHelper.generateComment(model.description)); } buffer @@ -27,7 +27,7 @@ String _generateEnumCodeWithoutImports(ApiModel model) { for (var i = 0; i < model.enumValues.length; i++) { final value = model.enumValues[i]; - final enumName = StringUtils.generateEnumValueName(value, i); + final enumName = StringHelper.generateEnumValueName(value, i); final enumLine = enumType == 'integer' || enumType == 'number' ? ' $enumName($value),' : " $enumName('$value'),"; @@ -73,10 +73,10 @@ String _generateAnnotatedModelCodeWithoutImports( ModelCodeGenerator generator, ApiModel model, ) { - final className = StringUtils.generateClassName(model.name); + final className = StringHelper.generateClassName(model.name); final buffer = StringBuffer(); - final partFileName = StringUtils.generateFileName(model.name); + final partFileName = StringHelper.generateFileName(model.name); final freezedPart = partFileName.replaceAll('.dart', '.freezed.dart'); final generatedPart = partFileName.replaceAll('.dart', '.g.dart'); buffer @@ -85,7 +85,7 @@ String _generateAnnotatedModelCodeWithoutImports( ..writeln(); if (model.description.isNotEmpty) { - buffer.writeln(StringUtils.generateComment(model.description)); + buffer.writeln(StringHelper.generateComment(model.description)); } buffer @@ -100,11 +100,11 @@ String _generateAnnotatedModelCodeWithoutImports( property.format != 'date'; final hasDefaultValue = property.defaultValue != null || isNormalString; final nullable = hasDefaultValue ? '' : (property.nullable ? '?' : ''); - final dartPropName = StringUtils.toDartPropertyName(propName); + final dartPropName = StringHelper.toDartPropertyName(propName); if (property.description.isNotEmpty) { buffer.writeln( - ' ${StringUtils.generateComment(property.description)}', + ' ${StringHelper.generateComment(property.description)}', ); } @@ -179,7 +179,7 @@ String _generateSubDirectoryIndexFile( ..sort((a, b) => a.name.compareTo(b.name)); for (final model in sortedModels) { - final fileName = StringUtils.generateFileName(model.name); + final fileName = StringHelper.generateFileName(model.name); buffer.writeln("export '$fileName';"); } diff --git a/lib/pipeline/generate/impl/model/model_file_writers.dart b/lib/pipeline/generate/impl/model/model_file_writers.dart index 10636ed..10759e9 100644 --- a/lib/pipeline/generate/impl/model/model_file_writers.dart +++ b/lib/pipeline/generate/impl/model/model_file_writers.dart @@ -12,7 +12,7 @@ Map buildSeparateModelFiles(ModelCodeGenerator generator) { final subDir = _getModelSubDirectory(model); modelsByDirectory.putIfAbsent(subDir, () => []).add(model); - final fileName = StringUtils.generateFileName(model.name); + final fileName = StringHelper.generateFileName(model.name); final filePath = '$subDir/$fileName'; final content = buildSingleModelFile(generator, model, fileName: fileName); files[filePath] = content; @@ -38,7 +38,7 @@ String buildSingleModelFile( ..writeln( generator.generateFileHeader( '${model.name} 模型定义', - fileName: fileName ?? StringUtils.generateFileName(model.name), + fileName: fileName ?? StringHelper.generateFileName(model.name), ), ) ..writeln(); diff --git a/lib/pipeline/generate/impl/model/model_pagination_helpers.dart b/lib/pipeline/generate/impl/model/model_pagination_helpers.dart index 7ffa2ff..0b49d43 100644 --- a/lib/pipeline/generate/impl/model/model_pagination_helpers.dart +++ b/lib/pipeline/generate/impl/model/model_pagination_helpers.dart @@ -24,7 +24,7 @@ String _getPaginationItemType(ApiModel items) { items.name != 'integer' && items.name != 'number' && items.name != 'boolean') { - return StringUtils.generateClassName(items.name); + return StringHelper.generateClassName(items.name); } switch (items.name) { diff --git a/lib/pipeline/generate/impl/model_code_generator.dart b/lib/pipeline/generate/impl/model_code_generator.dart index 516d6d3..6018480 100644 --- a/lib/pipeline/generate/impl/model_code_generator.dart +++ b/lib/pipeline/generate/impl/model_code_generator.dart @@ -1,7 +1,7 @@ import 'package:swagger_generator_flutter/core/config.dart'; import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/base_generator.dart'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_helper.dart'; part 'model/model_content_builders.dart'; part 'model/model_file_writers.dart'; diff --git a/lib/pipeline/generate/impl/retrofit_api/api_parameter_entities.dart b/lib/pipeline/generate/impl/retrofit_api/api_parameter_entities.dart index a329d8b..51f0818 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_parameter_entities.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_parameter_entities.dart @@ -6,7 +6,7 @@ mixin RetrofitApiParameterEntities { /// 生成参数实体类的类名 String _generateParameterEntityClassName(ApiPath path) { final methodName = _g._generateSimpleMethodName(path); - return '${StringUtils.toPascalCase(methodName)}Parameters'; + return '${StringHelper.toPascalCase(methodName)}Parameters'; } /// 生成参数实体类 @@ -19,7 +19,7 @@ mixin RetrofitApiParameterEntities { ..writeln( _g.generateFileHeader( '参数实体类 - $className', - fileName: '${StringUtils.toSnakeCase(className)}.dart', + fileName: '${StringHelper.toSnakeCase(className)}.dart', ), ) ..writeln( @@ -28,12 +28,12 @@ mixin RetrofitApiParameterEntities { ..writeln() ..writeln("import 'package:json_annotation/json_annotation.dart';") ..writeln() - ..writeln("part '${StringUtils.toSnakeCase(className)}.g.dart';") + ..writeln("part '${StringHelper.toSnakeCase(className)}.g.dart';") ..writeln() ..writeln('@JsonSerializable(checked: true, includeIfNull: false)') ..writeln('class $className {'); for (final param in queryParams) { - final dartName = StringUtils.toDartPropertyName(param.name); + final dartName = StringHelper.toDartPropertyName(param.name); final dartType = _g._getDartType(param.type); final nullable = param.required ? '' : '?'; @@ -53,7 +53,7 @@ mixin RetrofitApiParameterEntities { buffer.writeln(' const $className({'); for (final param in queryParams) { - final dartName = StringUtils.toDartPropertyName(param.name); + final dartName = StringHelper.toDartPropertyName(param.name); final required = param.required ? 'required ' : ''; buffer.writeln(' ${required}this.$dartName,'); } @@ -73,7 +73,7 @@ mixin RetrofitApiParameterEntities { ..writeln(' Map toQueryMap() {') ..writeln(' final map = {};'); for (final param in queryParams) { - final dartName = StringUtils.toDartPropertyName(param.name); + final dartName = StringHelper.toDartPropertyName(param.name); buffer.writeln( " if ($dartName != null) map['${param.name}'] = $dartName;", ); @@ -96,7 +96,7 @@ mixin RetrofitApiParameterEntities { for (final entry in _generatedParameterEntities.entries) { final className = entry.key; final content = entry.value; - final fileName = StringUtils.generateFileName(className); + final fileName = StringHelper.generateFileName(className); files[fileName] = content; } diff --git a/lib/pipeline/generate/impl/retrofit_api/api_parameters.dart b/lib/pipeline/generate/impl/retrofit_api/api_parameters.dart index 62268de..41776f2 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_parameters.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_parameters.dart @@ -13,7 +13,7 @@ mixin RetrofitApiParameters { for (final param in pathParams) { parameters.add( ApiMethodParameter( - name: StringUtils.toDartPropertyName(param.name), + name: StringHelper.toDartPropertyName(param.name), type: _getDartType(param.type), annotation: _g.useRetrofit ? "@Path('${param.name}')" : '', required: param.required, @@ -46,7 +46,7 @@ mixin RetrofitApiParameters { final nullable = param.required ? '' : '?'; parameters.add( ApiMethodParameter( - name: StringUtils.toDartPropertyName(param.name), + name: StringHelper.toDartPropertyName(param.name), type: '${_getDartType(param.type)}$nullable', annotation: _g.useRetrofit ? "@Query('${param.name}')" : '', required: param.required, @@ -64,7 +64,7 @@ mixin RetrofitApiParameters { final bodyType = _inferRequestBodyType(path); parameters.add( ApiMethodParameter( - name: StringUtils.toDartPropertyName( + name: StringHelper.toDartPropertyName( param.name.isNotEmpty ? param.name : 'request', ), type: bodyType, diff --git a/lib/pipeline/generate/impl/retrofit_api/api_schema_composition.dart b/lib/pipeline/generate/impl/retrofit_api/api_schema_composition.dart index 5d5bf36..d140dab 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_schema_composition.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_schema_composition.dart @@ -36,7 +36,7 @@ mixin RetrofitApiSchemaComposition { if (schemaData[r'$ref'] != null) { final ref = schemaData[r'$ref'] as String; final refName = ref.split('/').last; - return StringUtils.generateClassName(refName); + return StringHelper.generateClassName(refName); } if (schemaData['type'] != null) { @@ -67,7 +67,7 @@ mixin RetrofitApiSchemaComposition { if (schemaData is Map && schemaData[r'$ref'] != null) { final ref = schemaData[r'$ref'] as String; final refName = ref.split('/').last; - refTypes.add(StringUtils.generateClassName(refName)); + refTypes.add(StringHelper.generateClassName(refName)); } } @@ -104,7 +104,7 @@ mixin RetrofitApiSchemaComposition { for (final value in mapping.values) { if (value is String) { final refName = value.split('/').last; - mappedTypes.add(StringUtils.generateClassName(refName)); + mappedTypes.add(StringHelper.generateClassName(refName)); } } diff --git a/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart b/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart index a9d4c96..2b0fc34 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart @@ -50,7 +50,7 @@ mixin RetrofitApiSchema { if (schema[r'$ref'] != null) { final ref = schema[r'$ref'] as String; final refName = ref.split('/').last; - return StringUtils.generateClassName(refName); + return StringHelper.generateClassName(refName); } if (schema['type'] != null) { @@ -110,7 +110,7 @@ mixin RetrofitApiSchema { /// 生成简单方法名 String _generateSimpleMethodName(ApiPath path) { if (path.operationId.isNotEmpty) { - return StringUtils.toCamelCase(path.operationId); + return StringHelper.toCamelCase(path.operationId); } final pathParts = path.path @@ -124,7 +124,7 @@ mixin RetrofitApiSchema { final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), ''); final method = path.method.value.toLowerCase(); - final pascalPart = StringUtils.toPascalCase(lastPart); + final pascalPart = StringHelper.toPascalCase(lastPart); final methodName = '$method$pascalPart'; return methodName; diff --git a/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart b/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart index 2d9b92a..59eb1f0 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart @@ -6,7 +6,7 @@ mixin RetrofitApiTemplateData { List _getMainImports() { final tagGroups = _g._groupPathsByTags(); final tagImports = tagGroups.keys.map((tag) { - final fileName = StringUtils.generateFileName(tag); + final fileName = StringHelper.generateFileName(tag); return "import '$fileName.dart';"; }).toList(); @@ -22,8 +22,8 @@ mixin RetrofitApiTemplateData { 'apis': tagGroups.entries.map((entry) { final tagName = entry.key; return { - 'name': StringUtils.toCamelCase(tagName), - 'className': '${StringUtils.toPascalCase(tagName)}Api', + 'name': StringHelper.toCamelCase(tagName), + 'className': '${StringHelper.toPascalCase(tagName)}Api', }; }).toList(), }; @@ -34,7 +34,7 @@ mixin RetrofitApiTemplateData { _g.document.servers.isNotEmpty ? _g.document.servers.first.url : ''; var fileName = ''; if (_g.className.isNotEmpty) { - fileName = StringUtils.generateFileName(_g.className); + fileName = StringHelper.generateFileName(_g.className); } return { diff --git a/lib/pipeline/generate/impl/retrofit_api_generator.dart b/lib/pipeline/generate/impl/retrofit_api_generator.dart index 6f366c3..55417e0 100644 --- a/lib/pipeline/generate/impl/retrofit_api_generator.dart +++ b/lib/pipeline/generate/impl/retrofit_api_generator.dart @@ -2,7 +2,7 @@ import 'package:swagger_generator_flutter/core/config_repository.dart'; import 'package:swagger_generator_flutter/core/models.dart'; import 'package:swagger_generator_flutter/core/template_renderer.dart'; import 'package:swagger_generator_flutter/pipeline/generate/impl/base_generator.dart'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_helper.dart'; part 'retrofit_api/api_grouping.dart'; part 'retrofit_api/api_method_parameter.dart'; @@ -108,8 +108,8 @@ class RetrofitApiGenerator extends BaseGenerator final tagName = entry.key; final paths = entry.value; // Use ${tagName}Api to match old behavior (user -> user_api.dart) - final fileName = StringUtils.generateFileName('${tagName}Api'); - final apiClassName = '${StringUtils.toPascalCase(tagName)}Api'; + final fileName = StringHelper.generateFileName('${tagName}Api'); + final apiClassName = '${StringHelper.toPascalCase(tagName)}Api'; final data = _buildApiClassData(paths); data['className'] = apiClassName; diff --git a/lib/pipeline/parse/impl/swagger_data_parser.dart b/lib/pipeline/parse/impl/swagger_data_parser.dart index 3accda5..a93ff0f 100644 --- a/lib/pipeline/parse/impl/swagger_data_parser.dart +++ b/lib/pipeline/parse/impl/swagger_data_parser.dart @@ -8,7 +8,7 @@ import 'package:swagger_generator_flutter/utils/cache_manager.dart'; import 'package:swagger_generator_flutter/utils/logger.dart'; import 'package:swagger_generator_flutter/utils/performance_monitor.dart'; import 'package:swagger_generator_flutter/utils/reference_resolver.dart'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_helper.dart'; /// Swagger数据解析器 /// 负责解析Swagger JSON文档并提取相关信息 @@ -390,7 +390,7 @@ class SwaggerDataParser { } // 默认为自定义类型 - return StringUtils.generateClassName(swaggerType); + return StringHelper.generateClassName(swaggerType); } } diff --git a/lib/swagger_cli_new.dart b/lib/swagger_cli_new.dart index 58000a6..6d52e8b 100644 --- a/lib/swagger_cli_new.dart +++ b/lib/swagger_cli_new.dart @@ -4,7 +4,8 @@ import 'package:logging/logging.dart'; import 'package:swagger_generator_flutter/commands/base_command.dart'; import 'package:swagger_generator_flutter/commands/generate_command.dart'; import 'package:swagger_generator_flutter/core/config.dart'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_helper.dart'; +import 'package:swagger_generator_flutter/utils/string_utils/index.dart'; /// Swagger CLI 应用程序 /// 使用命令模式架构的新版本CLI工具 @@ -78,7 +79,9 @@ class SwaggerCLI { if (exitCode == 0) { _logger ..info('') - ..info('⏱️ 执行时间: ${StringUtils.formatDuration(stopwatch.elapsed)}'); + ..info( + '⏱️ 执行时间: ${StringHelper.formatDuration(stopwatch.elapsed)}', + ); } return exitCode; diff --git a/lib/swagger_generator_flutter.dart b/lib/swagger_generator_flutter.dart index d828a46..409cae3 100644 --- a/lib/swagger_generator_flutter.dart +++ b/lib/swagger_generator_flutter.dart @@ -7,5 +7,3 @@ export 'core/error_reporter.dart'; // 核心模型 export 'core/models.dart'; export 'core/performance_parser.dart'; -// 工具类 -export 'utils/string_utils.dart'; diff --git a/lib/utils/api_naming_utils.dart b/lib/utils/api_naming_utils.dart new file mode 100644 index 0000000..c291453 --- /dev/null +++ b/lib/utils/api_naming_utils.dart @@ -0,0 +1,50 @@ +/// API naming utilities for endpoint and controller name generation +library; + +import 'package:swagger_generator_flutter/core/models.dart'; +import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart'; + +/// API naming utilities +class ApiNamingUtils { + /// Generate endpoint name from path and operationId + static String generateEndpointName(String path, String? operationId) { + // If operationId exists, use it with priority + if (operationId != null && operationId.isNotEmpty) { + return NamingConverter.toCamelCase(operationId); + } + + // Remove version prefix from path + var cleanPath = path.replaceFirst('/api/v1', ''); + + // Remove leading slash + if (cleanPath.startsWith('/')) { + cleanPath = cleanPath.substring(1); + } + + // Convert path to camelCase + final parts = cleanPath.split('/'); + if (parts.length >= 2) { + final controller = parts[0]; + final action = parts[1]; + return NamingConverter.toCamelCase('${controller}_$action'); + } + + return NamingConverter.toCamelCase(cleanPath.replaceAll('/', '_')); + } + + /// Extract controller name from API path + static String extractControllerName(ApiPath path) { + // Extract controller name from tags + if (path.tags.isNotEmpty) { + return path.tags.first; + } + + // Extract controller name from path + final pathParts = path.path.split('/'); + if (pathParts.length > 1) { + return NamingConverter.toPascalCase(pathParts[1]); + } + + return 'General'; + } +} diff --git a/lib/utils/cache_manager.dart b/lib/utils/cache_manager.dart index d5be82b..ae0a786 100644 --- a/lib/utils/cache_manager.dart +++ b/lib/utils/cache_manager.dart @@ -1,6 +1,6 @@ import 'dart:collection'; -import 'package:swagger_generator_flutter/utils/string_utils.dart'; +import 'package:swagger_generator_flutter/utils/string_utils/index.dart'; /// 缓存管理器 /// 提供简单的内存缓存功能 @@ -115,7 +115,7 @@ class CacheStats { 'memoryItems: $memoryItems, ' 'diskItems: $diskItems, ' 'hitRate: ${(hitRate * 100).toStringAsFixed(1)}%, ' - 'totalSize: ${StringUtils.formatBytes(totalSize)}' + 'totalSize: ${FormattingUtils.formatBytes(totalSize)}' '}'; } diff --git a/lib/utils/string_utils.dart b/lib/utils/string_helper.dart similarity index 78% rename from lib/utils/string_utils.dart rename to lib/utils/string_helper.dart index 998e866..a2f82e0 100644 --- a/lib/utils/string_utils.dart +++ b/lib/utils/string_helper.dart @@ -5,22 +5,24 @@ /// - NamingConverter: 命名转换(camelCase, PascalCase, snake_case 等) /// - TextCleaner: 文本清理和格式化 /// - TemplateService: 模板服务(注释生成、文件头生成等) +/// - FormattingUtils: 格式化工具(缩进、字节大小、持续时间等) /// /// # 典型用法示例 /// ```dart /// // snake_case 转 camelCase -/// StringUtils.toDartPropertyName('user_id'); // userId +/// StringHelper.toDartPropertyName('user_id'); // userId /// // 含特殊字符 -/// StringUtils.toDartPropertyName('user-id'); // userId +/// StringHelper.toDartPropertyName('user-id'); // userId /// // 数字开头 -/// StringUtils.toDartPropertyName('1st_field'); // n1stField +/// StringHelper.toDartPropertyName('1st_field'); // n1stField /// // 生成注释 -/// StringUtils.generateComment('API description'); // /// API description +/// StringHelper.generateComment('API description'); // /// API description /// ``` /// library; import 'package:swagger_generator_flutter/core/models.dart'; +import 'package:swagger_generator_flutter/utils/string_utils/formatting_utils.dart'; import 'package:swagger_generator_flutter/utils/string_utils/naming_converter.dart'; import 'package:swagger_generator_flutter/utils/string_utils/template_service.dart'; import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart'; @@ -28,7 +30,7 @@ import 'package:swagger_generator_flutter/utils/string_utils/text_cleaner.dart'; /// 字符串工具类 - 统一导出接口 /// /// 将各子模块的功能聚合到统一的 API 中,保持向后兼容性 -class StringUtils { +class StringHelper { // ==================== 命名转换 (NamingConverter) ==================== /// 转换为 camelCase static String toCamelCase(String input) => NamingConverter.toCamelCase(input); @@ -77,10 +79,8 @@ class StringUtils { static String escapeString(String input) => TextCleaner.escapeString(input); /// 缩进文本 - static String indent(String text, int spaces) { - final indentation = ' ' * spaces; - return text.split('\n').map((line) => '$indentation$line').join('\n'); - } + static String indent(String text, int spaces) => + FormattingUtils.indent(text, spaces); /// 截断文本到指定长度 static String truncate(String text, int maxLength, {String suffix = '...'}) => @@ -111,9 +111,21 @@ class StringUtils { ); } - // ==================== 业务逻辑辅助方法 ==================== + // ==================== 格式化工具 (FormattingUtils) ==================== + + /// 格式化字节大小 + static String formatBytes(int bytes) => FormattingUtils.formatBytes(bytes); + + /// 格式化持续时间 + static String formatDuration(Duration duration) => + FormattingUtils.formatDuration(duration); + + // ==================== 已废弃的方法(向后兼容) ==================== + // 这些方法已移至 ApiNamingUtils,保留此处以兼容旧代码 /// 生成端点名称 + /// @deprecated 使用 ApiNamingUtils.generateEndpointName 代替 + @Deprecated('Use ApiNamingUtils.generateEndpointName instead') static String generateEndpointName(String path, String? operationId) { // 如果有 operationId,优先使用 if (operationId != null && operationId.isNotEmpty) { @@ -140,6 +152,8 @@ class StringUtils { } /// 提取控制器名称 + /// @deprecated 使用 ApiNamingUtils.extractControllerName 代替 + @Deprecated('Use ApiNamingUtils.extractControllerName instead') static String extractControllerName(ApiPath path) { // 从 tags 中提取控制器名称 if (path.tags.isNotEmpty) { @@ -154,31 +168,4 @@ class StringUtils { return 'General'; } - - /// 清理路径,保留版本前缀 - static String cleanPath(String path) { - // 保留版本前缀,只清理其他不必要的字符 - return path; - } - - // ==================== 格式化工具 ==================== - - /// 格式化字节大小 - static String formatBytes(int bytes) { - if (bytes < 1024) return '${bytes}B'; - if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB'; - if (bytes < 1024 * 1024 * 1024) { - return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB'; - } - return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB'; - } - - /// 格式化持续时间 - static String formatDuration(Duration duration) { - if (duration.inMilliseconds >= 1000) { - return '${(duration.inMilliseconds / 1000).toStringAsFixed(2)}秒'; - } else { - return '${duration.inMilliseconds}毫秒'; - } - } } diff --git a/lib/utils/string_utils/formatting_utils.dart b/lib/utils/string_utils/formatting_utils.dart new file mode 100644 index 0000000..8046571 --- /dev/null +++ b/lib/utils/string_utils/formatting_utils.dart @@ -0,0 +1,30 @@ +/// Formatting utilities for various data types +library; + +/// Formatting utilities for bytes, durations, and text indentation +class FormattingUtils { + /// Indent text by specified number of spaces + static String indent(String text, int spaces) { + final indentation = ' ' * spaces; + return text.split('\n').map((line) => '$indentation$line').join('\n'); + } + + /// Format byte size to human-readable string + static String formatBytes(int bytes) { + if (bytes < 1024) return '${bytes}B'; + if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)}KB'; + if (bytes < 1024 * 1024 * 1024) { + return '${(bytes / (1024 * 1024)).toStringAsFixed(1)}MB'; + } + return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)}GB'; + } + + /// Format duration to human-readable string + static String formatDuration(Duration duration) { + if (duration.inMilliseconds >= 1000) { + return '${(duration.inMilliseconds / 1000).toStringAsFixed(2)}秒'; + } else { + return '${duration.inMilliseconds}毫秒'; + } + } +} diff --git a/lib/utils/string_utils/index.dart b/lib/utils/string_utils/index.dart new file mode 100644 index 0000000..115a85a --- /dev/null +++ b/lib/utils/string_utils/index.dart @@ -0,0 +1,9 @@ +/// String utilities - unified export +/// +/// This file provides a single export point for all string utilities +library; + +export 'formatting_utils.dart'; +export 'naming_converter.dart'; +export 'template_service.dart'; +export 'text_cleaner.dart';