/** * 扫描设备页面 */ const ble = require('../../../services/ble.js'); const storage = require('../../../utils/storage.js'); Page({ data: { scanning: false, scannedDevices: [], statusText: '准备扫描', statusHint: '点击下方按钮开始扫描 BLE 设备', // 配置弹窗 showConfigModal: false, configuring: false, selectedDevice: null, configForm: { name: '', serialNumber: '', productId: '', productSecret: '', serviceUUID: '', }, }, onLoad() { // 初始化蓝牙 this._initBluetooth(); }, onUnload() { // 停止扫描 if (this.data.scanning) { ble.bleService.stopScan(); } }, /** * 初始化蓝牙 */ async _initBluetooth() { try { await ble.bleService.initBluetooth(); this.setData({ statusText: '蓝牙已就绪', statusHint: '点击下方按钮开始扫描 BLE 设备', }); } catch (err) { console.error('[Scan] 初始化蓝牙失败:', err); this.setData({ statusText: '蓝牙初始化失败', statusHint: err.message || '请确保已开启蓝牙', }); wx.showModal({ title: '蓝牙错误', content: err.message || '请确保已开启蓝牙权限', showCancel: false, success: () => { wx.navigateBack(); }, }); } }, /** * 开始扫描 */ async handleScan() { if (this.data.scanning) return; this.setData({ scanning: true, scannedDevices: [], statusText: '正在扫描...', statusHint: '请确保设备已开机且在附近', }); try { const devices = await ble.bleService.scanDevices(); this.setData({ scanning: false, scannedDevices: devices, statusText: devices.length > 0 ? `发现 ${devices.length} 个设备` : '扫描完成', statusHint: devices.length > 0 ? '点击设备进行连接配置' : '未发现设备,请确保设备已开机', }); } catch (err) { console.error('[Scan] 扫描失败:', err); this.setData({ scanning: false, statusText: '扫描失败', statusHint: err.message || '请重试', }); } }, /** * 停止扫描 */ async handleStopScan() { await ble.bleService.stopScan(); this.setData({ scanning: false, statusText: '已停止扫描', }); }, /** * 选择设备 - 显示配置弹窗 */ handleSelectDevice(e) { const index = e.currentTarget.dataset.index; const device = this.data.scannedDevices[index]; if (!device) return; this.setData({ selectedDevice: device, showConfigModal: true, configForm: { name: device.name || '', serialNumber: '', productId: '', productSecret: '', serviceUUID: '', }, }); }, /** * 配置输入 */ onConfigInput(e) { const field = e.currentTarget.dataset.field; const value = e.detail.value; this.setData({ [`configForm.${field}`]: value, }); }, /** * 取消配置 */ handleCancelConfig() { this.setData({ showConfigModal: false, selectedDevice: null, }); }, /** * 确认配置 - 连接设备并保存 */ async handleConfirmConfig() { const { selectedDevice, configForm } = this.data; // 验证配置 if (!configForm.serialNumber) { wx.showToast({ title: '请输入设备编号', icon: 'none' }); return; } if (!configForm.productId) { wx.showToast({ title: '请输入产品ID', icon: 'none' }); return; } if (!configForm.productSecret) { wx.showToast({ title: '请输入产品密钥', icon: 'none' }); return; } this.setData({ configuring: true }); try { // 连接设备 wx.showLoading({ title: '正在连接...', mask: true }); const serviceId = configForm.serviceUUID || null; await ble.bleService.connectDevice(selectedDevice.deviceId, serviceId); wx.hideLoading(); // 保存设备配置 const deviceConfig = { deviceId: selectedDevice.deviceId, serialNumber: configForm.serialNumber, name: configForm.name || selectedDevice.name || configForm.serialNumber, productId: parseInt(configForm.productId), productSecret: configForm.productSecret, serviceUUID: configForm.serviceUUID, bleName: selectedDevice.name, RSSI: selectedDevice.RSSI, enabled: true, connected: true, createTime: Date.now(), }; storage.addDevice(deviceConfig); wx.showToast({ title: '保存成功', icon: 'success' }); // 断开 BLE 连接(让详情页重新连接,防止连接泄漏) await ble.bleService.disconnect(); // 延迟返回 setTimeout(() => { this.setData({ showConfigModal: false }); wx.navigateBack(); }, 500); } catch (err) { wx.hideLoading(); console.error('[Scan] 连接失败:', err); wx.showToast({ title: err.message || '连接失败', icon: 'none', }); } finally { this.setData({ configuring: false }); } }, });