Files
digital-pilates/services/dietRecords.ts
richarjiang 9aa0a692a8 feat: 新增营养摄入分析卡片并优化相关页面
- 在统计页面中引入营养摄入分析卡片,展示用户的营养数据
- 更新探索页面,增加营养数据加载逻辑,确保用户体验一致性
- 移除不再使用的推荐文章逻辑,简化代码结构
- 更新路由常量,确保路径管理集中化
- 优化体重历史记录卡片,提升用户交互体验
2025-08-19 10:01:26 +08:00

115 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { api } from '@/services/api';
export type MealType = 'breakfast' | 'lunch' | 'dinner' | 'snack' | 'other';
export type RecordSource = 'manual' | 'vision' | 'other';
export type DietRecord = {
id: number;
mealType: MealType;
foodName: string;
foodDescription?: string;
weightGrams?: number;
portionDescription?: string;
estimatedCalories?: number;
proteinGrams?: number;
carbohydrateGrams?: number;
fatGrams?: number;
fiberGrams?: number;
sugarGrams?: number;
sodiumMg?: number;
additionalNutrition?: any;
source: RecordSource;
mealTime?: string;
imageUrl?: string;
notes?: string;
createdAt: string;
updatedAt: string;
};
export type NutritionSummary = {
totalCalories: number;
totalProtein: number;
totalCarbohydrate: number;
totalFat: number;
totalFiber: number;
totalSugar: number;
totalSodium: number;
};
export async function getDietRecords({
startDate,
endDate,
}: {
startDate: string;
endDate: string;
}): Promise<{
records: DietRecord[]
total: number
page: number
limit: number
}> {
const params = startDate && endDate ? `?startDate=${startDate}&endDate=${endDate}` : '';
return await api.get<{
records: DietRecord[]
total: number
page: number
limit: number
}>(`/users/diet-records${params}`);
}
export function calculateNutritionSummary(records: DietRecord[]): NutritionSummary {
if (records?.length === 0) {
return {
totalCalories: 0,
totalProtein: 0,
totalCarbohydrate: 0,
totalFat: 0,
totalFiber: 0,
totalSugar: 0,
totalSodium: 0,
};
}
return records.reduce(
(summary, record) => ({
totalCalories: summary.totalCalories + (record.estimatedCalories || 0),
totalProtein: summary.totalProtein + (record.proteinGrams || 0),
totalCarbohydrate: summary.totalCarbohydrate + (record.carbohydrateGrams || 0),
totalFat: summary.totalFat + (record.fatGrams || 0),
totalFiber: summary.totalFiber + (record.fiberGrams || 0),
totalSugar: summary.totalSugar + (record.sugarGrams || 0),
totalSodium: summary.totalSodium + (record.sodiumMg || 0),
}),
{
totalCalories: 0,
totalProtein: 0,
totalCarbohydrate: 0,
totalFat: 0,
totalFiber: 0,
totalSugar: 0,
totalSodium: 0,
}
);
}
// 将营养数据转换为雷达图数据0-5分制
export function convertToRadarData(summary: NutritionSummary): number[] {
// 基于推荐日摄入量计算分数
const recommendations = {
calories: 2000, // 卡路里
protein: 50, // 蛋白质(g)
carbohydrate: 300, // 碳水化合物(g)
fat: 65, // 脂肪(g)
fiber: 25, // 膳食纤维(g)
sodium: 2300, // 钠(mg)
};
return [
Math.min(5, (summary.totalCalories / recommendations.calories) * 5),
Math.min(5, (summary.totalProtein / recommendations.protein) * 5),
Math.min(5, (summary.totalCarbohydrate / recommendations.carbohydrate) * 5),
Math.min(5, (summary.totalFat / recommendations.fat) * 5),
Math.min(5, (summary.totalFiber / recommendations.fiber) * 5),
Math.min(5, Math.max(0, 5 - (summary.totalSodium / recommendations.sodium) * 5)), // 钠含量越低越好
];
}