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文件路径获取子目录结构 */