import PrinterJobs from '@/components/print/printerjobs.js' import printerUtil from '@/components/print/printerutil.js' import util from '@/components/print/util.js' import drawQrcode from '@/components/print/weapp.qrcode.esm.js' import Bluetooth from '@/components/print/bluetooth.js' let bluetooth = new Bluetooth(); let isPrint = false let data1 = {} export default { getData(onDone) { var that = this; if (uni.getStorageSync('bluetoothDeviceId')) { let id = uni.getStorageSync('bluetoothDeviceId') const baseUrl = getApp().globalData.mainurl uni.request({ url: baseUrl + "/mall/order/detail/" + getApp().globalData.printData[0].order_id, data: {}, method: 'GET', header: { "content-type": 'application/x-www-form-urlencoded', 'accessToken': uni.getStorageSync('hiver_token') }, success: function(res) { if (res.data.code == 200) { data1 = res.data.result console.log('打印的数据----------',data1) that.bindViewTap(id, false, onDone) } else { uni.showToast({ title: res.data.message, icon: 'none' }); if (typeof onDone === 'function') onDone(); return; } uni.hideLoading(); }, fail: function(err) { uni.hideLoading(); if (typeof onDone === 'function') onDone(); } }) } else { uni.showModal({ title: '提示', content: '您还没有连接打印机,将无法为您打印小票!', confirmText: '连接蓝牙', cancelText: '暂不连接', success: function(res) { if (res.confirm) { uni.navigateTo({ url: '/pages/myCenter/setPrint' }) } if (typeof onDone === 'function') onDone(); } }); } }, async bindViewTap(deviceId, state, onDone) { var _this = this; try { await bluetooth.createBLEConnection(deviceId).then((res) => { bluetooth.deviceId = deviceId; }).catch((e) => { throw e; }); let server = []; await bluetooth.getBLEDeviceServices().then((res) => { bluetooth.notifyId = ''; bluetooth.writeId = ''; bluetooth.num = 0; bluetooth.serviceList = res }).catch((e) => { throw e; }); let result3 = await bluetooth.getBLEDeviceCharacteristics().then(res => { uni.setStorageSync('bluetoothDeviceId', deviceId); this.pickUpOnce(onDone) }).catch((e) => { throw e; }); } catch (e) { if (typeof onDone === 'function') onDone(); } }, //打印一次 pickUpOnce(onDone) { isPrint = true; bluetooth.notifyBLECharacteristicValue(); let self = this; setTimeout(() => { self.writeBLECharacteristicValue(onDone); }, 500); }, maskPhoneLastFour(phone) { if (!phone) return ''; const str = String(phone); if (str.length <= 4) return str; return str.replace(/.(?=.{4})/g, '*'); }, //写入控制命令 async writeBLECharacteristicValue(onDone) { let printerJobs = new PrinterJobs(); printerJobs.setAlign('ct').setSize(2, 2).setLineSpacing(60).print( data1.deliveryType == 1 && data1.orderType == 3 ? data1.deliveryInfo.numberCode : data1.numberCode ); printerJobs.setAlign('ct').setSize(2, 2).setLineSpacing(60).print( (data1.deliveryInfo && data1.deliveryInfo.appointmentDelivery == 1 && data1.status != 7 && data1.status == 11)? '预约单': (data1.status == 7 || data1.status == 11)? '申请退款': (data1.deliveryType == 1 && data1.orderType == 3) ? '面对面配送': (data1.status == 3 && data1.deliveryType == 2)? '待消费': data1.status == 5? '已完成': data1.status == 6? '已取消': data1.status == 8? '已退款': data1.status == 12? '已售后': data1.isPack == 0 ? '到店-堂食': data1.isPack == 1 ? '到店-打包': data1.deliveryType == 1 ? '配送': '' ); if(data1.deliveryInfo && data1.deliveryInfo.appointmentDelivery == 1){ printerJobs.setAlign('lt').print( '要求送达时间:' + (data1.deliveryInfo == null ? ' ' : this.formatTime(data1.deliveryInfo.mustFinishTime)) ); } printerJobs.setSize(1, 1).setLineSpacing(40); printerJobs.setAlign('lt').print(data1.shopName); printerJobs.setAlign('lt').print( '下单时间:' + this.formatTime(data1.createTime) ); if(data1.mallRefundRecord == null){ if(data1.deliveryType == 1){ printerJobs.setAlign('lt').print( '预计送达时间:' + (data1.deliveryInfo == null ? ' ' : this.formatTime(data1.deliveryInfo.mustFinishTime)) ); }else if(data1.userRequireMake == 1){ printerJobs.setAlign('lt').print( '核销时间:' + this.formatTime(data1.createTime) ); } } if(data1.mallRefundRecord != null){ if(data1.userRequireMake == 1 && data1.deliveryType == 2){ printerJobs.setAlign('lt').print( '核销时间:' + this.formatTime(data1.createTime) ); } printerJobs.setAlign('lt').print( '申请退款时间:' + (data1.mallRefundRecord == null ? ' ' : this.formatTime(data1.mallRefundRecord[0].createTime)) ); } printerJobs.print(printerUtil.fillLine('-', 1, 32)); if(data1.deliveryType == 1 && data1.status != 7 && data1.status != 11 && data1.status != 5 && data1.status != 6 && data1.status != 8 && data1.status != 12){ printerJobs.setAlign('lt').setSize(2, 2).setLineSpacing(60).print( data1.receiverName == null ? ' ' : data1.receiverName ); } printerJobs.setSize(1, 1).setLineSpacing(40); printerJobs.setAlign('lt').print('联系电话: ' + this.maskPhoneLastFour(data1.receiverPhone)); if(data1.deliveryType == 1 && data1.status != 7 && data1.status != 11 && data1.status != 5 && data1.status != 6 && data1.status != 8 && data1.status != 12){ printerJobs.setAlign('lt').setSize(2, 2).setLineSpacing(60).print( '地址:' + (data1.receiverAddress == null ? ' ' : data1.receiverAddress) ); } printerJobs.setSize(1, 1).setLineSpacing(40); printerJobs.setAlign('lt').print('顾客电话已被隐藏,您可登录商家端或骑手端查看'); printerJobs.print(printerUtil.fillLine('-', 1, 32)); for (var i = 0; i < data1.goodsList.length; i++) { var productName = this.removeEmojis(data1.goodsList[i].productName) printerJobs.setAlign('lt').setSize(2, 2).print(productName); if (data1.goodsList[i].specs) { printerJobs.setSize(1, 1).print(this.delNode(data1.goodsList[i].specs)); } printerJobs.setSize(2, 2); printerJobs.setAlign('lt').text('¥' + data1.goodsList[i].price); printerJobs.text(" "); printerJobs.print('X' + data1.goodsList[i].quantity); printerJobs.setSize(1, 1); } printerJobs.print(printerUtil.fillLine('-', 1, 32)); printerJobs.setAlign('lt').print('配送费:' + data1.deliveryFee); if(data1.packageFee > 0){ printerJobs.print('打包费:' + data1.packageFee); } if(data1.userCoupon && data1.userCoupon.length >0){ printerJobs.print('优惠券:-' + data1.userCoupon[0].discountAmount); } if(data1.freeAmount > 0){ printerJobs.print('锦鲤免单:-' + data1.freeAmount); } printerJobs.print('商品金额:' + data1.goodsAmount); printerJobs.print('合计金额:' + (data1.goodsAmount + data1.deliveryFee + data1.packageFee)); if(data1.mallRefundRecord != null){ printerJobs.print('应退金额:' + data1.totalAmount); }else{ printerJobs.print('实付金额:' + data1.totalAmount); } printerJobs.setSize(2, 2).print('备注:' + data1.remark); if(data1.mallRefundRecord != null){ printerJobs.setAlign('lt').print( '退款原因:' + (data1.mallRefundRecord == null ? ' ' : data1.mallRefundRecord[0].reason) ); } printerJobs.setSize(1, 1).print(printerUtil.fillLine('-', 1, 32)); printerJobs.setAlign('lt').print('商品取到后,如有任何商品问题,请及时联系商家和平台,客服将为您服务,谢谢您的惠顾'); printerJobs.lineFeed(3); let buffer = printerJobs.buffer(); this.sendPrint(buffer, onDone); }, // 去除字符串中的 Emoji 表情 removeEmojis(str) { if (!str) return ''; var emojiRegex = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/g; return str.replace(emojiRegex, ''); }, formatTime(value) { if (!value) return ''; if (value == '尽快送达') return '尽快送达'; const date = new Date(value); const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); const hour = String(date.getHours()).padStart(2, '0'); const minute = String(date.getMinutes()).padStart(2, '0'); const second = String(date.getSeconds()).padStart(2, '0'); return `${year}-${month}-${day} ${hour}:${minute}:${second}`; }, delNode(data) { let str; if (typeof data === 'object' && data !== null) { str = JSON.stringify(data); } else if (typeof data === 'string') { str = data; } else { str = String(data); } const result = str.replace(/[{}"]/g, ''); return result; }, sendPrint(buffer, onDone) { const maxChunk = 20; const delay = 50; isPrint = true; const totalLength = buffer.byteLength; let currentIndex = 0; const srcView = new Uint8Array(buffer); const sendNextChunk = () => { if (currentIndex >= totalLength) { isPrint = false; if (typeof onDone === 'function') onDone(); return; } const end = Math.min(currentIndex + maxChunk, totalLength); const chunkLength = end - currentIndex; const valueToSend = new ArrayBuffer(chunkLength); const dstView = new Uint8Array(valueToSend); dstView.set(srcView.subarray(currentIndex, end)); bluetooth.writeBLECharacteristicValue(valueToSend).then(() => { currentIndex = end; setTimeout(sendNextChunk, delay); }).catch((err) => { isPrint = false; if (typeof onDone === 'function') onDone(err); }); }; sendNextChunk(); }, sendPrintData(buffer) { bluetooth.writeBLECharacteristicValue(buffer).then(res => {}); }, startSearch(state) { let that = this bluetooth.openBluetoothAdapter().then(e => { uni.startBluetoothDevicesDiscovery({ success: res => { uni.onBluetoothDeviceFound(result => { let arr = that.list; let devices = []; let list = result.devices; for (let i = 0; i < list.length; ++i) { if (list[i].name && list[i].name != "未知设备") { let arrNew = arr.filter((item) => { return item.deviceId == list[i].deviceId; }); if (arrNew.length == 0) { devices.push(list[i]); } if (uni.getStorageSync('bluetoothDeviceId') == list[i] .deviceId) { // that.bindViewTap(list[i].deviceId, state) } } } that.list = arr.concat(devices); }); }, fail: res => { uni.hideLoading(); uni.showToast({ title: `搜索设备失败` + JSON.stringify(err) }) } }) }).catch(e => {}); }, // 停止搜索 stopSearch() { uni.hideLoading(); bluetooth.stopBluetoothDevicesDiscovery(); } }