perf: 优化食物选择

This commit is contained in:
richarjiang
2025-08-29 10:13:59 +08:00
parent 8d567fb4cb
commit f38f495008
2 changed files with 79 additions and 12 deletions

View File

@@ -1,6 +1,7 @@
import { FoodDetailModal } from '@/components/model/food/FoodDetailModal';
import { useFoodLibrary, useFoodSearch } from '@/hooks/useFoodLibrary';
import type { FoodItem, MealType, SelectedFoodItem } from '@/types/food';
import { addDietRecord, type CreateDietRecordDto } from '@/services/dietRecords';
import { Ionicons } from '@expo/vector-icons';
import { Image } from 'expo-image';
import { useLocalSearchParams, useRouter } from 'expo-router';
@@ -45,6 +46,7 @@ export default function FoodLibraryScreen() {
const [selectedFoodItems, setSelectedFoodItems] = useState<SelectedFoodItem[]>([]);
const [showMealSelector, setShowMealSelector] = useState(false);
const [currentMealType, setCurrentMealType] = useState<MealType>(mealType);
const [isRecording, setIsRecording] = useState(false);
// 获取当前选中的分类
const selectedCategory = categories.find(cat => cat.id === selectedCategoryId);
@@ -127,6 +129,47 @@ export default function FoodLibraryScreen() {
setSelectedFood(null);
};
// 处理饮食记录
const handleRecordDiet = async () => {
if (selectedFoodItems.length === 0) return;
setIsRecording(true);
try {
// 逐个记录选中的食物
for (const item of selectedFoodItems) {
const dietRecordData: CreateDietRecordDto = {
mealType: currentMealType,
foodName: item.food.name,
foodDescription: item.food.description,
portionDescription: `${item.amount}${item.unit}`,
estimatedCalories: item.calories,
proteinGrams: item.food.protein ? Number(((item.food.protein * item.amount) / 100).toFixed(2)) : undefined,
carbohydrateGrams: item.food.carbohydrate ? Number(((item.food.carbohydrate * item.amount) / 100).toFixed(2)) : undefined,
fatGrams: item.food.fat ? Number(((item.food.fat * item.amount) / 100).toFixed(2)) : undefined,
fiberGrams: item.food.fiber ? Number(((item.food.fiber * item.amount) / 100).toFixed(2)) : undefined,
sugarGrams: item.food.sugar ? Number(((item.food.sugar * item.amount) / 100).toFixed(2)) : undefined,
sodiumMg: item.food.sodium ? Number(((item.food.sodium * item.amount) / 100).toFixed(2)) : undefined,
additionalNutrition: item.food.additionalNutrition,
source: 'manual',
mealTime: new Date().toISOString(),
imageUrl: item.food.imageUrl,
};
await addDietRecord(dietRecordData);
}
// 记录成功后清空选择列表并返回
setSelectedFoodItems([]);
router.back();
} catch (error) {
console.error('记录饮食失败:', error);
// 这里可以显示错误提示
} finally {
setIsRecording(false);
}
};
// 处理餐次选择
const handleMealTypeSelect = (selectedMealType: MealType) => {
setCurrentMealType(selectedMealType);
@@ -324,20 +367,19 @@ export default function FoodLibraryScreen() {
<TouchableOpacity
style={[
styles.recordButton,
selectedFoodItems.length === 0 && styles.recordButtonDisabled
(selectedFoodItems.length === 0 || isRecording) && styles.recordButtonDisabled
]}
disabled={selectedFoodItems.length === 0}
onPress={() => {
// 这里可以处理记录逻辑
console.log('记录食物:', selectedFoodItems);
// 记录成功后可以清空选择列表或返回上一页
router.back();
}}
disabled={selectedFoodItems.length === 0 || isRecording}
onPress={handleRecordDiet}
>
<Text style={[
styles.recordButtonText,
selectedFoodItems.length === 0 && styles.recordButtonTextDisabled
]}></Text>
{isRecording ? (
<ActivityIndicator size="small" color="#FFF" />
) : (
<Text style={[
styles.recordButtonText,
selectedFoodItems.length === 0 && styles.recordButtonTextDisabled
]}></Text>
)}
</TouchableOpacity>
</View>