import { fetchHRVWithStatus } from '@/utils/health'; import { convertHrvToStressIndex } from '@/utils/stress'; import { Image } from 'expo-image'; import { LinearGradient } from 'expo-linear-gradient'; import React, { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { StressAnalysisModal } from './StressAnalysisModal'; interface StressMeterProps { curDate: Date } export function StressMeter({ curDate }: StressMeterProps) { const { t } = useTranslation(); const [hrvValue, setHrvValue] = useState(0) const [updateTime, setUpdateTime] = useState(new Date()) useEffect(() => { getHrvData() }, [curDate]) const getHrvData = async () => { try { console.log('StressMeter: Starting to get HRV data...', curDate); // 使用智能HRV数据获取功能 const result = await fetchHRVWithStatus(curDate); console.log('StressMeter: HRV data fetch result:', result); if (result.hrvData) { setHrvValue(Math.round(result.hrvData.value)); if (result.hrvData.recordedAt) { setUpdateTime(new Date(result.hrvData.recordedAt)); } console.log(`StressMeter: Using ${result.message}, HRV value: ${result.hrvData.value}ms`); } else { console.log('StressMeter: No HRV data obtained'); // 可以设置一个默认值或者显示无数据状态 setHrvValue(0); } } catch (error) { console.error('StressMeter: Failed to get HRV data:', error); setHrvValue(0); } } // 使用传入的 hrvValue 进行转换 const stressIndex = convertHrvToStressIndex(hrvValue); // 计算进度条位置(0-100%) // 压力指数越高,进度条越满(红色区域越多) const progressPercentage = stressIndex !== null ? Math.max(0, Math.min(100, stressIndex)) : 0; // 在组件内部添加状态 const [showStressModal, setShowStressModal] = useState(false); // 修改 onPress 处理函数 const handlePress = () => { setShowStressModal(true); }; return ( <> {/* 头部区域 */} {t('statistics.components.stress.title')} {/* {updateTime && ( {formatUpdateTime(updateTime)} )} */} {/* 数值显示区域 */} {hrvValue || '--'} {t('statistics.components.stress.unit')} {/* 进度条区域 */} {/* 渐变背景进度条 */} {/* 白色圆形指示器 */} {/* 压力分析浮窗 */} setShowStressModal(false)} hrvValue={hrvValue} updateTime={updateTime} /> ); } const styles = StyleSheet.create({ container: { flex: 1, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.08, shadowRadius: 8, elevation: 3, position: 'relative', overflow: 'hidden', }, header: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8, }, leftSection: { flexDirection: 'row', alignItems: 'center', }, iconContainer: { width: 24, height: 24, borderRadius: 6, backgroundColor: '#EBF4FF', alignItems: 'center', justifyContent: 'center', marginRight: 6, }, titleIcon: { width: 16, height: 16, marginRight: 6, resizeMode: 'contain', }, title: { fontSize: 14, color: '#192126', fontWeight: '600', fontFamily: 'AliBold', }, valueSection: { flexDirection: 'row', alignItems: 'baseline', marginBottom: 12, }, value: { fontSize: 20, fontWeight: '600', color: '#192126', lineHeight: 20, marginTop: 2, fontFamily: 'AliBold', }, unit: { fontSize: 12, fontWeight: '500', color: '#9AA3AE', marginLeft: 4, fontFamily: 'AliRegular', }, progressContainer: { height: 6, }, progressTrack: { height: 6, borderRadius: 4, position: 'relative', overflow: 'visible', }, progressBar: { height: '100%', borderRadius: 4, overflow: 'hidden', }, gradientBar: { height: '100%', borderRadius: 4, }, indicator: { position: 'absolute', top: -2, width: 10, height: 10, borderRadius: 8, backgroundColor: '#FFFFFF', shadowColor: '#000', shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, borderWidth: 1.5, borderColor: '#E5E7EB', }, updateTime: { fontSize: 10, color: '#9AA3AE', textAlign: 'right', marginTop: 2, }, headerUpdateTime: { fontSize: 11, color: '#9AA3AE', fontWeight: '500', }, });