From 15463bfc74eb7fc44d5eeab603e53662320369f0 Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 24 Nov 2025 13:43:15 +0800 Subject: [PATCH] fix: template bugs --- .../retrofit_api/api_schema_extraction.dart | 7 +-- .../impl/retrofit_api/api_template_data.dart | 37 +++++++-------- .../generate/impl/retrofit_api_generator.dart | 1 + .../render/impl/template/template_loader.dart | 46 +++++++++++++++++++ lib/templates/api/api_method.mustache | 4 +- lib/utils/path_resolver.dart | 24 ++++++++++ 6 files changed, 94 insertions(+), 25 deletions(-) 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 2b0fc34..e53e176 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_schema_extraction.dart @@ -122,10 +122,11 @@ mixin RetrofitApiSchema { return 'unnamedMethod'; } + // 直接使用路径最后部分,转换为 camelCase + // 例如: GetTaskTypeInfo -> getTaskTypeInfo + // 不添加 HTTP 方法前缀,保持与 Swagger 文档一致 final lastPart = pathParts.last.replaceAll(RegExp(r'\W+'), ''); - final method = path.method.value.toLowerCase(); - final pascalPart = StringHelper.toPascalCase(lastPart); - final methodName = '$method$pascalPart'; + final methodName = StringHelper.toCamelCase(lastPart); 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 2cbbd22..8a7e2cf 100644 --- a/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart +++ b/lib/pipeline/generate/impl/retrofit_api/api_template_data.dart @@ -54,7 +54,7 @@ mixin RetrofitApiTemplateData { List _getImportsForPaths(List paths) { final imports = {}; final config = ConfigRepository.loadSync(); - + // 添加基础包导入 imports ..add('package:dio/dio.dart') @@ -74,36 +74,26 @@ mixin RetrofitApiTemplateData { /// 获取 models index.dart 的导入路径 String _getModelsIndexImport() { final config = ConfigRepository.loadSync(); - final apiDir = config.apiDir; final modelsDir = config.modelsDir; // 如果配置为空,返回空字符串 - if (apiDir.isEmpty || modelsDir.isEmpty) { + if (modelsDir.isEmpty) { return ''; } - // 获取包名(从 base_result_import 中提取) - final baseResultImport = config.baseResultImport; - if (baseResultImport.isEmpty) { + // 从 pubspec.yaml 获取包名 + final packageName = PathResolver.getPackageName(); + if (packageName == null || packageName.isEmpty) { return ''; } - // 从 base_result_import 中提取包名 - // 例如: "package:example_app/common/base_result.dart" -> "example_app" - final packageMatch = RegExp(r'^package:([^/]+)/').firstMatch(baseResultImport); - if (packageMatch == null) { - return ''; - } - - final packageName = packageMatch.group(1)!; - // 将 models_dir 转换为包导入路径 - // 例如: "./lib/src/api_models" -> "package:example_app/src/api_models/index.dart" - var modelsPath = modelsDir + // 例如: "./lib/src/api_models" -> "package:oa_api_hs/src/api_models/index.dart" + final modelsPath = modelsDir .replaceAll(r'\', '/') .replaceAll('./', '') .replaceAll('lib/', ''); - + return 'package:$packageName/$modelsPath/index.dart'; } @@ -112,17 +102,24 @@ mixin RetrofitApiTemplateData { } Map _buildMethodData(ApiPath path) { + final params = _buildParametersData(path); return { 'docLines': _buildDocLines(path), 'annotations': _buildAnnotations(path), 'returnType': _g._generateReturnType(path), 'methodName': _g._generateSimpleMethodName(path), - 'params': _buildParametersData(path), + 'params': params, + 'hasParams': params.isNotEmpty, }; } List _buildDocLines(ApiPath path) { final docLines = []; + + // 添加 HTTP 方法信息 + final httpMethod = path.method.value.toUpperCase(); + docLines.add('[$httpMethod]'); + if (path.summary.isNotEmpty) { // Clean summary to remove newlines and other problematic characters docLines.add(TextCleaner.cleanDescription(path.summary)); @@ -137,7 +134,7 @@ mixin RetrofitApiTemplateData { List _buildAnnotations(ApiPath path) { final annotations = []; final method = path.method.value.toUpperCase(); - annotations.add('@$method(\'${path.path}\')'); + annotations.add("@$method('${path.path}')"); if (path.isMultipart) { annotations.add('@MultiPart()'); diff --git a/lib/pipeline/generate/impl/retrofit_api_generator.dart b/lib/pipeline/generate/impl/retrofit_api_generator.dart index 72a594e..281ae45 100644 --- a/lib/pipeline/generate/impl/retrofit_api_generator.dart +++ b/lib/pipeline/generate/impl/retrofit_api_generator.dart @@ -2,6 +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/path_resolver.dart'; import 'package:swagger_generator_flutter/utils/string_helper.dart'; import 'package:swagger_generator_flutter/utils/string_utils/index.dart'; diff --git a/lib/pipeline/render/impl/template/template_loader.dart b/lib/pipeline/render/impl/template/template_loader.dart index f2e6622..86bca7a 100644 --- a/lib/pipeline/render/impl/template/template_loader.dart +++ b/lib/pipeline/render/impl/template/template_loader.dart @@ -53,6 +53,10 @@ class TemplateLoader { // 从当前目录向上查找 templates 与 lib/templates _collectUpwardTemplateDirs().forEach(addDir); + // 尝试从包的 lib/templates 目录加载(用于包依赖场景) + final packageTemplateDirs = _findPackageTemplateDirs(); + packageTemplateDirs.forEach(addDir); + return files; } @@ -78,6 +82,48 @@ class TemplateLoader { return dirs; } + /// 查找包的模板目录(用于作为依赖使用时) + List _findPackageTemplateDirs() { + final dirs = []; + + try { + // 尝试从 .dart_tool/package_config.json 解析包路径 + final packageConfigFile = File('.dart_tool/package_config.json'); + if (!packageConfigFile.existsSync()) { + return dirs; + } + + final configContent = packageConfigFile.readAsStringSync(); + + // 简单的正则匹配提取 swagger_generator_flutter 的 rootUri + // 格式示例: "name": "swagger_generator_flutter", ... "rootUri": "file:///path/to/package" + final pattern = RegExp( + r'"name"\s*:\s*"swagger_generator_flutter"[^}]*"rootUri"\s*:\s*"([^"]+)"', + multiLine: true, + ); + + final match = pattern.firstMatch(configContent); + if (match != null) { + var rootUri = match.group(1)!; + + // 移除 file:// 前缀 + if (rootUri.startsWith('file://')) { + rootUri = rootUri.substring(7); + } + + // 添加模板目录路径 + final templateDir = p.join(rootUri, 'lib', 'templates'); + if (Directory(templateDir).existsSync()) { + dirs.add(templateDir); + } + } + } catch (_) { + // 忽略错误,返回空列表 + } + + return dirs; + } + void clearCache() { _cache.clear(); } diff --git a/lib/templates/api/api_method.mustache b/lib/templates/api/api_method.mustache index 73bd743..82a2460 100644 --- a/lib/templates/api/api_method.mustache +++ b/lib/templates/api/api_method.mustache @@ -4,6 +4,6 @@ {{#annotations}} {{.}} {{/annotations}} - Future<{{returnType}}> {{methodName}}( + Future<{{returnType}}> {{methodName}}({{#hasParams}}{ {{#params}} {{#annotation}}{{.}} {{/annotation}}{{type}} {{name}}, -{{/params}} ); +{{/params}} }{{/hasParams}}); diff --git a/lib/utils/path_resolver.dart b/lib/utils/path_resolver.dart index 89382a7..9df1c41 100644 --- a/lib/utils/path_resolver.dart +++ b/lib/utils/path_resolver.dart @@ -47,6 +47,30 @@ class PathResolver { return null; } + /// 获取项目包名(从 pubspec.yaml 中读取) + static String? getPackageName() { + final configDir = getConfigDirectory(); + if (configDir == null) { + return null; + } + + final pubspecFile = File(path.join(configDir, 'pubspec.yaml')); + if (!pubspecFile.existsSync()) { + return null; + } + + try { + final content = pubspecFile.readAsStringSync(); + // 简单的正则匹配提取包名 + // 格式: name: package_name + final match = + RegExp(r'^name:\s*(\S+)', multiLine: true).firstMatch(content); + return match?.group(1); + } catch (_) { + return null; + } + } + /// 解析路径(支持相对路径和绝对路径) /// 如果是相对路径,相对于项目根目录(配置文件所在目录) static String resolvePath(String filePath) {