优化新增串口

This commit is contained in:
gyq 2024-03-07 18:29:19 +08:00
parent fc810fd02f
commit 58993e00ee
9 changed files with 186 additions and 188 deletions

View File

@ -1,8 +1,13 @@
"use strict"; "use strict";
const electron = require("electron");
const path = require("path"); const path = require("path");
const electron = require("electron");
const { SerialPort } = require("serialport");
SerialPort.list().then((res) => {
console.log(res);
});
let win;
electron.app.whenReady().then(() => { electron.app.whenReady().then(() => {
const win = new electron.BrowserWindow({ win = new electron.BrowserWindow({
title: "银收客", title: "银收客",
width: 1024, width: 1024,
height: 768, height: 768,
@ -46,15 +51,6 @@ electron.app.whenReady().then(() => {
electron.ipcMain.on("printerInfoSync", (event, params) => { electron.ipcMain.on("printerInfoSync", (event, params) => {
printWin.webContents.send("getParams", params); printWin.webContents.send("getParams", params);
}); });
electron.ipcMain.on("printStart", () => {
printWin.webContents.printToPDF({}, (error, data) => {
if (!error && data) {
console.log("成功生成PDF");
} else {
console.error("无法生成PDF", error);
}
});
});
}); });
electron.app.on("window-all-closed", () => { electron.app.on("window-all-closed", () => {
if (process.platform !== "darwin") if (process.platform !== "darwin")

View File

@ -1,8 +1,14 @@
import path from "path";
import { app, BrowserWindow, ipcMain } from "electron"; import { app, BrowserWindow, ipcMain } from "electron";
import path from 'path' const { SerialPort } = require("serialport");
SerialPort.list().then(res => {
console.log(res);
});
let win;
app.whenReady().then(() => { app.whenReady().then(() => {
const win = new BrowserWindow({ win = new BrowserWindow({
title: "银收客", title: "银收客",
width: 1024, width: 1024,
height: 768, height: 768,
@ -23,15 +29,15 @@ app.whenReady().then(() => {
// 使用vite开发服务的url路径访问应用 // 使用vite开发服务的url路径访问应用
// win.webContents.openDevTools(); // win.webContents.openDevTools();
} else { } else {
win.loadFile(path.resolve(__dirname, '../dist/index.html')); // 打包后使用文件路径访问应用 win.loadFile(path.resolve(__dirname, "../dist/index.html")); // 打包后使用文件路径访问应用
} }
app.on("activate", () => { app.on("activate", () => {
// 在 macOS 系统内, 如果没有已开启的应用窗口 // 在 macOS 系统内, 如果没有已开启的应用窗口
// 点击托盘图标时通常会重新创建一个新窗口 // 点击托盘图标时通常会重新创建一个新窗口
if (BrowserWindow.getAllWindows().length === 0) { if (BrowserWindow.getAllWindows().length === 0) {
createWindow() createWindow();
}; }
}); });
ipcMain.on("quitHandler", (_, msg) => { ipcMain.on("quitHandler", (_, msg) => {
@ -46,37 +52,28 @@ app.whenReady().then(() => {
// 集成网页和 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, params) => { ipcMain.on("printerInfoSync", (event, params) => {
// console.log(JSON.parse(params)) // console.log(JSON.parse(params))
printWin.webContents.send('getParams', params) printWin.webContents.send("getParams", params);
}) });
// 执行打印操作 // 执行打印操作
ipcMain.on('printStart', () => { // ipcMain.on('printStart', () => {
// console.log('开始打印') // console.log('开始打印')
// printWin.webContents.print({
printWin.webContents.printToPDF({}, (error, data) => { // silent: true
if (!error && data) { // })
console.log("成功生成PDF") // })
} else {
console.error("无法生成PDF", error)
}
})
// printWin.webContents.print({
// silent: true
// })
})
}); });
app.on("window-all-closed", () => { app.on("window-all-closed", () => {

View File

@ -1,69 +1,70 @@
{ {
"name": "vite-electron", "name": "vite-electron",
"private": true, "private": true,
"version": "0.0.1", "version": "0.0.2",
"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",
"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"
}, },
"dependencies": { "dependencies": {
"@element-plus/icons-vue": "^2.3.1", "@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.2", "axios": "^1.6.2",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"element-plus": "^2.4.3", "element-plus": "^2.4.3",
"html2canvas": "^1.4.1", "lodash": "^4.17.21",
"lodash": "^4.17.21", "pinia": "^2.1.7",
"pinia": "^2.1.7", "serialport": "^12.0.0",
"vue": "^3.3.8", "vue": "^3.3.8",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^4.5.0", "@vitejs/plugin-vue": "^4.5.0",
"electron": "^28.2.3", "electron": "^28.2.3",
"electron-builder": "^24.13.3", "electron-builder": "^24.13.3",
"path": "^0.12.7", "electron-rebuild": "^3.2.9",
"sass": "^1.69.5", "path": "^0.12.7",
"sass-loader": "^13.3.2", "sass": "^1.69.5",
"tree-kill": "^1.2.2", "sass-loader": "^13.3.2",
"vite": "^5.0.0", "tree-kill": "^1.2.2",
"vite-plugin-electron": "^0.15.4", "vite": "^5.0.0",
"vite-plugin-electron-renderer": "^0.14.5" "vite-plugin-electron": "^0.15.4",
}, "vite-plugin-electron-renderer": "^0.14.5"
"build": { },
"appId": "com.cashierdesktop.app", "build": {
"productName": "cashier_desktop", "appId": "com.cashierdesktop.app",
"asar": true, "productName": "cashier_desktop",
"files": [ "asar": true,
"./dist/**/*", "files": [
"./dist-electron/**/*" "./dist/**/*",
], "./dist-electron/**/*"
"directories": { ],
"buildResources": "build", "directories": {
"output": "release" "buildResources": "build",
}, "output": "release"
"win": { },
"icon": "./public/logo.ico", "win": {
"target": [ "icon": "./public/logo.ico",
{ "target": [
"target": "nsis", {
"arch": [ "target": "nsis",
"ia32" "arch": [
] "ia32"
} ]
] }
}, ]
"nsis": { },
"oneClick": false, "nsis": {
"allowElevation": true, "oneClick": false,
"allowToChangeInstallationDirectory": true, "allowElevation": true,
"installerIcon": "./public/logo.ico", "allowToChangeInstallationDirectory": true,
"uninstallerIcon": "./public/logo.ico", "installerIcon": "./public/logo.ico",
"installerHeaderIcon": "./public/logo.ico", "uninstallerIcon": "./public/logo.ico",
"createDesktopShortcut": true, "installerHeaderIcon": "./public/logo.ico",
"createStartMenuShortcut": true "createDesktopShortcut": true,
} "createStartMenuShortcut": true
} }
} }
}

View File

@ -49,34 +49,37 @@
<body> <body>
<div id="app"> <div id="app">
<div class="html2cavas" style="position: fixed; top: -1000%; left: 0"> <div class="html2cavas">
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<pre>{{data.shop_name || '结账单位'}}</pre>
<div class="header"> <div class="header">
<div class="t1">{{data.shop_name || '结账单位'}}</div>
<div class="t2">结账单</div> <div class="t2">结账单</div>
</div> </div>
<div class="time">开始时间: 2024/3/7 09:56:23</div> <div class="time">开始时间: 2024/3/7 09:56:23</div>
<div class="time">结束时间: 2024/3/8 13:11:07</div> <div class="time">结束时间: 2024/3/8 13:11:07</div>
<div class="thead"> <div class="thead">
<div class="item">品相</div> 品相 数量 单位 单价 小计 注
<div class="item">数量</div>
<div class="item">单位</div>
<div class="item">单价</div>
<div class="item">小计</div>
<div class="item"></div>
</div> </div>
<div class="tbody"> <div class="tbody">
<div v-for="item in data.carts" :key="item.id" class="tr"> <div v-for="item in data.carts" :key="item.id" class="tr">
<div class="item">{{item.name}}</div> {{item.name}} x{{item.number}} x{{item.number}} {{item.unitName}} {{item.salePrice}} {{item.salePrice}}
<div class="item">x{{item.number}}</div>
<div class="item">{{item.unitName}}</div>
<div class="item">{{item.salePrice}}</div>
<div class="item"></div>
<div class="item"></div>
</div> </div>
</div> </div>
<div>优惠信息</div> <div>优惠信息</div>
<div><br> </div>
<div>赠送优惠:{{data.amount}}</div> <div>赠送优惠:{{data.amount}}</div>
<div><br> </div>
<div>结算方式</div> <div>结算方式</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
</div> </div>
</div> </div>
<script type="module"> <script type="module">
@ -86,7 +89,6 @@
ref, ref,
onMounted, onMounted,
} from "../node_modules/vue/dist/vue.esm-browser.js"; } from "../node_modules/vue/dist/vue.esm-browser.js";
import html2canvas from "../node_modules/html2canvas/dist/html2canvas.esm.js";
createApp({ createApp({
setup() { setup() {
@ -94,16 +96,9 @@
onMounted(() => { onMounted(() => {
ipcRenderer.on("getParams", (event, arg) => { ipcRenderer.on("getParams", (event, arg) => {
console.log(arg); // console.log(arg);
data.value = JSON.parse(arg); data.value = JSON.parse(arg);
setTimeout(() => { ipcRenderer.send("printStart");
html2canvas(document.querySelector(".html2cavas")).then(
function (canvas) {
document.querySelector("#app").appendChild(canvas);
ipcRenderer.send("printStart");
}
);
}, 1000);
}); });
}); });

View File

@ -180,12 +180,12 @@ const menus = ref([
} }
&.more { &.more {
margin-top: 50px; margin-top: 200px;
} }
.icon { .icon {
color: #999; color: #999;
font-size: 26px; font-size: 22px;
margin-bottom: 4px; margin-bottom: 4px;
} }

View File

@ -125,9 +125,9 @@ async function confirmOrder() {
default: default:
break; break;
} }
payLoading.value = false
ElMessage.success('支付成功') ElMessage.success('支付成功')
emit('paySuccess') emit('paySuccess')
payLoading.value = false
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error)

View File

@ -1,51 +1,53 @@
<!-- 扫码弹窗 --> <!-- 扫码弹窗 -->
<template> <template>
<el-dialog title="扫码支付" width="800" v-model="dialogVisible" @open="reset"> <div class="dialog">
<div class="content"> <el-dialog title="扫码支付" width="600" v-model="dialogVisible" @open="reset">
<div class="left"> <div class="content">
<el-image :src="icon"></el-image> <div class="left">
</div> <el-image :src="icon" style="width: 60px;height: 60px;"></el-image>
<div class="right" v-if="!userPayWait">
<div class="amount">
<span class="t">扫码支付</span>
<span class="n">{{ props.amount }}</span>
</div> </div>
<div class="input"> <div class="right" v-if="!userPayWait">
<el-input ref="inputRef" v-model="scanCode" <div class="amount">
style="height: calc(var(--el-component-size-large) + 20px);" placeholder="请扫描付款码" <span class="t">扫码支付</span>
@keydown.enter="enterHandle" clearable></el-input> <span class="n">{{ props.amount }}</span>
</div> </div>
<div class="number_warp"> <div class="input">
<div class="item" v-for="item in 9" :key="item" @click="inputHandle(item)">{{ item }}</div> <el-input ref="inputRef" v-model="scanCode"
<div class="item disabled">.</div> style="height: calc(var(--el-component-size-large) + 20px);" placeholder="请扫描付款码"
<div class="item" @click="inputHandle(0)">0</div> @keydown.enter="enterHandle" clearable></el-input>
<div class="item" @click="delHandle"> </div>
<el-icon> <div class="number_warp">
<CloseBold /> <div class="item" v-for="item in 9" :key="item" @click="inputHandle(item)">{{ item }}</div>
</el-icon> <div class="item disabled">.</div>
<div class="item" @click="inputHandle(0)">0</div>
<div class="item" @click="delHandle">
<el-icon>
<CloseBold />
</el-icon>
</div>
</div>
<div class="btn">
<el-button type="primary" style="width: 100%;" v-loading="loading"
@click="submitHandle">立即支付</el-button>
</div> </div>
</div> </div>
<div class="btn"> <div class="pay_wait" v-else>
<el-button type="primary" style="width: 100%;" v-loading="loading" <div class="loading" v-loading="loading" element-loading-text="用户支付中..."></div>
@click="submitHandle">立即支付</el-button> <div class="btn">
<el-button type="primary" style="width: 100%;" v-loading="checkPayStatusLoading"
@click="checkPayStauts">
<span v-if="!checkPayStatusLoading">查询用户支付状态</span>
<span v-else>查询中...</span>
</el-button>
</div>
<div class="btn">
<el-button style="width: 100%;" @click="resetScanCode">重新扫码</el-button>
</div>
</div> </div>
</div> </div>
<div class="pay_wait" v-else> </el-dialog>
<div class="loading" v-loading="loading" element-loading-text="用户支付中..."></div> </div>
<div class="btn">
<el-button type="primary" style="width: 100%;" v-loading="checkPayStatusLoading"
@click="checkPayStauts">
<span v-if="!checkPayStatusLoading">查询用户支付状态</span>
<span v-else>查询中...</span>
</el-button>
</div>
<div class="btn">
<el-button style="width: 100%;" @click="resetScanCode">重新扫码</el-button>
</div>
</div>
</div>
</el-dialog>
</template> </template>
<script setup> <script setup>
@ -86,11 +88,14 @@ async function submitHandle() {
orderId: props.orderId, orderId: props.orderId,
authCode: scanCode.value authCode: scanCode.value
}) })
loading.value = false
scanCode.value = ''
emits('success') emits('success')
} catch (error) { } catch (error) {
if (error.code === '100015') { if (error.code === '100015') {
userPayWait.value = true userPayWait.value = true
} else { } else {
loading.value = false
console.log(error) console.log(error)
} }
} }
@ -168,7 +173,7 @@ defineExpose({
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-dialog__body) { .dialog :deep(.el-dialog__body) {
padding: 0 !important; padding: 0 !important;
} }
@ -176,7 +181,7 @@ defineExpose({
display: flex; display: flex;
.left { .left {
width: 300px; width: 200px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -185,7 +190,7 @@ defineExpose({
.right { .right {
flex: 1; flex: 1;
padding: 0 var(--el-font-size-base); padding: var(--el-font-size-base);
.amount { .amount {
display: flex; display: flex;
@ -209,11 +214,11 @@ defineExpose({
} }
.number_warp { .number_warp {
--h: 40px; --h: 50px;
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: var(--h) var(--h) var(--h) var(--h); grid-template-rows: var(--h) var(--h) var(--h) var(--h);
gap: var(--el-font-size-base); gap: 8px;
.item { .item {
background-color: #dddddd; background-color: #dddddd;

View File

@ -1,5 +1,5 @@
<template> <template>
<el-dialog :title="goods.name" width="800" v-model="dialogVisible"> <el-dialog :title="goods.name" width="500" v-model="dialogVisible">
<div class="header">选择规格</div> <div class="header">选择规格</div>
<div v-loading="loading"> <div v-loading="loading">
<div class="row" v-for="(item, index) in goods.tbProductSpec.specList" :key="index"> <div class="row" v-for="(item, index) in goods.tbProductSpec.specList" :key="index">
@ -147,8 +147,9 @@ function show(item, t = 'shop') {
break; break;
case 'cart': case 'cart':
// //
const skus = goods.value.skuName.split(',')
arr.push({ arr.push({
active: goods.value.skuName.includes(val), active: !!skus.find(item => item === val),
name: val name: val
}) })
break; break;

View File

@ -293,11 +293,14 @@ async function queryCartAjax() {
// //
async function createCodeAjax() { async function createCodeAjax() {
try { try {
const res = await createCode({ if (process.env.VITE_DEV_SERVER_URL) {
shopId: store.userInfo.shopId masterId.value = '#8'
}) } else {
masterId.value = res.code const res = await createCode({
// masterId.value = '#8' shopId: store.userInfo.shopId
})
masterId.value = res.code
}
queryCartAjax() queryCartAjax()
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -430,10 +433,10 @@ onMounted(() => {
align-items: center; align-items: center;
.icon_item { .icon_item {
$size: 40px; $size: 30px;
width: $size; width: $size;
height: $size; height: $size;
border-radius: 6px; border-radius: 4px;
background-color: #e2e2e2; background-color: #e2e2e2;
display: flex; display: flex;
align-items: center; align-items: center;
@ -460,8 +463,8 @@ onMounted(() => {
align-items: center; align-items: center;
.selected { .selected {
width: 20px; width: 16px;
height: 20px; height: 16px;
display: flex; display: flex;
align-items: center; align-items: center;
position: relative; position: relative;