连接蓝牙

  • 初始化蓝牙模块、找到对应连接的打印机 Bluetooth
  • 连接蓝牙 BLE
  • 找到支持写入数据 write、订阅变化 notify的特征值 characteristic

打印

  • 根据打印机提供API,拼接打印指令

    SIZE 40 mm,20 mm\r\n
    GAP 2 mm,0 mm\r\n
    CLS\r\n
    QRCODE 12,28,L,3,A,0,"http://172.16.0.20:15016?O22CdW14$A00002073106"\r\n
    TEXT 116,32,"3",0,1,1,"6233"\r\n
    TEXT 116,64,"3",0,1,1,"220704SK1001"\r\n
    TEXT 116,96,"3",0,1,1,"0"\r\n
    PRINT 1,1\r\n
    
  • 一张一张标签发送打印指令
  • 打印指令发送失败,记录索引下标,标签打印指令全部发送完成,弹窗提示是否重新打印失败的标签。
  • 标签发送失败 failArr记录下标,上一张标签发送指令失败(发送的指令不知在哪个位置发生截断),在数组起始位置添加换行符\r\n,使下一张标签的指令生效(都是记录思路的伪代码!
    /*** @param {Array} printData 需要打印的数据数组, 一项代表一张标签*/
    async function _print (printData = []) {const number = 1, // 几张标签调用函数发送一次打印指令failArr = [];   // 记录失败的标签let command = [],num = 0,percentage = 0;   // 进度for (let i = 0, len = printData.length; i < len; i++) {command = [...];    // ... 拼接打印指令 调用打印机API转为数组num++;if ((number === num) || ((i === len - 1) && num > 0)) {// 发送打印指令const arr = await handleSend(i - number + 1, i, command);  // 调用函数发送打印指令if (arr.length) {// 打印指令发送失败 记录索引下标failArr.push(...arr);}// 重新记录打印指令num = 0;command = [];if (arr.length) {// 上一张标签的打印指令发送失败, 在下一张标签起始位置添加换行符, 使CLS生效command.push(...);   // EOL}}percentage = Math.ceil((i + 1) / len * 100);  // 更新进度}if (failArr.length) {// 处理发送失败的标签const arr = printData.filter((item, index) => (failArr.indexOf(index) != -1));// 弹窗提示:以下编号的标签打印失败:8、16,是否需要重新打印?// 如果用户选择重新打印return this._print(arr);}
    }
    
  • 发送打印指令(number张标签)
  • 若打印指令发送失败,手动添加换行符\r\n,使CLS生效,重试3次
  • 若发送失败,返回打印指令发送失败的索引下标
    async function handleSend(begin, end, command) {const retryCount = 3;  // 定义重试次数let complete = false, // 是否打印完成tryNum = 0;           // 尝试打印次数while (!complete && (tryNum < (retryCount + 1))) {tryNum++;if (tryNum == 2) {// 指令发送失败 直接结束循环 重新发送打印指令(尝试打印的第2次)// 在数组起始位置添加换行符 (使CLS生效)command.unshift(...);  // EOL}const hasFail = await send(command);if (hasFail) {console.log('--- 重新打印 --->', end);}complete = !hasFail;}const arr = [];if (!complete) {for (let j = begin; j <= end; j++) {arr.push(j); // 打印指令发送失败的标签索引}}return arr;
    }
    
  • 分包发送打印指令:若某次指令发送失败,直接结束循环,结束函数
  • 通过蓝牙写入数据发送打印指令,官网建议每次写入不超过20字节 oneTimeData
    async function send(buff) {const oneTimeData = 20, // 每次发送字节数printNum = 1;        // 打印份数const loopTime = Math.ceil(buff.length / oneTimeData),  // 一份发送几次 = buff / 每次发送字节数lastData = parseInt(buff.length % oneTimeData);for (let i = 0; i < printNum; i++) {   // printNum 份// 第 i 份for (let j = 0; j < loopTime; j++) {     // 循环发送// 分包发送的第 j 次const size = (j == loopTime - 1 && lastData > 0) ? lastData : oneTimeData;    // 是否余数 ? lastData : 每次发送字节数const buf = new ArrayBuffer(size);const dataView = new DataView(buf);for (let k = 0; k < size; k++) {const index = j * oneTimeData + k;dataView.setUint8(k, buff[index]);}const flag = await handleSendItem(buf, j, loopTime);if (!flag) {console.warn(`fail: 发送的第${j}次, 共发送${loopTime}次 (经多次重试失败)`);// 指令发送失败 直接结束循环 不继续往后发return true;}}}return false;
    }
    
  • 问题:不确定哪次指令发送失败,直接结束循环,可能导致打印机走纸,但是没有打印内容,也可能中间几张标签丢失(没想明白原因)
  • 解决方法:
    • handleSendItem函数内部添加逻辑,如果某个包(20字节)发送失败,这个包重试3次。
    • 若仍旧失败,再走之前逻辑,问题依旧在,只是概率小
    async function handleSendItem(buf, j, loopTime) {const retryCount = 3;   // 定义重试次数let complete = false, // 指令是否发送完成tryNum = 0;         // 尝试发送次数while (!complete && (tryNum < (retryCount + 1))) {tryNum++;if (tryNum > 1) {console.log('重新发送这个包', tryNum);}// 调用 uni.writeBLECharacteristicValue 向低功耗蓝牙设备特征值中写入二进制数据 发送打印指令const flag = await writeBLECharacteristicValue(buf);if (!flag) {console.warn(`fail: 发送的第${j}次, 共发送${loopTime}次`);}complete = flag;}return complete;
    }
    

流程图

流程图:标签打印(语雀)

问题

  • 某一张标签指令发送失败,直接结束循环,重新发送指令,或直接发送下一张标签指令

    • 往数组前添加换行符EOL使CLS生效,可能导致空标签、几张标签漏打印
  • 解决方法:
    • 某个包发送失败,这个包重新发送,重试三次
    • 若仍旧失败,走之前流程(结束循环,发送下一张标签指令)
    • 问题依旧在,只是概率小 ~( TロT)σ

优化

  • handleSendhandleSendItem 通过调用函数 _try 传入参数tryNum(重试次数)、fn(处理函数)处理重试逻辑

    function isPromise(obj) {return obj instanceof Promise;// return (!!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function');
    }/*** 传入参数tryNum(重试次数)、fn(处理函数)处理重试逻辑* @param {Function} fn 处理函数 返回Boolean(是否成功); 或者返回Promise, thenable返回状态数据Boolean(是否成功)* @param {Number} retryCount 重试次数* @returns {Promise} 是否执行成功*/
    async function _try(fn, retryCount = 3) {if (retryCount < 0) {console.warn('retryCount must be greater than 0');retryCount = 0;}let tryNum = 0, // 执行次数complete = false; // 是否完成while (!complete && (tryNum < (retryCount + 1))) {tryNum++;if (tryNum > 1) {console.log(`重试第${tryNum - 1}次`);}let result = fn.call(this, tryNum);if (isPromise(result)) {result = await result;}if (result) { // 执行成功complete = true;}}return complete;
    }
    
  • 优化 handleSend
    async function handleSend(begin, end, command) {const complete = await _try(async (tryNum) => {// 处理函数if (tryNum == 2) {// 指令发送失败 直接结束循环 重新发送打印指令(尝试打印的第2次)// 在数组起始位置添加换行符 (使CLS生效)command.unshift(...); // EOL}const hasFail = await send(command);return !hasFail;}, 3); // 重试3次const arr = [];if (!complete) {for (let j = begin; j <= end; j++) {arr.push(j); // 打印指令发送失败的标签索引}}return arr;
    }
    
  • 优化 handleSendItem
    async function handleSendItem(buf, j, loopTime) {const complete = await _try(() => {// 调用 uni.writeBLECharacteristicValue 向低功耗蓝牙设备特征值中写入二进制数据 发送打印指令const flag = await writeBLECharacteristicValue(buf);if (!flag) {console.warn(`fail: 发送的第${j}次, 共发送${loopTime}次`);}return flag;}, 3); // 重试3次return complete;
    }
    

uniapp 标签打印 笔记相关推荐

  1. uniapp 标签技能多选 最多选三个

    uniapp 标签技能多选 最多选三个 html部分 <template><view class="en"><view class="xh& ...

  2. 调用 标签打印软件_标签打印软件如何制作陶瓷标签模板

    产品贴上标签可以让客户在外观上对产品有一个大概的了解,也能很快的从标签文字上得到产品用途等信息.现在市面上所见到的各种产品都有自己的标签,而且很多建材比如门板,窗户.家具.电器等等也是有自己的标签,包 ...

  3. brother标签打印软件_标签打印软件如何设计食品留样标签模板

    食品留样标签是为了记录从早中晚餐中预留的食品的名称.留样时间,留样人等信息,方便对食品的检测等等.那么食品留样标签模板是如何设计的呢?接下来用中琅标签打印软件给大家演示一下具体的操作方法. 运行中琅标 ...

  4. access 打印预览 代码_标签打印软件如何批量打印样品标签

    一般产品在进行大批量生产之前都需要先生产一批样品进行检测,当样品合格率达到了才能大批量的生产产品.或者是从某些地方取一些样品进行检测,如石油样品,土壤样品等等.样品标签就是为了记录下样品名称.样品编号 ...

  5. 屏幕中间显示已停用缩放_有关标签打印软件缩放工具的介绍

    在标签打印软件中设计标签时,为了方便编辑,有时会根据自己的需求放大缩小标签来精确位置大小等,做更细致的调整,这时就会用到缩放工具.下面,主要就是给大家介绍标签打印软件缩放工具的用处: 在标签打印软件中 ...

  6. 票据打印, 账单打印, 标签打印, 文档打印, 条码打印, 批量打印, 包装纸打印与设计,可变数据打印打印,发布,VC++源代码组件库解决方案...

    票据打印, 账单打印, 标签打印, 文档打印, 条码打印, 批量打印, 包装纸打印与设计,可变数据打印打印,发布,VC++源代码组件库解决方案 使用E-Form++源码库开发任何标签,票据,文档,条码 ...

  7. pads中如何设置等长_标签打印软件中标签间距以及边距如何设置

    我们在用标签打印软件设置标签纸时,通常会遇到上下左右边距,以及上下间距或左右间距等,如果是平面纸,可能边距以及间距方面会比较好设置和理解但是对于小标签纸的边距该如何设置呢? 在本站其他技术文档中有对于 ...

  8. 如何改变tabcontrol控件背景色和标签字体和颜色_如何利用标签打印软件将网址信息转成带logo的二维码...

    随着二维码应用范围越来越广,个别客户在标签打印软件中制作二维码时有特殊要求,想要制作网址二维码并在二维码中间插入图片,咨询这个该如何操作,接下来我们一起来看下具体的操作步骤吧: 1.在标签打印软件中点 ...

  9. 林期苏曼属性标签编辑_标签打印软件如何打印指定日期

    我们平时见到的产品标签上,很多都会有生产日期或者出厂日期等,而且大多还会有保质期,或者有效期,那么这些指定的日期如何在标签打印软件中统一设置并一起打印出来呢?下面我们就中琅标签打印软件来详细看一下如何 ...

  10. brother标签打印软件_标签打印软件如何调整字体高度

    在我们使用标签打印软件添加文字内容时,经常会需要对文字部分做各种各样的放大缩小等调整以适应整个标签内容的展示效果.工具栏中的字体字号都是宽高同时放大或缩小,如果只是想要调整字体高度该如何操作呢,下面我 ...

最新文章

  1. 浅谈Angular如何自定义创建指令@Directive
  2. 敏捷软件开发实践——估算与计划(01)
  3. Flutter开发之爬坑集合(五)
  4. WPF-MVVM学习心德(WinForm转WPF心德)
  5. Oracle-绑定变量binding variable解读
  6. linux jar命令找不到 -bash: jar: command not found
  7. 阶段1 语言基础+高级_1-3-Java语言高级_02-继承与多态_第1节 继承_7_继承中方法的覆盖重写_注意事项...
  8. MFC中如何让一个CStatic控件响应消息
  9. html坐标绘制路径,canvas学习笔记之绘制简单路径
  10. Tensorflow学习—— Estimator简介
  11. 联想台式机usb驱动_windows安装系列教程—驱动安装
  12. 廖雪峰 - nodejs教程
  13. 基于深度学习的短视频内容分析简介
  14. 《Python黑客编程之极速入门》正式开课
  15. 软件测试经典案例佣金问题,佣金等价划分和测试用例设计.PPT
  16. 《Java性能调优实战》00丨开篇词丨怎样才能做好性能调优?2022.03.08-20220329学习完
  17. cross product or vector product - 叉积或向量积
  18. linux内核源码分析之proc文件系统(三)
  19. python3 使用相对路径 import模块
  20. 学习笔记(十八):MoRe-Fi用深度学习网络从非线性信号中恢复呼吸波形

热门文章

  1. 计算机网络(2.12)物理层- 宽带接入技术-FTTx技术
  2. 5个免费可商用的图片素材网站,赶快收藏
  3. 速记JVM内存模型和垃圾回收策略
  4. 情感预测SHINE: Signed Heterogeneous Information Network Embedding for Sentiment Link Prediction引介
  5. 引用 USB启动盘,将DOS工具集成到WinPE的grub - Windows
  6. linux ip转发 丢包,sendto频率过快导致发送丢包
  7. 使用excel分类汇总数据生成饼图
  8. MySQL:互联网公司常用分库分表方案汇总
  9. kali系统自带的aircrack-ng破解WIFI
  10. 怎样设置公众号自动回复