Files
uni-pda/pages/testpages/bleconfig.vue
T
2026-07-03 11:45:16 +08:00

173 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="container">
<!-- 步骤1扫描设备 -->
<button @click="startScan">1. 扫描蓝牙设备</button>
<view v-if="devices.length">
<view v-for="device in devices" :key="device.deviceId" class="device-item" @click="selectDevice(device)">
<text>{{ device.name || '未知设备' }}</text>
<text class="mac">{{ device.deviceId }}</text>
</view>
</view>
<!-- 步骤2连接后展示服务 -->
<view v-if="services.length">
<text>请选择服务</text>
<view v-for="svc in services" :key="svc.uuid" class="service-item" @click="selectService(svc)">
<text>{{ svc.uuid }}</text>
</view>
</view>
<!-- 步骤3选择特征值 -->
<view v-if="characteristics.length">
<text>请选择写入特征值</text>
<view v-for="char in characteristics" :key="char.uuid" class="char-item" @click="selectWriteChar(char)">
<text>{{ char.uuid }} ({{ char.properties.write ? '可写' : '' }})</text>
</view>
<text>请选择通知特征值可选</text>
<view v-for="char in characteristics" :key="char.uuid" class="char-item" @click="selectNotifyChar(char)">
<text>{{ char.uuid }} ({{ char.properties.notify ? '可通知' : '' }})</text>
</view>
</view>
<!-- 步骤4保存配置 -->
<button v-if="selectedWriteChar" @click="saveConfiguration">4. 保存配置并测试连接</button>
</view>
</template>
<script>
import bluetoothManager from '@/utils/BluetoothManager.js';
export default {
data() {
return {
devices: [], // 扫描到的设备列表
selectedDeviceId: null,
services: [], // 选中设备的服务列表
characteristics: [], // 选中服务的特征值列表
selectedServiceId: null,
selectedWriteChar: null,
selectedNotifyChar: null,
};
},
methods: {
async startScan() {
await bluetoothManager.init();
this.devices = [];
bluetoothManager.setDeviceFoundCallback((device) => {
// 避免重复添加
if (!this.devices.find(d => d.deviceId === device.deviceId)) {
this.devices.push(device);
}
});
await bluetoothManager.startScan();
uni.showToast({ title: '扫描中...', icon: 'none' });
// 30秒后停止
setTimeout(() => bluetoothManager.stopScan(), 30000);
},
async selectDevice(device) {
bluetoothManager.stopScan();
uni.showLoading({ title: '连接设备中...' });
try {
const { services, deviceId } = await bluetoothManager.connectForDiscovery(device.deviceId);
this.selectedDeviceId = deviceId;
this.services = services;
this.characteristics = [];
this.selectedServiceId = null;
this.selectedWriteChar = null;
this.selectedNotifyChar = null;
uni.hideLoading();
uni.showToast({ title: '连接成功,请选择服务', icon: 'success' });
} catch (err) {
uni.hideLoading();
uni.showToast({ title: '连接失败', icon: 'none' });
}
},
async selectService(service) {
this.selectedServiceId = service.uuid;
uni.showLoading({ title: '获取特征值...' });
try {
const chars = await this._getCharacteristics(this.selectedDeviceId, service.uuid);
this.characteristics = chars;
uni.hideLoading();
} catch (err) {
uni.hideLoading();
uni.showToast({ title: '获取特征值失败', icon: 'none' });
}
},
async _getCharacteristics(deviceId, serviceId) {
return new Promise((resolve, reject) => {
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success: (res) => resolve(res.characteristics),
fail: reject,
});
});
},
selectWriteChar(char) {
if (!char.properties.write && !char.properties.writeNoResponse) {
uni.showToast({ title: '该特征值不支持写入', icon: 'none' });
return;
}
this.selectedWriteChar = char.uuid;
},
selectNotifyChar(char) {
if (!char.properties.notify && !char.properties.indicate) {
uni.showToast({ title: '该特征值不支持通知', icon: 'none' });
return;
}
this.selectedNotifyChar = char.uuid;
},
async saveConfiguration() {
if (!this.selectedWriteChar) {
uni.showToast({ title: '请先选择写入特征值', icon: 'none' });
return;
}
try {
await bluetoothManager.saveAndConnect(
this.selectedDeviceId,
this.selectedServiceId,
this.selectedWriteChar,
this.selectedNotifyChar
);
// 保存配置到本地
const config = {
deviceId: this.selectedDeviceId,
serviceId: this.selectedServiceId,
writeCharId: this.selectedWriteChar,
notifyCharId: this.selectedNotifyChar,
deviceName: this.devices.find(d => d.deviceId === this.selectedDeviceId)?.name || '',
};
uni.setStorageSync('bleDeviceConfig', config);
uni.showToast({ title: '配置已保存,可返回使用', icon: 'success' });
// 可选:跳转到主页面
setTimeout(() => uni.navigateBack(), 1500);
} catch (err) {
console.error('保存失败', err);
uni.showToast({ title: '保存失败', icon: 'none' });
}
},
},
};
</script>
<style lang="scss">
@import '@/styles/variables.scss';
.device-item, .service-item, .char-item {
padding: 10px;
border-bottom: 1px solid #ddd;
margin: 5px 0;
}
.mac {
font-size: $font-size-sm;
color: gray;
margin-left: 10px;
}
</style>