feat: 优化统计页面和BMI卡片,移除压力分析相关代码

- 在统计页面中移除压力分析模态框及相关状态管理,简化组件逻辑
- 更新BMI卡片,改进弹窗展示方式,增加渐变背景和健康建议
- 新增更新体重的功能,支持将体重数据写入健康数据中
- 优化压力计组件,调整数据展示逻辑,提升用户体验
This commit is contained in:
richarjiang
2025-08-20 17:25:42 +08:00
parent d76ba48424
commit 1c44c3083b
4 changed files with 334 additions and 157 deletions

View File

@@ -1,27 +1,27 @@
import { Ionicons } from '@expo/vector-icons';
import { LinearGradient } from 'expo-linear-gradient';
import React from 'react';
import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { StressAnalysisModal } from './StressAnalysisModal';
interface StressMeterProps {
value: number | null;
updateTime?: Date;
style?: any;
onPress?: () => void;
hrvValue: number;
}
export function StressMeter({ value, updateTime, style, onPress }: StressMeterProps) {
export function StressMeter({ value, updateTime, style, hrvValue }: StressMeterProps) {
// 将HRV值转换为压力指数0-100
// HRV值范围30-110ms映射到压力指数100-0
// HRV值越高压力越小HRV值越低压力越大
const stressIndex = value ? Math.round(Math.min(100, Math.max(0, 100 - ((value - 30) / 80) * 100))) : null;
// 根据压力指数计算状态
const getStressStatus = () => {
if (stressIndex === null) {
if (value === null) {
return '未知';
} else if (stressIndex <= 30) {
} else if (value <= 30) {
return '放松';
} else if (stressIndex <= 70) {
} else if (value <= 70) {
return '正常';
} else {
return '紧张';
@@ -47,55 +47,71 @@ export function StressMeter({ value, updateTime, style, onPress }: StressMeterPr
// 计算进度条位置0-100%
// 压力指数越高,进度条越满
const progressPercentage = stressIndex === null ? 0 : stressIndex;
const progressPercentage = value === null ? 0 : value;
// 在组件内部添加状态
const [showStressModal, setShowStressModal] = useState(false);
// 修改 onPress 处理函数
const handlePress = () => {
setShowStressModal(true);
};
return (
<TouchableOpacity
style={[styles.container, style]}
onPress={onPress}
activeOpacity={0.8}
>
{/* 头部区域 */}
<View style={styles.header}>
<View style={styles.leftSection}>
<View style={styles.iconContainer}>
<Ionicons name="heart" size={16} color="#3B82F6" />
<>
<TouchableOpacity
style={[styles.container, style]}
onPress={handlePress}
activeOpacity={0.8}
>
{/* 头部区域 */}
<View style={styles.header}>
<View style={styles.leftSection}>
<View style={styles.iconContainer}>
<Ionicons name="heart" size={16} color="#3B82F6" />
</View>
<Text style={styles.title}></Text>
</View>
<Text style={styles.title}></Text>
<Text style={styles.emoji}>{getStatusEmoji()}</Text>
</View>
<Text style={styles.emoji}>{getStatusEmoji()}</Text>
</View>
{/* 数值显示区域 */}
<View style={styles.valueSection}>
<Text style={styles.value}>{stressIndex === null ? '--' : stressIndex}</Text>
<Text style={styles.unit}></Text>
</View>
{/* 数值显示区域 */}
<View style={styles.valueSection}>
<Text style={styles.value}>{value === null ? '--' : value}</Text>
<Text style={styles.unit}></Text>
</View>
{/* 进度条区域 */}
<View style={styles.progressContainer}>
<View style={styles.progressTrack}>
{/* 渐变背景进度条 */}
<View style={[styles.progressBar, { width: `${progressPercentage}%` }]}>
<LinearGradient
colors={['#10B981', '#FCD34D', '#F97316']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.gradientBar}
/>
{/* 进度条区域 */}
<View style={styles.progressContainer}>
<View style={styles.progressTrack}>
{/* 渐变背景进度条 */}
<View style={[styles.progressBar, { width: `${progressPercentage}%` }]}>
<LinearGradient
colors={['#10B981', '#FCD34D', '#F97316']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={styles.gradientBar}
/>
</View>
{/* 白色圆形指示器 */}
<View style={[styles.indicator, { left: `${Math.max(0, Math.min(100, progressPercentage - 2))}%` }]} />
</View>
{/* 白色圆形指示器 */}
<View style={[styles.indicator, { left: `${Math.max(0, Math.min(100, progressPercentage - 2))}%` }]} />
</View>
</View>
{/* 更新时间
{updateTime && (
<Text style={styles.updateTime}>{formatUpdateTime(updateTime)}</Text>
)} */}
</TouchableOpacity>
{/* 更新时间
{updateTime && (
<Text style={styles.updateTime}>{formatUpdateTime(updateTime)}</Text>
)} */}
</TouchableOpacity>
{/* 压力分析浮窗 */}
<StressAnalysisModal
visible={showStressModal}
onClose={() => setShowStressModal(false)}
hrvValue={hrvValue}
updateTime={updateTime || new Date()}
/>
</>
);
}