feat: 新增基础代谢率功能及相关组件

- 在健康数据中引入基础代谢率的读取和展示,支持用户记录健身进度
- 更新统计页面,替换BMI卡片为基础代谢卡片,提升用户体验
- 优化健康数据获取逻辑,确保基础代谢数据的准确性
- 更新权限描述,明确应用对健康数据的访问需求
This commit is contained in:
2025-08-21 22:53:22 +08:00
parent 098c65b23e
commit f10b7a0fb5
7 changed files with 538 additions and 34 deletions

View File

@@ -1,5 +1,5 @@
import { AnimatedNumber } from '@/components/AnimatedNumber';
import { BMICard } from '@/components/BMICard';
import { BasalMetabolismCard } from '@/components/BasalMetabolismCard';
import { FitnessRingsCard } from '@/components/FitnessRingsCard';
import { MoodCard } from '@/components/MoodCard';
import { NutritionRadarCard } from '@/components/NutritionRadarCard';
@@ -140,6 +140,8 @@ export default function ExploreScreen() {
// HealthKit: 每次页面聚焦都拉取今日数据
const [stepCount, setStepCount] = useState<number | null>(null);
const [activeCalories, setActiveCalories] = useState<number | null>(null);
// 基础代谢率(千卡)
const [basalMetabolism, setBasalMetabolism] = useState<number | null>(null);
// 睡眠时长(分钟)
const [sleepDuration, setSleepDuration] = useState<number | null>(null);
// HRV数据
@@ -235,6 +237,7 @@ export default function ExploreScreen() {
if (latestRequestKeyRef.current === requestKey) {
setStepCount(data.steps);
setActiveCalories(Math.round(data.activeEnergyBurned));
setBasalMetabolism(Math.round(data.basalEnergyBurned));
setSleepDuration(data.sleepDuration);
// 更新健身圆环数据
setFitnessRingsData({
@@ -455,14 +458,6 @@ export default function ExploreScreen() {
{/* 右列 */}
<View style={styles.masonryColumn}>
<FloatingCard style={styles.masonryCard} delay={250}>
<BMICard
weight={userProfile?.weight ? parseFloat(userProfile.weight) : undefined}
height={userProfile?.height ? parseFloat(userProfile.height) : undefined}
style={styles.bmiCardOverride}
/>
</FloatingCard>
<FloatingCard style={styles.masonryCard} delay={750}>
<FitnessRingsCard
activeCalories={fitnessRingsData.activeCalories}
activeCaloriesGoal={fitnessRingsData.activeCaloriesGoal}
@@ -474,7 +469,7 @@ export default function ExploreScreen() {
/>
</FloatingCard>
<FloatingCard style={[styles.masonryCard, styles.sleepCard]} delay={1250}>
<FloatingCard style={[styles.masonryCard, styles.sleepCard]} delay={750}>
<View style={styles.cardHeaderRow}>
<Text style={styles.cardTitle}></Text>
</View>
@@ -487,6 +482,14 @@ export default function ExploreScreen() {
)}
</FloatingCard>
{/* 基础代谢卡片 */}
<FloatingCard style={styles.masonryCard} delay={1250}>
<BasalMetabolismCard
value={basalMetabolism}
resetToken={animToken}
style={styles.basalMetabolismCardOverride}
/>
</FloatingCard>
</View>
</View>
@@ -823,7 +826,7 @@ const styles = StyleSheet.create({
shadowRadius: 12,
elevation: 6,
},
bmiCardOverride: {
basalMetabolismCardOverride: {
margin: -16, // 抵消 masonryCard 的 padding
borderRadius: 16,
},