import { useState, useCallback } from 'react'; import { View, Text } from '@tarojs/components'; import { useDidShow } from '@tarojs/taro'; import { BLEManager } from '@/services/ble/BLEManager'; import { XiaomiBandAdapter } from '@/services/ble/adapters/XiaomiBandAdapter'; import { uploadReadings } from '@/services/device-sync'; import { useAuthStore } from '@/stores/auth'; import type { BLEDevice, NormalizedReading } from '@/services/ble/types'; import './index.scss'; const bleManager = new BLEManager({ scanTimeout: 10000, retryCount: 3 }); bleManager.registerAdapter(XiaomiBandAdapter); type PageState = 'idle' | 'scanning' | 'connecting' | 'connected' | 'syncing' | 'done' | 'error'; export default function DeviceSync() { const { currentPatient } = useAuthStore(); const [pageState, setPageState] = useState('idle'); const [devices, setDevices] = useState([]); const [selectedDevice, setSelectedDevice] = useState(null); const [liveReadings, setLiveReadings] = useState([]); const [syncCount, setSyncCount] = useState(0); const [errorMsg, setErrorMsg] = useState(''); useDidShow(() => { bleManager.setOnConnectionChange(() => {}); bleManager.setOnReadings((readings) => { setLiveReadings((prev) => [...prev, ...readings]); }); return () => { bleManager.destroy(); }; }); const handleScan = useCallback(async () => { setPageState('scanning'); setDevices([]); setErrorMsg(''); try { const found = await bleManager.scanDevices(); setDevices(found); if (found.length === 0) { setErrorMsg('未发现支持的设备,请确认手环已开启蓝牙并靠近手机'); } setPageState('idle'); } catch (e: any) { setErrorMsg(e.message || '扫描失败'); setPageState('error'); } }, []); const handleConnect = useCallback(async (device: BLEDevice) => { setSelectedDevice(device); setPageState('connecting'); setErrorMsg(''); try { await bleManager.connect(device); setPageState('connected'); } catch (e: any) { setErrorMsg(e.message || '连接失败'); setPageState('error'); } }, []); const handleSync = useCallback(async () => { if (!currentPatient || !selectedDevice) return; setPageState('syncing'); setErrorMsg(''); try { const result = await bleManager.syncToServer(async (readings) => { return uploadReadings( currentPatient.id, selectedDevice.deviceId, selectedDevice.name, readings, ); }); if (result.success) { setSyncCount(result.uploadedCount); setPageState('done'); } else { setErrorMsg(result.error || '同步失败'); setPageState('error'); } } catch (e: any) { setErrorMsg(e.message || '同步失败'); setPageState('error'); } }, [currentPatient, selectedDevice]); const handleDisconnect = useCallback(async () => { await bleManager.disconnect(); setPageState('idle'); setSelectedDevice(null); setLiveReadings([]); setSyncCount(0); setErrorMsg(''); }, []); const renderIdle = () => ( 设备同步 连接智能手环,自动采集健康数据 扫描设备 {devices.length > 0 && ( 发现的设备 {devices.map((d) => ( handleConnect(d)} > {d.name} {d.adapter?.name} 信号 {d.RSSI > -60 ? '强' : d.RSSI > -80 ? '中' : '弱'} ))} )} ); const renderConnected = () => ( 已连接: {selectedDevice?.name} {liveReadings.length > 0 && ( 实时数据 {liveReadings.slice(-5).reverse().map((r, i) => ( {r.device_type === 'heart_rate' ? '心率' : r.device_type} {r.device_type === 'heart_rate' ? `${r.values.heart_rate} bpm` : JSON.stringify(r.values)} ))} 已采集 {liveReadings.length} 条数据 )} 上传数据 断开连接 ); const renderDone = () => ( 同步完成 成功上传 {syncCount} 条数据 完成 ); return ( 设备同步 {errorMsg && ( {errorMsg} )} {(pageState === 'scanning' || pageState === 'connecting' || pageState === 'syncing') && ( {pageState === 'scanning' && '正在扫描设备...'} {pageState === 'connecting' && '正在连接设备...'} {pageState === 'syncing' && '正在上传数据...'} )} {(pageState === 'idle' || pageState === 'error') && renderIdle()} {pageState === 'connected' && renderConnected()} {pageState === 'done' && renderDone()} ); }