<template> <view class="printer_box"> <view> <view> <img src="http://110.42.248.235:866/images/system/666/XTiaCluc-1.png" class="printer_img" v-if="state ==0"> <img src="http://110.42.248.235:866/images/system/666/XTiaCluc-1.png" class="printer_imgs" v-if="state ==1"> </view> <view> <view class="printer_text" v-if="state ==0"> 未连接设备 </view> <view v-if="state ==1"> <view class="printer_text"> {{name}} </view> <view class="printer_text_tag"> 已连接 </view> </view> </view> </view> </view> <button class="printer_btn" @click="openBluetoothAdapter" v-if="!isConnected" :disabled="searching">开始搜索</button> <button class="printer_btn" @click="stopBluetooth" v-else>断开当前蓝牙设备</button> <view class="printer_under"> <view class="printer_under_title"> 已配对 </view> <view class="printer_under_content" v-for="(item,index) in devices" :key="index" @click="createBLEConnection(item)"> {{item.name}} </view> <view class="printer_under_content no-devices" v-if="!devices.length">未搜索到蓝牙设备</view> </view> <view class="" @click="a"> 跳转 </view> </template> <script setup lang="ts"> import { ref } from 'vue' import { onLoad } from '@dcloudio/uni-app' const searching = ref(false) const devices = ref([]) const state = ref(0) const isConnected = ref(false) const name = ref('') const deviceId = ref(null) const a = () =>{ uni.navigateTo({ url:'/pages/distribution/distribution' }) } onLoad(() => { console.log(uni.getStorageSync('deviceId')) console.log(uni.getStorageSync('serviceId')) if (uni.getStorageSync('deviceId') && uni.getStorageSync('serviceId')) { isConnected.value = true state.value = 1 name.value = uni.getStorageSync('blueTooothName') } }) const openBluetoothAdapter = () => { console.log('初始化蓝牙模块 openBluetoothAdapter'); if (searching.value) return if (!uni.openBluetoothAdapter) { console.log('微信版本过低'); uni.showModal({ title: '提示', content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。' }); return; } searching.value = true; uni.openBluetoothAdapter({ success: res => { console.log('初始化成功openBluetoothAdapter success', res); startBluetoothDevicesDiscovery(); }, fail: res => { console.log('初始化失败openBluetoothAdapter fail', res); uni.hideLoading(); if (res.errCode === 10001) { // 当前蓝牙适配器不可用 uni.showModal({ title: '错误', content: '未找到蓝牙设备, 请打开蓝牙后重试。', showCancel: false }); // 监听蓝牙适配器状态变化事件 uni.onBluetoothAdapterStateChange(res => { console.log('监听蓝牙适配器状态 onBluetoothAdapterStateChange', res); // available:蓝牙适配器是否可用 if (res.available) { // 开始搜寻附近的蓝牙外围设备 startBluetoothDevicesDiscovery(); } }); } } }) } const onBluetoothDeviceFound = () => { console.log('进入查询设备'); uni.onBluetoothDeviceFound(res => { if (res.devices[0].name) { devices.value.push({ name: res.devices[0].name, deviceId: res.devices[0].deviceId, services: [] }) } console.log(devices.value); }); } const startBluetoothDevicesDiscovery = () => { console.log('开始搜寻附近的蓝牙设备'); uni.startBluetoothDevicesDiscovery({ allowDuplicatesKey: false, interval: 0, success: res => { // 监听寻找到新设备的事件 onBluetoothDeviceFound(); }, fail: res => { } }); } /** * 点击连接 */ const createBLEConnection = (e : any) => { const deviceId = e.deviceId; uni.showLoading({ title: '连接中' }) uni.createBLEConnection({ deviceId: deviceId, success: (res : any) => { uni.hideLoading() console.log(res); name.value = e.name state.value = 1 isConnected.value = true searching.value = false; uni.showToast({ title: '连接成功', icon: 'success' }) stopBluetoothDevicesDiscovery() uni.setStorageSync('deviceId', deviceId) uni.setStorageSync('blueTooothName', e.name) setTimeout(() => { getBLEDeviceServices(deviceId) }, 2000) }, fail: (res : any) => { uni.hideLoading() console.log(res); uni.showToast({ title: '连接失败', icon: 'error' }) } }) } /** * 连接完停止搜索 */ const stopBluetoothDevicesDiscovery = () => { uni.stopBluetoothDevicesDiscovery({ success: (res : any) => { // console.log('stopBluetoothDevicesDiscovery') console.log(res); } }); } /** * 获取所有蓝牙服务 */ const getBLEDeviceServices = (deviceId ?: any) => { console.log(deviceId) uni.getBLEDeviceServices({ deviceId: deviceId, success: (res : any) => { console.log(res); for (let i = 0; i < res.services.length; i++) { let serviceId = res.services[i].uuid getBLEDeviceCharacteristics(deviceId, serviceId); } } }) } /* 获取蓝牙设备某个服务中所有特征值(characteristic) characteristic: uuid:蓝牙设备特征值的 uuid properties:该特征值支持的操作类型 */ const getBLEDeviceCharacteristics = (deviceId : any, serviceId : any) => { uni.getBLEDeviceCharacteristics({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId: deviceId, serviceId, success: (res : any) => { let result = JSON.parse(JSON.stringify(res)) console.log(result); for (let i = 0; i < result.characteristics.length; i++) { if (result.characteristics[i].properties.write == true) { let uuid = result.characteristics[i].uuid for (let index in devices.value) { if (devices.value[index].deviceId === deviceId) { devices.value[index].services.push({ serviceId: serviceId, characteristicId: uuid }) let obj = devices.value.find((item : any) => item.deviceId === deviceId) uni.setStorageSync('serviceId', obj.services[0].serviceId) uni.setStorageSync('characteristicId', obj.services[0].characteristicId) break } } } } } }) } const stopBluetooth = () => { uni.closeBLEConnection({ deviceId: uni.getStorageSync('deviceId'), success: (res : any) => { console.log(res); state.value = 0 name.value = '' isConnected.value = false devices.value = [] uni.showToast({ title: '成功断开连接', icon: 'success' }) uni.removeStorageSync('serviceId') uni.removeStorageSync('characteristicId') uni.closeBluetoothAdapter({ success: res => { devices.value = [] }, fail: res => { } }) } }); } </script> <style> .printer_box { display: flex; align-items: center; justify-content: center; width: 750rpx; height: 200rpx; margin-top: 100rpx; } .printer_img { width: 130rpx; height: 130rpx; background-color: darkgray; padding: 27rpx; box-sizing: border-box; border-radius: 100rpx; display: flex; margin: 10rpx auto; } .printer_imgs { width: 130rpx; height: 130rpx; background-color: #2588FF; padding: 27rpx; box-sizing: border-box; border-radius: 100rpx; display: flex; margin: 10rpx auto; } .printer_text { font-size: 34rpx; font-weight: 500; margin-top: 30rpx; } .printer_text_tag { color: #A3A3A3; font-size: 26rpx; text-align: center; margin-top: 10rpx; } .printer_btn { width: 660rpx; height: 88rpx; border-radius: 60rpx; background-color: #2588FF; color: #fff; font-size: 30rpx; line-height: 88rpx; margin-top: 70rpx; } .printer_under_title { width: 100%; height: 50rpx; background-color: #F9FBFC; font-size: 24rpx; color: #333333; line-height: 50rpx; margin: 50rpx 0 0 30rpx; } .printer_under_content { font-size: 28rpx; width: 80%; height: 60rpx; border-bottom: 1rpx solid #f3f2f2; margin: 30rpx auto; } </style>