Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f522fa9d2 | |||
| efb7dd3e57 | |||
| ac469cbc32 | |||
| f8c5c9bf59 | |||
| 6e2e7f9719 | |||
| b4872fec16 | |||
| 804b677174 | |||
| 367b49c68a | |||
| f393299f0f | |||
| 49cabfed21 | |||
| b2e450fd52 | |||
|
|
4fb34a4235 | ||
|
|
fdacaab44a | ||
| b33086ba04 | |||
|
|
fd6410f742 | ||
| ea0c01bb2b | |||
| 4eb5df7668 | |||
| 2c58c99d1e | |||
| 9e57753323 | |||
| d2183eec37 | |||
| a282636266 | |||
| c155e8a805 | |||
| aa25c6be3b | |||
| 4543854d0a | |||
| 5e7935bb53 | |||
| 38366601d4 | |||
| e00feb82ec | |||
| 815b6e0a25 | |||
| 8c1e1d3fbc | |||
| bb554a28d2 | |||
| 2a09a3fd5b | |||
| a70fa744b2 | |||
| 91670a440b | |||
| d101ecea41 |
@@ -11,15 +11,20 @@ VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
|||||||
# 阿伟本地ws
|
# 阿伟本地ws
|
||||||
# VITE_API_WSS = 'ws://192.168.2.17:9998/client'
|
# VITE_API_WSS = 'ws://192.168.2.17:9998/client'
|
||||||
|
|
||||||
|
# 正式 php
|
||||||
|
VITE_API_PHP_URL = 'https://czgdoumei.sxczgkj.com/index.php/api'
|
||||||
|
|
||||||
# 测试 php
|
# 测试 php 开票
|
||||||
VITE_API_PHP_URL = 'http://192.168.2.33:1666/index.php/api'
|
# VITE_API_KP_URL = 'http://192.168.1.13:8888/api'
|
||||||
|
|
||||||
|
# 正式 php 开票
|
||||||
|
VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
|
||||||
|
|
||||||
# 阿伟
|
# 阿伟
|
||||||
# VITE_API_URL = 'http://192.168.2.96:10587/cashier-client'
|
# VITE_API_URL = 'http://192.168.2.96:10587/cashier-client'
|
||||||
|
|
||||||
# 鹏辉
|
# 鹏辉
|
||||||
# VITE_API_URL = 'http://192.168.2.41:10589/cashier-client'
|
# VITE_API_URL = 'http://192.168.1.106:10589/cashier-client'
|
||||||
|
|
||||||
# 测试
|
# 测试
|
||||||
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
# VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
||||||
|
|||||||
@@ -4,14 +4,11 @@ ENV = production
|
|||||||
# 正式ws
|
# 正式ws
|
||||||
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
||||||
|
|
||||||
#测试ws
|
# 正式 php
|
||||||
# VITE_API_WSS = 'wss://wxcashiertest.sxczgkj.cn/client'
|
VITE_API_PHP_URL = 'https://czgdoumei.sxczgkj.com/index.php/api'
|
||||||
|
|
||||||
# 测试 php
|
# 正式 php 开票
|
||||||
VITE_API_PHP_URL = 'http://192.168.2.33:1666/index.php/api'
|
VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
|
||||||
|
|
||||||
# 测试
|
|
||||||
# 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/'
|
||||||
23
.env.test
Normal file
23
.env.test
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 线上环境
|
||||||
|
ENV = test
|
||||||
|
|
||||||
|
#测试ws
|
||||||
|
VITE_API_WSS = 'wss://wxcashiertest.sxczgkj.cn/client'
|
||||||
|
|
||||||
|
# 正式ws
|
||||||
|
# VITE_API_WSS = 'wss://cashier.sxczgkj.cn/client'
|
||||||
|
|
||||||
|
# 正式 php
|
||||||
|
VITE_API_PHP_URL = 'https://czgdoumei.sxczgkj.com/index.php/api'
|
||||||
|
|
||||||
|
# 测试 php 开票
|
||||||
|
# VITE_API_KP_URL = 'http://192.168.1.13:8888/api'
|
||||||
|
|
||||||
|
# 正式 php 开票
|
||||||
|
VITE_API_KP_URL = 'https://invoice.sxczgkj.cn/api'
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
VITE_API_URL = 'https://cashier-client.sxczgkj.cn/cashier-client'
|
||||||
|
|
||||||
|
# 正式
|
||||||
|
# VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const electron = require("electron");
|
const electron = require("electron");
|
||||||
|
const os = require("os");
|
||||||
let win;
|
let win;
|
||||||
electron.app.whenReady().then(() => {
|
electron.app.whenReady().then(() => {
|
||||||
win = new electron.BrowserWindow({
|
win = new electron.BrowserWindow({
|
||||||
@@ -28,102 +29,28 @@ electron.app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
electron.ipcMain.on("quitHandler", (_, msg) => {
|
electron.ipcMain.on("quitHandler", (_, msg) => {
|
||||||
electron.app.quit();
|
win = null;
|
||||||
|
electron.app.exit();
|
||||||
});
|
});
|
||||||
electron.ipcMain.on("getPrintList", () => {
|
electron.ipcMain.on("getPrintList", () => {
|
||||||
win.webContents.getPrintersAsync().then((res) => {
|
win.webContents.getPrintersAsync().then((res) => {
|
||||||
win.webContents.send("printList", res);
|
win.webContents.send("printList", res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const printWin = new electron.BrowserWindow({
|
electron.ipcMain.on("getOSmacSync", () => {
|
||||||
show: false,
|
let mac = "";
|
||||||
width: 464,
|
if (os.networkInterfaces().WLAN) {
|
||||||
height: 1726,
|
mac = os.networkInterfaces().WLAN[0].mac;
|
||||||
webPreferences: {
|
console.log("wlan.mac===", mac);
|
||||||
// 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
|
} else {
|
||||||
nodeIntegration: true,
|
mac = os.networkInterfaces()["以太网"][0].mac;
|
||||||
contextIsolation: false
|
console.log("以太网.mac===", mac);
|
||||||
}
|
}
|
||||||
});
|
win.webContents.send("getOSmacRes", mac);
|
||||||
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) => {
|
|
||||||
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({
|
const tagPrintWin = new electron.BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
width: 320,
|
width: 360,
|
||||||
height: 240,
|
height: 240,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
@@ -146,7 +73,7 @@ electron.app.whenReady().then(() => {
|
|||||||
silent: true,
|
silent: true,
|
||||||
deviceName: name,
|
deviceName: name,
|
||||||
pageSize: {
|
pageSize: {
|
||||||
width: 4e4,
|
width: 45e3,
|
||||||
height: 3e4
|
height: 3e4
|
||||||
},
|
},
|
||||||
scaleFactor: 80,
|
scaleFactor: 80,
|
||||||
@@ -164,6 +91,23 @@ electron.app.whenReady().then(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
const gotTheLock = electron.app.requestSingleInstanceLock();
|
||||||
|
if (!gotTheLock) {
|
||||||
|
electron.app.quit();
|
||||||
|
} else {
|
||||||
|
electron.app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||||||
|
if (win) {
|
||||||
|
if (win.isMinimized())
|
||||||
|
win.restore();
|
||||||
|
win.focus();
|
||||||
|
win.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
win.on("close", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
win.webContents.send("showCloseDialog");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
electron.app.on("window-all-closed", () => {
|
electron.app.on("window-all-closed", () => {
|
||||||
if (process.platform !== "darwin")
|
if (process.platform !== "darwin")
|
||||||
|
|||||||
234
electron/main.js
234
electron/main.js
@@ -1,5 +1,6 @@
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import { app, BrowserWindow, ipcMain } from "electron";
|
import { app, BrowserWindow, ipcMain } from "electron";
|
||||||
|
import os from "os";
|
||||||
// const SerialPort = require("serialport");
|
// const SerialPort = require("serialport");
|
||||||
|
|
||||||
let win;
|
let win;
|
||||||
@@ -37,7 +38,8 @@ app.whenReady().then(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.on("quitHandler", (_, msg) => {
|
ipcMain.on("quitHandler", (_, msg) => {
|
||||||
app.quit();
|
win = null;
|
||||||
|
app.exit();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 给渲染进程返回打印机列表
|
// 给渲染进程返回打印机列表
|
||||||
@@ -47,6 +49,19 @@ app.whenReady().then(() => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 获取本机mac
|
||||||
|
ipcMain.on("getOSmacSync", () => {
|
||||||
|
let mac = "";
|
||||||
|
if (os.networkInterfaces().WLAN) {
|
||||||
|
mac = os.networkInterfaces().WLAN[0].mac;
|
||||||
|
console.log("wlan.mac===", mac);
|
||||||
|
} else {
|
||||||
|
mac = os.networkInterfaces()["以太网"][0].mac;
|
||||||
|
console.log("以太网.mac===", mac);
|
||||||
|
}
|
||||||
|
win.webContents.send("getOSmacRes", mac);
|
||||||
|
});
|
||||||
|
|
||||||
// ipcMain.on("getSerialPort", () => {
|
// ipcMain.on("getSerialPort", () => {
|
||||||
// SerialPort.SerialPort.list().then(
|
// SerialPort.SerialPort.list().then(
|
||||||
// (ports) => {
|
// (ports) => {
|
||||||
@@ -58,114 +73,114 @@ app.whenReady().then(() => {
|
|||||||
// });
|
// });
|
||||||
|
|
||||||
// 创建打印小票子窗口
|
// 创建打印小票子窗口
|
||||||
const printWin = new BrowserWindow({
|
// const printWin = new BrowserWindow({
|
||||||
show: false,
|
// show: false,
|
||||||
width: 464,
|
// width: 464,
|
||||||
height: 1726,
|
// height: 1726,
|
||||||
webPreferences: {
|
// webPreferences: {
|
||||||
// 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
|
// // 集成网页和 Node.js,也就是在渲染进程中,可以调用 Node.js 方法
|
||||||
nodeIntegration: true,
|
// nodeIntegration: true,
|
||||||
contextIsolation: false,
|
// contextIsolation: false,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (process.env.VITE_DEV_SERVER_URL) {
|
// if (process.env.VITE_DEV_SERVER_URL) {
|
||||||
// 加载打印的html文件
|
// // 加载打印的html文件
|
||||||
printWin.loadFile(path.join(__dirname, "../public/print.html"));
|
// printWin.loadFile(path.join(__dirname, "../public/print.html"));
|
||||||
} else {
|
// } else {
|
||||||
printWin.loadFile(path.resolve(__dirname, "../dist/print.html")); // 打包后使用文件路径访问应用
|
// printWin.loadFile(path.resolve(__dirname, "../dist/print.html")); // 打包后使用文件路径访问应用
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 接收订单页面发过来的参数发送给打印页
|
// // 接收订单页面发过来的参数发送给打印页
|
||||||
ipcMain.on("printerInfoSync", (event, arg) => {
|
// ipcMain.on("printerInfoSync", (event, arg) => {
|
||||||
printWin.webContents.send("getParams", arg);
|
// printWin.webContents.send("getParams", arg);
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 执行打印操作
|
// // 执行打印操作
|
||||||
ipcMain.on("printStart", (event, arg) => {
|
// ipcMain.on("printStart", (event, arg) => {
|
||||||
console.log(arg);
|
// console.log(arg);
|
||||||
const _parmas = JSON.parse(arg);
|
// const _parmas = JSON.parse(arg);
|
||||||
// console.log(_parmas)
|
// // console.log(_parmas)
|
||||||
let name = _parmas.deviceName;
|
// let name = _parmas.deviceName;
|
||||||
printWin.webContents.print({
|
// printWin.webContents.print({
|
||||||
silent: true,
|
// silent: true,
|
||||||
deviceName: name,
|
// deviceName: name,
|
||||||
pageSize: {
|
// pageSize: {
|
||||||
width: 58000,
|
// width: 58000,
|
||||||
height: 216000,
|
// height: 216000,
|
||||||
},
|
// },
|
||||||
scaleFactor: 80,
|
// scaleFactor: 80,
|
||||||
landscape: false,
|
// landscape: false,
|
||||||
margins: {
|
// margins: {
|
||||||
marginType: "none",
|
// marginType: "none",
|
||||||
top: 0,
|
// top: 0,
|
||||||
bottom: 0,
|
// bottom: 0,
|
||||||
left: 0,
|
// left: 0,
|
||||||
right: 0,
|
// right: 0,
|
||||||
},
|
// },
|
||||||
dpi: {
|
// dpi: {
|
||||||
horizontal: 203,
|
// horizontal: 203,
|
||||||
vertical: 203,
|
// vertical: 203,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 交班小票的窗口
|
// // 交班小票的窗口
|
||||||
const workPrintWin = new BrowserWindow({
|
// const workPrintWin = new BrowserWindow({
|
||||||
show: false,
|
// show: false,
|
||||||
width: 464,
|
// width: 464,
|
||||||
height: 1726,
|
// height: 1726,
|
||||||
webPreferences: {
|
// webPreferences: {
|
||||||
nodeIntegration: true,
|
// nodeIntegration: true,
|
||||||
contextIsolation: false,
|
// contextIsolation: false,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (process.env.VITE_DEV_SERVER_URL) {
|
// if (process.env.VITE_DEV_SERVER_URL) {
|
||||||
// 加载打印的html文件
|
// // 加载打印的html文件
|
||||||
workPrintWin.loadFile(path.join(__dirname, "../public/work_print.html"));
|
// workPrintWin.loadFile(path.join(__dirname, "../public/work_print.html"));
|
||||||
} else {
|
// } else {
|
||||||
workPrintWin.loadFile(path.resolve(__dirname, "../dist/work_print.html")); // 打包后使用文件路径访问应用
|
// workPrintWin.loadFile(path.resolve(__dirname, "../dist/work_print.html")); // 打包后使用文件路径访问应用
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 接收渲染进程发送的数据
|
// // 接收渲染进程发送的数据
|
||||||
ipcMain.on("printerWorkSync", (event, arg) => {
|
// ipcMain.on("printerWorkSync", (event, arg) => {
|
||||||
workPrintWin.webContents.send("getParams", arg);
|
// workPrintWin.webContents.send("getParams", arg);
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 执行交班小票的打印操作
|
// // 执行交班小票的打印操作
|
||||||
ipcMain.on("printWorkStart", (event, arg) => {
|
// ipcMain.on("printWorkStart", (event, arg) => {
|
||||||
// console.log(arg);
|
// // console.log(arg);
|
||||||
const _parmas = JSON.parse(arg);
|
// const _parmas = JSON.parse(arg);
|
||||||
// console.log(_parmas)
|
// // console.log(_parmas)
|
||||||
let name = _parmas.deviceName;
|
// let name = _parmas.deviceName;
|
||||||
workPrintWin.webContents.print({
|
// workPrintWin.webContents.print({
|
||||||
silent: true,
|
// silent: true,
|
||||||
deviceName: name,
|
// deviceName: name,
|
||||||
pageSize: {
|
// pageSize: {
|
||||||
width: 58000,
|
// width: 58000,
|
||||||
height: 216000,
|
// height: 216000,
|
||||||
},
|
// },
|
||||||
scaleFactor: 80,
|
// scaleFactor: 80,
|
||||||
landscape: false,
|
// landscape: false,
|
||||||
margins: {
|
// margins: {
|
||||||
marginType: "none",
|
// marginType: "none",
|
||||||
top: 0,
|
// top: 0,
|
||||||
bottom: 0,
|
// bottom: 0,
|
||||||
left: 0,
|
// left: 0,
|
||||||
right: 0,
|
// right: 0,
|
||||||
},
|
// },
|
||||||
dpi: {
|
// dpi: {
|
||||||
horizontal: 203,
|
// horizontal: 203,
|
||||||
vertical: 203,
|
// vertical: 203,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 标签小票的窗口
|
// 标签小票的窗口
|
||||||
const tagPrintWin = new BrowserWindow({
|
const tagPrintWin = new BrowserWindow({
|
||||||
show: false,
|
show: false,
|
||||||
width: 320,
|
width: 360,
|
||||||
height: 240,
|
height: 240,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
@@ -196,7 +211,7 @@ app.whenReady().then(() => {
|
|||||||
silent: true,
|
silent: true,
|
||||||
deviceName: name,
|
deviceName: name,
|
||||||
pageSize: {
|
pageSize: {
|
||||||
width: 40000,
|
width: 45000,
|
||||||
height: 30000,
|
height: 30000,
|
||||||
},
|
},
|
||||||
scaleFactor: 80,
|
scaleFactor: 80,
|
||||||
@@ -214,8 +229,27 @@ app.whenReady().then(() => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
|
if (!gotTheLock) {
|
||||||
|
app.quit();
|
||||||
|
} else {
|
||||||
|
app.on("second-instance", (event, commandLine, workingDirectory) => {
|
||||||
|
// 当运行第二个实例时,将会聚焦到mainWindow这个窗口
|
||||||
|
if (win) {
|
||||||
|
if (win.isMinimized()) win.restore();
|
||||||
|
win.focus();
|
||||||
|
win.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 阻止默认关闭
|
||||||
|
win.on("close", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
win.webContents.send("showCloseDialog");
|
||||||
|
});
|
||||||
|
});
|
||||||
app.on("window-all-closed", () => {
|
app.on("window-all-closed", () => {
|
||||||
if (process.platform !== "darwin") app.quit();
|
if (process.platform !== "darwin") app.quit();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "vite-electron",
|
"name": "vite-electron",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.3.41",
|
"version": "1.4.14",
|
||||||
"main": "dist-electron/main.js",
|
"main": "dist-electron/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "chcp 65001 && vite",
|
"dev": "chcp 65001 && vite",
|
||||||
"build": "node ./addVersion.js && vite build && electron-builder",
|
"build": "node ./addVersion.js && vite build && electron-builder",
|
||||||
|
"build:test": "vite build --mode test && electron-builder",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"build:win": "node ./addVersion.js && vite build && electron-builder --w"
|
"build:win": "node ./addVersion.js && vite build && electron-builder --w"
|
||||||
},
|
},
|
||||||
@@ -16,8 +17,10 @@
|
|||||||
"electron-pos-printer": "^1.3.6",
|
"electron-pos-printer": "^1.3.6",
|
||||||
"electron-pos-printer-vue": "^1.0.9",
|
"electron-pos-printer-vue": "^1.0.9",
|
||||||
"element-plus": "^2.4.3",
|
"element-plus": "^2.4.3",
|
||||||
|
"js-md5": "^0.8.3",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
|
"pinia-plugin-persistedstate": "^3.2.1",
|
||||||
"qrcode": "^1.5.3",
|
"qrcode": "^1.5.3",
|
||||||
"reconnecting-websocket": "^4.4.0",
|
"reconnecting-websocket": "^4.4.0",
|
||||||
"serialport": "^12.0.0",
|
"serialport": "^12.0.0",
|
||||||
|
|||||||
@@ -9,24 +9,25 @@
|
|||||||
|
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
width: 100%;
|
width: 100vw;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
padding: 2mm;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.print_view {
|
.print_view {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
padding-left: 12px;
|
||||||
}
|
}
|
||||||
.print_view .ewm {
|
.print_view .ewm {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
@@ -59,12 +60,12 @@ body {
|
|||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
}
|
}
|
||||||
.print_view .number_wrap .num {
|
.print_view .number_wrap .num {
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.print_view .number_wrap .info {
|
.print_view .number_wrap .info {
|
||||||
margin-left: 12px;
|
margin-left: 10px;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 2px;
|
||||||
}
|
}
|
||||||
.print_view .time {
|
.print_view .time {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|||||||
@@ -7,21 +7,22 @@
|
|||||||
}
|
}
|
||||||
html,
|
html,
|
||||||
body {
|
body {
|
||||||
width: 100%;
|
width: 100vw;
|
||||||
height: 100%;
|
height: 100vh;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
padding: 2mm;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
#app{
|
#app {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.print_view {
|
.print_view {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
padding-left: 12px;
|
||||||
.ewm {
|
.ewm {
|
||||||
$size: 50px;
|
$size: 50px;
|
||||||
width: $size;
|
width: $size;
|
||||||
@@ -46,12 +47,12 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
.num {
|
.num {
|
||||||
font-size: 18px;
|
font-size: 14px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.info {
|
.info {
|
||||||
margin-left: 12px;
|
margin-left: 10px;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.time {
|
.time {
|
||||||
|
|||||||
412
src/App.vue
412
src/App.vue
@@ -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,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import _ from 'lodash'
|
||||||
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, ElMessageBox } 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'
|
import { ipcRenderer } from 'electron';
|
||||||
import ReconnectingWebSocket from 'reconnecting-websocket';
|
const socket = useSocket();
|
||||||
|
|
||||||
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 +51,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", '/workrecord'];
|
||||||
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,294 +74,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
|
|
||||||
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
|
|
||||||
|
|
||||||
// 手动关闭后不在执行自动连接任务
|
|
||||||
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
|
|
||||||
|
|
||||||
// 手动关闭后不在执行自动连接任务
|
|
||||||
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
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@@ -402,23 +159,56 @@ async function getBarCode(e) {
|
|||||||
|
|
||||||
// console.log('code', code);
|
// console.log('code', code);
|
||||||
// 键入回车务必清空code值
|
// 键入回车务必清空code值
|
||||||
codeRef.value = ''
|
codeRef.value = "";
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取网络状态
|
||||||
|
const updateInfo = _.throttle(function () {
|
||||||
|
let isOnLine = navigator.onLine
|
||||||
|
// // 获取网络信息
|
||||||
|
// let info = navigator.connection
|
||||||
|
console.log(isOnLine);
|
||||||
|
// console.log(info);
|
||||||
|
if (store.userInfo && store.userInfo.shopId) {
|
||||||
|
if (isOnLine) {
|
||||||
|
console.log('有网了重新连接ws~');
|
||||||
|
socket.init();
|
||||||
|
} else {
|
||||||
|
socket.close();
|
||||||
|
console.log('网络连接失败~');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100, { leading: true, trailing: false })
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('keydown', (e) => {
|
document.addEventListener("keydown", (e) => {
|
||||||
getBarCode(e)
|
getBarCode(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 防止刷新页面长连接丢失
|
||||||
|
if (store.userInfo && store.userInfo.shopId) {
|
||||||
|
socket.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcRenderer.on('showCloseDialog', (event, arg) => {
|
||||||
|
ElMessageBox.confirm("确定要关闭软件吗?")
|
||||||
|
.then(() => {
|
||||||
|
ipcRenderer.send("quitHandler", "退出吧");
|
||||||
|
})
|
||||||
|
.catch(() => { });
|
||||||
})
|
})
|
||||||
// 监听网络在线状态
|
|
||||||
|
// listnerCloseDialog()
|
||||||
|
|
||||||
|
// // 监听网络在线状态
|
||||||
// window.addEventListener("onLine", updateInfo)
|
// window.addEventListener("onLine", updateInfo)
|
||||||
// // 监听网络离线
|
// // 监听网络离线
|
||||||
// window.addEventListener("offLine", updateInfo)
|
// window.addEventListener("offLine", updateInfo)
|
||||||
// // 监听网络信息变化
|
// 监听网络信息变化
|
||||||
// navigator.connection.addEventListener('change', updateInfo)
|
// navigator.connection.addEventListener('change', updateInfo)
|
||||||
})
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -119,3 +119,42 @@ export function douyinfulfilmentcertificatecancel(data) {
|
|||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 门店列表
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function douyinstorelist(data) {
|
||||||
|
return request_php({
|
||||||
|
method: "post",
|
||||||
|
url: "douyin/storelist",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定门店
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function douyinbindstore(data) {
|
||||||
|
return request_php({
|
||||||
|
method: "post",
|
||||||
|
url: "douyin/bindstore",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登出团购
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function tglogout(data) {
|
||||||
|
return request_php({
|
||||||
|
method: "post",
|
||||||
|
url: "user/logout",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
40
src/api/invoice.js
Normal file
40
src/api/invoice.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import request_kp from "@/utils/request_kp.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开票人列表
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function issuedby(data) {
|
||||||
|
return request_kp({
|
||||||
|
method: "post",
|
||||||
|
url: "szzpy/syjissuedby",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商家通过收银机提交开票信息
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function carsubinvoicing(data) {
|
||||||
|
return request_kp({
|
||||||
|
method: "post",
|
||||||
|
url: "store/carsubinvoicing",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印二维码
|
||||||
|
* @param {*} data
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function syjprintqrcode(data) {
|
||||||
|
return request_kp({
|
||||||
|
method: "post",
|
||||||
|
url: "store/syjprintqrcode",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -29,10 +29,10 @@ export function orderorderDetail(params) {
|
|||||||
* @param {*} params
|
* @param {*} params
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function payreturnOrder(data) {
|
export function payreturnOrder(data, pwd, isOnline) {
|
||||||
return request({
|
return request({
|
||||||
method: "post",
|
method: "post",
|
||||||
url: "pay/returnOrder",
|
url: `pay/returnOrder?pwd=${pwd}&isOnline=${isOnline}`,
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,3 +51,16 @@ export function handoverData(params) {
|
|||||||
params,
|
params,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印交班数据
|
||||||
|
* @param {*} params
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function handoverprint(params) {
|
||||||
|
return request({
|
||||||
|
method: "get",
|
||||||
|
url: "data/handoverprint",
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,7 +13,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="t1" v-else>
|
<div class="t1" v-else>
|
||||||
<span class="title">会员:</span>
|
<span class="title">会员:</span>
|
||||||
<span class="num">{{ props.userInfo.id && props.userInfo.telephone }}</span>
|
<span class="num">{{
|
||||||
|
props.userInfo.id && props.userInfo.telephone
|
||||||
|
}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="t2">
|
<div class="t2">
|
||||||
<span>已付:¥0.00</span>
|
<span>已付:¥0.00</span>
|
||||||
@@ -59,28 +61,38 @@
|
|||||||
</div>
|
</div>
|
||||||
<scanModal ref="scanModalRef" fast :amount="money" :selecttype="props.type" :orderId="props.userInfo.id"
|
<scanModal ref="scanModalRef" fast :amount="money" :selecttype="props.type" :orderId="props.userInfo.id"
|
||||||
@success="scanCodeSuccess" />
|
@success="scanCodeSuccess" />
|
||||||
|
<takeFoodCode ref="takeFoodCodeRef" title="支付密码" :type="2" input-type="password" placeholder="请输入支付密码"
|
||||||
|
@success="passwordSuccess" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { queryPayType, quickPay } from "@/api/pay";
|
import { queryPayType, quickPay } from "@/api/pay";
|
||||||
import { queryMembermember, createMembermember, membermemberScanPay, accountPaymember } from '@/api/member/index.js'
|
import {
|
||||||
|
queryMembermember,
|
||||||
|
createMembermember,
|
||||||
|
membermemberScanPay,
|
||||||
|
accountPaymember,
|
||||||
|
} from "@/api/member/index.js";
|
||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
import { clearNoNum } from "@/utils";
|
import { clearNoNum } from "@/utils";
|
||||||
|
import md5 from "js-md5";
|
||||||
|
|
||||||
import scanModal from "@/components/payCard/scanModal.vue";
|
import scanModal from "@/components/payCard/scanModal.vue";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
import takeFoodCode from "@/components/takeFoodCode.vue";
|
||||||
|
const takeFoodCodeRef = ref(null);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
type: {
|
type: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
default: 0 // 1快捷收银 2会员支付
|
default: 0, // 1快捷收银 2会员支付
|
||||||
},
|
},
|
||||||
userInfo: {
|
userInfo: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {}
|
default: {},
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
@@ -108,51 +120,68 @@ function payTypeChange(index, item) {
|
|||||||
if (money.value > 0) {
|
if (money.value > 0) {
|
||||||
scanModalRef.value.show();
|
scanModalRef.value.show();
|
||||||
} else {
|
} else {
|
||||||
ElMessage.error("请输入大于0的金额");
|
ElMessage.error("请输入金额");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
payActive.value = index;
|
payActive.value = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取支付密码
|
||||||
|
async function passwordSuccess(e) {
|
||||||
|
try {
|
||||||
|
payLoading.value = true;
|
||||||
|
await accountPaymember({
|
||||||
|
shopId: store.userInfo.shopId,
|
||||||
|
memberId: props.userInfo.id,
|
||||||
|
amount: money.value,
|
||||||
|
pwd: md5(e),
|
||||||
|
});
|
||||||
|
payLoading.value = false;
|
||||||
|
ElMessage.success("支付成功");
|
||||||
|
emit("paySuccess");
|
||||||
|
} catch (error) {
|
||||||
|
payLoading.value = false;
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 结算支付
|
// 结算支付
|
||||||
async function confirmOrder() {
|
async function confirmOrder() {
|
||||||
if (payLoading.value) return
|
if (payLoading.value) return;
|
||||||
try {
|
try {
|
||||||
if (payList.value[payActive.value].payType == "scanCode") {
|
if (payList.value[payActive.value].payType == "scanCode") {
|
||||||
if (money.value <= 0) {
|
if (money.value <= 0) {
|
||||||
ElMessage.error("请输入大于0的金额");
|
ElMessage.error("请输入金额");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
scanModalRef.value.show();
|
scanModalRef.value.show();
|
||||||
} else {
|
} else {
|
||||||
if (money.value <= 0) {
|
if (money.value <= 0) {
|
||||||
ElMessage.error("请输入大于0的金额");
|
ElMessage.error("请输入金额");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
payLoading.value = true;
|
|
||||||
switch (payList.value[payActive.value].payType) {
|
switch (payList.value[payActive.value].payType) {
|
||||||
case "cash": //现金
|
case "cash": //现金
|
||||||
if (props.type == 0) {
|
if (props.type == 0) {
|
||||||
|
payLoading.value = true;
|
||||||
await quickPay({
|
await quickPay({
|
||||||
amount: money.value,
|
amount: money.value,
|
||||||
authCode: "",
|
authCode: "",
|
||||||
payType: payList.value[payActive.value].payType,
|
payType: payList.value[payActive.value].payType,
|
||||||
});
|
});
|
||||||
|
payLoading.value = false;
|
||||||
|
ElMessage.success("支付成功");
|
||||||
|
emit("paySuccess");
|
||||||
} else {
|
} else {
|
||||||
await accountPaymember({
|
// 会员充值
|
||||||
shopId: store.userInfo.shopId,
|
takeFoodCodeRef.value.show();
|
||||||
memberId: props.userInfo.id,
|
// passwordSuccess()
|
||||||
amount: money.value
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
payLoading.value = false;
|
|
||||||
ElMessage.success("支付成功");
|
|
||||||
emit("paySuccess");
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
</el-icon>
|
</el-icon>
|
||||||
<el-text class="text">{{ item.label }}</el-text>
|
<el-text class="text">{{ item.label }}</el-text>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<div class="item" @click="workRef.show()">
|
||||||
|
<el-icon class="icon">
|
||||||
|
<component is="SwitchButton" />
|
||||||
|
</el-icon>
|
||||||
|
<el-text class="text">交班</el-text>
|
||||||
|
</div>
|
||||||
<div class="item more" @click="moreref.show()">
|
<div class="item more" @click="moreref.show()">
|
||||||
<el-icon class="icon">
|
<el-icon class="icon">
|
||||||
<Operation />
|
<Operation />
|
||||||
@@ -27,6 +33,8 @@
|
|||||||
<el-text class="text">更多</el-text>
|
<el-text class="text">更多</el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 交班 -->
|
||||||
|
<work ref="workRef" />
|
||||||
<!-- 更多 -->
|
<!-- 更多 -->
|
||||||
<more ref="moreref" @openCall="openCall"></more>
|
<more ref="moreref" @openCall="openCall"></more>
|
||||||
<!-- 叫号 -->
|
<!-- 叫号 -->
|
||||||
@@ -39,14 +47,15 @@ import { useRoute } from 'vue-router'
|
|||||||
import { useSocket } from '@/store/socket.js'
|
import { useSocket } from '@/store/socket.js'
|
||||||
import more from '@/components/more.vue'
|
import more from '@/components/more.vue'
|
||||||
import callNumber from './callNumber.vue'
|
import callNumber from './callNumber.vue'
|
||||||
|
import work from '@/views/work/index.vue'
|
||||||
const emits = defineEmits(['connectWsHandle'])
|
|
||||||
|
|
||||||
const socketStore = useSocket()
|
const socketStore = useSocket()
|
||||||
|
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const moreref = ref(null)
|
const moreref = ref(null)
|
||||||
const callNumberRef = ref(null)
|
const callNumberRef = ref(null)
|
||||||
|
const workRef = ref(null)
|
||||||
|
|
||||||
const menus = ref([
|
const menus = ref([
|
||||||
{
|
{
|
||||||
label: '收银',
|
label: '收银',
|
||||||
@@ -78,11 +87,11 @@ const menus = ref([
|
|||||||
path: '/member',
|
path: '/member',
|
||||||
icon: 'User'
|
icon: 'User'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: '交班',
|
// label: '交班',
|
||||||
path: '/work',
|
// path: '/work',
|
||||||
icon: 'SwitchButton'
|
// icon: 'SwitchButton'
|
||||||
}
|
// }
|
||||||
])
|
])
|
||||||
|
|
||||||
// 更新叫号记录
|
// 更新叫号记录
|
||||||
@@ -97,7 +106,7 @@ function openCall() {
|
|||||||
// 手动重新连接ws
|
// 手动重新连接ws
|
||||||
function connectWsHandle() {
|
function connectWsHandle() {
|
||||||
if (socketStore.online) return
|
if (socketStore.online) return
|
||||||
emits('connectWsHandle')
|
window.onload()
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
|||||||
207
src/components/lodop/LodopFuncs.js
Normal file
207
src/components/lodop/LodopFuncs.js
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
//==本JS是加载Lodop插件或Web打印服务CLodop/Lodop7的综合示例,可直接使用,建议理解后融入自己程序==
|
||||||
|
|
||||||
|
//用双端口加载主JS文件Lodop.js(或CLodopfuncs.js兼容老版本)以防其中某端口被占:
|
||||||
|
var MainJS = "CLodopfuncs.js",
|
||||||
|
URL_WS1 = "ws://localhost:8000/" + MainJS, //ws用8000/18000
|
||||||
|
URL_WS2 = "ws://localhost:18000/" + MainJS,
|
||||||
|
URL_HTTP1 = "http://localhost:8000/" + MainJS, //http用8000/18000
|
||||||
|
URL_HTTP2 = "http://localhost:18000/" + MainJS,
|
||||||
|
URL_HTTP3 = "https://localhost.lodop.net:8443/" + MainJS; //https用8000/8443
|
||||||
|
|
||||||
|
var CreatedOKLodopObject, CLodopIsLocal, LoadJsState;
|
||||||
|
|
||||||
|
//==判断是否需要CLodop(那些不支持插件的浏览器):==
|
||||||
|
function needCLodop() {
|
||||||
|
try {
|
||||||
|
var ua = navigator.userAgent;
|
||||||
|
if (ua.match(/Windows\sPhone/i) ||
|
||||||
|
ua.match(/iPhone|iPod|iPad/i) ||
|
||||||
|
ua.match(/Android/i) ||
|
||||||
|
ua.match(/Edge\D?\d+/i))
|
||||||
|
return true;
|
||||||
|
var verTrident = ua.match(/Trident\D?\d+/i);
|
||||||
|
var verIE = ua.match(/MSIE\D?\d+/i);
|
||||||
|
var verOPR = ua.match(/OPR\D?\d+/i);
|
||||||
|
var verFF = ua.match(/Firefox\D?\d+/i);
|
||||||
|
var x64 = ua.match(/x64/i);
|
||||||
|
if ((!verTrident) && (!verIE) && (x64)) return true;
|
||||||
|
else if (verFF) {
|
||||||
|
verFF = verFF[0].match(/\d+/);
|
||||||
|
if ((verFF[0] >= 41) || (x64)) return true;
|
||||||
|
} else if (verOPR) {
|
||||||
|
verOPR = verOPR[0].match(/\d+/);
|
||||||
|
if (verOPR[0] >= 32) return true;
|
||||||
|
} else if ((!verTrident) && (!verIE)) {
|
||||||
|
var verChrome = ua.match(/Chrome\D?\d+/i);
|
||||||
|
if (verChrome) {
|
||||||
|
verChrome = verChrome[0].match(/\d+/);
|
||||||
|
if (verChrome[0] >= 41) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (err) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==检查加载成功与否,如没成功则用http(s)再试==
|
||||||
|
//==低版本CLODOP6.561/Lodop7.043及前)用本方法==
|
||||||
|
function checkOrTryHttp() {
|
||||||
|
if (window.getCLodop) {
|
||||||
|
LoadJsState = "complete";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (LoadJsState == "loadingB" || LoadJsState == "complete") return;
|
||||||
|
LoadJsState = "loadingB";
|
||||||
|
var head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
|
||||||
|
var JS1 = document.createElement("script"),
|
||||||
|
JS2 = document.createElement("script"),
|
||||||
|
JS3 = document.createElement("script");
|
||||||
|
JS1.src = URL_HTTP1;
|
||||||
|
JS2.src = URL_HTTP2;
|
||||||
|
JS3.src = URL_HTTP3;
|
||||||
|
JS1.onload = JS2.onload = JS3.onload = JS2.onerror = JS3.onerror = function () {
|
||||||
|
LoadJsState = "complete";
|
||||||
|
}
|
||||||
|
JS1.onerror = function (e) {
|
||||||
|
if (window.location.protocol !== 'https:')
|
||||||
|
head.insertBefore(JS2, head.firstChild);
|
||||||
|
else
|
||||||
|
head.insertBefore(JS3, head.firstChild);
|
||||||
|
}
|
||||||
|
head.insertBefore(JS1, head.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==加载Lodop对象的主过程:==
|
||||||
|
(function loadCLodop() {
|
||||||
|
if (!needCLodop()) return;
|
||||||
|
CLodopIsLocal = !!((URL_WS1 + URL_WS2).match(/\/\/localho|\/\/127.0.0./i));
|
||||||
|
LoadJsState = "loadingA";
|
||||||
|
if (!window.WebSocket && window.MozWebSocket) window.WebSocket = window.MozWebSocket;
|
||||||
|
//ws方式速度快(小于200ms)且可避免CORS错误,但要求Lodop版本足够新:
|
||||||
|
try {
|
||||||
|
var WSK1 = new WebSocket(URL_WS1);
|
||||||
|
WSK1.onopen = function (e) {
|
||||||
|
setTimeout(checkOrTryHttp(), 200);
|
||||||
|
}
|
||||||
|
WSK1.onmessage = function (e) {
|
||||||
|
if (!window.getCLodop) eval(e.data);
|
||||||
|
}
|
||||||
|
WSK1.onerror = function (e) {
|
||||||
|
var WSK2 = new WebSocket(URL_WS2);
|
||||||
|
WSK2.onopen = function (e) {
|
||||||
|
setTimeout(checkOrTryHttp(), 200);
|
||||||
|
}
|
||||||
|
WSK2.onmessage = function (e) {
|
||||||
|
if (!window.getCLodop) eval(e.data);
|
||||||
|
}
|
||||||
|
WSK2.onerror = function (e) {
|
||||||
|
checkOrTryHttp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
checkOrTryHttp();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
//==获取LODOP对象主过程,判断是否安装、需否升级:==
|
||||||
|
function getLodop(oOBJECT, oEMBED) {
|
||||||
|
var strFontTag = "<br><font color='#FF00FF'>打印控件";
|
||||||
|
var strLodopInstall = strFontTag + "未安装!点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>执行安装</a>";
|
||||||
|
var strLodopUpdate = strFontTag + "需要升级!点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>执行升级</a>";
|
||||||
|
var strLodop64Install = strFontTag + "未安装!点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>执行安装</a>";
|
||||||
|
var strLodop64Update = strFontTag + "需要升级!点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>执行升级</a>";
|
||||||
|
var strCLodopInstallA =
|
||||||
|
"<br><font color='#FF00FF'>Web打印服务CLodop未安装启动,点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>下载执行安装</a>";
|
||||||
|
// var strCLodopInstallB = "<br>(若此前已安装过,可<a href='CLodop.protocol:setup' target='_self'>点这里直接再次启动</a>)";
|
||||||
|
var strCLodopUpdate =
|
||||||
|
"<br><font color='#FF00FF'>Web打印服务CLodop需升级!点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>执行升级</a>";
|
||||||
|
var strLodop7FontTag = "<br><font color='#FF00FF'>Web打印服务Lodop7";
|
||||||
|
var strLodop7HrefX86 = "点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip' target='_self'>下载安装</a>(下载后解压,点击lodop文件开始执行)";
|
||||||
|
var strLodop7HrefARM = "点击这里<a href='https://h5-invoice.sxczgkj.cn/invo/czg.zip'>下载安装</a>(下载后解压,点击lodop文件开始执行)";
|
||||||
|
var strLodop7Install_X86 = strLodop7FontTag + "未安装启动," + strLodop7HrefX86;
|
||||||
|
var strLodop7Install_ARM = strLodop7FontTag + "未安装启动," + strLodop7HrefARM;
|
||||||
|
var strLodop7Update_X86 = strLodop7FontTag + "需升级," + strLodop7HrefX86;
|
||||||
|
var strLodop7Update_ARM = strLodop7FontTag + "需升级," + strLodop7HrefARM;
|
||||||
|
var strInstallOK = ",成功后请刷新本页面或重启浏览器。</font>";
|
||||||
|
var LODOP;
|
||||||
|
try {
|
||||||
|
var isWinIE = (/MSIE/i.test(navigator.userAgent)) || (/Trident/i.test(navigator.userAgent));
|
||||||
|
var isWinIE64 = isWinIE && (/x64/i.test(navigator.userAgent));
|
||||||
|
var isLinuxX86 = (/Linux/i.test(navigator.platform)) && (/x86/i.test(navigator.platform));
|
||||||
|
var isLinuxARM = (/Linux/i.test(navigator.platform)) && (/aarch/i.test(navigator.platform));
|
||||||
|
|
||||||
|
if (needCLodop() || isLinuxX86 || isLinuxARM) {
|
||||||
|
try {
|
||||||
|
LODOP = window.getCLodop();
|
||||||
|
} catch (err) { }
|
||||||
|
if (!LODOP && LoadJsState !== "complete") {
|
||||||
|
if (!LoadJsState)
|
||||||
|
alert("未曾加载Lodop主JS文件,请先调用loadCLodop过程.");
|
||||||
|
else
|
||||||
|
alert("网页还没下载完毕,请稍等一下再操作.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var strAlertMessage;
|
||||||
|
if (!LODOP) {
|
||||||
|
if (isLinuxX86)
|
||||||
|
strAlertMessage = strLodop7Install_X86;
|
||||||
|
else if (isLinuxARM)
|
||||||
|
strAlertMessage = strLodop7Install_ARM;
|
||||||
|
else
|
||||||
|
strAlertMessage = strCLodopInstallA + (CLodopIsLocal ? strCLodopInstallB : "");
|
||||||
|
document.body.innerHTML = strAlertMessage + strInstallOK + document.body.innerHTML;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (isLinuxX86 && LODOP.CVERSION < "7.0.7.5")
|
||||||
|
strAlertMessage = strLodop7Update_X86;
|
||||||
|
else if (isLinuxARM && LODOP.CVERSION < "7.0.7.5")
|
||||||
|
strAlertMessage = strLodop7Update_ARM;
|
||||||
|
else if (CLODOP.CVERSION < "6.5.9.4")
|
||||||
|
strAlertMessage = strCLodopUpdate;
|
||||||
|
|
||||||
|
if (strAlertMessage)
|
||||||
|
document.body.innerHTML = strAlertMessage + strInstallOK + document.body.innerHTML;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//==如果页面有Lodop插件就直接使用,否则新建:==
|
||||||
|
if (oOBJECT || oEMBED) {
|
||||||
|
if (isWinIE)
|
||||||
|
LODOP = oOBJECT;
|
||||||
|
else
|
||||||
|
LODOP = oEMBED;
|
||||||
|
} else if (!CreatedOKLodopObject) {
|
||||||
|
LODOP = document.createElement("object");
|
||||||
|
LODOP.setAttribute("width", 0);
|
||||||
|
LODOP.setAttribute("height", 0);
|
||||||
|
LODOP.setAttribute("style", "position:absolute;left:0px;top:-100px;width:0px;height:0px;");
|
||||||
|
if (isWinIE)
|
||||||
|
LODOP.setAttribute("classid", "clsid:2105C259-1E0C-4534-8141-A753534CB4CA");
|
||||||
|
else
|
||||||
|
LODOP.setAttribute("type", "application/x-print-lodop");
|
||||||
|
document.documentElement.appendChild(LODOP);
|
||||||
|
CreatedOKLodopObject = LODOP;
|
||||||
|
} else
|
||||||
|
LODOP = CreatedOKLodopObject;
|
||||||
|
//==Lodop插件未安装时提示下载地址:==
|
||||||
|
if ((!LODOP) || (!LODOP.VERSION)) {
|
||||||
|
document.body.innerHTML = (isWinIE64 ? strLodop64Install : strLodopInstall) + strInstallOK + document
|
||||||
|
.body.innerHTML;
|
||||||
|
return LODOP;
|
||||||
|
}
|
||||||
|
if (LODOP.VERSION < "6.2.2.6") {
|
||||||
|
document.body.innerHTML = (isWinIE64 ? strLodop64Update : strLodopUpdate) + strInstallOK + document.body
|
||||||
|
.innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//===如下空白位置适合调用统一功能(如注册语句、语言选择等):=======================
|
||||||
|
// LODOP.SET_LICENSES("超掌柜独有!","DCFF409304DFCEB3E2C644BF96CD0720","","");
|
||||||
|
//===============================================================================
|
||||||
|
return LODOP;
|
||||||
|
} catch (err) {
|
||||||
|
alert("getLodop出错:" + err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default getLodop
|
||||||
113
src/components/lodop/index.vue
Normal file
113
src/components/lodop/index.vue
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-dialog v-model="centerDialogVisible" title="二维码" width="666" center>
|
||||||
|
<div class="dialog-footer" style="text-align: center">
|
||||||
|
<!-- <qrcode-vue :value="form.url" :size="200" /> -->
|
||||||
|
<div class="qrcodefooter">{{ props.form.article }}</div>
|
||||||
|
<div class="qrcodefooter">{{ props.form.type }}</div>
|
||||||
|
<div class="qrcodefooter">
|
||||||
|
<el-select v-model="rintermodel" placeholder="请选择打印机" @change="changerintermodel">
|
||||||
|
<el-option v-for="item in rintermodeldata" :key="item.id" :label="item.name" :value="item.id" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button @click="centerDialogVisible = false">关闭</el-button>
|
||||||
|
<el-button type="primary" :disabled="rintermodel ? false : true" @click="Printing"> 打印 </el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { dayjs } from 'element-plus'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import _lodash from 'lodash'
|
||||||
|
import getLodop from './LodopFuncs'
|
||||||
|
const props = defineProps({
|
||||||
|
form: Object,
|
||||||
|
})
|
||||||
|
|
||||||
|
const centerDialogVisible = ref(false) //显示隐藏
|
||||||
|
const rintermodeldata = ref([]) // 获取打印机列表
|
||||||
|
const rintermodel = ref() //打印机类型
|
||||||
|
// 确定打印机类型
|
||||||
|
const changerintermodel = (i: string) => {
|
||||||
|
rintermodel.value = i
|
||||||
|
}
|
||||||
|
const emit = defineEmits(['somethingDone'])
|
||||||
|
// 以下是打印
|
||||||
|
const Printing = () => {
|
||||||
|
let LODOP = getLodop()
|
||||||
|
centerDialogVisible.value = false
|
||||||
|
rintermodeldata.value = [] //清空
|
||||||
|
emit('somethingDone')
|
||||||
|
LODOP.PRINT_INIT('')
|
||||||
|
// 设置打印纸大小D
|
||||||
|
LODOP.SET_PRINT_PAGESIZE(3, 800, '', '')
|
||||||
|
// 二维码控制大小
|
||||||
|
LODOP.ADD_PRINT_BARCODE('', '30px', '150px', '150px', 'QRCode', props.form.url) //打印产品代码条码
|
||||||
|
LODOP.SET_PRINT_MODE('PRINT_PAGE_PERCENT', 'Full-Width ') //设置打印风格,这里是等宽打印
|
||||||
|
LODOP.SET_PRINTER_INDEX(rintermodel.value) //设置默认打印机(这里用的是打印机名称)
|
||||||
|
LODOP.SET_PRINT_STYLE("TextAlign", "Center");
|
||||||
|
// 文字内容
|
||||||
|
LODOP.ADD_PRINT_HTM(
|
||||||
|
'150px',
|
||||||
|
'5px',
|
||||||
|
'100%',
|
||||||
|
'100%',
|
||||||
|
`<div style="width: 100%;font-size: 12px; ">项目分类:${props.form.article}</div>
|
||||||
|
<div style="width: 100%;font-size: 12px; margin-top:6px;">发票类型:${props.form.type}</div>
|
||||||
|
<div style="width: 100%;font-size: 12px; margin-top:6px;">生成时间:${dayjs().format('YYYY-MM-DD HH:mm:ss')}</div>
|
||||||
|
<div style="width: 100%;font-size: 12px; margin-top:6px;">*二维码有效期30天,超过自动失效!</div>
|
||||||
|
<div style="width: 100%;font-size: 14px; margin-top: 15px;">您可以使用微信,扫码开票</div>`,
|
||||||
|
'150px',
|
||||||
|
'5px',
|
||||||
|
'100%',
|
||||||
|
'100%',
|
||||||
|
)
|
||||||
|
LODOP.SET_LICENSES('', 'DCFF409304DFCEB3E2C644BF96CD0720', '', '')
|
||||||
|
LODOP.PRINT()
|
||||||
|
}
|
||||||
|
const initialization = async () => {
|
||||||
|
rintermodeldata.value = [] //清空
|
||||||
|
let LODOP = getLodop()
|
||||||
|
setTimeout(() => {
|
||||||
|
if (LODOP == null) {
|
||||||
|
alert('请先安装打印控件')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (var i = 0; i < LODOP.GET_PRINTER_COUNT(); i++) {
|
||||||
|
let obj: {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
} = {
|
||||||
|
id: '',
|
||||||
|
name: '',
|
||||||
|
}
|
||||||
|
obj.id = LODOP.GET_PRINTER_NAME(i)
|
||||||
|
obj.name = LODOP.GET_PRINTER_NAME(i)
|
||||||
|
// console.log(obj)
|
||||||
|
rintermodeldata.value.push(obj)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
const centerDialogVisibleshow = () => {
|
||||||
|
centerDialogVisible.value = !centerDialogVisible.value
|
||||||
|
}
|
||||||
|
defineExpose({
|
||||||
|
Printing,
|
||||||
|
centerDialogVisibleshow,
|
||||||
|
initialization,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.dialog-footer {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.qrcodefooter {
|
||||||
|
text-align: center;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
32
src/components/lodop/invoicePrint.js
Normal file
32
src/components/lodop/invoicePrint.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import getLodop from "./LodopFuncs.js";
|
||||||
|
/**
|
||||||
|
* 打印订单发票
|
||||||
|
*/
|
||||||
|
export default (data) => {
|
||||||
|
console.log("data.deviceName===", data.deviceName);
|
||||||
|
let LODOP = getLodop();
|
||||||
|
LODOP.PRINT_INIT("打印小票");
|
||||||
|
// 设置打印纸大小D
|
||||||
|
LODOP.SET_PRINT_PAGESIZE(3, "58mm", 20, "");
|
||||||
|
// 二维码控制大小;
|
||||||
|
LODOP.ADD_PRINT_BARCODE("", "40px", "150px", "150px", "QRCode", data.url);
|
||||||
|
//设置默认打印机(这里用的是打印机名称)
|
||||||
|
LODOP.SET_PRINTER_INDEX(data.deviceName);
|
||||||
|
// 文字内容
|
||||||
|
let html = `
|
||||||
|
<div style="height: 100px;"></div>
|
||||||
|
<div style="width: 100%;font-size: 16px;display:flex;justify-content:center;">
|
||||||
|
请使用微信扫码下载发票,二维码有效期30天,超过自动失效
|
||||||
|
</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
LODOP.ADD_PRINT_HTM("9mm", "0mm", "RightMargin:0mm", 20, html);
|
||||||
|
LODOP.SET_LICENSES("", "DCFF409304DFCEB3E2C644BF96CD0720", "", "");
|
||||||
|
LODOP.PRINT();
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
161
src/components/lodop/lodopPrintWork.js
Normal file
161
src/components/lodop/lodopPrintWork.js
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
import getLodop from "./LodopFuncs.js";
|
||||||
|
/**
|
||||||
|
* 打印交班小票
|
||||||
|
*/
|
||||||
|
export default (data) => {
|
||||||
|
console.log("data.deviceName===", data.deviceName);
|
||||||
|
let LODOP = getLodop();
|
||||||
|
LODOP.PRINT_INIT("打印小票");
|
||||||
|
// 设置打印纸大小D
|
||||||
|
LODOP.SET_PRINT_PAGESIZE(3, "58mm", 20, "");
|
||||||
|
//设置默认打印机(这里用的是打印机名称)
|
||||||
|
LODOP.SET_PRINTER_INDEX(data.deviceName);
|
||||||
|
// 文字内容
|
||||||
|
let html = `
|
||||||
|
<div style="font-size: 30px;display:flex;justify-content:center;">
|
||||||
|
${data.merchantName}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
|
||||||
|
交班小票
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;margin-top:50px;">
|
||||||
|
当班时间:${data.startTime}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
交班时间:${data.endTime}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
收银员:${data.staff}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;margin-top: 4px;">
|
||||||
|
当班收入:${data.totalAmount}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let payInfos = "";
|
||||||
|
if (data.payInfos && data.payInfos.length) {
|
||||||
|
for (let item of data.payInfos) {
|
||||||
|
payInfos += `
|
||||||
|
<div style="font-size: 12px;padding-left:20px;">
|
||||||
|
${item.payType}:${item.amount}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let memberTitle = `
|
||||||
|
<div style="font-size: 12px;margin-top: 4px;">
|
||||||
|
会员数据
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let memberData = "";
|
||||||
|
if (data.memberData && data.memberData.length) {
|
||||||
|
for (let item of data.memberData) {
|
||||||
|
memberData += `
|
||||||
|
<div style="font-size: 12px;padding-left:20px;">
|
||||||
|
${item.deposit}:${item.amount}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let productCategoriesTabHead = `
|
||||||
|
<div style="font-size: 12px;margin-top: 4px;">分类数据</div>
|
||||||
|
<table class="table" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:50%;">名称</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">数量</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">总计</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let productCategoriesTableBody = "";
|
||||||
|
if (data.productCategories && data.productCategories.length) {
|
||||||
|
for (let item of data.productCategories) {
|
||||||
|
productCategoriesTableBody += `
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:50%;">
|
||||||
|
<div>${item.categoryName}</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">${item.num}</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">
|
||||||
|
${item.amount}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let tabHead = `
|
||||||
|
</table>
|
||||||
|
<div style="font-size: 12px;margin-top: 4px;">商品数据</div>
|
||||||
|
<table class="table" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:75%;">商品</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">数量</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let tableBody = "";
|
||||||
|
if (data.productInfos && data.productInfos.length) {
|
||||||
|
for (let item of data.productInfos) {
|
||||||
|
tableBody += `
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:75%;">
|
||||||
|
<div>${item.productName}</div>
|
||||||
|
</td>
|
||||||
|
<td style="font-size: 12px;width:25%;">${item.num}</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data.printShop) {
|
||||||
|
tabHead = "";
|
||||||
|
tableBody = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
let str = `
|
||||||
|
</table>
|
||||||
|
<div style="font-size: 12px;margin-top: 4px;">
|
||||||
|
<span>快捷收款金额:</span>
|
||||||
|
<span>${data.quickAmount}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
<span>退款金额:</span>
|
||||||
|
<span>${data.returnAmount}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
<span>总收入:</span>
|
||||||
|
<span>${data.totalAmount}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
<span>备用金:</span>
|
||||||
|
<span>${data.imprest}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
<span>应交金额:</span>
|
||||||
|
<span>${data.payable}</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 20px; font-size: 12px;">
|
||||||
|
<span>总订单数:</span>
|
||||||
|
<span>${data.orderNum}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 12px;">
|
||||||
|
打印时间:${data.printTime}
|
||||||
|
</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let lastHtml = `${html}${payInfos}${memberTitle}${memberData}${productCategoriesTabHead}${productCategoriesTableBody}${tabHead}${tableBody}${str}`;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
LODOP.ADD_PRINT_HTM("9mm", "0mm", "RightMargin:0mm", 20, lastHtml);
|
||||||
|
LODOP.SET_LICENSES("", "DCFF409304DFCEB3E2C644BF96CD0720", "", "");
|
||||||
|
LODOP.PRINT();
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
104
src/components/lodop/receiptPrint.js
Normal file
104
src/components/lodop/receiptPrint.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import getLodop from "./LodopFuncs.js";
|
||||||
|
/**
|
||||||
|
* 打印订单小票
|
||||||
|
*/
|
||||||
|
export default (data) => {
|
||||||
|
console.log(data);
|
||||||
|
console.log("data.deviceName===", data.deviceName);
|
||||||
|
let LODOP = getLodop();
|
||||||
|
LODOP.PRINT_INIT("打印小票");
|
||||||
|
// 设置打印纸大小D
|
||||||
|
LODOP.SET_PRINT_PAGESIZE(3, "58mm", 20, "");
|
||||||
|
//设置默认打印机(这里用的是打印机名称)
|
||||||
|
LODOP.SET_PRINTER_INDEX(data.deviceName);
|
||||||
|
// 文字内容
|
||||||
|
let t1 = 40;
|
||||||
|
let t2 = (100 - t1) / 3;
|
||||||
|
let html = `
|
||||||
|
<div style="font-size: 30px;display:flex;justify-content:center;">
|
||||||
|
${data.shop_name}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
|
||||||
|
${data.isBefore ? "预" : ""}结算单【${
|
||||||
|
data.orderInfo.masterId ? data.orderInfo.masterId : ""
|
||||||
|
}】
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:20px;">
|
||||||
|
${data.orderInfo.outNumber ? data.orderInfo.outNumber : ""}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 30px;font-size: 12px;">
|
||||||
|
订单号:${data.orderInfo && data.orderInfo.orderNo}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px;font-size: 12px;">
|
||||||
|
交易时间:${data.createdAt}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px;font-size: 12px;">
|
||||||
|
收银员:${data.loginAccount}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<table class="table" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:${t1}%;">品名</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">单价</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">数量</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">小计</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let table = "";
|
||||||
|
for (let item of data.carts) {
|
||||||
|
table += `
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:${t1}%;">
|
||||||
|
<div>${item.name}</div>
|
||||||
|
${
|
||||||
|
item.skuName
|
||||||
|
? `<div class="sku">规格:${item.skuName}</div>`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">${item.salePrice}</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">${item.number}</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">
|
||||||
|
${item.totalAmount}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let str = `
|
||||||
|
</table>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px; font-size: 22px;display:flex;justify-content: space-between;">
|
||||||
|
<span>应收</span>
|
||||||
|
<span>¥${data.amount}</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px; font-size: 12px;">
|
||||||
|
<span>余额:</span>
|
||||||
|
<span>0.00</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px; font-size: 16px;font-weight: bold;">备注:${data.remark}</div>
|
||||||
|
<div style="margin-top: 4px; font-size: 12px;">
|
||||||
|
打印时间:${data.printTime}
|
||||||
|
</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let lastHtml = `${html}${table}${str}`;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
LODOP.ADD_PRINT_HTM("9mm", "0mm", "RightMargin:0mm", 20, lastHtml);
|
||||||
|
LODOP.SET_LICENSES("", "DCFF409304DFCEB3E2C644BF96CD0720", "", "");
|
||||||
|
LODOP.PRINT();
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
96
src/components/lodop/refundPrint.js
Normal file
96
src/components/lodop/refundPrint.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import getLodop from "./LodopFuncs.js";
|
||||||
|
/**
|
||||||
|
* 打印退单小票
|
||||||
|
*/
|
||||||
|
export default (data) => {
|
||||||
|
let LODOP = getLodop();
|
||||||
|
LODOP.PRINT_INIT("打印小票");
|
||||||
|
// 设置打印纸大小D
|
||||||
|
LODOP.SET_PRINT_PAGESIZE(3, "58mm", 20, "");
|
||||||
|
//设置默认打印机(这里用的是打印机名称)
|
||||||
|
LODOP.SET_PRINTER_INDEX(data.deviceName);
|
||||||
|
// 文字内容
|
||||||
|
let t1 = 40;
|
||||||
|
let t2 = (100 - t1) / 3;
|
||||||
|
let html = `
|
||||||
|
<div style="font-size: 30px;display:flex;justify-content:center;">
|
||||||
|
${data.shop_name}
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 16px;display: flex; justify-content:center;margin-top:6px;">
|
||||||
|
退款单【${data.orderInfo.masterId ? data.orderInfo.masterId : ""}】
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 30px;font-size: 12px;">
|
||||||
|
订单号:${data.orderInfo && data.orderInfo.orderNo}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px;font-size: 12px;">
|
||||||
|
交易时间:${data.createdAt}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px;font-size: 12px;">
|
||||||
|
收银员:${data.loginAccount}
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<table class="table" style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:${t1}%;">品名</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">单价</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">数量</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">小计</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let table = "";
|
||||||
|
for (let item of data.carts) {
|
||||||
|
table += `
|
||||||
|
<tr>
|
||||||
|
<td style="font-size: 12px;width:${t1}%;">
|
||||||
|
<div>${item.name}</div>
|
||||||
|
${
|
||||||
|
item.skuName
|
||||||
|
? `<div class="sku">规格:${item.skuName}</div>`
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">${item.salePrice}</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">${item.number}</td>
|
||||||
|
<td style="font-size: 12px;width:${t2}%;">
|
||||||
|
${item.totalAmount}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
let str = `
|
||||||
|
</table>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px; font-size: 22px;display:flex;justify-content: space-between;">
|
||||||
|
<span>应退</span>
|
||||||
|
<span>¥${data.amount}</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px; font-size: 12px;">
|
||||||
|
<span>余额:</span>
|
||||||
|
<span>0.00</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 6px;margin-bottom: 6px;width: 100%">
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 4px; font-size: 12px;">
|
||||||
|
打印时间:${data.printTime}
|
||||||
|
</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
<div>.</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
let lastHtml = `${html}${table}${str}`;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
LODOP.ADD_PRINT_HTM("9mm", "0mm", "RightMargin:0mm", 20, lastHtml);
|
||||||
|
LODOP.SET_LICENSES("", "DCFF409304DFCEB3E2C644BF96CD0720", "", "");
|
||||||
|
LODOP.PRINT();
|
||||||
|
}, 800);
|
||||||
|
};
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="drawerbox">
|
<div class="drawerbox">
|
||||||
<el-drawer size="60%" :with-header="false" direction="rtl" v-model="dialogVisible" style="padding: 0;">
|
<el-drawer size="60%" :with-header="false" direction="rtl" v-model="dialogVisible" style="padding: 0">
|
||||||
<div class="drawerbox_box">
|
<div class="drawerbox_box">
|
||||||
<div class="drawerbox_bo_top">
|
<div class="drawerbox_bo_top">
|
||||||
<div class="drawerbox_bo_top_left">
|
<div class="drawerbox_bo_top_left">
|
||||||
<div class="drawerbox_bo_top_left_one">
|
<div class="drawerbox_bo_top_left_one" style="font-size: 24px;">
|
||||||
{{ store.userInfo.loginName }}
|
{{ store.userInfo.shopName }}
|
||||||
</div>
|
</div>
|
||||||
<div class="drawerbox_bo_top_left_tow" style="margin-top: 10px;">
|
<div class="drawerbox_bo_top_left_tow" style="margin-top: 10px">
|
||||||
收银员:{{ store.userInfo.userCode }} <span style="color: #666;">登录:{{
|
收银员:{{ store.userInfo.loginAccount }}
|
||||||
store.userInfo.loginTime }}</span>
|
</div>
|
||||||
</div>
|
<div>
|
||||||
</div>
|
<span style="color: #666">{{ dayjs(store.userInfo.loginTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||||||
<!-- <div class="drawerbox_bo_top_ring">
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <div class="drawerbox_bo_top_ring">
|
||||||
<div class="drawerbox_bo_top_ring_tb">
|
<div class="drawerbox_bo_top_ring_tb">
|
||||||
<el-icon style="margin: 0 auto;" size="20">
|
<el-icon style="margin: 0 auto;" size="20">
|
||||||
<FolderAdd />
|
<FolderAdd />
|
||||||
@@ -26,51 +28,43 @@
|
|||||||
<span>最小化</span>
|
<span>最小化</span>
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="drawerbox_bo_box">
|
<div class="drawerbox_bo_box">
|
||||||
<div style="padding:10px;color: #999; font-weight:bold;">系统</div>
|
<div style="padding: 10px; color: #999; font-weight: bold">系统</div>
|
||||||
<div class="drawerbox_bo_box_itemb_felx">
|
<div class="drawerbox_bo_box_itemb_felx">
|
||||||
<div class="drawerbox_bo_box_itembox">
|
<!-- <div class="drawerbox_bo_box_itembox">
|
||||||
<div class="drawerbox_bo_box_icon">
|
<div class="drawerbox_bo_box_icon">
|
||||||
<el-icon size="40">
|
<el-icon size="40">
|
||||||
<Setting />
|
<Setting />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="drawerbox_bo_box_icontext">
|
<div class="drawerbox_bo_box_icontext">设置</div>
|
||||||
设置
|
</div> -->
|
||||||
</div>
|
<div class="drawerbox_bo_box_itembox" @click="router.push({ name: 'device_list' })">
|
||||||
</div>
|
<div class="drawerbox_bo_box_icon">
|
||||||
<div class="drawerbox_bo_box_itembox" @click="openCallHandle">
|
<el-icon size="40">
|
||||||
<div class="drawerbox_bo_box_icon">
|
<TurnOff />
|
||||||
<el-icon size="40">
|
</el-icon>
|
||||||
<Bell />
|
</div>
|
||||||
</el-icon>
|
<div class="drawerbox_bo_box_icontext">设备管理</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="drawerbox_bo_box_icontext">
|
<div class="drawerbox_bo_box_itembox" @click="openCallHandle">
|
||||||
叫号
|
<div class="drawerbox_bo_box_icon">
|
||||||
</div>
|
<el-icon size="40">
|
||||||
</div>
|
<Bell />
|
||||||
<div class="drawerbox_bo_box_itembox" @click="router.push({ name: 'device_list' })">
|
</el-icon>
|
||||||
<div class="drawerbox_bo_box_icon">
|
</div>
|
||||||
<el-icon size="40">
|
<div class="drawerbox_bo_box_icontext">叫号</div>
|
||||||
<TurnOff />
|
</div>
|
||||||
</el-icon>
|
<div class="drawerbox_bo_box_itembox" @click="screenref.shows()">
|
||||||
</div>
|
<div class="drawerbox_bo_box_icon">
|
||||||
<div class="drawerbox_bo_box_icontext">
|
<el-icon size="40">
|
||||||
设备管理
|
<Lock />
|
||||||
</div>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="drawerbox_bo_box_itembox" @click="screenref.shows()">
|
<div class="drawerbox_bo_box_icontext">锁屏</div>
|
||||||
<div class="drawerbox_bo_box_icon">
|
</div>
|
||||||
<el-icon size="40">
|
<!-- <div class="drawerbox_bo_box_itembox" @click="to('webview', {
|
||||||
<Switch />
|
|
||||||
</el-icon>
|
|
||||||
</div>
|
|
||||||
<div class="drawerbox_bo_box_icontext">
|
|
||||||
锁屏
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- <div class="drawerbox_bo_box_itembox" @click="to('webview', {
|
|
||||||
url: 'https://cashiernewadmin.sxczgkj.cn/',
|
url: 'https://cashiernewadmin.sxczgkj.cn/',
|
||||||
title: '后台管理'
|
title: '后台管理'
|
||||||
})">
|
})">
|
||||||
@@ -83,155 +77,151 @@
|
|||||||
后台管理
|
后台管理
|
||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="boxabsolute">
|
<div class="boxabsolute">
|
||||||
<div>
|
<div>©银收客 v{{ packageData.version }}</div>
|
||||||
©银收客 v{{ packageData.version }}
|
<!-- <div>
|
||||||
</div>
|
|
||||||
<!-- <div>
|
|
||||||
有效期
|
有效期
|
||||||
</div> -->
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
</div>
|
</div>
|
||||||
<screen ref="screenref"></screen>
|
<screen ref="screenref"></screen>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from "vue";
|
||||||
import { useRouter } from 'vue-router'
|
import { dayjs } from 'element-plus'
|
||||||
import { useUser } from "@/store/user.js"
|
import { useRouter } from "vue-router";
|
||||||
import screen from '@/components/screen.vue'
|
import { useUser } from "@/store/user.js";
|
||||||
|
import screen from "@/components/screen.vue";
|
||||||
|
|
||||||
import packageData from '../../package.json'
|
import packageData from "../../package.json";
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
|
|
||||||
const emit = defineEmits(['openCall'])
|
const emit = defineEmits(["openCall"]);
|
||||||
|
|
||||||
const store = useUser()
|
const store = useUser();
|
||||||
const screenref = ref(null)
|
const screenref = ref(null);
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 打开叫号弹窗
|
// 打开叫号弹窗
|
||||||
function openCallHandle() {
|
function openCallHandle() {
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false;
|
||||||
emit('openCall')
|
emit("openCall");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳转
|
// 跳转
|
||||||
function to(pathName, data) {
|
function to(pathName, data) {
|
||||||
router.push({
|
router.push({
|
||||||
name: pathName,
|
name: pathName,
|
||||||
query: data
|
query: data,
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show
|
show,
|
||||||
})
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.drawerbox {
|
.drawerbox {
|
||||||
:deep(.el-drawer__body) {
|
:deep(.el-drawer__body) {
|
||||||
background: #1c1d1f !important;
|
background: #1c1d1f !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxabsolute {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%);
|
||||||
|
|
||||||
|
div {
|
||||||
|
color: #8c9196;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.boxabsolute {
|
div:nth-child(2) {
|
||||||
position: absolute;
|
margin-top: 10px;
|
||||||
bottom: 20px;
|
}
|
||||||
left: 50%;
|
}
|
||||||
transform: translate(-50%);
|
|
||||||
|
|
||||||
div {
|
.drawerbox_box {
|
||||||
color: #8c9196;
|
color: #fff;
|
||||||
|
|
||||||
|
.drawerbox_bo_top {
|
||||||
|
padding: 20px 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
|
||||||
|
.drawerbox_bo_top_left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawerbox_bo_top_ring {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.drawerbox_bo_top_ring_tb {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
width: 80px;
|
||||||
|
margin-top: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
div:nth-child(2) {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.drawerbox_box {
|
.drawerbox_bo_box {
|
||||||
color: #fff;
|
width: 100%;
|
||||||
|
|
||||||
.drawerbox_bo_top {
|
.drawerbox_bo_box_itemb_felx {
|
||||||
padding: 20px 0;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
|
||||||
|
.drawerbox_bo_box_itembox {
|
||||||
|
width: 20%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
.drawerbox_bo_box_icon {
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #2196f3;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: 1px solid #ccc;
|
justify-content: center;
|
||||||
|
}
|
||||||
.drawerbox_bo_top_left {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawerbox_bo_top_ring {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.drawerbox_bo_top_ring_tb {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 6px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
|
|
||||||
span {
|
|
||||||
width: 80px;
|
|
||||||
margin-top: 5px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawerbox_bo_box {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.drawerbox_bo_box_itemb_felx {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
|
|
||||||
.drawerbox_bo_box_itembox {
|
|
||||||
width: 20%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
margin-right: 20px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
|
|
||||||
.drawerbox_bo_box_icon {
|
|
||||||
border-radius: 6px;
|
|
||||||
background: #2196f3;
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawerbox_bo_box_icontext {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.drawerbox_bo_box_icontext {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog width="400" v-model="dialogVisible" style="padding: 0; " title="以锁屏" :close-on-click-modal="false" :show-close="false">
|
<el-dialog width="400" v-model="dialogVisible" style="padding: 0; " title="已锁屏" :close-on-click-modal="false" :show-close="false">
|
||||||
<div class="drawerbox_box">
|
<div class="drawerbox_box">
|
||||||
<el-input v-model="loginName" placeholder="请输入登录账号" />
|
<el-input v-model="loginName" placeholder="请输入登录账号" />
|
||||||
<el-button style="width: 100%; margin-top: 20px;" type="primary" @click="loginNameclick">确认</el-button>
|
<el-button style="width: 100%; margin-top: 20px;" type="primary" @click="loginNameclick">确认</el-button>
|
||||||
|
|||||||
@@ -1,74 +1,94 @@
|
|||||||
<!-- 取餐号组件 -->
|
<!-- 取餐号组件 -->
|
||||||
<template>
|
<template>
|
||||||
<el-dialog :title="props.title" width="600" v-model="dialogVisible" @open="opne">
|
<el-dialog :title="props.title" width="600" v-model="dialogVisible" @open="opne">
|
||||||
<el-input v-model="number" :placeholder="props.placeholder" readonly></el-input>
|
<el-input :type="props.inputType" v-model="number" :placeholder="props.placeholder" readonly></el-input>
|
||||||
<div class="keybord_wrap">
|
<div class="keybord_wrap">
|
||||||
<div v-for="item in 9" :key="item">
|
<div v-for="item in 9" :key="item">
|
||||||
<el-button plain type="info" style="width: 100%;" @click="inputHandle(item)">{{ item }}</el-button>
|
<el-button plain type="info" style="width: 100%" @click="inputHandle(item)">{{ item }}</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button plain type="info" disabled style="width: 100%;">.</el-button>
|
<el-button plain type="info" disabled style="width: 100%">.</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button plain type="info" style="width: 100%;" @click="inputHandle(0)">0</el-button>
|
<el-button plain type="info" style="width: 100%" @click="inputHandle(0)">0</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-button plain type="info" icon="CloseBold" style="width: 100%;" @click="delHandle"></el-button>
|
<el-button plain type="info" icon="CloseBold" style="width: 100%" @click="delHandle"></el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<el-button type="primary" style="width: 100%;" @click="confirmHandle">确认</el-button>
|
<el-button type="primary" style="width: 100%" @click="confirmHandle">确认</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from "vue";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
type: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 1, // 1取餐号 2密码
|
||||||
|
},
|
||||||
|
inputType: {
|
||||||
|
type: String,
|
||||||
|
default: 'text'
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '标题'
|
default: "标题",
|
||||||
},
|
},
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '提示'
|
default: "提示",
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
const dialogVisible = ref(false)
|
const dialogVisible = ref(false);
|
||||||
const number = ref('')
|
const number = ref("");
|
||||||
|
|
||||||
const emit = defineEmits(['success'])
|
const emit = defineEmits(["success"]);
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function opne() {
|
function opne() {
|
||||||
number.value = ''
|
number.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// 输入
|
// 输入
|
||||||
function inputHandle(n) {
|
function inputHandle(n) {
|
||||||
number.value += n
|
number.value += n;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除
|
// 删除
|
||||||
function delHandle() {
|
function delHandle() {
|
||||||
if (!number.value) return
|
if (!number.value) return;
|
||||||
number.value = number.value.substring(0, number.value.length - 1)
|
number.value = number.value.substring(0, number.value.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确认
|
// 确认
|
||||||
function confirmHandle() {
|
function confirmHandle() {
|
||||||
emit('success', number.value)
|
if (!number.value) return
|
||||||
dialogVisible.value = false
|
if (props.type == 2) {
|
||||||
|
if (number.value.length < 6) {
|
||||||
|
ElMessage.error('请输入正确的密码')
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
emit("success", number.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
emit("success", number.value);
|
||||||
|
dialogVisible.value = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
show
|
show,
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -88,4 +108,4 @@ defineExpose({
|
|||||||
height: 60px;
|
height: 60px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import { ipcRenderer } from "electron";
|
|||||||
import { bySubType } from "@/api/device";
|
import { bySubType } from "@/api/device";
|
||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
import dayjs from "dayjs";
|
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";
|
||||||
|
|
||||||
export const usePrint = defineStore({
|
export const usePrint = defineStore({
|
||||||
id: "print",
|
id: "print",
|
||||||
@@ -12,6 +16,8 @@ export const usePrint = defineStore({
|
|||||||
deviceLableList: [], // 添加的打印机
|
deviceLableList: [], // 添加的打印机
|
||||||
labelList: [], // 要打印的队列数据
|
labelList: [], // 要打印的队列数据
|
||||||
printTimer: null,
|
printTimer: null,
|
||||||
|
receiptList: [], // 小票队列数据
|
||||||
|
receiptTimer: null,
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
// 获取本地打印机和已添加的可以用打印机列表
|
// 获取本地打印机和已添加的可以用打印机列表
|
||||||
@@ -58,7 +64,10 @@ export const usePrint = defineStore({
|
|||||||
},
|
},
|
||||||
// 打印标签小票
|
// 打印标签小票
|
||||||
labelPrint(props) {
|
labelPrint(props) {
|
||||||
if (this.checkLocalPrint(this.deviceLableList[0].config.deviceName)) {
|
if (
|
||||||
|
this.deviceLableList.length &&
|
||||||
|
this.checkLocalPrint(this.deviceLableList[0].config.deviceName)
|
||||||
|
) {
|
||||||
let pids = this.deviceLableList[0].config.categoryList.map(
|
let pids = this.deviceLableList[0].config.categoryList.map(
|
||||||
(item) => item.id
|
(item) => item.id
|
||||||
);
|
);
|
||||||
@@ -94,6 +103,8 @@ export const usePrint = defineStore({
|
|||||||
});
|
});
|
||||||
// 执行打印操作
|
// 执行打印操作
|
||||||
this.startLabelPrint();
|
this.startLabelPrint();
|
||||||
|
} else {
|
||||||
|
console.log("没有标签打印机");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 开始打印标签数据
|
// 开始打印标签数据
|
||||||
@@ -114,5 +125,96 @@ export const usePrint = defineStore({
|
|||||||
}
|
}
|
||||||
}, 800);
|
}, 800);
|
||||||
},
|
},
|
||||||
|
// 添加小票打印对列表数据
|
||||||
|
pushReceiptData(props, isDevice = true) {
|
||||||
|
console.log("pushReceiptData===", props);
|
||||||
|
if (!isDevice) {
|
||||||
|
// 测试打印,无需校验本地打印机
|
||||||
|
const store = useUser();
|
||||||
|
props.shop_name = store.userInfo.shopName;
|
||||||
|
props.loginAccount = store.userInfo.loginAccount;
|
||||||
|
props.createdAt = dayjs(props.createdAt).format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
props.printTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
if (!props.orderInfo.masterId) {
|
||||||
|
props.orderInfo.masterId = props.orderInfo.tableName;
|
||||||
|
}
|
||||||
|
props.orderInfo.outNumber = props.outNumber;
|
||||||
|
|
||||||
|
this.receiptList.push(props);
|
||||||
|
this.startReceiptPrint();
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
this.deviceNoteList.length &&
|
||||||
|
this.checkLocalPrint(this.deviceNoteList[0].config.deviceName)
|
||||||
|
) {
|
||||||
|
const store = useUser();
|
||||||
|
props.deviceName = this.deviceNoteList[0].config.deviceName;
|
||||||
|
props.shop_name = store.userInfo.shopName;
|
||||||
|
props.loginAccount = store.userInfo.loginAccount;
|
||||||
|
props.createdAt = dayjs(props.createdAt).format(
|
||||||
|
"YYYY-MM-DD HH:mm:ss"
|
||||||
|
);
|
||||||
|
props.printTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
|
||||||
|
if (!props.orderInfo.masterId) {
|
||||||
|
props.orderInfo.masterId = props.orderInfo.tableName;
|
||||||
|
}
|
||||||
|
props.orderInfo.outNumber = props.outNumber;
|
||||||
|
|
||||||
|
this.receiptList.push(props);
|
||||||
|
this.startReceiptPrint();
|
||||||
|
} else {
|
||||||
|
console.log("订单小票:没有小票打印机");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 开始打印小票
|
||||||
|
startReceiptPrint() {
|
||||||
|
if (this.receiptTimer !== null) return;
|
||||||
|
this.receiptTimer = setInterval(() => {
|
||||||
|
if (!this.receiptList.length) {
|
||||||
|
clearInterval(this.receiptTimer);
|
||||||
|
this.receiptTimer = null;
|
||||||
|
} else {
|
||||||
|
receiptPrint(this.receiptList[0]);
|
||||||
|
this.receiptList.splice(0, 1);
|
||||||
|
}
|
||||||
|
}, 800);
|
||||||
|
},
|
||||||
|
// 打印交班小票
|
||||||
|
printWork(data) {
|
||||||
|
if (
|
||||||
|
this.deviceNoteList.length &&
|
||||||
|
this.checkLocalPrint(this.deviceNoteList[0].config.deviceName)
|
||||||
|
) {
|
||||||
|
data.deviceName = this.deviceNoteList[0].config.deviceName;
|
||||||
|
lodopPrintWork(data);
|
||||||
|
} else {
|
||||||
|
console.log("交班小票:没有小票打印机");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打印订单发票
|
||||||
|
printInvoice(data) {
|
||||||
|
if (
|
||||||
|
this.deviceNoteList.length &&
|
||||||
|
this.checkLocalPrint(this.deviceNoteList[0].config.deviceName)
|
||||||
|
) {
|
||||||
|
data.deviceName = this.deviceNoteList[0].config.deviceName;
|
||||||
|
invoicePrint(data);
|
||||||
|
} else {
|
||||||
|
console.log("订单发票:没有小票打印机");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 打印退单小票
|
||||||
|
printRefund(data) {
|
||||||
|
if (
|
||||||
|
this.deviceNoteList.length &&
|
||||||
|
this.checkLocalPrint(this.deviceNoteList[0].config.deviceName)
|
||||||
|
) {
|
||||||
|
data.deviceName = this.deviceNoteList[0].config.deviceName;
|
||||||
|
refundPrint(data);
|
||||||
|
} else {
|
||||||
|
console.log("退单小票:没有小票打印机");
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,144 @@
|
|||||||
|
import _ from "lodash";
|
||||||
|
import { dayjs } from "element-plus";
|
||||||
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 { ipcRenderer } from "electron";
|
||||||
|
|
||||||
export const useSocket = defineStore({
|
export const useSocket = defineStore({
|
||||||
id: "socket",
|
id: uuidv4(),
|
||||||
state: () => ({
|
state: () => ({
|
||||||
online: false,
|
online: false, // 在线状态
|
||||||
|
ws: null, // websocket实例
|
||||||
|
uuid: "", // 长连接唯一id
|
||||||
|
heartbeatTimer: null, // 心跳计时器
|
||||||
|
orderList: [],
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
// 登录
|
// 创建uuid
|
||||||
changeOnline(state) {
|
createUUID() {
|
||||||
this.online = state;
|
if (!useStorage.get("uuid")) {
|
||||||
|
ipcRenderer.send("getOSmacSync");
|
||||||
|
// useStorage.set("uuid", uuidv4());
|
||||||
|
ipcRenderer.on("getOSmacRes", (event, arg) => {
|
||||||
|
useStorage.set("uuid", arg);
|
||||||
|
this.uuid = useStorage.get("uuid");
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.uuid = useStorage.get("uuid");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 关闭ws
|
||||||
|
close() {
|
||||||
|
console.log("关闭ws");
|
||||||
|
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 }
|
||||||
|
),
|
||||||
|
// 初始化
|
||||||
|
init(wsUrl = import.meta.env.VITE_API_WSS) {
|
||||||
|
this.createUUID();
|
||||||
|
const store = useUser();
|
||||||
|
const printStore = usePrint();
|
||||||
|
|
||||||
|
printStore.init();
|
||||||
|
|
||||||
|
if (this.ws == null) {
|
||||||
|
console.log("创建新的ws连接");
|
||||||
|
|
||||||
|
const protocols = []; // 可选的子协议数组
|
||||||
|
const options = {
|
||||||
|
// 自动重新连接的选项(可选)
|
||||||
|
connectionTimeout: 1000,
|
||||||
|
maxRetries: 100,
|
||||||
|
};
|
||||||
|
this.ws = new ReconnectingWebSocket(wsUrl, protocols, options);
|
||||||
|
} else {
|
||||||
|
console.log("重新连接ws");
|
||||||
|
this.wsReconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ws.addEventListener("open", (event) => {
|
||||||
|
console.log("wss连接成功");
|
||||||
|
this.online = true;
|
||||||
|
// 清除心跳
|
||||||
|
this.clearHeartBeat();
|
||||||
|
|
||||||
|
console.log(this);
|
||||||
|
|
||||||
|
this.ws.send(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "connect",
|
||||||
|
shopId: store.userInfo.shopId,
|
||||||
|
clientId: this.uuid,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.startheartbeat();
|
||||||
|
});
|
||||||
|
|
||||||
|
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)
|
||||||
|
// 打印标签小票
|
||||||
|
if (!this.orderList.some((el) => el == data.orderInfo.orderNo)) {
|
||||||
|
// console.log("打印", data);
|
||||||
|
printStore.labelPrint(data);
|
||||||
|
printStore.pushReceiptData(data);
|
||||||
|
this.orderList.push(data.orderInfo.orderNo);
|
||||||
|
if (this.orderList.length > 30) {
|
||||||
|
this.orderList.splice(0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (data.type == "heartbeat") {
|
||||||
|
console.log("接收心跳");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -40,9 +40,10 @@ export function clearNoNum(obj) {
|
|||||||
* 保留小数n位,不进行四舍五入
|
* 保留小数n位,不进行四舍五入
|
||||||
* num你传递过来的数字,
|
* num你传递过来的数字,
|
||||||
* decimal你保留的几位,默认保留小数后两位
|
* decimal你保留的几位,默认保留小数后两位
|
||||||
|
* isInt 是否保留0
|
||||||
*/
|
*/
|
||||||
export function formatDecimal(num, decimal = 2) {
|
export function formatDecimal(num, decimal = 2, isInt = false) {
|
||||||
num = num.toString();
|
num = num.toFixed(3).toString();
|
||||||
const index = num.indexOf(".");
|
const index = num.indexOf(".");
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
num = num.substring(0, decimal + index + 1);
|
num = num.substring(0, decimal + index + 1);
|
||||||
@@ -50,5 +51,9 @@ export function formatDecimal(num, decimal = 2) {
|
|||||||
num = num.substring(0);
|
num = num.substring(0);
|
||||||
}
|
}
|
||||||
//截取后保留两位小数
|
//截取后保留两位小数
|
||||||
return parseFloat(num).toFixed(decimal);
|
if (isInt) {
|
||||||
|
return parseFloat(num);
|
||||||
|
} else {
|
||||||
|
return parseFloat(num).toFixed(decimal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
61
src/utils/request_kp.js
Normal file
61
src/utils/request_kp.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import useStorage from "@/utils/useStorage";
|
||||||
|
import router from "@/router";
|
||||||
|
|
||||||
|
const service = axios.create({
|
||||||
|
baseURL:
|
||||||
|
import.meta.env.MODE == "development"
|
||||||
|
? "/kp/"
|
||||||
|
: import.meta.env.VITE_API_KP_URL,
|
||||||
|
// withCredentials: true, // 跨域请求时发送 cookies
|
||||||
|
timeout: 5000, // 请求超时
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
service.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 在发送请求之前做些什么 token
|
||||||
|
config.headers["pctoken"] = useStorage.get("token");
|
||||||
|
config.headers["ispc"] = 1;
|
||||||
|
config.headers["loginName"] = useStorage.get("userInfo").loginName;
|
||||||
|
config.headers["clientType"] = "pc";
|
||||||
|
config.headers["shopId"] = useStorage.get("userInfo").shopId;
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
// 处理请求错误
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
service.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
// 对响应数据做点什么
|
||||||
|
if (+response.status === 200) {
|
||||||
|
if (+response.data.code == 1) {
|
||||||
|
return response.data.data;
|
||||||
|
} else {
|
||||||
|
// 响应错误
|
||||||
|
ElMessage.error(response.data.msg);
|
||||||
|
return Promise.reject(response.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
// 对响应错误做点什么
|
||||||
|
if (error.message.indexOf("timeout") != -1) {
|
||||||
|
ElMessage.error("网络超时");
|
||||||
|
} else if (error.message == "Network Error") {
|
||||||
|
ElMessage.error("网络连接错误");
|
||||||
|
} else {
|
||||||
|
console.log(error);
|
||||||
|
if (error.response.data) ElMessage.error(error.response.statusText);
|
||||||
|
else ElMessage.error("接口路径找不到");
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default service;
|
||||||
@@ -7,7 +7,7 @@ const service = axios.create({
|
|||||||
baseURL:
|
baseURL:
|
||||||
import.meta.env.MODE == "development"
|
import.meta.env.MODE == "development"
|
||||||
? "/php/"
|
? "/php/"
|
||||||
: import.meta.env.VITE_API_URL,
|
: import.meta.env.VITE_API_PHP_URL,
|
||||||
// withCredentials: true, // 跨域请求时发送 cookies
|
// withCredentials: true, // 跨域请求时发送 cookies
|
||||||
timeout: 5000, // 请求超时
|
timeout: 5000, // 请求超时
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -61,11 +61,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="menu_wrap">
|
<div class="menu_wrap">
|
||||||
<div class="print_view">
|
<div class="print_view">
|
||||||
<div class="title t1">溜溜</div>
|
<div class="title t1">{{ printData.shop_name }}</div>
|
||||||
<div class="title t2">结算单【#002】</div>
|
<div class="title t2">预结算单【{{ printData.orderInfo.masterId }}】</div>
|
||||||
<div class="row">订单号:202404021023542223445</div>
|
<div class="row">订单号:{{ printData.orderInfo.orderNo }}</div>
|
||||||
<div class="row">交易时间:2024-04-02 10:15</div>
|
<div class="row">交易时间:{{ printData.createdAt }}</div>
|
||||||
<div class="row">收银员:【POS-1】1</div>
|
<div class="row">收银员:{{ printData.loginAccount }}</div>
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
@@ -74,51 +74,31 @@
|
|||||||
<td>数量</td>
|
<td>数量</td>
|
||||||
<td>小计</td>
|
<td>小计</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr v-for="(item, index) in printData.carts" :key="index">
|
||||||
<td>
|
<td>
|
||||||
<div>娃哈哈矿泉水</div>
|
<div>{{ item.name }}</div>
|
||||||
<div class="sku">500ml</div>
|
<div class="sku">{{ item.skuName }}</div>
|
||||||
</td>
|
</td>
|
||||||
<td>1.0</td>
|
<td>{{ item.salePrice }}</td>
|
||||||
<td>10</td>
|
<td>{{ item.number }}</td>
|
||||||
<td>10</td>
|
<td>{{ item.totalAmount }}</td>
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div>柠檬奶茶</div>
|
|
||||||
<div class="sku">加冰、加珍珠</div>
|
|
||||||
</td>
|
|
||||||
<td>10.0</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>20</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<div class="row between">
|
<div class="row between">
|
||||||
<span>合计:</span>
|
<span>合计:</span>
|
||||||
<span>30.00</span>
|
<span>{{ printData.amount }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="row between">
|
<div class="row between">
|
||||||
<span>合计:</span>
|
<span>余额:</span>
|
||||||
<span>30.00</span>
|
|
||||||
</div>
|
|
||||||
<div class="row between">
|
|
||||||
<span>原价:20.00,节省了0</span>
|
|
||||||
</div>
|
|
||||||
<div class="row between">
|
|
||||||
<span>积分:</span>
|
|
||||||
<span>0</span>
|
|
||||||
</div>
|
|
||||||
<div class="row between">
|
|
||||||
<span>余额:</span>
|
|
||||||
<span>0.00</span>
|
<span>0.00</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="line"></div>
|
<div class="line"></div>
|
||||||
<div class="row">备注:</div>
|
<div class="row">备注:{{ printData.remark }}</div>
|
||||||
<div class="row">打印时间:2024-04-02 10:15</div>
|
<div class="row">打印时间:{{ printData.printTime }}</div>
|
||||||
<div class="btn_wrap">
|
<div class="btn_wrap">
|
||||||
<div class="btn">
|
<div class="btn">
|
||||||
<el-button plain style="width: 100%" @click="printHandle">
|
<el-button plain style="width: 100%" :loading="printDataLoading" @click="printHandle">
|
||||||
打印测试小票
|
打印测试小票
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -137,12 +117,15 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, reactive, ref } from "vue";
|
||||||
import { useRouter, useRoute } from "vue-router";
|
import { useRouter, useRoute } from "vue-router";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import { tbPrintMachinePost, tbPrintMachineDetail } from "@/api/device";
|
import { tbPrintMachinePost, tbPrintMachineDetail } from "@/api/device";
|
||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
import { Loading } from "element-plus/es/components/loading/src/service";
|
import { Loading } from "element-plus/es/components/loading/src/service";
|
||||||
|
import { usePrint } from "@/store/print.js";
|
||||||
|
|
||||||
|
const printStore = usePrint();
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -172,6 +155,40 @@ const form = ref({
|
|||||||
shopId: store.userInfo.shopId,
|
shopId: store.userInfo.shopId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const printDataLoading = ref(false)
|
||||||
|
const printData = reactive({
|
||||||
|
shop_name: store.userInfo.shopName,
|
||||||
|
loginAccount: store.userInfo.loginAccount,
|
||||||
|
isBefore: true,
|
||||||
|
carts: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: '【测试】娃哈哈矿泉水',
|
||||||
|
skuName: '500ml',
|
||||||
|
salePrice: '1.0',
|
||||||
|
number: '10',
|
||||||
|
totalAmount: '10'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: '【测试】柠檬奶茶',
|
||||||
|
skuName: '加冰、加珍珠',
|
||||||
|
salePrice: '10',
|
||||||
|
number: '2',
|
||||||
|
totalAmount: '20'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
amount: '30.00',
|
||||||
|
remark: '给我多放点辣椒,谢谢老板',
|
||||||
|
orderInfo: {
|
||||||
|
masterId: '#002',
|
||||||
|
orderNo: '202404021023542223445'
|
||||||
|
},
|
||||||
|
deviceName: '',
|
||||||
|
createdAt: '2024-04-02 10:15',
|
||||||
|
printTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
|
||||||
|
});
|
||||||
|
|
||||||
// 获取打印机列表
|
// 获取打印机列表
|
||||||
function getPrintList() {
|
function getPrintList() {
|
||||||
ipcRenderer.send("getPrintList");
|
ipcRenderer.send("getPrintList");
|
||||||
@@ -186,43 +203,13 @@ function printHandle() {
|
|||||||
ElMessage.warning("请选择打印设备");
|
ElMessage.warning("请选择打印设备");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printDataLoading.value = true
|
||||||
// ipcRenderer.send(
|
printData.deviceName = form.value.config.deviceName
|
||||||
// "printStart",
|
printData.printTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||||
// JSON.stringify({ deviceName: form.value.config.deviceName })
|
printStore.pushReceiptData(printData, false)
|
||||||
// );
|
setTimeout(() => {
|
||||||
|
printDataLoading.value = false
|
||||||
const data = {
|
}, 1500)
|
||||||
shop_name: '溜溜',
|
|
||||||
carts: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: '娃哈哈矿泉水',
|
|
||||||
skuName: '500ml',
|
|
||||||
salePrice: '1.0',
|
|
||||||
number: '10',
|
|
||||||
totalAmount: '10'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: '柠檬奶茶',
|
|
||||||
skuName: '加冰、加珍珠',
|
|
||||||
salePrice: '10',
|
|
||||||
number: '2',
|
|
||||||
totalAmount: '20'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
amount: '30.00',
|
|
||||||
remark: '',
|
|
||||||
orderInfo: {
|
|
||||||
masterId: '#002',
|
|
||||||
orderNo: '202404021023542223445'
|
|
||||||
},
|
|
||||||
deviceName: form.value.config.deviceName,
|
|
||||||
createdAt: '2024-04-02 10:15',
|
|
||||||
printTime: '2024-04-02 10:15',
|
|
||||||
};
|
|
||||||
ipcRenderer.send("printerInfoSync", JSON.stringify(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 提交打印机
|
// 提交打印机
|
||||||
@@ -236,6 +223,9 @@ async function submitHandle() {
|
|||||||
await tbPrintMachinePost(form.value, form.value.id ? "put" : "post");
|
await tbPrintMachinePost(form.value, form.value.id ? "put" : "post");
|
||||||
Loading.value = false;
|
Loading.value = false;
|
||||||
ElMessage.success(form.value.id ? "编辑成功" : "添加成功");
|
ElMessage.success(form.value.id ? "编辑成功" : "添加成功");
|
||||||
|
|
||||||
|
printStore.init();
|
||||||
|
|
||||||
router.back();
|
router.back();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ import { useUser } from "@/store/user.js";
|
|||||||
import { Loading } from "element-plus/es/components/loading/src/service";
|
import { Loading } from "element-plus/es/components/loading/src/service";
|
||||||
import classify from "@/components/classify/index.vue";
|
import classify from "@/components/classify/index.vue";
|
||||||
import QRCode from 'qrcode'
|
import QRCode from 'qrcode'
|
||||||
|
import { usePrint } from "@/store/print.js";
|
||||||
|
|
||||||
|
const printStore = usePrint();
|
||||||
|
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
@@ -176,6 +179,7 @@ const printHandle = _.throttle(function () {
|
|||||||
ElMessage.error("请选择打印设备");
|
ElMessage.error("请选择打印设备");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
printData.value.deviceName = form.value.config.deviceName
|
||||||
ipcRenderer.send(
|
ipcRenderer.send(
|
||||||
"printerTagSync",
|
"printerTagSync",
|
||||||
JSON.stringify(printData.value)
|
JSON.stringify(printData.value)
|
||||||
@@ -193,6 +197,7 @@ async function submitHandle() {
|
|||||||
await tbPrintMachinePost(form.value, form.value.id ? "put" : "post");
|
await tbPrintMachinePost(form.value, form.value.id ? "put" : "post");
|
||||||
Loading.value = false;
|
Loading.value = false;
|
||||||
ElMessage.success(form.value.id ? "编辑成功" : "添加成功");
|
ElMessage.success(form.value.id ? "编辑成功" : "添加成功");
|
||||||
|
printStore.init();
|
||||||
router.back();
|
router.back();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="device_container">
|
<div class="device_container">
|
||||||
<div class="header" @click="router.back()">
|
<div class="header" @click="router.back()">
|
||||||
<el-icon
|
<el-icon style="position: relative; top: 2px; margin-right: 4px" size="22">
|
||||||
style="position: relative; top: 2px; margin-right: 4px"
|
|
||||||
size="22"
|
|
||||||
>
|
|
||||||
<ArrowLeft />
|
<ArrowLeft />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<el-text>设备管理</el-text>
|
<el-text>设备管理</el-text>
|
||||||
@@ -16,10 +13,7 @@
|
|||||||
<div class="item" v-for="item in list" :key="item.id">
|
<div class="item" v-for="item in list" :key="item.id">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<div class="icon">
|
<div class="icon">
|
||||||
<el-image
|
<el-image :src="icons[item.subType]" style="width: 40px; height: 40px"></el-image>
|
||||||
:src="icons[item.subType]"
|
|
||||||
style="width: 40px; height: 40px"
|
|
||||||
></el-image>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">{{ item.name }}</div>
|
<div class="name">{{ item.name }}</div>
|
||||||
@@ -28,27 +22,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<div class="switch">
|
<div class="switch">
|
||||||
<el-switch
|
<el-switch v-model="item.status" inline-prompt active-text="开" inactive-text="关" :active-value="1"
|
||||||
v-model="item.status"
|
:inactive-value="0" width="90" @change="statusChange($event, item)" />
|
||||||
inline-prompt
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
:active-value="1"
|
|
||||||
:inactive-value="0"
|
|
||||||
width="90"
|
|
||||||
@change="statusChange($event, item)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="editor">
|
<div class="editor">
|
||||||
<el-text
|
<el-text type="primary" @click="
|
||||||
type="primary"
|
router.push({
|
||||||
@click="
|
name: deviceRoute[item.subType],
|
||||||
router.push({
|
query: { id: item.id },
|
||||||
name: deviceRoute[item.subType],
|
})
|
||||||
query: { id: item.id },
|
">
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
编辑
|
编辑
|
||||||
</el-text>
|
</el-text>
|
||||||
<el-text type="primary" @click="showDelete(item)">删除</el-text>
|
<el-text type="primary" @click="showDelete(item)">删除</el-text>
|
||||||
@@ -89,10 +72,7 @@
|
|||||||
<div class="menu_wrap">
|
<div class="menu_wrap">
|
||||||
<div class="row" @click="router.push({ name: 'add_device' })">
|
<div class="row" @click="router.push({ name: 'add_device' })">
|
||||||
<div class="icon" style="background-color: var(--primary-color)">
|
<div class="icon" style="background-color: var(--primary-color)">
|
||||||
<el-image
|
<el-image :src="icons.cash" style="width: 36px; height: 36px"></el-image>
|
||||||
:src="icons.cash"
|
|
||||||
style="width: 36px; height: 36px"
|
|
||||||
></el-image>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">添加小票打印机</div>
|
<div class="name">添加小票打印机</div>
|
||||||
@@ -101,28 +81,22 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row" @click="router.push({ name: 'add_label' })">
|
<div class="row" @click="router.push({ name: 'add_label' })">
|
||||||
<div class="icon" style="background-color: #79c3d5">
|
<div class="icon" style="background-color: #79c3d5">
|
||||||
<el-image
|
<el-image :src="icons.label" style="width: 38px; height: 38px"></el-image>
|
||||||
:src="icons.label"
|
|
||||||
style="width: 38px; height: 38px"
|
|
||||||
></el-image>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">添加标签打印机</div>
|
<div class="name">添加标签打印机</div>
|
||||||
<div class="intro">用来打印商品标签的打印机。</div>
|
<div class="intro">用来打印商品标签的打印机。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<!-- <div class="row">
|
||||||
<div class="icon" style="background-color: #8fc783">
|
<div class="icon" style="background-color: #8fc783">
|
||||||
<el-image
|
<el-image :src="icons.kitchen" style="width: 44px; height: 44px"></el-image>
|
||||||
:src="icons.kitchen"
|
|
||||||
style="width: 44px; height: 44px"
|
|
||||||
></el-image>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="name">添加出品打印机</div>
|
<div class="name">添加出品打印机</div>
|
||||||
<div class="intro">用来打印商品至厨房或出品台的打印机。</div>
|
<div class="intro">用来打印商品至厨房或出品台的打印机。</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -131,11 +105,7 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button
|
<el-button type="primary" :loading="delLoading" @click="tbPrintMachineDeleteAjax">
|
||||||
type="primary"
|
|
||||||
:loading="delLoading"
|
|
||||||
@click="tbPrintMachineDeleteAjax"
|
|
||||||
>
|
|
||||||
确定
|
确定
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@@ -154,6 +124,9 @@ import { useRouter } from "vue-router";
|
|||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import icons from "./icons";
|
import icons from "./icons";
|
||||||
|
import { usePrint } from "@/store/print.js";
|
||||||
|
|
||||||
|
const printStore = usePrint();
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -168,10 +141,10 @@ const deviceRoute = ref({
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function statusChange(e, item) {
|
async function statusChange(e, item) {
|
||||||
console.log(e, item);
|
|
||||||
try {
|
try {
|
||||||
await tbPrintMachinePost(item, "put");
|
await tbPrintMachinePost(item, "put");
|
||||||
tbPrintMachineGetAjax();
|
tbPrintMachineGetAjax();
|
||||||
|
printStore.init();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -192,6 +165,7 @@ async function tbPrintMachineDeleteAjax() {
|
|||||||
dialogVisible.value = false;
|
dialogVisible.value = false;
|
||||||
ElMessage.success("删除成功");
|
ElMessage.success("删除成功");
|
||||||
tbPrintMachineGetAjax();
|
tbPrintMachineGetAjax();
|
||||||
|
printStore.init();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -220,9 +194,11 @@ onMounted(() => {
|
|||||||
.dialog_content {
|
.dialog_content {
|
||||||
font-size: var(--el-font-size-base);
|
font-size: var(--el-font-size-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-footer {
|
.dialog-footer {
|
||||||
padding: 0 var(--el-font-size-base) var(--el-font-size-base);
|
padding: 0 var(--el-font-size-base) var(--el-font-size-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
.device_container {
|
.device_container {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
|||||||
104
src/views/group_buy/components/bindShop.vue
Normal file
104
src/views/group_buy/components/bindShop.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="绑定门店" v-model="showDialog" width="80%">
|
||||||
|
<div class="dialog">
|
||||||
|
<div class="tips">注意:门店绑定后无法更改,请谨慎选择</div>
|
||||||
|
<el-table :data="tableData.list" height="240px" border v-loading="tableData.loading">
|
||||||
|
<el-table-column label="门店名称" prop="poi_name"></el-table-column>
|
||||||
|
<el-table-column label="门店地址" prop="address"></el-table-column>
|
||||||
|
<el-table-column label="操作" width="120px">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button type="primary" size="small"
|
||||||
|
@click="bindShopHandle(scope.row.poi_id)">选择门店</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="pagination">
|
||||||
|
<el-pagination @current-change="paginationChange" :current-page="tableData.page"
|
||||||
|
:page-size="tableData.size" layout="total, prev, pager, next, jumper" :total="tableData.total"
|
||||||
|
background>
|
||||||
|
</el-pagination>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
|
import { douyinstorelist, douyinbindstore } from '@/api/group.js'
|
||||||
|
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
|
||||||
|
const showDialog = ref(false)
|
||||||
|
|
||||||
|
const tableData = reactive({
|
||||||
|
page: 1,
|
||||||
|
size: 10,
|
||||||
|
total: 0,
|
||||||
|
loading: false,
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 绑定门店
|
||||||
|
async function bindShopHandle(poi_id) {
|
||||||
|
try {
|
||||||
|
await douyinbindstore({
|
||||||
|
poi_id: poi_id
|
||||||
|
})
|
||||||
|
showDialog.value = false
|
||||||
|
ElMessage.success('绑定成功')
|
||||||
|
emits('success')
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页变化
|
||||||
|
function paginationChange(e) {
|
||||||
|
tableData.page = e
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取门店列表
|
||||||
|
async function getTableData() {
|
||||||
|
try {
|
||||||
|
tableData.loading = true
|
||||||
|
const { list, count } = await douyinstorelist({
|
||||||
|
page: tableData.page,
|
||||||
|
size: tableData.size
|
||||||
|
})
|
||||||
|
tableData.loading = false
|
||||||
|
tableData.list = list
|
||||||
|
tableData.total = count
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示
|
||||||
|
function show() {
|
||||||
|
showDialog.value = true;
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.tips {
|
||||||
|
color: var(--el-color-danger);
|
||||||
|
padding-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination {
|
||||||
|
display: flex;
|
||||||
|
padding: 0 14px;
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog {
|
||||||
|
padding: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset">
|
<el-dialog :title="`核销${props.title}团购券`" width="600" v-model="dialogVisible" @open="reset" @close="close">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<el-image :src="icon" style="width: 60px; height: 60px"></el-image>
|
<el-image :src="icon" style="width: 60px; height: 60px"></el-image>
|
||||||
@@ -79,8 +79,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-table ref="douyin_table" :data="groupDetail.goods" border v-if="props.type == 2"
|
<el-table ref="douyin_table" :data="groupDetail.goods" border v-if="props.type == 2">
|
||||||
@selection-change="douyinSelectionChange">
|
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column label="名称" prop="title"></el-table-column>
|
<el-table-column label="名称" prop="title"></el-table-column>
|
||||||
<el-table-column label="价格" prop="amount"></el-table-column>
|
<el-table-column label="价格" prop="amount"></el-table-column>
|
||||||
@@ -93,6 +92,7 @@
|
|||||||
@click="groupOrdergroupScanHandle">确认核销</el-button>
|
@click="groupOrdergroupScanHandle">确认核销</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<BindShop ref="BindShopRef" @success="submitHandle()" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -102,6 +102,8 @@ import { ref } from "vue";
|
|||||||
import icon from "@/assets/icon_scan.png";
|
import icon from "@/assets/icon_scan.png";
|
||||||
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group'
|
import { groupOrderorderInfo, groupOrdergroupScan, douyinfulfilmentcertificateprepare, douyincertificateprepare } from '@/api/group'
|
||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
|
import BindShop from './bindShop.vue'
|
||||||
|
const BindShopRef = ref(null)
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
import {
|
import {
|
||||||
queryMembermember,
|
queryMembermember,
|
||||||
@@ -110,6 +112,10 @@ import {
|
|||||||
accountPaymember,
|
accountPaymember,
|
||||||
} from "@/api/member/index.js";
|
} from "@/api/member/index.js";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
import { useGlobal } from '@/store/global.js'
|
||||||
|
const global = useGlobal()
|
||||||
|
|
||||||
const emits = defineEmits(["success"]);
|
const emits = defineEmits(["success"]);
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -151,13 +157,20 @@ async function groupOrdergroupScanHandle() {
|
|||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
groupDetailLoading.value = true
|
let encrypted_codes = douyin_table.value.getSelectionRows()
|
||||||
let encrypted_codes = groupDetail.value.goods.map(item => item.encrypted_code)
|
if (encrypted_codes.length) {
|
||||||
const res = await douyincertificateprepare({
|
groupDetailLoading.value = true
|
||||||
verify_token: groupDetail.value.verify_token,
|
let arr = encrypted_codes.map(item => item.encrypted_code)
|
||||||
encrypted_codes: encrypted_codes.join(','),
|
console.log(encrypted_codes);
|
||||||
id: groupDetail.value.id
|
const res = await douyincertificateprepare({
|
||||||
})
|
verify_token: groupDetail.value.verify_token,
|
||||||
|
encrypted_codes: arr.join(','),
|
||||||
|
id: groupDetail.value.id
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
ElMessage.error('请选择核销项目')
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -171,17 +184,12 @@ async function groupOrdergroupScanHandle() {
|
|||||||
emits('succcess')
|
emits('succcess')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
groupDetailLoading.value = false
|
groupDetailLoading.value = false
|
||||||
console.log(error);
|
console.log('groupOrdergroupScanHandle.error', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const douyin_table = ref(null)
|
const douyin_table = ref(null)
|
||||||
|
|
||||||
// 选择要核销的券
|
|
||||||
function douyinSelectionChange(e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 核销券码
|
// 核销券码
|
||||||
async function submitHandle() {
|
async function submitHandle() {
|
||||||
try {
|
try {
|
||||||
@@ -202,6 +210,7 @@ async function submitHandle() {
|
|||||||
const res = await douyinfulfilmentcertificateprepare({
|
const res = await douyinfulfilmentcertificateprepare({
|
||||||
object_id: decodeURI(scanCode.value),
|
object_id: decodeURI(scanCode.value),
|
||||||
});
|
});
|
||||||
|
dialogVisible.value = false
|
||||||
loading.value = false
|
loading.value = false
|
||||||
groupDetail.value = res
|
groupDetail.value = res
|
||||||
detailVisible.value = true
|
detailVisible.value = true
|
||||||
@@ -217,7 +226,10 @@ async function submitHandle() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
loading.value = false
|
loading.value = false
|
||||||
console.log(error);
|
console.log('submitHandle.error', error);
|
||||||
|
if (error.code == 4399) {
|
||||||
|
BindShopRef.value.show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,6 +267,7 @@ const inputChange = _.debounce(function (e) {
|
|||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
function show() {
|
function show() {
|
||||||
|
global.updateData(false)
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inputRef.value.focus();
|
inputRef.value.focus();
|
||||||
@@ -262,6 +275,7 @@ function show() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
|
global.updateData(true)
|
||||||
dialogVisible.value = false;
|
dialogVisible.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +288,7 @@ defineExpose({
|
|||||||
show,
|
show,
|
||||||
close,
|
close,
|
||||||
loading,
|
loading,
|
||||||
|
submitHandle
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="cart_wrap card">
|
<div class="cart_wrap card">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<el-select v-model="tableData.type" placeholder="核销类型">
|
<el-select v-model="tableData.type" placeholder="核销类型" @change="typeChange">
|
||||||
<el-option v-for="item in typeList" :key="item.value" :value="item.value"
|
<el-option v-for="item in typeList" :key="item.value" :value="item.value"
|
||||||
:label="item.label"></el-option>
|
:label="item.label"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -79,14 +79,16 @@
|
|||||||
<template v-slot="scope">
|
<template v-slot="scope">
|
||||||
<div class="goods_list">
|
<div class="goods_list">
|
||||||
<div class="row" v-for="item in scope.row.douyinCodeGoods" :key="item.id">
|
<div class="row" v-for="item in scope.row.douyinCodeGoods" :key="item.id">
|
||||||
<div class="item" style="flex: 1;white-space: nowrap;margin-right: 10px;">
|
<div class="item" style="width: 240px;">
|
||||||
{{ item.title }}
|
{{ item.title }}
|
||||||
</div>
|
</div>
|
||||||
<div class="item" style="flex: 1;margin-right: 10px;color: var(--primary-color);">
|
<div class="item" style="width: 100px;color: var(--primary-color);">
|
||||||
¥{{ item.pay_amount }}
|
¥{{ item.pay_amount }}
|
||||||
</div>
|
</div>
|
||||||
<div class="item" style="margin-right: 10px;">
|
<div class="item"
|
||||||
<el-tag type="success" disable-transitions size="default" effect="light" round>
|
style="margin-right: 10px;display: flex;justify-content: flex-end;">
|
||||||
|
<el-tag :type="typeStatus(item.status)" disable-transitions size="default"
|
||||||
|
effect="light" round>
|
||||||
{{ item.status_text }}
|
{{ item.status_text }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,9 +103,9 @@
|
|||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
<el-pagination @current-change="paginationChange" :current-page="tableData.page"
|
<el-pagination v-model:current-page="tableData.page" v-model:page-size="tableData.size"
|
||||||
:page-size="tableData.size" layout="total, prev, pager, next, jumper" :total="tableData.total"
|
layout="total, prev, pager, next" :total="tableData.total" background
|
||||||
background>
|
@current-change="paginationChange" @size-change="paginationChange">
|
||||||
</el-pagination>
|
</el-pagination>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -121,6 +123,7 @@ import { ref, onMounted, reactive } from 'vue'
|
|||||||
import scanGroup from './components/scanGroup.vue'
|
import scanGroup from './components/scanGroup.vue'
|
||||||
import refundDialog from './components/refundDialog.vue'
|
import refundDialog from './components/refundDialog.vue'
|
||||||
import { useUser } from "@/store/user.js"
|
import { useUser } from "@/store/user.js"
|
||||||
|
import BindShop from './components/bindShop.vue'
|
||||||
const store = useUser()
|
const store = useUser()
|
||||||
|
|
||||||
import { useGlobal } from '@/store/global.js'
|
import { useGlobal } from '@/store/global.js'
|
||||||
@@ -129,10 +132,19 @@ const global = useGlobal()
|
|||||||
const scanGroupRef = ref(null)
|
const scanGroupRef = ref(null)
|
||||||
const refundDialogRef = ref(null)
|
const refundDialogRef = ref(null)
|
||||||
|
|
||||||
|
function typeStatus(t) {
|
||||||
|
const m = {
|
||||||
|
0: 'warning',
|
||||||
|
1: 'success',
|
||||||
|
2: 'danger'
|
||||||
|
}
|
||||||
|
return m[t]
|
||||||
|
}
|
||||||
|
|
||||||
const tableData = reactive({
|
const tableData = reactive({
|
||||||
resetLoading: false,
|
resetLoading: false,
|
||||||
proName: '',
|
proName: '',
|
||||||
type: 1,
|
type: 2,
|
||||||
status: '',
|
status: '',
|
||||||
loading: false,
|
loading: false,
|
||||||
list: [],
|
list: [],
|
||||||
@@ -162,7 +174,8 @@ const typeList = reactive([
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
const statusList = reactive([
|
// 本店团购订单状态
|
||||||
|
const originStatus = [
|
||||||
{
|
{
|
||||||
value: 'unpaid',
|
value: 'unpaid',
|
||||||
label: '待付款'
|
label: '待付款'
|
||||||
@@ -187,16 +200,51 @@ const statusList = reactive([
|
|||||||
value: 'cancelled',
|
value: 'cancelled',
|
||||||
label: '已取消'
|
label: '已取消'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
|
|
||||||
|
// 抖音美团
|
||||||
|
const dmStatus = [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: '等待验券'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: '成功'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: '失败'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const statusList = ref([])
|
||||||
|
|
||||||
|
// 切换筛选条件
|
||||||
|
function typeChange(e) {
|
||||||
|
switch (e) {
|
||||||
|
case 1:
|
||||||
|
statusList.value = [...originStatus]
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
statusList.value = [...dmStatus]
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tableData.status = ''
|
||||||
|
tableData.page = 1
|
||||||
|
tableData.list = []
|
||||||
|
groupOrderlistAjax()
|
||||||
|
}
|
||||||
|
|
||||||
// 状态
|
// 状态
|
||||||
function statusFilter(t) {
|
function statusFilter(t) {
|
||||||
return statusList.find(item => item.value == t)?.label
|
return originStatus.find(item => item.value == t)?.label
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分页变化
|
// 分页变化
|
||||||
function paginationChange(e) {
|
function paginationChange(e) {
|
||||||
tableData.page = e
|
|
||||||
groupOrderlistAjax()
|
groupOrderlistAjax()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +291,9 @@ async function groupOrderlistAjax() {
|
|||||||
case 2:
|
case 2:
|
||||||
// 获取抖音团购数据
|
// 获取抖音团购数据
|
||||||
res = await douyinorderlist({
|
res = await douyinorderlist({
|
||||||
page: tableData.page
|
page: tableData.page,
|
||||||
|
status: tableData.status,
|
||||||
|
d_order_id: tableData.proName
|
||||||
})
|
})
|
||||||
tableData.resetLoading = false
|
tableData.resetLoading = false
|
||||||
tableData.loading = false
|
tableData.loading = false
|
||||||
@@ -260,7 +310,7 @@ async function groupOrderlistAjax() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
groupOrderlistAjax()
|
typeChange(tableData.type)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<!-- 结算订单 -->
|
<!-- 结算订单 -->
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible">
|
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible">
|
||||||
<div class="drawer_wrap">
|
<div class="drawer_wrap">
|
||||||
@@ -16,7 +15,7 @@
|
|||||||
<span class="member_info" v-if="memberInfo.telephone">会员:{{ memberInfo.telephone }}</span>
|
<span class="member_info" v-if="memberInfo.telephone">会员:{{ memberInfo.telephone }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="btm">
|
<div class="btm">
|
||||||
<span class="p">服务员:{{ store.userInfo.shopName || "暂无" }}</span>
|
<span class="p">服务员:{{ store.userInfo.loginAccount || "暂无" }}</span>
|
||||||
<span class="t">{{
|
<span class="t">{{
|
||||||
props.orderInfo.createdAt &&
|
props.orderInfo.createdAt &&
|
||||||
dayjs(props.orderInfo.createdAt).format("MM-DD HH:mm")
|
dayjs(props.orderInfo.createdAt).format("MM-DD HH:mm")
|
||||||
@@ -77,6 +76,8 @@ import { ElMessage } from "element-plus";
|
|||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import useStorage from '@/utils/useStorage'
|
import useStorage from '@/utils/useStorage'
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
|
import { formatDecimal } from '@/utils/index.js'
|
||||||
|
import receiptPrint from "@/components/lodop/receiptPrint.js";
|
||||||
|
|
||||||
import { usePrint } from '@/store/print.js'
|
import { usePrint } from '@/store/print.js'
|
||||||
const printStore = usePrint()
|
const printStore = usePrint()
|
||||||
@@ -121,31 +122,32 @@ const isPrint = ref(true);
|
|||||||
const printHandle = _.throttle(async function () {
|
const printHandle = _.throttle(async function () {
|
||||||
try {
|
try {
|
||||||
if (!isPrint.value) return;
|
if (!isPrint.value) return;
|
||||||
|
printLoading.value = true;
|
||||||
const data = {
|
const data = {
|
||||||
shop_name: store.userInfo.merchantName,
|
shop_name: store.userInfo.shopName,
|
||||||
|
loginAccount: store.userInfo.loginAccount,
|
||||||
|
isBefore: true,
|
||||||
carts: props.cart,
|
carts: props.cart,
|
||||||
amount: props.amount,
|
amount: props.amount,
|
||||||
remark: props.remark,
|
remark: props.remark,
|
||||||
orderInfo: props.orderInfo,
|
orderInfo: props.orderInfo,
|
||||||
createdAt: dayjs(props.orderInfo.createdAt).format(
|
createdAt: dayjs(props.orderInfo.createdAt).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
"YYYY-MM-DD HH:mm:ss"
|
|
||||||
),
|
|
||||||
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
||||||
};
|
};
|
||||||
printStore.labelPrint(data)
|
printStore.labelPrint(data)
|
||||||
|
setTimeout(() => {
|
||||||
try {
|
printLoading.value = false;
|
||||||
printLoading.value = true;
|
}, 1500)
|
||||||
|
if (printStore.deviceNoteList.length) {
|
||||||
|
printStore.pushReceiptData(data)
|
||||||
|
} else {
|
||||||
await print({
|
await print({
|
||||||
type: "normal",
|
type: "normal",
|
||||||
ispre: true,
|
ispre: true,
|
||||||
orderId: props.orderInfo.id,
|
orderId: props.orderInfo.id,
|
||||||
});
|
});
|
||||||
printLoading.value = false;
|
printLoading.value = false;
|
||||||
// ElMessage.success("打印成功");
|
ElMessage.success("打印成功");
|
||||||
} catch (error) {
|
|
||||||
printLoading.value = false;
|
|
||||||
console.log(error);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -155,6 +157,7 @@ const printHandle = _.throttle(async function () {
|
|||||||
// 打印订单标签
|
// 打印订单标签
|
||||||
async function printOrderLable() {
|
async function printOrderLable() {
|
||||||
try {
|
try {
|
||||||
|
if (!isPrint.value) return
|
||||||
const res = await orderfindOrder({
|
const res = await orderfindOrder({
|
||||||
shopId: store.userInfo.shopId,
|
shopId: store.userInfo.shopId,
|
||||||
status: '',
|
status: '',
|
||||||
@@ -166,13 +169,17 @@ async function printOrderLable() {
|
|||||||
const printLabelOrder = res.list[0]
|
const printLabelOrder = res.list[0]
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
shop_name: store.userInfo.merchantName,
|
shop_name: store.userInfo.shopName,
|
||||||
|
loginAccount: store.userInfo.loginAccount,
|
||||||
carts: [],
|
carts: [],
|
||||||
|
amount: printLabelOrder.orderAmount,
|
||||||
|
remark: printLabelOrder.remark,
|
||||||
orderInfo: printLabelOrder,
|
orderInfo: printLabelOrder,
|
||||||
outNumber: printLabelOrder.outNumber,
|
outNumber: printLabelOrder.outNumber,
|
||||||
createdAt: dayjs(printLabelOrder.createdAt).format(
|
createdAt: dayjs(printLabelOrder.createdAt).format(
|
||||||
"YYYY-MM-DD HH:mm:ss"
|
"YYYY-MM-DD HH:mm:ss"
|
||||||
)
|
),
|
||||||
|
printTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
|
||||||
}
|
}
|
||||||
printLabelOrder.skuInfos.map(item => {
|
printLabelOrder.skuInfos.map(item => {
|
||||||
data.carts.push(
|
data.carts.push(
|
||||||
@@ -180,13 +187,27 @@ async function printOrderLable() {
|
|||||||
categoryId: item.categoryId,
|
categoryId: item.categoryId,
|
||||||
name: item.productName,
|
name: item.productName,
|
||||||
number: item.num,
|
number: item.num,
|
||||||
skuName: item.productSkuName
|
skuName: item.productSkuName,
|
||||||
|
salePrice: formatDecimal(item.priceAmount / item.num),
|
||||||
|
totalAmount: formatDecimal(item.priceAmount)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
// 打印标签
|
||||||
// console.log('重打标签小票', data);
|
|
||||||
printStore.labelPrint(data)
|
printStore.labelPrint(data)
|
||||||
|
|
||||||
|
if (printStore.deviceNoteList.length) {
|
||||||
|
// 打印小票
|
||||||
|
printStore.pushReceiptData(data)
|
||||||
|
} else {
|
||||||
|
await print({
|
||||||
|
type: "normal",
|
||||||
|
ispre: true,
|
||||||
|
orderId: props.orderInfo.id,
|
||||||
|
});
|
||||||
|
printLoading.value = false;
|
||||||
|
ElMessage.success("打印成功");
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -291,6 +312,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
.p {
|
.p {
|
||||||
color: #999;
|
color: #999;
|
||||||
|
width: 160px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,19 +12,23 @@
|
|||||||
<el-text class="t">{{ masterId }}</el-text>
|
<el-text class="t">{{ masterId }}</el-text>
|
||||||
</div>
|
</div>
|
||||||
<div class="select_user" @click="fastCashierRef.show()" v-if="!memberInfo.telephone">
|
<div class="select_user" @click="fastCashierRef.show()" v-if="!memberInfo.telephone">
|
||||||
<el-icon class="icon">
|
<div class="left">
|
||||||
<WalletFilled />
|
<el-icon class="icon">
|
||||||
</el-icon>
|
<WalletFilled />
|
||||||
<el-text class="t">快捷收银</el-text>
|
</el-icon>
|
||||||
|
<el-text class="t">快捷收银</el-text>
|
||||||
|
</div>
|
||||||
<el-icon class="arrow">
|
<el-icon class="arrow">
|
||||||
<ArrowRight />
|
<ArrowRight />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
<div class="select_user" v-else @click="clearMember">
|
<div class="select_user" v-else @click="clearMember">
|
||||||
<el-icon class="icon">
|
<div class="left">
|
||||||
<UserFilled />
|
<el-icon class="icon">
|
||||||
</el-icon>
|
<UserFilled />
|
||||||
<el-text class="t">{{ memberInfo.telephone }}</el-text>
|
</el-icon>
|
||||||
|
<el-text class="t">{{ memberInfo.telephone }}</el-text>
|
||||||
|
</div>
|
||||||
<el-icon class="arrow">
|
<el-icon class="arrow">
|
||||||
<Close />
|
<Close />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
@@ -418,7 +422,7 @@ onMounted(() => {
|
|||||||
.menu {
|
.menu {
|
||||||
background-color: var(--el-color-warning);
|
background-color: var(--el-color-warning);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
width: 100px;
|
width: 60px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -437,7 +441,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.number {
|
.number {
|
||||||
flex: 1;
|
width: 50px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -450,24 +454,31 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.select_user {
|
.select_user {
|
||||||
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
background-color: var(--el-color-info-light-8);
|
background-color: var(--el-color-info-light-8);
|
||||||
padding: 0 var(--el-font-size-base);
|
padding: 0 var(--el-font-size-base);
|
||||||
|
|
||||||
.icon {
|
.left {
|
||||||
color: var(--el-color-primary);
|
display: flex;
|
||||||
font-size: 18px;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.t {
|
.icon {
|
||||||
font-size: var(--el-font-size-base);
|
color: var(--el-color-primary);
|
||||||
padding: 0 10px;
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.t {
|
||||||
|
font-size: var(--el-font-size-base);
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow {
|
.arrow {
|
||||||
color: #999;
|
color: #999;
|
||||||
font-size: 20px;
|
font-size: 16px;
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- <el-button @click="chooseSerial">获取串口列表</el-button> -->
|
<!-- <el-button @click="chooseSerial">获取串口列表</el-button> -->
|
||||||
<el-button @click="initWebSocket()">连接ws</el-button>
|
<el-button @click="initWebSocket()">连接ws</el-button>
|
||||||
|
<el-button @click="dakai()"></el-button>
|
||||||
|
<!-- 打印二维码 -->
|
||||||
|
<rintermodelindex ref="rintermodelindexref" :form="form" @somethingDone="handleSomethingDone"></rintermodelindex>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -12,8 +15,24 @@ import { ipcRenderer } from 'electron'
|
|||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { useUser } from "@/store/user.js";
|
import { useUser } from "@/store/user.js";
|
||||||
import useStorage from '@/utils/useStorage'
|
import useStorage from '@/utils/useStorage'
|
||||||
|
import rintermodelindex from '@/components/lodop/index.vue'
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
|
const rintermodelindexref = ref()//打印机ref
|
||||||
|
// 打印成功回调
|
||||||
|
const handleSomethingDone = () => {
|
||||||
|
console.log('打印成功回调成功')
|
||||||
|
}
|
||||||
|
const form = ref({
|
||||||
|
article: '1',
|
||||||
|
type: '2',
|
||||||
|
|
||||||
|
})
|
||||||
|
const dakai = () => {
|
||||||
|
rintermodelindexref.value.centerDialogVisibleshow() //打开二维码打印
|
||||||
|
rintermodelindexref.value.initialization()
|
||||||
|
}
|
||||||
|
|
||||||
// 小票打印机列表
|
// 小票打印机列表
|
||||||
const printList = ref([]);
|
const printList = ref([]);
|
||||||
// 标签打印机列表
|
// 标签打印机列表
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -22,7 +22,16 @@
|
|||||||
<el-input v-model="form.loginName" placeholder="请输入11位手机号码"></el-input>
|
<el-input v-model="form.loginName" placeholder="请输入11位手机号码"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="登录密码" prop="password">
|
<el-form-item label="登录密码" prop="password">
|
||||||
<el-input v-model="form.password" type="password" placeholder="请输入登录密码"></el-input>
|
<el-input v-model="form.password" :type="passwordType" placeholder="请输入登录密码">
|
||||||
|
<template #suffix>
|
||||||
|
<el-icon class="el-input__icon" v-if="passwordType == 'password'" @click="passwordType = 'text'">
|
||||||
|
<Hide />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon class="el-input__icon" v-else @click="passwordType = 'password'">
|
||||||
|
<View />
|
||||||
|
</el-icon>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item>
|
<!-- <el-form-item>
|
||||||
<div style="width: 100%; display: flex; justify-content: flex-end">
|
<div style="width: 100%; display: flex; justify-content: flex-end">
|
||||||
@@ -51,30 +60,33 @@
|
|||||||
</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 { Hide, View } from '@element-plus/icons-vue'
|
||||||
|
import { onMounted, 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";
|
||||||
|
import { useGlobal } from '@/store/global.js'
|
||||||
|
const global = useGlobal()
|
||||||
|
|
||||||
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 passwordType = ref('password')
|
||||||
|
|
||||||
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 +120,27 @@ 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,
|
ElMessage.success("登录成功");
|
||||||
// clientType: 'pc'
|
socket.init();
|
||||||
// })
|
setTimeout(() => {
|
||||||
// useStorage.set('douyin', douyin.userInfo)
|
router.replace({
|
||||||
ElMessage.success("登录成功");
|
name: "home",
|
||||||
setTimeout(() => {
|
});
|
||||||
router.replace({
|
}, 1000);
|
||||||
name: "home",
|
const douyin = await douyincheckIn({
|
||||||
});
|
token: res.token,
|
||||||
}, 1000);
|
loginName: res.loginName,
|
||||||
}).catch(err => {
|
clientType: 'pc'
|
||||||
loading.value = false
|
})
|
||||||
});
|
useStorage.set('douyin', douyin.userInfo)
|
||||||
|
global.updateData(true)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -135,6 +152,10 @@ const logout = () => {
|
|||||||
})
|
})
|
||||||
.catch(() => { });
|
.catch(() => { });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
global.updateData(false)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="demo_tabs_box">
|
<div class="demo_tabs_box" v-loading="props.loading">
|
||||||
<div class="demo_tabs_boxitem" v-for="(item, index) in ordereData.list" :key="index"
|
<div class="demo_tabs_boxitem" v-for="(item, index) in ordereData.list" :key="index"
|
||||||
@click="clickitemboxshow(item)">
|
@click="clickitemboxshow(item)">
|
||||||
<!-- <div class="demo_tabs_boxitem_oneyt" v-if="item.status == 'refund' && item.orderType == 'return'">已退款</div> -->
|
<!-- <div class="demo_tabs_boxitem_oneyt" v-if="item.status == 'refund' && item.orderType == 'return'">已退款</div> -->
|
||||||
|
|
||||||
<div class="demo_tabs_boxitem_one">
|
<div class="demo_tabs_boxitem_one">
|
||||||
<div class=""
|
<div class=""
|
||||||
style="width: 100px; height: 70px;border-radius: 10px; background:rgb(186 200 239); display: flex; justify-content: center; align-items: center;">
|
style="width: 100px; height: 70px;border-radius: 4px; background:rgb(186 200 239); display: flex; justify-content: center; align-items: center;">
|
||||||
<div>{{ item.zdNo || "pos" }}</div>
|
<div>{{ item.tableName || "pos" }}</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <el-image style="width: 100px; height: 70px;border-radius: 10px;" :src="item.imgUrl" fit="scale-down" /> -->
|
<!-- <el-image style="width: 100px; height: 70px;border-radius: 10px;" :src="item.imgUrl" fit="scale-down" /> -->
|
||||||
<div class="demo_tabs_boxitem_oneone">
|
<div class="demo_tabs_boxitem_oneone">
|
||||||
@@ -53,6 +53,10 @@ const props = defineProps({
|
|||||||
names: []
|
names: []
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(["emititemboxshow"])
|
const emit = defineEmits(["emititemboxshow"])
|
||||||
@@ -64,17 +68,15 @@ const clickitemboxshow = (e) => {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.demo_tabs_box {
|
.demo_tabs_box {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px 20px;
|
|
||||||
height: 82%;
|
height: 82%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
.demo_tabs_boxitem {
|
.demo_tabs_boxitem {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 6px 16px;
|
padding: 10px 0;
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #ececec;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
.demo_tabs_boxitem_oneyt {
|
.demo_tabs_boxitem_oneyt {
|
||||||
|
|||||||
78
src/views/order/components/dateRange.vue
Normal file
78
src/views/order/components/dateRange.vue
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<el-date-picker v-model="dateVlaue" type="daterange" :editable="false" :shortcuts="shortcuts" range-separator="至"
|
||||||
|
start-placeholder="开始时间" end-placeholder="结束时间" :clearable="false" @change="dateConfirm" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { onMounted, ref } from 'vue'
|
||||||
|
import { dayjs } from 'element-plus'
|
||||||
|
|
||||||
|
const emits = defineEmits(['success'])
|
||||||
|
|
||||||
|
const shortcuts = [
|
||||||
|
{
|
||||||
|
text: '今天',
|
||||||
|
value: () => {
|
||||||
|
return [
|
||||||
|
dayjs()
|
||||||
|
.startOf("day"),
|
||||||
|
dayjs()
|
||||||
|
.endOf("day")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '本月',
|
||||||
|
value: () => {
|
||||||
|
return [
|
||||||
|
dayjs()
|
||||||
|
.startOf("month"),
|
||||||
|
dayjs()
|
||||||
|
.endOf("month")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '最近三个月',
|
||||||
|
value: () => {
|
||||||
|
return [
|
||||||
|
dayjs()
|
||||||
|
.add(-3, "M"),
|
||||||
|
dayjs()
|
||||||
|
.endOf("month")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '本年',
|
||||||
|
value: () => {
|
||||||
|
return [
|
||||||
|
dayjs()
|
||||||
|
.startOf("year"),
|
||||||
|
dayjs()
|
||||||
|
.endOf("year")
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
const dateVlaue = ref([dayjs(), dayjs()])
|
||||||
|
const format = ["YYYY-MM-DD 00:00:00", "YYYY-MM-DD 23:59:59"];
|
||||||
|
|
||||||
|
// 确认选择时间
|
||||||
|
function dateConfirm(value) {
|
||||||
|
// console.log(value);
|
||||||
|
emits('success', [
|
||||||
|
dayjs(value[0]).format(format[0]),
|
||||||
|
dayjs(value[1]).format(format[1]),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 创建组件后执行一次时间传递
|
||||||
|
emits('success', [
|
||||||
|
dayjs(dateVlaue[0]).format(format[0]),
|
||||||
|
dayjs(dateVlaue[1]).format(format[1]),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
</script>
|
||||||
134
src/views/order/components/invoice.vue
Normal file
134
src/views/order/components/invoice.vue
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog title="选择开票人" width="60%" v-model="dialogVisible">
|
||||||
|
<el-table :data="tableData.list" border>
|
||||||
|
<el-table-column label="开票人" prop="name"></el-table-column>
|
||||||
|
<el-table-column label="操作" width="140">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button type="primary" icon="" :loading="scope.row.loading"
|
||||||
|
@click="selectHandle(scope.row)">选择</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
<el-dialog title="扫描二维码开票" width="330px" v-model="showEwmDialog">
|
||||||
|
<canvas class="ewm" ref="canvasRef"></canvas>
|
||||||
|
<div class="footer">
|
||||||
|
<el-button type="primary" style="width: 100%" :loading="printEwmLoading"
|
||||||
|
@click="printEwmHandle">打印二维码</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import QRCode from 'qrcode'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { issuedby, carsubinvoicing, syjprintqrcode } from '@/api/invoice.js'
|
||||||
|
import { useUser } from "@/store/user.js";
|
||||||
|
import { usePrint } from "@/store/print.js";
|
||||||
|
const printStore = usePrint();
|
||||||
|
const store = useUser();
|
||||||
|
|
||||||
|
const emits = defineEmits(['loadComplete', 'success'])
|
||||||
|
|
||||||
|
const dialogVisible = ref(false)
|
||||||
|
const showEwmDialog = ref(false)
|
||||||
|
const canvasRef = ref(null)
|
||||||
|
const ewmInfo = ref({})
|
||||||
|
const printEwmLoading = ref(false)
|
||||||
|
|
||||||
|
const tableData = reactive({
|
||||||
|
list: []
|
||||||
|
})
|
||||||
|
const orderInfo = ref({})
|
||||||
|
|
||||||
|
// 打印二维码
|
||||||
|
async function printEwmHandle() {
|
||||||
|
try {
|
||||||
|
printEwmLoading.value = true
|
||||||
|
if (printStore.deviceNoteList.length) {
|
||||||
|
printStore.printInvoice({
|
||||||
|
url: ewmInfo.value.wechat_url
|
||||||
|
})
|
||||||
|
ElMessage.success('打印成功')
|
||||||
|
showEwmDialog.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
printEwmLoading.value = false
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
const res = await syjprintqrcode({
|
||||||
|
id: ewmInfo.value.id
|
||||||
|
})
|
||||||
|
ElMessage.success('打印成功')
|
||||||
|
showEwmDialog.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
printEwmLoading.value = false
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
printEwmLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择开票
|
||||||
|
async function selectHandle(row) {
|
||||||
|
try {
|
||||||
|
row.loading = true
|
||||||
|
const res = await carsubinvoicing({
|
||||||
|
store_id: store.userInfo.loginName,
|
||||||
|
orderNo: orderInfo.value.id,
|
||||||
|
dlzh: row.id
|
||||||
|
})
|
||||||
|
console.log(res);
|
||||||
|
row.loading = false
|
||||||
|
ewmInfo.value = res
|
||||||
|
dialogVisible.value = false
|
||||||
|
showEwmDialog.value = true
|
||||||
|
setTimeout(() => {
|
||||||
|
QRCode.toCanvas(canvasRef.value, ewmInfo.value.wechat_url, function (error) {
|
||||||
|
if (error) console.error(error)
|
||||||
|
// console.log('success!');
|
||||||
|
})
|
||||||
|
}, 10)
|
||||||
|
} catch (error) {
|
||||||
|
row.loading = false
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取开票人列表
|
||||||
|
async function getTableData() {
|
||||||
|
try {
|
||||||
|
const res = await issuedby({
|
||||||
|
store_id: store.userInfo.loginName
|
||||||
|
})
|
||||||
|
emits('loadComplete', false)
|
||||||
|
dialogVisible.value = true
|
||||||
|
tableData.list = res.map(item => {
|
||||||
|
item.loading = false
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
emits('loadComplete', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(order) {
|
||||||
|
console.log(order);
|
||||||
|
orderInfo.value = order
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.ewm {
|
||||||
|
width: 300px !important;
|
||||||
|
height: 300px !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, defineEmits } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
|
||||||
const emit = defineEmits(['close'])
|
const emit = defineEmits(['close'])
|
||||||
|
|
||||||
|
|||||||
@@ -8,16 +8,16 @@
|
|||||||
<el-text>{{ item.label }}</el-text>
|
<el-text>{{ item.label }}</el-text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="all">
|
<!-- <div class="all">
|
||||||
<el-button type="text" icon="Clock">预定管理</el-button>
|
<el-button type="link" icon="Clock">预定管理</el-button>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="tab_container">
|
<div class="tab_container">
|
||||||
<div class="tab_head">
|
<div class="tab_head">
|
||||||
<el-radio-group v-model="area" @change="queryShopTableAjax">
|
<el-radio-group v-model="area" @change="queryShopTableAjax">
|
||||||
<el-radio-button label="">全部</el-radio-button>
|
<el-radio-button label="全部" value=""></el-radio-button>
|
||||||
<el-radio-button :label="item.id" v-for="item in areaList" :key="item.id">{{ item.name
|
<el-radio-button :label="item.name" :value="item.id" v-for="item in areaList"
|
||||||
}}</el-radio-button>
|
:key="item.id"></el-radio-button>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow_y" v-loading="loading">
|
<div class="overflow_y" v-loading="loading">
|
||||||
@@ -75,10 +75,10 @@ const tabAreas = ref([
|
|||||||
label: '使用中',
|
label: '使用中',
|
||||||
type: 2,
|
type: 2,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
label: '已预订',
|
// label: '已预订',
|
||||||
type: 3,
|
// type: 3,
|
||||||
}
|
// }
|
||||||
])
|
])
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
|
|||||||
@@ -2,12 +2,12 @@
|
|||||||
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible">
|
<el-drawer size="100%" :with-header="false" direction="btt" v-model="dialogVisible">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box_top">
|
<div class="box_top">
|
||||||
<router-link to="/" class="box_top_left">
|
<div class="box_top_left" @click="dialogVisible = false">
|
||||||
<el-icon size="20">
|
<el-icon size="20">
|
||||||
<ArrowLeft />
|
<ArrowLeft />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<div style="margin-left: 10px;">返回</div>
|
<div style="margin-left: 4px;">返回</div>
|
||||||
</router-link>
|
</div>
|
||||||
<router-link to='/workrecord' class="box_top_right">
|
<router-link to='/workrecord' class="box_top_right">
|
||||||
交班记录
|
交班记录
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="box_content_left_top_item_top">
|
<div class="box_content_left_top_item_top">
|
||||||
<div style="color:#ff5252; font-size: 30px;">
|
<div style="color:#ff5252; font-size: 30px;">
|
||||||
{{ infoData.amount || 0 }}
|
¥{{ formatDecimal(infoData.amount || 0) }}
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 6px; color: #666;">
|
<div style="margin-top: 6px; color: #666;">
|
||||||
营业额
|
营业额
|
||||||
@@ -36,83 +36,95 @@
|
|||||||
<div class="box_content_left_top_item">
|
<div class="box_content_left_top_item">
|
||||||
<div class="box_content_left_top_item_botton">
|
<div class="box_content_left_top_item_botton">
|
||||||
<div style=" font-size: 20px;">
|
<div style=" font-size: 20px;">
|
||||||
{{ infoData.cashAmount || 0 }}
|
¥{{ formatDecimal(infoData.cashAmount || 0) }}
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 6px;">
|
<div style="margin-top: 6px;">
|
||||||
现金支付
|
现金支付
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 6px;font-size: 14px;">
|
<!-- <div style="margin-top: 6px;font-size: 14px;">
|
||||||
查看详情
|
查看详情
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_left_top_item_botton">
|
<div class="box_content_left_top_item_botton">
|
||||||
<div style=" font-size: 20px;">
|
<div style=" font-size: 20px;">
|
||||||
{{ infoData.returnAmount || 0 }}
|
¥{{ formatDecimal(infoData.returnAmount || 0) }}
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 6px;">
|
<div style="margin-top: 6px;">
|
||||||
退款金额
|
退款金额
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 6px;font-size: 14px;">
|
<!-- <div style="margin-top: 6px;font-size: 14px;">
|
||||||
查看详情
|
查看详情
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_left_bottom">
|
<div class="box_content_left_bottom">
|
||||||
<el-table :data="infoData.detailList" style="width: 100%;" height="400px">
|
<el-table :data="infoData.detailList" border style="width: 100%;" height="360px">
|
||||||
<el-table-column prop="productName" label="商品名称" />
|
<el-table-column prop="productName" label="商品名称" />
|
||||||
<el-table-column prop="skuName" label="规格名称" />
|
<el-table-column prop="skuName" label="规格名称" />
|
||||||
<el-table-column prop="num" label="商品数量" />
|
<el-table-column prop="num" label="商品数量" />
|
||||||
<el-table-column prop="amount" label="商品金额" />
|
<el-table-column prop="amount" label="商品金额">
|
||||||
|
<template v-slot="scope">
|
||||||
|
¥{{ formatDecimal(scope.row.amount || 0) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_right">
|
<div class="box_content_right">
|
||||||
<div class="box_content_right_tiem">
|
<div class="top">
|
||||||
<div class="box_content_right_tiemleft">
|
<div class="box_content_right_tiem">
|
||||||
上岗时间:
|
<div class="box_content_right_tiemleft">
|
||||||
|
上岗时间:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
{{ dayjs(infoData.loginTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_right_tiemright">
|
<div class="box_content_right_tiem">
|
||||||
{{ dayjs(infoData.loginTime).format("YYYY-MM-DD HH:mm:ss") }}
|
<div class="box_content_right_tiemleft">
|
||||||
|
交班时间:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
{{ dayjs(infoData.loginOutTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
终端名称:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
{{ infoData.equipment || '无' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
备用金:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
{{ infoData.pettyCash || '无' }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
收营员:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
{{ infoData.userName || '无' }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_right_tiem">
|
<div class="footer">
|
||||||
<div class="box_content_right_tiemleft">
|
<div class="is_shop">
|
||||||
交班时间:
|
<div class="button">
|
||||||
|
<el-checkbox v-model="isPrint" border label="是否打印商品销售数据" style="width: 100%" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_right_tiemright">
|
<div class="box_content_right_tiembutton" :loading="loading" @click="exit">
|
||||||
{{ dayjs(infoData.loginOutTime).format("YYYY-MM-DD HH:mm:ss") }}
|
<span v-if="!loading">交班/关班</span>
|
||||||
|
<span v-else>交班/关班中....</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
终端名称:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
{{ infoData.equipment || '无' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
备用金:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
{{ infoData.pettyCash || '无' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
收营员:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
{{ infoData.userName || '无' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiembutton" :loading="loading" @click="exit">
|
|
||||||
<span v-if="!loading">交班/关班</span>
|
|
||||||
<span v-else>交班/关班中....</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,107 +134,89 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
|
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ElMessage, dayjs } from 'element-plus'
|
import { ElMessage, dayjs } from 'element-plus'
|
||||||
import { shopInfoqueryDuty, loginlogout, handoverData } from '@/api/work/index.js'
|
import { tglogout } from '@/api/group.js'
|
||||||
|
import { shopInfoqueryDuty, loginlogout, handoverData, handoverprint } from '@/api/work/index.js'
|
||||||
import useStorage from '@/utils/useStorage'
|
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";
|
||||||
|
import { formatDecimal } from '@/utils/index.js'
|
||||||
|
import { usePrint } from "@/store/print.js";
|
||||||
|
const printStore = usePrint();
|
||||||
|
|
||||||
|
const socket = useSocket();
|
||||||
|
|
||||||
const store = useUser();
|
const store = useUser();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const dialogVisible = ref(true) //交班
|
const dialogVisible = ref(false) //交班
|
||||||
//详情数据
|
//详情数据
|
||||||
const infoData = ref({})
|
const infoData = ref({})
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const printList = ref([]);
|
const isPrint = ref(true)
|
||||||
const localPrintList = ref([])
|
|
||||||
|
|
||||||
// 获取打印机状态
|
|
||||||
async function bySubTypeAjax() {
|
|
||||||
try {
|
|
||||||
const res = await bySubType({
|
|
||||||
shopId: store.userInfo.shopId,
|
|
||||||
contentType: "local",
|
|
||||||
subType: "cash",
|
|
||||||
});
|
|
||||||
printList.value = res;
|
|
||||||
} 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 开始交班
|
||||||
const exit = async () => {
|
const exit = async () => {
|
||||||
try {
|
try {
|
||||||
if (printList.value.length) {
|
let data = {}
|
||||||
if (!checkLocalPrint(printList.value[0].config.deviceName)) {
|
// 获取交班打印小票数据
|
||||||
loading.value = true;
|
data = await handoverData({
|
||||||
let res = await loginlogout({
|
id: infoData.value.id
|
||||||
status: 1
|
})
|
||||||
})
|
|
||||||
useStorage.clear()
|
if (printStore.deviceNoteList.length) {
|
||||||
ElMessage.success("交班成功");
|
|
||||||
setTimeout(() => {
|
|
||||||
router.replace({
|
|
||||||
name: "login",
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
loading.value = false;
|
|
||||||
} else {
|
|
||||||
// 获取交班打印小票数据
|
|
||||||
const data = await handoverData({
|
|
||||||
id: infoData.value.id
|
|
||||||
})
|
|
||||||
data.deviceName = printList.value[0].config.deviceName
|
|
||||||
data.printTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
|
|
||||||
ipcRenderer.send("printerWorkSync", JSON.stringify(data));
|
|
||||||
// return
|
|
||||||
useStorage.clear()
|
|
||||||
ElMessage.success("交班成功");
|
|
||||||
setTimeout(() => {
|
|
||||||
router.replace({
|
|
||||||
name: "login",
|
|
||||||
});
|
|
||||||
}, 1000);
|
|
||||||
loading.value = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let res = await loginlogout({
|
|
||||||
|
data.printTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
data.printShop = isPrint.value
|
||||||
|
printStore.printWork(data)
|
||||||
|
|
||||||
|
// return
|
||||||
|
await loginlogout({
|
||||||
status: 1
|
status: 1
|
||||||
})
|
})
|
||||||
useStorage.clear()
|
|
||||||
|
useStorage.del('userInfo')
|
||||||
|
useStorage.del('token')
|
||||||
|
useStorage.del('douyin')
|
||||||
|
useStorage.del('categorysActive')
|
||||||
|
|
||||||
|
ElMessage.success("交班成功");
|
||||||
|
setTimeout(() => {
|
||||||
|
router.replace({
|
||||||
|
name: "login",
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
loading.value = false;
|
||||||
|
} else {
|
||||||
|
console.log('云打印交班数据');
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
await tglogout()
|
||||||
|
|
||||||
|
// 退出登录
|
||||||
|
await loginlogout({
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
// 打印交班数据
|
||||||
|
await handoverprint({
|
||||||
|
id: infoData.value.id,
|
||||||
|
isprintProduct: isPrint.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// useStorage.clear()
|
||||||
|
useStorage.del('userInfo')
|
||||||
|
useStorage.del('token')
|
||||||
|
useStorage.del('douyin')
|
||||||
|
useStorage.del('categorysActive')
|
||||||
ElMessage.success("交班成功");
|
ElMessage.success("交班成功");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
router.replace({
|
router.replace({
|
||||||
@@ -231,10 +225,14 @@ const exit = async () => {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
|
socket.close()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取交班打印数据前置
|
||||||
const infoshopInfoqueryDutys = async () => {
|
const infoshopInfoqueryDutys = async () => {
|
||||||
try {
|
try {
|
||||||
let res = await shopInfoqueryDuty({
|
let res = await shopInfoqueryDuty({
|
||||||
@@ -243,14 +241,23 @@ const infoshopInfoqueryDutys = async () => {
|
|||||||
})
|
})
|
||||||
infoData.value = res
|
infoData.value = res
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
onMounted(() => {
|
|
||||||
getPrintList()
|
function show() {
|
||||||
bySubTypeAjax()
|
dialogVisible.value = true
|
||||||
infoshopInfoqueryDutys()
|
infoshopInfoqueryDutys()
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
show
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// getPrintList()
|
||||||
|
// bySubTypeAjax()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -301,7 +308,6 @@ onMounted(() => {
|
|||||||
.box_content_left_top {
|
.box_content_left_top {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-bottom: 1px solid #ccc;
|
|
||||||
padding-bottom: 20px;
|
padding-bottom: 20px;
|
||||||
|
|
||||||
.box_content_left_top_item {
|
.box_content_left_top_item {
|
||||||
@@ -351,21 +357,17 @@ onMounted(() => {
|
|||||||
.box_content_right {
|
.box_content_right {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: #fff;
|
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
border-radius: 6px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
.box_content_right_tiem:nth-child(1) {
|
flex-direction: column;
|
||||||
margin-top: 0;
|
gap: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.box_content_right_tiem {
|
.box_content_right_tiem {
|
||||||
margin-top: 10px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
.box_content_right_tiemleft {
|
.box_content_right_tiemleft {
|
||||||
color: #9e9e9e;
|
color: #9e9e9e;
|
||||||
@@ -374,11 +376,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.box_content_right_tiembutton {
|
.box_content_right_tiembutton {
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
left: 5%;
|
|
||||||
background: #ba5050;
|
background: #ba5050;
|
||||||
width: 90%;
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -389,4 +387,44 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.top {
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
padding: 10px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is_shop {
|
||||||
|
.button {
|
||||||
|
flex: 1;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
|
||||||
|
:deep(.el-checkbox.el-checkbox--large) {
|
||||||
|
height: var(--el-component-size-large);
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-checkbox__inner) {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
border-width: 2px;
|
||||||
|
top: 0;
|
||||||
|
left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-checkbox__label) {
|
||||||
|
font-size: var(--el-font-size-base) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,130 +1,132 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-drawer size="100%" :with-header="false" direction="btt" v-model="record">
|
<div class="box">
|
||||||
<div class="box">
|
<div class="box_top" @click="clickrecord">
|
||||||
<div class="box_top" @click="clickrecord">
|
<div class="box_top_left" @click="router.back()">
|
||||||
<router-link to='/work' class="box_top_left">
|
<el-icon size="20">
|
||||||
<el-icon size="20">
|
<ArrowLeft />
|
||||||
<ArrowLeft />
|
</el-icon>
|
||||||
</el-icon>
|
<div class="box_top_right">
|
||||||
<div class="box_top_right">
|
交班记录
|
||||||
交班记录
|
</div>
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content">
|
</div>
|
||||||
<div class="box_content_left">
|
<div class="box_content">
|
||||||
<div class="box_content_left_top">
|
<div class="box_content_left">
|
||||||
<div class="box_content_left_top_item">
|
<div class="box_content_left_top">
|
||||||
<div class="box_content_left_top_item_top">
|
<div class="box_content_left_top_item">
|
||||||
<div>
|
<div class="box_content_left_top_item_top">
|
||||||
{{ infoData.total }}
|
<div>
|
||||||
</div>
|
{{ infoData.total }}
|
||||||
<div>
|
|
||||||
交班数
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_left_top_item_top">
|
<div>
|
||||||
<div>
|
交班数
|
||||||
{{ infoData.amount }}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="box_content_left_top_item_top">
|
||||||
总收款
|
<div>
|
||||||
</div>
|
{{ infoData.amount }}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
总收款
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box_content_left_bouttom">
|
</div>
|
||||||
<div class="box_content_left_bouttomox">
|
<div class="box_content_left_bouttom">
|
||||||
<div class="box_content_left_bouttom_item" v-for="(item, index) in infoData.pageInfo.list"
|
<div class="box_content_left_bouttomox">
|
||||||
:key="index">
|
<div class="box_content_left_bouttom_item" v-for="(item, index) in infoData.pageInfo.list"
|
||||||
<div class="wbox_content_left_bouttom_item_top">
|
:key="index">
|
||||||
<div>
|
<div class="wbox_content_left_bouttom_item_top">
|
||||||
{{ dayjs(item.loginTime).format("YYYY-MM-DD HH:mm:ss") }}
|
<div>
|
||||||
</div>
|
{{ dayjs(item.loginTime).format("YYYY-MM-DD HH:mm:ss") }}
|
||||||
<div>
|
|
||||||
¥{{ item.amount }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="wbox_content_left_bouttom_item_topone">
|
<div>
|
||||||
<div style="display: flex;">
|
¥{{ item.amount }}
|
||||||
<span>收营员:</span>
|
|
||||||
<span style="font-weight: bold;">{{ item.userName }}</span>
|
|
||||||
</div>
|
|
||||||
<div style="display: flex;">
|
|
||||||
<span>总订单数:</span>
|
|
||||||
<span style="font-weight: bold;">{{ item.orderNum }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="wbox_content_left_bouttom_item_topone">
|
</div>
|
||||||
<div style="display: flex;">
|
<div class="wbox_content_left_bouttom_item_topone">
|
||||||
<span>起止时间:</span>
|
<div style="display: flex;">
|
||||||
<span style="font-weight: bold;"> {{ dayjs(item.loginTime).format("YYYY-MM-DD HH:mm:ss") }}</span>
|
<span>收营员:</span>
|
||||||
</div>
|
<span style="font-weight: bold;">{{ item.userName }}</span>
|
||||||
<div style="display: flex;">
|
</div>
|
||||||
<span>备用金:</span>
|
<div style="display: flex;">
|
||||||
<span style="font-weight: bold;">{{ item.pettyCash }}</span>
|
<span>总订单数:</span>
|
||||||
</div>
|
<span style="font-weight: bold;">{{ item.orderNum }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="wbox_content_left_bouttom_item_topone">
|
||||||
|
<div style="display: flex;">
|
||||||
|
<span>起止时间:</span>
|
||||||
|
<span style="font-weight: bold;"> {{
|
||||||
|
dayjs(item.loginTime).format("YYYY-MM-DD HH:mm:ss") }}</span>
|
||||||
|
</div>
|
||||||
|
<div style="display: flex;">
|
||||||
|
<span>备用金:</span>
|
||||||
|
<span style="font-weight: bold;">{{ item.pettyCash }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="box_content_right">
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
上岗时间:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
2024-03-05-19:33
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
交班时间:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
2024-03-05-19:33
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
终端名称:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
POS-1
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
备用金:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
0.00
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiem">
|
|
||||||
<div class="box_content_right_tiemleft">
|
|
||||||
收营员:
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiemright">
|
|
||||||
测试
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box_content_right_tiembutton">
|
|
||||||
关班/退出
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
|
<!-- <div class="box_content_right">
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
上岗时间:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
2024-03-05-19:33
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
交班时间:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
2024-03-05-19:33
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
终端名称:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
POS-1
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
备用金:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
0.00
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiem">
|
||||||
|
<div class="box_content_right_tiemleft">
|
||||||
|
收营员:
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiemright">
|
||||||
|
测试
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="box_content_right_tiembutton">
|
||||||
|
关班/退出
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</el-drawer>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import { shopinfoqueryDutyFlow } from '@/api/work/index.js'
|
import { shopinfoqueryDutyFlow } from '@/api/work/index.js'
|
||||||
import { useUser } from "@/store/user.js"
|
import { useUser } from "@/store/user.js"
|
||||||
import { ElMessage, dayjs } from 'element-plus'
|
import { ElMessage, dayjs } from 'element-plus'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const store = useUser()
|
const store = useUser()
|
||||||
const record = ref(true)//交班记录
|
const record = ref(true)//交班记录
|
||||||
//详情数据
|
//详情数据
|
||||||
@@ -150,8 +152,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.box {
|
.box {
|
||||||
padding: 16px 0;
|
width: 100%;
|
||||||
height: 100%;
|
padding: 16px;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #efefef;
|
||||||
|
|
||||||
.box_top {
|
.box_top {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -160,7 +164,7 @@ onMounted(() => {
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
/* 取消下划线效果 */
|
/* 取消下划线效果 */
|
||||||
|
|
||||||
.box_top_left {
|
.box_top_left {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -214,20 +218,23 @@ onMounted(() => {
|
|||||||
|
|
||||||
.box_content_left_bouttom {
|
.box_content_left_bouttom {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 80%;
|
height: 85%;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
.box_content_left_bouttomox::after {
|
.box_content_left_bouttomox::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 32%;
|
width: 32%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box_content_left_bouttomox {
|
.box_content_left_bouttomox {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
.box_content_left_bouttom_item {
|
.box_content_left_bouttom_item {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
width: 32%;
|
width: 32%;
|
||||||
background: #eeeeee;
|
background: #eeeeee;
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (path) => path.replace(/^\/php/, ""),
|
rewrite: (path) => path.replace(/^\/php/, ""),
|
||||||
},
|
},
|
||||||
|
"/kp": {
|
||||||
|
target: env.VITE_API_KP_URL,
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: (path) => path.replace(/^\/kp/, ""),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
@@ -34,5 +39,8 @@ export default defineConfig(({ command, mode }) => {
|
|||||||
"@": path.resolve(__dirname, "./src"),
|
"@": path.resolve(__dirname, "./src"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
esbuild: {
|
||||||
|
drop: ["console"],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user