import { useState, useEffect, useCallback, useRef } from 'react'; import { healthPermissionManager, HealthPermissionStatus, ensureHealthPermissions, checkHealthPermissionStatus, fetchTodayHealthData, fetchHealthDataForDate, TodayHealthData } from '@/utils/health'; export interface UseHealthPermissionsReturn { // 权限状态 permissionStatus: HealthPermissionStatus; isLoading: boolean; // 权限操作 requestPermissions: () => Promise; checkPermissions: (forceCheck?: boolean) => Promise; // 数据刷新 refreshHealthData: () => Promise; refreshHealthDataForDate: (date: Date) => Promise; // 健康数据 healthData: TodayHealthData | null; // 状态检查 hasPermission: boolean; needsPermission: boolean; } /** * HealthKit权限状态管理Hook * * 功能: * 1. 监听权限状态变化 * 2. 自动刷新数据当权限状态改变时 * 3. 提供权限请求和数据刷新方法 * 4. 缓存健康数据状态 */ export function useHealthPermissions(): UseHealthPermissionsReturn { const [permissionStatus, setPermissionStatus] = useState( healthPermissionManager.getPermissionStatus() ); const [isLoading, setIsLoading] = useState(false); const [healthData, setHealthData] = useState(null); // 使用ref避免闭包问题 const isLoadingRef = useRef(false); const lastRefreshTime = useRef(0); const refreshThrottle = 2000; // 2秒内避免重复刷新 // 刷新健康数据 const refreshHealthData = useCallback(async () => { const now = Date.now(); // 防抖:避免短时间内重复刷新 if (isLoadingRef.current || (now - lastRefreshTime.current) < refreshThrottle) { console.log('健康数据刷新被节流,跳过本次刷新'); return; } if (permissionStatus !== HealthPermissionStatus.Authorized) { console.log('没有HealthKit权限,跳过数据刷新'); return; } isLoadingRef.current = true; setIsLoading(true); lastRefreshTime.current = now; try { console.log('开始刷新今日健康数据...'); const data = await fetchTodayHealthData(); setHealthData(data); console.log('健康数据刷新成功:', data); } catch (error) { console.error('刷新健康数据失败:', error); } finally { isLoadingRef.current = false; setIsLoading(false); } }, [permissionStatus]); // 刷新指定日期的健康数据 const refreshHealthDataForDate = useCallback(async (date: Date) => { if (permissionStatus !== HealthPermissionStatus.Authorized) { console.log('没有HealthKit权限,跳过数据刷新'); return; } setIsLoading(true); try { console.log('开始刷新指定日期健康数据...', date); const data = await fetchHealthDataForDate(date); // 只有是今天的数据才更新state const today = new Date(); if (date.toDateString() === today.toDateString()) { setHealthData(data); } console.log('指定日期健康数据刷新成功:', data); } catch (error) { console.error('刷新指定日期健康数据失败:', error); } finally { setIsLoading(false); } }, [permissionStatus]); // 请求权限 const requestPermissions = useCallback(async (): Promise => { setIsLoading(true); try { console.log('开始请求HealthKit权限...'); const granted = await ensureHealthPermissions(); if (granted) { console.log('权限请求成功,准备刷新数据'); // 权限获取成功后,稍微延迟刷新数据 setTimeout(() => { refreshHealthData(); }, 500); } return granted; } catch (error) { console.error('请求HealthKit权限失败:', error); return false; } finally { setIsLoading(false); } }, [refreshHealthData]); // 检查权限状态 const checkPermissions = useCallback(async (forceCheck: boolean = false): Promise => { try { const status = await checkHealthPermissionStatus(forceCheck); return status; } catch (error) { console.error('检查权限状态失败:', error); return HealthPermissionStatus.Unknown; } }, []); // 监听权限状态变化 useEffect(() => { console.log('设置HealthKit权限状态监听器...'); // 权限状态变化监听 const handlePermissionStatusChanged = (newStatus: HealthPermissionStatus, oldStatus: HealthPermissionStatus) => { console.log(`权限状态变化: ${oldStatus} -> ${newStatus}`); setPermissionStatus(newStatus); // 如果从无权限变为有权限,自动刷新数据 if (oldStatus !== HealthPermissionStatus.Authorized && newStatus === HealthPermissionStatus.Authorized) { console.log('权限状态变为已授权,准备刷新健康数据...'); setTimeout(() => { refreshHealthData(); }, 500); } }; // 权限获取成功监听 const handlePermissionGranted = () => { console.log('权限获取成功事件触发,准备刷新数据...'); setTimeout(() => { refreshHealthData(); }, 500); }; healthPermissionManager.on('permissionStatusChanged', handlePermissionStatusChanged); healthPermissionManager.on('permissionGranted', handlePermissionGranted); // 组件挂载时检查一次权限状态 checkPermissions(true); // 如果已经有权限,立即刷新数据 if (permissionStatus === HealthPermissionStatus.Authorized) { refreshHealthData(); } return () => { console.log('清理HealthKit权限状态监听器...'); healthPermissionManager.off('permissionStatusChanged', handlePermissionStatusChanged); healthPermissionManager.off('permissionGranted', handlePermissionGranted); }; }, [checkPermissions, refreshHealthData, permissionStatus]); // 计算派生状态 const hasPermission = permissionStatus === HealthPermissionStatus.Authorized; const needsPermission = permissionStatus === HealthPermissionStatus.NotDetermined || permissionStatus === HealthPermissionStatus.Unknown; return { permissionStatus, isLoading, requestPermissions, checkPermissions, refreshHealthData, refreshHealthDataForDate, healthData, hasPermission, needsPermission }; } /** * 简化版Hook,只关注权限状态 */ export function useHealthPermissionStatus() { const [permissionStatus, setPermissionStatus] = useState( healthPermissionManager.getPermissionStatus() ); useEffect(() => { const handlePermissionStatusChanged = (newStatus: HealthPermissionStatus) => { setPermissionStatus(newStatus); }; healthPermissionManager.on('permissionStatusChanged', handlePermissionStatusChanged); // 检查一次当前状态 checkHealthPermissionStatus(true); return () => { healthPermissionManager.off('permissionStatusChanged', handlePermissionStatusChanged); }; }, []); return { permissionStatus, hasPermission: permissionStatus === HealthPermissionStatus.Authorized, needsPermission: permissionStatus === HealthPermissionStatus.NotDetermined || permissionStatus === HealthPermissionStatus.Unknown }; }