123 lines
3.0 KiB
TypeScript
123 lines
3.0 KiB
TypeScript
import { onMounted, onUnmounted, ref } from 'vue'
|
|
import {
|
|
ensureBluetoothReady,
|
|
getBluetoothErrorMessage,
|
|
getDiscoveredBluetoothDevices,
|
|
isBluetoothApiSupported,
|
|
startBluetoothDiscovery,
|
|
stopBluetoothDiscovery,
|
|
subscribeBluetoothDevicesFound,
|
|
} from '@/utils/bluetooth'
|
|
import { buildBindDeviceQuery } from '../add-device.types'
|
|
import type { ScannedDeviceItem } from './scan.types'
|
|
import { mapBluetoothDevice } from './scan.utils'
|
|
|
|
const SCAN_SECONDS = 20
|
|
|
|
export function useScanDevice() {
|
|
const currentStep = 2
|
|
const devices = ref<ScannedDeviceItem[]>([])
|
|
const selectedId = ref('')
|
|
const secondsLeft = ref(SCAN_SECONDS)
|
|
const scanning = ref(true)
|
|
const scanError = ref('')
|
|
|
|
let unsubscribeFound: (() => void) | undefined
|
|
|
|
function upsertDevice(item: ScannedDeviceItem) {
|
|
const idx = devices.value.findIndex((d) => d.id === item.id)
|
|
if (idx >= 0) {
|
|
devices.value[idx] = item
|
|
return
|
|
}
|
|
devices.value.push(item)
|
|
if (!selectedId.value) selectedId.value = item.id
|
|
}
|
|
|
|
function ingestBluetoothDevices(found: UniApp.BluetoothDeviceInfo[]) {
|
|
for (const device of found) {
|
|
upsertDevice(mapBluetoothDevice(device))
|
|
}
|
|
}
|
|
|
|
async function beginDiscovery() {
|
|
if (!isBluetoothApiSupported()) {
|
|
scanning.value = false
|
|
scanError.value = '当前环境不支持蓝牙扫描,请使用 App 或微信小程序'
|
|
return
|
|
}
|
|
|
|
try {
|
|
await ensureBluetoothReady()
|
|
|
|
unsubscribeFound = subscribeBluetoothDevicesFound((found) => {
|
|
ingestBluetoothDevices(found)
|
|
})
|
|
|
|
const existing = await getDiscoveredBluetoothDevices()
|
|
ingestBluetoothDevices(existing)
|
|
|
|
await startBluetoothDiscovery()
|
|
} catch (err) {
|
|
scanning.value = false
|
|
scanError.value = getBluetoothErrorMessage(err)
|
|
uni.showToast({ title: scanError.value, icon: 'none' })
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
void beginDiscovery()
|
|
})
|
|
|
|
const timer = setInterval(() => {
|
|
if (secondsLeft.value <= 0) {
|
|
scanning.value = false
|
|
return
|
|
}
|
|
secondsLeft.value -= 1
|
|
if (secondsLeft.value === 0) {
|
|
scanning.value = false
|
|
void stopBluetoothDiscovery().catch(() => {})
|
|
}
|
|
}, 1000)
|
|
|
|
onUnmounted(() => {
|
|
clearInterval(timer)
|
|
unsubscribeFound?.()
|
|
void stopBluetoothDiscovery().catch(() => {})
|
|
})
|
|
|
|
function onSelectDevice(id: string) {
|
|
selectedId.value = id
|
|
}
|
|
|
|
function onDeviceAction(device: ScannedDeviceItem) {
|
|
selectedId.value = device.id
|
|
if (!device.canAdd) {
|
|
uni.showToast({ title: '暂无法添加该设备', icon: 'none' })
|
|
return
|
|
}
|
|
const q = buildBindDeviceQuery({
|
|
deviceNo: device.deviceNo,
|
|
name: device.name,
|
|
serialMasked: device.serialMasked,
|
|
productId: device.productId,
|
|
model: device.model,
|
|
imei: device.imei,
|
|
mac: device.mac,
|
|
})
|
|
uni.navigateTo({ url: `/pages/add-device/pair/index?${q}` })
|
|
}
|
|
|
|
return {
|
|
currentStep,
|
|
devices,
|
|
selectedId,
|
|
secondsLeft,
|
|
scanning,
|
|
scanError,
|
|
onSelectDevice,
|
|
onDeviceAction,
|
|
}
|
|
}
|