Component({ mixins: [], data: { printdata: {}, percent: '0', array: ['TSPL', 'ZPL 待开发', 'CPCL 待开发', 'ESC/POS 待开发'], index: 0, // 初始化蓝牙的开关状态,false 表示关闭,true 表示打开 switchswitchopenBluetoothAdapter: false, // 搜索蓝牙设备的开关状态,false 表示停止搜索,true 表示开始搜索 switchstartBluetoothDevicesDiscovery: false, // 蓝牙模块是否处于搜索状态,'' 表示初始值,后续会更新为 true 或 false discovering: '', // 蓝牙模块是否可用,'' 表示初始值,后续会更新为 true 或 false available: '', // 存储已发现的蓝牙设备列表 deviceslist: [], // 选择的保持连接的蓝牙对象 devices: [], selectedDevice: {}, // 存储设备名称,可根据需求调整 devicesName: [], // 当前选中的蓝牙设备的 ID deviceId: '', // 只是查找某个蓝牙设备 services: '', // 图标类型数组,这里只包含 'cancel',可根据需求添加其他图标类型 iconType: [ // 'success', 'cancel', ], // 蓝牙连接状态 isConnected: false, // 心跳定时器 ID heartbeatTimer: null, // 存储获取到的可写特征值列表 writableCharacteristics: [], // 存储所有服务及其特征值 allServicesAndCharacteristics: {} }, props: { printdata: { type: Object, default: () => ({}) } }, didMount() { // 获取本机蓝牙模块的状态 this.getBluetoothAdapterState(); // 监听新设备发现事件 this.listenDeviceFound(); // 监听蓝牙连接断开事件 this.listenBLEConnectionStateChanged(); }, didUpdate() {}, didUnmount() { try { // 取消监听新设备发现事件,避免内存泄漏 dd.offBluetoothDeviceFound(this.handleDeviceFound); } catch (error) { console.warn('取消监听新设备发现事件时出错:', error); } try { // 关闭蓝牙连接 this.closeBluetoothConnection(); } catch (error) { console.warn('关闭蓝牙连接时出错:', error); } try { // 清除心跳定时器 if (this.data.heartbeatTimer) { clearInterval(this.data.heartbeatTimer); } } catch (error) { console.warn('清除心跳定时器时出错:', error); } try { // 取消监听蓝牙连接状态变化事件 dd.offBLEConnectionStateChanged(this.handleBLEConnectionStateChanged); } catch (error) { console.warn('取消监听蓝牙连接状态变化事件时出错:', error); } }, methods: { onSubmit() { const selectedDevice = this.data.selectedDevice; console.log('selectedDevice', selectedDevice); const isConnected = this.data.isConnected; // 检查蓝牙设备是否已连接 if (!selectedDevice || !isConnected) { console.log('请先连接蓝牙设备'); const title = '请先连接蓝牙设备'; if (title) { dd.showToast({ title, icon: 'none' }); } return; } // 从可写特征值列表中获取第一个可写特征值(这里假设只有一个可写特征值,你可以根据实际情况调整) const writableCharacteristic = this.data.writableCharacteristics[0]; console.log('writableCharacteristics', this.data.writableCharacteristics); if (!writableCharacteristic) { console.log('未找到可写特征值'); const title = '未找到可写特征值'; if (title) { dd.showToast({ title, icon: 'none' }); } return; } const serviceId = writableCharacteristic.serviceId; const characteristicId = writableCharacteristic.characteristicId; const deviceId = selectedDevice.deviceId; // 检查参数完整性 if (!deviceId || !serviceId || !characteristicId) { console.error('缺少必要参数:', { deviceId, serviceId, characteristicId }); const title = '缺少必要参数,请检查连接'; if (title) { dd.showToast({ title, icon: 'none' }); } return; } //打印数据处理 const selectedSaleOrderLines = dd.getStorageSync({ key: 'selectedSaleOrderLines' }).data; const printdata = selectedSaleOrderLines || {}; this.setData({ printdata }); const allValuesToPrint = []; // 检查打印数据是否存在,并且 selectedItems 是一个数组 if (printdata && printdata.selectedItems && Array.isArray(printdata.selectedItems)) { // 遍历 selectedItems 数组 printdata.selectedItems.forEach((item) => { // 输出当前遍历的 item console.log('每个订单行数据item:', item); // 检查 item 的 fineCode3Names 是否存在,并且是一个数组 if (item.fineCode3Names && Array.isArray(item.fineCode3Names)) { // 遍历 fineCode3Names 数组 item.fineCode3Names.forEach((value) => { // 将可能的浮点数转换为文本 const nameValue = typeof item.name === 'number'? item.name.toString() : item.name; const colorValue = typeof item.color_id_2[1] === 'number'? item.color_id_2[1].toString() : item.color_id_2[1]; const codeValue = typeof value === 'number'? value.toString() : value; // 拼接要打印的内容 value = `name ${nameValue}.color ${colorValue}.code ${codeValue}`; // 去除中文和[]符号 value = value.replace(/[\u4e00-\u9fa5\[\]]/g, ''); allValuesToPrint.push(value); }); } }); } const totalCodes = allValuesToPrint.length; let sentCodes = 0; let totalChunks = 0; let sentChunks = 0; // 计算总的数据块数量 allValuesToPrint.forEach((code) => { const command = ` SIZE 7,5 GAP 2,0 CLS QRCODE 20,150,H,5,A,0,"${code}" TEXT 20,350,"2",0,1,1,"${code}" PRINT 1,1 `; // const encoder = new TextEncoder('utf-8'); // const commandBuffer = encoder.encode(command); const commandBuffer = Buffer.from(command, 'utf-8'); const hexValue = Array.from(commandBuffer) .map(byte => byte.toString(16).padStart(2, '0')) .join(''); const chunkSize = 40; const chunks = []; for (let i = 0; i < hexValue.length; i += chunkSize) { chunks.push(hexValue.slice(i, i + chunkSize)); } totalChunks += chunks.length; }); const sendPrintCode = (index) => { if (index >= allValuesToPrint.length) { console.log('所有 printcode 数据发送完成'); this.setData({ percent: '100', }); return; } const currentCode = allValuesToPrint[index]; const command = ` SIZE 7,5 GAP 2,0 CLS QRCODE 20,150,H,5,A,0,"${currentCode}" TEXT 20,350,"2",0,1,1,"${currentCode}" PRINT 1,1 `; // const encoder = new TextEncoder('utf-8'); // const commandBuffer = encoder.encode(command); const commandBuffer = Buffer.from(command, 'utf-8'); // 将二进制数据转换为 hex 编码 const hexValue = Array.from(commandBuffer) .map(byte => byte.toString(16).padStart(2, '0')) .join(''); // 分段发送数据 const chunkSize = 40; // 每个分段的长度,20 字节 = 40 个十六进制字符 const chunks = []; for (let i = 0; i < hexValue.length; i += chunkSize) { chunks.push(hexValue.slice(i, i + chunkSize)); } const sendNextChunk = (chunkIndex) => { if (chunkIndex >= chunks.length) { console.log(`printcode ${currentCode} 的所有数据分段发送完成`); sentCodes++; sendPrintCode(index + 1); return; } const currentChunk = chunks[chunkIndex]; console.log(`准备发送 printcode ${currentCode} 的第 ${chunkIndex + 1} 个数据分段,长度: ${currentChunk.length}`, currentChunk); dd.writeBLECharacteristicValue({ deviceId, serviceId, characteristicId, value: currentChunk, success: (res) => { console.log(`printcode ${currentCode} 的第 ${chunkIndex + 1} 个数据分段发送成功`, res); sentChunks++; const percent = ((sentChunks / totalChunks) * 100).toFixed(0); this.setData({ percent: percent, }); sendNextChunk(chunkIndex + 1); }, fail: (res) => { console.error(`printcode ${currentCode} 的第 ${chunkIndex + 1} 个数据分段发送失败,错误码:`, res.errorCode); const title = `printcode ${currentCode} 的第 ${chunkIndex + 1} 个数据分段发送失败,错误码: ${res.errorCode}`; if (title) { dd.showToast({ title: title, icon: 'none' }); } }, complete: (res) => { console.log(`printcode ${currentCode} 的第 ${chunkIndex + 1} 个数据分段发送调用结束`, res); } }); }; sendNextChunk(0); }; sendPrintCode(0); }, getBluetoothAdapterState() { // 调用 dd.getBluetoothAdapterState 方法获取本机蓝牙模块的状态 dd.getBluetoothAdapterState({ success: (res) => { console.log('本机蓝牙模块状态:', res); // 更新组件数据,将蓝牙模块的搜索状态和可用性状态存储到 data 中 this.setData({ // res.discovering 为 true 表示蓝牙模块处于搜索状态,false 表示不处于搜索状态 discovering: res.discovering, // res.available 为 true 表示蓝牙模块可用,false 表示不可用 available: res.available }); }, fail: (res) => { console.log('获取本机蓝牙模块状态失败,错误码:', res.errorCode); if (res.errorCode === 10000) { // dd.showToast({ // title: '请先打开蓝牙开关', // icon: 'none' // }); } else { // dd.showToast({ // title: `获取本机蓝牙模块状态失败,错误码: ${res.errorCode}`, // icon: 'none' // }); } }, complete: (res) => { console.log('获取本机蓝牙模块状态调用结束', res); } }); }, switchopenBluetoothAdapter(e) { console.log('Data updated:', this.props.printdata); console.log('switchopenBluetoothAdapter 发生 change 事件,携带值为', e.detail.value); // 更新组件数据,将开关的新状态存储到 data 中 console.log('Received printdata:', this.data.printdata); this.setData({ switchswitchopenBluetoothAdapter: e.detail.value, }); if (e.detail.value) { // 开关打开,初始化蓝牙模块 // 调用 dd.openBluetoothAdapter 方法初始化蓝牙模块 dd.openBluetoothAdapter({ // 自动关闭蓝牙适配器 autoClose: true, success: (res) => { console.log('蓝牙模块初始化成功,是否支持 BLE:', res.isSupportBLE); // dd.showToast({ // title: '蓝牙模块初始化成功', // icon: 'success' // }); // 监听手机蓝牙状态的改变 dd.onBluetoothAdapterStateChange((res) => { console.log('蓝牙适配器状态改变:', res); }); }, fail: (res) => { console.error('蓝牙模块初始化失败,错误码:', res.errorCode); // const title = `蓝牙模块初始化失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } // 根据不同的错误码给出相应的提示信息 switch (res.errorCode) { case 12: console.log('请尝试打开蓝牙。'); break; case 13: console.log('请尝试重新连接。'); break; case 14: console.log('请授权使用蓝牙功能。'); break; case 15: console.log('未知错误。'); break; case 10000: console.log('未初始化蓝牙适配器'); break; default: console.log('其他错误'); } }, complete: (res) => { console.log('蓝牙模块初始化调用结束', res); } }); } else { // 开关关闭,关闭蓝牙模块 // 调用 dd.closeBluetoothAdapter 方法关闭蓝牙模块 dd.closeBluetoothAdapter({ success: () => { console.log('蓝牙模块已关闭'); // dd.showToast({ // title: '蓝牙模块已关闭', // icon: 'success' // }); }, fail: (res) => { console.error('关闭蓝牙模块失败,错误码:', res.errorCode); // const title = `关闭蓝牙模块失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: () => { console.log('关闭蓝牙模块调用结束'); } }); } }, startBluetoothDevicesDiscovery(e) { console.log('startBluetoothDevicesDiscovery 发生 change 事件,携带值为', e.detail.value); // 更新组件数据,将开关的新状态存储到 data 中 this.setData({ switchstartBluetoothDevicesDiscovery: e.detail.value, }); if (e.detail.value) { // 开关打开,开始搜索蓝牙设备 console.log('开始搜寻附近的蓝牙外围设备'); // 调用 dd.startBluetoothDevicesDiscovery 方法开始搜索蓝牙设备 dd.startBluetoothDevicesDiscovery({ // 搜索指定服务 UUID 的蓝牙设备 // services: ['fff0'], success: (res) => { console.log(res); // dd.showToast({ // title: '开始搜索蓝牙设备', // icon: 'success' // }); // 开始搜索后获取已发现设备 this.getDiscoveredDevices(); }, fail: (res) => { console.error('搜寻蓝牙设备失败,错误码:', res.errorCode); // const title = `搜寻蓝牙设备失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: (res) => { console.log('搜寻蓝牙设备调用结束', res); } }); } else { // 开关关闭,停止搜索蓝牙设备 console.log('停止搜寻附近的蓝牙外围设备'); // 调用 dd.stopBluetoothDevicesDiscovery 方法停止搜索蓝牙设备 dd.stopBluetoothDevicesDiscovery({ success: (res) => { console.log(res); // dd.showToast({ // title: '停止搜索蓝牙设备', // icon: 'success' // }); }, fail: (res) => { console.error('停止搜寻蓝牙设备失败,错误码:', res.errorCode); // const title = `停止搜寻蓝牙设备失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: (res) => { console.log('停止搜寻蓝牙设备调用结束', res); } }); } }, getDiscoveredDevices() { // 调用 dd.getBluetoothDevices 方法获取已发现的蓝牙设备列表 dd.getBluetoothDevices({ success: (res) => { console.log('已发现的蓝牙设备:', res.devices); // 更新组件数据,将已发现的设备列表和设备名称存储到 data 中 this.setData({ deviceslist: res.devices, devicesName: res.devices.map(device => device.name), devices: res.devices // 将完整的设备对象保存到 devices 数组中 }); // dd.showToast({ // title: '获取已发现蓝牙设备成功', // icon: 'success' // }); }, fail: (res) => { console.error('获取已发现的蓝牙设备失败,错误码:', res.errorCode); // const title = `获取已发现的蓝牙设备失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: (res) => { console.log('获取已发现的蓝牙设备调用结束', res); } }); }, listenDeviceFound() { // 绑定 handleDeviceFound 方法的上下文,确保在事件回调中 this 指向正确 this.handleDeviceFound = this.handleDeviceFound.bind(this); // 调用 dd.onBluetoothDeviceFound 方法监听新设备发现事件 dd.onBluetoothDeviceFound(this.handleDeviceFound); }, handleDeviceFound(res) { // console.log('新发现的蓝牙设备:', res.devices); // 获取当前已发现的设备列表 const currentDevices = this.data.devices; // 过滤出新发现的设备,避免重复添加 const newDevices = res.devices.filter(device => { return currentDevices.every(existingDevice => existingDevice.deviceId !== device.deviceId); }); // 更新组件数据,将新发现的设备添加到已发现设备列表中 this.setData({ devices: [...currentDevices, ...newDevices], devicesName: [...this.data.devicesName, ...newDevices.map(device => device.name)] }); // const title = '发现新的蓝牙设备'; // if (title) { // dd.showToast({ // title, // icon: 'success' // }); // } }, radioChange(e) { console.log('选择的蓝牙是', e.detail.value); const deviceId = e.detail.value; const devices = this.data.devices; const selectedDevice = devices.find(device => device.deviceId === deviceId); if (selectedDevice) { this.setData({ deviceId, selectedDevice: selectedDevice // 将选中的蓝牙设备对象保存到 data 的 devices 中 }); // const title = '已选择蓝牙设备,开始连接'; // if (title) { // dd.showToast({ // title, // icon: 'success' // }); // } this.connectBluetoothDevice(); } else { console.log('未找到选中的蓝牙设备'); // const title = '未找到选中的蓝牙设备'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }, connectBluetoothDevice() { const deviceId = this.data.deviceId; if (deviceId) { dd.connectBLEDevice({ deviceId, success: (res) => { console.log('连接蓝牙设备成功', res); // const title = '蓝牙设备连接成功'; // if (title) { // dd.showToast({ // title, // icon: 'success' // }); // } // 获取设备的服务列表 this.getBLEDeviceServices(deviceId); this.setData({ isConnected: true, iconType: [ 'success', ], }); }, fail: (res) => { console.error('连接蓝牙设备失败,错误码:', res.errorCode); // const title = `连接蓝牙设备失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: (res) => { console.log('连接蓝牙设备调用结束', res); } }); } else { console.log('请先选择要连接的蓝牙设备'); const title = '请先选择要连接的蓝牙设备'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }, /** * 获取设备的服务列表 * @param {string} deviceId - 设备 ID */ getBLEDeviceServices(deviceId) { dd.getBLEDeviceServices({ deviceId, success: (serviceRes) => { const services = serviceRes.services; if (services && services.length > 0) { services.forEach((service) => { const serviceUuid = service.uuid || service.serviceId; if (serviceUuid) { this.getBLEDeviceCharacteristics(deviceId, serviceUuid); } else { console.error('服务的 UUID 和 serviceId 均为空,无法获取特征值。服务详情:', service); const title = '服务 UUID 和 serviceId 均为空,无法获取特征值'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }); } else { console.error('未获取到服务列表'); // const title = '未获取到服务列表'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }, fail: (serviceErr) => { console.error('获取服务失败', serviceErr); // const title = '获取服务失败'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }); }, /** * 获取设备的特征值列表 * @param {string} deviceId - 设备 ID * @param {string} serviceId - 服务 ID */ getBLEDeviceCharacteristics(deviceId, serviceId) { if (!deviceId || !serviceId) { console.error('deviceId 或 serviceId 为空,无法获取特征值'); return; } dd.getBLEDeviceCharacteristics({ deviceId, serviceId, success: (characteristicRes) => { const characteristics = characteristicRes.characteristics; console.log('获取到的所有特征值:', characteristics); // 先筛选出可读可写的特征值 const readableAndWritable = characteristics.filter( (characteristic) => characteristic.properties.read && characteristic.properties.write ); // 如果没有可读可写的特征值,则筛选出只可写的特征值 const writable = readableAndWritable.length > 0 ? readableAndWritable : characteristics.filter( (characteristic) => characteristic.properties.write ); console.log('筛选出的可写特征值:', writable); // 更新组件数据,存储可写特征值列表 this.setData({ writableCharacteristics: [...this.data.writableCharacteristics, ...writable] }); console.log('获取特征值成功', characteristicRes); // const title = '获取特征值成功'; // if (title) { // dd.showToast({ // title, // icon: 'success' // }); // } }, fail: (characteristicErr) => { console.error('获取特征值失败', characteristicErr); // const title = '获取特征值失败'; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } } }); }, /** * 重新连接蓝牙设备 */ reconnectBluetoothDevice() { const deviceId = this.data.deviceId; if (deviceId) { setTimeout(() => { dd.createBLEConnection({ deviceId, success: (res) => { console.log('重新连接蓝牙设备成功', res); this.setData({ isConnected: true, iconType: [ 'success', ], }); const title = '蓝牙设备重新连接成功'; if (title) { dd.showToast({ title, icon: 'success' }); } // this.startHeartbeat(); }, fail: (res) => { console.error('重新连接蓝牙设备失败,错误码:', res.errorCode); // const title = `重新连接蓝牙设备失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } this.reconnectBluetoothDevice(); }, complete: (res) => { console.log('重新连接蓝牙设备调用结束', res); } }); }, 2000); // 2 秒后重试 } }, /** * 关闭蓝牙连接 */ closeBluetoothConnection() { const deviceId = this.data.deviceId; if (deviceId && this.data.isConnected) { dd.closeBLEConnection({ deviceId, success: (res) => { console.log('蓝牙连接已关闭', res); this.setData({ isConnected: false, iconType: [ 'cancel', ], }); if (this.data.heartbeatTimer) { clearInterval(this.data.heartbeatTimer); } const title = '蓝牙连接已关闭'; if (title) { dd.showToast({ title, icon: 'success' }); } }, fail: (res) => { console.error('关闭蓝牙连接失败,错误码:', res.errorCode); // const title = `关闭蓝牙连接失败,错误码: ${res.errorCode}`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } }, complete: (res) => { console.log('关闭蓝牙连接调用结束', res); } }); } }, /** * 监听蓝牙连接状态变化事件 */ listenBLEConnectionStateChanged() { // 先关闭之前的事件监听 dd.offBLEConnectionStateChanged(this.handleBLEConnectionStateChanged); // 绑定回调函数上下文 this.handleBLEConnectionStateChanged = this.handleBLEConnectionStateChanged.bind(this); // 监听蓝牙连接状态变化事件 dd.onBLEConnectionStateChanged(this.handleBLEConnectionStateChanged); }, /** * 处理蓝牙连接状态变化事件的回调函数 */ handleBLEConnectionStateChanged(res) { const { deviceId, connected } = res; if (connected) { console.log(`蓝牙设备 ${deviceId} 连接成功`); // const title = `蓝牙设备 ${deviceId} 连接成功`; // if (title) { // dd.showToast({ // title, // icon: 'success' // }); // } this.setData({ isConnected: true, iconType: [ 'success', ], }); } else { console.log(`蓝牙设备 ${deviceId} 连接断开,尝试重新连接`); // const title = `蓝牙设备 ${deviceId} 连接断开,尝试重新连接`; // if (title) { // dd.showToast({ // title, // icon: 'none' // }); // } this.setData({ isConnected: false, iconType: [ // 'success', 'cancel' ], }); this.reconnectBluetoothDevice(); } } }, });