feat: 添加食物分析结果页面的图片预览功能,优化记录栏显示逻辑

This commit is contained in:
richarjiang
2025-09-04 15:12:39 +08:00
parent 5e00cb7788
commit 05a643a9e6
6 changed files with 495 additions and 99 deletions

View File

@@ -1,11 +1,14 @@
import { CalorieRingChart } from '@/components/CalorieRingChart';
import { DateSelector } from '@/components/DateSelector';
import { FloatingFoodOverlay } from '@/components/FloatingFoodOverlay';
import { NutritionRecordCard } from '@/components/NutritionRecordCard';
import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
import { DietRecord } from '@/services/dietRecords';
import { type FoodRecognitionResponse } from '@/services/foodRecognition';
import { saveRecognitionResult } from '@/store/foodRecognitionSlice';
import { selectHealthDataByDate } from '@/store/healthSlice';
import {
deleteNutritionRecord,
@@ -70,6 +73,9 @@ export default function NutritionRecordsScreen() {
const [hasMoreData, setHasMoreData] = useState(true);
const [page, setPage] = useState(1);
// 食物添加弹窗状态
const [showFoodOverlay, setShowFoodOverlay] = useState(false);
// 根据视图模式选择使用的数据
const displayRecords = viewMode === 'daily' ? nutritionRecords : allRecords;
const loading = viewMode === 'daily' ? nutritionLoading.records : allRecordsLoading;
@@ -249,6 +255,51 @@ export default function NutritionRecordsScreen() {
}
};
// 处理营养记录卡片点击
const handleRecordPress = (record: DietRecord) => {
// 将 DietRecord 转换为 FoodRecognitionResponse 格式
const recognitionResult: FoodRecognitionResponse = {
items: [{
id: record.id.toString(),
label: record.foodName,
foodName: record.foodName,
portion: record.portionDescription || `${record.estimatedCalories || 0}g`,
calories: record.estimatedCalories || 0,
mealType: record.mealType,
nutritionData: {
proteinGrams: record.proteinGrams || 0,
carbohydrateGrams: record.carbohydrateGrams || 0,
fatGrams: record.fatGrams || 0,
fiberGrams: 0, // DietRecord 中没有纤维数据设为0
}
}],
analysisText: record.foodDescription || `${record.foodName} - ${record.portionDescription}`,
confidence: 95, // 设置一个默认置信度
isFoodDetected: true,
nonFoodMessage: undefined
};
// 生成唯一的识别ID
const recognitionId = `record-${record.id}-${Date.now()}`;
// 保存到 Redux
dispatch(saveRecognitionResult({
id: recognitionId,
result: recognitionResult
}));
// 跳转到分析结果页面
router.push({
pathname: '/food/analysis-result',
params: {
imageUri: record.imageUrl || '',
mealType: record.mealType,
recognitionId: recognitionId,
hideRecordBar: 'true'
}
});
};
// 渲染视图模式切换器
const renderViewModeToggle = () => (
<View style={[styles.viewModeContainer, { backgroundColor: colorTokens.pageBackgroundEmphasis }]}>
@@ -294,8 +345,12 @@ export default function NutritionRecordsScreen() {
<DateSelector
selectedIndex={selectedIndex}
onDateSelect={(index, date) => setSelectedIndex(index)}
showMonthTitle={false}
showMonthTitle={true}
disableFutureDates={true}
showCalendarIcon={true}
containerStyle={{
paddingHorizontal: 16
}}
/>
);
};
@@ -317,6 +372,7 @@ export default function NutritionRecordsScreen() {
const renderRecord = ({ item, index }: { item: DietRecord; index: number }) => (
<NutritionRecordCard
record={item}
onPress={() => handleRecordPress(item)}
onDelete={() => handleDeleteRecord(item.id)}
/>
);
@@ -362,8 +418,7 @@ export default function NutritionRecordsScreen() {
// 添加食物的处理函数
const handleAddFood = () => {
const mealType = getCurrentMealType();
router.push(`/food-library?mealType=${mealType}`);
setShowFoodOverlay(true);
};
// 渲染右侧添加按钮
@@ -385,7 +440,7 @@ export default function NutritionRecordsScreen() {
right={renderRightButton()}
/>
{renderViewModeToggle()}
{/* {renderViewModeToggle()} */}
{renderDateSelector()}
{/* Calorie Ring Chart */}
@@ -425,6 +480,13 @@ export default function NutritionRecordsScreen() {
onEndReachedThreshold={0.1}
/>
)}
{/* 食物添加悬浮窗 */}
<FloatingFoodOverlay
visible={showFoodOverlay}
onClose={() => setShowFoodOverlay(false)}
mealType={getCurrentMealType()}
/>
</View>
);
}