""" 补货建议触发接口 替代原定时任务,提供接口触发补货建议生成 """ import logging from typing import Optional from fastapi import APIRouter, HTTPException from pydantic import BaseModel from ...agent import ReplenishmentAgent from ...services import DataService logger = logging.getLogger(__name__) router = APIRouter() class InitRequest(BaseModel): """初始化请求""" group_id: int dealer_grouping_id: Optional[int] = None class InitResponse(BaseModel): """初始化响应""" success: bool message: str task_count: int = 0 @router.post("/replenishment/init", response_model=InitResponse) async def init_replenishment(req: InitRequest): """ 初始化补货建议 触发全量补货建议生成。 - 若指定 dealer_grouping_id,仅处理该商家组合 - 若未指定,处理 group_id 下所有商家组合 """ try: agent = ReplenishmentAgent() if req.dealer_grouping_id: data_service = DataService() try: groupings = data_service.get_dealer_groupings(req.group_id) grouping = next( (g for g in groupings if g["id"] == req.dealer_grouping_id), None, ) if not grouping: raise HTTPException( status_code=404, detail=f"未找到商家组合: {req.dealer_grouping_id}", ) agent.run( group_id=req.group_id, dealer_grouping_id=grouping["id"], dealer_grouping_name=grouping["name"], ) return InitResponse( success=True, message=f"商家组合 [{grouping['name']}] 补货建议生成完成", task_count=1, ) finally: data_service.close() else: data_service = DataService() try: groupings = data_service.get_dealer_groupings(req.group_id) finally: data_service.close() task_count = 0 for grouping in groupings: try: agent.run( group_id=req.group_id, dealer_grouping_id=grouping["id"], dealer_grouping_name=grouping["name"], ) task_count += 1 except Exception as e: logger.error( f"商家组合执行失败: {grouping['name']}, error={e}", exc_info=True, ) continue return InitResponse( success=True, message=f"补货建议生成完成,共处理 {task_count}/{len(groupings)} 个商家组合", task_count=task_count, ) except HTTPException: raise except Exception as e: logger.error(f"补货建议初始化失败: {e}", exc_info=True) raise HTTPException(status_code=500, detail=str(e))