Files
wwjcloud-nest-v1/tools-v1/java-tools/generators/service-generator.js
wanwujie 699680c93a feat: 重构v1框架架构和清理整理
- 将preset.ts移动到config目录,符合架构规范
- 迁移php-tools到java-tools,参考Java架构而非PHP
- 清理AI层文档,整合为单一README
- 删除core层,专注boot和ai层
- 集成AI层与Boot层,实现100%组件集成
- 清理废弃js文件和临时报告文件
- 更新导入路径,保持代码一致性
2025-10-20 23:07:37 +08:00

894 lines
30 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const BusinessLogicConverter = require('./business-logic-converter');
/**
* ⚙️ 服务生成器
* 专门负责生成和更新NestJS服务
*/
class ServiceGenerator {
constructor() {
this.config = {
javaBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-java/niucloud-core/src/main/java',
phpBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-php/niucloud', // 用于业务逻辑提取
nestjsBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest-v1/libs/wwjcloud-core/src',
discoveryResultPath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/tools-v1/java-tools/java-discovery-result.json'
};
this.discoveryData = null;
this.converter = new BusinessLogicConverter();
this.stats = {
servicesCreated: 0,
servicesUpdated: 0,
methodsProcessed: 0,
errors: 0
};
}
/**
* 运行服务生成
*/
async run() {
console.log('⚙️ 启动服务生成器...');
try {
// 加载发现数据
await this.loadDiscoveryData();
// 生成服务
await this.generateServices();
// 更新服务为真实业务逻辑
await this.updateAllServicesWithRealLogic();
// 生成统计报告
this.generateStatsReport();
} catch (error) {
console.error('❌ 服务生成过程中发生错误:', error.message);
this.stats.errors++;
throw error;
}
}
/**
* 加载Java架构发现结果含PHP业务逻辑
*/
async loadDiscoveryData() {
try {
const data = fs.readFileSync(this.config.discoveryResultPath, 'utf-8');
this.discoveryData = JSON.parse(data);
console.log(' ✅ 成功加载Java架构发现结果含PHP业务逻辑');
} catch (error) {
console.error(' ❌ 加载发现数据失败:', error.message);
throw error;
}
}
/**
* 按模块动态扫描Java服务层结构参考Java框架架构
*/
async scanJavaModulesAndGenerateServices() {
console.log(' 🔨 扫描Java框架架构生成对应的NestJS服务...');
const javaServicePath = path.join(this.config.javaBasePath, 'com/niu/core/service');
const layers = ['core', 'admin', 'api'];
let processedCount = 0;
// 收集所有模块 - 从Java项目中扫描
const modules = new Set();
for (const layer of layers) {
const layerPath = path.join(javaServicePath, layer);
if (fs.existsSync(layerPath)) {
try {
const moduleDirs = fs.readdirSync(layerPath, { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
moduleDirs.forEach(module => modules.add(module));
console.log(` 📁 发现Java ${layer}层模块: ${moduleDirs.join(', ')}`);
} catch (error) {
console.log(` ⚠️ 无法读取Java ${layer}层目录: ${error.message}`);
}
}
}
console.log(` 📊 发现 ${modules.size} 个模块: ${Array.from(modules).join(', ')}`);
// 为每个模块生成服务 - 按照Java的@Service + @Resource模式
for (const moduleName of modules) {
console.log(` 🔍 处理模块: ${moduleName} (参考Java架构)`);
// 检查模块在各层的存在性 - 扫描Java service/core, service/admin, service/api结构
const moduleLayers = [];
for (const layer of layers) {
const moduleServicePath = path.join(javaServicePath, layer, moduleName);
if (fs.existsSync(moduleServicePath)) {
try {
const files = fs.readdirSync(moduleServicePath, { withFileTypes: true });
const javaFiles = files
.filter(dirent => dirent.isFile() && dirent.name.endsWith('.java') && dirent.name.includes('Impl'))
.map(dirent => dirent.name);
if (javaFiles.length > 0) {
moduleLayers.push({
layer,
serviceFiles: javaFiles,
servicePath: moduleServicePath
});
}
} catch (error) {
console.log(` ⚠️ 无法读取Java模块${moduleName}/${layer}目录: ${error.message}`);
}
}
}
if (moduleLayers.length === 0) {
console.log(` ⚠️ 模块 ${moduleName} 没有任何Java服务文件跳过`);
continue;
}
console.log(` 📁 模块 ${moduleName}${moduleLayers.length} 个Java服务层: ${moduleLayers.map(l => l.layer).join(', ')}`);
// 为每个Java服务层生成对应的NestJS服务 - 按Java架构处理core依赖
for (const { layer, serviceFiles, servicePath } of moduleLayers) {
for (const serviceFile of serviceFiles) {
const javaServicePath = path.join(servicePath, serviceFile);
console.log(` ⚙️ 处理Java服务: ${moduleName}/${layer}/${serviceFile} -> NestJS`);
try {
await this.createNestJSServiceFromJava(moduleName, serviceFile, javaServicePath, layer);
processedCount++;
console.log(` ✅ 成功创建NestJS服务: ${moduleName}/${layer}/${serviceFile}`);
} catch (error) {
console.error(` ❌ 创建NestJS服务失败 ${moduleName}/${layer}/${serviceFile}:`, error.message);
this.stats.errors++;
}
}
}
}
this.stats.servicesCreated = processedCount;
console.log(` ✅ 创建了 ${this.stats.servicesCreated} 个服务`);
}
/**
* 生成服务
*/
async generateServices() {
console.log(' 🔨 生成服务文件...');
// 优先扫描Java项目架构参考Java的@Service和Core依赖模式
await this.scanJavaModulesAndGenerateServices();
// 如果发现数据存在,也尝试基于发现数据生成(作为备选)
if (this.discoveryData.services && Object.keys(this.discoveryData.services).length > 0) {
console.log(' 🔄 基于发现数据补充生成服务...');
await this.generateServicesFromDiscovery();
}
}
/**
* 基于发现数据生成服务(备选方法)
*/
async generateServicesFromDiscovery() {
let processedCount = 0;
// 服务数据结构是按层级分组的,需要遍历所有层级
for (const [layerName, services] of Object.entries(this.discoveryData.services)) {
console.log(` 📁 处理服务层级: ${layerName}, 服务数量: ${Object.keys(services).length}`);
for (const [serviceName, serviceInfo] of Object.entries(services)) {
console.log(` ⚙️ 处理服务: ${serviceName}`);
try {
const correctModuleName = this.extractModuleNameFromServicePath(serviceInfo.filePath);
const layer = this.extractLayerFromServicePath(serviceInfo.filePath);
// 检查Java架构是否有对应的服务目录
if (!this.hasPHPServices(correctModuleName, layer)) {
console.log(` ⚠️ 模块 ${correctModuleName} 在Java架构中无对应且PHP项目中也无${layer}服务,跳过`);
continue;
}
await this.createService(correctModuleName, serviceName, serviceInfo, layer);
processedCount++;
console.log(` ✅ 成功创建服务: ${correctModuleName}/${serviceName}`);
} catch (error) {
console.error(` ❌ 创建服务失败 ${serviceName}:`, error.message);
this.stats.errors++;
}
}
}
console.log(` ✅ 基于发现数据创建了 ${processedCount} 个服务`);
}
/**
* 更新所有服务为真实业务逻辑
*/
async updateAllServicesWithRealLogic() {
console.log(' 🔨 更新服务为真实业务逻辑...');
let processedCount = 0;
// 服务数据结构是按层级分组的,需要遍历所有层级
for (const [layerName, services] of Object.entries(this.discoveryData.services)) {
console.log(` 📁 处理服务层级: ${layerName}, 服务数量: ${Object.keys(services).length}`);
for (const [serviceName, serviceInfo] of Object.entries(services)) {
console.log(` ⚙️ 处理服务: ${serviceName}`);
try {
const correctModuleName = this.extractModuleNameFromServicePath(serviceInfo.filePath);
const layer = this.extractLayerFromServicePath(serviceInfo.filePath);
await this.updateServiceWithRealLogic(correctModuleName, serviceName, serviceInfo, layer);
processedCount++;
console.log(` ✅ 成功更新服务: ${correctModuleName}/${serviceName}`);
} catch (error) {
console.error(` ❌ 更新服务失败 ${serviceName}:`, error.message);
this.stats.errors++;
}
}
}
this.stats.servicesUpdated = processedCount;
console.log(` ✅ 更新了 ${this.stats.servicesUpdated} 个服务`);
}
/**
* 创建服务
*/
async createService(moduleName, serviceName, serviceInfo, layer) {
// 先去掉层级后缀再去掉Service后缀
const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
const servicePath = path.join(
this.config.nestjsBasePath,
moduleName,
'services',
layer,
`${this.toKebabCase(baseName)}.service.ts`
);
// 确保目录存在
const serviceDir = path.dirname(servicePath);
if (!fs.existsSync(serviceDir)) {
fs.mkdirSync(serviceDir, { recursive: true });
}
// 检查是否有对应的PHP服务文件
// 从服务名中提取基础类名去掉_layer后缀
const baseServiceName = serviceName.replace(/_(admin|api|core)$/, '');
const phpServicePath = path.join(this.config.phpBasePath, 'app/service', layer, moduleName, `${baseServiceName}.php`);
if (!fs.existsSync(phpServicePath)) {
console.log(` ❌ 未找到PHP服务文件跳过生成: ${phpServicePath}`);
return;
}
// 生成基础服务内容
const serviceContent = this.generateBasicServiceContent(moduleName, serviceName, layer);
// 写入文件
fs.writeFileSync(servicePath, serviceContent);
console.log(` ✅ 创建服务: ${moduleName}/${layer}/${this.toKebabCase(baseName)}.service.ts`);
this.stats.servicesCreated++;
}
/**
* 从Java服务文件创建NestJS服务 - 参考Java架构处理core依赖
*/
async createNestJSServiceFromJava(moduleName, javaServiceFile, javaFilePath, layer) {
// 确保服务目录存在
const serviceDir = path.join(
this.config.nestjsBasePath,
moduleName,
'services',
layer
);
// 从Java文件名提取服务名去掉Impl和Service后缀
let serviceName = javaServiceFile.replace('.java', '');
if (serviceName.endsWith('ServiceImpl')) {
serviceName = serviceName.replace('ServiceImpl', '');
} else if (serviceName.endsWith('Service')) {
serviceName = serviceName.replace('Service', '');
}
const servicePath = path.join(serviceDir, `${this.toKebabCase(serviceName)}.service.ts`);
// 检查文件是否已存在
if (fs.existsSync(servicePath)) {
console.log(` ⚠️ 服务文件已存在: ${servicePath}`);
return;
}
try {
// 读取Java服务文件
const javaContent = fs.readFileSync(javaFilePath, 'utf-8');
// 解析Java服务的依赖关系特别是core服务依赖
const coreDependencies = this.extractCoreDependencies(javaContent);
const javaMethods = this.extractJavaMethods(javaContent);
console.log(` 📝 从${path.basename(javaFilePath)}中找到 ${javaMethods.length} 个方法`);
console.log(` 🔗 发现Core依赖: ${coreDependencies.join(', ')}`);
// 生成NestJS服务内容处理core依赖
const nestjsContent = this.generateNestJSServiceFromJava(moduleName, serviceName, layer, javaMethods, coreDependencies);
// 确保目录存在
if (!fs.existsSync(serviceDir)) {
fs.mkdirSync(serviceDir, { recursive: true });
}
// 写入文件
fs.writeFileSync(servicePath, nestjsContent, 'utf-8');
console.log(` ✅ 创建NestJS服务: ${moduleName}/${layer}/${this.toKebabCase(serviceName)}.service.ts`);
this.stats.methodsProcessed += javaMethods.length;
this.stats.servicesCreated++;
} catch (error) {
console.log(` ❌ 无法创建NestJS服务 ${serviceName}: ${error.message}`);
this.stats.errors++;
}
}
/**
* 从PHP文件创建NestJS服务 - 参考Java架构使用V1框架基础设施
*/
async createNestJSServiceFromPHP(moduleName, serviceName, phpFilePath, layer) {
// 确保服务目录存在
const serviceDir = path.join(
this.config.nestjsBasePath,
moduleName,
'services',
layer
);
// 先去掉Service后缀
const baseName = serviceName.endsWith('Service') ? serviceName.slice(0, -7) : serviceName;
const servicePath = path.join(serviceDir, `${this.toKebabCase(baseName)}.service.ts`);
// 检查文件是否已存在
if (fs.existsSync(servicePath)) {
console.log(` ⚠️ 服务文件已存在: ${servicePath}`);
return;
}
try {
// 读取PHP服务文件
const phpContent = fs.readFileSync(phpFilePath, 'utf-8');
// 提取PHP方法
const phpMethods = this.converter.extractPHPMethods(phpContent);
console.log(` 📝 从${path.basename(phpFilePath)}中找到 ${phpMethods.length} 个PHP方法`);
// 生成NestJS服务内容
const nestjsContent = phpMethods.length > 0
? this.generateRealServiceContent(moduleName, serviceName, layer, phpMethods)
: this.generateBasicServiceContent(moduleName, serviceName, layer);
// 确保目录存在
if (!fs.existsSync(serviceDir)) {
fs.mkdirSync(serviceDir, { recursive: true });
}
// 写入文件
fs.writeFileSync(servicePath, nestjsContent, 'utf-8');
console.log(` ✅ 创建服务: ${moduleName}/${layer}/${this.toKebabCase(baseName)}.service.ts`);
this.stats.methodsProcessed += phpMethods.length;
this.stats.servicesCreated++;
} catch (error) {
console.log(` ❌ 无法创建服务 ${serviceName}: ${error.message}`);
this.stats.errors++;
}
}
/**
* 更新服务为真实逻辑
*/
async updateServiceWithRealLogic(moduleName, serviceName, serviceInfo, layer) {
// 先去掉层级后缀再去掉Service后缀
const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
const servicePath = path.join(
this.config.nestjsBasePath,
moduleName,
'services',
layer,
`${this.toKebabCase(baseName)}.service.ts`
);
if (!fs.existsSync(servicePath)) {
console.log(` ⚠️ 服务文件不存在: ${servicePath}`);
return;
}
try {
// 读取PHP服务文件
const phpServicePath = serviceInfo.filePath;
const phpContent = fs.readFileSync(phpServicePath, 'utf-8');
// 提取PHP方法
const phpMethods = this.converter.extractPHPMethods(phpContent);
if (phpMethods.length === 0) {
console.log(` ⚠️ 未找到PHP方法: ${serviceName}`);
return;
}
console.log(` 📝 找到 ${phpMethods.length} 个PHP方法`);
// 生成NestJS服务内容
const nestjsContent = this.generateRealServiceContent(moduleName, serviceName, layer, phpMethods);
// 写入文件
fs.writeFileSync(servicePath, nestjsContent);
console.log(` ✅ 更新服务: ${moduleName}/${layer}/${this.toKebabCase(baseName)}.service.ts`);
this.stats.methodsProcessed += phpMethods.length;
} catch (error) {
console.log(` ❌ 无法更新服务 ${serviceName}: ${error.message}`);
this.stats.errors++;
}
}
/**
* 生成基础服务内容
*/
generateBasicServiceContent(moduleName, serviceName, layer) {
// 先去掉层级后缀再去掉Service后缀
const cleanServiceName = serviceName.replace(/_(admin|api|core)$/,'');
const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
// 正确的命名规范服务类名与PHP/Java保持一致
let className = `${baseName}Service`;
if (layer === 'core') {
// Core层服务需要Core前缀
className = baseName.startsWith('Core') ? `${baseName}Service` : `Core${baseName}Service`;
} else {
// admin和api层直接使用业务名称
className = `${baseName}Service`;
}
// 获取V1框架基础设施和Vendor服务导入
const infrastructureImports = this.getV1FrameworkInfrastructureImports();
const vendorImports = this.getV1FrameworkVendorImports();
return `import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
${infrastructureImports}
${vendorImports}
/**
* ${className} - ${layer}层服务
* 参考Java Spring Boot架构@Service注解 + 依赖注入
* 对应Java: @Service + @Resource注入类似CoreAliappConfigServiceImpl
* 使用V1框架基础设施CacheService, MetricsService, TenantService等
* 业务逻辑来源PHP ${moduleName}/${layer}层服务
*/
@Injectable()
export class ${className} {
private readonly logger = new Logger(${className}.name);
constructor(
@InjectRepository(Object)
private readonly repository: Repository<any>,
private readonly configService: ConfigService,
private readonly cacheService: CacheService,
private readonly metricsService: MetricsService,
private readonly tenantService: TenantService,
private readonly uploadService: UploadService,
private readonly payService: PayService,
private readonly smsService: SmsService,
private readonly noticeService: NoticeService,
) {}
// 服务方法基于Java框架风格直接从PHP业务逻辑迁移
// 使用V1框架提供的服务configService, cacheService, metricsService等
}`;
}
/**
* 获取V1框架基础设施导入 - 基于实际V1框架导出
*/
getV1FrameworkInfrastructureImports() {
return `import { ConfigService } from '@nestjs/config';
import { CacheService } from '@wwjcloud-boot/infra/cache/cache.service';
import { MetricsService } from '@wwjcloud-boot/infra/metrics/metrics.service';
import { TenantService } from '@wwjcloud-boot/infra/tenant/tenant.service';`;
}
/**
* 获取V1框架Vendor服务导入 - 基于实际V1框架vendor导出
*/
getV1FrameworkVendorImports() {
return `import { UploadService } from '@wwjcloud-boot/vendor/upload';
import { PayService } from '@wwjcloud-boot/vendor/pay';
import { SmsService } from '@wwjcloud-boot/vendor/sms';
import { NoticeService } from '@wwjcloud-boot/vendor/notice';`;
}
/**
* 生成真实服务内容
*/
generateRealServiceContent(moduleName, serviceName, layer, phpMethods) {
// 先去掉层级后缀再去掉Service后缀
const cleanServiceName = serviceName.replace(/_(admin|api|core)$/, '');
const baseName = cleanServiceName.endsWith('Service') ? cleanServiceName.slice(0, -7) : cleanServiceName;
// 正确的命名规范服务类名与PHP/Java保持一致
let className = `${baseName}Service`;
if (layer === 'core') {
// Core层服务需要Core前缀
className = baseName.startsWith('Core') ? `${baseName}Service` : `Core${baseName}Service`;
} else {
// admin和api层直接使用业务名称
className = `${baseName}Service`;
}
const methodImplementations = phpMethods.filter(method => method && method.name).map(method => {
console.log(`🔍 调试参数: ${method.name}`, method.parameters);
const parameters = this.converter.generateServiceParameters(method.parameters);
const realLogic = this.generateRealServiceLogic(method);
const logic = method.logic || { type: 'real', description: '基于真实PHP业务逻辑' };
return ` /**
* ${method.name}
* 对应 PHP: ${serviceName}::${method.name}()
* 逻辑类型: ${logic.type} - ${logic.description}
*/
async ${method.name}(${parameters}) {
${realLogic}
}`;
}).join('\n\n');
const infrastructureImports = this.getV1FrameworkInfrastructureImports();
const vendorImports = this.getV1FrameworkVendorImports();
return `import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
${infrastructureImports}
${vendorImports}
/**
* ${className} - ${layer}层服务
* 参考Java Spring Boot架构@Service + @Resource模式
* 对应Java实现类似CoreAliappConfigServiceImpl的结构
* 使用V1框架基础设施CacheService, MetricsService, TenantService
* 业务逻辑迁移自PHP ${moduleName}/${layer}层服务
*/
@Injectable()
export class ${className} {
private readonly logger = new Logger(${className}.name);
constructor(
@InjectRepository(Object)
private readonly repository: Repository<any>,
private readonly configService: ConfigService,
private readonly cacheService: CacheService,
private readonly metricsService: MetricsService,
private readonly tenantService: TenantService,
private readonly uploadService: UploadService,
private readonly payService: PayService,
private readonly smsService: SmsService,
private readonly noticeService: NoticeService,
) {}
${methodImplementations}
}
`;
}
/**
* 生成真实服务逻辑
*/
generateRealServiceLogic(method) {
if (!method || !method.name) {
return ` // 方法信息缺失
return { success: false, message: "Method information missing" };`;
}
// 使用method.logic而不是method.body
const phpLogic = method.logic || method.body || '';
if (!phpLogic.trim()) {
return ` // TODO: 实现${method.name}业务逻辑
throw new Error('${method.name} not implemented');`;
}
// 转换PHP代码到TypeScript
const tsBody = this.converter.convertBusinessLogic('', method.name, phpLogic);
return ` // 基于PHP真实逻辑: ${method.name}
// PHP原文: ${phpLogic.substring(0, 150).replace(/\n/g, ' ')}...
${tsBody}`;
}
/**
* 从服务路径提取模块名
*/
extractModuleNameFromServicePath(filePath) {
// 从路径中提取模块名
const pathParts = filePath.split('/');
const serviceIndex = pathParts.findIndex(part => part === 'service');
if (serviceIndex > 0 && serviceIndex < pathParts.length - 2) {
// service目录后面应该是层级(admin/api/core),再后面是模块名
// 路径格式: .../app/service/admin/home/AuthSiteService.php
// 索引: .../8 9 10 11 12
return pathParts[serviceIndex + 2];
}
// 如果找不到service目录尝试从文件名推断
const fileName = path.basename(filePath, '.php');
if (fileName.includes('Service')) {
return fileName.replace('Service', '').toLowerCase();
}
return 'unknown';
}
/**
* 从服务路径提取层级
*/
extractLayerFromServicePath(filePath) {
// 从路径中提取层级信息
if (filePath.includes('/admin/')) {
return 'admin';
} else if (filePath.includes('/api/')) {
return 'api';
} else if (filePath.includes('/core/')) {
return 'core';
}
return 'core'; // 默认为core层
}
/**
* 转换为驼峰命名
*/
toCamelCase(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/\s+/g, '');
}
/**
* 转换为PascalCase
*/
toPascalCase(str) {
return str.replace(/(^|-)([a-z])/g, (match, p1, p2) => p2.toUpperCase());
}
/**
* 转换为kebab-case我们框架的标准命名格式
*/
toKebabCase(str) {
return str
.replace(/([A-Z])/g, '-$1')
.replace(/^-/, '')
.toLowerCase();
}
/**
* 检查模块是否有PHP服务
*/
hasPHPServices(moduleName, layer) {
const phpProjectPath = path.join(__dirname, '../../niucloud-php/niucloud');
const servicePath = path.join(phpProjectPath, 'app/service', layer, moduleName);
if (!fs.existsSync(servicePath)) return false;
// 检查目录内是否有PHP文件
try {
const files = fs.readdirSync(servicePath);
return files.some(file => file.endsWith('.php'));
} catch (error) {
return false;
}
}
/**
* 提取Java服务中的Core依赖关系
*/
extractCoreDependencies(javaContent) {
const coreDependencies = [];
// 查找 @Resource ICore*Service 依赖
const resourcePattern = /@Resource\s+(\w+)\s+(\w+);/g;
const imports = javaContent.match(/import\s+[\w\.]+\.ICore[\w]+Service;?/g) || [];
imports.forEach(importLine => {
const serviceName = importLine.match(/ICore([\w]+)Service/)?.[1];
if (serviceName) {
coreDependencies.push(`Core${serviceName}Service`);
}
});
return coreDependencies;
}
/**
* 提取Java服务的方法
*/
extractJavaMethods(javaContent) {
const methods = [];
// 简单的Java方法提取 - 查找 public 方法
const methodPattern = /public\s+(\w+(?:<\w+>)?)\s+(\w+)\s*\(([^)]*)\)\s*\{/g;
let match;
while ((match = methodPattern.exec(javaContent)) !== null) {
const [fullMatch, returnType, methodName, parameters] = match;
methods.push({
name: methodName,
returnType: returnType,
parameters: parameters.trim(),
body: this.extractMethodBody(javaContent, fullMatch)
});
}
return methods;
}
/**
* 提取方法体(简化版)
*/
extractMethodBody(javaContent, methodStart) {
// 这是一个简化的实现,实际应用中需要更复杂的解析
const startIndex = javaContent.indexOf(methodStart);
if (startIndex === -1) return '';
let braceCount = 0;
let bodyStart = -1;
for (let i = startIndex; i < javaContent.length; i++) {
if (javaContent[i] === '{') {
braceCount++;
if (bodyStart === -1) bodyStart = i + 1;
} else if (javaContent[i] === '}') {
braceCount--;
if (braceCount === 0) {
return javaContent.substring(bodyStart, i).trim();
}
}
}
return '';
}
/**
* 基于Java服务生成NestJS服务内容
*/
generateNestJSServiceFromJava(moduleName, serviceName, layer, javaMethods, coreDependencies) {
const infrastructureImports = this.getV1FrameworkInfrastructureImports();
const vendorImports = this.getV1FrameworkVendorImports();
// 生成core服务依赖的导入
const coreImports = coreDependencies.map(dep => {
const depName = dep.replace('Core', '').replace('Service', '');
return `import { ${dep} } from '../core/${this.toKebabCase(depName)}.service';`;
}).join('\n');
// 生成core服务依赖的注入
const coreInjections = coreDependencies.map(dep => {
const propName = this.toCamelCase(dep.replace('Service', ''));
return ` private readonly ${propName}: ${dep},`;
}).join('\n');
const methodImplementations = javaMethods.map(method => {
return ` /**
* ${method.name}
* 对应Java: ${serviceName}ServiceImpl::${method.name}()
*/
async ${method.name}(${this.convertJavaParametersToTS(method.parameters)}) {
// TODO: 实现 ${method.name} 业务逻辑
// 原始Java逻辑: ${method.body.substring(0, 100)}...
throw new Error('${method.name} not implemented');
}`;
}).join('\n\n');
return `import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
${infrastructureImports}
${vendorImports}
${coreImports}
/**
* ${serviceName}Service - ${layer}层服务
* 对应Java: ${serviceName}ServiceImpl
* 使用V1框架基础设施和Core服务依赖
*/
@Injectable()
export class ${serviceName}Service {
private readonly logger = new Logger(${serviceName}Service.name);
constructor(
@InjectRepository(Object)
private readonly repository: Repository<any>,
private readonly configService: ConfigService,
private readonly cacheService: CacheService,
private readonly metricsService: MetricsService,
private readonly tenantService: TenantService,
private readonly uploadService: UploadService,
private readonly payService: PayService,
private readonly smsService: SmsService,
private readonly noticeService: NoticeService,
${coreInjections}
) {}
${methodImplementations}
}
`;
}
/**
* 转换Java参数到TypeScript参数简化版
*/
convertJavaParametersToTS(javaParameters) {
if (!javaParameters.trim()) return '';
// 简单的Java到TS参数转换
return javaParameters
.split(',')
.map(param => {
const trimmed = param.trim();
const [type, name] = trimmed.split(/\s+/);
if (!name) return trimmed;
const tsType = this.convertJavaTypeToTS(type);
return `${name}: ${tsType}`;
})
.join(', ');
}
/**
* 转换Java类型到TypeScript类型简化版
*/
convertJavaTypeToTS(javaType) {
const typeMap = {
'String': 'string',
'Integer': 'number',
'Long': 'number',
'Boolean': 'boolean',
'List': 'any[]',
'Map': 'Record<string, any>',
'void': 'void'
};
return typeMap[javaType] || 'any';
}
/**
* 生成统计报告
*/
generateStatsReport() {
console.log('\n📊 服务生成统计报告');
console.log('='.repeat(50));
console.log(`✅ 创建服务数量: ${this.stats.servicesCreated}`);
console.log(`🔄 更新服务数量: ${this.stats.servicesUpdated}`);
console.log(`📝 处理方法数量: ${this.stats.methodsProcessed}`);
console.log(`❌ 错误数量: ${this.stats.errors}`);
console.log(`📈 成功率: ${this.stats.servicesCreated > 0 ? ((this.stats.servicesCreated - this.stats.errors) / this.stats.servicesCreated * 100).toFixed(2) : 0}%`);
}
}
// 如果直接运行此文件
if (require.main === module) {
const generator = new ServiceGenerator();
generator.run().catch(console.error);
}
module.exports = ServiceGenerator;