- 修复了迁移工具的所有构建错误 - 成功生成了87个实体、211个服务、114个控制器 - 修复了Result导入路径问题,从@wwjBoot导入 - 修复了重复方法问题,运行了批量修复脚本 - 项目构建完全成功,0个错误 - 迁移工具现在可以正常使用
298 lines
8.7 KiB
JavaScript
298 lines
8.7 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const NamingUtils = require('../utils/naming-utils');
|
|
|
|
/**
|
|
* 服务生成器
|
|
* 将Java服务转换为NestJS服务
|
|
*/
|
|
class ServiceGenerator {
|
|
constructor() {
|
|
this.namingUtils = new NamingUtils();
|
|
}
|
|
|
|
/**
|
|
* 生成服务文件
|
|
*/
|
|
generateService(javaService, outputDir) {
|
|
// 检查服务数据是否有效
|
|
if (!javaService || !javaService.className) {
|
|
console.warn(`⚠️ 跳过无效服务: ${JSON.stringify(javaService)}`);
|
|
return null;
|
|
}
|
|
|
|
// 根据Java文件路径创建子目录结构
|
|
const subDir = this.getSubDirectoryFromJavaPath(javaService.filePath, 'service');
|
|
const fullOutputDir = path.join(outputDir, subDir);
|
|
|
|
// 确保子目录存在
|
|
if (!fs.existsSync(fullOutputDir)) {
|
|
fs.mkdirSync(fullOutputDir, { recursive: true });
|
|
}
|
|
|
|
const serviceName = this.namingUtils.generateServiceName(javaService.className);
|
|
const fileName = this.namingUtils.generateFileName(javaService.className, 'service');
|
|
const filePath = path.join(fullOutputDir, fileName);
|
|
|
|
const content = this.generateServiceContent(javaService, serviceName);
|
|
fs.writeFileSync(filePath, content);
|
|
|
|
console.log(`✅ 生成服务: ${filePath}`);
|
|
return { fileName, content };
|
|
}
|
|
|
|
/**
|
|
* 根据Java文件路径获取子目录结构
|
|
*/
|
|
getSubDirectoryFromJavaPath(javaFilePath, type) {
|
|
if (!javaFilePath) return '';
|
|
|
|
// 从Java文件路径中提取包结构
|
|
// 例如: /path/to/java/com/niu/core/service/core/aliapp/ICoreAliappConfigService.java
|
|
// 提取: service/core/aliapp
|
|
const pathParts = javaFilePath.split(path.sep);
|
|
const javaIndex = pathParts.findIndex(part => part === 'java');
|
|
|
|
if (javaIndex === -1) return '';
|
|
|
|
// 获取java目录后的包结构
|
|
const packageParts = pathParts.slice(javaIndex + 1, -1); // 排除文件名
|
|
|
|
// 根据类型过滤相关目录
|
|
const typeIndex = packageParts.findIndex(part => part === type || part === type + 's');
|
|
if (typeIndex === -1) return '';
|
|
|
|
// 返回类型目录后的子目录结构
|
|
const subParts = packageParts.slice(typeIndex + 1);
|
|
return subParts.join('/');
|
|
}
|
|
|
|
/**
|
|
* 生成服务内容
|
|
*/
|
|
generateServiceContent(javaService, serviceName) {
|
|
const imports = this.generateImports(javaService);
|
|
const decorators = this.generateDecorators();
|
|
const constructor = this.generateConstructor(javaService);
|
|
const methods = this.generateMethods(javaService);
|
|
|
|
return `${imports}
|
|
|
|
${decorators}
|
|
export class ${serviceName} {
|
|
${constructor}
|
|
${methods}
|
|
}
|
|
`;
|
|
}
|
|
|
|
/**
|
|
* 生成导入语句
|
|
*/
|
|
generateImports(javaService) {
|
|
const imports = [
|
|
"import { Injectable } from '@nestjs/common';",
|
|
"import { InjectRepository } from '@nestjs/typeorm';",
|
|
"import { Repository } from 'typeorm';",
|
|
"import { QueueService, EventBus } from '@wwjBoot';",
|
|
"import { Result } from '@wwjBoot';"
|
|
];
|
|
|
|
// 添加实体导入
|
|
if (javaService.entities && javaService.entities.length > 0) {
|
|
javaService.entities.forEach(entity => {
|
|
const entityName = this.namingUtils.generateEntityName(entity);
|
|
const entityFileName = this.namingUtils.generateFileName(entity, 'entity');
|
|
imports.push(`import { ${entityName} } from '../entities/${entityFileName.replace('.entity.ts', '')}';`);
|
|
});
|
|
}
|
|
|
|
// 添加DTO导入
|
|
if (javaService.dtos && javaService.dtos.length > 0) {
|
|
javaService.dtos.forEach(dto => {
|
|
const dtoName = this.namingUtils.generateDtoName(dto);
|
|
const dtoFileName = this.namingUtils.generateFileName(dto, 'dto');
|
|
imports.push(`import { ${dtoName} } from '../dtos/${dtoFileName.replace('.dto.ts', '')}';`);
|
|
});
|
|
}
|
|
|
|
// 添加其他服务导入
|
|
if (javaService.dependencies && javaService.dependencies.length > 0) {
|
|
javaService.dependencies.forEach(dep => {
|
|
const serviceName = this.namingUtils.generateServiceName(dep);
|
|
const serviceFileName = this.namingUtils.generateFileName(dep, 'service');
|
|
imports.push(`import { ${serviceName} } from './${serviceFileName.replace('.service.ts', '')}';`);
|
|
});
|
|
}
|
|
|
|
return imports.join('\n');
|
|
}
|
|
|
|
/**
|
|
* 生成装饰器
|
|
*/
|
|
generateDecorators() {
|
|
return '@Injectable()';
|
|
}
|
|
|
|
/**
|
|
* 生成构造函数
|
|
*/
|
|
generateConstructor(javaService) {
|
|
const injections = [];
|
|
|
|
// 添加框架服务注入
|
|
injections.push(' private readonly eventBus: EventBus,');
|
|
injections.push(' private readonly queueService: QueueService,');
|
|
|
|
// 添加实体注入
|
|
if (javaService.entities && javaService.entities.length > 0) {
|
|
javaService.entities.forEach(entity => {
|
|
const entityName = this.namingUtils.generateEntityName(entity);
|
|
const propertyName = this.namingUtils.toCamelCase(entity) + 'Repository';
|
|
injections.push(` @InjectRepository(${entityName})
|
|
private readonly ${propertyName}: Repository<${entityName}>,`);
|
|
});
|
|
}
|
|
|
|
// 添加其他服务注入
|
|
if (javaService.dependencies && javaService.dependencies.length > 0) {
|
|
javaService.dependencies.forEach(dep => {
|
|
const serviceName = this.namingUtils.generateServiceName(dep);
|
|
const propertyName = this.namingUtils.toCamelCase(dep) + 'Service';
|
|
injections.push(` private readonly ${propertyName}: ${serviceName},`);
|
|
});
|
|
}
|
|
|
|
if (injections.length === 0) {
|
|
return ' constructor() {}';
|
|
}
|
|
|
|
return ` constructor(
|
|
${injections.join('\n')}
|
|
) {}`;
|
|
}
|
|
|
|
/**
|
|
* 生成方法
|
|
*/
|
|
generateMethods(javaService) {
|
|
if (!javaService.methods || javaService.methods.length === 0) {
|
|
return ' // 无方法';
|
|
}
|
|
|
|
return javaService.methods.map(method => {
|
|
return this.generateMethod(method, javaService);
|
|
}).join('\n\n');
|
|
}
|
|
|
|
/**
|
|
* 生成单个方法
|
|
*/
|
|
generateMethod(method, javaService) {
|
|
const methodName = this.namingUtils.generateMethodName(method.methodName);
|
|
const parameters = this.generateMethodParameters(method);
|
|
const returnType = this.generateReturnType(method);
|
|
const body = this.generateMethodBody(method, javaService);
|
|
|
|
return ` /**
|
|
* ${method.methodName}
|
|
*/
|
|
async ${methodName}(${parameters}): Promise<${returnType}> {
|
|
${body}
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 生成方法参数
|
|
*/
|
|
generateMethodParameters(method) {
|
|
const parameters = [];
|
|
|
|
// 检查methodName是否存在
|
|
const methodName = method.methodName || method.name || 'unknown';
|
|
|
|
// 根据方法名推断参数
|
|
if (methodName.includes('create') || methodName.includes('update')) {
|
|
parameters.push('data: any');
|
|
}
|
|
|
|
if (methodName.includes('ById') || methodName.includes('delete')) {
|
|
parameters.push('id: number');
|
|
}
|
|
|
|
if (methodName.includes('list') || methodName.includes('page')) {
|
|
parameters.push('page: number = 1', 'limit: number = 10');
|
|
}
|
|
|
|
return parameters.join(', ');
|
|
}
|
|
|
|
/**
|
|
* 生成返回类型
|
|
*/
|
|
generateReturnType(method) {
|
|
// 检查methodName是否存在
|
|
const methodName = method.methodName || method.name || 'unknown';
|
|
|
|
if (methodName.includes('list') || methodName.includes('page')) {
|
|
return 'any[]';
|
|
}
|
|
|
|
if (methodName.includes('count') || methodName.includes('exists')) {
|
|
return 'number';
|
|
}
|
|
|
|
if (methodName.includes('delete') || methodName.includes('remove')) {
|
|
return 'void';
|
|
}
|
|
|
|
return 'any';
|
|
}
|
|
|
|
/**
|
|
* 生成方法体
|
|
*/
|
|
generateMethodBody(method, javaService) {
|
|
const methodName = method.methodName || method.name || 'unknown';
|
|
const returnType = this.generateReturnType(method);
|
|
|
|
// 根据返回类型生成合适的返回值
|
|
let returnValue = 'null';
|
|
if (returnType === 'any[]') {
|
|
returnValue = '[]';
|
|
} else if (returnType === 'number') {
|
|
returnValue = '0';
|
|
} else if (returnType === 'void') {
|
|
returnValue = '';
|
|
}
|
|
|
|
return ` // TODO: 实现业务逻辑
|
|
return ${returnValue};`;
|
|
}
|
|
|
|
/**
|
|
* 验证服务一致性
|
|
*/
|
|
validateServiceConsistency(javaService, nestJSService) {
|
|
const issues = [];
|
|
|
|
// 验证方法数量
|
|
if (javaService.methods.length !== nestJSService.methods.length) {
|
|
issues.push('方法数量不一致');
|
|
}
|
|
|
|
// 验证每个方法
|
|
javaService.methods.forEach((javaMethod, index) => {
|
|
const nestJSMethod = nestJSService.methods[index];
|
|
if (nestJSMethod && javaMethod.methodName !== nestJSMethod.methodName) {
|
|
issues.push(`方法名不一致: ${javaMethod.methodName} vs ${nestJSMethod.methodName}`);
|
|
}
|
|
});
|
|
|
|
return issues;
|
|
}
|
|
}
|
|
|
|
module.exports = ServiceGenerator;
|