From 84029fa31561f97d895ecb53c587e9c351a282f1 Mon Sep 17 00:00:00 2001 From: wanwu Date: Sun, 26 Oct 2025 23:26:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Service=E5=92=8CController=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=99=A8=E4=BF=AE=E5=A4=8D=20-=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=E4=BF=9D=E6=8A=A4=E5=B7=B2=E5=AE=9E=E7=8E=B0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=20=F0=9F=94=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ Service生成器修复: 1. 添加isServiceImplemented()检测方法 2. 检查文件是否包含实际业务逻辑: - @InjectRepository - JwtService - bcrypt - await Repository调用 - 非TODO的实际代码 3. 跳过已实现的Service,只覆盖TODO占位符 ✅ Controller生成器修复: 1. 自动识别登录路由: - 路径包含login - 路径包含register - 路径为api(公开API) 2. 自动添加@Public()装饰器 3. 无需手动修改生成的Controller 🎯 效果: - 手动实现的Service不会被覆盖 ✅ - 登录路由自动标记为公开 ✅ - 工具完全自动化,无需手动修改产物 ✅ 📋 修改文件: - service-generator.js: generateService() + isServiceImplemented() - controller-generator.js: generateDecorators() --- .../generators/controller-generator.js | 15 +++++-- .../generators/service-generator.js | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js index 2f7af918..844d1879 100644 --- a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js +++ b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/controller-generator.js @@ -343,14 +343,21 @@ ${methods} // API文档装饰器 decorators.push('@ApiTags(\'API\')'); + // ✅ 修复:自动识别登录路由,添加@Public()装饰器 + const controllerPath = (routeInfo.controllerPath || '').toLowerCase(); + const isLoginRoute = controllerPath.includes('login') || + controllerPath.includes('register') || + controllerPath === 'api' || // Java的/api通常是公开API + controllerPath === 'api/login'; + // 根据路由信息决定是否添加认证守卫 - if (routeInfo.hasClassLevelAuth) { + if (isLoginRoute || routeInfo.hasClassLevelIgnore) { + // 登录/注册路由或Java标记@SaIgnore的路由,自动添加@Public() + decorators.push('@Public()'); + } else if (routeInfo.hasClassLevelAuth) { // 如果类级别有 @SaCheckLogin,添加守卫 decorators.push('@UseGuards(AuthGuard)'); decorators.push('@ApiBearerAuth()'); - } else if (routeInfo.hasClassLevelIgnore) { - // 如果类级别有 @SaIgnore,添加 @Public() - decorators.push('@Public()'); } return decorators.join('\n'); diff --git a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/service-generator.js b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/service-generator.js index b54daeda..328e82ff 100644 --- a/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/service-generator.js +++ b/wwjcloud-nest-v1/tools/java-to-nestjs-migration/generators/service-generator.js @@ -47,6 +47,21 @@ class ServiceGenerator { const fileName = this.namingUtils.generateFileName(javaService.className, 'service'); const filePath = path.join(fullOutputDir, fileName); + // ✅ 修复:检查Service是否已实现,不覆盖已实现的Service + if (fs.existsSync(filePath)) { + const existingContent = fs.readFileSync(filePath, 'utf-8'); + + // 检查是否已实现(不只是TODO占位符) + const isImplemented = this.isServiceImplemented(existingContent); + + if (isImplemented) { + console.log(`⏭️ 跳过已实现服务: ${filePath}`); + return { fileName, content: existingContent, skipped: true }; + } + + console.log(`🔄 覆盖TODO占位服务: ${filePath}`); + } + const content = this.generateServiceContent(javaService, serviceName); fs.writeFileSync(filePath, content); @@ -54,6 +69,30 @@ class ServiceGenerator { return { fileName, content }; } + /** + * 检查Service是否已实现(不只是TODO占位符) + */ + isServiceImplemented(content) { + // 检查是否包含实际业务逻辑的标志: + // 1. 有TypeORM的@InjectRepository + // 2. 有JwtService + // 3. 有bcrypt + // 4. 方法体中不只是return null/undefined + // 5. 有实际的业务代码(非TODO注释) + + const implementationMarkers = [ + /@InjectRepository/, + /JwtService/, + /bcrypt/, + /await.*Repository/, + /this\..*Repository\./, + /async\s+\w+\([^)]*\)\s*:\s*Promise<[^>]+>\s*{\s*[^}]*(?!\/\/\s*TODO)(?!return\s+null)/, + ]; + + // 如果包含任一实现标志,认为是已实现 + return implementationMarkers.some(marker => marker.test(content)); + } + /** * 根据Java文件路径获取子目录结构 */