fix: 修复压力数据
This commit is contained in:
@@ -64,7 +64,7 @@ export default function ExploreScreen() {
|
||||
|
||||
// 开发调试:设置为true来使用mock数据
|
||||
// 在真机测试时,可以暂时设置为true来验证组件显示逻辑
|
||||
const useMockData = __DEV__ || false; // 改为true来启用mock数据调试
|
||||
const useMockData = false; // 改为true来启用mock数据调试
|
||||
|
||||
const { pushIfAuthedElseLogin, isLoggedIn } = useAuthGuard();
|
||||
|
||||
@@ -92,7 +92,7 @@ export default function ExploreScreen() {
|
||||
const hourlySteps = useMockData ? (mockData?.hourlySteps ?? []) : (healthData?.hourlySteps ?? []);
|
||||
const activeCalories = useMockData ? (mockData?.activeEnergyBurned ?? null) : (healthData?.activeEnergyBurned ?? null);
|
||||
const basalMetabolism: number | null = useMockData ? (mockData?.basalEnergyBurned ?? null) : (healthData?.basalEnergyBurned ?? null);
|
||||
const hrvValue = useMockData ? (mockData?.hrv ?? null) : (healthData?.hrv ?? null);
|
||||
|
||||
const oxygenSaturation = useMockData ? (mockData?.oxygenSaturation ?? null) : (healthData?.oxygenSaturation ?? null);
|
||||
|
||||
// 调试HRV数据
|
||||
@@ -100,7 +100,6 @@ export default function ExploreScreen() {
|
||||
console.log('useMockData:', useMockData);
|
||||
console.log('mockData?.hrv:', mockData?.hrv);
|
||||
console.log('healthData?.hrv:', healthData?.hrv);
|
||||
console.log('final hrvValue:', hrvValue);
|
||||
console.log('healthData:', healthData);
|
||||
console.log('==================');
|
||||
|
||||
@@ -563,9 +562,7 @@ export default function ExploreScreen() {
|
||||
|
||||
<FloatingCard style={styles.masonryCard} delay={0}>
|
||||
<StressMeter
|
||||
value={hrvValue}
|
||||
updateTime={hrvUpdateTime}
|
||||
hrvValue={hrvValue}
|
||||
curDate={currentSelectedDate}
|
||||
/>
|
||||
</FloatingCard>
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { fetchHRVForDate } from '@/utils/health';
|
||||
import dayjs from 'dayjs';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { StressAnalysisModal } from './StressAnalysisModal';
|
||||
|
||||
interface StressMeterProps {
|
||||
value: number | null;
|
||||
updateTime?: Date;
|
||||
style?: any;
|
||||
hrvValue: number | null;
|
||||
curDate: Date
|
||||
}
|
||||
|
||||
export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterProps) {
|
||||
export function StressMeter({ curDate }: StressMeterProps) {
|
||||
// 格式化更新时间显示
|
||||
const formatUpdateTime = (date: Date): string => {
|
||||
const now = dayjs();
|
||||
@@ -41,12 +39,31 @@ export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterP
|
||||
|
||||
// HRV 范围: 30-110ms,对应压力指数: 100-0
|
||||
// 线性映射: stressIndex = 100 - ((hrv - 30) / (110 - 30)) * 100
|
||||
const normalizedHrv = Math.max(30, Math.min(110, hrv));
|
||||
const stressIndex = 100 - ((normalizedHrv - 30) / (110 - 30)) * 100;
|
||||
const normalizedHrv = Math.max(30, Math.min(130, hrv));
|
||||
const stressIndex = 100 - ((normalizedHrv - 30) / (130 - 30)) * 100;
|
||||
|
||||
return Math.round(stressIndex);
|
||||
};
|
||||
|
||||
const [hrvValue, setHrvValue] = useState(0)
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
getHrvData()
|
||||
}, [curDate])
|
||||
|
||||
const getHrvData = async () => {
|
||||
try {
|
||||
const data = await fetchHRVForDate(curDate)
|
||||
|
||||
if (data) {
|
||||
setHrvValue(data)
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 使用传入的 hrvValue 进行转换
|
||||
const stressIndex = convertHrvToStressIndex(hrvValue);
|
||||
|
||||
@@ -72,7 +89,7 @@ export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterP
|
||||
return (
|
||||
<>
|
||||
<TouchableOpacity
|
||||
style={[styles.container, style]}
|
||||
style={[styles.container]}
|
||||
onPress={handlePress}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
@@ -81,15 +98,15 @@ export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterP
|
||||
<View style={styles.leftSection}>
|
||||
<Text style={styles.title}>压力</Text>
|
||||
</View>
|
||||
{updateTime && (
|
||||
{/* {updateTime && (
|
||||
<Text style={styles.headerUpdateTime}>{formatUpdateTime(updateTime)}</Text>
|
||||
)}
|
||||
)} */}
|
||||
</View>
|
||||
|
||||
{/* 数值显示区域 */}
|
||||
<View style={styles.valueSection}>
|
||||
<Text style={styles.value}>{stressIndex === null ? '--' : stressIndex}</Text>
|
||||
<Text style={styles.unit}>%</Text>
|
||||
<Text style={styles.value}>{hrvValue || '--'}</Text>
|
||||
<Text>ms</Text>
|
||||
</View>
|
||||
|
||||
{/* 进度条区域 */}
|
||||
@@ -116,7 +133,7 @@ export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterP
|
||||
visible={showStressModal}
|
||||
onClose={() => setShowStressModal(false)}
|
||||
hrvValue={hrvValue}
|
||||
updateTime={updateTime || new Date()}
|
||||
// updateTime={updateTime || new Date()}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -116,7 +116,7 @@ PODS:
|
||||
- ExpoModulesCore
|
||||
- ExpoSystemUI (6.0.7):
|
||||
- ExpoModulesCore
|
||||
- ExpoUI (0.2.0-beta.0):
|
||||
- ExpoUI (0.2.0-beta.1):
|
||||
- ExpoModulesCore
|
||||
- ExpoWebBrowser (15.0.6):
|
||||
- ExpoModulesCore
|
||||
@@ -3018,9 +3018,9 @@ PODS:
|
||||
- ReactCommon/turbomodule/core
|
||||
- SocketRocket
|
||||
- Yoga
|
||||
- SDWebImage (5.21.2):
|
||||
- SDWebImage/Core (= 5.21.2)
|
||||
- SDWebImage/Core (5.21.2)
|
||||
- SDWebImage (5.21.1):
|
||||
- SDWebImage/Core (= 5.21.1)
|
||||
- SDWebImage/Core (5.21.1)
|
||||
- SDWebImageAVIFCoder (0.11.0):
|
||||
- libavif/core (>= 0.11.0)
|
||||
- SDWebImage (~> 5.10)
|
||||
@@ -3444,7 +3444,7 @@ SPEC CHECKSUMS:
|
||||
ExpoSplashScreen: 1665809071bd907c6fdbfd9c09583ee4d51b41d4
|
||||
ExpoSymbols: 3efee6865b1955fe3805ca88b36e8674ce6970dd
|
||||
ExpoSystemUI: 6cd74248a2282adf6dec488a75fa532d69dee314
|
||||
ExpoUI: b219c02a788f7cefd7976e657e97c14aea64dac1
|
||||
ExpoUI: 1e4b3045678eb66004d78d9a6602afdcbdc06bbd
|
||||
ExpoWebBrowser: 84d4438464d9754a4c1f1eaa97cd747f3752187e
|
||||
EXTaskManager: eedcd03c1a574c47d3f48d83d4e4659b3c1fa29b
|
||||
fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6
|
||||
@@ -3539,7 +3539,7 @@ SPEC CHECKSUMS:
|
||||
RNSentry: f2c39f1113e22413c9bb6e3faa6b27f110d95eaf
|
||||
RNSVG: 6f39605a4c4d200b11435c35bd077553c6b5963a
|
||||
RNWorklets: ad0606bee2a8103c14adb412149789c60b72bfb2
|
||||
SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
|
||||
SDWebImage: f29024626962457f3470184232766516dee8dfea
|
||||
SDWebImageAVIFCoder: 00310d246aab3232ce77f1d8f0076f8c4b021d90
|
||||
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
|
||||
SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -8,7 +8,7 @@
|
||||
"name": "digital-pilates",
|
||||
"version": "1.0.2",
|
||||
"dependencies": {
|
||||
"@expo/ui": "~0.2.0-beta.0",
|
||||
"@expo/ui": "~0.2.0-beta.1",
|
||||
"@expo/vector-icons": "^15.0.2",
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
"@react-native-community/datetimepicker": "^8.4.4",
|
||||
@@ -2295,9 +2295,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@expo/ui": {
|
||||
"version": "0.2.0-beta.0",
|
||||
"resolved": "https://registry.npmjs.org/@expo/ui/-/ui-0.2.0-beta.0.tgz",
|
||||
"integrity": "sha512-bxLMKBbodqLzGMC8GVPZw6FugB2LpnocgdBP5JYJ8oWojy7RkGl6fcki+97w6EJagRr/+82XAGTCzyOUFBUCoQ==",
|
||||
"version": "0.2.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/@expo/ui/-/ui-0.2.0-beta.1.tgz",
|
||||
"integrity": "sha512-9eEbZmpWHLbpApwWNpeAC7Xf4rzlWsBcgHzGGN1QAfKvAq2S9eJfoIqPergrnnjN8Ju8G3EAos1DCk84q3oBgw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo": "*",
|
||||
|
||||
@@ -40,10 +40,6 @@ async function executeWaterReminderTask(): Promise<void> {
|
||||
|
||||
// 检查时间限制(避免深夜打扰)
|
||||
const currentHour = new Date().getHours();
|
||||
if (currentHour < 8 || currentHour >= 21) {
|
||||
console.log(`当前时间${currentHour}点,不在提醒时间范围内,跳过喝水提醒`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取用户名
|
||||
const userName = userProfile?.name || '朋友';
|
||||
@@ -152,7 +148,7 @@ async function executeBackgroundTasks(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
|
||||
await sendTestNotification()
|
||||
// await sendTestNotification()
|
||||
|
||||
// 执行喝水提醒检查任务
|
||||
await executeWaterReminderTask();
|
||||
|
||||
@@ -461,27 +461,7 @@ async function fetchHeartRateVariability(options: HealthDataOptions): Promise<nu
|
||||
return resolve(null);
|
||||
}
|
||||
|
||||
logSuccess('HRV', res);
|
||||
console.log('HRV数据样本数量:', res.length);
|
||||
|
||||
// 打印最新的几个样本用于调试
|
||||
const latestSamples = res.slice(-3);
|
||||
console.log('最新的HRV样本:', latestSamples.map(sample => ({
|
||||
value: sample.value,
|
||||
startDate: sample.startDate,
|
||||
endDate: sample.endDate
|
||||
})));
|
||||
|
||||
const latestHrv = res[res.length - 1];
|
||||
if (latestHrv && latestHrv.value !== undefined && latestHrv.value !== null) {
|
||||
// HealthKit 中的 HRV 数据已经是毫秒单位,无需转换
|
||||
const hrvValue = Math.round(latestHrv.value);
|
||||
console.log('最终HRV值:', hrvValue);
|
||||
resolve(hrvValue);
|
||||
} else {
|
||||
console.warn('HRV样本值无效:', latestHrv);
|
||||
resolve(null);
|
||||
}
|
||||
resolve(Math.round(res[0].value * 1000))
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -657,7 +657,7 @@ export class WaterNotificationHelpers {
|
||||
): Promise<boolean> {
|
||||
try {
|
||||
// 检查时间限制:早上9点以前和晚上9点以后不通知
|
||||
if (currentHour < 9 || currentHour >= 21) {
|
||||
if (currentHour < 9 || currentHour >= 23) {
|
||||
console.log(`当前时间${currentHour}点,不在通知时间范围内(9:00-21:00),跳过喝水提醒`);
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user