This commit is contained in:
gyq 2024-03-11 14:34:17 +08:00
parent 11290d1505
commit 0fbc614c61
13 changed files with 156 additions and 217 deletions

View File

@ -3,4 +3,4 @@ ENV = development
# 本地环境接口地址
# VITE_API_URL = 'http://192.168.2.87:10587/cashier-client'
VITE_API_URL = 'https://cashierclient.sxczgkj.cn/cashier-client'
VITE_API_URL = 'https://cashiernew.sxczgkj.cn/cashier-client'

View File

@ -19,6 +19,7 @@ electron.app.whenReady().then(() => {
});
if (process.env.VITE_DEV_SERVER_URL) {
win.loadURL(process.env.VITE_DEV_SERVER_URL);
win.webContents.openDevTools();
} else {
win.loadFile(path.resolve(__dirname, "../dist/index.html"));
}
@ -30,24 +31,7 @@ electron.app.whenReady().then(() => {
electron.ipcMain.on("quitHandler", (_, msg) => {
electron.app.quit();
});
const printWin = new electron.BrowserWindow({
show: false,
webPreferences: {
// 集成网页和 Node.js也就是在渲染进程中可以调用 Node.js 方法
nodeIntegration: true,
contextIsolation: false
}
});
if (process.env.VITE_DEV_SERVER_URL) {
printWin.loadFile(path.join(__dirname, "../public/print.html"));
} else {
printWin.loadFile(path.resolve(__dirname, "../dist/print.html"));
}
electron.ipcMain.on("printerInfoSync", (event, params) => {
printWin.webContents.send("getParams", params);
});
electron.ipcMain.on("printStart", () => {
console.log("开始打印");
electron.ipcMain.on("printStart", (event, arg) => {
});
});
electron.app.on("window-all-closed", () => {

View File

@ -22,7 +22,7 @@ app.whenReady().then(() => {
if (process.env.VITE_DEV_SERVER_URL) {
win.loadURL(process.env.VITE_DEV_SERVER_URL);
// 使用vite开发服务的url路径访问应用
// win.webContents.openDevTools();
win.webContents.openDevTools();
} else {
win.loadFile(path.resolve(__dirname, "../dist/index.html")); // 打包后使用文件路径访问应用
}
@ -40,36 +40,37 @@ app.whenReady().then(() => {
});
// 创建打印小票子窗口
const printWin = new BrowserWindow({
show: false,
webPreferences: {
// 集成网页和 Node.js也就是在渲染进程中可以调用 Node.js 方法
nodeIntegration: true,
contextIsolation: false,
},
});
// const printWin = new BrowserWindow({
// show: false,
// webPreferences: {
// // 集成网页和 Node.js也就是在渲染进程中可以调用 Node.js 方法
// nodeIntegration: true,
// contextIsolation: false,
// },
// });
if (process.env.VITE_DEV_SERVER_URL) {
// 加载打印的html文件
printWin.loadFile(path.join(__dirname, "../public/print.html"));
} else {
printWin.loadFile(path.resolve(__dirname, "../dist/print.html")); // 打包后使用文件路径访问应用
}
// if (process.env.VITE_DEV_SERVER_URL) {
// // 加载打印的html文件
// printWin.loadFile(path.join(__dirname, "../public/print.html"));
// } else {
// printWin.loadFile(path.resolve(__dirname, "../dist/print.html")); // 打包后使用文件路径访问应用
// }
// win.webContents.getPrintersAsync().then(res => {
// console.log('list', res)
// // console.log('list', res)
// })
ipcMain.on("printerInfoSync", (event, params) => {
// console.log(JSON.parse(params))
printWin.webContents.send("getParams", params);
});
// ipcMain.on("printerInfoSync", (event, params) => {
// // console.log(JSON.parse(params))
// printWin.webContents.send("getParams", params);
// });
// 执行打印操作
ipcMain.on('printStart', () => {
console.log('开始打印')
ipcMain.on('printStart', (event, arg) => {
// console.log('开始打印', arg)
let name = 'RONGTA 80mm Series Printer'
// let name = 'Xprinter XP-365B'
// // let name = 'Generic / Text Only'
// printWin.webContents.print({
// silent: true,

View File

@ -1,7 +1,7 @@
{
"name": "vite-electron",
"private": true,
"version": "0.0.5",
"version": "0.0.7",
"main": "dist-electron/main.js",
"scripts": {
"dev": "chcp 65001 && vite",
@ -13,7 +13,8 @@
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.2",
"dayjs": "^1.11.10",
"electron-pos-printer": "^1.3.7",
"electron-pos-printer": "^1.3.6",
"electron-pos-printer-vue": "^1.0.9",
"element-plus": "^2.4.3",
"lodash": "^4.17.21",
"pinia": "^2.1.7",

View File

@ -7,114 +7,58 @@
<meta charset="UTF-8" />
<title>Print preview</title>
<style>
#app {
padding: 30px;
}
.header {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-bottom: 30px;
}
.t1 {
section {
font-size: 24px;
font-weight: bold;
}
.t2 {
font-size: 18px;
}
.time {
padding-bottom: 10px;
}
.thead {
display: flex;
}
.thead .item {
flex: 1;
font-weight: bold;
}
.tbody .tr {
padding: 10px 0;
display: flex;
}
.tbody .tr .item {
flex: 1;
}
.html2cavas {
width: 100%;
}
</style>
</head>
<body>
<div id="app">
<div class="html2cavas">
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<ESC> "@"
<ESC> "|cA" "Sample Text" <LF>
<ESC> "|cA" "Price: $10.00" <LF>
<ESC> "|cA" "Thank you!" <LF>
<ESC> "d" "n" <LF>
<pre style="text-align: center">{{data.shop_name || '结账单位'}}</pre>
<div class="header">
<div class="t2">结账单</div>
</div>
<div class="time">开始时间: 2024/3/7 09:56:23</div>
<div class="time">结束时间: 2024/3/8 13:11:07</div>
<div class="thead">品相 数量 单位 单价 小计 注</div>
<div class="tbody">
<div v-for="item in data.carts" :key="item.id" class="tr">
{{item.name}} x{{item.number}} x{{item.number}} {{item.unitName}}
{{item.salePrice}} {{item.salePrice}}
</div>
</div>
<div>优惠信息</div>
<div><br /></div>
<div>赠送优惠:{{data.amount}}</div>
<div><br /></div>
<div>结算方式</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div>---------------</div>
<div class="html2canvas" style="position: fixed;top: -1000%;">
<section style="font-size: 22px;">#B1 B2</section>
<section style="font-size: 22px;">喔喔奶茶 x12</section>
<section style="font-size: 22px;">麻辣味</section></section></section>
<section style="font-size: 22px;">03-08 16:32 ¥123.00</section>
</div>
<!-- <section>我是标签111</section>
<section>我是标签222</section>
<section>我是标签333</section>
<section>我是标签444</section> -->
</div>
<script type="module">
const { ipcRenderer } = require("electron");
import {
createApp,
ref,
onMounted,
} from "../node_modules/vue/dist/vue.esm-browser.js";
// import {
// createApp,
// ref,
// onMounted,
// } from "../node_modules/vue/dist/vue.esm-browser.js";
createApp({
setup() {
const data = ref({});
import html2canvas from '../node_modules/html2canvas/dist/html2canvas.esm.js'
onMounted(() => {
ipcRenderer.on("getParams", (event, arg) => {
// console.log(arg);
data.value = JSON.parse(arg);
ipcRenderer.send("printStart");
});
});
html2canvas(document.querySelector('.html2canvas')).then(canvas => {
console.log(canvas)
document.querySelector('#app').appendChild(canvas)
}).catch(err=> {
console.log(err);
})
return {
data,
};
},
}).mount("#app");
// createApp({
// setup() {
// const data = ref({});
// onMounted(() => {
// ipcRenderer.on("getParams", (event, arg) => {
// // console.log(arg);
// data.value = JSON.parse(arg);
// setTimeout(() => {
// ipcRenderer.send("printStart");
// },500)
// });
// });
// return {
// data,
// };
// },
// }).mount("#app");
</script>
</body>
</html>

View File

@ -5,28 +5,36 @@
<left-menu />
</div>
<div :class="{ view: route.path != '/login' }">
<router-view />
<!-- <div class="wrapper">
<div class="wrapper">
<div class="animation">
<router-view v-slot="{ Component }">
<transition :name="transitionName">
<!-- <transition :name="transitionName"> -->
<keep-alive :include="includeList">
<component :is="Component"></component>
</transition>
</keep-alive>
<!-- </transition> -->
</router-view>
</div>
</div> -->
</div>
</div>
</div>
</el-config-provider>
</template>
<script setup>
import { ref } from "vue";
import { ref, reactive, watch } from "vue";
import { useRouter, useRoute } from "vue-router"
import leftMenu from '@/components/leftMenu.vue'
const route = useRoute()
const includeList = reactive([]);
watch(route, (to) => {
if (to.meta.keepAlive) {
includeList.push(to.name);
}
});
let transitionName = ref();
let router = useRouter();
router.beforeEach((to, from) => {

View File

@ -1,14 +1,14 @@
<template>
<el-dialog :title="goods.name" width="500" v-model="dialogVisible">
<el-dialog :title="goods.name" width="600" v-model="dialogVisible">
<div class="header">选择规格</div>
<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.selectSpec" :key="index">
<div class="title">{{ item.name }}</div>
<div class="sku_wrap">
<!-- <div class="item" :class="{ active: val.active }" v-for="(val, i) in item.value" :key="i"
@click="selectedSku(index, i)">{{ val.name }}</div> -->
<el-button :plain="!val.active" type="primary" v-for="(val, i) in item.value" :key="i"
@click="selectedSku(index, i)">{{ val.name }}</el-button>
<el-button :plain="!val.active" type="primary" v-for="(val, i) in item.selectSpecResult
" :key="i" @click="selectedSku(index, i)" class="btn">{{ val.name }}</el-button>
</div>
</div>
</div>
@ -68,14 +68,14 @@ function submitSku() {
//
function selectedSku(index, i) {
goods.value.tbProductSpec.specList[index].value.map(item => {
goods.value.selectSpec[index].selectSpecResult.map(item => {
item.active = false
})
if (goods.value.tbProductSpec.specList[index].value[i].active) {
goods.value.tbProductSpec.specList[index].value[i].active = false
if (goods.value.selectSpec[index].selectSpecResult[i].active) {
goods.value.selectSpec[index].selectSpecResult[i].active = false
selectedSkuNum.value--
} else {
goods.value.tbProductSpec.specList[index].value[i].active = true
goods.value.selectSpec[index].selectSpecResult[i].active = true
selectedSkuNum.value++
}
selectedSuccess()
@ -85,8 +85,8 @@ function selectedSku(index, i) {
function selectedSuccess() {
let num = 0
let tag = []
goods.value.tbProductSpec.specList.map(item => {
item.value.map(val => {
goods.value.selectSpec.map(item => {
item.selectSpecResult.map(val => {
if (val.active) {
num++
tag.push(val.name)
@ -96,7 +96,7 @@ function selectedSuccess() {
selectedSkuTag.value = tag.join(',')
})
if (selectedSkuNum.value >= goods.value.tbProductSpec.specList.length) {
if (selectedSkuNum.value >= goods.value.selectSpec.length) {
//
queryProductSkuAjax()
}
@ -133,34 +133,33 @@ function show(item, t = 'shop') {
goods.value = ""
goods.value = item
type.value = t
if (typeof goods.value.tbProductSpec.specList == 'string') {
goods.value.tbProductSpec.specList = JSON.parse(goods.value.tbProductSpec.specList)
goods.value.tbProductSpec.specList.map(item => {
let arr = []
item.value.map(val => {
switch (type.value) {
case 'shop':
arr.push({
active: false,
name: val
})
break;
case 'cart':
//
const skus = goods.value.skuName.split(',')
arr.push({
active: !!skus.find(item => item === val),
name: val
})
break;
goods.value.selectSpec = JSON.parse(goods.value.selectSpec)
goods.value.selectSpec.map(item => {
let arr = []
item.selectSpecResult.map(val => {
switch (type.value) {
case 'shop':
arr.push({
active: false,
name: val
})
break;
case 'cart':
//
const skus = goods.value.skuName.split(',')
arr.push({
active: !!skus.find(item => item === val),
name: val
})
break;
default:
break;
}
})
item.value = arr
default:
break;
}
})
}
item.selectSpecResult = arr
})
console.log(goods.value)
selectedSuccess()
}
@ -185,7 +184,9 @@ defineExpose({
.sku_wrap {
display: flex;
padding: 14px 0;
padding: var(--el-font-size-base) 0;
flex-wrap: wrap;
gap: var(--el-font-size-base);
}
}

View File

@ -6,6 +6,9 @@ const routes = [
{
path: "/",
name: "home",
meta: {
keepAlive: true
},
component: home,
},
{

View File

@ -125,11 +125,11 @@ function skuConfirm(e) {
padding: 10px;
display: flex;
flex-direction: column;
gap: 14px;
gap: 16px;
.item {
width: 70px;
height: 30px;
height: 34px;
display: flex;
align-items: center;
justify-content: center;

View File

@ -39,8 +39,7 @@
<div class="item">
<div class="dot" v-if="item.orderCount">{{ item.orderCount }}</div>
<div class="cover" v-if="shopListType == 'img'">
<el-image :src="item.coverImg" style="width: 100%;height: 100%;background-color: #efefef;"
fit="contain"></el-image>
<el-image :src="item.coverImg" class="el_img" fit="cover"></el-image>
</div>
<div class="name"><el-text line-clamp="2">{{ item.name }}</el-text></div>
<div class="item_empty" v-if="shopListType == 'text'"></div>
@ -330,7 +329,17 @@ defineExpose({
.cover {
width: 100%;
height: 80px;
padding-bottom: 100%;
position: relative;
.el_img {
width: 100%;
height: 100%;
background-color: #efefef;
position: absolute;
top: 0;
left: 0;
}
}
.name {

View File

@ -104,6 +104,11 @@
<pendingCartModal ref="pendingCartModalRef" @select="pendingCartHandle" />
</template>
<script>
export default {
name: 'home'
}
</script>
<script setup>
import { onMounted, ref } from 'vue'
import { useUser } from "@/store/user.js"

View File

@ -1,37 +1,20 @@
<template>
<el-button @click="chooseSerial">选择扫码枪串口</el-button>
<el-input ref="inputRef" v-model="printValue" @keyup.enter="enterHandle" @input="inputHandle"></el-input>
<el-button @click="chooseSerial">打印</el-button>
</template>
<script setup>
import _ from 'lodash'
import { ref, onMounted } from 'vue';
const inputRef = ref(null)
const printValue = ref('')
function enterHandle() {
console.log('回车了')
}
const inputHandle = _.debounce(function (e) {
console.log('扫码枪输入完了', e)
}, 100)
import { ipcRenderer } from 'electron'
//
const chooseSerial = async () => {
if ('serial' in navigator) {
// await port.close();
console.log('当前浏览器支持serial')
const port = await navigator.serial.requestPort()
await port.open({ baudRate: 9600 })
let printNum = localStorage.getItem('printNum')
if (!printNum) {
printNum = 1
localStorage.setItem('printNum', printNum)
} else {
printNum++
localStorage.setItem('printNum', printNum)
}
ipcRenderer.send('printStart', printNum)
};
onMounted(() => {
setTimeout(() => {
inputRef.value.focus()
}, 1000)
})
</script>

View File

@ -72,9 +72,9 @@ const loading = ref(false);
const form = reactive({
serialNumber: RandomNumBoth(1000, 9999),
clientType: 'pc',
merchantName: '18821670757',
loginName: "18821670757",
password: "123456",
merchantName: '',
loginName: "",
password: "",
});
const rules = reactive({