cashier_desktop/src/store/socket.js

217 lines
6.6 KiB
JavaScript

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