# 饮食记录确认流程 API 文档 ## 概述 新的饮食记录流程分为两个阶段: 1. **图片识别阶段**:AI识别食物并返回确认选项 2. **用户确认阶段**:用户选择确认选项后记录到数据库 ## 重要说明 ⚠️ **流式响应兼容性**:当系统需要返回确认选项时,会自动使用非流式模式返回JSON结构,即使客户端请求了 `stream: true`。这确保了确认选项的正确显示。 ## API 流程 ### 第一阶段:图片识别(返回确认选项) **请求示例:** ```json POST /ai-coach/chat { "conversationId": "user123-1234567890", "messages": [ { "role": "user", "content": "#记饮食" } ], "imageUrls": ["https://example.com/food-image.jpg"], "stream": false } ``` **响应示例:** ```json { "conversationId": "user123-1234567890", "data": { "content": "我识别到了以下食物,请选择要记录的内容:\n\n图片中识别到烤鱼和米饭,看起来是一份营养均衡的晚餐。", "choices": [ { "id": "food_0", "label": "一条烤鱼 220卡", "value": { "id": "food_0", "foodName": "烤鱼", "portion": "1条", "calories": 220, "mealType": "dinner", "nutritionData": { "proteinGrams": 35, "carbohydrateGrams": 2, "fatGrams": 8, "fiberGrams": 0 } }, "recommended": true }, { "id": "food_1", "label": "一碗米饭 150卡", "value": { "id": "food_1", "foodName": "米饭", "portion": "1碗", "calories": 150, "mealType": "dinner", "nutritionData": { "proteinGrams": 3, "carbohydrateGrams": 32, "fatGrams": 0.5, "fiberGrams": 1 } }, "recommended": false } ], "interactionType": "food_confirmation", "pendingData": { "imageUrl": "https://example.com/food-image.jpg", "recognitionResult": { "recognizedItems": [...], "analysisText": "图片中识别到烤鱼和米饭...", "confidence": 85 } }, "context": { "command": "diet", "step": "confirmation" } } } ``` ### 第二阶段:用户确认选择 **请求示例:** ```json POST /ai-coach/chat { "conversationId": "user123-1234567890", "messages": [ { "role": "user", "content": "我选择记录烤鱼" } ], "selectedChoiceId": "food_0", "confirmationData": { "selectedOption": { "id": "food_0", "foodName": "烤鱼", "portion": "1条", "calories": 220, "mealType": "dinner", "nutritionData": { "proteinGrams": 35, "carbohydrateGrams": 2, "fatGrams": 8, "fiberGrams": 0 } }, "imageUrl": "https://example.com/food-image.jpg" }, "stream": false } ``` **响应示例:** ```json { "conversationId": "user123-1234567890", "text": "很好!我已经为您记录了这份烤鱼(1条,约220卡路里)。\n\n根据您的饮食记录,这是一份优质的蛋白质来源,包含35克蛋白质,脂肪含量适中。建议搭配一些蔬菜来增加膳食纤维的摄入。\n\n您今天的饮食营养搭配看起来不错,记得保持均衡的饮食习惯!" } ``` ## 数据结构说明 ### AiChoiceOptionDto ```typescript { id: string; // 选项唯一标识符 label: string; // 显示给用户的文本(如"一条鱼 200卡") value: any; // 选项对应的数据 recommended?: boolean; // 是否为推荐选项 } ``` ### AiResponseDataDto ```typescript { content: string; // AI回复的文本内容 choices?: AiChoiceOptionDto[]; // 选择选项(可选) interactionType?: string; // 交互类型:'text' | 'food_confirmation' | 'selection' pendingData?: any; // 需要用户确认的数据(可选) context?: any; // 上下文信息(可选) } ``` ### FoodConfirmationOption ```typescript { id: string; // 唯一标识符 label: string; // 显示文本 foodName: string; // 食物名称 portion: string; // 份量描述 calories: number; // 估算热量 mealType: MealType; // 餐次类型 nutritionData: { // 营养数据 proteinGrams?: number; // 蛋白质(克) carbohydrateGrams?: number; // 碳水化合物(克) fatGrams?: number; // 脂肪(克) fiberGrams?: number; // 膳食纤维(克) }; } ``` ## 错误处理 ### 图片识别失败 如果图片模糊或无法识别食物,API会返回正常的文本响应: ```json { "conversationId": "user123-1234567890", "text": "抱歉,我无法清晰地识别图片中的食物。请确保图片清晰,光线充足,食物在画面中清晰可见,然后重新上传。" } ``` ### 无效的确认数据 如果第二阶段的确认数据无效,系统会返回错误提示: ```json { "conversationId": "user123-1234567890", "text": "确认数据无效,请重新选择要记录的食物。" } ``` ## 使用建议 1. **图片质量**:确保上传的图片清晰,光线充足,食物在画面中清晰可见 2. **选择确认**:用户可以选择多个食物选项,每次确认记录一种食物 3. **营养分析**:系统会基于用户的历史饮食记录提供个性化的营养分析和建议 4. **流式响应处理**: - 客户端应该检查响应的 `Content-Type` - `application/json`:结构化数据(确认选项) - `text/plain`:流式文本 - 当返回确认选项时,系统会忽略 `stream` 参数并返回JSON ## 客户端适配指南 ### 响应类型检测 ```javascript // 检查响应类型 if (response.headers['content-type'].includes('application/json')) { // 处理结构化数据(确认选项) const data = await response.json(); if (data.data && data.data.choices) { // 显示选择选项 showFoodConfirmationOptions(data.data.choices); } } else { // 处理流式文本 handleStreamResponse(response); } ``` ### 确认选择发送 ```javascript // 用户选择后发送确认 const confirmationRequest = { conversationId: "user123-1234567890", messages: [{ role: "user", content: "我选择记录烤鱼" }], selectedChoiceId: "food_0", confirmationData: { selectedOption: selectedFoodOption, imageUrl: originalImageUrl }, stream: true // 第二阶段可以使用流式 }; ```