feat: 修复健康数据

This commit is contained in:
2025-09-24 09:43:17 +08:00
parent e6dfd4d59a
commit 028ef56caf
8 changed files with 175 additions and 105 deletions

View File

@@ -5,7 +5,7 @@ import { fetchBasalEnergyBurned } from '@/utils/health';
import dayjs from 'dayjs';
import { Image } from 'expo-image';
import { router } from 'expo-router';
import React, { useEffect, useState } from 'react';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Modal, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
interface BasalMetabolismCardProps {
@@ -22,8 +22,13 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
const userProfile = useAppSelector(selectUserProfile);
const userAge = useAppSelector(selectUserAge);
// 计算基础代谢率范围
const calculateBMRRange = () => {
// 缓存和防抖相关
const cacheRef = useRef<Map<string, { data: number | null; timestamp: number }>>(new Map());
const loadingRef = useRef<Map<string, Promise<number | null>>>(new Map());
const CACHE_DURATION = 5 * 60 * 1000; // 5分钟缓存
// 使用 useMemo 缓存 BMR 计算,避免每次渲染重复计算
const bmrRange = useMemo(() => {
const { gender, weight, height } = userProfile;
// 检查是否有足够的信息来计算BMR
@@ -52,35 +57,83 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
const maxBMR = Math.round(bmr * 1.15);
return { min: minBMR, max: maxBMR, base: Math.round(bmr) };
};
}, [userProfile.gender, userProfile.weight, userProfile.height, userAge]);
const bmrRange = calculateBMRRange();
// 优化的数据获取函数,包含缓存和去重复请求
const fetchBasalMetabolismData = useCallback(async (date: Date): Promise<number | null> => {
const dateKey = dayjs(date).format('YYYY-MM-DD');
const now = Date.now();
// 检查缓存
const cached = cacheRef.current.get(dateKey);
if (cached && (now - cached.timestamp) < CACHE_DURATION) {
return cached.data;
}
// 检查是否已经在请求中(防止重复请求)
const existingRequest = loadingRef.current.get(dateKey);
if (existingRequest) {
return existingRequest;
}
// 创建新的请求
const request = (async () => {
try {
const options = {
startDate: dayjs(date).startOf('day').toDate().toISOString(),
endDate: dayjs(date).endOf('day').toDate().toISOString()
};
const basalEnergy = await fetchBasalEnergyBurned(options);
const result = basalEnergy || null;
// 更新缓存
cacheRef.current.set(dateKey, { data: result, timestamp: now });
return result;
} catch (error) {
console.error('BasalMetabolismCard: 获取基础代谢数据失败:', error);
return null;
} finally {
// 清理请求记录
loadingRef.current.delete(dateKey);
}
})();
// 记录请求
loadingRef.current.set(dateKey, request);
return request;
}, []);
// 获取基础代谢数据
useEffect(() => {
const loadBasalMetabolismData = async () => {
if (!selectedDate) return;
if (!selectedDate) return;
let isCancelled = false;
const loadData = async () => {
setLoading(true);
try {
setLoading(true);
const options = {
startDate: dayjs(selectedDate).startOf('day').toDate().toISOString(),
endDate: dayjs(selectedDate).endOf('day').toDate().toISOString()
};
const basalEnergy = await fetchBasalEnergyBurned(options);
setBasalMetabolism(basalEnergy || null);
} catch (error) {
console.error('BasalMetabolismCard: 获取基础代谢数据失败:', error);
setBasalMetabolism(null);
const result = await fetchBasalMetabolismData(selectedDate);
if (!isCancelled) {
setBasalMetabolism(result);
}
} finally {
setLoading(false);
if (!isCancelled) {
setLoading(false);
}
}
};
loadBasalMetabolismData();
}, [selectedDate]);
// 获取基础代谢状态描述
const getMetabolismStatus = () => {
loadData();
// 清理函数,防止组件卸载后的状态更新
return () => {
isCancelled = true;
};
}, [selectedDate, fetchBasalMetabolismData]);
// 使用 useMemo 优化状态描述计算
const status = useMemo(() => {
if (basalMetabolism === null || basalMetabolism === 0) {
return { text: '未知', color: '#9AA3AE' };
}
@@ -95,9 +148,7 @@ export function BasalMetabolismCard({ selectedDate, style }: BasalMetabolismCard
} else {
return { text: '较低', color: '#EF4444' };
}
};
const status = getMetabolismStatus();
}, [basalMetabolism]);
return (
<>