blePrintMixin.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import { mapState, mapActions } from "vuex";
  2. import { FakeConnectedDevice } from "@psdk/frame-father";
  3. import bluetoothTool from "@/plugins/BluetoothTool.js";
  4. import { printMaterial } from "@/common/request/apis/print";
  5. import printPop from "@/components/print-pop/print-pop.vue";
  6. import blePop from "@/components/ble-pop/ble-pop.vue";
  7. import bleTipPop from "@/components/ble-tip-pop/ble-tip-pop.vue";
  8. import {
  9. TBar,
  10. TBarCode,
  11. TQRCode,
  12. TBox,
  13. TImage,
  14. TPage,
  15. TRotation,
  16. TCodeType,
  17. TLine,
  18. TText,
  19. TFont,
  20. TTLine,
  21. } from "@psdk/tspl";
  22. ///转成安卓有符号的
  23. function uint8ArrayToSignedArray(uint8Array) {
  24. let signedArray = new Array(uint8Array.length);
  25. for (let i = 0; i < uint8Array.length; i++) {
  26. if (uint8Array[i] >= 128) {
  27. signedArray[i] = uint8Array[i] - 256;
  28. } else {
  29. signedArray[i] = uint8Array[i];
  30. }
  31. }
  32. return signedArray;
  33. }
  34. async function sendMessage(cmd) {
  35. console.log(cmd);
  36. const result = bluetoothTool.sendByteData(cmd);
  37. uni.showToast({
  38. icon: "none",
  39. title: result ? "发送成功!" : "发送失败...",
  40. });
  41. }
  42. export default {
  43. name: "blePrintMixin",
  44. components: {
  45. printPop,
  46. blePop,
  47. bleTipPop,
  48. },
  49. computed: {
  50. ...mapState({
  51. discoveredDevices: (state) => state.ble.discoveredDevices, // 已发现的蓝牙设备
  52. connectedBleDevice: (state) => state.ble.connectedBleDevice,
  53. connectedDeviceId: (state) => state.ble.connectedDeviceId, // 已连接的蓝牙设备ID
  54. }),
  55. },
  56. data() {
  57. return {
  58. bleErrorTipPop: {
  59. show: false,
  60. content: "未连接 蓝牙",
  61. extraText: "请连接蓝牙之后再继续操作",
  62. },
  63. // 蓝牙打印弹框
  64. blePrintPop: {
  65. show: false,
  66. data: {},
  67. },
  68. // 选择蓝牙设备弹框
  69. bleSelectPop: {
  70. show: false,
  71. discoveredDevices: [],
  72. },
  73. };
  74. },
  75. methods: {
  76. ...mapActions("ble", [
  77. "checkBleStatus", // 检查蓝牙设备连接状态
  78. "discovery", // 搜索蓝牙设备
  79. "connectBT", // 连接蓝牙设备
  80. "cancelDiscovery", // 停止蓝牙搜索
  81. ]),
  82. bleErrorTipConfirm() {
  83. this.bleErrorTipPop.show = false;
  84. this.openBleSelectPop();
  85. },
  86. //打开蓝牙选择弹框
  87. openBleSelectPop() {
  88. this.discovery(); // 搜索蓝牙设备
  89. this.bleSelectPop.show = true;
  90. },
  91. //关闭蓝牙选择弹框
  92. closeBleSelectPop() {
  93. this.cancelDiscovery();
  94. this.bleSelectPop.show = false;
  95. },
  96. //选择蓝牙设备
  97. async handleSelectBle(item) {
  98. console.log("选择蓝牙设备=====", item);
  99. const device = await this.connectBT(item);
  100. if (device) {
  101. this.closeBleSelectPop();
  102. this.$printer.init(new FakeConnectedDevice()); // 初始化打印机
  103. this.blePrintPop.show = true;
  104. }
  105. console.log("this.blePrintPop.data=====", this.blePrintPop.data);
  106. },
  107. // 打开蓝牙打印弹框
  108. async openBlePrintPop(data) {
  109. const res = await this.checkBleStatus(); // 检查蓝牙设备打开状态
  110. this.blePrintPop.data = data;
  111. switch (res.code) {
  112. case 0:
  113. // const devices = bluetoothTool.getPairedDevices(); // 获取已配对的蓝牙设备
  114. // console.log("devices======", devices);
  115. if (this.connectedDeviceId != "") {
  116. this.blePrintPop.show = true;
  117. } else {
  118. // 如果没有配对的设备,提示用户去配对
  119. this.bleErrorTipPop.show = true;
  120. }
  121. break;
  122. case 1:
  123. uni.showToast({
  124. icon: "none",
  125. title: "请打开蓝牙",
  126. });
  127. break;
  128. case 2:
  129. uni.showToast({
  130. icon: "none",
  131. title: "当前设备不支持蓝牙",
  132. });
  133. break;
  134. }
  135. },
  136. // 重新搜索蓝牙设备
  137. refreshBleDevice() {
  138. this.discovery();
  139. },
  140. /**
  141. * 打印
  142. *@data {Object} 需要打印的数据
  143. *@num {number} 需要打印的数量
  144. * */
  145. async writeTsplModel(data, num = 1) {
  146. const vm = this;
  147. const obj = {
  148. qrCode: data.number, // 二维码
  149. barCode: data.barCode, // 商品条码
  150. customerName: data.customerName, //客户名
  151. number: data.number, // 单据编号
  152. };
  153. try {
  154. let cellWidth = 6;
  155. if (obj.qrCode.length > 30) cellWidth = 4;
  156. if (obj.qrCode.length > 60) cellWidth = 2;
  157. const startX = 80;
  158. const startY = 30;
  159. const qrcodeX = startX;
  160. const qrcodeY = startY;
  161. const qrcodeSize = cellWidth * 21; // 经验值
  162. const textStartX = qrcodeX + qrcodeSize + 10;
  163. const textStartY = qrcodeY;
  164. const textLineHeight = 28;
  165. const barcodeX = startX;
  166. const barcodeY =
  167. Math.max(qrcodeY + qrcodeSize, textStartY + textLineHeight * 3) + 15;
  168. const barcodeHeight = 50;
  169. const tspl = await vm.$printer
  170. .tspl()
  171. .clear()
  172. .page(new TPage({ width: 76, height: 130 }))
  173. .qrcode(
  174. new TQRCode({
  175. x: qrcodeX,
  176. y: qrcodeY,
  177. content: obj.qrCode,
  178. cellWidth,
  179. })
  180. )
  181. .text(
  182. new TText({
  183. x: textStartX,
  184. y: textStartY,
  185. content: obj.customerName,
  186. font: TFont.TSS24,
  187. })
  188. )
  189. .text(
  190. new TText({
  191. x: textStartX,
  192. y: textStartY + textLineHeight * 2,
  193. content: obj.number,
  194. font: TFont.TSS24,
  195. })
  196. )
  197. .barcode(
  198. new TBarCode({
  199. x: barcodeX,
  200. y: barcodeY,
  201. cellWidth: 2,
  202. height: barcodeHeight,
  203. content: obj.barCode,
  204. rotation: TRotation.ROTATION_0,
  205. codeType: TCodeType.CODE128,
  206. showType: 2,
  207. })
  208. )
  209. .print(num);
  210. var binary = tspl.command().binary();
  211. await sendMessage(Array.from(uint8ArrayToSignedArray(binary)));
  212. } catch (e) {
  213. console.error(e);
  214. uni.showToast({
  215. title: "失败",
  216. });
  217. }
  218. },
  219. async writeData({ num = 1, data }) {
  220. await this.writeTsplModel(data, num);
  221. },
  222. //条码逻辑
  223. async handlePrint(id) {
  224. try {
  225. uni.showLoading({
  226. mask: true,
  227. });
  228. const res = await printMaterial({ id });
  229. console.log("item===id==", id);
  230. console.log("res=====", res);
  231. if (res.code == 200) {
  232. const data = {
  233. customerName: res.data.customerName,
  234. number: res.data.number,
  235. barCode: res.data.barCode,
  236. };
  237. this.openBlePrintPop(data);
  238. } else {
  239. uni.showToast({
  240. icon: "none",
  241. title: res.msg || res.data || "服务器错误",
  242. duration: 2000,
  243. });
  244. }
  245. } catch (error) {
  246. //TODO handle the exception
  247. } finally {
  248. uni.hideLoading();
  249. }
  250. },
  251. //开始打印
  252. startPrint(data) {
  253. this.writeData(data);
  254. },
  255. },
  256. };