import { Injectable } from '@nestjs/common'; import { InjectQueue } from '@nestjs/bullmq'; import { Queue } from 'bullmq'; import { PrintDataDto } from '../dto/print-data.dto'; import { PrintHtmlDto } from '../dto/print-html.dto'; import { ThermalPrinter, PrinterTypes } from 'node-thermal-printer'; @Injectable() export class PrinterService { private readonly printerType = PrinterTypes.EPSON; constructor(@InjectQueue('printer') private printerQueue: Queue) {} async printReceipt( data: PrintDataDto, ): Promise<{ success: boolean; message: string }> { if (!data.lines?.length) { return { success: false, message: 'No lines provided' }; } try { let printerInterface = data.printerInterface; if ( printerInterface && !printerInterface.includes('://') && !printerInterface.startsWith('printer:') ) { printerInterface = `printer:${printerInterface}`; } const printer = new ThermalPrinter({ type: this.printerType, interface: printerInterface, }); this.applyAlignment(printer, data.alignment); for (const line of data.lines) { if (data.upsideDown) { printer.upsideDown(true); } printer.println(line); if (data.upsideDown) { printer.upsideDown(false); } } printer.drawLine(); printer.beep(); await printer.execute(); return { success: true, message: 'Print successful!' }; } catch (error) { return { success: false, message: `Print failed: ${error.message || error}`, }; } } private applyAlignment(printer: any, alignment?: string): void { if (alignment === 'center') { return printer.alignCenter(); } if (alignment === 'right') { return printer.alignRight(); } return printer.alignLeft(); } async printHtml( data: PrintHtmlDto, ): Promise<{ success: boolean; message: string; jobId?: string }> { const jobOptions: any = {}; if (data.jobId) { const safeJobId = /^\d+$/.test(data.jobId) ? `print-${data.jobId}` : data.jobId; jobOptions.jobId = safeJobId; } const job = await this.printerQueue.add('print-html-job', data, jobOptions); return { success: true, message: 'Tarefa enviada para a fila de impressão', jobId: job.id, }; } }