import { ConfigsService } from '@/modules/bids/services/configs.service'; import { DashboardService } from '@/modules/bids/services/dashboard.service'; import { MailsService } from '@/modules/mails/services/mails.service'; import { delay } from '@/ultils'; import { Injectable, Logger } from '@nestjs/common'; import { Cron } from '@nestjs/schedule'; import * as moment from 'moment'; import { Between } from 'typeorm'; import { ScrapItemsService } from './scrap-item-config.service'; @Injectable() export class TasksService { private readonly logger = new Logger(TasksService.name); constructor( private readonly scrapItemsService: ScrapItemsService, private readonly mailsService: MailsService, private readonly configsSerivce: ConfigsService, private readonly dashboardService: DashboardService, ) {} async runProcessAndSendReport(processName: string) { const mails = (await this.configsSerivce.getConfig('MAIL_SCRAP_REPORT')) ?.value; if (!mails) { console.warn('No mails configured for report. Skipping.'); return; } // Nếu process đang chạy, không chạy lại const initialStatus = await this.dashboardService.getStatusProcessByName(processName); if (initialStatus === 'online') { console.log( `Process ${processName} is already running. Skipping execution.`, ); return; } // Reset và chạy process await this.dashboardService.resetProcessByName(processName); console.log(`Process ${processName} started.`); // Đợi process kết thúc, có timeout const maxAttempts = 60; // 10 phút let attempts = 0; let status = 'online'; while (status === 'online' && attempts < maxAttempts) { await delay(10000); // 10 giây status = await this.dashboardService.getStatusProcessByName(processName); attempts++; } if (status === 'online') { console.warn( `Process ${processName} still running after timeout. Skipping report.`, ); return; } // Khi process kết thúc => gửi mail const startOfDay = new Date(); startOfDay.setHours(0, 0, 0, 0); const endOfDay = new Date(); endOfDay.setHours(23, 59, 59, 999); try { const data = await this.scrapItemsService.scrapItemRepo.find({ where: { updated_at: Between(startOfDay, endOfDay), }, relations: { scrap_config: { web_bid: true } }, order: { updated_at: 'DESC' }, }); await this.mailsService.sendHtmlMailJob({ to: mails, subject: `Auction Items Matching Your Keywords – Daily Update ${moment().format('YYYY-MM-DD HH:mm')}`, html: this.mailsService.generateProductTableHTML(data), }); console.log('Report mail sent successfully.'); } catch (err) { console.error('Failed to generate or send report:', err); } } @Cron('58 5 * * *') async handleScraps() { const processName = 'scrape-data-keyword'; await this.runProcessAndSendReport(processName); } }