2026-01-22 15:15:23 +00:00
|
|
|
import { Injectable } from '@nestjs/common';
|
2026-01-22 21:02:42 +00:00
|
|
|
import { InjectQueue } from '@nestjs/bullmq';
|
|
|
|
|
import { Queue } from 'bullmq';
|
2026-01-22 15:15:23 +00:00
|
|
|
import { PrintDataDto } from '../dto/print-data.dto';
|
|
|
|
|
import { PrintHtmlDto } from '../dto/print-html.dto';
|
2026-01-22 21:02:42 +00:00
|
|
|
import { ThermalPrinter, PrinterTypes } from 'node-thermal-printer';
|
2026-01-22 15:15:23 +00:00
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class ListPrinterService {
|
|
|
|
|
private readonly printerType = PrinterTypes.EPSON;
|
|
|
|
|
|
2026-01-22 21:02:42 +00:00
|
|
|
constructor(@InjectQueue('printer') private printerQueue: Queue) {}
|
|
|
|
|
|
2026-01-22 15:15:23 +00:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-22 21:02:42 +00:00
|
|
|
async printHtml(data: PrintHtmlDto): Promise<{ success: boolean; message: string; jobId?: string }> {
|
|
|
|
|
const jobOptions: any = {};
|
2026-01-22 15:15:23 +00:00
|
|
|
|
2026-01-22 21:02:42 +00:00
|
|
|
if (data.jobId) {
|
|
|
|
|
const safeJobId = /^\d+$/.test(data.jobId) ? `print-${data.jobId}` : data.jobId;
|
|
|
|
|
jobOptions.jobId = safeJobId;
|
|
|
|
|
}
|
2026-01-22 15:15:23 +00:00
|
|
|
|
2026-01-22 21:02:42 +00:00
|
|
|
const job = await this.printerQueue.add('print-html-job', data, jobOptions);
|
2026-01-22 15:15:23 +00:00
|
|
|
|
2026-01-22 21:02:42 +00:00
|
|
|
return {
|
|
|
|
|
success: true,
|
|
|
|
|
message: 'Tarefa enviada para a fila de impressão',
|
|
|
|
|
jobId: job.id
|
|
|
|
|
};
|
2026-01-22 15:15:23 +00:00
|
|
|
}
|
|
|
|
|
}
|