parent
c86fff9691
commit
0b2b4b44d0
|
|
@ -1,8 +1,15 @@
|
|||
# 本地环境
|
||||
ENV = development
|
||||
|
||||
|
||||
# 正式ws
|
||||
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
||||
|
||||
#测试ws
|
||||
# VITE_API_WSS = 'wss://wxcashiertest.sxczgkj.cn/client'
|
||||
|
||||
# 测试
|
||||
VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
||||
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
||||
|
||||
# 阿伟
|
||||
# VITE_API_URL = 'http://192.168.2.96:10587/cashier-client'
|
||||
|
|
@ -11,4 +18,4 @@ VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
|||
# VITE_API_URL = 'http://192.168.2.41:10587/cashier-client'
|
||||
|
||||
# 正式
|
||||
# VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'
|
||||
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
# 线上环境
|
||||
ENV = production
|
||||
|
||||
# 正式ws
|
||||
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
||||
|
||||
# 线上环境接口地址
|
||||
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client/'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,172 +1 @@
|
|||
"use strict";
|
||||
const path = require("path");
|
||||
const electron = require("electron");
|
||||
let win;
|
||||
electron.app.whenReady().then(() => {
|
||||
win = new electron.BrowserWindow({
|
||||
title: "银收客",
|
||||
width: 1024,
|
||||
height: 768,
|
||||
fullscreenable: true,
|
||||
fullscreen: process.env.VITE_DEV_SERVER_URL ? false : true,
|
||||
simpleFullscreen: true,
|
||||
frame: process.env.VITE_DEV_SERVER_URL ? true : false,
|
||||
webPreferences: {
|
||||
// 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
win.loadURL(process.env.VITE_DEV_SERVER_URL);
|
||||
} else {
|
||||
win.loadFile(path.resolve(__dirname, "../dist/index.html"));
|
||||
}
|
||||
electron.app.on("activate", () => {
|
||||
if (electron.BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
electron.ipcMain.on("quitHandler", (_, msg) => {
|
||||
electron.app.quit();
|
||||
});
|
||||
electron.ipcMain.on("getPrintList", () => {
|
||||
win.webContents.getPrintersAsync().then((res) => {
|
||||
win.webContents.send("printList", res);
|
||||
});
|
||||
});
|
||||
const printWin = new electron.BrowserWindow({
|
||||
show: false,
|
||||
width: 464,
|
||||
height: 1726,
|
||||
webPreferences: {
|
||||
// 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
printWin.loadFile(path.join(__dirname, "../public/print.html"));
|
||||
} else {
|
||||
printWin.loadFile(path.resolve(__dirname, "../dist/print.html"));
|
||||
}
|
||||
electron.ipcMain.on("printerInfoSync", (event, arg) => {
|
||||
printWin.webContents.send("getParams", arg);
|
||||
});
|
||||
electron.ipcMain.on("printStart", (event, arg) => {
|
||||
console.log(arg);
|
||||
const _parmas = JSON.parse(arg);
|
||||
let name = _parmas.deviceName;
|
||||
printWin.webContents.print({
|
||||
silent: true,
|
||||
deviceName: name,
|
||||
pageSize: {
|
||||
width: 58e3,
|
||||
height: 216e3
|
||||
},
|
||||
scaleFactor: 80,
|
||||
landscape: false,
|
||||
margins: {
|
||||
marginType: "none",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
dpi: {
|
||||
horizontal: 203,
|
||||
vertical: 203
|
||||
}
|
||||
});
|
||||
});
|
||||
const workPrintWin = new electron.BrowserWindow({
|
||||
show: false,
|
||||
width: 464,
|
||||
height: 1726,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
workPrintWin.loadFile(path.join(__dirname, "../public/work_print.html"));
|
||||
} else {
|
||||
workPrintWin.loadFile(path.resolve(__dirname, "../dist/work_print.html"));
|
||||
}
|
||||
electron.ipcMain.on("printerWorkSync", (event, arg) => {
|
||||
workPrintWin.webContents.send("getParams", arg);
|
||||
});
|
||||
electron.ipcMain.on("printWorkStart", (event, arg) => {
|
||||
console.log(arg);
|
||||
const _parmas = JSON.parse(arg);
|
||||
let name = _parmas.deviceName;
|
||||
workPrintWin.webContents.print({
|
||||
silent: true,
|
||||
deviceName: name,
|
||||
pageSize: {
|
||||
width: 58e3,
|
||||
height: 216e3
|
||||
},
|
||||
scaleFactor: 80,
|
||||
landscape: false,
|
||||
margins: {
|
||||
marginType: "none",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
dpi: {
|
||||
horizontal: 203,
|
||||
vertical: 203
|
||||
}
|
||||
});
|
||||
});
|
||||
const tagPrintWin = new electron.BrowserWindow({
|
||||
show: true,
|
||||
width: 320,
|
||||
height: 240,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
}
|
||||
});
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
tagPrintWin.loadFile(path.join(__dirname, "../public/tag_print.html"));
|
||||
} else {
|
||||
tagPrintWin.loadFile(path.resolve(__dirname, "../dist/tag_print.html"));
|
||||
}
|
||||
electron.ipcMain.on("printerTagSync", (event, arg) => {
|
||||
tagPrintWin.webContents.send("getParams", arg);
|
||||
});
|
||||
electron.ipcMain.on("printTagStart", (event, arg) => {
|
||||
console.log(arg);
|
||||
const _parmas = JSON.parse(arg);
|
||||
let name = _parmas.deviceName;
|
||||
tagPrintWin.webContents.print({
|
||||
silent: true,
|
||||
deviceName: name,
|
||||
pageSize: {
|
||||
width: 4e4,
|
||||
height: 3e4
|
||||
},
|
||||
scaleFactor: 80,
|
||||
landscape: false,
|
||||
margins: {
|
||||
marginType: "none",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0
|
||||
},
|
||||
dpi: {
|
||||
horizontal: 203,
|
||||
vertical: 203
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
electron.app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin")
|
||||
electron.app.quit();
|
||||
});
|
||||
"use strict";const i=require("path"),e=require("electron");let a;e.app.whenReady().then(()=>{a=new e.BrowserWindow({title:"银收客",width:1024,height:768,fullscreenable:!0,fullscreen:!process.env.VITE_DEV_SERVER_URL,simpleFullscreen:!0,frame:!!process.env.VITE_DEV_SERVER_URL,webPreferences:{nodeIntegration:!0,contextIsolation:!1}}),process.env.VITE_DEV_SERVER_URL?a.loadURL(process.env.VITE_DEV_SERVER_URL):a.loadFile(i.resolve(__dirname,"../dist/index.html")),e.app.on("activate",()=>{e.BrowserWindow.getAllWindows().length===0&&createWindow()}),e.ipcMain.on("quitHandler",(t,n)=>{e.app.quit()}),e.ipcMain.on("getPrintList",()=>{a.webContents.getPrintersAsync().then(t=>{a.webContents.send("printList",t)})});const o=new e.BrowserWindow({show:!1,width:464,height:1726,webPreferences:{nodeIntegration:!0,contextIsolation:!1}});process.env.VITE_DEV_SERVER_URL?o.loadFile(i.join(__dirname,"../public/print.html")):o.loadFile(i.resolve(__dirname,"../dist/print.html")),e.ipcMain.on("printerInfoSync",(t,n)=>{o.webContents.send("getParams",n)}),e.ipcMain.on("printStart",(t,n)=>{console.log(n);let r=JSON.parse(n).deviceName;o.webContents.print({silent:!0,deviceName:r,pageSize:{width:58e3,height:216e3},scaleFactor:80,landscape:!1,margins:{marginType:"none",top:0,bottom:0,left:0,right:0},dpi:{horizontal:203,vertical:203}})});const s=new e.BrowserWindow({show:!1,width:464,height:1726,webPreferences:{nodeIntegration:!0,contextIsolation:!1}});process.env.VITE_DEV_SERVER_URL?s.loadFile(i.join(__dirname,"../public/work_print.html")):s.loadFile(i.resolve(__dirname,"../dist/work_print.html")),e.ipcMain.on("printerWorkSync",(t,n)=>{s.webContents.send("getParams",n)}),e.ipcMain.on("printWorkStart",(t,n)=>{let r=JSON.parse(n).deviceName;s.webContents.print({silent:!0,deviceName:r,pageSize:{width:58e3,height:216e3},scaleFactor:80,landscape:!1,margins:{marginType:"none",top:0,bottom:0,left:0,right:0},dpi:{horizontal:203,vertical:203}})});const l=new e.BrowserWindow({show:!1,width:320,height:240,webPreferences:{nodeIntegration:!0,contextIsolation:!1}});process.env.VITE_DEV_SERVER_URL?l.loadFile(i.join(__dirname,"../public/tag_print.html")):l.loadFile(i.resolve(__dirname,"../dist/tag_print.html")),e.ipcMain.on("printerTagSync",(t,n)=>{console.log(n),l.webContents.send("getParams",n)}),e.ipcMain.on("printTagStart",(t,n)=>{let r=JSON.parse(n).deviceName;l.webContents.print({silent:!0,deviceName:r,pageSize:{width:4e4,height:3e4},scaleFactor:80,landscape:!1,margins:{marginType:"none",top:0,bottom:0,left:0,right:0},dpi:{horizontal:203,vertical:203}})})});e.app.on("window-all-closed",()=>{process.platform!=="darwin"&&e.app.quit()});
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ app.whenReady().then(() => {
|
|||
|
||||
// 执行交班小票的打印操作
|
||||
ipcMain.on("printWorkStart", (event, arg) => {
|
||||
console.log(arg);
|
||||
// console.log(arg);
|
||||
const _parmas = JSON.parse(arg);
|
||||
// console.log(_parmas)
|
||||
let name = _parmas.deviceName;
|
||||
|
|
@ -164,7 +164,7 @@ app.whenReady().then(() => {
|
|||
|
||||
// 标签小票的窗口
|
||||
const tagPrintWin = new BrowserWindow({
|
||||
show: true,
|
||||
show: false,
|
||||
width: 320,
|
||||
height: 240,
|
||||
webPreferences: {
|
||||
|
|
@ -182,12 +182,13 @@ app.whenReady().then(() => {
|
|||
|
||||
// 接收渲染进程发送的数据
|
||||
ipcMain.on("printerTagSync", (event, arg) => {
|
||||
console.log(arg);
|
||||
tagPrintWin.webContents.send("getParams", arg);
|
||||
});
|
||||
|
||||
// 执行标签小票的打印操作
|
||||
ipcMain.on("printTagStart", (event, arg) => {
|
||||
console.log(arg);
|
||||
// console.log(arg);
|
||||
const _parmas = JSON.parse(arg);
|
||||
// console.log(_parmas)
|
||||
let name = _parmas.deviceName;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "vite-electron",
|
||||
"private": true,
|
||||
"version": "1.2.21",
|
||||
"version": "1.3.5",
|
||||
"main": "dist-electron/main.js",
|
||||
"scripts": {
|
||||
"dev": "chcp 65001 && vite",
|
||||
|
|
@ -18,8 +18,10 @@
|
|||
"element-plus": "^2.4.3",
|
||||
"lodash": "^4.17.21",
|
||||
"pinia": "^2.1.7",
|
||||
"qrcode": "^1.5.3",
|
||||
"serialport": "^12.0.0",
|
||||
"swiper": "^11.1.1",
|
||||
"uuid": "^10.0.0",
|
||||
"vue": "^3.3.8",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -15,11 +15,9 @@ body {
|
|||
position: relative;
|
||||
}
|
||||
.print_view .ewm {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
right: 4px;
|
||||
z-index: 99;
|
||||
}
|
||||
.print_view .header {
|
||||
|
|
|
|||
|
|
@ -12,29 +12,27 @@
|
|||
<body>
|
||||
<div id="app">
|
||||
<div class="print_view">
|
||||
<img
|
||||
class="ewm"
|
||||
src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAGp0lEQVR4nO3cQY4aQRBFQbfF/a+M97NALos0+eiI9agpcPupVv96Pp+/AAp+f/oAAH9LsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMh7TH3Bd1/RH3Mrz+Tz6+9Pf//T506bP7/18r+n3xw0LyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgIzxPaxT2/aYpk3vMW3bhzo9z7b3Ydt5pm3bC3PDAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBj3R7WqW17PfW9pPr5t/F+vpcbFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZ+T0sXjvdY6rvJfHd3LCADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyLCH9eWm963sbfE/uWEBGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkJHfw7Kv9F6n+1bTz6//+9bPv40bFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZ6/awpveY7mZ6f6r+/FPez89ywwIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgY3wPa3qfiNf8/q/5fVrcsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIuOp7QNd1Hf396fc9ff606fN7Hz5r2/m3nccNC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsICMx/QHTO/pbNuH2vb8u7nbPtSp+vndsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIuLbt3UzvPdX3p+rnP1V/P7ftc02b/r5uWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkjO9hbdvrmVbfb5o2vedlL+y1bXtep9ywgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8i43R7W3faSeK2+JzX9ftrDAvhHggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQMb6HxWdt2/Oq709tYw8LYCnBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gY38PatsdUt22fyF7Va9t+n23nOeWGBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWEDG49MH+Gnb/s606b2wbXtk0+c5fX+m96G27VvVuWEBGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkLFuD+vUtj2gu+153e37npre2zq1bS/slBsWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGYIFZAgWkCFYQIZgARn5PSxem94nmt5Lmt4727YPVX/+NDcsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjLsYX256T2padv2mLa5236WGxaQIVhAhmABGYIFZAgWkCFYQIZgARmCBWQIFpAhWECGYAEZggVkCBaQIVhAhmABGdf0fs22PZ1ttv0+9f2su7nb/xc3LCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyHp8+wE/2mFq27XOdnmf6fZs+z7bfZ/p9cMMCMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIOOa3q8BeBc3LCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMgQLyBAsIEOwgAzBAjIEC8gQLCBDsIAMwQIyBAvIECwgQ7CADMECMv4ARUAaEG+15lEAAAAASUVORK5CYII="
|
||||
alt=""
|
||||
/>
|
||||
<div class="ewm" id="ewm"></div>
|
||||
<div class="header">
|
||||
<img class="logo" src="./logo.png" />
|
||||
<!-- <span class="title">双屿Pisces</span> -->
|
||||
</div>
|
||||
<div class="number_wrap">
|
||||
<div class="num">196</div>
|
||||
<div class="info">座位号:B4</div>
|
||||
<div class="num">{{data.outNumber}}</div>
|
||||
<div class="info">座位号:{{data.masterId}}</div>
|
||||
</div>
|
||||
<div class="shop_info">
|
||||
<div class="name">[冰]美式抹茶拿铁焦糖</div>
|
||||
<div class="text">【半塘 去冰 去咖啡液】</div>
|
||||
<div class="name">{{data.name}}</div>
|
||||
<div class="text">【{{data.skuName}}】</div>
|
||||
</div>
|
||||
<div class="time">2024-06-14 16:22:44</div>
|
||||
<div class="tips">建议尽快享用,风味更佳</div>
|
||||
<div class="time">{{data.createdAt}}</div>
|
||||
<div class="tips">建议尽快享用,风味更佳 {{ data.count }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="./qrcode.js"></script>
|
||||
<script type="module">
|
||||
const { ipcRenderer } = require("electron");
|
||||
|
||||
import {
|
||||
createApp,
|
||||
ref,
|
||||
|
|
@ -50,12 +48,25 @@
|
|||
data.value = JSON.parse(arg);
|
||||
console.log(data.value);
|
||||
|
||||
let size = 40;
|
||||
let qrcode = new QRCode(document.getElementById("ewm"), {
|
||||
text: data.value.outNumber,
|
||||
width: size,
|
||||
height: size,
|
||||
correctLevel: QRCode.CorrectLevel.H,
|
||||
});
|
||||
|
||||
// ipcRenderer.send(
|
||||
// "printTagStart",
|
||||
// JSON.stringify({ deviceName: data.value.deviceName })
|
||||
// );
|
||||
|
||||
setTimeout(() => {
|
||||
ipcRenderer.send(
|
||||
"printTagStart",
|
||||
JSON.stringify({ deviceName: data.value.deviceName })
|
||||
);
|
||||
}, 500);
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,9 @@ body {
|
|||
.print_view {
|
||||
position: relative;
|
||||
.ewm {
|
||||
$size: 50px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
right: 4px;
|
||||
z-index: 99;
|
||||
}
|
||||
.header {
|
||||
|
|
|
|||
297
src/App.vue
297
src/App.vue
|
|
@ -22,15 +22,28 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, watch } from "vue";
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import leftMenu from "@/components/leftMenu.vue";
|
||||
import useStorage from '@/utils/useStorage'
|
||||
import { useUser } from "@/store/user.js";
|
||||
import { bySubType } from "@/api/device";
|
||||
import { dayjs, ElMessage } from "element-plus";
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
if (!useStorage.get('uuid')) {
|
||||
useStorage.set('uuid', uuidv4())
|
||||
}
|
||||
|
||||
const store = useUser();
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const includeList = reactive([]);
|
||||
const hideLeftMenu = ref(false);
|
||||
watch(route, (to) => {
|
||||
// console.log(to);
|
||||
if (to.meta.keepAlive) {
|
||||
includeList.push(to.name);
|
||||
}
|
||||
|
|
@ -40,8 +53,27 @@ watch(route, (to) => {
|
|||
} else {
|
||||
hideLeftMenu.value = false;
|
||||
}
|
||||
if (to.fullPath == '/login') {
|
||||
if (ws.value != null) {
|
||||
console.log('关闭ws');
|
||||
ws.value.close()
|
||||
wsIsClose.value = true
|
||||
}
|
||||
} else {
|
||||
// 打开ws
|
||||
console.log('打开ws');
|
||||
openWs()
|
||||
}
|
||||
});
|
||||
|
||||
// 登录成功后开始连接ws
|
||||
function openWs() {
|
||||
if (store.userInfo && store.userInfo.shopId && ws.value == null) {
|
||||
bySubTypeAjax();
|
||||
initWebSocket()
|
||||
}
|
||||
}
|
||||
|
||||
let transitionName = ref();
|
||||
let router = useRouter();
|
||||
router.beforeEach((to, from) => {
|
||||
|
|
@ -56,6 +88,229 @@ router.beforeEach((to, from) => {
|
|||
transitionName.value = "";
|
||||
}
|
||||
});
|
||||
|
||||
// 小票打印机列表
|
||||
const printList = ref([]);
|
||||
// 标签打印机列表
|
||||
const printLabelList = ref([]);
|
||||
const localPrintList = ref([])
|
||||
|
||||
// 获取打印机状态
|
||||
async function bySubTypeAjax() {
|
||||
try {
|
||||
const res1 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "cash",
|
||||
});
|
||||
const res2 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "label",
|
||||
});
|
||||
printList.value = res1;
|
||||
printLabelList.value = res2;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取本地打印机列表
|
||||
function getPrintList() {
|
||||
ipcRenderer.send("getPrintList");
|
||||
ipcRenderer.on("printList", (event, arg) => {
|
||||
localPrintList.value = arg;
|
||||
// console.log(localPrintList.value);
|
||||
});
|
||||
}
|
||||
|
||||
// 检查本地打印机是否能正常使用
|
||||
function checkLocalPrint(deviceName) {
|
||||
let print = ''
|
||||
for (let item of localPrintList.value) {
|
||||
if (item.name == deviceName) {
|
||||
print = item
|
||||
}
|
||||
}
|
||||
|
||||
if (!print.name) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 打印小票
|
||||
function printBill(props) {
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
const data = {
|
||||
shop_name: store.userInfo.merchantName,
|
||||
carts: props.carts,
|
||||
amount: props.amount,
|
||||
remark: props.remark,
|
||||
orderInfo: props.orderInfo,
|
||||
deviceName: printList.value[0].config.deviceName,
|
||||
createdAt: dayjs(props.orderInfo.createdAt).format(
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
),
|
||||
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
||||
};
|
||||
ipcRenderer.send("printerInfoSync", JSON.stringify(data));
|
||||
}
|
||||
}
|
||||
|
||||
// 检测是否打印标签小票
|
||||
function checkLabelPrint(props) {
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
let pids = printLabelList.value[0].config.categoryList.map(item => item.id)
|
||||
let labelList = []
|
||||
props.carts.map(item => {
|
||||
if (pids.some(el => el == item.categoryId)) {
|
||||
for (let i = 0; i < item.number; i++) {
|
||||
labelList.push(
|
||||
{
|
||||
outNumber: props.outNumber,
|
||||
name: item.name,
|
||||
skuName: item.skuName,
|
||||
masterId: props.orderInfo.tableName,
|
||||
deviceName: printLabelList.value[0].config.deviceName,
|
||||
createdAt: dayjs(props.createdAt).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
printLabel(labelList)
|
||||
}
|
||||
}
|
||||
|
||||
// 打印标签
|
||||
let labelCount = ref(0)
|
||||
let labelPrintTimer = ref(null)
|
||||
function printLabel(list) {
|
||||
console.log(list);
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
labelPrintTimer.value = setInterval(() => {
|
||||
// console.log('labelCount', labelCount.value);
|
||||
list[labelCount.value].count = `${list.length - labelCount.value}/${list.length}`
|
||||
ipcRenderer.send('printerTagSync', JSON.stringify(list[labelCount.value]))
|
||||
labelCount.value++
|
||||
if (labelCount.value > list.length - 1) {
|
||||
clearInterval(labelPrintTimer.value)
|
||||
labelPrintTimer.value = null
|
||||
labelCount.value = 0
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
let ws = ref(null)
|
||||
let wsIsClose = ref(false)
|
||||
// 初始化websocket
|
||||
function initWebSocket(wsUrl = import.meta.env.VITE_API_WSS) {
|
||||
wsIsClose.value = false
|
||||
ws.value = new WebSocket(wsUrl);
|
||||
console.log("websocket:", ws.value);
|
||||
|
||||
ws.value.onopen = function () {
|
||||
console.log('wss连接成功');
|
||||
// 清除心跳
|
||||
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: useStorage.get('uuid')
|
||||
}))
|
||||
};
|
||||
|
||||
// 接收消息
|
||||
ws.value.onmessage = function (e) {
|
||||
// websocketonmessage(e);
|
||||
let data = JSON.parse(e.data)
|
||||
if (data.type == 'order') {
|
||||
console.log('接收消息', data);
|
||||
// 接收订单消息,打印小票
|
||||
// printBill(data)
|
||||
|
||||
// 检测是否需要打印标签小票
|
||||
checkLabelPrint(data)
|
||||
}
|
||||
};
|
||||
|
||||
// 连接发生错误
|
||||
ws.value.onerror = function () {
|
||||
console.log("WebSocket连接发生错误");
|
||||
|
||||
// 清除心跳
|
||||
clearInterval(heartbeatTimer.value)
|
||||
heartbeatTimer.value = null
|
||||
|
||||
// 手动关闭后不在执行自动连接任务
|
||||
if (!wsIsClose.value) reConnect(wsUrl);
|
||||
};
|
||||
|
||||
// 关闭
|
||||
ws.value.onclose = function (e) {
|
||||
console.log('ws关闭了', e);
|
||||
|
||||
// 清除心跳
|
||||
clearInterval(heartbeatTimer.value)
|
||||
heartbeatTimer.value = null
|
||||
|
||||
// 手动关闭后不在执行自动连接任务
|
||||
if (!wsIsClose.value) reConnect(wsUrl);
|
||||
};
|
||||
}
|
||||
|
||||
// 启动心跳连接
|
||||
let heartbeatTimer = ref(null)
|
||||
function startheartbeat() {
|
||||
heartbeatTimer.value = setInterval(() => {
|
||||
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
|
||||
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)
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getPrintList();
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
@ -87,28 +342,20 @@ router.beforeEach((to, from) => {
|
|||
--b-darker: calc(var(--b) * 0.8);
|
||||
|
||||
--primary-color: rgb(var(--r), var(--g), var(--b));
|
||||
--primary-color-hover: rgb(
|
||||
var(--r-lighter3),
|
||||
var(--g-lighter3),
|
||||
var(--b-lighter3)
|
||||
);
|
||||
--primary-color-hover: rgb(var(--r-lighter3),
|
||||
var(--g-lighter3),
|
||||
var(--b-lighter3));
|
||||
--el-color-primary: var(--primary-color) !important;
|
||||
--el-button-hover-bg-color: var(--primary-color) !important;
|
||||
--el-color-primary-light-3: rgb(
|
||||
var(--r-lighter),
|
||||
var(--g-lighter),
|
||||
var(--b-lighter)
|
||||
) !important;
|
||||
--el-color-primary-dark-2: rgb(
|
||||
var(--r-darker),
|
||||
var(--g-darker),
|
||||
var(--b-darker)
|
||||
) !important;
|
||||
--el-color-primary-light-5: rgb(
|
||||
var(--r-lighter2),
|
||||
var(--g-lighter2),
|
||||
var(--b-lighter2)
|
||||
) !important;
|
||||
--el-color-primary-light-3: rgb(var(--r-lighter),
|
||||
var(--g-lighter),
|
||||
var(--b-lighter)) !important;
|
||||
--el-color-primary-dark-2: rgb(var(--r-darker),
|
||||
var(--g-darker),
|
||||
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-message-close-size: var(--el-font-size-base) !important;
|
||||
|
|
@ -163,8 +410,7 @@ html {
|
|||
background-color: #555;
|
||||
margin-right: 0 !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 {
|
||||
|
|
@ -185,8 +431,7 @@ html {
|
|||
}
|
||||
|
||||
.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 {
|
||||
|
|
@ -274,7 +519,7 @@ html {
|
|||
display: flex;
|
||||
width: 200%;
|
||||
|
||||
& > div {
|
||||
&>div {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,66 +2,66 @@ import request from "@/utils/request.js";
|
|||
|
||||
/**
|
||||
* 新增打印机
|
||||
* @param {*} data
|
||||
* @returns
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachinePost(data, method = 'post') {
|
||||
return request({
|
||||
method: method,
|
||||
url: "tbPrintMachine",
|
||||
data
|
||||
});
|
||||
export function tbPrintMachinePost(data, method = "post") {
|
||||
return request({
|
||||
method: method,
|
||||
url: "tbPrintMachine",
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询打印机
|
||||
* @param {*} params
|
||||
* @returns
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachineGet(params) {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/tbPrintMachine",
|
||||
params
|
||||
});
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/tbPrintMachine",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过主键查询打印机
|
||||
* @param {*} params
|
||||
* @returns
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachineDetail(id) {
|
||||
return request({
|
||||
method: "get",
|
||||
url: `/tbPrintMachine/${id}`
|
||||
});
|
||||
return request({
|
||||
method: "get",
|
||||
url: `/tbPrintMachine/${id}`,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除打印机
|
||||
* @param {*} data
|
||||
* @returns
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
export function tbPrintMachineDelete(params) {
|
||||
return request({
|
||||
method: 'DELETE',
|
||||
url: "tbPrintMachine",
|
||||
params
|
||||
});
|
||||
return request({
|
||||
method: "DELETE",
|
||||
url: "tbPrintMachine",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据类型查询打印机列表
|
||||
* @param {*} params
|
||||
* @returns
|
||||
* @param {*} params
|
||||
* @returns
|
||||
*/
|
||||
export function bySubType(params) {
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/tbPrintMachine/bySubType",
|
||||
params
|
||||
});
|
||||
return request({
|
||||
method: "get",
|
||||
url: "/tbPrintMachine/bySubType",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -69,9 +69,9 @@ export function bySubType(params) {
|
|||
* @returns
|
||||
*/
|
||||
export function tbShopCategoryGet(params) {
|
||||
return request({
|
||||
url: `/tbShopCategory`,
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
return request({
|
||||
url: `/product/queryAllCategory`,
|
||||
method: "get",
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@
|
|||
<div class="item" v-for="item in tableData.list" :key="item.id">
|
||||
<div class="top">
|
||||
<div class="left">
|
||||
{{ item.outCode }} - {{ item.productName }}
|
||||
<div class="title">取餐号:{{ filterCode(item.outCode) }}</div>
|
||||
<div class="shop">商品:{{ item.productName }}</div>
|
||||
</div>
|
||||
<div class="state s1" v-if="item.status == 0">
|
||||
叫号成功
|
||||
<div class="dot"></div> 叫号成功
|
||||
</div>
|
||||
<div class="state s2" v-if="item.status == 1">
|
||||
叫号失败
|
||||
<div class="dot"></div> 叫号失败
|
||||
</div>
|
||||
</div>
|
||||
<div class="btm">
|
||||
|
|
@ -54,6 +55,7 @@
|
|||
<script setup>
|
||||
import _ from "lodash";
|
||||
import dayjs from 'dayjs'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { useUser } from "@/store/user.js";
|
||||
import { scanSendMessage, getsendMessage } from '@/api/order/index'
|
||||
|
|
@ -85,8 +87,15 @@ const tableData = reactive({
|
|||
|
||||
const emit = defineEmits(['success'])
|
||||
|
||||
// 截取字符串
|
||||
function filterCode(t, c = '#') {
|
||||
let n = t.split(c)
|
||||
return n[1]
|
||||
}
|
||||
|
||||
function show() {
|
||||
dialogVisible.value = true
|
||||
getsendMessageAjax()
|
||||
setTimeout(() => {
|
||||
inputRef.value.focus();
|
||||
}, 500);
|
||||
|
|
@ -120,6 +129,7 @@ function handleCurrentChange() {
|
|||
// 获取叫号记录
|
||||
async function getsendMessageAjax() {
|
||||
try {
|
||||
if (!store.userInfo.shopId) return
|
||||
tableData.loading = true
|
||||
const res = await getsendMessage({
|
||||
page: tableData.page,
|
||||
|
|
@ -132,6 +142,7 @@ async function getsendMessageAjax() {
|
|||
tableData.total = res.total
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
tableData.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +156,10 @@ const confirmHandle = _.throttle(async function () {
|
|||
shopId: store.userInfo.shopId,
|
||||
// shopId: 4
|
||||
})
|
||||
ElMessage.success('叫号成功')
|
||||
|
||||
loading.value = false
|
||||
number.value = ''
|
||||
getsendMessageAjax()
|
||||
setTimeout(() => {
|
||||
inputRef.value.focus();
|
||||
|
|
@ -163,10 +177,6 @@ const confirmHandle = _.throttle(async function () {
|
|||
defineExpose({
|
||||
show
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getsendMessageAjax()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
@ -218,15 +228,42 @@ onMounted(() => {
|
|||
|
||||
.left {
|
||||
color: #000;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.shop {
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
|
||||
.state {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.dot {
|
||||
$size: 6px;
|
||||
width: $size;
|
||||
height: $size;
|
||||
border-radius: 50%;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
&.s1 {
|
||||
color: var(--primary-color);
|
||||
|
||||
.dot {
|
||||
background-color: var(--primary-color);
|
||||
}
|
||||
}
|
||||
|
||||
&.s2 {
|
||||
color: var(--el-color-error);
|
||||
|
||||
.dot {
|
||||
background-color: var(--el-color-error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -236,7 +273,8 @@ onMounted(() => {
|
|||
justify-content: space-between;
|
||||
padding-top: 4px;
|
||||
|
||||
.time {
|
||||
.time,
|
||||
.info {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,18 +4,9 @@
|
|||
<div class="row" v-for="(item, index) in categorys" :key="item.id">
|
||||
<div class="list_title">{{ item.name }}</div>
|
||||
<div class="item_wrap">
|
||||
<el-button
|
||||
:type="item.active ? 'primary' : ''"
|
||||
@click="selectHandle(item)"
|
||||
>全部</el-button
|
||||
>
|
||||
<el-button
|
||||
:type="val.active ? 'primary' : ''"
|
||||
v-for="val in item.childrenList"
|
||||
:key="val.id"
|
||||
@click="selectHandle(val, index)"
|
||||
>{{ val.name }}</el-button
|
||||
>
|
||||
<el-button :type="item.active ? 'primary' : ''" @click="selectHandle(item)">全部</el-button>
|
||||
<el-button :type="val.active ? 'primary' : ''" v-for="val in item.childrenList" :key="val.id"
|
||||
@click="selectHandle(val, index)">{{ val.name }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -82,15 +73,16 @@ async function tbShopCategoryGetAjax() {
|
|||
shopId: store.userInfo.shopId,
|
||||
sort: "sort,desc",
|
||||
page: 0,
|
||||
size: 500,
|
||||
pageSize: 200,
|
||||
});
|
||||
res.map((item) => {
|
||||
console.log(res);
|
||||
res.list.map((item) => {
|
||||
item.active = false;
|
||||
item.childrenList.map((item) => {
|
||||
item.active = false;
|
||||
});
|
||||
});
|
||||
categorys.value = res;
|
||||
categorys.value = res.list;
|
||||
|
||||
setTimeout(() => {
|
||||
loading.value = false;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
<template>
|
||||
<div class="device_container">
|
||||
<div class="header" @click="router.back()">
|
||||
<el-icon
|
||||
style="position: relative; top: 2px; margin-right: 4px"
|
||||
size="22"
|
||||
>
|
||||
<el-icon style="position: relative; top: 2px; margin-right: 4px" size="22">
|
||||
<ArrowLeft />
|
||||
</el-icon>
|
||||
<el-text>{{ form.id ? "编辑便签打印机" : "添加便签打印机" }}</el-text>
|
||||
|
|
@ -26,28 +23,15 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="选择设备">
|
||||
<el-select v-model="form.config.deviceName">
|
||||
<el-option
|
||||
:label="item.name"
|
||||
:value="item.name"
|
||||
v-for="item in printList"
|
||||
:key="item.name"
|
||||
></el-option>
|
||||
<el-option :label="item.name" :value="item.name" v-for="item in printList" :key="item.name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备名称">
|
||||
<el-input
|
||||
v-model="form.name"
|
||||
placeholder="请输入设备名称"
|
||||
></el-input>
|
||||
<el-input v-model="form.name" placeholder="请输入设备名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="打印份数">
|
||||
<el-select v-model="form.config.printerNum">
|
||||
<el-option
|
||||
:label="item"
|
||||
:value="item"
|
||||
v-for="item in 4"
|
||||
:key="item"
|
||||
></el-option>
|
||||
<el-option :label="item" :value="item" v-for="item in 4" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="商品模式">
|
||||
|
|
@ -58,16 +42,10 @@
|
|||
</el-form-item>
|
||||
<el-form-item label="商品分类">
|
||||
<div style="cursor: pointer" @click="classifyRef.show()">
|
||||
<span
|
||||
style="color: #409eff"
|
||||
v-for="item in form.config.categoryList"
|
||||
>
|
||||
<span style="color: #409eff" v-for="item in form.config.categoryList">
|
||||
{{ item.name }},
|
||||
</span>
|
||||
<span
|
||||
style="color: #e65d6e"
|
||||
v-if="!form.config.categoryList.length"
|
||||
>
|
||||
<span style="color: #e65d6e" v-if="!form.config.categoryList.length">
|
||||
请选择分类
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -115,12 +93,7 @@
|
|||
</el-button>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button
|
||||
type="primary"
|
||||
style="width: 100%"
|
||||
:loading="loading"
|
||||
@click="submitHandle"
|
||||
>
|
||||
<el-button type="primary" style="width: 100%" :loading="loading" @click="submitHandle">
|
||||
保存
|
||||
</el-button>
|
||||
</div>
|
||||
|
|
@ -129,17 +102,14 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<classify
|
||||
ref="classifyRef"
|
||||
@success="(e) => (form.config.categoryList = e)"
|
||||
/>
|
||||
<classify ref="classifyRef" @success="(e) => (form.config.categoryList = e)" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ipcRenderer } from "electron";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ElMessage, dayjs } from "element-plus";
|
||||
import { tbPrintMachinePost, tbPrintMachineDetail } from "@/api/device";
|
||||
import { useUser } from "@/store/user.js";
|
||||
import { Loading } from "element-plus/es/components/loading/src/service";
|
||||
|
|
@ -190,8 +160,15 @@ function printHandle() {
|
|||
return;
|
||||
}
|
||||
ipcRenderer.send(
|
||||
"printStart",
|
||||
JSON.stringify({ deviceName: form.value.config.deviceName })
|
||||
"printerTagSync",
|
||||
JSON.stringify({
|
||||
deviceName: form.value.config.deviceName,
|
||||
outNumber: '123',
|
||||
name: '甜橙马黛茶',
|
||||
skuName: '加奶、加珍珠',
|
||||
masterId: '#A9',
|
||||
createdAt: dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -268,9 +245,11 @@ onMounted(() => {
|
|||
|
||||
.print_view {
|
||||
padding: 20px 0;
|
||||
|
||||
.blod {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,241 @@
|
|||
<template>
|
||||
<!-- <el-button @click="chooseSerial">获取串口列表</el-button> -->
|
||||
<el-button @click="printTag">打印标签</el-button>
|
||||
<el-button @click="initWebSocket()">连接ws</el-button>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import _ from 'lodash'
|
||||
import { bySubType } from "@/api/device";
|
||||
import { ElMessage } from "element-plus";
|
||||
import dayjs from 'dayjs'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { onMounted } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useUser } from "@/store/user.js";
|
||||
import useStorage from '@/utils/useStorage'
|
||||
const store = useUser();
|
||||
|
||||
// 小票打印机列表
|
||||
const printList = ref([]);
|
||||
// 标签打印机列表
|
||||
const printLabelList = ref([]);
|
||||
const localPrintList = ref([])
|
||||
|
||||
// 获取打印机状态
|
||||
async function bySubTypeAjax() {
|
||||
try {
|
||||
const res1 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "cash",
|
||||
});
|
||||
const res2 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "label",
|
||||
});
|
||||
printList.value = res1;
|
||||
printLabelList.value = res2;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取本地打印机列表
|
||||
function getPrintList() {
|
||||
ipcRenderer.send("getPrintList");
|
||||
ipcRenderer.on("printList", (event, arg) => {
|
||||
localPrintList.value = arg;
|
||||
// console.log(localPrintList.value);
|
||||
});
|
||||
}
|
||||
|
||||
// 检查本地打印机是否能正常使用
|
||||
function checkLocalPrint(deviceName) {
|
||||
let print = ''
|
||||
for (let item of localPrintList.value) {
|
||||
if (item.name == deviceName) {
|
||||
print = item
|
||||
}
|
||||
}
|
||||
|
||||
if (!print.name) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 打印小票
|
||||
function printBill(props) {
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
const data = {
|
||||
shop_name: store.userInfo.merchantName,
|
||||
carts: props.carts,
|
||||
amount: props.amount,
|
||||
remark: props.remark,
|
||||
orderInfo: props.orderInfo,
|
||||
deviceName: printList.value[0].config.deviceName,
|
||||
createdAt: dayjs(props.orderInfo.createdAt).format(
|
||||
"YYYY-MM-DD HH:mm:ss"
|
||||
),
|
||||
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
||||
};
|
||||
ipcRenderer.send("printerInfoSync", JSON.stringify(data));
|
||||
}
|
||||
}
|
||||
|
||||
// 检测是否打印标签小票
|
||||
function checkLabelPrint(props) {
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
let pids = printLabelList.value[0].config.categoryList.map(item => item.id)
|
||||
let labelList = []
|
||||
props.carts.map(item => {
|
||||
if (pids.some(el => el == item.categoryId)) {
|
||||
for (let i = 0; i < item.number; i++) {
|
||||
labelList.push(
|
||||
{
|
||||
outNumber: props.outNumber,
|
||||
name: item.name,
|
||||
skuName: item.skuName,
|
||||
masterId: props.orderInfo.tableName,
|
||||
deviceName: printLabelList.value[0].config.deviceName,
|
||||
createdAt: dayjs(props.createdAt).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
printLabel(labelList)
|
||||
}
|
||||
}
|
||||
|
||||
// 打印标签
|
||||
let labelCount = ref(0)
|
||||
let labelPrintTimer = ref(null)
|
||||
function printLabel(list) {
|
||||
console.log(list);
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
labelPrintTimer.value = setInterval(() => {
|
||||
// console.log('labelCount', labelCount.value);
|
||||
list[labelCount.value].count = `${list.length - labelCount.value}/${list.length}`
|
||||
ipcRenderer.send('printerTagSync', JSON.stringify(list[labelCount.value]))
|
||||
labelCount.value++
|
||||
if (labelCount.value > list.length - 1) {
|
||||
clearInterval(labelPrintTimer.value)
|
||||
labelPrintTimer.value = null
|
||||
labelCount.value = 0
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
let ws = ref(null)
|
||||
let wsIsClose = ref(false)
|
||||
// 初始化websocket
|
||||
function initWebSocket(wsUrl = 'wss://wxcashiertest.sxczgkj.cn/client') {
|
||||
ws.value = new WebSocket(wsUrl);
|
||||
console.log("websocket:", ws.value);
|
||||
|
||||
ws.value.onopen = function () {
|
||||
console.log('wss连接成功');
|
||||
// 清除心跳
|
||||
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: useStorage.get('uuid')
|
||||
}))
|
||||
};
|
||||
|
||||
// 接收消息
|
||||
ws.value.onmessage = function (e) {
|
||||
// websocketonmessage(e);
|
||||
let data = JSON.parse(e.data)
|
||||
if (data.type == 'order') {
|
||||
console.log('接收消息', data);
|
||||
// 接收订单消息,打印小票
|
||||
// printBill(data)
|
||||
|
||||
// 检测是否需要打印标签小票
|
||||
checkLabelPrint(data)
|
||||
}
|
||||
};
|
||||
|
||||
// 连接发生错误
|
||||
ws.value.onerror = function () {
|
||||
console.log("WebSocket连接发生错误");
|
||||
|
||||
// 清除心跳
|
||||
clearInterval(heartbeatTimer.value)
|
||||
heartbeatTimer.value = null
|
||||
|
||||
// 手动关闭后不在执行自动连接任务
|
||||
if (!wsIsClose.value) reConnect(wsUrl);
|
||||
};
|
||||
|
||||
// 关闭
|
||||
ws.value.onclose = function (e) {
|
||||
console.log('ws关闭了', e);
|
||||
|
||||
// 清除心跳
|
||||
clearInterval(heartbeatTimer.value)
|
||||
heartbeatTimer.value = null
|
||||
|
||||
// 手动关闭后不在执行自动连接任务
|
||||
if (!wsIsClose.value) reConnect(wsUrl);
|
||||
};
|
||||
}
|
||||
|
||||
// 启动心跳连接
|
||||
let heartbeatTimer = ref(null)
|
||||
function startheartbeat() {
|
||||
heartbeatTimer.value = setInterval(() => {
|
||||
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
|
||||
reConnectTimer.value = setInterval(() => {
|
||||
// 自动连接超过5次不在连接,需手动出发
|
||||
console.log('reConnectCount.value===', reConnectCount.value);
|
||||
if (reConnectCount.value >= 5) {
|
||||
console.log('重连超过5次,不在连接');
|
||||
clearInterval(reConnectTimer.value)
|
||||
reConnectTimer.value = null
|
||||
reConnectCount.value = 0
|
||||
wsIsClose.value = true
|
||||
ws.value.close()
|
||||
} else {
|
||||
reConnectCount.value++
|
||||
initWebSocket(wsUrl)
|
||||
}
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 打印标签小票
|
||||
const printTag = () => {
|
||||
|
|
@ -25,12 +255,17 @@ const chooseSerial = async () => {
|
|||
// localStorage.setItem('printNum', printNum)
|
||||
// }
|
||||
// ipcRenderer.send('printStart', printNum)
|
||||
ipcRenderer.send('getSerialPort')
|
||||
// ipcRenderer.send('getSerialPort')
|
||||
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
ipcRenderer.on('seriaportList', (e, a) => {
|
||||
console.log('seriaportList', a);
|
||||
})
|
||||
|
||||
getPrintList();
|
||||
bySubTypeAjax();
|
||||
initWebSocket()
|
||||
})
|
||||
</script>
|
||||
|
|
@ -247,6 +247,120 @@ import { clearNoNum } from '@/utils'
|
|||
const store = useUser()
|
||||
const itemboxshow = ref(false)
|
||||
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
|
||||
import { bySubType } from "@/api/device";
|
||||
|
||||
|
||||
// 小票打印机列表
|
||||
const printList = ref([]);
|
||||
// 标签打印机列表
|
||||
const printLabelList = ref([]);
|
||||
const localPrintList = ref([])
|
||||
|
||||
// 获取打印机状态
|
||||
async function bySubTypeAjax() {
|
||||
try {
|
||||
const res1 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "cash",
|
||||
});
|
||||
const res2 = await bySubType({
|
||||
shopId: store.userInfo.shopId,
|
||||
contentType: "local",
|
||||
subType: "label",
|
||||
});
|
||||
printList.value = res1;
|
||||
printLabelList.value = res2;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取本地打印机列表
|
||||
function getPrintList() {
|
||||
ipcRenderer.send("getPrintList");
|
||||
ipcRenderer.on("printList", (event, arg) => {
|
||||
localPrintList.value = arg;
|
||||
// console.log(localPrintList.value);
|
||||
});
|
||||
}
|
||||
|
||||
// 检查本地打印机是否能正常使用
|
||||
function checkLocalPrint(deviceName) {
|
||||
let print = ''
|
||||
for (let item of localPrintList.value) {
|
||||
if (item.name == deviceName) {
|
||||
print = item
|
||||
}
|
||||
}
|
||||
|
||||
if (!print.name) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 检测是否打印标签小票
|
||||
function checkLabelPrint(props) {
|
||||
// console.log(props);
|
||||
// console.log(printLabelList.value);
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
let pids = printLabelList.value[0].config.categoryList.map(item => item.id)
|
||||
let labelList = []
|
||||
props.skuInfos.map(item => {
|
||||
if (pids.some(el => el == item.categoryId)) {
|
||||
for (let i = 0; i < item.num; i++) {
|
||||
labelList.push(
|
||||
{
|
||||
outNumber: props.outNumber,
|
||||
name: item.productName,
|
||||
skuName: item.productSkuName,
|
||||
masterId: props.tableName,
|
||||
deviceName: printLabelList.value[0].config.deviceName,
|
||||
createdAt: dayjs(props.createAt).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (labelList.length) printLabel(labelList)
|
||||
}
|
||||
}
|
||||
|
||||
// 打印标签
|
||||
let labelCount = ref(0)
|
||||
let labelPrintTimer = ref(null)
|
||||
const printLabel = lodash.throttle(function (list) {
|
||||
// console.log('printLabel===', list);
|
||||
if (!checkLocalPrint(printLabelList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
} else {
|
||||
clearInterval(labelPrintTimer.value)
|
||||
labelPrintTimer.value = null
|
||||
labelCount.value = 0
|
||||
labelPrintTimer.value = setInterval(() => {
|
||||
// console.log('labelCount', labelCount.value);
|
||||
list[labelCount.value].count = `${list.length - labelCount.value}/${list.length}`
|
||||
ipcRenderer.send('printerTagSync', JSON.stringify(list[labelCount.value]))
|
||||
labelCount.value++
|
||||
console.log(labelCount.value);
|
||||
if (labelCount.value > list.length - 1) {
|
||||
clearInterval(labelPrintTimer.value)
|
||||
labelPrintTimer.value = null
|
||||
labelCount.value = 0
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
}, 1500, { leading: true, trailing: false })
|
||||
|
||||
|
||||
const handleClick = (Name) => {//切换teb
|
||||
ordereData.status = Name.props.name
|
||||
asyncorderfindOrder()
|
||||
|
|
@ -303,23 +417,32 @@ const payreturnOrderclick = lodash.debounce(async () => { //搜索手机号
|
|||
|
||||
const print = async (e) => {
|
||||
try {
|
||||
await cloudPrinterprint({
|
||||
type: e,
|
||||
orderId: orderDetaildata.value.id,
|
||||
ispre: false
|
||||
})
|
||||
ElMessage({
|
||||
message: '成功打票',
|
||||
type: 'success',
|
||||
})
|
||||
if (e == 'label' && printLabelList.value.length) {
|
||||
checkLabelPrint(printLabelOrder.value)
|
||||
} else {
|
||||
await cloudPrinterprint({
|
||||
type: e,
|
||||
orderId: orderDetaildata.value.id,
|
||||
ispre: false
|
||||
})
|
||||
ElMessage({
|
||||
message: '成功打票',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
const loadingboxshow = ref(false);
|
||||
// 要打印标签的订单数据
|
||||
const printLabelOrder = ref('')
|
||||
|
||||
const emititemboxshow = async (e) => { //接收子组件值 并赋值给父组件
|
||||
// console.log('emititemboxshow', e);
|
||||
printLabelOrder.value = e
|
||||
|
||||
loadingboxshow.value = true
|
||||
try {
|
||||
let res = await orderorderDetail({
|
||||
|
|
@ -453,6 +576,9 @@ const callNumberHandle = async () => {
|
|||
onMounted(() => {
|
||||
// resetMembrform.value = { ...membrform.value }
|
||||
asyncorderfindOrder()
|
||||
|
||||
getPrintList();
|
||||
bySubTypeAjax();
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,18 @@ const exit = async () => {
|
|||
try {
|
||||
if (printList.value.length) {
|
||||
if (!checkLocalPrint(printList.value[0].config.deviceName)) {
|
||||
ElMessage.error("本地打印机无法使用,请检查打印机是否正确连接");
|
||||
loading.value = true;
|
||||
let res = await loginlogout({
|
||||
status: 1
|
||||
})
|
||||
useStorage.clear()
|
||||
ElMessage.success("交班成功");
|
||||
setTimeout(() => {
|
||||
router.replace({
|
||||
name: "login",
|
||||
});
|
||||
}, 1000);
|
||||
loading.value = false;
|
||||
} else {
|
||||
// 获取交班打印小票数据
|
||||
const data = await handoverData({
|
||||
|
|
|
|||
Loading…
Reference in New Issue