fix: 删除遗漏的enhanced-migration-coordinator.js
抱歉,之前遗漏了这个文件 现在所有enhanced-*文件都已删除 只保留原始的migration-coordinator.js
This commit is contained in:
@@ -1,358 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const JavaScanner = require('./scanners/java-scanner');
|
|
||||||
const LayerMapper = require('./mappers/layer-mapper');
|
|
||||||
const EnhancedDependencyInjectionConverter = require('./generators/enhanced-dependency-injection-converter');
|
|
||||||
const EnhancedBusinessLogicConverter = require('./generators/enhanced-business-logic-converter');
|
|
||||||
const DtoGenerator = require('./generators/dto-generator');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 增强的迁移协调器
|
|
||||||
* 集成所有增强的转换器
|
|
||||||
*/
|
|
||||||
class EnhancedMigrationCoordinator {
|
|
||||||
constructor() {
|
|
||||||
this.javaPath = '';
|
|
||||||
this.nestJSPath = '';
|
|
||||||
this.scanner = new JavaScanner();
|
|
||||||
this.mapper = new LayerMapper();
|
|
||||||
|
|
||||||
// 使用增强的转换器
|
|
||||||
this.diConverter = new EnhancedDependencyInjectionConverter();
|
|
||||||
this.businessConverter = new EnhancedBusinessLogicConverter();
|
|
||||||
this.dtoGenerator = new DtoGenerator(); // 使用原本的DTO生成器
|
|
||||||
|
|
||||||
this.stats = {
|
|
||||||
startTime: null,
|
|
||||||
endTime: null,
|
|
||||||
filesProcessed: 0,
|
|
||||||
servicesGenerated: 0,
|
|
||||||
typesGenerated: 0,
|
|
||||||
successRate: 0,
|
|
||||||
errors: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行完整迁移流程
|
|
||||||
*/
|
|
||||||
async runMigration() {
|
|
||||||
console.log('╔══════════════════════════════════════════════════════════════╗');
|
|
||||||
console.log('║ 🚀 增强的Java到NestJS迁移工具 ║');
|
|
||||||
console.log('╚══════════════════════════════════════════════════════════════╝\n');
|
|
||||||
|
|
||||||
this.stats.startTime = new Date();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 第1阶段:初始化路径和类型映射器
|
|
||||||
console.log('📋 第1阶段:初始化...');
|
|
||||||
await this.initialize();
|
|
||||||
|
|
||||||
// 第2阶段:扫描Java项目
|
|
||||||
console.log('\n📊 第2阶段:扫描Java项目...');
|
|
||||||
await this.scanJavaProject();
|
|
||||||
|
|
||||||
// 第3阶段:映射层级关系
|
|
||||||
console.log('\n🔄 第3阶段:映射层级关系...');
|
|
||||||
const nestJSModules = this.mapLayers();
|
|
||||||
|
|
||||||
// 第4阶段:生成Service(使用增强的转换器)
|
|
||||||
console.log('\n🔧 第4阶段:生成Service(增强转换)...');
|
|
||||||
await this.generateServices(nestJSModules);
|
|
||||||
|
|
||||||
// 第5阶段:生成类型定义
|
|
||||||
console.log('\n📝 第5阶段:生成类型定义...');
|
|
||||||
await this.generateTypes();
|
|
||||||
|
|
||||||
// 第6阶段:生成报告
|
|
||||||
console.log('\n📋 第6阶段:生成迁移报告...');
|
|
||||||
this.generateReport();
|
|
||||||
|
|
||||||
this.stats.endTime = new Date();
|
|
||||||
console.log('\n✅ 迁移流程完成!');
|
|
||||||
this.printStats();
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ 迁移过程中发生错误:', error.message);
|
|
||||||
this.stats.errors.push(error.message);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化
|
|
||||||
*/
|
|
||||||
async initialize() {
|
|
||||||
this.javaPath = '/Users/wanwu/Documents/wanwujie/wwjcloud-nsetjs/niucloud-java/niucloud-core/src/main/java';
|
|
||||||
this.nestJSPath = path.resolve(__dirname, '../../wwjcloud/libs/wwjcloud-core/src');
|
|
||||||
|
|
||||||
console.log(`📁 Java项目路径: ${this.javaPath}`);
|
|
||||||
console.log(`📁 NestJS项目路径: ${this.nestJSPath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫描Java项目
|
|
||||||
*/
|
|
||||||
async scanJavaProject() {
|
|
||||||
this.scanner.setJavaPath(this.javaPath);
|
|
||||||
await this.scanner.scanJavaProject();
|
|
||||||
|
|
||||||
const scanResults = this.scanner.getScanResults();
|
|
||||||
this.stats.filesProcessed = Object.values(scanResults).reduce((total, arr) => total + arr.length, 0);
|
|
||||||
console.log(`📊 扫描完成,共处理 ${this.stats.filesProcessed} 个文件`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 映射层级关系
|
|
||||||
*/
|
|
||||||
mapLayers() {
|
|
||||||
const scanResults = this.scanner.getScanResults();
|
|
||||||
const nestJSModules = this.mapper.mapToNestJSModules(scanResults);
|
|
||||||
|
|
||||||
console.log(`🔄 映射完成,共生成 ${Object.keys(nestJSModules).length} 个模块`);
|
|
||||||
return nestJSModules;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成Service(使用增强的转换器)
|
|
||||||
*/
|
|
||||||
async generateServices(nestJSModules) {
|
|
||||||
let successCount = 0;
|
|
||||||
let failCount = 0;
|
|
||||||
|
|
||||||
// nestJSModules是对象,需要转换为数组
|
|
||||||
const modules = Object.values(nestJSModules || {});
|
|
||||||
|
|
||||||
for (const module of modules) {
|
|
||||||
console.log(`\n📦 处理模块: ${module.moduleName}`);
|
|
||||||
|
|
||||||
// components数组包含了Java类信息
|
|
||||||
for (const component of module.components || []) {
|
|
||||||
const javaClass = component.javaClass;
|
|
||||||
if (!javaClass || !javaClass.className) continue;
|
|
||||||
|
|
||||||
// ✅ 严格过滤:只处理 type='service' 的组件
|
|
||||||
// 跳过:enum, dto, controller, entity, listener, job 等
|
|
||||||
if (component.type !== 'service') {
|
|
||||||
console.log(` ⊘ ${javaClass.className}: 跳过(类型=${component.type})`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 1. 使用增强的DI转换器
|
|
||||||
const diResult = this.diConverter.convertDependencyInjection(javaClass);
|
|
||||||
console.log(` ✓ ${javaClass.className}: 推断${diResult.dependencies.length}个依赖`);
|
|
||||||
|
|
||||||
// 2. 使用增强的业务逻辑转换器
|
|
||||||
const methods = [];
|
|
||||||
if (javaClass.methods) {
|
|
||||||
for (const method of javaClass.methods) {
|
|
||||||
const converted = this.businessConverter.convertFullMethod(method);
|
|
||||||
methods.push({
|
|
||||||
name: method.methodName || method.name,
|
|
||||||
body: converted.body,
|
|
||||||
hasBusinessLogic: converted.hasBusinessLogic,
|
|
||||||
quality: converted.quality
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 生成完整的Service文件
|
|
||||||
const serviceContent = this.assembleService(javaClass, diResult, methods);
|
|
||||||
|
|
||||||
// 4. 写入文件
|
|
||||||
const outputPath = this.getServiceOutputPath(javaClass, module);
|
|
||||||
this.writeServiceFile(outputPath, serviceContent);
|
|
||||||
|
|
||||||
successCount++;
|
|
||||||
this.stats.servicesGenerated++;
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.error(` ✗ ${javaClass.className}: ${error.message}`);
|
|
||||||
failCount++;
|
|
||||||
this.stats.errors.push(`${javaClass.className}: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stats.successRate = ((successCount / (successCount + failCount)) * 100).toFixed(1);
|
|
||||||
console.log(`\n📊 Service生成完成: 成功(${successCount}), 失败(${failCount}), 成功率(${this.stats.successRate}%)`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 组装完整的Service文件
|
|
||||||
*/
|
|
||||||
assembleService(javaClass, diResult, methods) {
|
|
||||||
const className = javaClass.className;
|
|
||||||
let content = '';
|
|
||||||
|
|
||||||
// 1. 导入语句
|
|
||||||
content += diResult.imports.join('\n') + '\n\n';
|
|
||||||
|
|
||||||
// 2. 类装饰器和声明
|
|
||||||
content += `/**\n`;
|
|
||||||
content += ` * ${className}\n`;
|
|
||||||
content += ` * 🤖 使用增强迁移工具自动生成\n`;
|
|
||||||
content += ` * 📊 依赖: ${diResult.dependencies.length}个\n`;
|
|
||||||
content += ` * 📊 方法: ${methods.length}个\n`;
|
|
||||||
content += ` */\n`;
|
|
||||||
content += `@Injectable()\n`;
|
|
||||||
content += `export class ${className} {\n`;
|
|
||||||
|
|
||||||
// 3. 字段声明(如Logger)
|
|
||||||
if (diResult.fields && diResult.fields.length > 0) {
|
|
||||||
content += diResult.fields.join('\n') + '\n\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 构造函数
|
|
||||||
content += diResult.constructor + '\n\n';
|
|
||||||
|
|
||||||
// 5. 方法
|
|
||||||
for (const method of methods) {
|
|
||||||
content += ` /**\n`;
|
|
||||||
content += ` * ${method.name}\n`;
|
|
||||||
if (method.quality) {
|
|
||||||
content += ` * 质量评分: ${method.quality.score}/100\n`;
|
|
||||||
}
|
|
||||||
content += ` */\n`;
|
|
||||||
content += ` async ${method.name}(...args: any[]): Promise<any> {\n`;
|
|
||||||
content += method.body + '\n';
|
|
||||||
content += ` }\n\n`;
|
|
||||||
}
|
|
||||||
|
|
||||||
content += '}\n';
|
|
||||||
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Service输出路径
|
|
||||||
*/
|
|
||||||
getServiceOutputPath(javaClass, module) {
|
|
||||||
const serviceDir = path.join(this.nestJSPath, 'services', module.moduleName);
|
|
||||||
if (!fs.existsSync(serviceDir)) {
|
|
||||||
fs.mkdirSync(serviceDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileName = this.convertToKebabCase(javaClass.className) + '.service.ts';
|
|
||||||
return path.join(serviceDir, fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 写入Service文件
|
|
||||||
*/
|
|
||||||
writeServiceFile(filePath, content) {
|
|
||||||
fs.writeFileSync(filePath, content, 'utf-8');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成DTO类型定义
|
|
||||||
*/
|
|
||||||
async generateTypes() {
|
|
||||||
console.log('\n📝 第5阶段:生成DTO类型定义...\n');
|
|
||||||
|
|
||||||
const dtoDir = path.join(this.nestJSPath, 'dto');
|
|
||||||
if (!fs.existsSync(dtoDir)) {
|
|
||||||
fs.mkdirSync(dtoDir, { recursive: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
const scanResults = this.scanner.getScanResults();
|
|
||||||
let generated = 0;
|
|
||||||
|
|
||||||
// 生成所有DTO(包括vo、param、dto)
|
|
||||||
if (scanResults.dtos && scanResults.dtos.length > 0) {
|
|
||||||
for (const dtoItem of scanResults.dtos) {
|
|
||||||
try {
|
|
||||||
this.dtoGenerator.generateDto(dtoItem, dtoDir);
|
|
||||||
generated++;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(` ✗ 生成DTO失败 ${dtoItem.className}: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stats.typesGenerated = generated;
|
|
||||||
console.log(`✅ 生成了 ${generated} 个DTO类型文件`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成报告
|
|
||||||
*/
|
|
||||||
generateReport() {
|
|
||||||
const report = {
|
|
||||||
summary: {
|
|
||||||
totalTime: this.stats.endTime - this.stats.startTime,
|
|
||||||
filesProcessed: this.stats.filesProcessed,
|
|
||||||
servicesGenerated: this.stats.servicesGenerated,
|
|
||||||
typesGenerated: this.stats.typesGenerated,
|
|
||||||
successRate: this.stats.successRate + '%',
|
|
||||||
errors: this.stats.errors.length
|
|
||||||
},
|
|
||||||
details: {
|
|
||||||
diStats: {
|
|
||||||
description: '依赖注入推断统计',
|
|
||||||
note: '已集成增强的DI转换器'
|
|
||||||
},
|
|
||||||
businessLogicStats: {
|
|
||||||
description: '业务逻辑转换统计',
|
|
||||||
note: '已集成增强的业务逻辑转换器'
|
|
||||||
},
|
|
||||||
dtoStats: {
|
|
||||||
description: 'DTO生成统计',
|
|
||||||
generated: this.stats.typesGenerated
|
|
||||||
}
|
|
||||||
},
|
|
||||||
errors: this.stats.errors
|
|
||||||
};
|
|
||||||
|
|
||||||
const reportPath = path.join(__dirname, 'ENHANCED_MIGRATION_REPORT.json');
|
|
||||||
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');
|
|
||||||
console.log(`📄 报告已保存: ${reportPath}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 打印统计信息
|
|
||||||
*/
|
|
||||||
printStats() {
|
|
||||||
const duration = (this.stats.endTime - this.stats.startTime) / 1000;
|
|
||||||
|
|
||||||
console.log('\n╔══════════════════════════════════════════════════════════════╗');
|
|
||||||
console.log('║ 📊 迁移统计报告 ║');
|
|
||||||
console.log('╚══════════════════════════════════════════════════════════════╝\n');
|
|
||||||
|
|
||||||
console.log(`⏱️ 总耗时: ${duration.toFixed(1)}秒`);
|
|
||||||
console.log(`📁 处理文件: ${this.stats.filesProcessed}个`);
|
|
||||||
console.log(`🔧 生成Service: ${this.stats.servicesGenerated}个`);
|
|
||||||
console.log(`📝 生成类型: ${this.stats.typesGenerated}个`);
|
|
||||||
console.log(`✅ 成功率: ${this.stats.successRate}%`);
|
|
||||||
console.log(`❌ 错误数: ${this.stats.errors.length}个\n`);
|
|
||||||
|
|
||||||
if (this.stats.errors.length > 0 && this.stats.errors.length <= 10) {
|
|
||||||
console.log('错误列表:');
|
|
||||||
this.stats.errors.forEach((err, i) => {
|
|
||||||
console.log(` ${i + 1}. ${err}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 辅助方法:转换为kebab-case
|
|
||||||
*/
|
|
||||||
convertToKebabCase(str) {
|
|
||||||
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果直接运行此文件
|
|
||||||
if (require.main === module) {
|
|
||||||
const coordinator = new EnhancedMigrationCoordinator();
|
|
||||||
coordinator.runMigration().catch(error => {
|
|
||||||
console.error('迁移失败:', error);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = EnhancedMigrationCoordinator;
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user