fastbee/yack-mini/miniprogram/pages/device/scan/scan.js

232 lines
5.8 KiB
JavaScript

/**
* 扫描设备页面
*/
const ble = require('../../../services/ble.js');
const storage = require('../../../utils/storage.js');
const { gateway } = require('../../../services/gateway.js');
Page({
data: {
scanning: false,
scannedDevices: [],
statusText: '准备扫描',
statusHint: '点击下方按钮开始扫描 BLE 设备',
// 配置弹窗
showConfigModal: false,
configuring: false,
selectedDevice: null,
configForm: {
name: '',
serialNumber: '',
productId: '',
productSecret: '',
serviceUUID: '',
},
},
onLoad() {
// 暂停正在跑的网关,避免常驻会话与扫描/校验连接抢占同一 BLE 目标;
// 返回首页后 index.onShow → gateway.ensureStarted() 会自动恢复。
gateway.stop().then(() => 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);
// 新设备成为唯一启用(单 enabled 不变量,兼修历史多启用数据)
storage.activateDevice(deviceConfig.serialNumber);
wx.showToast({ title: '保存成功', icon: 'success' });
// 延迟返回(先断开连接再返回,让详情页重新连接)
setTimeout(async () => {
try {
await ble.bleService.disconnect();
} catch (e) {
console.warn('[Scan] 断开连接失败:', e);
}
this.setData({ showConfigModal: false });
wx.navigateBack();
}, 500);
} catch (err) {
wx.hideLoading();
console.error('[Scan] 连接失败:', err);
wx.showToast({
title: err.message || '连接失败',
icon: 'none',
});
// 连接失败时确保断开,避免残留连接
try {
await ble.bleService.disconnect();
} catch (e) {
console.warn('[Scan] 断开连接失败:', e);
}
} finally {
this.setData({ configuring: false });
}
},
});