支付宝/钉钉小程序实现蓝牙打印
2021/5/8 20:27:19
本文主要是介绍支付宝/钉钉小程序实现蓝牙打印,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
本文主要是钉钉小程序通过蓝牙进行打印,当然钉钉和支付宝都是相同的。打印机设备佳博M-322便携式打印机,打印效果图在文末
使用到的接口请参照钉钉开发文档
1.连接蓝牙打印机的js
Page({ data: { list: [], loading: false,//搜索状态 write: false,//写入的值是否已经确定 characteristicId: '', serviceId: '', deviceId: '', services: [], num: 0, printer: '' }, onl oad() { //初始化蓝牙 dd.openBluetoothAdapter({ success: (res) => { //获取本季蓝牙模块的状态 dd.getBluetoothAdapterState({ success: (res) => { //是否可用 if (res.available) { //是否正在搜索 this.setData({ loading: res.discovering }) /*if (res.discovering) { //停止搜索 dd.stopBluetoothDevicesDiscovery({ success: (res) => { console.log(res) }, fail: (res) => { }, complete: (res) => { } }); }*/ //获取已经搜索到的设备 this.getBluetoothDevices(); } else { dd.alert({ title: '提示', content: '手机蓝牙模块不可用!' }) } }, fail: (res) => { console.log(res) }, complete: (res) => { console.log(res) } }); }, fail: (res) => { if (res.error == 12) { dd.alert({ title: '提示', content: '蓝牙未打开,请尝试打开蓝牙。' }) } else if (res.error == 13) { dd.alert({ title: '提示', content: '与系统服务的链接暂时丢失,请尝试重新连接。' }) } else if (res.error == 14) { dd.alert({ title: '提示', content: '未授权使用蓝牙功能。请授权使用蓝牙功能。' }) } else if (res.error == 10000) { dd.alert({ title: '提示', content: '未初始化蓝牙适配器' }) } else { dd.alert({ title: '提示', content: '未知错误!' }) } }, complete: (res) => { } }); //监听搜索到的设备 this.callback = this.callback.bind(this); dd.onBluetoothDeviceFound(this.callback); }, callback(res) { //监听新设备事件 //console.log(res); var list = this.data.list; res.devices.forEach(element => { //判断list中的id没有这个才可以 var ok = true; for (var i = 0; i < list.length; i++) { //console.log(list[i].deviceId, element.deviceId) if (list[i].deviceId == element.deviceId) { ok = false; } } if (ok && element.localName != '' && element.name != null) { list.push(element); } }); this.setData({ list: list }) //console.log(list) }, getBluetoothDevices() { //android 6.0需要授权地理位置权限 dd.getBluetoothDevices({ success: (res) => { this.callback(res); }, fail: (res) => { console.log(res) dd.alert({ title: '提示', content: '位置权限未开启!请给钉钉开启定位权限' }) }, complete: (res) => { console.log(res) } }); }, onClick(e) { console.log(e) this.setData({ deviceId: e.target.dataset.item.deviceId, printer: e.target.dataset.item.name }) this.stopBluetoothDevicesDiscovery();//停止搜索蓝牙 //链接蓝牙设备 dd.showLoading(); dd.connectBLEDevice({ //判断蓝牙搜索的状态如果是正在搜索那么就关闭掉搜索 // 这里的 deviceId 可通过 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取 deviceId: e.target.dataset.item.deviceId, success: (res) => { //获取设备的特征值用于收发数据 dd.getBLEDeviceServices({ deviceId: e.target.dataset.item.deviceId, success: (res) => { this.setData({ services: res.services }) //遍历特征值看都是什么类型的。只需要写入类型 this.getBLEDeviceServices(); }, fail: (res) => { console.log(res) }, complete: (res) => { dd.hideLoading() } }) }, fail: (res) => { dd.alert({ title: '提示', content: res.errorMessage }) }, complete: (res) => { } }); }, getBLEDeviceServices() { dd.getBLEDeviceCharacteristics({ deviceId: this.data.deviceId, serviceId: this.data.services[this.data.num].serviceId, success: (res) => { console.log(res) for (var j = 0; j < res.characteristics.length; j++) { //判断特征值是否支持写入,读取,通知,操作,如果支持就可以了 if (res.characteristics[j].properties.write && !this.data.write) { //characteristicId = res.characteristics[0].characteristicId; //serviceId = res.characteristics[0].serviceId; this.setData({ write: true, characteristicId: res.characteristics[j].characteristicId, serviceId: res.characteristics[j].serviceId, }) } } if (this.data.write) { dd.showToast({ type: 'success', content: '连接成功!' }) //返回上一个页面 let pages = getCurrentPages();//获取当前页面js里面的pages里的所有信息。 //prevPage 是获取上一个页面的js里面的pages的所有信息。 -2 是上一个页面,-3是上上个页面以此类推 let prevPage = pages[pages.length - 2]; prevPage.setData({ characteristicId: this.data.characteristicId, deviceId: this.data.deviceId, printer: this.data.printer, serviceId: this.data.serviceId, printtype: '1', 'printtypes[1].checked': true, 'printtypes[0].checked': false, }) console.log(this.data.serviceId); console.log(this.data.characteristicId) dd.navigateBack(); } else { if (this.data.num < this.data.services.length) { this.setData({ num: this.data.num + 1 }) this.getBLEDeviceServices(); } } } }) }, stopBluetoothDevicesDiscovery() { //停止搜索 dd.stopBluetoothDevicesDiscovery({ success: (res) => { //获得蓝牙的状态 dd.getBluetoothAdapterState({ success: (res) => { //是否可用 if (res.available) { //是否正在搜索 this.setData({ loading: res.discovering }) //获取已经搜索到的设备 this.getBluetoothDevices(); } else { dd.alert({ title: '提示', content: '手机蓝牙模块不可用!' }) } }, fail: (res) => { console.log(res) }, complete: (res) => { console.log(res) } }); }, fail: (res) => { }, complete: (res) => { } }); }, onseaer() { //如果但当前正在搜索蓝牙,那么点击就是停止搜索 if (this.data.loading) { this.stopBluetoothDevicesDiscovery(); } else { //开启蓝牙搜索 dd.startBluetoothDevicesDiscovery({ //services: ['fff0'], success: (res) => { //获得蓝牙的状态 //获取本季蓝牙模块的状态 dd.getBluetoothAdapterState({ success: (res) => { //是否可用 if (res.available) { //是否正在搜索 this.setData({ loading: res.discovering }) /* if (res.discovering) { //停止搜索 dd.stopBluetoothDevicesDiscovery({ success: (res) => { console.log(res) }, fail: (res) => { }, complete: (res) => { } }); }*/ //获取已经搜索到的设备 this.getBluetoothDevices(); } else { dd.alert({ title: '提示', content: '手机蓝牙模块不可用!' }) } }, fail: (res) => { console.log(res) }, complete: (res) => { console.log(res) } }); }, fail: (res) => { }, complete: (res) => { } }); } } });
2.发送打印标签打印数据js
import { GetSkuList } from "../../../api/api"; import { GetPrintGood } from "../../../api/api" import { jpPrinter } from "../../../util/tsc" Page({ data: { hidden: true, //款号选者是否隐藏 ITCODE_IT: '', Price: 0, printtypes: [{ value: '0', label: 'WIFI', checked: true }, { value: '1', label: '蓝牙' }], printtype: '0', printer: '', characteristicId: '', deviceId: '', serviceId: '', time: 20,//限制在20字节内 looptime: 0,//发送字节整数数量 lastData: 0,//余数 currentTime: 1,//发送次数 }, onl oad() { // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调 dd.onSocketClose((res) => { dd.showToast({ type: 'exception', content: '连接打印机失败' }); this.setData({ sendMessageAbility: false, closeLinkAbility: false, }); }); // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调 dd.onSocketOpen((res) => { dd.showToast({ type: 'success', content: '已连接打印机!' }); this.setData({ sendMessageAbility: true, closeLinkAbility: true, }); }); dd.onSocketError(function (res) { dd.showToast({ type: 'exception', content: 'WebSocket 连接打开失败,请检查!' + res }); }); // 注意: 回调方法的注册在整个小程序启动阶段只要做一次,调多次会有多次回调 dd.onSocketMessage((res) => { //dd.alert({ content: '收到数据!' + JSON.stringify(res) }); }); }, connect_start() { dd.connectSocket({ url: 'ws://namemeiprintserver1.vaiwan.com', // 开发者服务器接口地址,必须是 wss 协议,且域名必须是后台配置的合法域名 success: (res) => { } }); }, onPickerTap(e) { if (e.currentTarget.dataset.type == 'item') { //设置弹出的单选界面为显示 this.setData( { hidden: false }); } else { //跳转到蓝牙打印机 dd.navigateTo( { url: '../lianjielanyadayinji/lianjielanyadayinji' } ) } }, onShowSlect(e)//选者界面回掉韩素 { this.setData({ hidden: true }) //console.log(e); if (e == null) { return } //请求这个款的sku var IT_CODE = e.value.split(" ")[0]; GetSkuList({ ItCode: IT_CODE }).then(res => { //console.log(res); this.setData( { ITCODE_IT: IT_CODE, Skus: res.data.Data.Skus, Price: res.data.Data.ip_priceb } ) }) }, //同步输入的数字 onInputqty(e) { var str = 'Skus[' + e.target.dataset.index + '].qty'; this.setData( { [str]: e.detail.value } ) },//发送打印的数据 ontap() { //用条码来请求符合要求的数据 var str = ''; this.data.Skus.forEach(element => { if (element.qty != null && element.qty > 0) { str += element.Sku + "','"; } }); if (this.data.Price <= 0 || this.data.Price > 9000) { dd.alert({ title: '价格不对请先修改!' }) return; } if (str.length > 0) { var app = getApp(); GetPrintGood({ Code: str, type: 0 }).then(res => { if (res.data.ErrorCode == 0) { //把数量都添加到对应的地方上面 var oksku = []; res.data.Data.forEach(item => { this.data.Skus.forEach(list => { if (item.商品条码 == list.Sku) { item.数量 = list.qty oksku.push(item); } }) }) //如果是wifi if (this.data.printtype == 0) { this.connect_start(); dd.sendSocketMessage({ data: JSON.stringify(oksku), // 需要发送的内容 success: (res) => { dd.showToast({ type: 'success', content: '发送成功!' }); }, }); } else { if (this.data.characteristicId == '' || this.data.deviceId == '' || this.data.serviceId == '') { dd.showToast({ type: 'fail', content: '打印机未连接!' }) } else { console.log(oksku); this.setData({ oksku: oksku, printnum: 0 }) dd.showLoading(); this.printsku(); } } } else { dd.alert({ title: '请输入要打印的数量' }) } }) } }, printsku() { //通过蓝牙发送数据 var command = jpPrinter.createNew(); command.setSize(60, 40); command.setGap(0); command.setCls(); command.setText(0, 30, "TSS24.BF2", 1, 1, "品名:" + this.data.oksku[this.data.printnum].商品名称); //command.setText(0, 60, "TSS24.BF2", 1, 1, "款号:" + this.data.oksku[this.data.printnum].款号); command.setText(240, 70, "TSS24.BF2", 1, 1, "尺码:" + this.data.oksku[this.data.printnum].尺码描述); command.setText(0, 70, "TSS24.BF2", 1, 1, "颜色:" + this.data.oksku[this.data.printnum].颜色描述); command.setBar(0, 100, 128, 120, 1, 2, 1, this.data.oksku[this.data.printnum].商品条码); command.setText(240, 260, "TSS16.BF2", 2, 2, "零售价:" + this.data.oksku[this.data.printnum].建议零售价); command.setPagePrint(this.data.oksku[this.data.printnum].数量); var buffer = command.getData(); var looptime = parseInt(buffer.length / this.data.time);//发送次数 var lastData = parseInt(buffer.length % this.data.time);//余数 this.setData({ looptime: looptime + 1, lastData: lastData, currentTime: 1 }) //console.log(buffer.length); this.send(buffer); }, radioChannge(e) { //打印方式修改 this.setData( { printtype: e.detail.value, }) }, send(buff) { var buf; if (this.data.currentTime < this.data.looptime) { //如果当前发送次数小于总共需要发送的次数 buf = buff.substring((this.data.currentTime - 1) * this.data.time, this.data.currentTime * this.data.time); } else { //否者发送剩余的字节 buf = buff.substring((this.data.currentTime - 1) * this.data.time, (this.data.currentTime - 1) * this.data.time + this.data.lastData); } console.log(buf) //console.log('第' + this.data.currentTime + '次发送数据大小为:' + buf.byteLength); dd.writeBLECharacteristicValue({ deviceId: this.data.deviceId, serviceId: this.data.serviceId, characteristicId: this.data.characteristicId, value: buf, success: (res) => { console.log(res) }, fail: (res) => { console.log(res) }, complete: (res) => { if (this.data.currentTime < this.data.looptime) { //如果当前发送的次数小于或者等于总共要发送的次数,那么就进行加一 this.data.currentTime++; //console.log(this.data.currentTime); //开始下一次的发送 this.send(buff); } else { //打印下一个条码 this.data.printnum++; if (this.data.printnum < this.data.oksku.length) { this.printsku(); } else { dd.hideLoading() //发送完毕 dd.showToast({ type: 'success', content: '发送陈工' }) } } } }) } });
3.打印指令文件tsc.js
var app = getApp(); var encode = require("./encoding.js"); export const jpPrinter = { createNew: function () { var jpPrinter = {}; var data = ""; var command = []; var str = ""; jpPrinter.name = "蓝牙打印机"; jpPrinter.init = function () { }; jpPrinter.addCommand = function (content) { //将指令转成数组装起 //content = 'HEX'; var code = new encode.TextEncoder( 'gb18030', { NONSTANDARD_allowLegacyEncoding: true }).encode(content) for (var i = 0; i < code.length; ++i) { command.push(code[i]) } //str += content; } jpPrinter.setSize = function (pageWidght, pageHeight) { //设置页面大小 data = "SIZE " + pageWidght.toString() + " mm" + "," + pageHeight.toString() + " mm" + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setSpeed = function (printSpeed) { //设置打印机速度 data = "SPEED " + printSpeed.toString() + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setDensity = function (printDensity) { //设置打印机浓度 data = "DENSITY " + printDensity.toString() + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setGap = function (printGap) { //传感器 data = "GAP " + printGap.toString() + " mm\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setCountry = function (country) { //选择国际字符集 /* 001:USA 002:French 003:Latin America 034:Spanish 039:Italian 044:United Kingdom 046:Swedish 047:Norwegian 049:German */ data = "COUNTRY " + country + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setCodepage = function (codepage) { //选择国际代码页 /* 8-bit codepage 字符集代表 437:United States 850:Multilingual 852:Slavic 860:Portuguese 863:Canadian/French 865:Nordic Windows code page 1250:Central Europe 1252:Latin I 1253:Greek 1254:Turkish 以下代码页仅限于 12×24 dot 英数字体 WestEurope:WestEurope Greek:Greek Hebrew:Hebrew EastEurope:EastEurope Iran:Iran IranII:IranII Latvian:Latvian Arabic:Arabic Vietnam:Vietnam Uygur:Uygur Thai:Thai 1252:Latin I 1257:WPC1257 1251:WPC1251 866:Cyrillic 858:PC858 747:PC747 864:PC864 1001:PC100 */ data = "CODEPAGE " + codepage + "\r\n"; jpPrinter.addCommand(data) } jpPrinter.setCls = function () { //清除打印机缓存 data = "CLS" + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setFeed = function (feed) { //将纸向前推出n data = "FEED " + feed + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setBackFeed = function (backup) { //将纸向后回拉n data = "BACKFEED " + backup + "\r\n"; jpPrinter.addCommand(data) } jpPrinter.setDirection = function (direction) { //设置打印方向,参考编程手册 data = "DIRECTION " + direction + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setReference = function (x, y) { //设置坐标原点,与打印方向有关 data = "REFERENCE " + x + "," + y + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setFromfeed = function () { //根据Size进一张标签纸 data = "FORMFEED \r\n"; jpPrinter.addCommand(data) }; jpPrinter.setHome = function () { //根据Size找到下一张标签纸的位置 data = "HOME \r\n"; jpPrinter.addCommand(data) }; jpPrinter.setSound = function (level, interval) { //控制蜂鸣器 data = "SOUND " + level + "," + interval + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setLimitfeed = function (limit) { // 检测垂直间距 data = "LIMITFEED " + limit + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setBar = function (x, y, width, height) { //绘制线条 data = "BAR " + x + "," + y + "," + width + "," + height + "\r\n" jpPrinter.addCommand(data) }; jpPrinter.setBox = function (x_start, y_start, x_end, y_end, thickness) { //绘制方框 data = "BOX " + x_start + "," + y_start + "," + x_end + "," + y_end + "," + thickness + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setErase = function (x_start, y_start, x_width, y_height) { //清除指定区域的数据 data = "ERASE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setReverse = function (x_start, y_start, x_width, y_height) { //将指定的区域反相打印 data = "REVERSE " + x_start + "," + y_start + "," + x_width + "," + y_height + "\r\n"; jpPrinter.addCommand(data) }; jpPrinter.setText = function (x, y, font, x_, y_, str) { //打印文字 data = "TEXT " + x + "," + y + ",\"" + font + "\"," + 0 + "," + x_ + "," + y_ + "," + "\"" + str + "\"\r\n" jpPrinter.addCommand(data) }; jpPrinter.setQR = function (x, y, level, width, mode, content) { //打印二维码 data = "QRCODE " + x + "," + y + "," + level + "," + width + "," + mode + "," + 0 + ",\"" + content + "\"\r\n" jpPrinter.addCommand(data) }; jpPrinter.setBar = function (x, y, codetype, height, readable, narrow, wide, content) { //打印条形码 data = "BARCODE " + x + "," + y + ",\"" + codetype + "\"," + height + "," + readable + "," + 0 + "," + narrow + "," + wide + ",\"" + content + "\"\r\n" jpPrinter.addCommand(data) }; jpPrinter.setBitmap = function (x, y, mode, res) { //添加图片,res为画布参数 console.log(res) var width = parseInt((res.width + 7) / 8 * 8 / 8) var height = res.height; var time = 1; var temp = res.data.length - width * 32; var pointList = [] console.log(width + "--" + height) data = "BITMAP " + x + "," + y + "," + width + "," + height + "," + mode + "," jpPrinter.addCommand(data) for (var i = 0; i < height; ++i) { console.log(temp) for (var j = 0; j < width; ++j) { for (var k = 0; k < 32; k += 4) { if (res.data[temp] == 0 && res.data[temp + 1] == 0 && res.data[temp + 2] == 0 && res.data[temp + 3] == 0) { pointList.push(1) } else { pointList.push(0) } temp += 4 } } time++ temp = res.data.length - width * 32 * time } for (var i = 0; i < pointList.length; i += 8) { var p = pointList[i] * 128 + pointList[i + 1] * 64 + pointList[i + 2] * 32 + pointList[i + 3] * 16 + pointList[i + 4] * 8 + pointList[i + 5] * 4 + pointList[i + 6] * 2 + pointList[i + 7] command.push(p) } } jpPrinter.setPagePrint = function (qty) { //打印页面 data = "PRINT " + qty + ",1\r\n" jpPrinter.addCommand(data) }; //获取打印数据 jpPrinter.getData = function () { var buf = new ArrayBuffer(command.length); var dataView = new DataView(buf); for (var i = 0; i < command.length; ++i) { dataView.setUint8(i, command[i]); } return Array.prototype.map.call(new Uint8Array(buf), x => ('00' + x.toString(16)).slice(-2)).join(''); }; return jpPrinter; } };
这篇关于支付宝/钉钉小程序实现蓝牙打印的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-302024年最新版云开发cms开通步骤,开始开发微信小程序前的准备工作,认真看完奥!
- 2024-03-30微信小程序的网络设置,及网络请求:wx.request(OBJECT)
- 2024-01-22基于taro搭建小程序多项目框架
- 2024-01-13小程序开发:在插件市场寻找步骤条组件并二开
- 2024-01-05钉钉小程序生态—企业机器人加互动卡片,改善用户体验的开始!
- 2023-12-29【UniApp】-uni-app-打包成小程序
- 2023-12-26性能翻倍!京东亿级体量小程序优化实践
- 2023-12-25小程序优化:第三方SDK过大解决方案
- 2023-11-26微信小程序文件预览和下载-文件系统
- 2023-11-2652天学习微信小程序计划No.2:注册小程序账号&安装开发者工具