feat: 支持围度数据图表

This commit is contained in:
richarjiang
2025-09-24 18:04:12 +08:00
parent 028ef56caf
commit 6303795870
9 changed files with 1180 additions and 359 deletions

View File

@@ -1,7 +1,8 @@
import { FloatingSelectionModal, SelectionItem } from '@/components/ui/FloatingSelectionModal';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useAuthGuard } from '@/hooks/useAuthGuard';
import { selectUserProfile, updateUserBodyMeasurements } from '@/store/userSlice';
import { selectUserProfile, updateUserBodyMeasurements, UserProfile } from '@/store/userSlice';
import { router } from 'expo-router';
import React, { useState } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
@@ -59,6 +60,41 @@ const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
},
];
// 根据不同围度类型获取合理的默认值
const getDefaultCircumferenceValue = (measurementKey: string, userProfile?: UserProfile): number => {
// 如果用户已有该围度数据,直接使用
const existingValue = userProfile?.[measurementKey as keyof UserProfile] as number;
if (existingValue) {
return existingValue;
}
// 根据性别设置合理的默认值
const isMale = userProfile?.gender === 'male';
switch (measurementKey) {
case 'chestCircumference':
// 胸围:男性 85-110cm女性 75-95cm
return isMale ? 95 : 80;
case 'waistCircumference':
// 腰围:男性 70-90cm女性 60-80cm
return isMale ? 80 : 70;
case 'upperHipCircumference':
// 上臀围:
return 30;
case 'armCircumference':
// 臂围:男性 25-35cm女性 20-30cm
return isMale ? 30 : 25;
case 'thighCircumference':
// 大腿围:男性 45-60cm女性 40-55cm
return isMale ? 50 : 45;
case 'calfCircumference':
// 小腿围:男性 30-40cm女性 25-35cm
return isMale ? 35 : 30;
default:
return 70; // 默认70cm
}
};
// Generate circumference options (30-150 cm)
const circumferenceOptions: SelectionItem[] = Array.from({ length: 121 }, (_, i) => {
const value = i + 30;
@@ -75,10 +111,13 @@ const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
return;
}
// 使用智能默认值,如果用户已有数据则使用现有数据,否则使用基于性别的合理默认值
const defaultValue = getDefaultCircumferenceValue(measurement.key, userProfile);
setSelectedMeasurement({
key: measurement.key,
label: measurement.label,
currentValue: measurement.value,
currentValue: measurement.value || defaultValue,
});
setModalVisible(true);
};
@@ -95,8 +134,17 @@ const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
setSelectedMeasurement(null);
};
// 处理整个卡片点击,跳转到详情页
const handleCardPress = () => {
router.push('/circumference-detail');
};
return (
<View style={[styles.container, style]}>
<TouchableOpacity
style={[styles.container, style]}
onPress={handleCardPress}
activeOpacity={0.8}
>
<Text style={styles.title}> (cm)</Text>
<View style={styles.measurementsContainer}>
@@ -104,7 +152,10 @@ const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
<TouchableOpacity
key={index}
style={styles.measurementItem}
onPress={() => handleMeasurementPress(measurement)}
onPress={(e) => {
e.stopPropagation(); // 阻止事件冒泡
handleMeasurementPress(measurement);
}}
activeOpacity={0.7}
>
<Text style={styles.label}>{measurement.label}</Text>
@@ -131,7 +182,7 @@ const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
confirmButtonText="确认"
pickerHeight={180}
/>
</View>
</TouchableOpacity>
);
};