"""食谱 API - 支持热量识别与营养分析""" from typing import Optional from fastapi import APIRouter, Depends, HTTPException, UploadFile, File from sqlalchemy.ext.asyncio import AsyncSession from ..database import get_db from ..dependencies.auth import get_current_tenant_id from ..schemas.recipe import ( RecipeCreate, RecipeUpdate, RecipeResponse, RecipeImageUploadRequest, RecipeAnalyzeCaloriesResponse, ) from ..services.recipe_service import get_recipe_service router = APIRouter(prefix="/recipes", tags=["食谱"]) @router.post("/", response_model=RecipeResponse, summary="创建食谱") async def create_recipe( recipe_data: RecipeCreate, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """创建新食谱""" service = get_recipe_service() recipe = await service.create_recipe(db, recipe_data, tenant_id) return recipe @router.post("/analyze", response_model=RecipeAnalyzeCaloriesResponse, summary="AI 热量分析") async def analyze_food_calories( recipe_data: RecipeCreate, food_description: str, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """ 创建食谱并进行 AI 热量分析 - food_description: 食物描述(可以是图片识别后的描述) """ service = get_recipe_service() recipe, analysis = await service.create_recipe_with_ai_analysis( db, recipe_data, food_description, tenant_id ) if not analysis["success"]: return RecipeAnalyzeCaloriesResponse( success=False, data=None, message=analysis["message"], ) return RecipeAnalyzeCaloriesResponse( success=True, data=recipe, message=analysis["message"], ) @router.get("/", response_model=list[RecipeResponse], summary="获取食谱列表") async def list_recipes( skip: int = 0, limit: int = 20, category: Optional[str] = None, cuisine: Optional[str] = None, status: Optional[str] = None, is_favorite: Optional[bool] = None, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """获取食谱列表,支持分类筛选""" service = get_recipe_service() recipes = await service.list_recipes( db, tenant_id, skip=skip, limit=limit, category=category, cuisine=cuisine, status=status, is_favorite=is_favorite, ) return recipes @router.get("/{recipe_id}", response_model=RecipeResponse, summary="获取单个食谱") async def get_recipe( recipe_id: int, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """获取指定食谱详情""" service = get_recipe_service() recipe = await service.get_recipe(db, recipe_id, tenant_id) if not recipe: raise HTTPException(status_code=404, detail="食谱不存在") return recipe @router.put("/{recipe_id}", response_model=RecipeResponse, summary="更新食谱") async def update_recipe( recipe_id: int, recipe_data: RecipeUpdate, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """更新食谱信息""" service = get_recipe_service() recipe = await service.update_recipe(db, recipe_id, recipe_data, tenant_id) if not recipe: raise HTTPException(status_code=404, detail="食谱不存在") return recipe @router.delete("/{recipe_id}", summary="删除食谱") async def delete_recipe( recipe_id: int, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """删除食谱""" service = get_recipe_service() success = await service.delete_recipe(db, recipe_id, tenant_id) if not success: raise HTTPException(status_code=404, detail="食谱不存在") return {"message": "删除成功"} @router.post("/{recipe_id}/favorite", response_model=RecipeResponse, summary="收藏/取消收藏食谱") async def toggle_favorite( recipe_id: int, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """收藏或取消收藏食谱""" service = get_recipe_service() recipe = await service.get_recipe(db, recipe_id, tenant_id) if not recipe: raise HTTPException(status_code=404, detail="食谱不存在") recipe.is_favorite = not recipe.is_favorite await db.commit() await db.refresh(recipe) return recipe @router.post("/upload-image", response_model=dict, summary="上传图片(示例)") async def upload_recipe_image( image_base64: str, filename: Optional[str] = None, db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_current_tenant_id), ): """ 上传食谱图片 注意:这是示例实现,实际项目中需要集成对象存储服务(如 S3、OSS、COS 等) """ service = get_recipe_service() image_url = await service.upload_image(image_base64, filename) return {"image_url": image_url}