小票打印机

This commit is contained in:
jjLv 2025-09-11 14:48:13 +08:00
parent 854c120920
commit 36aef6744f
3 changed files with 1137 additions and 744 deletions

192
src/utils/printer/Common.js Normal file
View File

@ -0,0 +1,192 @@
var port = 18080;
var connectionMode = "ws:";
var wsPrint = null;
let wsGetPrinterList = null;
var CHUNK_SIZE = 1024 * 64;
const WebSocketPrint = function (serverURL, strPrinterName, request, callback) {
var _websocket;
var _callback = callback;
var _request = request;
var _connectedsocket = false;
var onMessage = function (msg) {
if (_websocket.readyState == 1) {
var res = JSON.parse(msg.data);
var ret = res.statusMessage;
var printerStatus;
if (res.printerStatus !== undefined) {
printerStatus = res.printerStatus.message;
ret += ":" + printerStatus;
}
_callback(res);
} else {
_callback(msg.data);
}
};
var onClose = function (msg) {
if (!_connectedsocket) {
_callback("Cannot connect to server");
}
_websocket.close();
_connectedsocket = false;
wsPrint = null;
};
var webSocketInit = function (uri) {
_websocket = new WebSocket(uri);
_websocket.binaryType = "arraybuffer";
_websocket.onopen = function (event) {
console.log("open : " + uri);
};
_websocket.onerror = function (event) {
wsPrint = null;
if (_websocket.readyState == 3) {
_callback("Cannot connect to server");
}
};
_websocket.onmessage = function (msg) {
onMessage(msg);
};
_websocket.onclose = function (msg) {
onClose(msg);
};
};
webSocketInit(serverURL + strPrinterName + _request);
this.send = function (data) {
const sendData = () => {
for (let i = 0; i < data.length; i += CHUNK_SIZE) {
const chunk = data.slice(i, i + CHUNK_SIZE);
_websocket.send(chunk);
}
};
if (_websocket.readyState === WebSocket.OPEN) {
sendData();
} else if (_websocket.readyState === WebSocket.CONNECTING) {
const originalOnOpen = _websocket.onopen;
_websocket.onopen = function(event) {
if (originalOnOpen) originalOnOpen(event);
sendData();
_connectedsocket = true;
};
}
};
this.disconnect = function () {
if (_websocket && _websocket.readyState === WebSocket.OPEN) {
console.log("Closing WebSocket connection...");
_websocket.close();
}
};
};
const WebSocketGetPrinterList = function (serverURL, callback) {
var _websocket;
var _callback = callback;
var _connectedsocket = false;
var onMessage = function (msg) {
if (_websocket.readyState == 1) {
var res = JSON.parse(msg.data);
_callback(res);
} else {
a;
_callback(msg.data);
}
};
var onClose = function (msg) {
if (!_connectedsocket) {
_callback("Cannot connect to server");
}
_websocket.close();
_connectedsocket = false;
wsGetPrinterList = null;
};
var webSocketInit = function (uri) {
_websocket = new WebSocket(uri);
_websocket.onopen = function (event) {
console.log("open : " + uri);
};
_websocket.onerror = function (event) {
wsGetPrinterList = null;
if (_websocket.readyState == 3) {
_callback("Cannot connect to server");
}
};
_websocket.onmessage = function (msg) {
onMessage(msg);
};
_websocket.onclose = function (msg) {
console.log("WebSocket connection closed");
onClose(msg);
};
};
webSocketInit(serverURL);
this.send = function (strSubmit) {
if (_websocket.readyState == 1) {
_websocket.send(strSubmit);
} else {
_websocket.onopen = function () {
if (_websocket.readyState == 1) {
_websocket.send(strSubmit);
_connectedsocket = true;
}
};
}
};
};
function setPort(serverPort) {
port = serverPort;
}
function getServerURL() {
var localAddress = `//127.0.0.1:${port}/WebSDK/`;
var serverURL = connectionMode + localAddress;
return {
url: serverURL,
};
}
function setConnectionMode(mode) {
connectionMode = mode;
}
function requestPrint(strPrinterName, strSubmit, _callback) {
_callback("");
var serverURL = getServerURL().url;
console.log(serverURL);
if (wsPrint == null)
wsPrint = new WebSocketPrint(serverURL, strPrinterName, "", _callback);
const encoder = new TextEncoder();
const bytesSubmit = encoder.encode(strSubmit);
wsPrint.send(bytesSubmit);
}
function getPrinterList(category, _callback) {
var serverURL = getServerURL().url + "getPrinterList";
if (wsGetPrinterList == null) {
wsGetPrinterList = new WebSocketGetPrinterList(serverURL, _callback);
}
wsGetPrinterList.send(JSON.stringify(category));
}
export {
setPort,
getServerURL,
setConnectionMode,
requestPrint,
getPrinterList,
wsPrint,
WebSocketPrint,
WebSocketGetPrinterList
}

File diff suppressed because one or more lines are too long

View File

@ -11,17 +11,24 @@
start-placeholder="开始日期"
end-placeholder="结束日期"
format="yyyy-MM-dd" style="width: 220px"
:picker-options="pickerOptions" >
:picker-options="pickerOptions"
>
</el-date-picker>
</el-form-item>
<el-form-item label="关键字">
<el-input v-model="queryParams.custSearchInfo" placeholder="请输入用户姓名,编号,手机号" maxlength="20" clearable style="width: 220px"/>
<el-input v-model="queryParams.custSearchInfo" placeholder="请输入用户姓名,编号,手机号" maxlength="20" clearable
style="width: 220px"
/>
</el-form-item>
<el-form-item label="订单号">
<el-input v-model.number="queryParams.orderId" placeholder="请输入订单号" maxlength="20" clearable style="width: 220px" @input="(v)=>(queryParams.orderId=v.replace(/[^\d]/g,''))"/>
<el-input v-model.number="queryParams.orderId" placeholder="请输入订单号" maxlength="20" clearable
style="width: 220px" @input="(v)=>(queryParams.orderId=v.replace(/[^\d]/g,''))"
/>
</el-form-item>
<el-form-item label="菜品名称">
<el-input v-model="queryParams.goodsSearchInfo" placeholder="请输入菜品名称" maxlength="20" clearable style="width: 220px"/>
<el-input v-model="queryParams.goodsSearchInfo" placeholder="请输入菜品名称" maxlength="20" clearable
style="width: 220px"
/>
</el-form-item>
<el-form-item label="餐次">
<el-select v-model="queryParams.mealtimeTypeList" multiple style="width: 220px" clearable collapse-tags>
@ -39,11 +46,14 @@
emitPath: false,// falseid
checkStrictly: false,//
value:'id',label:'label'
}" clearable collapse-tags @change="handleAreaChange">
}" clearable collapse-tags @change="handleAreaChange"
>
</el-cascader>
</el-form-item>
<el-form-item label="所属食堂" prop="canteenId">
<el-select v-model="queryParams.canteenId" clearable collapse-tags placeholder="请选择所属食堂" style="width: 220px" @change="handleCanteenChange">
<el-select v-model="queryParams.canteenId" clearable collapse-tags placeholder="请选择所属食堂"
style="width: 220px" @change="handleCanteenChange"
>
<el-option v-for="item in canteenOptions"
:key="item.canteenId"
:label="item.canteenName"
@ -52,7 +62,9 @@
</el-select>
</el-form-item>
<el-form-item label="所属档口" prop="stallId">
<el-select v-model="queryParams.stallId" clearable collapse-tags placeholder="请选择所属档口" style="width: 220px" >
<el-select v-model="queryParams.stallId" clearable collapse-tags placeholder="请选择所属档口"
style="width: 220px"
>
<el-option v-for="item in stallOptions"
:key="item.stallId"
:label="item.stallName"
@ -61,7 +73,9 @@
</el-select>
</el-form-item>
<el-form-item label="订单状态">
<el-select v-model="queryParams.orderStateList" clearable multiple collapse-tags style="width: 220px">
<el-select v-model="queryParams.orderStateList" clearable multiple collapse-tags style="width: 220px"
@change="changePrint"
>
<el-option
v-for="dict in dict.type.sm_order_status"
:key="dict.value"
@ -98,9 +112,20 @@
emitPath: false,// falseid
checkStrictly: false,//
value:'id',label:'label'
}" clearable collapse-tags >
}" clearable collapse-tags
>
</el-cascader>
</el-form-item>
<!-- <el-form-item label="小票打印机" prop="deptIdList">-->
<!-- <el-select v-model="printerName" clearable collapse-tags style="width: 220px">-->
<!-- <el-option-->
<!-- v-for="item in printList"-->
<!-- :key="item.value"-->
<!-- :label="item.name"-->
<!-- :value="item.value"-->
<!-- />-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<el-form-item>
@ -115,14 +140,25 @@
type="primary"
size="mini" :disabled="multiple"
@click="handleBatchWriteOff"
>批量核销</el-button>
>批量核销
</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="primary"
size="mini" :disabled="multiple"
@click="handleBatchRefund"
>批量退单</el-button>
>批量退单
</el-button>
</el-col>
<el-col :span="1.5" style="display: flex">
<el-button
type="primary"
size="mini" :disabled="multiple"
@click="handleBatchPrint"
style="margin-left: 5px;"
>批量打印小票
</el-button>
</el-col>
<!--
@ -136,7 +172,9 @@
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="tableListData" height="800" ref="multipleTable" :row-key="(row)=>{return row.orderId}" @selection-change="handleOrderSelectionChange">
<el-table v-loading="loading" :data="tableListData" height="800" ref="multipleTable"
:row-key="(row)=>{return row.orderId}" @selection-change="handleOrderSelectionChange"
>
<el-table-column type="selection" width="50" align="center" :reserve-selection="true"/>
<el-table-column label="序号" align="center" width="80" type="index" fixed="left">
<template slot-scope="scope">
@ -152,7 +190,9 @@
<el-table-column label="餐次" align="center" prop="mealtimeName" :show-overflow-tooltip="true" width="80"/>
<el-table-column label="菜品明细" align="center" prop="orderDetailList" :show-overflow-tooltip="true" width="120">
<template slot-scope="scope">
<span v-for="item in scope.row.orderDetailList" :key="item.detailId">{{ item.goodsName }}*{{ item.quantity }};</span>
<span v-for="item in scope.row.orderDetailList" :key="item.detailId">{{ item.goodsName }}*{{
item.quantity
}};</span>
</template>
</el-table-column>
<el-table-column label="订单金额" align="center" prop="payableAmount" :show-overflow-tooltip="true" width="80">
@ -198,27 +238,32 @@
size="mini"
type="text"
@click="handleView(scope.row)"
>详情</el-button>
>详情
</el-button>
<el-button
size="mini"
type="text" v-if="scope.row.orderState==1||scope.row.orderState==2||scope.row.orderState==5"
@click="handleRefundPart(scope.row)"
>部分退款</el-button>
>部分退款
</el-button>
<el-button
size="mini"
type="text" v-if="scope.row.orderState==1||scope.row.orderState==2||scope.row.orderState==4"
@click="handleRefund(scope.row)"
>退单</el-button>
>退单
</el-button>
<el-button
size="mini"
type="text" v-if="scope.row.orderState==1"
@click="writeOffOrder(scope.row)"
>核销</el-button>
>核销
</el-button>
<el-button
size="mini"
type="text" v-if="scope.row.commentState==1"
@click="checkEvaluate(scope.row)"
>评价</el-button>
>评价
</el-button>
</template>
</el-table-column>
</el-table>
@ -386,7 +431,9 @@
</el-col>
</el-row> -->
<el-table :data="orderDetailList" ref="multiplePartTable" @selection-change="handleSelectionChange" :row-key="(row)=>{return row.detailId}" v-if="refundType==1">
<el-table :data="orderDetailList" ref="multiplePartTable" @selection-change="handleSelectionChange"
:row-key="(row)=>{return row.detailId}" v-if="refundType==1"
>
<el-table-column type="selection" width="50" align="center" :selectable="selectable"/>
<el-table-column label="菜品名称" align="center" prop="goodsName" :show-overflow-tooltip="true"/>
<el-table-column label="菜品单价" align="center" prop="salePrice" :show-overflow-tooltip="true">
@ -410,7 +457,10 @@
<el-table-column label="退款数量" align="center" prop="goRefundNum" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-input v-model="scope.row.goRefundNum" placeholder="退款数量" maxlength="20" clearable style="width: 100%" @change="inputNum(scope.row)" @input="(v)=>(scope.row.goRefundNum=v.replace(/[^\d]/g,''))"/>
<el-input v-model="scope.row.goRefundNum" placeholder="退款数量" maxlength="20" clearable
style="width: 100%" @change="inputNum(scope.row)"
@input="(v)=>(scope.row.goRefundNum=v.replace(/[^\d]/g,''))"
/>
</template>
</el-table-column>
<el-table-column label="退款金额" align="center" prop="refundMoney" :show-overflow-tooltip="true">
@ -434,7 +484,10 @@
<span>{{ (rowData.refundAmount / 100).toFixed(2) }}</span>
</el-form-item>
<el-form-item label="本次退款金额:" prop="refundMoney">
<el-input v-model="rowData.refundMoney" placeholder="请输入本次退款金额" maxlength="20" clearable @input="(v)=>(rowData.refundMoney=v.replace(/[^\d.]/g, '').replace(/^(\d*\.\d{2}).*$/, '$1'))" style="width: 200px;"/>
<el-input v-model="rowData.refundMoney" placeholder="请输入本次退款金额" maxlength="20" clearable
@input="(v)=>(rowData.refundMoney=v.replace(/[^\d.]/g, '').replace(/^(\d*\.\d{2}).*$/, '$1'))"
style="width: 200px;"
/>
</el-form-item>
</el-form>
</div>
@ -446,19 +499,28 @@
<!-- 评价弹窗 -->
<el-dialog title="订单评价" :visible.sync="openEva" width="500px" append-to-body>
<div style="width: 100%;height: auto;padding-left: 30px;margin-bottom: 20px;">
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">用户姓名</span>{{evaluateData.createBy}}</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">评价内容</span>{{evaluateData.description}}</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;" v-if="evaluateData.pictureList&&evaluateData.pictureList.length>0">评价图片</span></div>
<div style="margin-bottom: 10px;width: 96%;padding: 5px;display: flex;flex-wrap: wrap;" v-if="evaluateData.pictureList&&evaluateData.pictureList.length>0">
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">用户姓名</span>{{ evaluateData.createBy }}
</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">评价内容</span>{{ evaluateData.description }}
</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;"
v-if="evaluateData.pictureList&&evaluateData.pictureList.length>0"
>评价图片</span></div>
<div style="margin-bottom: 10px;width: 96%;padding: 5px;display: flex;flex-wrap: wrap;"
v-if="evaluateData.pictureList&&evaluateData.pictureList.length>0"
>
<div v-for="(item,index) in evaluateData.pictureList" :key="index">
<img :src="item" style="width: 80px;height: 80px;" alt="">
</div>
</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">评价时间</span>{{evaluateData.createTime}}</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">评价时间</span>{{ evaluateData.createTime }}
</div>
<div style="margin-bottom: 10px;"><span style="font-weight: 600;">菜品评分</span></div>
</div>
<div style="width: 100%;height: 200px;overflow-y: auto;">
<div v-for="(item,index) in evaluateData.detailList" :key="index" style="display: flex;width: 100%;margin-bottom: 15px;align-items: center;">
<div v-for="(item,index) in evaluateData.detailList" :key="index"
style="display: flex;width: 100%;margin-bottom: 15px;align-items: center;"
>
<div style="width: 35%;word-break: break-all;font-size: 16px;text-align: center;">
{{ item.dishesName }}
</div>
@ -475,12 +537,30 @@
<!-- 提醒对话框 -->
<el-dialog :title="handleType+'提醒'" :visible.sync="openRemind" width="40%" append-to-body>
<div>
<el-select v-model="printerName" clearable collapse-tags style="width: 220px">
<el-option
v-for="item in printList"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
</div>
<div class="remind-question">请问是否对以下可{{ handleType }}订单进行{{ handleType }}操作</div>
<div class="remind-title">{{ handleType }}订单 {{ ableList.length }} </div>
<div v-for="(item,index) in ableList" :key="item.orderId">{{ (index+1) }}. 订单编号:{{item.orderId}}用户姓名:{{item.nickName}}用户编号:{{item.userId}}订单金额:{{(item.payableAmount/100).toFixed(2)}}</div>
<div v-for="(item,index) in ableList" :key="item.orderId">{{ (index + 1) }}.
订单编号:{{ item.orderId }}用户姓名:{{ item.nickName }}用户编号:{{
item.userId
}}订单金额:{{ (item.payableAmount / 100).toFixed(2) }}
</div>
<div class="remind-title">不可{{ handleType }}订单 {{ unableList.length }} </div>
<div v-for="(item,index) in unableList" :key="item.orderId">{{ (index+1) }}. 订单编号:{{item.orderId}}用户姓名:{{item.nickName}}用户编号:{{item.userId}}订单金额:{{(item.payableAmount/100).toFixed(2)}}</div>
<div v-for="(item,index) in unableList" :key="item.orderId">{{ (index + 1) }}.
订单编号:{{ item.orderId }}用户姓名:{{ item.nickName }}用户编号:{{
item.userId
}}订单金额:{{ (item.payableAmount / 100).toFixed(2) }}
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmRemind" :disabled="ableList.length==0"> </el-button>
@ -493,11 +573,21 @@
<script>
import { deptTreeSelect } from '@/api/system/user'
import { systemAreaTreeApi,getCanteenByAreaApi,getStallByCanteenApi } from "@/api/base/stall";
import { orderPageListApi,refundOrderPartApi,refundOrderApi,writeOffOrderApi,syncOrderPayStateApi,getEvaluaOrderDetailApi } from "@/api/order/reserve";
import { decryptWithSM4,encryptWithSM4 } from '@/utils/sm';
import { systemAreaTreeApi, getCanteenByAreaApi, getStallByCanteenApi } from '@/api/base/stall'
import {
orderPageListApi,
refundOrderPartApi,
refundOrderApi,
writeOffOrderApi,
syncOrderPayStateApi,
getEvaluaOrderDetailApi
} from '@/api/order/reserve'
import { decryptWithSM4, encryptWithSM4 } from '@/utils/sm'
import { WebSDK } from '@/utils/printer/WebSDK'
import { setPort, getPrinterList, requestPrint, wsPrint, WebSocketPrint } from '@/utils/printer/Common'
export default {
name: "",
name: '',
dicts: ['sys_user_type', 'sm_order_type', 'sm_order_status', 'sm_order_pay_type'],
data() {
return {
@ -522,26 +612,26 @@ export default {
shortcuts: [{
text: '最近一周',
onClick(picker) {
const start = new Date();
const end = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
picker.$emit('pick', [start, end]);
const start = new Date()
const end = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 6)
picker.$emit('pick', [start, end])
}
}, {
text: '最近一个月',
onClick(picker) {
const start = new Date();
const end = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit('pick', [start, end]);
const start = new Date()
const end = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
}, {
text: '最近三个月',
onClick(picker) {
const start = new Date();
const end = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 91);
picker.$emit('pick', [start, end]);
const start = new Date()
const end = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 91)
picker.$emit('pick', [start, end])
}
}]
},
@ -567,7 +657,7 @@ export default {
stallId: null,//-
orderStateList: [],//
payStateList: [], //
deptIdList:[], //
deptIdList: [] //
},
//
orderInfoData: {},
@ -581,8 +671,8 @@ export default {
refundMoney: [
{
required: true,
message: "本次退款金额不能为空",
trigger: "blur",
message: '本次退款金额不能为空',
trigger: 'blur'
}
]
},
@ -590,36 +680,69 @@ export default {
batchIds: [],//id
batchList: [],//
//退
handleType:"退单",
handleType: '退单',
ableList: [],
unableList: [],
openRemind: false,
openEva: false,
evaluateData:{}
};
evaluateData: {},
PosPrinter: null,
printList: [],
printerName: ''
}
},
created() {
this.getAreaTreeData();
this.getDeptTree();
// this.printerName = ''
// this.printList = []
this.PosPrinter = new WebSDK.EscPosCommand()
this.refreshPrinterList()
this.getAreaTreeData()
this.getDeptTree()
this.getList()
},
mounted() {
},
methods: {
refreshPrinterList() {
setPort(18080)
const category = { 'category': 1 }
getPrinterList(category, this.updatePrinterList)
},
updatePrinterList(printers) {
// this.printList = printers
// console.log(this.printList)
// if (!Array.isArray(printers)) {
// console.error('Expected an array of printers, but got:', typeof printers)
// return
// }
// console.log('Available printers:', this.printList)
this.printList = printers.map(item => ({
name: item.logicalName,
value: item.logicalName
}))
console.log('Available printers:', this.printList)
if (this.printList.length > 0) {
this.printerName = this.printList[0].name
}
},
//
getAreaTreeData() {
systemAreaTreeApi({}).then((response) => {
this.treeAreaOptions = response.data;
});
this.treeAreaOptions = response.data
})
},
handleAreaChange(e) {
let param = {
areaId:this.queryParams.areaId,"canteenType": 1
areaId: this.queryParams.areaId, 'canteenType': 1
}
getCanteenByAreaApi(param).then((response) => {
this.canteenOptions = response.rows || []
this.queryParams.canteenId = null
this.stallOptions = []
this.queryParams.stallId = null
});
})
},
handleCanteenChange(e) {
let param = {
@ -628,7 +751,7 @@ export default {
getStallByCanteenApi(param).then((response) => {
this.stallOptions = response.rows || []
this.queryParams.stallId = null
});
})
},
/** 查询部门下拉树结构 */
@ -650,8 +773,8 @@ export default {
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
@ -668,24 +791,24 @@ export default {
stallId: null,//-
orderStateList: [],//
payStateList: [], //
deptIdList:[], //
deptIdList: [] //
}
this.resetForm("queryForm");
this.handleQuery();
this.resetForm('queryForm')
this.handleQuery()
},
/** 查询列表 */
getList() {
this.loading = true;
this.loading = true
let param = {
...this.queryParams,
"orderTypeList":[2],
'orderTypeList': [2]
}
if (this.dateRange && this.dateRange.length > 0) {
param.startDate = this.formatDate(this.dateRange[0])
param.endDate = this.formatDate(this.dateRange[1])
} else {
param.startDate=undefined;
param.endDate=undefined;
param.startDate = undefined
param.endDate = undefined
}
if (this.queryParams.canteenId) {
param.canteenIdList = [this.queryParams.canteenId]
@ -694,50 +817,51 @@ export default {
param.stallIdList = [this.queryParams.stallId]
}
orderPageListApi(param).then(response => {
this.tableListData = response.rows;
this.tableListData = response.rows
this.tableListData.forEach(item => {
if(item.phoneNumber&&item.phoneNumber!=""){
this.$set(item,"phoneNumber",decryptWithSM4(item.phoneNumber))
if (item.phoneNumber && item.phoneNumber != '') {
this.$set(item, 'phoneNumber', decryptWithSM4(item.phoneNumber))
}
})
this.total = Number(response.total);
this.loading = false;
});
this.total = Number(response.total)
this.loading = false
})
},
/** 修改按钮操作 */
handleView(row) {
this.orderInfoData = Object.assign({}, row)
this.open = true;
this.open = true
},
/** 部分退款按钮操作 */
handleRefundPart(row) {
this.orderDetailList = row.orderDetailList;
this.rowData = row;
this.$set(this.rowData,"refundMoney","")
this.orderDetailList = row.orderDetailList
this.rowData = row
this.$set(this.rowData, 'refundMoney', '')
console.log(this.rowData)
this.orderDetailList.forEach((item, index) => {
this.$set(this.orderDetailList[index],"unRefundNum",item.quantity-item.refundNum)
this.$set(this.orderDetailList[index],"goRefundNum",item.unRefundNum)
this.$set(this.orderDetailList[index],"refundMoney",Number(item.goRefundNum)*(item.salePrice).toFixed(2))
this.$set(this.orderDetailList[index], 'unRefundNum', item.quantity - item.refundNum)
this.$set(this.orderDetailList[index], 'goRefundNum', item.unRefundNum)
this.$set(this.orderDetailList[index], 'refundMoney', Number(item.goRefundNum) * (item.salePrice).toFixed(2))
})
this.refundList = []
this.openPart = true;
this.openPart = true
this.$refs.multiplePartTable.clearSelection()
},
inputNum(row) {
if (Number(row.goRefundNum) > row.unRefundNum) {
this.$modal.msgError("退款数量不能大于可退款数量!");
this.$modal.msgError('退款数量不能大于可退款数量!')
row.goRefundNum = row.unRefundNum
}
row.refundMoney = Number(row.goRefundNum) * (row.salePrice).toFixed(2)
this.refundList.forEach((item) => {
if (item.detailId == row.detailId) {
this.$set(item,"quantity",row.goRefundNum)
this.$set(item, 'quantity', row.goRefundNum)
}
})
},
//退/退
choseRefundTypeRadio(e){},
choseRefundTypeRadio(e) {
},
//退
handleSelectionChange(selection) {
console.log(selection)
@ -753,7 +877,7 @@ export default {
confirmRefund() {
if (this.refundType == 1) {
if (this.refundList.length == 0) {
this.$modal.msgError("请先勾选退款菜品!");
this.$modal.msgError('请先勾选退款菜品!')
} else {
console.log(this.refundList)
let param = {
@ -762,10 +886,10 @@ export default {
}
refundOrderPartApi(param).then(response => {
if (response.code == 200) {
this.$modal.msgSuccess("退款成功");
this.$modal.msgSuccess('退款成功')
}
this.getList()
this.openPart = false;
this.openPart = false
}).catch(err => {
this.refundList = []
this.$refs.multiplePartTable.clearSelection()
@ -773,7 +897,7 @@ export default {
}
}
if (this.refundType == 2) {
this.$refs["rowData"].validate(valid => {
this.$refs['rowData'].validate(valid => {
if (valid) {
let param = {
refundAmount: Number(this.rowData.refundMoney * 100),
@ -781,18 +905,16 @@ export default {
}
refundOrderPartApi(param).then(response => {
if (response.code == 200) {
this.$modal.msgSuccess("退款成功");
this.$modal.msgSuccess('退款成功')
}
this.getList()
this.openPart = false;
});
this.openPart = false
})
}
});
})
}
},
/** 退单按钮操作 */
handleRefund(row) {
@ -802,11 +924,12 @@ export default {
orderId: row.orderId
}
this.$modal.confirm('是否确认退单?').then(function() {
return refundOrderApi(param);
return refundOrderApi(param)
}).then(() => {
this.getList();
this.$modal.msgSuccess("退单成功");
}).catch(() => {});
this.getList()
this.$modal.msgSuccess('退单成功')
}).catch(() => {
})
},
/** 核销按钮操作 */
writeOffOrder(row) {
@ -814,11 +937,12 @@ export default {
orderIdList: [row.orderId]
}
this.$modal.confirm('是否确认核销?').then(function() {
return writeOffOrderApi(param);
return writeOffOrderApi(param)
}).then(() => {
this.getList();
this.$modal.msgSuccess("核销成功");
}).catch(() => {});
this.getList()
this.$modal.msgSuccess('核销成功')
}).catch(() => {
})
},
/** 评价按钮操作 */
checkEvaluate(row) {
@ -834,13 +958,13 @@ export default {
// ----------
handleOrderSelectionChange(selection) {
this.batchIds = selection.map((item) => item.orderId)
this.batchList = selection;
this.batchList = selection
this.single = selection.length !== 1
this.multiple = !selection.length
},
//退
handleBatchRefund() {
this.handleType="退单"
this.handleType = '退单'
this.ableList = []
this.unableList = []
this.batchList.forEach(item => {
@ -852,9 +976,35 @@ export default {
})
this.openRemind = true
},
changePrint(e) {
this.printerName = e
if (wsPrint) {
wsPrint.disconnect()
console.log('WebSocket connection closed.')
}
},
handleBatchPrint() {
console.log(this.printList)
this.handleType = '打印小票'
this.ableList = []
this.unableList = []
this.batchList.forEach(item => {
if (item.orderState == 1 || item.orderState == 5) {
this.ableList.push(item)
} else {
this.unableList.push(item)
}
})
this.openRemind = true
},
handleBatchPrintRefresh() {
setPort(18080)
const category = { 'category': 1 }
getPrinterList(category, this.updatePrinterList)
},
//
handleBatchWriteOff() {
this.handleType="核销"
this.handleType = '核销'
this.ableList = []
this.unableList = []
this.batchList.forEach(item => {
@ -869,7 +1019,7 @@ export default {
confirmRemind() {
console.log(this.ableList.length)
if (this.ableList.length > 0) {
if(this.handleType=="退单"){
if (this.handleType == '退单') {
this.ableList.forEach(item => {
let param = {
orderId: item.orderId
@ -878,11 +1028,11 @@ export default {
// if(response.code!=200){
// this.$modal.msgError(response.msg);
// }
});
})
this.$modal.msgSuccess("批量退单完成");
})
this.$modal.msgSuccess('批量退单完成')
}
if(this.handleType=="核销"){
if (this.handleType == '核销') {
this.ableList.forEach(item => {
let param = {
orderIdList: [item.orderId]
@ -891,9 +1041,51 @@ export default {
// if(response.code!=200){
// this.$modal.msgError(response.msg);
// }
});
})
this.$modal.msgSuccess("批量核销完成");
})
this.$modal.msgSuccess('批量核销完成')
}
if (this.handleType == '打印小票') {
if (this.printList.length === 0) {
this.$modal.msgWarning('请先开启小票打印机服务!')
return
}
if (this.printerName === '') {
this.$modal.msgWarning('请先选择小票打印机!')
return
}
const _titles = ['菜品名称', '数量', '单价', '总价']
const _columnWidths = [20, 10, 10, 8]
console.log(this.ableList)
this.ableList.forEach(item => {
let _rows = []
item.orderDetailList.forEach((it) => {
let row = []
row.push(it.goodsName)
row.push(it.quantity)
row.push((it.salePrice / 100).toFixed(2))
row.push((it.totalAmount / 100).toFixed(2))
_rows.push(row)
})
this.PosPrinter.cleanBuffer()
.setCodePage(256)
.setEncoding('gbk')
.printText({ data: item.nickName + '(' + item.phoneNumber + ')\n' + item.orderId, textSize: 2 })
.printText({ data: item.orderTime + '\n', textSize: 1 })
.printAndFeed(1)
.printTable({ titles: _titles, columnWidths: _columnWidths, rows: _rows })
.printAndFeed(1)
.printText({
data: '\n\n订单金额' + item.payableAmount / 100 + '\n实付金额' + (item.payableAmount - item.refundAmount) / 100 + '\n\nThank you for your order!\nWelcome again next time!',
textSize: 1,
alignment: 0
}) // : 277 -> Total: 277; : 277 -> Amount Due: 277; : 1234567891011 -> Flow Number: 1234567891011; -> Thank you for your visit! Welcome again next time!
.printAndFeed(2)
.feedAndCut(50)
this.prepareAndPrint(this.printerName)
})
this.$modal.msgSuccess('打印小票完成')
}
this.$refs.multipleTable.clearSelection()
setTimeout(() => {
@ -902,38 +1094,44 @@ export default {
}, 500)
}
},
prepareAndPrint(printerName) {
setPort(18080)
const data = this.PosPrinter.cleanBuffer()
.checkPrinterStatus()
.getData()
requestPrint(printerName, data, this.updatePrinterCallback)
},
updatePrinterCallback(res) {
this.$modal.msgSuccess('打印小票完成')
},
//
handleSyncPayState() {
if (this.batchIds.length > 0) {
this.batchIds.forEach(item => {
syncOrderPayStateApi({ orderId: item }).then(response => {
if (response.code != 200) {
this.$modal.msgError(response.msg);
this.$modal.msgError(response.msg)
}
});
})
this.$modal.msgSuccess("同步已完成");
})
this.$modal.msgSuccess('同步已完成')
this.getList()
this.$refs.multipleTable.clearSelection()
} else {
this.$modal.msgError("请先勾选订单数据!");
this.$modal.msgError('请先勾选订单数据!')
}
},
//
formatDate(date) {
// YYYY-MM-DD
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 0
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0') // 0
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
}
}
};
</script>
<style scoped>
.remind-question {
@ -944,6 +1142,7 @@ export default {
align-items: center;
justify-content: center;
}
.remind-title {
width: 100%;
height: 40px;
@ -954,6 +1153,7 @@ export default {
align-items: center;
justify-content: center;
}
::v-deep .el-rate__icon {
font-size: 30px;
}