From 6c21c4b4487ea508f7634d50aab14298e2edb13e Mon Sep 17 00:00:00 2001 From: richarjiang Date: Thu, 4 Sep 2025 17:46:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A3=9F=E7=89=A9?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A3=9F=E7=89=A9=E5=90=8D=E7=A7=B0=E3=80=81?= =?UTF-8?q?=E9=87=8D=E9=87=8F=E5=92=8C=E5=8D=A1=E8=B7=AF=E9=87=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/food/analysis-result.tsx | 221 ++++++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 1 deletion(-) diff --git a/app/food/analysis-result.tsx b/app/food/analysis-result.tsx index b856230..2b68f28 100644 --- a/app/food/analysis-result.tsx +++ b/app/food/analysis-result.tsx @@ -15,9 +15,11 @@ import { BackHandler, Image, Modal, + Pressable, ScrollView, StyleSheet, Text, + TextInput, TouchableOpacity, View } from 'react-native'; @@ -84,6 +86,8 @@ export default function FoodAnalysisResultScreen() { const [isRecording, setIsRecording] = useState(false); const [showImagePreview, setShowImagePreview] = useState(false); const [animationTrigger, setAnimationTrigger] = useState(0); + const [editingFood, setEditingFood] = useState(null); + const [editFormData, setEditFormData] = useState({ name: '', amount: '', calories: '' }); const { imageUri, recognitionId, hideRecordBar } = params; // 判断是否隐藏记录栏(默认显示) @@ -199,6 +203,39 @@ export default function FoodAnalysisResultScreen() { setFoodItems(prev => prev.filter(item => item.id !== itemId)); }; + // 打开编辑弹窗 + const handleEditFood = (item: typeof mockFoodItems[0]) => { + setEditFormData({ + name: item.name, + amount: item.amount.toString(), + calories: item.calories.toString(), + }); + setEditingFood(item.id); + }; + + // 保存编辑 + const handleSaveEdit = () => { + if (!editingFood) return; + + const amount = parseFloat(editFormData.amount) || 0; + const calories = parseFloat(editFormData.calories) || 0; + + setFoodItems(prev => prev.map(item => + item.id === editingFood + ? { ...item, name: editFormData.name, amount, calories } + : item + )); + + setEditingFood(null); + setEditFormData({ name: '', amount: '', calories: '' }); + }; + + // 关闭编辑弹窗 + const handleCloseEdit = () => { + setEditingFood(null); + setEditFormData({ name: '', amount: '', calories: '' }); + }; + // 获取随机食物emoji function getRandomFoodEmoji(): string { const foodEmojis = ['🍎', '🍌', '🍞', '🥛', '🥗', '🍗', '🍖', '🥕', '🥦', '🥬', '🍅', '🥒', '🍇', '🥝', '🍓']; @@ -367,7 +404,10 @@ export default function FoodAnalysisResultScreen() { {item.calories}千卡 - {shouldHideRecordBar ? null : + {shouldHideRecordBar ? null : handleEditFood(item)} + > } {shouldHideRecordBar ? null : )} /> + + {/* 编辑食物弹窗 */} + ); } +// 编辑食物弹窗组件 +function FoodEditModal({ + visible, + formData, + onFormDataChange, + onClose, + onSave +}: { + visible: boolean; + formData: { name: string; amount: string; calories: string }; + onFormDataChange: (data: { name: string; amount: string; calories: string }) => void; + onClose: () => void; + onSave: () => void; +}) { + const handleFieldChange = (field: string, value: string) => { + onFormDataChange({ ...formData, [field]: value }); + }; + + return ( + + + + + + 编辑食物信息 + + {/* 食物名称 */} + + 食物名称 + handleFieldChange('name', value)} + autoFocus + /> + + + {/* 重量/数量 */} + + 重量 (克) + handleFieldChange('amount', value)} + keyboardType="numeric" + /> + + + {/* 卡路里 */} + + 卡路里 (千卡) + handleFieldChange('calories', value)} + keyboardType="numeric" + /> + + + {/* 按钮区域 */} + + + 取消 + + + 保存 + + + + + ); +} + // 营养圆环组件 function NutritionRing({ label, @@ -1039,4 +1178,84 @@ const styles = StyleSheet.create({ fontSize: 16, fontWeight: '500', }, + modalBackdrop: { + ...StyleSheet.absoluteFillObject, + backgroundColor: 'rgba(0,0,0,0.4)', + }, + // 编辑弹窗样式 + editModalSheet: { + position: 'absolute', + left: 0, + right: 0, + bottom: 0, + backgroundColor: '#FFFFFF', + borderTopLeftRadius: 20, + borderTopRightRadius: 20, + paddingHorizontal: 20, + paddingBottom: 40, + paddingTop: 20, + }, + modalHandle: { + width: 36, + height: 4, + backgroundColor: '#E0E0E0', + borderRadius: 2, + alignSelf: 'center', + marginBottom: 20, + }, + modalTitle: { + fontSize: 20, + fontWeight: '600', + color: '#333333', + marginBottom: 24, + textAlign: 'center', + }, + editFieldContainer: { + marginBottom: 20, + }, + editFieldLabel: { + fontSize: 16, + fontWeight: '500', + color: '#333333', + marginBottom: 8, + }, + editInput: { + height: 50, + borderWidth: 1, + borderColor: '#E0E0E0', + borderRadius: 12, + paddingHorizontal: 16, + fontSize: 16, + backgroundColor: '#FFFFFF', + color: '#333333', + }, + modalButtons: { + flexDirection: 'row', + gap: 12, + marginTop: 8, + }, + modalCancelBtn: { + flex: 1, + height: 50, + backgroundColor: '#F0F0F0', + borderRadius: 12, + alignItems: 'center', + justifyContent: 'center', + }, + modalCancelText: { + fontSize: 16, + fontWeight: '600', + color: '#666666', + }, + modalSaveBtn: { + flex: 1, + height: 50, + borderRadius: 12, + alignItems: 'center', + justifyContent: 'center', + }, + modalSaveText: { + fontSize: 16, + fontWeight: '600', + }, }); \ No newline at end of file