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, page = 1, limit = 10, }: { startDate?: string; endDate?: string; page?: number; limit?: number; }): Promise<{ records: DietRecord[] total: number page: number limit: number }> { const searchParams = new URLSearchParams(); if (startDate) searchParams.append('startDate', startDate); if (endDate) searchParams.append('endDate', endDate); searchParams.append('page', page.toString()); searchParams.append('limit', limit.toString()); const params = searchParams.toString() ? `?${searchParams.toString()}` : ''; 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)), // 钠含量越低越好 ]; }