diff --git a/package-lock.json b/package-lock.json index de0eac5..156d56d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "es-toolkit": "^1.42.0", "highcharts": "^12.2.0", "highcharts-vue": "^2.0.1", + "jsbarcode": "^3.12.3", "mammoth": "^1.9.1", "nuxt-qrcode": "^0.4.8", "pdfjs-dist": "^3.11.174", @@ -8637,6 +8638,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, + "node_modules/jsbarcode": { + "version": "3.12.3", + "resolved": "https://registry.npmjs.org/jsbarcode/-/jsbarcode-3.12.3.tgz", + "integrity": "sha512-CuHU9hC6dPsHF5oVFMo8NW76uQVjH4L22CsP4hW+dNnGywJHC/B0ThA1CTDVLnxKLrrpYdicBLnd2xsgTfRnvg==", + "license": "MIT" + }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -12300,7 +12307,7 @@ "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", "license": "MIT" }, -"node_modules/undici-types": { + "node_modules/undici-types": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", diff --git a/package.json b/package.json index 8ddb2f4..e8dee14 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "es-toolkit": "^1.42.0", "highcharts": "^12.2.0", "highcharts-vue": "^2.0.1", + "jsbarcode": "^3.12.3", "mammoth": "^1.9.1", "nuxt-qrcode": "^0.4.8", "pdfjs-dist": "^3.11.174", diff --git a/print/print_barcode.py b/print/print_barcode.py new file mode 100644 index 0000000..9b6ccb8 --- /dev/null +++ b/print/print_barcode.py @@ -0,0 +1,32 @@ +import win32print +import sys +import json + +def print_barcode(tspl_content, printer_name="Xprinter XP-350BM"): + h = win32print.OpenPrinter(printer_name) + try: + win32print.StartDocPrinter(h, 1, ("Print Barcode", None, "RAW")) + win32print.StartPagePrinter(h) + win32print.WritePrinter(h, tspl_content.encode('utf-8')) + win32print.EndPagePrinter(h) + win32print.EndDocPrinter(h) + finally: + win32print.ClosePrinter(h) + +if __name__ == "__main__": + data = json.loads(sys.argv[1]) + + tspl = f''' +SIZE 50 mm,40 mm +GAP 2 mm,0 +DIRECTION 1 +DENSITY 8 +CLS +TEXT 20,15,"3",0,1,1,"{data['name']}" +TEXT 20,70,"1",0,1,1,"Price: {data['price']} VND" +BARCODE 20,140,"128",50,1,0,2,2,"{data['imei']}" +PRINT 1,1 +'''.strip() + + print_barcode(tspl) + print("Sent to printer.") \ No newline at end of file diff --git a/print/test_barcode.txt b/print/test_barcode.txt new file mode 100644 index 0000000..e979e48 --- /dev/null +++ b/print/test_barcode.txt @@ -0,0 +1,17 @@ +SIZE 50 mm,40 mm +GAP 2 mm,0 +DIRECTION 1 +DENSITY 8 +CLS + +TEXT 20,15,"3",0,1,1,"CellphoneS Store" +TEXT 20,45,"2",0,1,1,"iPhone 15 Pro Max 256GB" +TEXT 20,70,"2",0,1,1,"Color: Natural Titanium" +TEXT 20,95,"1",0,1,1,"Price: 29,990,000 VND" +TEXT 20,115,"1",0,1,1,"Warranty: 12 months" + +BARCODE 20,140,"128",50,1,0,2,2,"SKU123456789" + +QRCODE 280,140,"L",4,"A",0,"https://example.com/p/123456789" + +PRINT 1,1 \ No newline at end of file diff --git a/server/api/print/barcode.post.ts b/server/api/print/barcode.post.ts new file mode 100644 index 0000000..d662004 --- /dev/null +++ b/server/api/print/barcode.post.ts @@ -0,0 +1,20 @@ +import { execFile } from "child_process"; +import { promisify } from "util"; +import path from "path"; + +const execFileAsync = promisify(execFile); + +export default defineEventHandler(async (event) => { + const body = await readBody(event); + const { name, imei, price } = body; + + const scriptPath = path.join(process.cwd(), "print", "print_barcode.py"); + const payload = JSON.stringify({ name, imei, price }); + + try { + const { stdout } = await execFileAsync("python", [scriptPath, payload]); + return { success: true, output: stdout }; + } catch (err) { + throw createError({ statusCode: 500, statusMessage: "Print failed", data: String(err) }); + } +});