from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.models.database import get_db from app.models.user import UserDB from app.api.deps import get_admin_user from app.core.response import success_response, error_response, ResponseModel from app.models.community_timeperiod import ( CommunityTimePeriodDB, CommunityTimePeriodCreate, CommunityTimePeriodUpdate, CommunityTimePeriodInfo, CommunityTimePeriodWithDetail, CommunityTimePeriodBatchCreate ) from app.models.timeperiod import TimePeriodDB, TimePeriodInfo from app.models.community import CommunityDB, CommunityInfo from typing import List, Optional import logging from sqlalchemy.orm import joinedload from app.core.redis_client import redis_client from datetime import datetime, timedelta router = APIRouter() @router.post("", response_model=ResponseModel) async def create_community_time_period( time_period: CommunityTimePeriodCreate, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """为社区添加配送时段""" try: # 检查社区是否存在 community = db.query(CommunityDB).filter(CommunityDB.id == time_period.community_id).first() if not community: return error_response(code=404, message="社区不存在") # 检查时段是否存在 time_period_obj = db.query(TimePeriodDB).filter(TimePeriodDB.id == time_period.time_period_id).first() if not time_period_obj: return error_response(code=404, message="配送时段不存在") # 检查是否已经存在 existing = db.query(CommunityTimePeriodDB).filter( CommunityTimePeriodDB.community_id == time_period.community_id, CommunityTimePeriodDB.time_period_id == time_period.time_period_id ).first() if existing: return error_response(code=400, message="该社区已经添加了此配送时段") # 创建新的关联 db_community_time_period = CommunityTimePeriodDB( community_id=time_period.community_id, time_period_id=time_period.time_period_id, capacity=time_period.capacity ) db.add(db_community_time_period) db.commit() db.refresh(db_community_time_period) return success_response(message="社区配送时段添加成功", data=CommunityTimePeriodInfo.model_validate(db_community_time_period)) except Exception as e: db.rollback() logging.exception(f"添加社区配送时段失败: {str(e)}") return error_response(code=500, message="添加社区配送时段失败,请稍后重试") @router.post("/batch", response_model=ResponseModel) async def batch_create_community_time_period( batch: CommunityTimePeriodBatchCreate, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """批量为社区添加配送时段""" try: # 检查社区是否存在 community = db.query(CommunityDB).filter(CommunityDB.id == batch.community_id).first() if not community: return error_response(code=404, message="社区不存在") # 检查时段是否存在 time_periods = db.query(TimePeriodDB).filter(TimePeriodDB.id.in_([time_period_capacity.time_period_id for time_period_capacity in batch.time_period_capacity_list])).all() if len(time_periods) != len([time_period_capacity.time_period_id for time_period_capacity in batch.time_period_capacity_list]): return error_response(code=404, message="部分配送时段不存在") # 先删除该社区的所有配送时段 db.query(CommunityTimePeriodDB).filter( CommunityTimePeriodDB.community_id == batch.community_id ).delete() # 批量添加新的配送时段 for time_period_capacity in batch.time_period_capacity_list: db_community_time_period = CommunityTimePeriodDB( community_id=batch.community_id, time_period_id=time_period_capacity.time_period_id, capacity=time_period_capacity.capacity ) db.add(db_community_time_period) db.commit() return success_response(message="社区配送时段批量添加成功") except Exception as e: db.rollback() logging.exception(f"批量添加社区配送时段失败: {str(e)}") return error_response(code=500, message="批量添加社区配送时段失败,请稍后重试") @router.get("/community/{community_id}", response_model=ResponseModel) async def get_community_time_periods( community_id: int, db: Session = Depends(get_db) ): """获取社区的配送时段列表""" try: # 查询社区的配送时段 community_time_periods = db.query(CommunityTimePeriodDB, TimePeriodDB.name.label("time_period_name"),TimePeriodDB.from_time.label("time_period_from_time"), TimePeriodDB.to_time.label("time_period_to_time")).join(TimePeriodDB).filter( CommunityTimePeriodDB.community_id == community_id ).order_by(TimePeriodDB.from_time).all() result = [] tomorrow_count=0 today_date = datetime.now().date() tomorrow_date = today_date + timedelta(days=1) # 构建今日配送时段 for ctp in community_time_periods: # 获取今日订单数量 today_orders_count = redis_client.get_community_period_orders_count(today_date,ctp.CommunityTimePeriodDB.id) # 如果已经过了时段,则不加入列表 if datetime.now().time() > ctp.time_period_to_time: tomorrow_count+=1 continue result.append({ "communtiy_time_period_id" :ctp.CommunityTimePeriodDB.id, "time_period_id": ctp.CommunityTimePeriodDB.time_period_id, "time_period_name": f"今日 {ctp.time_period_name}", "time_period_date": today_date, "capacity": ctp.CommunityTimePeriodDB.capacity, "from_time": ctp.time_period_from_time, "to_time": ctp.time_period_to_time, "order_full": today_orders_count >= ctp.CommunityTimePeriodDB.capacity, "is_default": False }) # 构建明日配送时段 for i in range(tomorrow_count): ctp = community_time_periods[i] result.append({ "communtiy_time_period_id" :ctp.CommunityTimePeriodDB.id, "time_period_id": ctp.CommunityTimePeriodDB.time_period_id, "time_period_name": f"明日 {ctp.time_period_name}", "time_period_date": tomorrow_date, "capacity": ctp.CommunityTimePeriodDB.capacity, "from_time": ctp.time_period_from_time, "to_time": ctp.time_period_to_time, "order_full": False, "is_default": False }) for ctp in result: if not ctp['order_full']: ctp['is_default'] = True break return success_response(data=result) except Exception as e: logging.exception(f"获取社区配送时段列表失败: {str(e)}") return error_response(code=500, message="获取社区配送时段列表失败,请稍后重试") @router.put("/{community_time_period_id}", response_model=ResponseModel) async def update_community_time_period( community_time_period_id: int, update_data: CommunityTimePeriodUpdate, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """更新社区配送时段""" try: # 查询社区配送时段 community_time_period = db.query(CommunityTimePeriodDB).filter( CommunityTimePeriodDB.id == community_time_period_id ).first() if not community_time_period: return error_response(code=404, message="社区配送时段不存在") # 更新运力 community_time_period.capacity = update_data.capacity db.commit() db.refresh(community_time_period) return success_response(message="社区配送时段更新成功", data=CommunityTimePeriodInfo.model_validate(community_time_period)) except Exception as e: db.rollback() logging.exception(f"更新社区配送时段失败: {str(e)}") return error_response(code=500, message="更新社区配送时段失败,请稍后重试") @router.delete("/{community_time_period_id}", response_model=ResponseModel) async def delete_community_time_period( community_time_period_id: int, db: Session = Depends(get_db), admin: UserDB = Depends(get_admin_user) ): """删除社区配送时段""" try: # 查询社区配送时段 community_time_period = db.query(CommunityTimePeriodDB).filter( CommunityTimePeriodDB.id == community_time_period_id ).first() if not community_time_period: return error_response(code=404, message="社区配送时段不存在") # 删除 db.delete(community_time_period) db.commit() return success_response(message="社区配送时段删除成功") except Exception as e: db.rollback() logging.exception(f"删除社区配送时段失败: {str(e)}") return error_response(code=500, message="删除社区配送时段失败,请稍后重试") # 根据社区进行 group 的配送时段列表 @router.get("/group_by_community", response_model=ResponseModel) async def get_group_by_community( skip: int = 0, limit: int = 10, db: Session = Depends(get_db) ): """根据社区进行 group 的配送时段列表""" try: #1. 查询有配送时段数据的社区 community_time_periods = db.query(CommunityTimePeriodDB).all() communities = db.query(CommunityDB).offset(skip).limit(limit).all() #2. 查询社区的配送时段 community_time_periods = db.query(CommunityTimePeriodDB, TimePeriodDB.name.label("time_period_name"),TimePeriodDB.from_time.label("time_period_from_time"), TimePeriodDB.to_time.label("time_period_to_time")).join(TimePeriodDB).filter( CommunityTimePeriodDB.community_id.in_([community.id for community in communities]) ).all() #3. 根据社区进行 group 的配送时段列表 communities_with_time_periods = [] for community in communities: community_time_periods = [ctp for ctp in community_time_periods if ctp.CommunityTimePeriodDB.community_id == community.id] communities_with_time_periods.append({ "community_id": community.id, "community_name": community.name, "time_periods": [{ "time_period_name": ctp.time_period_name, "time_period_from_time": ctp.time_period_from_time, "time_period_to_time": ctp.time_period_to_time, "capacity": ctp.CommunityTimePeriodDB.capacity } for ctp in community_time_periods] }) return success_response(data=communities_with_time_periods) except Exception as e: logging.exception(f"获取社区配送时段列表失败: {str(e)}") return error_response(code=500, message="获取社区配送时段列表失败,请稍后重试")