使用socket.io开发微信点餐并在后台蓝牙打印小票功能(一)

近期公司要开发个能连接蓝牙,并用蓝牙打印的一个app,由于遇到的坑比较多,特此纪录
也许你会问,为啥前端还要研究硬件?
前端为啥就不能研究硬件,前端工程师首先是工程师,不能把眼界局限在前端.而且通过cordova,用JS的语法就能开发硬件了,还能提高自己JS姿势,何乐而不为?
我们选择的打印机是主流的芯烨XP-58IIH热敏蓝牙打印机,厂家也提供了足够多的文档,编程手册,和开发实例.
我选择了 vue 和 cordova 来开发这个app,然后就是蓝牙插件的选择了,然后这里就遇到了第一个坑,一开始使用了 cordova-plugin-ble-central 这个蓝牙插件,也能扫描出来打印机的蓝牙信号,就是死活连不上,在查了资料,折腾了几个钟后才恍然大悟,我用的是低功耗蓝牙的插件,于是就选择了另外一个蓝牙插件 BluetoothSerial ,总算是能连上了,连接代码如下:


连上了就该打印了,打印英文还是很简单的


但是,在打印中文的时候就出问题了,


这肯定不行,下意识查看厂家提供的资料
厂家提供的是安卓源码,首先查找核心打印部分的代码,很快就找到了

然后开始分析这段代码:
这段代码主要作用是获取输入框内容,然后进行字符串拼接,最后通过getBytes("GBK")来转换成gbk码的字节数组
JAVA代码简单,到JS这里就不是一回事了,首先就卡在gbk编码上了,花了好长时间查询JS怎么转gbk编码,发现js原生不支持gbk转换,最后才锁定一个库,不过年久失修,原地址失效了,找了好久才下载到,于是我把它用module.exports包装了下,然后放到github上了
传送门
这个库能把中文转换成gbk编码的十六进制字符串,格式是%xx%yy形式的,比如转换”哈”这个字,是转换成”%B9%FE”的,然而我通过一番搜索发现打印机需要的格式是十六进制字节数组的,即类似[‘0xB9’,’0xFE’]格式的,这个好办,我写了个转换函数,用 replace加正则去掉第一个”%”,然后用split(“%”)转换成数组,再用map加上”0x”就行.不过最后也发现,这个库不会转换数字和字母,于是我又用 str.charCodeAt(0).toString(16)转换成对应的ASCII码,再加上”0x”,就OK了,整个转换函数也写好了,不知道还有没有更好的方法

整个转换源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const $ = require('./gbk.js')
module.exports=function(str) {
const arr = []
for (let i = 0; i < str.length; i++) {
const result = $.encode(str[i])
const length = result.length
switch (length) {
case 1:
const c = result.charCodeAt(0).toString(16)
arr.push("0x" +c)
break
case 3:
arr.push("0x" + result.replace(/%/, ''))
break
case 6:
const tmp = result.replace(/%/, '').split('%')
const newArr = tmp.map(item => "0x" + item)
arr.push(...newArr)
break
}
}
arr.push('0x0a')
return arr
}


然后在组件处引入

1
const encode =require('../encode.js')

再把这里要打印的内容用encode函数包起来

最后就可以愉快的打印中英文啦

如果需要打印表单内容,把encode里面内容换成this.content就行

app原始界面:

ps:文章简单,填坑艰辛,望能为后来人提供有用的帮助信息