import { mapState, mapActions } from "vuex"; import { FakeConnectedDevice } from "@psdk/frame-father"; import bluetoothTool from "@/plugins/BluetoothTool.js"; import { printMaterial } from "@/common/request/apis/print"; import printPop from "@/components/print-pop/print-pop.vue"; import blePop from "@/components/ble-pop/ble-pop.vue"; import bleTipPop from "@/components/ble-tip-pop/ble-tip-pop.vue"; import { TBar, TBarCode, TQRCode, TBox, TImage, TPage, TRotation, TCodeType, TLine, TText, TFont, TTLine, } from "@psdk/tspl"; ///转成安卓有符号的 function uint8ArrayToSignedArray(uint8Array) { let signedArray = new Array(uint8Array.length); for (let i = 0; i < uint8Array.length; i++) { if (uint8Array[i] >= 128) { signedArray[i] = uint8Array[i] - 256; } else { signedArray[i] = uint8Array[i]; } } return signedArray; } async function sendMessage(cmd) { console.log(cmd); const result = bluetoothTool.sendByteData(cmd); uni.showToast({ icon: "none", title: result ? "发送成功!" : "发送失败...", }); } export default { name: "blePrintMixin", components: { printPop, blePop, bleTipPop, }, computed: { ...mapState({ discoveredDevices: (state) => state.ble.discoveredDevices, // 已发现的蓝牙设备 connectedBleDevice: (state) => state.ble.connectedBleDevice, connectedDeviceId: (state) => state.ble.connectedDeviceId, // 已连接的蓝牙设备ID }), }, data() { return { bleErrorTipPop: { show: false, content: "未连接 蓝牙", extraText: "请连接蓝牙之后再继续操作", }, // 蓝牙打印弹框 blePrintPop: { show: false, data: {}, }, // 选择蓝牙设备弹框 bleSelectPop: { show: false, discoveredDevices: [], }, }; }, methods: { ...mapActions("ble", [ "checkBleStatus", // 检查蓝牙设备连接状态 "discovery", // 搜索蓝牙设备 "connectBT", // 连接蓝牙设备 "cancelDiscovery", // 停止蓝牙搜索 ]), bleErrorTipConfirm() { this.bleErrorTipPop.show = false; this.openBleSelectPop(); }, //打开蓝牙选择弹框 openBleSelectPop() { this.discovery(); // 搜索蓝牙设备 this.bleSelectPop.show = true; }, //关闭蓝牙选择弹框 closeBleSelectPop() { this.cancelDiscovery(); this.bleSelectPop.show = false; }, //选择蓝牙设备 async handleSelectBle(item) { console.log("选择蓝牙设备=====", item); const device = await this.connectBT(item); if (device) { this.closeBleSelectPop(); this.$printer.init(new FakeConnectedDevice()); // 初始化打印机 this.blePrintPop.show = true; } console.log("this.blePrintPop.data=====", this.blePrintPop.data); }, // 打开蓝牙打印弹框 async openBlePrintPop(data) { const res = await this.checkBleStatus(); // 检查蓝牙设备打开状态 this.blePrintPop.data = data; switch (res.code) { case 0: // const devices = bluetoothTool.getPairedDevices(); // 获取已配对的蓝牙设备 // console.log("devices======", devices); if (this.connectedDeviceId != "") { this.blePrintPop.show = true; } else { // 如果没有配对的设备,提示用户去配对 this.bleErrorTipPop.show = true; } break; case 1: uni.showToast({ icon: "none", title: "请打开蓝牙", }); break; case 2: uni.showToast({ icon: "none", title: "当前设备不支持蓝牙", }); break; } }, // 重新搜索蓝牙设备 refreshBleDevice() { this.discovery(); }, /** * 打印 *@data {Object} 需要打印的数据 *@num {number} 需要打印的数量 * */ async writeTsplModel(data, num = 1) { const vm = this; const obj = { qrCode: data.number, // 二维码 barCode: data.barCode, // 商品条码 customerName: data.customerName, //客户名 number: data.number, // 单据编号 batchNumber: data.batchNumber, // 单据编号 type: data.type, // 入库:1 出库;2 status: data.status, // 订单状态 入库状态为2才有批次号,出库不显示批次号 }; try { let cellWidth = 6; if (obj.qrCode.length > 30) cellWidth = 4; if (obj.qrCode.length > 60) cellWidth = 2; const startX = 50; const startY = 30; const qrcodeX = startX; const qrcodeY = startY; const qrcodeSize = cellWidth * 21; // 经验值 const textStartX = qrcodeX + qrcodeSize + 10; const textStartY = qrcodeY; const textLineHeight = 28; const barcodeX = startX; const barcodeY = Math.max(qrcodeY + qrcodeSize, textStartY + textLineHeight * 3) + 15; const barcodeHeight = 50; console.log("obj==========", obj); let tspl; if (obj.type == 2) { tspl = await vm.$printer .tspl() .clear() .page(new TPage({ width: 76, height: 130 })) .qrcode( new TQRCode({ x: qrcodeX, y: qrcodeY, content: obj.qrCode, cellWidth, }) ) .text( new TText({ x: textStartX, y: textStartY, content: obj.customerName, font: TFont.TSS24, }) ) .text( new TText({ x: textStartX, y: textStartY + textLineHeight * 2, content: obj.number, font: TFont.TSS24, }) ) .barcode( new TBarCode({ x: barcodeX, y: barcodeY, cellWidth: 2, height: barcodeHeight, content: `${obj.barCode}`, rotation: TRotation.ROTATION_0, codeType: TCodeType.CODE128, showType: 0, }) ) .text( new TText({ x: barcodeX, y: barcodeY + barcodeHeight + 5, content: `SKU-${obj.barCode}`, font: TFont.TSS16, }) ) .print(num); } else { if (obj.status == 2) { tspl = await vm.$printer .tspl() .clear() .page(new TPage({ width: 76, height: 130 })) .barcode( new TBarCode({ x: 50, y: 30, cellWidth: 2, height: 100, content: `${obj.barCode}`, rotation: TRotation.ROTATION_0, codeType: TCodeType.CODE128, showType: 0, }) ) .text( new TText({ x: 50, y: 30 + 100 + 5, content: `SKU-${obj.barCode}`, font: TFont.TSS16, }) ) .barcode( new TBarCode({ x: 50, y: 30 + 100 + 5 + 35, cellWidth: 2, height: 50, content: `${obj.batchNumber}`, rotation: TRotation.ROTATION_0, codeType: TCodeType.CODE128, showType: 0, }) ) .text( new TText({ x: 50, y: 30 + 100 + 5 + 35 + 50 + 5, content: `PC${obj.batchNumber}`, font: TFont.TSS16, }) ) .print(num); } else { tspl = await vm.$printer .tspl() .clear() .page(new TPage({ width: 76, height: 130 })) .barcode( new TBarCode({ x: 50, y: 30, cellWidth: 2, height: 100, content: `${obj.barCode}`, rotation: TRotation.ROTATION_0, codeType: TCodeType.CODE128, showType: 0, }) ) .text( new TText({ x: 50, y: 30 + 100 + 5, content: `SKU-${obj.barCode}`, font: TFont.TSS16, }) ) .print(num); } } var binary = tspl.command().binary(); await sendMessage(Array.from(uint8ArrayToSignedArray(binary))); } catch (e) { console.error(e); uni.showToast({ title: "失败", }); } }, async writeData({ num = 1, data }) { await this.writeTsplModel(data, num); }, //条码逻辑 async handlePrint(id, type, status) { try { uni.showLoading({ mask: true, }); const res = await printMaterial({ id }); console.log("item===id==", id); console.log("res=====", res); console.log("type=====", type); console.log("status=====", status); if (res.code == 200) { const data = { customerName: res.data.customerName, number: res.data.number, barCode: res.data.barCode, batchNumber: res.data.batchNumber, type, status, }; this.openBlePrintPop(data); } else { uni.showToast({ icon: "none", title: res.msg || res.data || "服务器错误", duration: 2000, }); } } catch (error) { //TODO handle the exception } finally { uni.hideLoading(); } }, //开始打印 startPrint(data) { this.writeData(data); }, }, };