Files
cashier_desktop/src/store/print.js
2026-04-03 15:35:48 +08:00

386 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { defineStore } from "pinia";
import { ipcRenderer } from "electron";
import { useUser } from "@/store/user.js";
import dayjs from "dayjs";
import receiptPrint from "@/components/lodop/receiptPrint.js";
import lodopPrintWork from "@/components/lodop/lodopPrintWork.js";
import invoicePrint from "@/components/lodop/invoicePrint.js";
import refundPrint from "@/components/lodop/refundPrint.js";
import { printerList } from "@/api/account.js";
import { useSocket } from './socket.js';
export const usePrint = defineStore("print", {
state: () => ({
isPrintService: false,
printServiceTimer: null,
printServiceTimerCount: 0,
printServiceTimerMaxCount: 10,
showPrintNotService: false,
localDevices: [],
deviceNoteList: [],
deviceLableList: [],
labelList: [],
printTimer: null,
receiptList: [],
receiptTimer: null,
}),
actions: {
async init() {
ipcRenderer.send("getPrintList");
ipcRenderer.on("printList", (event, arg) => {
this.localDevices = arg;
});
try {
const res = await printerList();
this.deviceNoteList = res.records.filter(
(item) => item.status && item.subType == "cash"
);
this.deviceLableList = res.records.filter(
(item) => item.status && item.subType == "label"
);
} catch (error) {
console.error("获取打印机列表失败", error);
}
this.checkPrintService();
},
checkPrintService() {
this.printServiceTimer = setInterval(() => {
if (
typeof LODOP !== "undefined" &&
LODOP.webskt &&
LODOP.webskt.readyState == 1
) {
this.isPrintService = true;
clearInterval(this.printServiceTimer);
this.printServiceTimer = null;
} else {
this.printServiceTimerCount++;
if (this.printServiceTimerCount >= this.printServiceTimerMaxCount) {
this.isPrintService = false;
this.showPrintNotService = true;
clearInterval(this.printServiceTimer);
this.printServiceTimer = null;
}
}
}, 1000);
},
// 检查打印机是否可用
checkPrinterAvailable(printer) {
if (printer.connectionType === "局域网") {
const ipReg = /^(\d{1,3}\.){3}\d{1,3}$/;
return ipReg.test(printer.address);
}
if (printer.connectionType === "usb") {
return this.localDevices.some(item => item.name === printer.address);
}
return false;
},
// ==============================
// 最终完美版 → 空数组打印全部
// ==============================
pushReceiptData(props, isDevice = true) {
if (!isDevice) {
this.receiptList.push(props);
this.startReceiptPrint();
return;
}
const validPrinters = this.deviceNoteList.filter(p => {
return this.checkPrinterAvailable(p) && this.isPrintService;
});
if (validPrinters.length === 0) {
console.log("无可用小票打印机");
return;
}
const store = useUser();
validPrinters.forEach(printer => {
let filterCarts = [];
// ======================================
// ✅ 核心:分类为空数组 → 打印全部菜品
// ======================================
if (!printer.categoryList || printer.categoryList.length === 0) {
filterCarts = props.carts || [];
} else {
// 有分类 → 只打印对应分类
filterCarts = (props.carts || []).filter(item => {
return printer.categoryList.includes(item.categoryId);
});
}
if (filterCarts.length === 0) return;
const printData = {
...props,
carts: filterCarts,
deviceId: printer.id,
deviceName: printer.address,
printerName: printer.name,
connectionType: printer.connectionType,
shop_name: store.shopInfo.shopName,
loginAccount: store.userInfo.name,
createdAt: dayjs(props.createdAt).format("YYYY-MM-DD HH:mm:ss"),
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
};
if (!printData.orderInfo.masterId) {
printData.orderInfo.masterId = printData.orderInfo.tableName;
}
printData.orderInfo.outNumber = printData.outNumber;
if (!printData.discountAmount) {
printData.discountAmount = printData.amount;
}
this.receiptList.push(printData);
});
if (this.receiptList.length > 0) {
this.startReceiptPrint();
}
},
// ==============================
// 打印执行USB/局域网自动区分)
// ==============================
async startReceiptPrint() {
try {
const socketStore = useSocket();
const userStore = useUser();
if (this.receiptTimer !== null) return;
this.receiptTimer = setInterval(() => {
if (!this.receiptList.length) {
clearInterval(this.receiptTimer);
this.receiptTimer = null;
return;
}
const printData = this.receiptList[0];
try {
if (printData.connectionType === "局域网") {
ipcRenderer.send('networkPrint', JSON.stringify({
printerIp: printData.deviceName,
orderData: printData
}));
} else {
receiptPrint(printData);
}
const syncData = {
type: "cashier",
operate_type: "order_print_status",
table_code: printData.orderInfo.tableCode,
account: userStore.shopInfo.account,
print_status: "1",
order_id: printData.orderInfo.id,
print_id: printData.deviceId,
shop_id: printData.orderInfo.shopId,
};
socketStore.ws.send(JSON.stringify(syncData));
console.log("✅ 打印成功:", printData.deviceName, "菜品数:", printData.carts.length);
} catch (error) {
console.error("❌ 打印失败:", printData.deviceName, error);
} finally {
this.receiptList.splice(0, 1);
}
}, 2000);
} catch (error) {
console.log("打印定时器异常", error);
}
},
// ————————————————————————————————
// 以下原有代码完全不动除了printWork方法
// ————————————————————————————————
checkLocalPrint(address) {
let print = "";
for (let item of this.localDevices) {
if (item.name == address) {
print = item;
}
}
if (!print.name) {
return false;
} else {
return true;
}
},
labelPrint(props) {
const store = useUser();
if (
this.deviceLableList.length &&
this.checkLocalPrint(this.deviceLableList[0].address)
) {
let pids = this.deviceLableList[0].categoryList;
let count = 0;
let sum = 0;
props.carts.map((item) => {
if (pids.some((el) => el == item.categoryId)) {
for (let i = 0; i < item.number; i++) {
sum++;
}
}
});
props.carts.map((item) => {
if (pids.some((el) => el == item.categoryId)) {
for (let i = 0; i < item.number; i++) {
count++;
this.labelList.push({
outNumber: props.outNumber,
name: item.name,
skuName: item.skuName,
masterId: props.orderInfo.tableName,
deviceName: this.deviceLableList[0].address,
createdAt: dayjs(props.createdAt).format("YYYY-MM-DD HH:mm:ss"),
isPrint: false,
count: `${count}/${sum}`,
ticketLogo: store.shopInfo.ticketLogo,
});
}
}
});
this.startLabelPrint();
} else {
console.log("标签打印:未在本机查询到打印机");
}
},
startLabelPrint() {
if (this.printTimer != null) return;
this.printTimer = setInterval(() => {
let item = "";
if (!this.labelList.length) {
clearInterval(this.printTimer);
this.printTimer = null;
} else {
item = this.labelList[0];
if (!item.isPrint) {
ipcRenderer.send("printerTagSync", JSON.stringify(item));
this.labelList[0].isPrint = true;
this.labelList.splice(0, 1);
}
}
}, 2000);
},
// 打印交班小票优化1. 新增handoverSwitch=1才打印 2. 兼容局域网打印机)
printWork(data) {
// 筛选条件:
// 1. 状态启用 + 小票类型 + handoverSwitch=1
// 2. 打印机可用
// 3. 打印服务正常
const validPrinters = this.deviceNoteList.filter(p => {
return p.status
&& p.subType === "cash"
&& p.handoverSwitch === 1 // 新增只有handoverSwitch为1的打印机才打印交班小票
&& this.checkPrinterAvailable(p)
&& this.isPrintService;
});
if (validPrinters.length === 0) {
console.log("交班小票无符合条件的可用打印机handoverSwitch≠1 或 打印机不可用)");
return;
}
// 遍历符合条件的打印机打印
validPrinters.forEach(printer => {
const printData = {
...data,
deviceId: printer.id,
deviceName: printer.address,
connectionType: printer.connectionType,
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
};
try {
// 区分局域网和USB打印机
if (printer.connectionType === "局域网") {
// 局域网打印机使用networkPrint指令
ipcRenderer.send('printHandoverReceipt', JSON.stringify({
printerIp: printer.address,
handoverData: printData
}));
} else {
// USB打印机使用原有LODOP方式
lodopPrintWork(printData);
}
console.log("✅ 交班小票打印成功:", printer.address);
} catch (error) {
console.error("❌ 交班小票打印失败:", printer.address, error);
}
});
},
printInvoice(data) {
if (
this.deviceNoteList.length &&
this.checkLocalPrint(this.deviceNoteList[0].address)
) {
data.deviceName = this.deviceNoteList[0].address;
invoicePrint(data);
} else {
console.log("订单发票:未在本机查询到打印机");
}
},
// 退菜/退款
printRefund(data) {
// 筛选条件:
// 1. 状态启用 + 小票类型
// 2. 打印机可用
// 3. 打印服务正常
const validPrinters = this.deviceNoteList.filter(p => {
return p.status
&& p.subType === "cash"
&& this.checkPrinterAvailable(p)
&& this.isPrintService;
});
if (validPrinters.length === 0) {
console.log("退单小票:无符合条件的可用打印机");
return;
}
const store = useUser();
// 遍历符合条件的打印机打印
validPrinters.forEach(printer => {
const printData = {
...data,
deviceId: printer.id,
deviceName: printer.address,
printerName: printer.name,
connectionType: printer.connectionType,
shop_name: store.shopInfo.shopName,
loginAccount: store.userInfo.name,
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
};
try {
// 区分局域网和USB打印机
if (printer.connectionType === "局域网") {
// 局域网打印机使用networkPrint指令
ipcRenderer.send('printRefund', JSON.stringify({
printerIp: printer.address,
orderData: printData
}));
} else {
// USB打印机使用原有LODOP方式
refundPrint(printData);
}
console.log("✅ 退单小票打印成功:", printer.address);
} catch (error) {
console.error("❌ 退单小票打印失败:", printer.address, error);
}
});
}
},
});