feat: 增加睡眠分析通知功能,支持睡眠质量评估与建议

This commit is contained in:
richarjiang
2025-12-03 10:13:14 +08:00
parent 02b2de3ea3
commit e713ffbace
14 changed files with 190 additions and 415 deletions

View File

@@ -4,10 +4,14 @@
* 负责在睡眠分析完成后发送通知,提供睡眠质量评估和建议
*/
import i18n from '@/i18n';
import { logger } from '@/utils/logger';
import dayjs from 'dayjs';
import * as Notifications from 'expo-notifications';
import { SleepAnalysisData } from './sleepMonitor';
const t = (key: string, options?: Record<string, unknown>) => i18n.t(`sleepNotification.${key}`, options);
/**
* 分析睡眠数据并发送通知
*/
@@ -51,12 +55,22 @@ function buildSleepNotification(analysis: SleepAnalysisData): Notifications.Noti
// 构建通知正文
const sleepDuration = formatSleepDuration(totalSleepHours);
const efficiencyText = `睡眠效率 ${sleepEfficiency.toFixed(0)}%`;
const body = `您昨晚睡了 ${sleepDuration}${efficiencyText}。评分:${sleepScore}`;
const body = t('body', {
duration: sleepDuration,
efficiency: sleepEfficiency.toFixed(0),
score: sleepScore
});
// 获取建议
const suggestion = getSleepSuggestion(analysis);
// 计算睡眠日期
// 睡眠详情页面使用的日期逻辑是传入的日期会查询从前一天18:00到当天12:00的数据
// 所以我们应该传递醒来的日期sessionEnd这样用户点击通知后能看到正确的睡眠数据
const sleepDate = analysis.sessionEnd
? dayjs(analysis.sessionEnd).format('YYYY-MM-DD')
: dayjs().format('YYYY-MM-DD');
return {
title,
body: `${body}\n${suggestion}`,
@@ -64,6 +78,7 @@ function buildSleepNotification(analysis: SleepAnalysisData): Notifications.Noti
type: 'sleep_analysis',
score: sleepScore,
quality,
date: sleepDate, // 添加日期参数,用于点击通知后跳转
analysis: JSON.stringify(analysis),
url: '/sleep-detail', // 点击通知跳转到睡眠详情页
},
@@ -79,32 +94,32 @@ function getQualityConfig(quality: string): {
emoji: string;
title: string;
} {
const configs = {
const configs: Record<string, { emoji: string; title: string }> = {
excellent: {
emoji: '😴',
title: '睡眠质量优秀',
emoji: '🥳',
title: t('quality.excellent'),
},
good: {
emoji: '😊',
title: '睡眠质量良好',
emoji: '☀️',
title: t('quality.good'),
},
fair: {
emoji: '😐',
title: '睡眠质量一般',
emoji: '🌤️',
title: t('quality.fair'),
},
poor: {
emoji: '😟',
title: '睡眠质量较差',
emoji: '🌛',
title: t('quality.poor'),
},
very_poor: {
emoji: '😰',
title: '睡眠质量很差',
emoji: '🫂',
title: t('quality.veryPoor'),
},
};
return configs[quality as keyof typeof configs] || {
emoji: '💤',
title: '睡眠分析完成',
return configs[quality] || {
emoji: '🛏️',
title: t('quality.default'),
};
}
@@ -116,9 +131,9 @@ function formatSleepDuration(hours: number): string {
const m = Math.round((hours - h) * 60);
if (m === 0) {
return `${h}小时`;
return t('duration.hoursOnly', { hours: h });
}
return `${h}小时${m}分钟`;
return t('duration.hoursAndMinutes', { hours: h, minutes: m });
}
/**
@@ -127,35 +142,36 @@ function formatSleepDuration(hours: number): string {
function getSleepSuggestion(analysis: SleepAnalysisData): string {
const { quality, totalSleepHours, deepSleepPercentage, remSleepPercentage, sleepEfficiency } = analysis;
// 优秀或良好的睡眠
// 优秀或良好的睡眠 - 给予鼓励
if (quality === 'excellent' || quality === 'good') {
const tips = [
'继续保持良好的睡眠习惯!',
'坚持规律作息,身体会感谢你!',
'优质睡眠让你精力充沛!',
t('tips.excellent.keepItUp'),
t('tips.excellent.greatJob'),
t('tips.excellent.energized'),
t('tips.excellent.proud'),
];
return tips[Math.floor(Math.random() * tips.length)];
return `${tips[Math.floor(Math.random() * tips.length)]}`;
}
// 根据具体问题给出建议
// 根据具体问题给出温暖的建议
const suggestions: string[] = [];
if (totalSleepHours < 7) {
suggestions.push('建议增加睡眠时间至7-9小时');
suggestions.push(t('tips.suggestions.shortSleep'));
} else if (totalSleepHours > 9) {
suggestions.push('睡眠时间偏长,注意睡眠质量');
suggestions.push(t('tips.suggestions.longSleep'));
}
if (deepSleepPercentage < 13) {
suggestions.push('深度睡眠不足,睡前避免使用电子设备');
suggestions.push(t('tips.suggestions.lowDeepSleep'));
}
if (remSleepPercentage < 20) {
suggestions.push('REM睡眠不足保持规律的作息时间');
suggestions.push(t('tips.suggestions.lowRemSleep'));
}
if (sleepEfficiency < 85) {
suggestions.push('睡眠效率较低,改善睡眠环境');
suggestions.push(t('tips.suggestions.lowEfficiency'));
}
// 如果有具体建议,返回第一条;否则返回通用建议
@@ -163,29 +179,5 @@ function getSleepSuggestion(analysis: SleepAnalysisData): string {
return `💡 ${suggestions[0]}`;
}
return '建议关注睡眠质量,保持良好作息';
return `💡 ${t('tips.general')}`;
}
/**
* 发送简单的睡眠提醒(用于测试)
*/
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);
}
}