feat: 优化统计和步数详情页面,添加活动等级计算和展示,更新压力计组件以支持HRV值直接显示
This commit is contained in:
@@ -12,17 +12,14 @@ import { Colors } from '@/constants/Colors';
|
||||
import { getTabBarBottomPadding } from '@/constants/TabBar';
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useAuthGuard } from '@/hooks/useAuthGuard';
|
||||
import { notificationService } from '@/services/notifications';
|
||||
import { selectHealthDataByDate, setHealthData } from '@/store/healthSlice';
|
||||
import { fetchDailyMoodCheckins, selectLatestMoodRecordByDate } from '@/store/moodSlice';
|
||||
import { fetchDailyNutritionData, selectNutritionSummaryByDate } from '@/store/nutritionSlice';
|
||||
import { fetchTodayWaterStats, selectTodayStats } from '@/store/waterSlice';
|
||||
import { getMonthDaysZh, getTodayIndexInMonth } from '@/utils/date';
|
||||
import { ensureHealthPermissions, fetchHealthDataForDate, fetchRecentHRV } from '@/utils/health';
|
||||
import { ensureHealthPermissions, fetchHealthDataForDate } from '@/utils/health';
|
||||
import { getTestHealthData } from '@/utils/mockHealthData';
|
||||
import { WaterNotificationHelpers } from '@/utils/notificationHelpers';
|
||||
import { calculateNutritionGoals } from '@/utils/nutrition';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import dayjs from 'dayjs';
|
||||
@@ -412,121 +409,6 @@ export default function ExploreScreen() {
|
||||
};
|
||||
}, [loadAllData, currentSelectedDate]);
|
||||
|
||||
// 检查压力水平并发送通知
|
||||
const checkStressLevelAndNotify = React.useCallback(async () => {
|
||||
try {
|
||||
console.log('开始检查压力水平...');
|
||||
|
||||
// 确保有健康权限
|
||||
const hasPermission = await ensureHealthPermissions();
|
||||
if (!hasPermission) {
|
||||
console.log('没有健康权限,跳过压力检查');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取最近2小时内的实时HRV数据
|
||||
const recentHRV = await fetchRecentHRV(2);
|
||||
console.log('获取到的最近2小时HRV值:', recentHRV);
|
||||
|
||||
if (recentHRV === null || recentHRV === undefined) {
|
||||
console.log('没有最近的HRV数据,跳过压力检查');
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断压力水平(HRV值低于60表示压力过大)
|
||||
if (recentHRV < 60) {
|
||||
console.log(`检测到压力过大,HRV值: ${recentHRV},准备发送鼓励通知`);
|
||||
|
||||
// 检查是否在过去2小时内已经发送过压力提醒,避免重复打扰
|
||||
const lastNotificationKey = '@last_stress_notification';
|
||||
const lastNotificationTime = await AsyncStorage.getItem(lastNotificationKey);
|
||||
const now = new Date().getTime();
|
||||
const twoHoursAgo = now - (2 * 60 * 60 * 1000); // 2小时前
|
||||
|
||||
if (lastNotificationTime && parseInt(lastNotificationTime) > twoHoursAgo) {
|
||||
console.log('2小时内已发送过压力提醒,跳过本次通知');
|
||||
return;
|
||||
}
|
||||
|
||||
// 随机选择一条鼓励性消息
|
||||
const encouragingMessages = [
|
||||
'放松一下吧 🌸\n检测到您的压力指数较高,不妨暂停一下,做几个深呼吸,或者来一段轻松的普拉提练习。您的健康最重要!',
|
||||
'该休息一下了 🧘♀️\n您的身体在提醒您需要放松。试试冥想、散步或听听舒缓的音乐,让心情平静下来。',
|
||||
'压力山大?我们来帮您 💆♀️\n高压力对健康不利,建议您做一些放松运动,比如瑜伽或普拉提,释放身心压力。',
|
||||
'关爱自己,从现在开始 💝\n检测到您可能承受较大压力,记得给自己一些时间,做喜欢的事情,保持身心健康。',
|
||||
'深呼吸,一切都会好的 🌈\n压力只是暂时的,试试腹式呼吸或简单的伸展运动,让身体和心灵都得到放松。'
|
||||
];
|
||||
|
||||
const randomMessage = encouragingMessages[Math.floor(Math.random() * encouragingMessages.length)];
|
||||
const [title, body] = randomMessage.split('\n');
|
||||
|
||||
// 发送鼓励性推送通知
|
||||
await notificationService.sendImmediateNotification({
|
||||
title: title,
|
||||
body: body,
|
||||
data: {
|
||||
type: 'stress_alert',
|
||||
hrvValue: recentHRV,
|
||||
timestamp: new Date().toISOString(),
|
||||
url: '/mood/calendar' // 点击通知跳转到心情页面
|
||||
},
|
||||
sound: true,
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
// 记录通知发送时间
|
||||
await AsyncStorage.setItem(lastNotificationKey, now.toString());
|
||||
|
||||
console.log('压力提醒通知已发送');
|
||||
} else {
|
||||
console.log(`压力水平正常,HRV值: ${recentHRV}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('检查压力水平失败:', error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// 检查喝水目标并发送通知
|
||||
const checkWaterGoalAndNotify = React.useCallback(async () => {
|
||||
try {
|
||||
console.log('开始检查喝水目标完成情况...');
|
||||
|
||||
// 获取最新的喝水统计数据
|
||||
if (!todayWaterStats || !todayWaterStats.dailyGoal || todayWaterStats.dailyGoal <= 0) {
|
||||
console.log('没有设置喝水目标或目标无效,跳过喝水检查');
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取用户名
|
||||
const userName = userProfile?.name || '朋友';
|
||||
const currentHour = new Date().getHours();
|
||||
|
||||
// 构造今日统计数据
|
||||
const waterStatsForCheck = {
|
||||
totalAmount: todayWaterStats.totalAmount || 0,
|
||||
dailyGoal: todayWaterStats.dailyGoal,
|
||||
completionRate: todayWaterStats.completionRate || 0
|
||||
};
|
||||
|
||||
// 调用喝水通知检查函数
|
||||
const notificationSent = await WaterNotificationHelpers.checkWaterGoalAndNotify(
|
||||
userName,
|
||||
waterStatsForCheck,
|
||||
currentHour
|
||||
);
|
||||
|
||||
if (notificationSent) {
|
||||
console.log('喝水提醒通知已发送');
|
||||
} else {
|
||||
console.log('无需发送喝水提醒通知');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('检查喝水目标失败:', error);
|
||||
}
|
||||
}, [todayWaterStats, userProfile]);
|
||||
|
||||
|
||||
|
||||
// 日期点击时,加载对应日期数据
|
||||
const onSelectDate = React.useCallback((index: number, date: Date) => {
|
||||
|
||||
Reference in New Issue
Block a user