[AI Generated]: feat(*): 修复连接设备页及配网页交互逻辑、蓝牙状态显示与设备名获取
This commit is contained in:
@@ -29,6 +29,20 @@
|
|||||||
"componentFramework": "glass-easel",
|
"componentFramework": "glass-easel",
|
||||||
"sitemapLocation": "sitemap.json",
|
"sitemapLocation": "sitemap.json",
|
||||||
"lazyCodeLoading": "requiredComponents",
|
"lazyCodeLoading": "requiredComponents",
|
||||||
|
"plugins": {
|
||||||
|
"ppScale-plugin": {
|
||||||
|
"version": "0.0.24",
|
||||||
|
"provider": "wx0826af4e4908f524"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permission": {
|
||||||
|
"scope.userLocation": {
|
||||||
|
"desc": "您的位置信息将用于发现附近的蓝牙设备,以便连接蓝牙秤。"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requiredPrivateInfos": [
|
||||||
|
"getLocation"
|
||||||
|
],
|
||||||
"tabBar": {
|
"tabBar": {
|
||||||
"color": "#999999",
|
"color": "#999999",
|
||||||
"selectedColor": "#000000",
|
"selectedColor": "#000000",
|
||||||
|
|||||||
+8
-8
@@ -11,13 +11,13 @@ App<IAppOption>({
|
|||||||
lefuService.init()
|
lefuService.init()
|
||||||
|
|
||||||
// 已登录则跳过登录页
|
// 已登录则跳过登录页
|
||||||
const userInfo = wx.getStorageSync('userInfo')
|
// const userInfo = wx.getStorageSync('userInfo')
|
||||||
if (userInfo) {
|
// if (userInfo) {
|
||||||
const connectDeviceInfo = wx.getStorageSync('connectDeviceInfo')
|
// const connectDeviceInfo = wx.getStorageSync('connectDeviceInfo')
|
||||||
const hasDevice = connectDeviceInfo && Object.keys(connectDeviceInfo).length > 0
|
// const hasDevice = connectDeviceInfo && Object.keys(connectDeviceInfo).length > 0
|
||||||
wx.reLaunch({
|
// wx.reLaunch({
|
||||||
url: hasDevice ? '/pages/home/home' : '/pages/connectedDevice/connectedDevice'
|
// url: hasDevice ? '/pages/home/home' : '/pages/connectedDevice/connectedDevice'
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 976 B |
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
+127
-41
@@ -68,6 +68,8 @@ const DEVICE_SETTINGS: DeviceSetting[] = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const TAG = '[LeFuService]'
|
||||||
|
|
||||||
class LeFuService {
|
class LeFuService {
|
||||||
private _plugin: LeFuPlugin | null = null
|
private _plugin: LeFuPlugin | null = null
|
||||||
/** 设备协议对象,devicesModel 事件返回,用于 WiFi 配网等高级操作 */
|
/** 设备协议对象,devicesModel 事件返回,用于 WiFi 配网等高级操作 */
|
||||||
@@ -84,16 +86,23 @@ class LeFuService {
|
|||||||
/** 连接后从 deviceInfo 事件获取的固件信息 */
|
/** 连接后从 deviceInfo 事件获取的固件信息 */
|
||||||
private _deviceInfo: DeviceInfo | null = null
|
private _deviceInfo: DeviceInfo | null = null
|
||||||
|
|
||||||
|
/** bus 事件是否已订阅(防止多次 startScan 重复 subscribe 累积) */
|
||||||
|
private _busSubscribed = false
|
||||||
|
|
||||||
/** 回调注册(页面通过 on* 方法注册,stopScan 时清空) */
|
/** 回调注册(页面通过 on* 方法注册,stopScan 时清空) */
|
||||||
private _onDevicesListCb: ((devices: ScannedDevice[]) => void) | null = null
|
private _onDevicesListCb: ((devices: ScannedDevice[]) => void) | null = null
|
||||||
private _onConnectStateCb: ((state: string) => void) | null = null
|
private _onConnectStateCb: ((state: string) => void) | null = null
|
||||||
|
private _onDeviceConnectCb: (() => void) | null = null
|
||||||
private _onProgressCb: ((data: ProgressData) => void) | null = null
|
private _onProgressCb: ((data: ProgressData) => void) | null = null
|
||||||
private _onLockedCb: ((data: LockData) => void) | null = null
|
private _onLockedCb: ((data: LockData) => void) | null = null
|
||||||
private _onDisconnectedCb: (() => void) | null = null
|
private _onDisconnectedCb: (() => void) | null = null
|
||||||
|
private _onDeviceInfoCb: ((info: DeviceInfo) => void) | null = null
|
||||||
|
|
||||||
/** 在 app.ts onLaunch 中调用,加载 ppScale-plugin */
|
/** 在 app.ts onLaunch 中调用,加载 ppScale-plugin */
|
||||||
init(): void {
|
init(): void {
|
||||||
|
console.log(TAG, 'init() 开始加载插件')
|
||||||
this._plugin = requirePlugin('ppScale-plugin') as LeFuPlugin
|
this._plugin = requirePlugin('ppScale-plugin') as LeFuPlugin
|
||||||
|
console.log(TAG, 'init() 插件加载完成:', !!this._plugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取插件(未初始化时抛出) */
|
/** 获取插件(未初始化时抛出) */
|
||||||
@@ -111,14 +120,45 @@ class LeFuService {
|
|||||||
|
|
||||||
/** 注册设备列表回调(扫描到设备时触发) */
|
/** 注册设备列表回调(扫描到设备时触发) */
|
||||||
onDevicesList(cb: (devices: ScannedDevice[]) => void): void {
|
onDevicesList(cb: (devices: ScannedDevice[]) => void): void {
|
||||||
|
console.log(TAG, 'onDevicesList 回调已注册')
|
||||||
this._onDevicesListCb = cb
|
this._onDevicesListCb = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 注册蓝牙连接状态回调 */
|
/** 注册蓝牙连接状态回调 */
|
||||||
onConnectState(cb: (state: string) => void): void {
|
onConnectState(cb: (state: string) => void): void {
|
||||||
|
console.log(TAG, 'onConnectState 回调已注册')
|
||||||
this._onConnectStateCb = cb
|
this._onConnectStateCb = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 注册设备连接就绪回调(activeProtocol 可用时触发) */
|
||||||
|
onDeviceConnect(cb: () => void): void {
|
||||||
|
console.log(TAG, 'onDeviceConnect 回调已注册')
|
||||||
|
this._onDeviceConnectCb = cb
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 当前蓝牙连接状态(connectState bus 事件实时更新) */
|
||||||
|
private _connectState = ''
|
||||||
|
|
||||||
|
/** 设备是否已连接(activeProtocol 就绪) */
|
||||||
|
get isConnected(): boolean {
|
||||||
|
return !!this._activeProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 当前蓝牙连接状态字符串 */
|
||||||
|
get connectState(): string {
|
||||||
|
return this._connectState
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 插件 BLUE_STATE 常量对象(供页面 wxml 条件判断用) */
|
||||||
|
get BLUE_STATE(): Record<string, string> {
|
||||||
|
return this._plugin?.BLUE_STATE ?? {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 连接后从 deviceInfo 事件获取的设备信息(含 modelNumber / serialNumber 等) */
|
||||||
|
get deviceInfo(): DeviceInfo | null {
|
||||||
|
return this._deviceInfo
|
||||||
|
}
|
||||||
|
|
||||||
/** 注册实时测量回调(测量过程中多次触发) */
|
/** 注册实时测量回调(测量过程中多次触发) */
|
||||||
onMeasuring(cb: (data: ProgressData) => void): void {
|
onMeasuring(cb: (data: ProgressData) => void): void {
|
||||||
this._onProgressCb = cb
|
this._onProgressCb = cb
|
||||||
@@ -134,57 +174,84 @@ class LeFuService {
|
|||||||
this._onDisconnectedCb = cb
|
this._onDisconnectedCb = cb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 注册 deviceInfo 就绪回调(设备名/固件信息可用时触发) */
|
||||||
|
onDeviceInfo(cb: (info: DeviceInfo) => void): void {
|
||||||
|
this._onDeviceInfoCb = cb
|
||||||
|
}
|
||||||
|
|
||||||
// ─── 扫描与连接 ───────────────────────────────
|
// ─── 扫描与连接 ───────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始蓝牙扫描
|
* 开始蓝牙扫描
|
||||||
* 先注册所有 bus 事件再调用 plugin.Blue.start()
|
* 对齐 master:先 setDeviceSetting → start,再 subscribe(master searchDevice.js 顺序)
|
||||||
* 页面 onShow 时调用
|
|
||||||
*/
|
*/
|
||||||
startScan(): void {
|
startScan(): void {
|
||||||
|
console.log(TAG, 'startScan() 开始,busSubscribed:', this._busSubscribed)
|
||||||
const plugin = this._p
|
const plugin = this._p
|
||||||
|
|
||||||
// 扫描到设备列表
|
// ① 先设置设备配置并启动扫描(必须在 subscribe 之前,与 master 一致)
|
||||||
plugin.bus.subscribe('devicesList', (devList: RawDevice[]) => {
|
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||||
// 广播秤(BleAdv)自动调用 setbroadcastDev,无需用户手动点击连接
|
const deviceNames = DEVICE_SETTINGS.map(s => s.deviceName)
|
||||||
const advDev = devList.find((item: RawDevice) => {
|
console.log(TAG, 'plugin.Blue.start() 调用,设备名称:', deviceNames)
|
||||||
const model = plugin.Blue.getDeviceModel(item)
|
plugin.Blue.start(deviceNames, false)
|
||||||
return model?.deviceConnectType === plugin.PPBluetoothDefine.PPDeviceConnectType.PPDeviceConnectTypeBleAdv
|
|
||||||
})
|
|
||||||
if (advDev) {
|
|
||||||
plugin.Blue.setbroadcastDev(advDev)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换为展示层数据
|
// bus 订阅只注册一次,stopScan 时重置,避免多次搜索导致订阅累积
|
||||||
|
if (this._busSubscribed) {
|
||||||
|
console.log(TAG, 'bus 已订阅,跳过重复注册')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this._busSubscribed = true
|
||||||
|
|
||||||
|
// ② 启动后再订阅设备列表(master 也是 start 后才 subscribe)
|
||||||
|
plugin.bus.subscribe('devicesList', (devList: RawDevice[]) => {
|
||||||
|
console.log(TAG, 'bus[devicesList] 触发,原始设备数:', devList?.length, devList?.map((d: RawDevice) => d.name || d.deviceName))
|
||||||
|
if (!devList || !devList.length) {
|
||||||
|
this._onDevicesListCb?.([])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 直接用原始列表转换,不调用 getDeviceModel(master 也是直接传 res)
|
||||||
const devices: ScannedDevice[] = devList.map((item: RawDevice) => ({
|
const devices: ScannedDevice[] = devList.map((item: RawDevice) => ({
|
||||||
name: item.name || item.deviceName || '未知设备',
|
name: item.name || item.deviceName || '未知设备',
|
||||||
raw: item,
|
raw: item,
|
||||||
model: plugin.Blue.getDeviceModel(item) || {},
|
model: {},
|
||||||
}))
|
}))
|
||||||
|
console.log(TAG, '转换后设备列表:', devices.map(d => d.name))
|
||||||
this._onDevicesListCb?.(devices)
|
this._onDevicesListCb?.(devices)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 协议对象(持有 activeProtocol,WiFi 配网等高级操作依赖它)
|
// 设备模型信息(含 mac 等,仅用于日志/调试)
|
||||||
plugin.bus.subscribe('devicesModel', (res: any) => {
|
plugin.bus.subscribe('devicesModel', (res: any) => {
|
||||||
this._activeProtocol = res
|
console.log(TAG, 'bus[devicesModel] 触发,deviceMac:', res?.deviceMac)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 连接成功后获取固件信息(用于后续 OTA 版本比对)
|
// 连接成功后获取固件信息(用于后续 OTA 版本比对)
|
||||||
plugin.bus.subscribe('deviceInfo', (res: DeviceInfo) => {
|
plugin.bus.subscribe('deviceInfo', (res: DeviceInfo) => {
|
||||||
|
console.log(TAG, 'bus[deviceInfo] 触发:',res, res?.firmwareRevision, res?.modelNumber)
|
||||||
this._deviceInfo = res
|
this._deviceInfo = res
|
||||||
|
this._onDeviceInfoCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 连接成功
|
// 连接建立:从 ScaleAction 获取 activeProtocol,启动数据进度(对齐 master configureDevice.js)
|
||||||
plugin.bus.subscribe('deviceConnect', () => {
|
plugin.bus.subscribe('deviceConnect', () => {
|
||||||
|
console.log(TAG, 'bus[deviceConnect] 触发,获取 activeProtocol,启动数据进度')
|
||||||
this._reconnectCount = 0
|
this._reconnectCount = 0
|
||||||
plugin.ScaleAction.startDataProgress()
|
plugin.ScaleAction.startDataProgress(true)
|
||||||
this._startKeepAlive()
|
this._activeProtocol = plugin.ScaleAction.getActiveProtocol()
|
||||||
|
this._connectState = plugin.BLUE_STATE.CONNECTSUCCESS
|
||||||
|
this._onDeviceConnectCb?.()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 连接状态变化
|
// 连接状态变化:CONNECTSUCCESS 时启动保活,CONNECTFAILED 时重连
|
||||||
plugin.bus.subscribe('connectState', (res: string) => {
|
plugin.bus.subscribe('connectState', (res: string) => {
|
||||||
|
console.log(TAG, 'bus[connectState] 触发:', res)
|
||||||
|
this._connectState = res
|
||||||
this._onConnectStateCb?.(res)
|
this._onConnectStateCb?.(res)
|
||||||
|
if (res === plugin.BLUE_STATE.CONNECTSUCCESS) {
|
||||||
|
console.log(TAG, '连接成功,启动保活心跳')
|
||||||
|
this._startKeepAlive()
|
||||||
|
}
|
||||||
if (res === plugin.BLUE_STATE.CONNECTFAILED) {
|
if (res === plugin.BLUE_STATE.CONNECTFAILED) {
|
||||||
|
console.warn(TAG, '连接失败,触发重连逻辑')
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._doReconnect()
|
this._doReconnect()
|
||||||
}
|
}
|
||||||
@@ -192,58 +259,51 @@ class LeFuService {
|
|||||||
|
|
||||||
// 实时测量数据
|
// 实时测量数据
|
||||||
plugin.bus.subscribe('progressData', (res: ProgressData) => {
|
plugin.bus.subscribe('progressData', (res: ProgressData) => {
|
||||||
|
console.log(TAG, 'bus[progressData] 体重(g):', res?.weight)
|
||||||
this._onProgressCb?.(res)
|
this._onProgressCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 测量锁定(完成)
|
// 测量锁定(完成)
|
||||||
plugin.bus.subscribe('lockData', (res: LockData) => {
|
plugin.bus.subscribe('lockData', (res: LockData) => {
|
||||||
|
console.log(TAG, 'bus[lockData] 测量完成,体重(g):', res?.weight, '阻抗:', res?.resistance)
|
||||||
this._onLockedCb?.(res)
|
this._onLockedCb?.(res)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 设备自动断开
|
// 设备自动断开
|
||||||
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
plugin.bus.subscribe('deviceWillDisconnect', () => {
|
||||||
|
console.warn(TAG, 'bus[deviceWillDisconnect] 设备断开,触发重连')
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._onDisconnectedCb?.()
|
this._onDisconnectedCb?.()
|
||||||
this._doReconnect()
|
this._doReconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 开始扫描,传入设备配置过滤列表
|
|
||||||
plugin.Blue.start(DEVICE_SETTINGS)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主动连接指定设备
|
* 主动连接指定设备(对齐 master:直接调 createBLEConnection,不判断 deviceConnectType)
|
||||||
* BleAdv 类型已在 devicesList 中自动处理,无需调用此方法
|
|
||||||
* BleConnect 类型需要用户点击后调用
|
|
||||||
*/
|
*/
|
||||||
connect(device: ScannedDevice): void {
|
connect(device: ScannedDevice): void {
|
||||||
const connectType = this._p.PPBluetoothDefine.PPDeviceConnectType
|
console.log(TAG, 'connect() 设备:', device.name)
|
||||||
if (device.model?.deviceConnectType === connectType.PPDeviceConnectTypeBleConnect) {
|
this._p.Blue.createBLEConnection(device.raw)
|
||||||
this._p.Blue.createBLEConnection(device.raw)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 主动断开当前连接 */
|
/** 主动断开当前连接 */
|
||||||
disconnect(): void {
|
disconnect(): void {
|
||||||
|
console.log(TAG, 'disconnect() 主动断开')
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
this._p.Blue.disconnect()
|
this._p.Blue.disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停止扫描,清理所有 bus 订阅与回调
|
* 停止扫描(仅停止设备发现,不清连接态)
|
||||||
* 页面 onUnload / onHide 时调用
|
* connectedDevice onHide / onUnload 时调用
|
||||||
*/
|
*/
|
||||||
stopScan(): void {
|
stopScan(): void {
|
||||||
this._stopKeepAlive()
|
console.log(TAG, 'stopScan() 停止扫描')
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
this._p.Blue.stop()
|
this._busSubscribed = false
|
||||||
this._activeProtocol = null
|
wx.stopBluetoothDevicesDiscovery()
|
||||||
this._deviceInfo = null
|
|
||||||
this._onDevicesListCb = null
|
this._onDevicesListCb = null
|
||||||
this._onConnectStateCb = null
|
this._onDeviceConnectCb = null
|
||||||
this._onProgressCb = null
|
|
||||||
this._onLockedCb = null
|
|
||||||
this._onDisconnectedCb = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── WiFi 配网 ────────────────────────────────
|
// ─── WiFi 配网 ────────────────────────────────
|
||||||
@@ -253,6 +313,7 @@ class LeFuService {
|
|||||||
* 内部延迟 2 秒后调用,15 秒超时
|
* 内部延迟 2 秒后调用,15 秒超时
|
||||||
*/
|
*/
|
||||||
getWifiList(): Promise<LeFuWifiItem[]> {
|
getWifiList(): Promise<LeFuWifiItem[]> {
|
||||||
|
console.log(TAG, 'getWifiList() 开始')
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('[LeFu] 设备未连接,无法获取 WiFi 列表'))
|
reject(new Error('[LeFu] 设备未连接,无法获取 WiFi 列表'))
|
||||||
@@ -267,6 +328,7 @@ class LeFuService {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this._activeProtocol.dataFindSurroundDevice((res: any[]) => {
|
this._activeProtocol.dataFindSurroundDevice((res: any[]) => {
|
||||||
clearTimeout(timer)
|
clearTimeout(timer)
|
||||||
|
console.log(TAG, 'getWifiList 原始结果:', res)
|
||||||
if (!res || res.length === 0) {
|
if (!res || res.length === 0) {
|
||||||
this._activeProtocol.dataExitWifiConfig(() => {})
|
this._activeProtocol.dataExitWifiConfig(() => {})
|
||||||
resolve([])
|
resolve([])
|
||||||
@@ -276,6 +338,7 @@ class LeFuService {
|
|||||||
ssid: item.ssid || item.name || '',
|
ssid: item.ssid || item.name || '',
|
||||||
signal: item.signal,
|
signal: item.signal,
|
||||||
}))
|
}))
|
||||||
|
console.log(TAG, 'getWifiList 解析结果:', list.map(w => w.ssid))
|
||||||
resolve(list)
|
resolve(list)
|
||||||
})
|
})
|
||||||
}, 2000)
|
}, 2000)
|
||||||
@@ -290,6 +353,7 @@ class LeFuService {
|
|||||||
* 返回码 23 = 配网成功
|
* 返回码 23 = 配网成功
|
||||||
*/
|
*/
|
||||||
configWifi(ssid: string, password: string, version: WifiVersion): Promise<void> {
|
configWifi(ssid: string, password: string, version: WifiVersion): Promise<void> {
|
||||||
|
console.log(TAG, 'configWifi() ssid:', ssid, 'version:', version)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('[LeFu] 设备未连接,无法配网'))
|
reject(new Error('[LeFu] 设备未连接,无法配网'))
|
||||||
@@ -297,9 +361,12 @@ class LeFuService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const callback = (res: number) => {
|
const callback = (res: number) => {
|
||||||
|
console.log(TAG, 'configWifi 回调 res:', res)
|
||||||
if (res === 23) {
|
if (res === 23) {
|
||||||
|
console.log(TAG, 'configWifi 成功')
|
||||||
resolve()
|
resolve()
|
||||||
} else {
|
} else {
|
||||||
|
console.error(TAG, 'configWifi 失败,错误码:', res)
|
||||||
reject(new Error(`[LeFu] 配网失败,错误码:${res}`))
|
reject(new Error(`[LeFu] 配网失败,错误码:${res}`))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,12 +396,14 @@ class LeFuService {
|
|||||||
* 返回 true = 已配网(0x01),false = 未配网
|
* 返回 true = 已配网(0x01),false = 未配网
|
||||||
*/
|
*/
|
||||||
checkWifiConfig(): Promise<boolean> {
|
checkWifiConfig(): Promise<boolean> {
|
||||||
|
console.log(TAG, 'checkWifiConfig() 查询配网状态')
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('[LeFu] 设备未连接'))
|
reject(new Error('[LeFu] 设备未连接'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this._activeProtocol.codeFetchWifiConfig((res: number | undefined | null) => {
|
this._activeProtocol.codeFetchWifiConfig((res: number | undefined | null) => {
|
||||||
|
console.log(TAG, 'checkWifiConfig 回调 res:', res, '已配网:', res === 0x01)
|
||||||
resolve(res === 0x01)
|
resolve(res === 0x01)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -348,6 +417,7 @@ class LeFuService {
|
|||||||
* 调用时机由业务层决定,不自动触发
|
* 调用时机由业务层决定,不自动触发
|
||||||
*/
|
*/
|
||||||
checkAndUpgrade(): Promise<boolean> {
|
checkAndUpgrade(): Promise<boolean> {
|
||||||
|
console.log(TAG, 'checkAndUpgrade() 开始检查固件版本')
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('[LeFu] 设备未连接'))
|
reject(new Error('[LeFu] 设备未连接'))
|
||||||
@@ -359,6 +429,7 @@ class LeFuService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { firmwareRevision, modelNumber } = this._deviceInfo
|
const { firmwareRevision, modelNumber } = this._deviceInfo
|
||||||
|
console.log(TAG, '当前固件:', firmwareRevision, '型号:', modelNumber)
|
||||||
const [mcuVer, bleVer, wifiVer, resVer] = (firmwareRevision || '').split('.')
|
const [mcuVer, bleVer, wifiVer, resVer] = (firmwareRevision || '').split('.')
|
||||||
|
|
||||||
// 设备单段版本(如 "006")vs 服务端 x.y.z 格式(如 "0.0.6")比对
|
// 设备单段版本(如 "006")vs 服务端 x.y.z 格式(如 "0.0.6")比对
|
||||||
@@ -371,12 +442,14 @@ class LeFuService {
|
|||||||
get<FirmwareVersion>('weighingScale/v2/firmware/version', { type: modelNumber }, { loading: false })
|
get<FirmwareVersion>('weighingScale/v2/firmware/version', { type: modelNumber }, { loading: false })
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const { mcuVersion, bleVersion, wifiVersion, resVersion } = res.result
|
const { mcuVersion, bleVersion, wifiVersion, resVersion } = res.result
|
||||||
|
console.log(TAG, '服务端固件版本:', { mcuVersion, bleVersion, wifiVersion, resVersion })
|
||||||
const needUpdate =
|
const needUpdate =
|
||||||
isServerNewer(mcuVer, mcuVersion) ||
|
isServerNewer(mcuVer, mcuVersion) ||
|
||||||
isServerNewer(bleVer, bleVersion) ||
|
isServerNewer(bleVer, bleVersion) ||
|
||||||
isServerNewer(wifiVer, wifiVersion) ||
|
isServerNewer(wifiVer, wifiVersion) ||
|
||||||
isServerNewer(resVer, resVersion)
|
isServerNewer(resVer, resVersion)
|
||||||
|
|
||||||
|
console.log(TAG, '需要 OTA 升级:', needUpdate)
|
||||||
if (!needUpdate) {
|
if (!needUpdate) {
|
||||||
resolve(false)
|
resolve(false)
|
||||||
return
|
return
|
||||||
@@ -384,6 +457,7 @@ class LeFuService {
|
|||||||
|
|
||||||
// status: false = 成功,true = 失败
|
// status: false = 成功,true = 失败
|
||||||
this._activeProtocol.codeOtaUpdate((status: boolean) => {
|
this._activeProtocol.codeOtaUpdate((status: boolean) => {
|
||||||
|
console.log(TAG, 'OTA 升级回调 status:', status)
|
||||||
if (!status) {
|
if (!status) {
|
||||||
resolve(true)
|
resolve(true)
|
||||||
} else {
|
} else {
|
||||||
@@ -399,6 +473,7 @@ class LeFuService {
|
|||||||
|
|
||||||
private _startKeepAlive(): void {
|
private _startKeepAlive(): void {
|
||||||
this._stopKeepAlive()
|
this._stopKeepAlive()
|
||||||
|
console.log(TAG, '_startKeepAlive 保活心跳启动')
|
||||||
this._keepAliveTimer = setInterval(() => {
|
this._keepAliveTimer = setInterval(() => {
|
||||||
this._activeProtocol?.sendKeepAliveCode?.()
|
this._activeProtocol?.sendKeepAliveCode?.()
|
||||||
}, 15000)
|
}, 15000)
|
||||||
@@ -408,6 +483,7 @@ class LeFuService {
|
|||||||
if (this._keepAliveTimer !== null) {
|
if (this._keepAliveTimer !== null) {
|
||||||
clearInterval(this._keepAliveTimer)
|
clearInterval(this._keepAliveTimer)
|
||||||
this._keepAliveTimer = null
|
this._keepAliveTimer = null
|
||||||
|
console.log(TAG, '_stopKeepAlive 保活心跳停止')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -421,11 +497,16 @@ class LeFuService {
|
|||||||
|
|
||||||
/** 自动重连,最多 _maxReconnect 次,超限后等待用户手动重试 */
|
/** 自动重连,最多 _maxReconnect 次,超限后等待用户手动重试 */
|
||||||
private _doReconnect(): void {
|
private _doReconnect(): void {
|
||||||
if (this._reconnectCount >= this._maxReconnect) return
|
if (this._reconnectCount >= this._maxReconnect) {
|
||||||
|
console.warn(TAG, '重连次数已达上限:', this._maxReconnect)
|
||||||
|
return
|
||||||
|
}
|
||||||
this._reconnectCount++
|
this._reconnectCount++
|
||||||
|
console.log(TAG, `_doReconnect 第 ${this._reconnectCount} 次重连`)
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
this._reconnectTimer = setTimeout(() => {
|
this._reconnectTimer = setTimeout(() => {
|
||||||
this._plugin?.Blue?.disconnect((res: any) => {
|
this._plugin?.Blue?.disconnect((res: any) => {
|
||||||
|
console.log(TAG, '重连 disconnect 回调:', res?.errCode)
|
||||||
if (res?.errCode === 0) {
|
if (res?.errCode === 0) {
|
||||||
this._plugin?.Blue?.startBluetoothDevicesDiscovery()
|
this._plugin?.Blue?.startBluetoothDevicesDiscovery()
|
||||||
}
|
}
|
||||||
@@ -442,6 +523,7 @@ class LeFuService {
|
|||||||
* @param members 成员列表,必须包含且仅包含一个 isSelf=true 的主用户
|
* @param members 成员列表,必须包含且仅包含一个 isSelf=true 的主用户
|
||||||
*/
|
*/
|
||||||
syncMembersToDevice(members: DeviceMember[]): Promise<void> {
|
syncMembersToDevice(members: DeviceMember[]): Promise<void> {
|
||||||
|
console.log(TAG, 'syncMembersToDevice() 成员数:', members.length)
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!this._activeProtocol) {
|
if (!this._activeProtocol) {
|
||||||
reject(new Error('[LeFu] 设备未连接,无法同步成员'))
|
reject(new Error('[LeFu] 设备未连接,无法同步成员'))
|
||||||
@@ -461,6 +543,7 @@ class LeFuService {
|
|||||||
|
|
||||||
this._activeProtocol.codeClearDeviceData('01', (clearRes: number) => {
|
this._activeProtocol.codeClearDeviceData('01', (clearRes: number) => {
|
||||||
clearTimeout(clearTimer)
|
clearTimeout(clearTimer)
|
||||||
|
console.log(TAG, 'codeClearDeviceData 回调:', clearRes)
|
||||||
if (clearRes !== 0x00) {
|
if (clearRes !== 0x00) {
|
||||||
reject(new Error('[LeFu] 清除设备成员失败'))
|
reject(new Error('[LeFu] 清除设备成员失败'))
|
||||||
return
|
return
|
||||||
@@ -480,11 +563,13 @@ class LeFuService {
|
|||||||
const syncNext = () => {
|
const syncNext = () => {
|
||||||
if (index >= members.length) {
|
if (index >= members.length) {
|
||||||
if (syncTimer !== null) clearTimeout(syncTimer)
|
if (syncTimer !== null) clearTimeout(syncTimer)
|
||||||
|
console.log(TAG, 'syncMembersToDevice 全部同步完成')
|
||||||
resolve()
|
resolve()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const member = members[index]
|
const member = members[index]
|
||||||
|
console.log(TAG, `下发第 ${index + 1}/${members.length} 个成员:`, member.name)
|
||||||
resetTimer()
|
resetTimer()
|
||||||
|
|
||||||
this._activeProtocol.dataSyncUserInfo(
|
this._activeProtocol.dataSyncUserInfo(
|
||||||
@@ -504,6 +589,7 @@ class LeFuService {
|
|||||||
recentData: [],
|
recentData: [],
|
||||||
},
|
},
|
||||||
(res: number) => {
|
(res: number) => {
|
||||||
|
console.log(TAG, `第 ${index + 1} 个成员同步回调:`, res)
|
||||||
if (res === 0) {
|
if (res === 0) {
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 48rpx 30rpx 0;
|
padding: 48rpx 30rpx 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
background-color: #ffffff;
|
||||||
|
|
||||||
/* 三层同心圆波纹动画 */
|
/* 三层同心圆波纹动画 */
|
||||||
.ripple {
|
.ripple {
|
||||||
|
|||||||
@@ -1,103 +1,189 @@
|
|||||||
import { lefuService } from '../../lefu/index'
|
import { lefuService } from '../../lefu/index'
|
||||||
import type { ScannedDevice } from '../../lefu/index'
|
import type { ScannedDevice } from '../../lefu/index'
|
||||||
|
|
||||||
/** 展示用设备项 */
|
/** 展示用设备项(仅存入 setData,不含复杂对象) */
|
||||||
interface DeviceItem {
|
interface DeviceItem {
|
||||||
/** 设备名称 */
|
|
||||||
name: string
|
name: string
|
||||||
/** 是否已连接 */
|
|
||||||
connected: boolean
|
connected: boolean
|
||||||
/** 原始设备对象(连接时传回给 SDK) */
|
|
||||||
_raw: ScannedDevice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 页面状态 */
|
/** 页面状态 */
|
||||||
type DeviceStatus = 'idle' | 'searching' | 'found' | 'empty'
|
type DeviceStatus = 'idle' | 'searching' | 'found' | 'empty'
|
||||||
|
|
||||||
|
/** 页面级原始设备缓存,不进入 setData 避免序列化异常 */
|
||||||
|
let _rawDevices: ScannedDevice[] = []
|
||||||
|
|
||||||
|
const TAG = '[connectedDevice]'
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
/**
|
|
||||||
* 页面状态
|
|
||||||
* - idle: 未搜索(进入页面默认态)
|
|
||||||
* - searching: 扫描中
|
|
||||||
* - found: 扫描完成且有设备
|
|
||||||
* - empty: 扫描完成但无设备
|
|
||||||
*/
|
|
||||||
status: 'idle' as DeviceStatus,
|
status: 'idle' as DeviceStatus,
|
||||||
|
|
||||||
/** 扫描到的设备列表 */
|
|
||||||
deviceList: [] as DeviceItem[],
|
deviceList: [] as DeviceItem[],
|
||||||
|
/** 防止权限弹框重入 */
|
||||||
|
_modalLock: false,
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
// 注册回调后开始扫描
|
console.log(TAG, 'onShow')
|
||||||
lefuService.onDevicesList((devices) => {
|
|
||||||
if (!devices.length) {
|
|
||||||
this.setData({ status: 'empty', deviceList: [] })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const list: DeviceItem[] = devices.map(d => ({
|
|
||||||
name: d.name,
|
|
||||||
connected: false,
|
|
||||||
_raw: d,
|
|
||||||
}))
|
|
||||||
this.setData({ status: 'found', deviceList: list })
|
|
||||||
})
|
|
||||||
|
|
||||||
lefuService.onConnectState((state) => {
|
|
||||||
const plugin = lefuService['_plugin']
|
|
||||||
if (!plugin) return
|
|
||||||
|
|
||||||
if (state === plugin.BLUE_STATE.CONNECTSUCCESS) {
|
|
||||||
// 蓝牙连接成功,存储设备信息后跳配网页
|
|
||||||
const connected = this.data.deviceList.find(d => d.connected)
|
|
||||||
if (connected) {
|
|
||||||
wx.setStorageSync('connectDeviceInfo', { name: connected.name })
|
|
||||||
}
|
|
||||||
wx.navigateTo({ url: '/pages/connectedWifi/connectedWifi' })
|
|
||||||
} else if (state === plugin.BLUE_STATE.WIFISUCCESS) {
|
|
||||||
// 设备已配网,直接进首页
|
|
||||||
wx.reLaunch({ url: '/pages/home/home' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.onStartSearch()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onHide() {
|
onHide() {
|
||||||
// 页面隐藏时停止扫描,释放 bus 订阅
|
console.log(TAG, 'onHide, 停止扫描')
|
||||||
lefuService.stopScan()
|
lefuService.stopScan()
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
|
console.log(TAG, 'onUnload, 停止扫描')
|
||||||
lefuService.stopScan()
|
lefuService.stopScan()
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 开始 / 重新搜索 */
|
/** 点击「开始搜索 / 重新搜索」按钮:先验权限,再扫描 */
|
||||||
onStartSearch() {
|
async onStartSearch() {
|
||||||
|
console.log(TAG, 'onStartSearch, _modalLock:', this.data._modalLock)
|
||||||
|
if (this.data._modalLock) return
|
||||||
|
_rawDevices = []
|
||||||
this.setData({ status: 'searching', deviceList: [] })
|
this.setData({ status: 'searching', deviceList: [] })
|
||||||
|
await this._checkPermissionAndScan()
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 检查蓝牙 + 位置权限,通过后开始扫描 */
|
||||||
|
async _checkPermissionAndScan() {
|
||||||
|
console.log(TAG, '_checkPermissionAndScan 开始')
|
||||||
|
try {
|
||||||
|
const { authSetting } = await wx.getSetting()
|
||||||
|
const setting = authSetting as Record<string, boolean | undefined>
|
||||||
|
const hasBle = setting['scope.bluetooth']
|
||||||
|
const hasLoc = setting['scope.userLocation']
|
||||||
|
console.log(TAG, '权限状态 → 蓝牙:', hasBle, '位置:', hasLoc)
|
||||||
|
|
||||||
|
if (hasBle && hasLoc) {
|
||||||
|
await this._openAdapterAndScan()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 逐个申请缺失权限
|
||||||
|
const missing: Array<{ scope: string; label: string }> = []
|
||||||
|
if (!hasBle) missing.push({ scope: 'scope.bluetooth', label: '蓝牙' })
|
||||||
|
if (!hasLoc) missing.push({ scope: 'scope.userLocation', label: '位置' })
|
||||||
|
console.log(TAG, '缺失权限:', missing.map(m => m.label))
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const item of missing) {
|
||||||
|
console.log(TAG, '申请权限:', item.scope)
|
||||||
|
await wx.authorize({ scope: item.scope })
|
||||||
|
console.log(TAG, '权限申请成功:', item.scope)
|
||||||
|
}
|
||||||
|
await this._openAdapterAndScan()
|
||||||
|
} catch (err) {
|
||||||
|
console.warn(TAG, '权限申请被拒绝:', err)
|
||||||
|
this._showPermissionModal(missing.map(m => m.label).join('和'))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(TAG, 'getSetting 失败:', err)
|
||||||
|
wx.showToast({ title: '获取权限设置失败', icon: 'none' })
|
||||||
|
this.setData({ status: 'idle' })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 引导用户去设置页开启权限 */
|
||||||
|
_showPermissionModal(permissionNames: string) {
|
||||||
|
console.log(TAG, '弹出权限引导框, 缺失:', permissionNames)
|
||||||
|
this.setData({ _modalLock: true })
|
||||||
|
|
||||||
|
wx.showModal({
|
||||||
|
title: '需要授权',
|
||||||
|
content: `小程序需要您的${permissionNames}权限才能搜索蓝牙设备,请前往手机设置开启。`,
|
||||||
|
confirmText: '去开启',
|
||||||
|
cancelText: '取消',
|
||||||
|
success: (res) => {
|
||||||
|
console.log(TAG, '权限弹框结果:', res.confirm ? '去开启' : '取消')
|
||||||
|
this.setData({ _modalLock: false, status: 'idle' })
|
||||||
|
if (res.confirm) {
|
||||||
|
wx.openSetting({
|
||||||
|
success: () => this.onStartSearch(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
this.setData({ _modalLock: false, status: 'idle' })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 打开蓝牙适配器,成功后启动扫描 */
|
||||||
|
async _openAdapterAndScan() {
|
||||||
|
console.log(TAG, 'wx.openBluetoothAdapter() 开始')
|
||||||
|
try {
|
||||||
|
await wx.openBluetoothAdapter()
|
||||||
|
console.log(TAG, 'wx.openBluetoothAdapter() 成功')
|
||||||
|
this._startScan()
|
||||||
|
} catch (err: any) {
|
||||||
|
console.error(TAG, 'wx.openBluetoothAdapter() 失败, errCode:', err?.errCode, err?.errMsg)
|
||||||
|
if (err?.errCode === 10001) {
|
||||||
|
wx.showModal({
|
||||||
|
title: '蓝牙未开启',
|
||||||
|
content: '请先开启手机蓝牙后重试',
|
||||||
|
showCancel: false,
|
||||||
|
confirmText: '知道了',
|
||||||
|
success: () => this.setData({ status: 'idle' }),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
wx.showToast({ title: '蓝牙初始化失败', icon: 'none' })
|
||||||
|
this.setData({ status: 'idle' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 权限已就绪,注册设备列表回调并启动扫描 */
|
||||||
|
_startScan() {
|
||||||
|
console.log(TAG, '_startScan 启动')
|
||||||
|
lefuService.onDevicesList((devices) => {
|
||||||
|
console.log(TAG, 'onDevicesList 回调, 设备数:', devices.length, devices.map(d => d.name))
|
||||||
|
if (!devices.length) {
|
||||||
|
_rawDevices = []
|
||||||
|
this.setData({ status: 'empty', deviceList: [] })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_rawDevices = devices
|
||||||
|
// 保留已连接设备的状态,避免扫描刷新时把 connected 重置为 false
|
||||||
|
const connectedName = this.data.deviceList.find(d => d.connected)?.name
|
||||||
|
const list: DeviceItem[] = devices.map(d => ({
|
||||||
|
name: d.name,
|
||||||
|
connected: d.name === connectedName,
|
||||||
|
}))
|
||||||
|
this.setData({ status: 'found', deviceList: list })
|
||||||
|
})
|
||||||
lefuService.startScan()
|
lefuService.startScan()
|
||||||
|
console.log(TAG, 'lefuService.startScan() 已调用')
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 连接指定设备 */
|
/** 连接指定设备 */
|
||||||
onConnect(e: WechatMiniprogram.TouchEvent) {
|
onConnect(e: WechatMiniprogram.TouchEvent) {
|
||||||
const index = e.currentTarget.dataset.index as number
|
const index = e.currentTarget.dataset.index as number
|
||||||
const target = this.data.deviceList[index]
|
const raw = _rawDevices[index]
|
||||||
if (!target) return
|
console.log(TAG, 'onConnect, index:', index, 'device:', raw)
|
||||||
|
if (!raw) {
|
||||||
|
console.warn(TAG, 'onConnect: 找不到对应 raw device, index:', index)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 更新 UI 连接状态
|
wx.showLoading({ title: '连接中...', mask: true })
|
||||||
const list = this.data.deviceList.map((item, i) => ({
|
lefuService.connect(raw)
|
||||||
...item,
|
lefuService.onDeviceConnect(() => {
|
||||||
connected: i === index,
|
const list = this.data.deviceList.map((item, i) => ({
|
||||||
}))
|
...item,
|
||||||
this.setData({ deviceList: list })
|
connected: i === index,
|
||||||
|
}))
|
||||||
// 调用 SDK 连接(BleAdv 类型已在 startScan 内自动处理,BleConnect 类型需此处触发)
|
this.setData({ deviceList: list })
|
||||||
lefuService.connect(target._raw)
|
wx.hideLoading()
|
||||||
|
console.log(TAG, '设备连接就绪,跳转配网页')
|
||||||
|
wx.navigateTo({ url: '/pages/connectedWifi/connectedWifi' })
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 断开当前连接 */
|
/** 断开当前连接 */
|
||||||
onDisconnect() {
|
onDisconnect() {
|
||||||
|
console.log(TAG, 'onDisconnect')
|
||||||
const list = this.data.deviceList.map(item => ({ ...item, connected: false }))
|
const list = this.data.deviceList.map(item => ({ ...item, connected: false }))
|
||||||
this.setData({ deviceList: list })
|
this.setData({ deviceList: list })
|
||||||
lefuService.disconnect()
|
lefuService.disconnect()
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<!-- 找到设备:统一循环,内部按 connected 切换 UI -->
|
<!-- 找到设备:统一循环,内部按 connected 切换 UI -->
|
||||||
<block wx:if="{{ status === 'found' }}">
|
<block wx:if="{{ status === 'found' }}">
|
||||||
<view class="device-list">
|
<view class="device-list">
|
||||||
<block wx:for="{{ deviceList }}" wx:key="id">
|
<block wx:for="{{ deviceList }}" wx:key="name">
|
||||||
<view class="device-card">
|
<view class="device-card">
|
||||||
<view class="card-icon"></view>
|
<view class="card-icon"></view>
|
||||||
<view class="card-info">
|
<view class="card-info">
|
||||||
|
|||||||
@@ -167,26 +167,33 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
>view {
|
|
||||||
width: 12rpx;
|
|
||||||
height: 12rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin-right: 14rpx;
|
|
||||||
background-color: #2AC79F;
|
|
||||||
}
|
|
||||||
|
|
||||||
>text {
|
|
||||||
color: #2AC79F;
|
|
||||||
height: 28rpx;
|
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 28rpx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-dot {
|
||||||
|
width: 12rpx;
|
||||||
|
height: 12rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 14rpx;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&--green { background-color: #2AC79F; }
|
||||||
|
&--red { background-color: #F24439; }
|
||||||
|
&--gray { background-color: #999999; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
height: 28rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 28rpx;
|
||||||
|
|
||||||
|
&--green { color: #2AC79F; }
|
||||||
|
&--red { color: #F24439; }
|
||||||
|
&--gray { color: #999999; }
|
||||||
|
}
|
||||||
|
|
||||||
/* idle / searching 两态:居中文案 */
|
/* idle / searching 两态:居中文案 */
|
||||||
.wifiIdle,
|
.wifiIdle,
|
||||||
.wifiSearching {
|
.wifiSearching {
|
||||||
@@ -246,7 +253,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
padding: 0 12rpx;
|
padding-left: 12rpx;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,15 +266,20 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 32rpx;
|
margin-bottom: 32rpx;
|
||||||
|
|
||||||
/* 左侧灰底圆形图标占位 */
|
/* 左侧 wifi 图标容器 */
|
||||||
>view:nth-of-type(1) {
|
>view:nth-of-type(1) {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
overflow: hidden;
|
|
||||||
margin-right: 24rpx;
|
margin-right: 24rpx;
|
||||||
border-radius: 50%;
|
|
||||||
background-color: #F7F7F7;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WiFi 名称 */
|
/* WiFi 名称 */
|
||||||
@@ -284,17 +296,11 @@
|
|||||||
>view:nth-of-type(2) {
|
>view:nth-of-type(2) {
|
||||||
width: 10rpx;
|
width: 10rpx;
|
||||||
height: 18rpx;
|
height: 18rpx;
|
||||||
background-color: #B6B6B6;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 列表项:已连接态 */
|
/* 列表项:已连接态 */
|
||||||
.wifiItem-connected {
|
.wifiItem-connected {
|
||||||
/* 左侧图标不加底色圆,保留图标自身颜色 */
|
|
||||||
>view:nth-of-type(1) {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
>text {
|
>text {
|
||||||
color: #1385FA;
|
color: #1385FA;
|
||||||
@@ -364,6 +370,7 @@
|
|||||||
>view {
|
>view {
|
||||||
width: 566rpx;
|
width: 566rpx;
|
||||||
height: 499rpx;
|
height: 499rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
border-radius: 16rpx;
|
border-radius: 16rpx;
|
||||||
background-color: #F5F8FF;
|
background-color: #F5F8FF;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,21 @@ Page({
|
|||||||
*/
|
*/
|
||||||
status: 'idle' as WifiStatus,
|
status: 'idle' as WifiStatus,
|
||||||
|
|
||||||
/** 顶部固定卡片(从上一页状态中读取,当前先用占位) */
|
/** 顶部固定卡片 */
|
||||||
currentDevice: {
|
currentDevice: {
|
||||||
id: '',
|
id: '',
|
||||||
name: '智能体重秤',
|
name: '智能体重秤',
|
||||||
} as CurrentDevice,
|
} as CurrentDevice,
|
||||||
|
|
||||||
|
/** 蓝牙连接状态常量(从插件获取,供 wxml 做条件判断) */
|
||||||
|
BLUE_STATE: {} as Record<string, string>,
|
||||||
|
|
||||||
|
/** 当前蓝牙连接状态(实时更新) */
|
||||||
|
connectState: '',
|
||||||
|
|
||||||
|
/** 顶部卡片蓝牙状态:connected / failed / connecting */
|
||||||
|
bleStatus: 'connected' as 'connected' | 'failed' | 'connecting',
|
||||||
|
|
||||||
/** WiFi 列表 */
|
/** WiFi 列表 */
|
||||||
wifiList: [] as WifiItem[],
|
wifiList: [] as WifiItem[],
|
||||||
|
|
||||||
@@ -60,21 +69,49 @@ Page({
|
|||||||
type: true,
|
type: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_toBleStatus(state: string): 'connected' | 'failed' | 'connecting' {
|
||||||
|
const bs = lefuService.BLUE_STATE
|
||||||
|
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS) return 'connected'
|
||||||
|
if (state === bs.CONNECTFAILED) return 'failed'
|
||||||
|
return 'connecting'
|
||||||
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
// idle 起步,通过统一入口触发搜索
|
this.setData({
|
||||||
|
bleStatus: this._toBleStatus(lefuService.connectState),
|
||||||
|
currentDevice: { id: '', name: lefuService.deviceInfo?.modelNumber ?? '智能体重秤' },
|
||||||
|
})
|
||||||
this.onStartSearch()
|
this.onStartSearch()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
lefuService.onConnectState((state) => {
|
||||||
|
const bs = lefuService.BLUE_STATE
|
||||||
|
// 只处理明确的连接/断开状态,忽略蓝牙初始化过程中的中间状态
|
||||||
|
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS || state === bs.CONNECTFAILED) {
|
||||||
|
this.setData({ bleStatus: this._toBleStatus(state) })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
lefuService.onDeviceInfo((info) => {
|
||||||
|
this.setData({ currentDevice: { id: '', name: info.modelNumber } })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
// 页面卸载时不调用 stopScan,蓝牙连接由 home 页维持
|
wx.hideLoading()
|
||||||
|
if (this.data.status === 'configuring') {
|
||||||
|
lefuService.disconnect()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** 从设备获取 WiFi 列表 */
|
/** 从设备获取 WiFi 列表 */
|
||||||
onStartSearch() {
|
onStartSearch() {
|
||||||
this.setData({ status: 'searching', wifiList: [] })
|
this.setData({ status: 'searching', wifiList: [] })
|
||||||
|
wx.showLoading({ title: '正在获取 WiFi 列表...', mask: true })
|
||||||
|
|
||||||
lefuService.getWifiList()
|
lefuService.getWifiList()
|
||||||
.then((items: LeFuWifiItem[]) => {
|
.then((items: LeFuWifiItem[]) => {
|
||||||
|
wx.hideLoading()
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
this.setData({ status: 'empty' })
|
this.setData({ status: 'empty' })
|
||||||
return
|
return
|
||||||
@@ -86,6 +123,7 @@ Page({
|
|||||||
this.setData({ status: 'list', wifiList: list })
|
this.setData({ status: 'list', wifiList: list })
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
wx.hideLoading()
|
||||||
this.setData({ status: 'empty' })
|
this.setData({ status: 'empty' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -139,7 +177,6 @@ Page({
|
|||||||
lefuService.configWifi(selectedWifi.ssid, selectWifiPWD, this._wifiVersion)
|
lefuService.configWifi(selectedWifi.ssid, selectWifiPWD, this._wifiVersion)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
wx.hideLoading()
|
wx.hideLoading()
|
||||||
// 配网成功:标记该 WiFi,回列表态
|
|
||||||
const next = this.data.wifiList.map(item => ({
|
const next = this.data.wifiList.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
connected: item.ssid === selectedWifi.ssid,
|
connected: item.ssid === selectedWifi.ssid,
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
<view class="setWifi-form">
|
<view class="setWifi-form">
|
||||||
<view>
|
<view>
|
||||||
<view>
|
<view>
|
||||||
<image src="/images/configureDevice/wifiPwd.png"/>
|
<image src="/images/connectedWifi/wifiPwd.png"/>
|
||||||
</view>
|
</view>
|
||||||
<view>{{selectedWifi.name}}</view>
|
<view>{{selectedWifi.ssid}}</view>
|
||||||
</view>
|
</view>
|
||||||
<view>
|
<view>
|
||||||
<view>密码</view>
|
<view>密码</view>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<view bind:tap="inputTypeChange">
|
<view bind:tap="inputTypeChange">
|
||||||
<image src="/images/configureDevice/{{type ? 'open' : 'close'}}.png"/>
|
<image src="/images/connectedWifi/{{type ? 'open' : 'close'}}.png"/>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -48,8 +48,18 @@
|
|||||||
<view>
|
<view>
|
||||||
<view>{{currentDevice.name}}</view>
|
<view>{{currentDevice.name}}</view>
|
||||||
<view>
|
<view>
|
||||||
<view></view>
|
<block wx:if="{{bleStatus === 'connected'}}">
|
||||||
<text>已连接</text>
|
<view class="status-dot status-dot--green"></view>
|
||||||
|
<text class="status-text status-text--green">已连接</text>
|
||||||
|
</block>
|
||||||
|
<block wx:elif="{{bleStatus === 'failed'}}">
|
||||||
|
<view class="status-dot status-dot--red"></view>
|
||||||
|
<text class="status-text status-text--red">连接断开</text>
|
||||||
|
</block>
|
||||||
|
<block wx:else>
|
||||||
|
<view class="status-dot status-dot--gray"></view>
|
||||||
|
<text class="status-text status-text--gray">连接中...</text>
|
||||||
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -74,11 +84,13 @@
|
|||||||
<view>网络列表(请选择一个网络进行连接)</view>
|
<view>网络列表(请选择一个网络进行连接)</view>
|
||||||
</view>
|
</view>
|
||||||
<scroll-view class="wifiList" scroll-y>
|
<scroll-view class="wifiList" scroll-y>
|
||||||
<block wx:for="{{wifiList}}" wx:key="id">
|
<block wx:for="{{wifiList}}" wx:key="ssid">
|
||||||
<block wx:if="{{item.connected}}">
|
<block wx:if="{{item.connected}}">
|
||||||
<view class="wifiItem wifiItem-connected" data-id="{{item.id}}" bind:tap="onTapWifi">
|
<view class="wifiItem wifiItem-connected" data-ssid="{{item.ssid}}" bind:tap="onTapWifi">
|
||||||
<view></view>
|
<view>
|
||||||
<text>{{item.name}}</text>
|
<image src="/images/connectedWifi/wifi.png" mode="aspectFit"/>
|
||||||
|
</view>
|
||||||
|
<text>{{item.ssid}}</text>
|
||||||
<view>
|
<view>
|
||||||
<text>已连接</text>
|
<text>已连接</text>
|
||||||
<view></view>
|
<view></view>
|
||||||
@@ -86,10 +98,12 @@
|
|||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
<block wx:else>
|
<block wx:else>
|
||||||
<view class="wifiItem" data-id="{{item.id}}" bind:tap="onTapWifi">
|
<view class="wifiItem" data-ssid="{{item.ssid}}" bind:tap="onTapWifi">
|
||||||
<view></view>
|
<view>
|
||||||
<text>{{item.name}}</text>
|
<image src="/images/connectedWifi/wifi.png" mode="aspectFit"/>
|
||||||
<view></view>
|
</view>
|
||||||
|
<text>{{item.ssid}}</text>
|
||||||
|
<view class="arrow"></view>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</block>
|
</block>
|
||||||
@@ -108,7 +122,9 @@
|
|||||||
<view>网络列表(请选择一个网络进行连接)</view>
|
<view>网络列表(请选择一个网络进行连接)</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="wifiEmpty">
|
<view class="wifiEmpty">
|
||||||
<view></view>
|
<view>
|
||||||
|
<image src="/images/connectedWifi/noData.png" mode="aspectFit"/>
|
||||||
|
</view>
|
||||||
<text>未查找到可用wifi,请重试</text>
|
<text>未查找到可用wifi,请重试</text>
|
||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
|
|||||||
Reference in New Issue
Block a user