将长链接剥离出来

This commit is contained in:
gyq 2024-07-10 10:24:45 +08:00
parent d101ecea41
commit 91670a440b
6 changed files with 220 additions and 379 deletions

View File

@ -22,7 +22,7 @@ VITE_API_PHP_URL = 'http://192.168.2.33:1666/index.php/api'
# VITE_API_URL = 'http://192.168.2.41:10589/cashier-client' # VITE_API_URL = 'http://192.168.2.41:10589/cashier-client'
# 测试 # 测试
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client' VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
# 正式 # 正式
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client' # VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'

View File

@ -1,7 +1,7 @@
{ {
"name": "vite-electron", "name": "vite-electron",
"private": true, "private": true,
"version": "1.3.42", "version": "1.3.44",
"main": "dist-electron/main.js", "main": "dist-electron/main.js",
"scripts": { "scripts": {
"dev": "chcp 65001 && vite", "dev": "chcp 65001 && vite",

View File

@ -2,7 +2,7 @@
<el-config-provider size="large"> <el-config-provider size="large">
<div class="container"> <div class="container">
<div class="left" v-if="!hideLeftMenu"> <div class="left" v-if="!hideLeftMenu">
<left-menu ref="leftMenuRef" @connectWsHandle="initWebSocket" /> <left-menu ref="leftMenuRef" />
</div> </div>
<div :class="{ view: !hideLeftMenu }"> <div :class="{ view: !hideLeftMenu }">
<!-- <div class="wrapper"> <!-- <div class="wrapper">
@ -22,35 +22,20 @@
</template> </template>
<script setup> <script setup>
import { v4 as uuidv4 } from 'uuid'
import { ref, reactive, watch, onMounted } from "vue"; import { ref, reactive, watch, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router"; import { useRouter, useRoute } from "vue-router";
import leftMenu from "@/components/leftMenu.vue"; import leftMenu from "@/components/leftMenu.vue";
import useStorage from '@/utils/useStorage' import useStorage from "@/utils/useStorage";
import { useUser } from "@/store/user.js"; import { useUser } from "@/store/user.js";
import { dayjs, ElMessage } from "element-plus"; import { dayjs, ElMessage } from "element-plus";
import { scanSendMessage } from '@/api/order/index' import { scanSendMessage } from "@/api/order/index";
import { useGlobal } from '@/store/global.js' import { useGlobal } from "@/store/global.js";
import { useSocket } from '@/store/socket.js' import { useSocket } from "@/store/socket.js";
import { usePrint } from '@/store/print.js' const socket = useSocket();
import ReconnectingWebSocket from 'reconnecting-websocket';
const global = useGlobal() const global = useGlobal();
const socketStore = useSocket()
const printStore = usePrint()
const leftMenuRef = ref(null) const leftMenuRef = ref(null);
const uuid = ref('')
function createUUID() {
if (!useStorage.get('uuid')) {
useStorage.set('uuid', uuidv4())
uuid.value = useStorage.get('uuid')
} else {
uuid.value = useStorage.get('uuid')
}
}
const store = useUser(); const store = useUser();
@ -64,34 +49,14 @@ watch(route, (to) => {
includeList.push(to.name); includeList.push(to.name);
} }
// //
let arr = ["/login", "/device_list", "/add_device", "/add_label", '/webview']; let arr = ["/login", "/device_list", "/add_device", "/add_label", "/webview"];
if (arr.includes(to.path)) { if (arr.includes(to.path)) {
hideLeftMenu.value = true; hideLeftMenu.value = true;
} else { } else {
hideLeftMenu.value = false; hideLeftMenu.value = false;
} }
if (to.fullPath == '/login') {
if (ws.value != null) {
console.log('退出登录关闭ws');
ws.value.close()
ws.value = null
// wsIsClose.value = true
}
} else {
// ws
openWs()
}
}); });
// ws
function openWs() {
if (store.userInfo && store.userInfo.shopId && ws.value == null) {
initWebSocket()
// print
printStore.init()
}
}
let transitionName = ref(); let transitionName = ref();
let router = useRouter(); let router = useRouter();
router.beforeEach((to, from) => { router.beforeEach((to, from) => {
@ -107,301 +72,84 @@ router.beforeEach((to, from) => {
} }
}); });
let ws = ref(null)
let wsIsClose = ref(false)
// websocket
function initWebSocket(wsUrl = import.meta.env.VITE_API_WSS) {
createUUID()
// wsIsClose.value = false
if (ws.value == null) {
ws.value = new ReconnectingWebSocket(`${wsUrl}`, null, {
reconnectInterval: 10000
})
}
// console.log("websocket:", ws.value);
ws.value.addEventListener('open', function (event) {
console.log('wss连接成功');
socketStore.changeOnline(true)
//
clearInterval(heartbeatTimer.value)
heartbeatTimer.value = null
startheartbeat()
//
// clearInterval(reConnectTimer.value)
// reConnectTimer.value = null
// reConnectCount.value = 0
ws.value.send(JSON.stringify({
type: "connect",
shopId: store.userInfo.shopId,
clientId: uuid.value
}))
})
// ws.value.onopen = function () {
// console.log('wss');
// socketStore.changeOnline(true)
// //
// clearInterval(heartbeatTimer.value)
// heartbeatTimer.value = null
// startheartbeat()
// //
// clearInterval(reConnectTimer.value)
// reConnectTimer.value = null
// reConnectCount.value = 0
// ws.value.send(JSON.stringify({
// type: "connect",
// shopId: store.userInfo.shopId,
// clientId: uuid.value
// }))
// };
ws.value.addEventListener('message', function (e) {
let data = JSON.parse(e.data)
if (data.type == 'order') {
console.log('接收消息', data);
ws.value.send(JSON.stringify({
type: "send",
orderNo: data.orderInfo.orderNo
}))
//
// printBill(data)
//
// checkLabelPrint(data)
printStore.labelPrint(data)
}
})
//
// ws.value.addEventListener('WebSocket.CLOSED', function () {
// })
//
// ws.value.onmessage = function (e) {
// // websocketonmessage(e);
// let data = JSON.parse(e.data)
// if (data.type == 'order') {
// console.log('', data);
// ws.value.send(JSON.stringify({
// type: "send",
// orderNo: data.orderInfo.orderNo
// }))
// //
// // printBill(data)
// //
// // checkLabelPrint(data)
// printStore.labelPrint(data)
// }
// };
ws.value.addEventListener('error', function () {
console.log("WebSocket连接发生错误");
socketStore.changeOnline(false)
//
clearInterval(heartbeatTimer.value)
heartbeatTimer.value = null
//
// ws.value.close();
// if (!wsIsClose.value) reConnect(wsUrl);
})
//
// ws.value.onerror = function () {
// console.log("WebSocket");
// socketStore.changeOnline(false)
// //
// clearInterval(heartbeatTimer.value)
// heartbeatTimer.value = null
// //
// if (!wsIsClose.value) reConnect(wsUrl);
// };
ws.value.addEventListener('error', function (e) {
console.log('ws关闭了', e);
socketStore.changeOnline(false)
//
clearInterval(heartbeatTimer.value)
heartbeatTimer.value = null
//
// ws.value.close();
// if (!wsIsClose.value) reConnect(wsUrl);
})
//
// ws.value.onclose = function (e) {
// console.log('ws', e);
// socketStore.changeOnline(false)
// //
// clearInterval(heartbeatTimer.value)
// heartbeatTimer.value = null
// //
// if (!wsIsClose.value) reConnect(wsUrl);
// };
}
//
let heartbeatTimer = ref(null)
function startheartbeat() {
heartbeatTimer.value = setInterval(() => {
console.log('发送心跳');
ws.value.send(JSON.stringify({ type: 'heartbeat' }))
}, 10000)
}
// 5
// let reConnectCount = ref(0)
// let reConnectTimer = ref(null)
// function reConnect(wsUrl) {
// if (reConnectTimer.value != null) return
// console.log('ws.value.readyState', ws.value.readyState);
// console.log('ReconnectingWebSocket.OPEN', ReconnectingWebSocket.OPEN);
// if (ws.value.readyState == ReconnectingWebSocket.OPEN) return
// ws.value.reconnect();
// reConnectTimer.value = setInterval(() => {
// // 5
// // console.log('reConnectCount.value===', reConnectCount.value);
// // if (reConnectCount.value >= 100) {
// // console.log('5');
// // clearInterval(reConnectTimer.value)
// // reConnectTimer.value = null
// // reConnectCount.value = 0
// // wsIsClose.value = true
// // ws.value.close()
// // } else {
// // }
// // reConnectCount.value++
// // initWebSocket(wsUrl)
// ws.value.reconnect();
// }, 2000)
// }
//
function updateInfo() {
//
let isOnLine = navigator.onLine
//
let info = navigator.connection
console.log('isOnLine===', isOnLine);
console.log('info===', info);
if (isOnLine) {
console.log('有网了重连ws连接');
reConnect()
} else {
console.log('没网了断开ws连接');
ws.value.close()
//
clearInterval(reConnectTimer.value)
reConnectTimer.value = null
clearInterval(heartbeatTimer.value)
heartbeatTimer.value = null
}
}
const nextCodeRef = ref('')
const lastTimeRef = ref('')
const codeRef = ref('')
// //
const nextCodeRef = ref("");
const lastTimeRef = ref("");
const codeRef = ref("");
async function getBarCode(e) { async function getBarCode(e) {
let nextCode = '' let nextCode = "";
let nextTime = '' let nextTime = "";
const lastTime = lastTimeRef.value const lastTime = lastTimeRef.value;
let code = codeRef.value let code = codeRef.value;
if (window.event) { if (window.event) {
// IE // IE
nextCode = e.keyCode nextCode = e.keyCode;
} else if (e.which) { } else if (e.which) {
// Netscape/Firefox/Opera // Netscape/Firefox/Opera
nextCode = e.which nextCode = e.which;
} }
nextTime = new Date().getTime() nextTime = new Date().getTime();
// 0-9 48-57; 0-9 96-105 // 0-9 48-57; 0-9 96-105
if ( if (
(nextCode >= 48 && nextCode <= 57) || (nextCode >= 48 && nextCode <= 57) ||
(nextCode >= 96 && nextCode <= 105) (nextCode >= 96 && nextCode <= 105)
) { ) {
const codes = { const codes = {
'48': 48, 48: 48,
'49': 49, 49: 49,
'50': 50, 50: 50,
'51': 51, 51: 51,
'52': 52, 52: 52,
'53': 53, 53: 53,
'54': 54, 54: 54,
'55': 55, 55: 55,
'56': 56, 56: 56,
'57': 57, 57: 57,
'96': 48, 96: 48,
'97': 49, 97: 49,
'98': 50, 98: 50,
'99': 51, 99: 51,
'100': 52, 100: 52,
'101': 53, 101: 53,
'102': 54, 102: 54,
'103': 55, 103: 55,
'104': 56, 104: 56,
'105': 57 105: 57,
} };
nextCode = codes[nextCode] nextCode = codes[nextCode];
nextTime = new Date().getTime() nextTime = new Date().getTime();
} }
// //
if (nextTime && lastTime && nextTime - lastTime > 2000) { if (nextTime && lastTime && nextTime - lastTime > 2000) {
code = String.fromCharCode(nextCode) code = String.fromCharCode(nextCode);
} else { } else {
code += String.fromCharCode(nextCode) code += String.fromCharCode(nextCode);
} }
// //
nextCodeRef.value = nextCode nextCodeRef.value = nextCode;
lastTimeRef.value = nextTime lastTimeRef.value = nextTime;
codeRef.value = code codeRef.value = code;
// Enter // Enter
if (e.which === 13) { if (e.which === 13) {
// code // code
code = code.trim() code = code.trim();
if (code.length == 13) { if (code.length == 13) {
console.log('A类条码:' + code); console.log("A类条码:" + code);
} else if (code.length == 23) { } else if (code.length == 23) {
console.log('B类条码:' + code); console.log("B类条码:" + code);
} else if (code.length == 0) { } else if (code.length == 0) {
console.log('请输入条码'); console.log("请输入条码");
} else { } else {
console.log('条码不合法:' + code); console.log("条码不合法:" + code);
try { try {
if (!global.isCallNumber || !code.length) return if (!global.isCallNumber || !code.length) return;
await scanSendMessage({ await scanSendMessage({
outNumber: code, outNumber: code,
shopId: store.userInfo.shopId shopId: store.userInfo.shopId,
}) });
ElMessage.success('叫号成功') ElMessage.success("叫号成功");
leftMenuRef.value.updateCallNumber() leftMenuRef.value.updateCallNumber();
} catch (error) { } catch (error) {
console.log(error); console.log(error);
} }
@ -409,23 +157,21 @@ async function getBarCode(e) {
// console.log('code', code); // console.log('code', code);
// code // code
codeRef.value = '' codeRef.value = "";
return false return false;
} }
} }
onMounted(() => { onMounted(() => {
document.addEventListener('keydown', (e) => { document.addEventListener("keydown", (e) => {
getBarCode(e) getBarCode(e);
}) });
// 线
// window.addEventListener("onLine", updateInfo)
// // 线
// window.addEventListener("offLine", updateInfo)
// //
// navigator.connection.addEventListener('change', updateInfo)
})
//
if (store.userInfo && store.userInfo.shopId) {
socket.init();
}
});
</script> </script>
<style lang="scss"> <style lang="scss">
@ -457,20 +203,28 @@ onMounted(() => {
--b-darker: calc(var(--b) * 0.8); --b-darker: calc(var(--b) * 0.8);
--primary-color: rgb(var(--r), var(--g), var(--b)); --primary-color: rgb(var(--r), var(--g), var(--b));
--primary-color-hover: rgb(var(--r-lighter3), --primary-color-hover: rgb(
var(--g-lighter3), var(--r-lighter3),
var(--b-lighter3)); var(--g-lighter3),
var(--b-lighter3)
);
--el-color-primary: var(--primary-color) !important; --el-color-primary: var(--primary-color) !important;
--el-button-hover-bg-color: var(--primary-color) !important; --el-button-hover-bg-color: var(--primary-color) !important;
--el-color-primary-light-3: rgb(var(--r-lighter), --el-color-primary-light-3: rgb(
var(--g-lighter), var(--r-lighter),
var(--b-lighter)) !important; var(--g-lighter),
--el-color-primary-dark-2: rgb(var(--r-darker), var(--b-lighter)
var(--g-darker), ) !important;
var(--b-darker)) !important; --el-color-primary-dark-2: rgb(
--el-color-primary-light-5: rgb(var(--r-lighter2), var(--r-darker),
var(--g-lighter2), var(--g-darker),
var(--b-lighter2)) !important; var(--b-darker)
) !important;
--el-color-primary-light-5: rgb(
var(--r-lighter2),
var(--g-lighter2),
var(--b-lighter2)
) !important;
--el-font-size-base: 16px !important; --el-font-size-base: 16px !important;
--el-message-close-size: var(--el-font-size-base) !important; --el-message-close-size: var(--el-font-size-base) !important;
@ -525,7 +279,8 @@ html {
background-color: #555; background-color: #555;
margin-right: 0 !important; margin-right: 0 !important;
padding-bottom: 20px !important; padding-bottom: 20px !important;
border-radius: var(--el-dialog-border-radius) var(--el-dialog-border-radius) 0 0; border-radius: var(--el-dialog-border-radius) var(--el-dialog-border-radius) 0
0;
} }
.el-dialog__title { .el-dialog__title {
@ -546,7 +301,8 @@ html {
} }
.el-dialog__body { .el-dialog__body {
padding: calc(var(--el-dialog-padding-primary) + 10px) var(--el-dialog-padding-primary); padding: calc(var(--el-dialog-padding-primary) + 10px)
var(--el-dialog-padding-primary);
} }
.el-dialog__header { .el-dialog__header {
@ -634,7 +390,7 @@ html {
display: flex; display: flex;
width: 200%; width: 200%;
&>div { & > div {
width: 50%; width: 50%;
} }

View File

@ -1,28 +1,107 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { useUser } from "@/store/user.js";
import { usePrint } from "@/store/print.js";
import { v4 as uuidv4 } from "uuid";
import useStorage from "@/utils/useStorage";
import ReconnectingWebSocket from "reconnecting-websocket"; import ReconnectingWebSocket from "reconnecting-websocket";
export const useSocket = defineStore({ export const useSocket = defineStore({
id: "socket", id: "socket",
state: () => ({ state: () => ({
online: false, // 是否在线 online: false, // 在线状态
ws: null, ws: null, // websocket实例
uuid: "", // 长连接唯一id
heartbeatTimer: null, // 心跳计时器
}), }),
actions: { actions: {
// 改变在线状态 // 创建uuid
changeOnline(state) { createUUID() {
this.online = state; if (!useStorage.get("uuid")) {
useStorage.set("uuid", uuidv4());
this.uuid = useStorage.get("uuid");
} else {
this.uuid = useStorage.get("uuid");
}
},
// 关闭ws
close() {
console.log("关闭ws");
this.ws.close();
this.ws = null;
this.clearHeartBeat();
}, },
// 初始化 // 初始化
init(wsUrl = import.meta.env.VITE_API_WSS) { init(wsUrl = import.meta.env.VITE_API_WSS) {
this.createUUID();
const store = useUser();
const printStore = usePrint();
printStore.init();
if (this.ws == null) { if (this.ws == null) {
this.ws = new ReconnectingWebSocket( this.ws = new ReconnectingWebSocket(wsUrl);
`${wsUrl}/shopId=${store.userInfo.shopId}/clientId=${uuid.value}`,
null,
{
reconnectInterval: 10000,
}
);
} }
this.ws.addEventListener("open", (event) => {
console.log("wss连接成功");
this.online = true;
// 清除心跳
this.clearHeartBeat();
this.startheartbeat();
this.ws.send(
JSON.stringify({
type: "connect",
shopId: store.userInfo.shopId,
clientId: this.uuid,
})
);
});
this.ws.addEventListener("message", (e) => {
let data = JSON.parse(e.data);
if (data.type == "order") {
console.log("接收消息", data);
this.ws.send(
JSON.stringify({
type: "send",
orderNo: data.orderInfo.orderNo,
})
);
// 接收订单消息,打印小票
// printBill(data)
// 打印标签小票
printStore.labelPrint(data);
}
});
this.ws.addEventListener("error", () => {
console.log("WebSocket连接发生错误");
this.online = false;
this.clearHeartBeat();
});
this.ws.addEventListener("error", (e) => {
console.log("ws关闭了", e);
this.online = false;
this.clearHeartBeat();
});
},
// 启动心跳连接
startheartbeat() {
this.heartbeatTimer = setInterval(() => {
console.log("发送心跳");
this.ws.send(JSON.stringify({ type: "heartbeat" }));
}, 10000);
},
// 清除心跳
clearHeartBeat() {
// 清除心跳
clearInterval(this.heartbeatTimer);
this.heartbeatTimer = null;
}, },
}, },
}); });

View File

@ -4,7 +4,7 @@
<el-image :src="logo" style="width: 180px"></el-image> <el-image :src="logo" style="width: 180px"></el-image>
</div> </div>
<div class="form-wrap"> <div class="form-wrap">
<div style="flex: 1;"> <div style="flex: 1">
<!-- <div class="reg-wrap"> <!-- <div class="reg-wrap">
<router-link :to="{ name: 'register' }"> <router-link :to="{ name: 'register' }">
<el-link type="primary">注册</el-link> <el-link type="primary">注册</el-link>
@ -51,30 +51,29 @@
</template> </template>
<script setup> <script setup>
import packageData from "../../package.json";
import packageData from '../../package.json'
import logo from "@/assets/logo.png"; import logo from "@/assets/logo.png";
import { ElMessage, ElMessageBox } from "element-plus"; import { ElMessage, ElMessageBox } from "element-plus";
import { reactive, ref } from "vue"; import { reactive, ref } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { ipcRenderer } from "electron"; import { ipcRenderer } from "electron";
import { RandomNumBoth } from '@/utils' import { RandomNumBoth } from "@/utils";
import useStorage from '@/utils/useStorage' import useStorage from "@/utils/useStorage";
import { douyincheckIn } from '@/api/group' import { douyincheckIn } from "@/api/group";
import { useUser } from "@/store/user.js"; import { useUser } from "@/store/user.js";
import { useSocket } from "@/store/socket.js";
const store = useUser(); const store = useUser();
const socket = useSocket();
const router = useRouter(); const router = useRouter();
const formRef = ref(null); const formRef = ref(null);
const loading = ref(false); const loading = ref(false);
const form = reactive({ const form = reactive({
serialNumber: RandomNumBoth(1000, 9999), serialNumber: RandomNumBoth(1000, 9999),
clientType: 'pc', clientType: "pc",
merchantName: '',//19191703856 merchantName: "",
loginName: "", loginName: "",
password: "", password: "",
}); });
@ -108,22 +107,26 @@ const submitHandle = () => {
formRef.value.validate(async (valid) => { formRef.value.validate(async (valid) => {
if (valid) { if (valid) {
loading.value = true; loading.value = true;
store.userlogin(form).then(async (res) => { store
// const douyin = await douyincheckIn({ .userlogin(form)
// token: res.token, .then(async (res) => {
// loginName: res.loginName, // const douyin = await douyincheckIn({
// clientType: 'pc' // token: res.token,
// }) // loginName: res.loginName,
// useStorage.set('douyin', douyin.userInfo) // clientType: 'pc'
ElMessage.success("登录成功"); // })
setTimeout(() => { // useStorage.set('douyin', douyin.userInfo)
router.replace({ ElMessage.success("登录成功");
name: "home", socket.init();
}); setTimeout(() => {
}, 1000); router.replace({
}).catch(err => { name: "home",
loading.value = false });
}); }, 1000);
})
.catch((err) => {
loading.value = false;
});
} }
}); });
}; };

View File

@ -131,6 +131,8 @@ import useStorage from '@/utils/useStorage'
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { bySubType } from "@/api/device"; import { bySubType } from "@/api/device";
import { useUser } from "@/store/user.js"; import { useUser } from "@/store/user.js";
import { useSocket } from "@/store/socket.js";
const socket = useSocket();
const store = useUser(); const store = useUser();
@ -163,7 +165,7 @@ function getPrintList() {
ipcRenderer.send("getPrintList"); ipcRenderer.send("getPrintList");
ipcRenderer.on("printList", (event, arg) => { ipcRenderer.on("printList", (event, arg) => {
localPrintList.value = arg; localPrintList.value = arg;
console.log(localPrintList.value); // console.log(localPrintList.value);
}); });
} }
@ -237,6 +239,7 @@ const exit = async () => {
}, 1000); }, 1000);
loading.value = false; loading.value = false;
} }
socket.close()
} catch (error) { } catch (error) {
loading.value = false; loading.value = false;
} }