#!/usr/bin/env node const fs = require('fs'); const path = require('path'); const BaseGenerator = require('./base-generator'); /** * ⚡ 任务生成器 * 专门负责生成NestJS任务/队列文件 */ class JobGenerator extends BaseGenerator { constructor() { super('JobGenerator'); this.config = { phpBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/niucloud-php/niucloud', nestjsBasePath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/wwjcloud-nest/src/core', discoveryResultPath: '/Users/wanwu/Documents/wwjcloud/wwjcloud-nsetjs/tools/php-discovery-result.json' }; this.discoveryData = null; this.jobStats = { jobsCreated: 0, jobsSkipped: 0 }; } /** * 运行任务生成 */ async run() { try { console.log('⚡ 启动任务生成器...'); console.log('目标:生成NestJS任务/队列文件\n'); // 加载PHP文件发现结果 await this.loadDiscoveryData(); // 生成任务 await this.generateJobs(); // 输出统计报告 this.printStats(); } catch (error) { console.error('❌ 任务生成失败:', error); this.stats.errors++; } } /** * 加载PHP文件发现结果 */ async loadDiscoveryData() { try { const data = fs.readFileSync(this.config.discoveryResultPath, 'utf8'); this.discoveryData = JSON.parse(data); console.log(' ✅ 成功加载PHP文件发现结果'); } catch (error) { console.error('❌ 加载发现结果失败:', error); throw error; } } /** * 生成任务 */ async generateJobs() { console.log(' 🔨 生成任务...'); // 检查是否有任务数据 if (!this.discoveryData.jobs || Object.keys(this.discoveryData.jobs).length === 0) { console.log(' ⚠️ 未发现PHP任务,跳过生成'); return; } for (const [moduleName, jobs] of Object.entries(this.discoveryData.jobs)) { // 检查PHP项目是否有对应的任务目录 if (!this.hasPHPJobs(moduleName)) { console.log(` ⚠️ 模块 ${moduleName} 在PHP项目中无任务,跳过`); continue; } for (const [jobName, jobInfo] of Object.entries(jobs)) { await this.createJob(moduleName, jobName, jobInfo); this.stats.jobsCreated++; } } console.log(` ✅ 生成了 ${this.stats.jobsCreated} 个任务`); } /** * 创建任务 */ async createJob(moduleName, jobName, jobInfo) { const jobDir = path.join(this.config.nestjsBasePath, moduleName, 'jobs'); this.ensureDir(jobDir); const normalizedBase = jobName.replace(/Job$/i, ''); const jobPath = path.join( jobDir, `${this.toPascalCase(normalizedBase)}Job.ts` ); // 检查是否有对应的PHP任务文件 const phpJobPath = path.join(this.config.phpBasePath, 'app/job', moduleName, `${jobName}.php`); if (!fs.existsSync(phpJobPath)) { console.log(` ❌ 未找到PHP任务文件,跳过生成: ${phpJobPath}`); return; } const content = this.generateJobContent(moduleName, jobName); this.writeFile(jobPath, content, `Job for ${moduleName}/${jobName}`); this.jobStats.jobsCreated++; } /** * 生成任务内容 */ generateJobContent(moduleName, jobName) { const baseName = jobName.replace(/Job$/i, ''); const className = `${this.toPascalCase(baseName)}Job`; return `import { Injectable, Logger } from '@nestjs/common'; import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; import { BusinessException } from '@wwjCommon/exceptions/business.exception'; /** * ${className} - 基于NestJS BullMQ * 参考: https://docs.nestjs.com/techniques/queues * 对应 Java: @Async + RabbitMQ * 对应 PHP: think\queue */ @Injectable() export class ${className} { private readonly logger = new Logger(${className}.name); constructor( @InjectQueue('${moduleName}') private readonly queue: Queue ) {} /** * 添加任务到队列 - 使用BullMQ标准API * 参考: https://docs.nestjs.com/techniques/queues#producers */ async addJob(data: any, options?: any) { try { const job = await this.queue.add('${baseName}', data, options); this.logger.log(\`${baseName} job added to queue: \${job.id}\`, data); return job; } catch (error) { this.logger.error('Failed to add ${baseName} job to queue:', error); throw new BusinessException('${baseName}任务添加失败'); } } /** * 处理队列任务 * 使用Core层基础设施:统一队列服务、异常处理、日志服务 */ async processJob(data: any) { this.logger.log('${baseName} job processing:', data); try { // 任务逻辑 await this.executeJob(data); this.logger.log('${baseName} job completed successfully'); } catch (error) { this.logger.error('${baseName} job failed:', error); // 使用Core层异常处理 throw new BusinessException('${baseName}任务处理失败', error); } } /** * 执行任务 * 使用Core层基础设施:日志服务、异常处理 */ private async executeJob(data: any) { // 实现具体的任务逻辑 // 例如: // - 数据清理 // - 报表生成 // - 邮件发送 // - 数据同步 // - 备份操作 this.logger.log('Executing ${baseName} job logic with data:', data); // 模拟异步操作 await new Promise(resolve => setTimeout(resolve, 1000)); this.logger.log('${baseName} job logic completed'); } /** * 手动触发任务 * 使用Core层基础设施:日志服务、异常处理 */ async triggerJob(data?: any) { this.logger.log('Manually triggering ${baseName} job...'); try { await this.executeJob(data || {}); } catch (error) { this.logger.error('Failed to trigger ${baseName} job:', error); // 使用Core层异常处理 throw new BusinessException('${baseName}任务触发失败', error); } } }`; } /** * 转换为PascalCase */ toPascalCase(str) { return str.charAt(0).toUpperCase() + str.slice(1); } /** * 转换为camelCase */ toCamelCase(str) { return str.charAt(0).toLowerCase() + str.slice(1); } toPascalCase(str) { return str.charAt(0).toUpperCase() + str.slice(1); } /** * 检查模块是否有PHP任务 */ hasPHPJobs(moduleName) { const phpProjectPath = path.join(__dirname, '../../niucloud-php/niucloud'); const jobPath = path.join(phpProjectPath, 'app/job', moduleName); return fs.existsSync(jobPath); } /** * 确保目录存在 */ ensureDir(dirPath) { if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } } /** * 输出统计报告 */ printStats() { super.printStats({ 'Jobs Created': this.jobStats.jobsCreated, 'Jobs Skipped': this.jobStats.jobsSkipped }); } } // 如果直接运行此文件 if (require.main === module) { const generator = new JobGenerator(); generator.run().catch(console.error); } module.exports = JobGenerator;