| | |
| | | |
| | | // 在全局定义一个变量来标识是否已经初始化 |
| | | var isPrinterInitialized = false; |
| | | |
| | | import { |
| | | getUserInfo |
| | | } from "@/utils/auth.js"; |
| | | import { |
| | | CommonUtils |
| | | } from "@/utils/common.js" |
| | | import { |
| | | PrinterWS |
| | | } from "@/utils/Print_HK.js" |
| | | export default { |
| | | data() { |
| | | return { |
| | |
| | | barCodeSplitInfo: [], //拆码信息 |
| | | cantGenerate: true, // 生成按钮初始禁用 |
| | | cantPrint: true, // 打印按钮初始禁用 |
| | | cantPrint_HK: true, // 打印按钮初始禁用 |
| | | cantSplit: false, // 拆码按钮初始可用 |
| | | HBarCodeFocus: false, |
| | | isPrinting: false, |
| | | printInfo: "" //打印 |
| | | printInfo: "" ,//打印, |
| | | socketTask: null, // 存放 uni-app WebSocket 实例 |
| | | wsConnected: false, |
| | | wsReconnectTimer: null, |
| | | wsHeartbeatTimer: null, |
| | | }; |
| | | }, |
| | | methods: { |
| | |
| | | printer.setConcentration({ //设置打印浓度。font_level 取值范围:1~39。 |
| | | level: 39 |
| | | }); |
| | | |
| | | }, |
| | | printerLabel() { |
| | | const formatDate = new Date().toISOString().split('T')[0]; |
| | |
| | | }, |
| | | printerLabel_HK() { |
| | | //设置打印内容 |
| | | |
| | | var HPrintData = "SIZE 58 mm,40 mm" + '\r\n';//设置标签纸张大小; |
| | | HPrintData += "CLS" + '\r\n';//清除图像缓存区 |
| | | const formatDate = new Date().toISOString().split('T')[0]; |
| | | var HPrintData = "SIZE 58 mm,40 mm" + '\r\n'+ '\r\n'; //设置标签纸张大小; |
| | | HPrintData += "CLS" + '\r\n'+ '\r\n'; //清除图像缓存区 |
| | | //TEXT X, Y, “font”, rotation, x-multiplication, y-multiplication, [alignment,] |
| | | //X:文本X坐标; Y:文本Y坐标; font:字体名称; rotation:文字旋转角度(0:不旋转,90:90 度,180:180 度,270:270 度); x-multiplication:水平方向放大; y-multiplication:垂直方向放大; alignment:指定文本对齐方式(0:默认(居左),1:居左,2:居中,3:居右); content:需要打印的文本内容。 |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '供应商名称:' + this.barCodeInfo['供应商'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '物料代码:' + this.barCodeInfo['物料代码'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '物料简称:' + this.barCodeInfo['物料简称'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '数量:' + this.barCodeInfo['剩余数量'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '工号:' + this.barCodeInfo['工号'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '生产日期:' + this.barCodeInfo['生产日期'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '流水号:' + this.barCodeInfo['流水号'] + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1' + '打印日期:' + formatDate + '\r\n'; |
| | | HPrintData += this.barCodeInfo['条码编号']; |
| | | printer.sendCommand_HK(HPrintData); |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"供应商名称:' + this.barCodeInfo['供应商'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"物料代码:' + this.barCodeInfo['物料代码'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"物料简称:' + this.barCodeInfo['物料简称'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"数量:' + this.barCodeInfo['剩余数量'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"工号:' + this.barCodeInfo['工号'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"生产日期:' + this.barCodeInfo['生产日期'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"流水号:' + this.barCodeInfo['流水号'] + '"' + '\r\n' + '\r\n'; |
| | | HPrintData += 'TEXT 50, 50, "4",0,1,1,1,' + '"打印日期:' + formatDate + '"' + '\r\n' + '\r\n'; |
| | | //HPrintData += this.barCodeInfo['条码编号']; |
| | | HPrintData += 'PRINT 1' + '\r\n' + '\r\n'; |
| | | |
| | | |
| | | var HPrintData2 = "SIZE 58 mm,40 mm" + '\r\n'+ '\r\n'; //设置标签纸张大小; |
| | | HPrintData2 += "CLS" + '\r\n'+ '\r\n'; //清除图像缓存区 |
| | | HPrintData2 += 'TEXT 50, 50, "4",0,1,1,1,"DEMO FOR TEXT"' + '\r\n'+ '\r\n'; |
| | | HPrintData2 += 'QRCODE 0, 92, M, 4, A, 0, M1,S0,"ABCD1234"' + '\r\n'+ '\r\n'; |
| | | HPrintData2 += 'PRINT 1' + '\r\n' + '\r\n'; |
| | | |
| | | |
| | | this.sendCommand_HK(HPrintData2); |
| | | }, |
| | | // 发送打印命令 |
| | | sendCommand_HK(commandData) { |
| | | if (this.ws.readyState === WebSocket.OPEN) { |
| | | // this.ws.send(JSON.stringify(commandData)); |
| | | this.ws.send(commandData); |
| | | |
| | | } else { |
| | | console.error('WebSocket 未连接'); |
| | | async sendCommand_HK(commandData) { |
| | | // 检查 WebSocket 是否已连接 |
| | | if (!this.socketTask) { |
| | | console.error('WebSocket 未初始化'); |
| | | uni.showToast({ |
| | | title: '打印机未连接', |
| | | icon: 'none' |
| | | }); |
| | | return false; |
| | | } |
| | | |
| | | if (this.socketTask.readyState === 1) { |
| | | console.log("打印内容:" + '\r\n' + commandData); |
| | | this.socketTask.send({ |
| | | data: commandData, |
| | | success: () => { |
| | | console.log('命令发送成功'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('命令发送失败:', err); |
| | | } |
| | | }); |
| | | return true; |
| | | } else { |
| | | console.error('WebSocket 未连接,当前状态:', this.socketTask.readyState); |
| | | uni.showToast({ |
| | | title: '打印机连接中,请稍后重试', |
| | | icon: 'none' |
| | | }); |
| | | return false; |
| | | } |
| | | }, |
| | | // 初始化连接 |
| | | async connect() { |
| | | return new Promise((resolve, reject) => { |
| | | // 关闭现有连接 |
| | | if (this.socketTask) { |
| | | try { |
| | | this.socketTask.close(); |
| | | } catch(e) {} |
| | | this.socketTask = null; |
| | | } |
| | | |
| | | // 根据实际环境配置 - 注意:在真实PDA上可能需要具体IP |
| | | // 先尝试使用 127.0.0.1,如果不行再尝试实际IP 'ws://localhost:40002' |
| | | const wsUrl = 'ws://192.168.2.141:40001'; |
| | | |
| | | console.log('准备连接 WebSocket:', wsUrl); |
| | | |
| | | this.socketTask = uni.connectSocket({ |
| | | url: wsUrl, |
| | | success: () => { |
| | | console.log('WebSocket 连接创建成功'); |
| | | }, |
| | | fail: (err) => { |
| | | console.error('WebSocket 连接失败:', err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | |
| | | // 设置超时 |
| | | const timeoutId = setTimeout(() => { |
| | | console.log('连接超时'); |
| | | if (this.socketTask && this.socketTask.close) { |
| | | this.socketTask.close(); |
| | | } |
| | | reject(new Error('连接超时(5秒)')); |
| | | }, 5000); |
| | | |
| | | console.log("this.socketTask内容:" + JSON.stringify(this.socketTask)); |
| | | // 监听打开事件 |
| | | this.socketTask.onOpen(() => { |
| | | clearTimeout(timeoutId); |
| | | console.log("WebSocket 连接成功,readyState:", this.socketTask.readyState); |
| | | this.wsConnected = true; |
| | | resolve(); |
| | | }); |
| | | |
| | | // 监听错误事件 - 这里会收到详细的错误信息 |
| | | this.socketTask.onError((err) => { |
| | | clearTimeout(timeoutId); |
| | | console.error("WebSocket 错误详情:", JSON.stringify(err)); |
| | | console.error("WebSocket readyState:", this.socketTask.readyState); |
| | | this.wsConnected = false; |
| | | reject(new Error('WebSocket 连接失败: ' + JSON.stringify(err))); |
| | | }); |
| | | |
| | | // 监听关闭事件 |
| | | this.socketTask.onClose((res) => { |
| | | clearTimeout(timeoutId); |
| | | console.log("WebSocket 连接关闭,code:", res.code, "reason:", res.reason); |
| | | console.log("关闭时的 readyState:", this.socketTask.readyState); |
| | | this.wsConnected = false; |
| | | |
| | | // 如果是非正常关闭,提示用户 |
| | | if (res.code !== 1000) { |
| | | console.warn('非正常关闭,错误码:', res.code); |
| | | } |
| | | }); |
| | | |
| | | // 监听消息 |
| | | this.socketTask.onMessage((res) => { |
| | | console.log("收到打印机消息:", res.data); |
| | | }); |
| | | }); |
| | | }, |
| | | // 添加心跳检测,保持连接 |
| | | startHeartbeat() { |
| | | if (this.wsHeartbeatTimer) { |
| | | clearInterval(this.wsHeartbeatTimer); |
| | | } |
| | | |
| | | this.wsHeartbeatTimer = setInterval(() => { |
| | | if (this.socketTask && this.socketTask.readyState === 1) { |
| | | // 发送心跳包 |
| | | this.socketTask.send({ |
| | | data: 'ping', |
| | | fail: (err) => { |
| | | console.log('心跳发送失败:', err); |
| | | this.wsConnected = false; |
| | | } |
| | | }); |
| | | } else if (this.socketTask && this.socketTask.readyState !== 1) { |
| | | console.log('WebSocket 状态异常,readyState:', this.socketTask?.readyState); |
| | | this.wsConnected = false; |
| | | } |
| | | }, 30000); // 每30秒发送一次心跳 |
| | | }, |
| | | // 添加连接状态检查方法 |
| | | checkConnection() { |
| | | return new Promise((resolve) => { |
| | | if (!this.socketTask) { |
| | | resolve(false); |
| | | return; |
| | | } |
| | | |
| | | if (this.socketTask.readyState === 1) { |
| | | // 已连接,发送测试消息确认 |
| | | this.socketTask.send({ |
| | | data: 'test', |
| | | success: () => { |
| | | resolve(true); |
| | | }, |
| | | fail: () => { |
| | | resolve(false); |
| | | } |
| | | }); |
| | | } else { |
| | | console.log('连接状态:', this.socketTask.readyState); |
| | | resolve(false); |
| | | } |
| | | }); |
| | | }, |
| | | // 测试打印机服务 |
| | | async testPrinterService() { |
| | | console.log('开始测试打印机服务...'); |
| | | |
| | | // 尝试不同的地址 |
| | | const testUrls = [ |
| | | 'ws://127.0.0.1:40002', |
| | | 'ws://localhost:40002', |
| | | 'ws://192.168.2.141:40001', |
| | | 'ws://192.168.2.141:40002', |
| | | // 如果有具体IP,可以添加 |
| | | // 'ws://192.168.1.100:40002' |
| | | ]; |
| | | |
| | | for (const url of testUrls) { |
| | | console.log(`测试地址: ${url}`); |
| | | try { |
| | | const result = await this.testConnect(url); |
| | | if (result) { |
| | | console.log(`成功连接到: ${url}`); |
| | | uni.showToast({ |
| | | title: `找到打印机: ${url}`, |
| | | icon: 'success' |
| | | }); |
| | | return true; |
| | | } |
| | | } catch (e) { |
| | | console.log(`连接失败: ${url}`, e); |
| | | } |
| | | } |
| | | |
| | | console.log('所有地址测试失败'); |
| | | uni.showToast({ |
| | | title: '未找到打印机服务', |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }); |
| | | return false; |
| | | }, |
| | | |
| | | // 测试单个连接 |
| | | testConnect(url) { |
| | | return new Promise((resolve) => { |
| | | const socket = uni.connectSocket({ |
| | | url: url, |
| | | success: () => { |
| | | console.log(`测试连接创建成功: ${url}`); |
| | | } |
| | | }); |
| | | |
| | | const timeout = setTimeout(() => { |
| | | if (socket) { |
| | | socket.close(); |
| | | } |
| | | resolve(false); |
| | | }, 2000); |
| | | |
| | | socket.onOpen(() => { |
| | | clearTimeout(timeout); |
| | | socket.close(); |
| | | resolve(true); |
| | | }); |
| | | |
| | | socket.onError((err) => { |
| | | clearTimeout(timeout); |
| | | console.log(`测试连接错误: ${url}`, err); |
| | | resolve(false); |
| | | }); |
| | | }); |
| | | }, |
| | | doRequest(url, data, resFunction, errFunction, method) { |
| | | uni.showLoading({ |
| | |
| | | async searchbarCodeInfoMeta() { |
| | | this.cantGenerate = true |
| | | this.cantPrint = true |
| | | this.cantPrint_HK = true |
| | | this.cantSplit = false // 拆码前确保拆码按钮可用 |
| | | if (CommonUtils.isEmpty(this.barCodeInfoMeta.barCodeNo) === true) { |
| | | return uni.showToast({ |
| | |
| | | this.cantSplit = true; |
| | | this.cantGenerate = false; |
| | | this.cantPrint = true; |
| | | this.cantPrint_HK = true; |
| | | //生成 |
| | | this.SaveBarCodeCreate(); |
| | | } else { |
| | |
| | | // 生成成功,禁用生成按钮,放开打印按钮 |
| | | this.cantGenerate = true; |
| | | this.cantPrint = false; |
| | | this.cantPrint_HK = false; |
| | | this.cantSplit = true; |
| | | this.barCodeInfoMeta.barCodeNo = ""; //清空输入框 |
| | | uni.showToast({ |
| | |
| | | }, |
| | | |
| | | //海康打印按钮 |
| | | async PrintHBarCode() { |
| | | // 防止重复点击 |
| | | async PrintHBarCode_HK() { |
| | | if (this.isPrinting) { |
| | | uni.showToast({ |
| | | title: '打印中,请稍候...', |
| | |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 先检查打印机服务是否可用 |
| | | uni.showLoading({ |
| | | title: '检查打印机...', |
| | | mask: true |
| | | }); |
| | | |
| | | this.isPrinting = true; |
| | | |
| | | try { |
| | | this.printerLabel_HK(); //打印 |
| | | // 检查当前连接状态 |
| | | const isConnected = await this.checkConnection(); |
| | | |
| | | if (!isConnected) { |
| | | uni.showLoading({ |
| | | title: '连接打印机...', |
| | | mask: true |
| | | }); |
| | | await this.connect(); |
| | | this.startHeartbeat(); // 启动心跳 |
| | | } |
| | | |
| | | uni.hideLoading(); |
| | | |
| | | // 确认连接成功 |
| | | if (this.socketTask && this.socketTask.readyState === 1) { |
| | | this.isPrinting = true; |
| | | this.printerLabel_HK(); |
| | | |
| | | // 延迟重置打印状态 |
| | | setTimeout(() => { |
| | | this.isPrinting = false; |
| | | }, 3000); |
| | | } else { |
| | | throw new Error(`打印机未连接,状态: ${this.socketTask?.readyState}`); |
| | | } |
| | | |
| | | } catch (error) { |
| | | uni.hideLoading(); |
| | | console.error('打印失败:', error); |
| | | this.isPrinting = false; |
| | | this.wsConnected = false; |
| | | |
| | | uni.showToast({ |
| | | title: error.message || '打印失败', |
| | | icon: 'error', |
| | | duration: 2000 |
| | | uni.showModal({ |
| | | title: '打印失败', |
| | | content: error.message || '请检查:\n1. 打印机服务是否启动\n2. 打印机地址是否正确\n3. 网络是否通畅', |
| | | confirmText: '重试', |
| | | cancelText: '取消', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | setTimeout(() => { |
| | | this.PrintHBarCode_HK(); |
| | | }, 1000); |
| | | } |
| | | } |
| | | }); |
| | | CommonUtils.playSound(0); |
| | | } |
| | | }, |
| | | |
| | |
| | | this.cantSplit = false; // 拆码按钮可用 |
| | | this.cantGenerate = true; // 生成按钮禁用 |
| | | this.cantPrint = true; // 打印按钮禁用 |
| | | this.cantPrint_HK = true; // 打印按钮禁用 |
| | | } |
| | | }, |
| | | onLoad() { |
| | |
| | | } |
| | | //初始化打印 |
| | | this.initPrinter(); |
| | | |
| | | // 预连接海康打印机(可选,不阻塞页面) |
| | | this.connect().catch(err => { |
| | | console.warn('海康打印机预连接失败:', err); |
| | | }); |
| | | // 测试打印机服务(可选) |
| | | setTimeout(() => { |
| | | this.testPrinterService(); |
| | | }, 1000); |
| | | }, |
| | | onReady() { |
| | | |
| | | }, |
| | | onUnload() { |
| | | // 调用同步方法 |
| | | // 清理定时器 |
| | | if (this.wsHeartbeatTimer) { |
| | | clearInterval(this.wsHeartbeatTimer); |
| | | this.wsHeartbeatTimer = null; |
| | | } |
| | | |
| | | if (this.wsReconnectTimer) { |
| | | clearTimeout(this.wsReconnectTimer); |
| | | this.wsReconnectTimer = null; |
| | | } |
| | | |
| | | // 关闭 WebSocket 连接 |
| | | if (this.socketTask) { |
| | | this.socketTask.close({ |
| | | code: 1000, |
| | | reason: '页面卸载' |
| | | }); |
| | | this.socketTask = null; |
| | | } |
| | | |
| | | this.wsConnected = false; |
| | | } |
| | | } |
| | | </script> |