- 修复了迁移工具的所有构建错误 - 成功生成了87个实体、211个服务、114个控制器 - 修复了Result导入路径问题,从@wwjBoot导入 - 修复了重复方法问题,运行了批量修复脚本 - 项目构建完全成功,0个错误 - 迁移工具现在可以正常使用
494 lines
12 KiB
JavaScript
494 lines
12 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const NamingUtils = require('../utils/naming-utils');
|
|
|
|
/**
|
|
* 事件转换器
|
|
* 将Java事件处理转换为NestJS事件处理
|
|
*/
|
|
class EventConverter {
|
|
constructor() {
|
|
this.namingUtils = new NamingUtils();
|
|
}
|
|
|
|
/**
|
|
* 转换Java事件到NestJS事件
|
|
*/
|
|
convertEvent(javaEvent) {
|
|
const eventInfo = this.extractEventInfo(javaEvent);
|
|
const decorators = this.generateEventDecorators(eventInfo);
|
|
const imports = this.generateEventImports(eventInfo);
|
|
const body = this.convertEventBody(javaEvent, eventInfo);
|
|
|
|
return {
|
|
eventInfo,
|
|
decorators,
|
|
imports,
|
|
body
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 提取Java事件信息
|
|
*/
|
|
extractEventInfo(javaEvent) {
|
|
const eventInfo = {
|
|
type: 'application',
|
|
name: '',
|
|
payload: {},
|
|
timestamp: new Date(),
|
|
source: '',
|
|
target: '',
|
|
async: false,
|
|
priority: 'normal'
|
|
};
|
|
|
|
if (javaEvent.annotations && javaEvent.annotations.includes('@EventListener')) {
|
|
eventInfo.type = 'listener';
|
|
|
|
// 提取事件名称
|
|
const eventListenerAnnotation = javaEvent.annotations.find(ann => ann.startsWith('@EventListener'));
|
|
if (eventListenerAnnotation) {
|
|
const nameMatch = eventListenerAnnotation.match(/value\s*=\s*["']([^"']+)["']/);
|
|
if (nameMatch) {
|
|
eventInfo.name = nameMatch[1];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (javaEvent.annotations && javaEvent.annotations.includes('@Async')) {
|
|
eventInfo.async = true;
|
|
}
|
|
|
|
if (javaEvent.annotations && javaEvent.annotations.includes('@Order')) {
|
|
const orderAnnotation = javaEvent.annotations.find(ann => ann.startsWith('@Order'));
|
|
if (orderAnnotation) {
|
|
const orderMatch = orderAnnotation.match(/value\s*=\s*(\d+)/);
|
|
if (orderMatch) {
|
|
eventInfo.priority = this.mapPriority(parseInt(orderMatch[1]));
|
|
}
|
|
}
|
|
}
|
|
|
|
return eventInfo;
|
|
}
|
|
|
|
/**
|
|
* 映射优先级
|
|
*/
|
|
mapPriority(order) {
|
|
if (order <= 0) {
|
|
return 'high';
|
|
} else if (order <= 100) {
|
|
return 'normal';
|
|
} else {
|
|
return 'low';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 生成事件装饰器
|
|
*/
|
|
generateEventDecorators(eventInfo) {
|
|
const decorators = [];
|
|
|
|
if (eventInfo.type === 'listener') {
|
|
decorators.push(`@OnEvent('${eventInfo.name}')`);
|
|
|
|
if (eventInfo.async) {
|
|
decorators.push('@Async()');
|
|
}
|
|
|
|
if (eventInfo.priority !== 'normal') {
|
|
decorators.push(`@Order(${this.mapOrderToNumber(eventInfo.priority)})`);
|
|
}
|
|
}
|
|
|
|
return decorators;
|
|
}
|
|
|
|
/**
|
|
* 映射优先级到数字
|
|
*/
|
|
mapOrderToNumber(priority) {
|
|
const priorityMap = {
|
|
'high': 0,
|
|
'normal': 100,
|
|
'low': 200
|
|
};
|
|
|
|
return priorityMap[priority] || 100;
|
|
}
|
|
|
|
/**
|
|
* 生成事件导入
|
|
*/
|
|
generateEventImports(eventInfo) {
|
|
const imports = [];
|
|
|
|
if (eventInfo.type === 'listener') {
|
|
imports.push("import { OnEvent } from '@nestjs/event-emitter';");
|
|
imports.push("import { EventBus } from '@wwjBoot';");
|
|
|
|
if (eventInfo.async) {
|
|
imports.push("import { Async } from '@nestjs/common';");
|
|
}
|
|
|
|
if (eventInfo.priority !== 'normal') {
|
|
imports.push("import { Order } from '@nestjs/common';");
|
|
}
|
|
}
|
|
|
|
return imports;
|
|
}
|
|
|
|
/**
|
|
* 转换事件方法体
|
|
*/
|
|
convertEventBody(javaEvent, eventInfo) {
|
|
const methodName = javaEvent.methodName;
|
|
|
|
if (methodName.includes('user')) {
|
|
return this.convertUserEventBody(javaEvent, eventInfo);
|
|
}
|
|
|
|
if (methodName.includes('order')) {
|
|
return this.convertOrderEventBody(javaEvent, eventInfo);
|
|
}
|
|
|
|
if (methodName.includes('payment')) {
|
|
return this.convertPaymentEventBody(javaEvent, eventInfo);
|
|
}
|
|
|
|
if (methodName.includes('notification')) {
|
|
return this.convertNotificationEventBody(javaEvent, eventInfo);
|
|
}
|
|
|
|
return this.convertDefaultEventBody(javaEvent, eventInfo);
|
|
}
|
|
|
|
/**
|
|
* 转换用户事件方法体
|
|
*/
|
|
convertUserEventBody(javaEvent, eventInfo) {
|
|
return ` this.logger.log('处理用户事件:', event);
|
|
try {
|
|
// 处理用户创建事件
|
|
if (event.type === 'user.created') {
|
|
await this.handleUserCreated(event);
|
|
}
|
|
|
|
// 处理用户更新事件
|
|
if (event.type === 'user.updated') {
|
|
await this.handleUserUpdated(event);
|
|
}
|
|
|
|
// 处理用户删除事件
|
|
if (event.type === 'user.deleted') {
|
|
await this.handleUserDeleted(event);
|
|
}
|
|
|
|
this.logger.log('用户事件处理完成');
|
|
} catch (error) {
|
|
this.logger.error('用户事件处理失败:', error);
|
|
throw error;
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 转换订单事件方法体
|
|
*/
|
|
convertOrderEventBody(javaEvent, eventInfo) {
|
|
return ` this.logger.log('处理订单事件:', event);
|
|
try {
|
|
// 处理订单创建事件
|
|
if (event.type === 'order.created') {
|
|
await this.handleOrderCreated(event);
|
|
}
|
|
|
|
// 处理订单更新事件
|
|
if (event.type === 'order.updated') {
|
|
await this.handleOrderUpdated(event);
|
|
}
|
|
|
|
// 处理订单取消事件
|
|
if (event.type === 'order.cancelled') {
|
|
await this.handleOrderCancelled(event);
|
|
}
|
|
|
|
this.logger.log('订单事件处理完成');
|
|
} catch (error) {
|
|
this.logger.error('订单事件处理失败:', error);
|
|
throw error;
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 转换支付事件方法体
|
|
*/
|
|
convertPaymentEventBody(javaEvent, eventInfo) {
|
|
return ` this.logger.log('处理支付事件:', event);
|
|
try {
|
|
// 处理支付成功事件
|
|
if (event.type === 'payment.success') {
|
|
await this.handlePaymentSuccess(event);
|
|
}
|
|
|
|
// 处理支付失败事件
|
|
if (event.type === 'payment.failed') {
|
|
await this.handlePaymentFailed(event);
|
|
}
|
|
|
|
// 处理支付退款事件
|
|
if (event.type === 'payment.refunded') {
|
|
await this.handlePaymentRefunded(event);
|
|
}
|
|
|
|
this.logger.log('支付事件处理完成');
|
|
} catch (error) {
|
|
this.logger.error('支付事件处理失败:', error);
|
|
throw error;
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 转换通知事件方法体
|
|
*/
|
|
convertNotificationEventBody(javaEvent, eventInfo) {
|
|
return ` this.logger.log('处理通知事件:', event);
|
|
try {
|
|
// 处理邮件通知事件
|
|
if (event.type === 'notification.email') {
|
|
await this.handleEmailNotification(event);
|
|
}
|
|
|
|
// 处理短信通知事件
|
|
if (event.type === 'notification.sms') {
|
|
await this.handleSmsNotification(event);
|
|
}
|
|
|
|
// 处理推送通知事件
|
|
if (event.type === 'notification.push') {
|
|
await this.handlePushNotification(event);
|
|
}
|
|
|
|
this.logger.log('通知事件处理完成');
|
|
} catch (error) {
|
|
this.logger.error('通知事件处理失败:', error);
|
|
throw error;
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 转换默认事件方法体
|
|
*/
|
|
convertDefaultEventBody(javaEvent, eventInfo) {
|
|
return ` this.logger.log('处理事件:', event);
|
|
try {
|
|
// TODO: 实现事件处理逻辑
|
|
this.logger.log('事件处理完成');
|
|
} catch (error) {
|
|
this.logger.error('事件处理失败:', error);
|
|
throw error;
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 转换事件发布
|
|
*/
|
|
convertEventPublishing(javaMethod) {
|
|
const methodName = javaMethod.methodName;
|
|
|
|
if (methodName.includes('create') || methodName.includes('add')) {
|
|
return this.convertCreateEventPublishing(javaMethod);
|
|
}
|
|
|
|
if (methodName.includes('update') || methodName.includes('modify')) {
|
|
return this.convertUpdateEventPublishing(javaMethod);
|
|
}
|
|
|
|
if (methodName.includes('delete') || methodName.includes('remove')) {
|
|
return this.convertDeleteEventPublishing(javaMethod);
|
|
}
|
|
|
|
return this.convertDefaultEventPublishing(javaMethod);
|
|
}
|
|
|
|
/**
|
|
* 转换创建事件发布
|
|
*/
|
|
convertCreateEventPublishing(javaMethod) {
|
|
const entityName = this.namingUtils.toCamelCase(javaMethod.className);
|
|
|
|
return ` // 发布创建事件
|
|
this.eventEmitter.emit('${entityName}.created', {
|
|
type: '${entityName}.created',
|
|
payload: result,
|
|
timestamp: new Date(),
|
|
source: '${entityName}Service',
|
|
target: '${entityName}Listener'
|
|
});`;
|
|
}
|
|
|
|
/**
|
|
* 转换更新事件发布
|
|
*/
|
|
convertUpdateEventPublishing(javaMethod) {
|
|
const entityName = this.namingUtils.toCamelCase(javaMethod.className);
|
|
|
|
return ` // 发布更新事件
|
|
this.eventEmitter.emit('${entityName}.updated', {
|
|
type: '${entityName}.updated',
|
|
payload: result,
|
|
timestamp: new Date(),
|
|
source: '${entityName}Service',
|
|
target: '${entityName}Listener'
|
|
});`;
|
|
}
|
|
|
|
/**
|
|
* 转换删除事件发布
|
|
*/
|
|
convertDeleteEventPublishing(javaMethod) {
|
|
const entityName = this.namingUtils.toCamelCase(javaMethod.className);
|
|
|
|
return ` // 发布删除事件
|
|
this.eventEmitter.emit('${entityName}.deleted', {
|
|
type: '${entityName}.deleted',
|
|
payload: { id },
|
|
timestamp: new Date(),
|
|
source: '${entityName}Service',
|
|
target: '${entityName}Listener'
|
|
});`;
|
|
}
|
|
|
|
/**
|
|
* 转换默认事件发布
|
|
*/
|
|
convertDefaultEventPublishing(javaMethod) {
|
|
const entityName = this.namingUtils.toCamelCase(javaMethod.className);
|
|
|
|
return ` // 发布事件
|
|
this.eventEmitter.emit('${entityName}.event', {
|
|
type: '${entityName}.event',
|
|
payload: result,
|
|
timestamp: new Date(),
|
|
source: '${entityName}Service',
|
|
target: '${entityName}Listener'
|
|
});`;
|
|
}
|
|
|
|
/**
|
|
* 生成事件发射器配置
|
|
*/
|
|
generateEventEmitterConfig() {
|
|
return {
|
|
imports: [
|
|
"import { EventEmitterModule } from '@nestjs/event-emitter';"
|
|
],
|
|
module: `EventEmitterModule.forRoot({
|
|
global: true,
|
|
delimiter: '.',
|
|
newListener: false,
|
|
removeListener: false,
|
|
maxListeners: 10,
|
|
verboseMemoryLeak: false,
|
|
ignoreErrors: false
|
|
})`,
|
|
providers: [
|
|
{
|
|
provide: 'EventEmitter2',
|
|
useFactory: () => new EventEmitter2()
|
|
}
|
|
]
|
|
};
|
|
}
|
|
|
|
/**
|
|
* 生成事件拦截器
|
|
*/
|
|
generateEventInterceptor() {
|
|
return `import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
|
import { Observable } from 'rxjs';
|
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
|
|
@Injectable()
|
|
export class EventInterceptor implements NestInterceptor {
|
|
constructor(private eventEmitter: EventEmitter2) {}
|
|
|
|
async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<any>> {
|
|
const result = await next.handle().toPromise();
|
|
|
|
// 发布事件
|
|
this.eventEmitter.emit('request.completed', {
|
|
type: 'request.completed',
|
|
payload: result,
|
|
timestamp: new Date(),
|
|
source: 'EventInterceptor',
|
|
target: 'EventLogger'
|
|
});
|
|
|
|
return result;
|
|
}
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 生成事件日志记录器
|
|
*/
|
|
generateEventLogger() {
|
|
return `import { Injectable, Logger } from '@nestjs/common';
|
|
import { OnEvent } from '@nestjs/event-emitter';
|
|
|
|
@Injectable()
|
|
export class EventLogger {
|
|
private readonly logger = new Logger(EventLogger.name);
|
|
|
|
@OnEvent('**')
|
|
async handleAllEvents(event: any) {
|
|
this.logger.log('事件记录:', {
|
|
type: event.type,
|
|
timestamp: event.timestamp,
|
|
source: event.source,
|
|
target: event.target,
|
|
payload: event.payload
|
|
});
|
|
}
|
|
}`;
|
|
}
|
|
|
|
/**
|
|
* 验证事件转换一致性
|
|
*/
|
|
validateEventConsistency(javaEvent, nestJSEvent) {
|
|
const issues = [];
|
|
|
|
// 验证事件类型
|
|
const javaEventInfo = this.extractEventInfo(javaEvent);
|
|
const nestJSEventInfo = this.extractEventInfo(nestJSEvent);
|
|
|
|
if (javaEventInfo.type !== nestJSEventInfo.type) {
|
|
issues.push(`事件类型不一致: ${javaEventInfo.type} vs ${nestJSEventInfo.type}`);
|
|
}
|
|
|
|
// 验证事件名称
|
|
if (javaEventInfo.name !== nestJSEventInfo.name) {
|
|
issues.push(`事件名称不一致: ${javaEventInfo.name} vs ${nestJSEventInfo.name}`);
|
|
}
|
|
|
|
// 验证异步属性
|
|
if (javaEventInfo.async !== nestJSEventInfo.async) {
|
|
issues.push(`异步属性不一致: ${javaEventInfo.async} vs ${nestJSEventInfo.async}`);
|
|
}
|
|
|
|
// 验证优先级
|
|
if (javaEventInfo.priority !== nestJSEventInfo.priority) {
|
|
issues.push(`优先级不一致: ${javaEventInfo.priority} vs ${nestJSEventInfo.priority}`);
|
|
}
|
|
|
|
return issues;
|
|
}
|
|
}
|
|
|
|
module.exports = EventConverter;
|