Files
digital-pilates/services/sleepNotificationService.ts
richarjiang 7bd0b5fc52 # 方案总结
基于提供的 Git diff,我将生成以下 conventional commit message:

## 变更分析:

1. **核心功能**:
   - 新增睡眠监控服务(`services/sleepMonitor.ts`)
   - 新增睡眠通知服务(`services/sleepNotificationService.ts`)
   - iOS 原生端增加睡眠观察者方法

2. **应用启动优化**:
   - 重构 `app/_layout.tsx` 中的初始化流程,按优先级分阶段加载服务

3. **药品功能改进**:
   - 优化语音识别交互(实时预览、可取消)
   - Widget 增加 URL scheme 支持

4. **路由配置**:
   - 新增药品管理路由常量

## 提交信息类型:
- **主类型**:`feat` (新增睡眠监控功能)
- **作用域**:`health` (健康相关功能)

---

请确认方案后,我将生成最终的 commit message。

---

**最终 Commit Message:**

feat(health): 添加睡眠监控和通知服务,优化应用启动流程

- 新增睡眠监控服务,支持实时监听 HealthKit 睡眠数据更新
- 实现睡眠质量分析算法,计算睡眠评分和各阶段占比
- 新增睡眠通知服务,分析完成后自动推送质量评估和建议
- iOS 原生端实现睡眠数据观察者,支持后台数据传递
- 重构应用启动初始化流程,按优先级分阶段加载服务(关键/次要/后台/空闲)
- 优化药品录入页面语音识别交互,支持实时预览和取消操作
- 药品 Widget 增加 deeplink 支持,点击跳转到应用
- 新增药品管理路由常量配置
2025-11-14 10:52:26 +08:00

191 lines
4.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 睡眠通知服务
*
* 负责在睡眠分析完成后发送通知,提供睡眠质量评估和建议
*/
import { logger } from '@/utils/logger';
import * as Notifications from 'expo-notifications';
import { SleepAnalysisData } from './sleepMonitor';
/**
* 分析睡眠数据并发送通知
*/
export async function analyzeSleepAndSendNotification(
analysis: SleepAnalysisData
): Promise<void> {
try {
logger.info('开始分析睡眠并发送通知:', {
score: analysis.sleepScore,
quality: analysis.quality,
duration: analysis.totalSleepHours,
});
// 构建通知内容
const notification = buildSleepNotification(analysis);
// 发送通知
await Notifications.scheduleNotificationAsync({
content: notification,
trigger: null, // 立即发送
});
logger.info('睡眠分析通知已发送');
} catch (error) {
logger.error('发送睡眠分析通知失败:', error);
throw error;
}
}
/**
* 构建睡眠通知内容
*/
function buildSleepNotification(analysis: SleepAnalysisData): Notifications.NotificationContentInput {
const { sleepScore, quality, totalSleepHours, sleepEfficiency } = analysis;
// 根据质量等级选择emoji和标题
const qualityConfig = getQualityConfig(quality);
// 构建通知标题
const title = `${qualityConfig.emoji} ${qualityConfig.title}`;
// 构建通知正文
const sleepDuration = formatSleepDuration(totalSleepHours);
const efficiencyText = `睡眠效率 ${sleepEfficiency.toFixed(0)}%`;
const body = `您昨晚睡了 ${sleepDuration}${efficiencyText}。评分:${sleepScore}`;
// 获取建议
const suggestion = getSleepSuggestion(analysis);
return {
title,
body: `${body}\n${suggestion}`,
data: {
type: 'sleep_analysis',
score: sleepScore,
quality,
analysis: JSON.stringify(analysis),
url: '/sleep-detail', // 点击通知跳转到睡眠详情页
},
sound: 'default',
badge: 1,
};
}
/**
* 获取质量配置
*/
function getQualityConfig(quality: string): {
emoji: string;
title: string;
} {
const configs = {
excellent: {
emoji: '😴',
title: '睡眠质量优秀',
},
good: {
emoji: '😊',
title: '睡眠质量良好',
},
fair: {
emoji: '😐',
title: '睡眠质量一般',
},
poor: {
emoji: '😟',
title: '睡眠质量较差',
},
very_poor: {
emoji: '😰',
title: '睡眠质量很差',
},
};
return configs[quality as keyof typeof configs] || {
emoji: '💤',
title: '睡眠分析完成',
};
}
/**
* 格式化睡眠时长
*/
function formatSleepDuration(hours: number): string {
const h = Math.floor(hours);
const m = Math.round((hours - h) * 60);
if (m === 0) {
return `${h}小时`;
}
return `${h}小时${m}分钟`;
}
/**
* 获取睡眠建议
*/
function getSleepSuggestion(analysis: SleepAnalysisData): string {
const { quality, totalSleepHours, deepSleepPercentage, remSleepPercentage, sleepEfficiency } = analysis;
// 优秀或良好的睡眠
if (quality === 'excellent' || quality === 'good') {
const tips = [
'继续保持良好的睡眠习惯!',
'坚持规律作息,身体会感谢你!',
'优质睡眠让你精力充沛!',
];
return tips[Math.floor(Math.random() * tips.length)];
}
// 根据具体问题给出建议
const suggestions: string[] = [];
if (totalSleepHours < 7) {
suggestions.push('建议增加睡眠时间至7-9小时');
} else if (totalSleepHours > 9) {
suggestions.push('睡眠时间偏长,注意睡眠质量');
}
if (deepSleepPercentage < 13) {
suggestions.push('深度睡眠不足,睡前避免使用电子设备');
}
if (remSleepPercentage < 20) {
suggestions.push('REM睡眠不足保持规律的作息时间');
}
if (sleepEfficiency < 85) {
suggestions.push('睡眠效率较低,改善睡眠环境');
}
// 如果有具体建议,返回第一条;否则返回通用建议
if (suggestions.length > 0) {
return `💡 ${suggestions[0]}`;
}
return '建议关注睡眠质量,保持良好作息';
}
/**
* 发送简单的睡眠提醒(用于测试)
*/
export async function sendSimpleSleepReminder(userName: string = '朋友'): Promise<void> {
try {
await Notifications.scheduleNotificationAsync({
content: {
title: '😴 睡眠质量分析',
body: `${userName},您的睡眠数据已更新,点击查看详细分析`,
data: {
type: 'sleep_reminder',
url: '/sleep-detail',
},
sound: 'default',
},
trigger: null,
});
logger.info('简单睡眠提醒已发送');
} catch (error) {
logger.error('发送简单睡眠提醒失败:', error);
}
}