import _ from "lodash"; import { defineStore } from "pinia"; import { useUser } from "@/store/user.js"; import { usePrint } from "@/store/print.js"; import useStorage from "@/utils/useStorage"; import ReconnectingWebSocket from "reconnecting-websocket"; import { useGoods } from "@/store/goods.js"; import { ElMessage } from "element-plus"; import { getOrderByIdAjax, commOrderPrintData } from "@/utils/index.js"; export const useSocket = defineStore("socket", { state: () => ({ online: false, // 在线状态 ws: null, // websocket实例 heartbeatTimer: null, // 心跳计时器 orderList: [], orderListTimer: null, log: false, }), actions: { // 关闭ws close() { if (this.log) console.log("关闭ws"); this.online = false; this.ws.close(1000); this.ws = null; this.clearHeartBeat(); }, wsReconnect: _.throttle( function () { if (this.ws.readyState == ReconnectingWebSocket.OPEN) return; this.ws.reconnect(); // console.log("11111"); }, 2000, { leading: true, trailing: false } ), cartInit() { const store = useUser(); const goodsStore = useGoods(); this.ws.send( JSON.stringify({ type: "cashier", account: `cashier_${store.shopInfo.id}`, operate_type: "init", shop_id: store.shopInfo.id, table_code: goodsStore.tableInfo.tableCode || useStorage.get("tableCode"), }) ); }, // 初始化 init(wsUrl = import.meta.env.VITE_API_WSS) { const printStore = usePrint(); const goodsStore = useGoods(); printStore.init(); if (this.ws == null) { if (this.log) console.log("创建新的ws连接"); const protocols = []; // 可选的子协议数组 const options = { // 自动重新连接的选项(可选) connectionTimeout: 1000, maxRetries: 100, }; this.ws = new ReconnectingWebSocket(wsUrl, protocols, options); } else { if (this.log) console.log("重新连接ws"); this.wsReconnect(); } this.ws.addEventListener("open", (event) => { if (this.log) console.log("wss连接成功"); this.online = true; // 清除心跳 this.clearHeartBeat(); if (this.log) console.log(this); this.cartInit(); this.startheartbeat(); }); this.ws.addEventListener("message", async (e) => { let data = JSON.parse(e.data); if (data.operate_type == "init") { // console.log("接收消息", data); if (!goodsStore.tableInfo.tableCode) { useStorage.set("tableCode", data.table_code); } goodsStore.getCartList(data.data); } this.ws.send( JSON.stringify({ type: "receipt", msg_id: data.msg_id, }) ); if (data.data_type == "cart") { if (data.status == 1) { // 返回成功状态 switch (data.operate_type) { case "add": // 添加购物车商品 goodsStore.successAddCart(data.data); break; case "edit": // 编辑购物车商品 goodsStore.successEditCart(data.data); break; case "del": // 删除购物车商品 if (data.type && data.type == "bc") { goodsStore.successDeleteCartItem(data.data); } else { goodsStore.successDeleteCartItem(); } break; case "cleanup": // 清空购物车 if ( data.data.table_code == goodsStore.orderListInfo.tableCode && !data.type ) return; goodsStore.successClearCart(); break; case "batch": // 整单打包 this.cartInit(); break; case "rottable": // 转桌 useStorage.set("tableCode", data.data.new_table_code); goodsStore.successClearCart(); goodsStore.historyOrderAjax(data.data.new_table_code); this.cartInit(); break; default: break; } } else { ElMessage.error("操作失败"); } } else if (data.data_type == "order") { // 收到订单消息,打印订单小票 if (!this.orderList.some((el) => el == data.data)) { // 防止重复打印 this.orderList.push(data.data); this.startPrintInterval(); } } else if (data.data_type == "product_update") { // 商品更新 this.updateGoods(); } }); this.ws.addEventListener("error", () => { if (this.log) console.log("WebSocket连接发生错误"); this.online = false; this.clearHeartBeat(); }); this.ws.addEventListener("error", (e) => { if (this.log) console.log("ws关闭了", e); this.online = false; this.clearHeartBeat(); }); }, updateGoods: _.throttle(function () { const goodsStore = useGoods(); goodsStore.updateGoodsList(); }, 1000), // 启动心跳连接 startheartbeat() { this.heartbeatTimer = setInterval(() => { if (this.log) console.log("发送心跳"); this.ws.send(JSON.stringify({ type: "ping_interval", set: "cashier" })); }, 10000); }, // 清除心跳 clearHeartBeat() { // 清除心跳 clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; }, // 打印队列开始执行 startPrintInterval() { const printStore = usePrint(); if (this.orderListTimer !== null) return; this.orderListTimer = setInterval(async () => { try { if (!this.orderList.length) { clearInterval(this.orderListTimer); this.orderListTimer = null; } else { const orderInfo = await getOrderByIdAjax(this.orderList[0]); if (orderInfo.status == "done" && orderInfo.platformType != "PC") { // 打印小票 printStore.pushReceiptData(commOrderPrintData(orderInfo)); // 打印标签小票 printStore.labelPrint(commOrderPrintData(orderInfo)); } this.orderList.splice(0, 1); } } catch (error) { this.orderList.splice(0, 1); console.log(error); } }, 2000); }, }, });