svr-imp/src/services/printer.service.ts

96 lines
2.4 KiB
TypeScript

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,
};
}
}