blePrintMixin.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. batchNumber: data.batchNumber, // 单据编号
  153. type: data.type, // 入库:1 出库;2
  154. status: data.status, // 订单状态 入库状态为2才有批次号,出库不显示批次号
  155. };
  156. try {
  157. let cellWidth = 6;
  158. if (obj.qrCode.length > 30) cellWidth = 4;
  159. if (obj.qrCode.length > 60) cellWidth = 2;
  160. const startX = 50;
  161. const startY = 30;
  162. const qrcodeX = startX;
  163. const qrcodeY = startY;
  164. const qrcodeSize = cellWidth * 21; // 经验值
  165. const textStartX = qrcodeX + qrcodeSize + 10;
  166. const textStartY = qrcodeY;
  167. const textLineHeight = 28;
  168. const barcodeX = startX;
  169. const barcodeY =
  170. Math.max(qrcodeY + qrcodeSize, textStartY + textLineHeight * 3) + 15;
  171. const barcodeHeight = 50;
  172. console.log("obj==========", obj);
  173. let tspl;
  174. if (obj.type == 2) {
  175. tspl = await vm.$printer
  176. .tspl()
  177. .clear()
  178. .page(new TPage({ width: 76, height: 130 }))
  179. .qrcode(
  180. new TQRCode({
  181. x: qrcodeX,
  182. y: qrcodeY,
  183. content: obj.qrCode,
  184. cellWidth,
  185. })
  186. )
  187. .text(
  188. new TText({
  189. x: textStartX,
  190. y: textStartY,
  191. content: obj.customerName,
  192. font: TFont.TSS24,
  193. })
  194. )
  195. .text(
  196. new TText({
  197. x: textStartX,
  198. y: textStartY + textLineHeight * 2,
  199. content: obj.number,
  200. font: TFont.TSS24,
  201. })
  202. )
  203. .barcode(
  204. new TBarCode({
  205. x: barcodeX,
  206. y: barcodeY,
  207. cellWidth: 2,
  208. height: barcodeHeight,
  209. content: `${obj.barCode}`,
  210. rotation: TRotation.ROTATION_0,
  211. codeType: TCodeType.CODE128,
  212. showType: 0,
  213. })
  214. )
  215. .text(
  216. new TText({
  217. x: barcodeX,
  218. y: barcodeY + barcodeHeight + 5,
  219. content: `SKU-${obj.barCode}`,
  220. font: TFont.TSS16,
  221. })
  222. )
  223. .print(num);
  224. } else {
  225. if (obj.status == 2) {
  226. tspl = await vm.$printer
  227. .tspl()
  228. .clear()
  229. .page(new TPage({ width: 76, height: 130 }))
  230. .barcode(
  231. new TBarCode({
  232. x: 50,
  233. y: 30,
  234. cellWidth: 2,
  235. height: 100,
  236. content: `${obj.barCode}`,
  237. rotation: TRotation.ROTATION_0,
  238. codeType: TCodeType.CODE128,
  239. showType: 0,
  240. })
  241. )
  242. .text(
  243. new TText({
  244. x: 50,
  245. y: 30 + 100 + 5,
  246. content: `SKU-${obj.barCode}`,
  247. font: TFont.TSS16,
  248. })
  249. )
  250. .barcode(
  251. new TBarCode({
  252. x: 50,
  253. y: 30 + 100 + 5 + 35,
  254. cellWidth: 2,
  255. height: 50,
  256. content: `${obj.batchNumber}`,
  257. rotation: TRotation.ROTATION_0,
  258. codeType: TCodeType.CODE128,
  259. showType: 0,
  260. })
  261. )
  262. .text(
  263. new TText({
  264. x: 50,
  265. y: 30 + 100 + 5 + 35 + 50 + 5,
  266. content: `PC${obj.batchNumber}`,
  267. font: TFont.TSS16,
  268. })
  269. )
  270. .print(num);
  271. } else {
  272. tspl = await vm.$printer
  273. .tspl()
  274. .clear()
  275. .page(new TPage({ width: 76, height: 130 }))
  276. .barcode(
  277. new TBarCode({
  278. x: 50,
  279. y: 30,
  280. cellWidth: 2,
  281. height: 100,
  282. content: `${obj.barCode}`,
  283. rotation: TRotation.ROTATION_0,
  284. codeType: TCodeType.CODE128,
  285. showType: 0,
  286. })
  287. )
  288. .text(
  289. new TText({
  290. x: 50,
  291. y: 30 + 100 + 5,
  292. content: `SKU-${obj.barCode}`,
  293. font: TFont.TSS16,
  294. })
  295. )
  296. .print(num);
  297. }
  298. }
  299. var binary = tspl.command().binary();
  300. await sendMessage(Array.from(uint8ArrayToSignedArray(binary)));
  301. } catch (e) {
  302. console.error(e);
  303. uni.showToast({
  304. title: "失败",
  305. });
  306. }
  307. },
  308. async writeData({ num = 1, data }) {
  309. await this.writeTsplModel(data, num);
  310. },
  311. //条码逻辑
  312. async handlePrint(id, type, status) {
  313. try {
  314. uni.showLoading({
  315. mask: true,
  316. });
  317. const res = await printMaterial({ id });
  318. console.log("item===id==", id);
  319. console.log("res=====", res);
  320. console.log("type=====", type);
  321. console.log("status=====", status);
  322. if (res.code == 200) {
  323. const data = {
  324. customerName: res.data.customerName,
  325. number: res.data.number,
  326. barCode: res.data.barCode,
  327. batchNumber: res.data.batchNumber,
  328. type,
  329. status,
  330. };
  331. this.openBlePrintPop(data);
  332. } else {
  333. uni.showToast({
  334. icon: "none",
  335. title: res.msg || res.data || "服务器错误",
  336. duration: 2000,
  337. });
  338. }
  339. } catch (error) {
  340. //TODO handle the exception
  341. } finally {
  342. uni.hideLoading();
  343. }
  344. },
  345. //开始打印
  346. startPrint(data) {
  347. this.writeData(data);
  348. },
  349. },
  350. };