- 在营养分析卡片中引入更新日期和图标,提升信息展示 - 修改营养维度标签,简化文本内容 - 更新雷达图组件,支持自定义尺寸和标签显示 - 增加尺寸配置,优化图表显示效果 - 更新饮食记录服务,添加更新时间字段以支持新功能
119 lines
3.2 KiB
TypeScript
119 lines
3.2 KiB
TypeScript
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;
|
||
updatedAt: string;
|
||
};
|
||
|
||
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,
|
||
updatedAt: '',
|
||
};
|
||
}
|
||
|
||
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),
|
||
updatedAt: record.updatedAt,
|
||
}),
|
||
{
|
||
totalCalories: 0,
|
||
totalProtein: 0,
|
||
totalCarbohydrate: 0,
|
||
totalFat: 0,
|
||
totalFiber: 0,
|
||
totalSugar: 0,
|
||
totalSodium: 0,
|
||
updatedAt: '',
|
||
}
|
||
);
|
||
}
|
||
|
||
// 将营养数据转换为雷达图数据(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)), // 钠含量越低越好
|
||
];
|
||
} |