This commit is contained in:
aihe 2024-05-10 02:29:39 +08:00
parent 7546192eee
commit f2babe0dd9
2 changed files with 216 additions and 128 deletions

View File

@ -55,10 +55,10 @@ const confirmModal = (title) => {
}) })
} }
const showLoading = ()=> { const showLoading = (title)=> {
uni.showLoading({ uni.showLoading({
mask: true, mask: true,
title: '加载中' title: title || '加载中'
}); });
} }

View File

@ -1,54 +1,123 @@
<template> <template>
<view> <tpx-page>
<button @click="discoveryPrinter">搜索打印机</button> <tpx-layout>
<button @click="stopDiscoveryPrinter">停止搜索打印机</button> <template v-slot:header>
<view>选中的设备:{{deviceId}}</view> <view class="blcok-white">
<view class="text-red">设备列表</view> <view >
<radio-group @change="radioChange"> <u-row custom-style="gap: 10rpx;">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in devices" :key="index" <u-button @click="discoveryPrinter">搜索周边设备</u-button>
v-if="item.name && item.deviceId" <u-button @click="stopDiscoveryPrinter">停止搜索</u-button>
> <u-button @click="writeBLECharacteristicValue" type="primary" disabled="!(deviceId && !serviceId && characteristicId)">打印</u-button>
<view> </u-row>
<radio :value="item.deviceId" />{{item.name}}({{item.deviceId}}) </view>
<view class="">
<view class="pt-10 pb-10">连接信息</view>
<u-steps activeColor="#969799" :current="curTab" direction="column" dot="true">
<u-steps-item v-for="(item, index) in conInfos" @click="changeTab(index)">
<template v-slot:title>
<view class="clr-sub pl-20">{{item.title}}</view>
</template>
<template v-slot:desc>
<view class="mt-10 pl-20">{{item.desc}}</view>
</template>
</u-steps-item>
</u-steps>
</view>
</view> </view>
</label>
</radio-group>
<view class="text-red">设备服务列表</view> </template>
<radio-group @change="radioChange2"> <template v-slot:body>
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in serverList" :key="index"> <view class="blcok-white">
<view> <view v-if="curTab == 0">
<radio :value="item.uuid" />{{item.uuid}} <view class="pb-10">蓝牙设备列表</view>
<template v-for="(item, index) in devices">
<view @click="handleSelectDeviceId(item)" v-if="item.name.length>0"
:key="index" :class="`list-item ${item.deviceId == deviceId?'list-item-active':''}`"
>
<u-row justify="between">
<view class="font-weight">{{item.name }}</view>
</u-row>
<view>
<text class="clr-sub">信号强度:</text> {{item.RSSI}}dBm ({{Math.max(100+item.RSSI,0)}}%)
</view>
<view>
<text class="clr-sub">deviceId:</text>{{item.deviceId}}
</view>
<view >
<text class="clr-sub">Service数量:</text> {{item.advertisServiceUUIDs.length || 0}}
</view>
</view>
</template>
</view>
<view v-if="curTab == 1">
<view class="pb-10">服务列表</view>
<template v-for="(item, index) in serverList" :key="index">
<view @click="handleSelectService(item)"
:class="`list-item ${item.uuid == serviceId?'list-item-active':''}`"
>
<view>
<text class="clr-sub">uuid:</text> {{item.uuid}}
</view>
</view>
</template>
</view>
<view v-if="curTab == 2">
<view class="pb-10">特征值列表</view>
<template v-for="(item, index) in characteristics" :key="index">
<view @click="handleSelectChara(item)"
:class="`list-item ${item.uuid == characteristicId?'list-item-active':''}`"
>
<view>
<text class="clr-sub">uuid:</text> {{item.uuid}}
</view>
<template v-if="item.properties">
<view>
<text class="clr-sub">write:</text> {{item.properties.write}}
</view>
<view>
<text class="clr-sub">notify:</text> {{item.properties.notify}}
</view>
<view>
<text class="clr-sub">indicate:</text> {{item.properties.indicate}}
</view>
</template>
</view>
</template>
</view>
</view> </view>
</label> </template>
</radio-group> <canvas canvas-id="shareCanvas" :style="{width:canvas_width+'px', height: canvas_height+'px'}"></canvas>
</tpx-layout>
<view class="text-red">特征值</view> </tpx-page>
<radio-group @change="radioChange3">
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in characteristics" :key="index">
<view>
<radio :value="item.uuid" />{{item.uuid}}(write:{{item.properties.write}} notify:{{item.properties.notify}} indicate:{{item.properties.indicate}})
</view>
</label>
</radio-group>
<button @click="writeBLECharacteristicValue">打印</button>
<canvas canvas-id="shareCanvas" :style="{width:canvas_width+'px', height: canvas_height+'px'}"></canvas>
</view>
</template> </template>
<script> <script>
import { showLoading, showToast, hideLoading } from "@/common/untool"
import PrinterJobs from './print/printerjobs.js' import PrinterJobs from './print/printerjobs.js'
import * as printerUtil from './print/printerutil.js' import * as printerUtil from './print/printerutil.js'
import * as util from './print/util.js' import * as util from './print/util.js'
export default { export default {
name: 'xun_bluetoothPrint', name: 'bluetoothPrint',
computed: {
conInfos() {
let ary = [
{ title: '蓝牙设备', desc: this.deviceId || '-' },
{ title: '服务', desc: this.serviceId || '-' },
{ title: '特征值', desc: this.characteristicId || '-' }
]
return ary
},
},
data () { data () {
return { return {
canvasId: 'shareCanvas', canvasId: 'shareCanvas',
canvas_width: 240, canvas_width: 240,
canvas_height: 240, canvas_height: 240,
curTab: 0,
devices: [], devices: [],
deviceId: '', deviceId: '',
serverList: [], serverList: [],
@ -62,6 +131,9 @@ export default {
this.openBluetoothAdapter() this.openBluetoothAdapter()
}, },
methods: { methods: {
changeTab(type) {
this.curTab = type
},
openBluetoothAdapter () { openBluetoothAdapter () {
var _this = this var _this = this
uni.openBluetoothAdapter({ uni.openBluetoothAdapter({
@ -70,15 +142,10 @@ export default {
if (!e.errCode) { if (!e.errCode) {
console.log('初始化完成') console.log('初始化完成')
} else if (e.errCode == 10001) { } else if (e.errCode == 10001) {
uni.showToast({ showToast('请打开手机蓝牙')
icon: 'none',
title: '请打开手机蓝牙'
})
} else { } else {
uni.showToast({ console.log('openBluetoothAdapter:error=========', e.errMsg)
icon: 'none', showToast(e.errMsg)
title: e.errMsg
})
} }
} }
}) })
@ -93,7 +160,7 @@ export default {
if (e.errMsg == "startBluetoothDevicesDiscovery:ok") { if (e.errMsg == "startBluetoothDevicesDiscovery:ok") {
// ArrayBuffer转16进度字符串示例 // ArrayBuffer转16进度字符串示例
uni.onBluetoothDeviceFound(devices => { uni.onBluetoothDeviceFound(devices => {
console.log(devices) console.log("========devices=====", devices)
_this.devices.push(devices.devices[0]) _this.devices.push(devices.devices[0])
}) })
} }
@ -104,112 +171,123 @@ export default {
async stopDiscoveryPrinter () { async stopDiscoveryPrinter () {
uni.stopBluetoothDevicesDiscovery() uni.stopBluetoothDevicesDiscovery()
}, },
radioChange (e) { async handleSelectDeviceId (item) {
console.log(e) this.deviceId = item.deviceId
this.deviceId = e.target.value
this.serviceId = '' this.serviceId = ''
this.serverList = [] this.serverList = []
this.characteristics = [] this.characteristics = []
this.characteristicId = '' this.characteristicId = ''
//连接蓝牙 //连接蓝牙
this.connect() await this.connect()
if(this.serverList?.length > 0) {
this.curTab = 1
} else {
showToast('该设备无服务,请检查配置或换一个设备连接')
}
}, },
radioChange2 (e) { handleSelectService (item) {
console.log(e) this.serviceId = item.uuid
this.serviceId = e.target.value
this.characteristics = [] this.characteristics = []
this.characteristicId = '' this.characteristicId = ''
// 获取蓝牙特征值 // 获取蓝牙特征值
setTimeout(() =>{ setTimeout(async () =>{
this.getBLEDeviceCharacteristics() await this.getBLEDeviceCharacteristics()
if(this.characteristics?.length > 0) {
this.curTab = 2
} else {
showToast('该服务无特征值,请检查配置或换一个服务')
}
}, 500); }, 500);
}, },
radioChange3 (e) { handleSelectChara (item) {
console.log(e) this.characteristicId = item.uuid
this.characteristicId = e.target.value
}, },
connect () { connect () {
var _this = this var _this = this
uni.createBLEConnection({ console.log("连接蓝牙=====deviceId", _this.deviceId)
deviceId: _this.deviceId, showLoading('正在连接蓝牙')
complete (e) { return new Promise((resolve)=> {
console.log("蓝牙连接回调=====", e) uni.createBLEConnection({
if (!e.errCode) { deviceId: _this.deviceId,
uni.showToast({ complete (e) {
icon: 'none', hideLoading()
title: `蓝牙连接成功` console.log("蓝牙连接回调=====", e)
}) if (e.errMsg == "createBLEConnection:ok") {
//获取蓝牙设备所有服务(service)。 showToast(`蓝牙连接成功`)
setTimeout(()=> { //获取蓝牙设备所有服务(service)。
_this.getBLEDeviceServices() setTimeout(async()=> {
}, 2000) await _this.getBLEDeviceServices()
} else { resolve()
uni.showToast({ }, 2000)
icon: 'none', } else {
title: `连接设备失败:${e.errMsg}` resolve()
}) showToast(`连接设备失败:${e.errMsg}`)
}
} }
} })
}) })
}, },
getBLEDeviceServices(){ getBLEDeviceServices(){
var _this = this var _this = this
uni.getBLEDeviceServices({ return new Promise((resolve)=> {
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 showLoading('正在搜索服务')
deviceId: _this.deviceId, uni.getBLEDeviceServices({
success:(res)=>{ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
console.log('device services:', res) deviceId: _this.deviceId,
_this.serverList = res.services success:(res)=>{
// _this.serviceId = res.services[0].uuid; hideLoading()
console.log('serverId:', _this.serviceId) resolve()
}, console.log('device services:', res)
fail:(e) =>{ _this.serverList = res.services
uni.showToast({ // _this.serviceId = res.services[0].uuid;
icon: 'none', console.log('serverId:', _this.serviceId)
title: `设备服务获取失败:${e.errMsg}` },
}) fail:(e) =>{
console.log("getBLEDeviceServices - fail==============", e) hideLoading()
} resolve()
this.serverList = []
showToast(`设备服务获取失败:${e.errMsg}`)
console.log("getBLEDeviceServices - fail==============", e)
}
})
}) })
}, },
getBLEDeviceCharacteristics () { getBLEDeviceCharacteristics () {
var _this = this var _this = this
uni.getBLEDeviceCharacteristics({ return new Promise((resolve)=> {
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 showLoading('正在搜索特征值')
deviceId: _this.deviceId, uni.getBLEDeviceCharacteristics({
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
serviceId:_this.serviceId, deviceId: _this.deviceId,
success:(res)=>{ // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
console.log('getBLEDeviceCharacteristics', res) serviceId:_this.serviceId,
_this.characteristics = res.characteristics success:(res)=>{
// _this.characteristicId = res.characteristics[0].uuid hideLoading()
}, console.log('getBLEDeviceCharacteristics', res)
fail:(res)=>{ _this.characteristics = res.characteristics
console.log(res) resolve()
} // _this.characteristicId = res.characteristics[0].uuid
},
fail:(res)=>{
hideLoading()
resolve()
console.log(res)
}
})
}) })
}, },
// 发送二进制数据 // 发送二进制数据
async writeBLECharacteristicValue(){ async writeBLECharacteristicValue(){
if (!this.deviceId) { if (!this.deviceId) {
uni.showToast({ showToast('请选择设备')
icon: 'none',
title: '请选择设备'
})
return return
} }
if (!this.serviceId) { if (!this.serviceId) {
uni.showToast({ showToast('请选择设备服务')
icon: 'none',
title: '请选择设备服务'
})
return return
} }
if (!this.characteristicId) { if (!this.characteristicId) {
uni.showToast({ showToast('请选择特征值')
icon: 'none',
title: '请选择特征值'
})
return return
} }
let pic_res = await this.renderPic(); let pic_res = await this.renderPic();
@ -344,13 +422,23 @@ export default {
</script> </script>
<style scoped> <style scoped>
* { font-size: 24rpx;} .list-item {
button { font-size: 28rpx;} font-size: 26rpx;
.text-red { color: red; font-size: 28rpx;} margin-bottom: 20rpx;
border-radius: 10rpx;
/*二维码隐藏到窗口外*/ border: 2rpx solid #ddd;
canvas { padding: 20rpx;
position: absolute; background-color: #F6F6F6;
top: -999rpx }
} .list-item-active{
border-color: #B12D29;
&:last-child{
margin-bottom: 0;
}
}
/*二维码隐藏到窗口外*/
canvas {
position: absolute;
top: -999rpx
}
</style> </style>