deliveryman-api/app/api/endpoints/community_timeperiod.py
2025-03-11 00:35:51 +08:00

285 lines
12 KiB
Python

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, CommunityTimePeriodDB.time_period_id == TimePeriodDB.id)\
.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)
# 当前时间 < 配送时段结束时间前半小时 #datetime.time数据类型是 time
dt = datetime.combine(datetime.today(), ctp.time_period_to_time)
dt = dt - timedelta(hours=0.5)
if datetime.now().time() > dt.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:
communities = db.query(CommunityDB).offset(skip).limit(limit).all()
#3. 根据社区进行 group 的配送时段列表
communities_with_time_periods = []
for community in communities:
# 查询配送时段
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
).all()
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="获取社区配送时段列表失败,请稍后重试")