/** * 睡眠监控服务 * * 负责监听睡眠数据更新事件,分析睡眠质量并提供反馈 */ import { logger } from '@/utils/logger'; import { NativeEventEmitter, NativeModules } from 'react-native'; import { analyzeSleepAndSendNotification } from './sleepNotificationService'; const { HealthKitManager } = NativeModules; // 睡眠阶段类型 export type SleepStage = 'inBed' | 'asleep' | 'awake' | 'core' | 'deep' | 'rem' | 'unknown'; // 睡眠样本数据 export interface SleepSample { id: string; startDate: string; endDate: string; value: number; categoryType: SleepStage; duration: number; source: { name: string; bundleIdentifier: string; }; metadata: Record; } // 睡眠分析结果 export interface SleepAnalysisData { sessionStart: string; sessionEnd: string; totalSleepDuration: number; // 秒 totalSleepHours: number; // 小时 deepSleepDuration: number; // 秒 deepSleepHours: number; // 小时 deepSleepPercentage: number; // 百分比 remSleepDuration: number; // 秒 remSleepHours: number; // 小时 remSleepPercentage: number; // 百分比 coreSleepDuration: number; // 秒 coreSleepHours: number; // 小时 coreSleepPercentage: number; // 百分比 awakeDuration: number; // 秒 awakeMinutes: number; // 分钟 sleepEfficiency: number; // 百分比 sleepScore: number; // 0-100分 quality: 'excellent' | 'good' | 'fair' | 'poor' | 'very_poor'; } // 睡眠事件数据 export interface SleepEventData { timestamp: number; type: 'sleep_data_updated'; } /** * 睡眠监控服务类 */ class SleepMonitorService { private eventEmitter: NativeEventEmitter | null = null; private eventSubscription: any = null; private isInitialized = false; private lastProcessedTime = 0; private debounceDelay = 3000; // 3秒防抖延迟 /** * 初始化睡眠监控服务 */ async initialize(): Promise { if (this.isInitialized) { console.log('[SleepMonitor] Already initialized'); return true; } try { // 创建事件发射器 this.eventEmitter = new NativeEventEmitter(HealthKitManager); // 订阅睡眠更新事件 this.eventSubscription = this.eventEmitter.addListener( 'sleepUpdate', this.handleSleepUpdate.bind(this) ); // 启动睡眠观察者 await HealthKitManager.startSleepObserver(); this.isInitialized = true; console.log('[SleepMonitor] Initialized successfully'); return true; } catch (error) { console.error('[SleepMonitor] Initialization failed:', error); return false; } } /** * 停止睡眠监控服务 */ async stop(): Promise { if (!this.isInitialized) { return; } try { // 取消事件订阅 if (this.eventSubscription) { this.eventSubscription.remove(); this.eventSubscription = null; } // 停止睡眠观察者 await HealthKitManager.stopSleepObserver(); this.isInitialized = false; console.log('[SleepMonitor] Stopped successfully'); } catch (error) { console.error('[SleepMonitor] Stop failed:', error); } } /** * 处理睡眠更新事件 */ private async handleSleepUpdate(event: SleepEventData): Promise { console.log('[SleepMonitor] Sleep data updated:', event); // 防抖处理:避免短时间内重复处理 const now = Date.now(); if (now - this.lastProcessedTime < this.debounceDelay) { console.log('[SleepMonitor] Debouncing, skipping this update'); return; } this.lastProcessedTime = now; try { // 分析最近的睡眠数据 const analysis = await this.analyzeSleepData(); if (analysis) { logger.info('[SleepMonitor] Sleep analysis completed:', { score: analysis.sleepScore, quality: analysis.quality, duration: `${analysis.totalSleepHours.toFixed(1)}h`, }); // 发送睡眠分析通知 await this.notifySleepAnalysis(analysis); } } catch (error) { console.error('[SleepMonitor] Failed to analyze sleep data:', error); } } /** * 分析睡眠数据 */ async analyzeSleepData(): Promise { try { // 获取最近24小时的睡眠数据 const endDate = new Date(); const startDate = new Date(endDate.getTime() - 24 * 60 * 60 * 1000); const result = await HealthKitManager.getSleepData({ startDate: startDate.toISOString(), endDate: endDate.toISOString(), }); if (!result.data || result.data.length === 0) { console.log('[SleepMonitor] No sleep data found'); return null; } const sleepSamples: SleepSample[] = result.data; // 找到最近一次完整的睡眠会话 const session = this.findLatestCompleteSleepSession(sleepSamples); if (!session) { console.log('[SleepMonitor] No complete sleep session found'); return null; } // 分析睡眠样本 const analysis = this.analyzeSleepSamples(session.samples, session.startDate, session.endDate); return analysis; } catch (error) { console.error('[SleepMonitor] Failed to analyze sleep data:', error); return null; } } /** * 找到最近一次完整的睡眠会话 */ private findLatestCompleteSleepSession(samples: SleepSample[]): { samples: SleepSample[]; startDate: Date; endDate: Date; } | null { if (samples.length === 0) return null; // 按开始时间排序 const sortedSamples = [...samples].sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime() ); // 从最新的样本开始往前查找 const reversedSamples = [...sortedSamples].reverse(); const sessionSamples: SleepSample[] = []; let sessionEnd: Date | null = null; for (const sample of reversedSamples) { // 如果是第一个样本,记录结束时间 if (!sessionEnd) { sessionEnd = new Date(sample.endDate); } // 收集连续的睡眠样本(时间间隔不超过30分钟) if (sessionSamples.length > 0) { const lastSample = sessionSamples[sessionSamples.length - 1]; const gap = new Date(lastSample.startDate).getTime() - new Date(sample.endDate).getTime(); if (gap > 30 * 60 * 1000) { // 间隔超过30分钟 break; } } sessionSamples.push(sample); } // 反转回正常顺序 sessionSamples.reverse(); if (sessionSamples.length === 0) return null; const sessionStart = new Date(sessionSamples[0].startDate); const sessionEndDate = sessionEnd || new Date(sessionSamples[sessionSamples.length - 1].endDate); // 确保会话至少有2小时的数据 const duration = sessionEndDate.getTime() - sessionStart.getTime(); if (duration < 2 * 60 * 60 * 1000) { // 至少2小时 return null; } return { samples: sessionSamples, startDate: sessionStart, endDate: sessionEndDate, }; } /** * 分析睡眠样本数据 */ private analyzeSleepSamples( samples: SleepSample[], sessionStart: Date, sessionEnd: Date ): SleepAnalysisData { // 计算各阶段睡眠时长 let totalSleepDuration = 0; let deepSleepDuration = 0; let remSleepDuration = 0; let coreSleepDuration = 0; let awakeDuration = 0; for (const sample of samples) { const duration = sample.duration; switch (sample.categoryType) { case 'deep': deepSleepDuration += duration; totalSleepDuration += duration; break; case 'rem': remSleepDuration += duration; totalSleepDuration += duration; break; case 'core': coreSleepDuration += duration; totalSleepDuration += duration; break; case 'asleep': totalSleepDuration += duration; break; case 'awake': awakeDuration += duration; break; } } // 计算睡眠效率 const totalInBedDuration = (sessionEnd.getTime() - sessionStart.getTime()) / 1000; const sleepEfficiency = totalInBedDuration > 0 ? (totalSleepDuration / totalInBedDuration) * 100 : 0; // 计算各阶段睡眠占比 const deepSleepPercentage = totalSleepDuration > 0 ? (deepSleepDuration / totalSleepDuration) * 100 : 0; const remSleepPercentage = totalSleepDuration > 0 ? (remSleepDuration / totalSleepDuration) * 100 : 0; const coreSleepPercentage = totalSleepDuration > 0 ? (coreSleepDuration / totalSleepDuration) * 100 : 0; // 计算睡眠评分 const sleepScore = this.calculateSleepScore( totalSleepDuration, deepSleepDuration, remSleepDuration, sleepEfficiency, awakeDuration ); return { sessionStart: sessionStart.toISOString(), sessionEnd: sessionEnd.toISOString(), totalSleepDuration, totalSleepHours: totalSleepDuration / 3600, deepSleepDuration, deepSleepHours: deepSleepDuration / 3600, deepSleepPercentage, remSleepDuration, remSleepHours: remSleepDuration / 3600, remSleepPercentage, coreSleepDuration, coreSleepHours: coreSleepDuration / 3600, coreSleepPercentage, awakeDuration, awakeMinutes: awakeDuration / 60, sleepEfficiency, sleepScore, quality: this.getSleepQualityLabel(sleepScore), }; } /** * 计算睡眠评分(0-100分) */ private calculateSleepScore( totalSleepDuration: number, deepSleepDuration: number, remSleepDuration: number, sleepEfficiency: number, awakeDuration: number ): number { let score = 0; // 1. 总睡眠时长评分(40分) const sleepHours = totalSleepDuration / 3600; if (sleepHours >= 7 && sleepHours <= 9) { score += 40; // 理想睡眠时长 } else if (sleepHours >= 6 && sleepHours < 7) { score += 35; // 稍短 } else if (sleepHours >= 9 && sleepHours < 10) { score += 35; // 稍长 } else if (sleepHours >= 5 && sleepHours < 6) { score += 25; // 较短 } else if (sleepHours >= 10 && sleepHours < 11) { score += 30; // 较长 } else if (sleepHours >= 4 && sleepHours < 5) { score += 15; // 很短 } else if (sleepHours >= 11) { score += 20; // 过长 } else { score += 10; // 极短 } // 2. 深度睡眠评分(25分) const deepSleepPercentage = totalSleepDuration > 0 ? (deepSleepDuration / totalSleepDuration) * 100 : 0; if (deepSleepPercentage >= 13 && deepSleepPercentage <= 23) { score += 25; // 理想的深度睡眠占比(13-23%) } else if (deepSleepPercentage >= 10 && deepSleepPercentage < 13) { score += 20; } else if (deepSleepPercentage >= 23 && deepSleepPercentage < 30) { score += 20; } else if (deepSleepPercentage >= 7 && deepSleepPercentage < 10) { score += 15; } else if (deepSleepPercentage >= 30) { score += 15; } else { score += 10; } // 3. REM睡眠评分(20分) const remSleepPercentage = totalSleepDuration > 0 ? (remSleepDuration / totalSleepDuration) * 100 : 0; if (remSleepPercentage >= 20 && remSleepPercentage <= 25) { score += 20; // 理想的REM睡眠占比(20-25%) } else if (remSleepPercentage >= 15 && remSleepPercentage < 20) { score += 18; } else if (remSleepPercentage >= 25 && remSleepPercentage < 30) { score += 18; } else if (remSleepPercentage >= 10 && remSleepPercentage < 15) { score += 12; } else if (remSleepPercentage >= 30) { score += 15; } else { score += 8; } // 4. 睡眠效率评分(15分) if (sleepEfficiency >= 85) { score += 15; // 优秀的睡眠效率 } else if (sleepEfficiency >= 75) { score += 12; } else if (sleepEfficiency >= 65) { score += 8; } else { score += 5; } return Math.min(Math.round(score), 100); } /** * 根据评分获取睡眠质量标签 */ private getSleepQualityLabel(score: number): 'excellent' | 'good' | 'fair' | 'poor' | 'very_poor' { if (score >= 90) return 'excellent'; if (score >= 75) return 'good'; if (score >= 60) return 'fair'; if (score >= 40) return 'poor'; return 'very_poor'; } /** * 通知睡眠分析结果 */ private async notifySleepAnalysis(analysis: SleepAnalysisData): Promise { try { // 发送睡眠分析通知 await analyzeSleepAndSendNotification(analysis); logger.info('[SleepMonitor] Sleep analysis notification sent:', { score: analysis.sleepScore, quality: analysis.quality, duration: `${analysis.totalSleepHours.toFixed(1)}h`, efficiency: `${analysis.sleepEfficiency.toFixed(0)}%`, }); // 可以在这里更新 Redux store // store.dispatch(updateSleepAnalysis(analysis)); } catch (error) { logger.error('[SleepMonitor] Failed to send sleep notification:', error); } } /** * 获取睡眠质量描述 */ getQualityDescription(quality: string): string { const descriptions = { excellent: '优秀 - 您的睡眠质量非常好!', good: '良好 - 您的睡眠质量不错', fair: '一般 - 您的睡眠质量还可以改善', poor: '较差 - 建议改善睡眠习惯', very_poor: '很差 - 强烈建议关注睡眠健康', }; return descriptions[quality as keyof typeof descriptions] || '未知'; } /** * 获取睡眠建议 */ getSleepRecommendations(analysis: SleepAnalysisData): string[] { const recommendations: string[] = []; // 基于总睡眠时长的建议 if (analysis.totalSleepHours < 7) { recommendations.push('建议增加睡眠时间,成年人每晚需要7-9小时睡眠'); } else if (analysis.totalSleepHours > 9) { recommendations.push('睡眠时间偏长,可能影响睡眠质量'); } // 基于深度睡眠的建议 if (analysis.deepSleepPercentage < 13) { recommendations.push('深度睡眠不足,建议睡前避免使用电子设备'); } // 基于REM睡眠的建议 if (analysis.remSleepPercentage < 20) { recommendations.push('REM睡眠不足,建议保持规律的作息时间'); } // 基于睡眠效率的建议 if (analysis.sleepEfficiency < 85) { recommendations.push('睡眠效率较低,建议改善睡眠环境'); } // 基于清醒时间的建议 if (analysis.awakeMinutes > 30) { recommendations.push('夜间醒来时间较长,建议睡前放松身心'); } return recommendations; } } // 导出单例 export const sleepMonitorService = new SleepMonitorService();