增加社区配送时段的接口
This commit is contained in:
parent
1c7b4e85bd
commit
a2c248ff4d
242
app/api/endpoints/community_timeperiod.py
Normal file
242
app/api/endpoints/community_timeperiod.py
Normal file
@ -0,0 +1,242 @@
|
||||
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
|
||||
|
||||
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).filter(
|
||||
CommunityTimePeriodDB.community_id == community_id
|
||||
).all()
|
||||
|
||||
# 获取时段详情
|
||||
result = []
|
||||
for ctp in community_time_periods:
|
||||
time_period = db.query(TimePeriodDB).filter(TimePeriodDB.id == ctp.time_period_id).first()
|
||||
if time_period:
|
||||
ctp_info = CommunityTimePeriodWithDetail.model_validate(ctp)
|
||||
ctp_info.time_period = TimePeriodInfo.model_validate(time_period)
|
||||
result.append(ctp_info)
|
||||
|
||||
# 按时段开始时间排序
|
||||
result.sort(key=lambda x: x.time_period.from_time if x.time_period else None)
|
||||
|
||||
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="获取社区配送时段列表失败,请稍后重试")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -334,7 +334,12 @@ async def create_order(
|
||||
|
||||
# 添加到新订单队列
|
||||
if db_order.address_community_id:
|
||||
redis_client.push_order_to_queue(db_order.address_community_id, db_order.orderid)
|
||||
background_tasks.add_task(
|
||||
redis_client.push_order_to_queue,
|
||||
db_order.address_community_id,
|
||||
db_order.orderid,
|
||||
db
|
||||
)
|
||||
|
||||
return success_response(
|
||||
message="订单创建成功",
|
||||
@ -1362,19 +1367,6 @@ async def deliveryman_order_summary(
|
||||
"yesterday_count": yesterday_total,
|
||||
"today_count": today_total
|
||||
})
|
||||
|
||||
@router.get("/deliveryman/new_orders_checked", response_model=ResponseModel)
|
||||
async def deliveryman_new_orders_checked(
|
||||
db: Session = Depends(get_db),
|
||||
deliveryman: UserDB = Depends(get_deliveryman_user)
|
||||
):
|
||||
"""获取新订单已检查标记"""
|
||||
success = redis_client.remove_orders(deliveryman.community_id)
|
||||
|
||||
return success_response(data={
|
||||
"message": "新订单已检查标记已移除",
|
||||
"success": success
|
||||
})
|
||||
|
||||
|
||||
@router.get("/deliveryman/check_new_order", response_model=ResponseModel)
|
||||
@ -1385,7 +1377,7 @@ async def deliveryman_check_new_orders(
|
||||
"""检查新订单"""
|
||||
|
||||
# 从Redis获取新订单ID列表
|
||||
order_ids = redis_client.get_orders_from_queue(deliveryman.community_id, 10)
|
||||
order_ids = redis_client.pop_orders_from_queue(deliveryman.userid, deliveryman.community_id, 10)
|
||||
|
||||
if not order_ids:
|
||||
return success_response(data={
|
||||
|
||||
@ -3,7 +3,8 @@ import json
|
||||
import logging
|
||||
from app.core.config import settings
|
||||
from typing import List, Dict, Any, Optional
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from app.models.user import UserDB
|
||||
class RedisClient:
|
||||
"""Redis 客户端"""
|
||||
|
||||
@ -32,11 +33,12 @@ class RedisClient:
|
||||
"""获取 Redis 客户端"""
|
||||
return self.client
|
||||
|
||||
def push_order_to_queue(self, community_id: int, order_id: str) -> bool:
|
||||
def push_order_to_queue(self, community_id: int, order_id: str, db: Session) -> bool:
|
||||
"""
|
||||
添加新订单到社区队列
|
||||
|
||||
Args:
|
||||
Args:
|
||||
user_id: 用户ID
|
||||
community_id: 社区ID
|
||||
order_id: 订单ID
|
||||
|
||||
@ -44,21 +46,25 @@ class RedisClient:
|
||||
bool: 是否添加成功
|
||||
"""
|
||||
try:
|
||||
key = f"community:{community_id}:new_orders"
|
||||
# 使用 LPUSH 将订单ID添加到列表头部
|
||||
self.client.lpush(key, order_id)
|
||||
# 设置过期时间为24小时
|
||||
self.client.expire(key, 86400)
|
||||
# 查询所有社区的用户
|
||||
users = db.query(UserDB).filter(UserDB.community_id == community_id).all()
|
||||
for user in users:
|
||||
key = f"user:{user.userid}:community:{community_id}:new_orders"
|
||||
# 使用 LPUSH 将订单ID添加到列表头部
|
||||
self.client.lpush(key, order_id)
|
||||
# 设置过期时间为24小时
|
||||
self.client.expire(key, 86400)
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error(f"添加新订单到队列失败: {str(e)}")
|
||||
return False
|
||||
|
||||
def get_orders_from_queue(self, community_id: int, count: int = 10) -> List[str]:
|
||||
def pop_orders_from_queue(self, user_id: int, community_id: int, count: int = 10) -> List[str]:
|
||||
"""
|
||||
获取社区新订单列表
|
||||
|
||||
Args:
|
||||
user_id: 用户ID
|
||||
community_id: 社区ID
|
||||
count: 获取数量,默认10个
|
||||
|
||||
@ -66,32 +72,13 @@ class RedisClient:
|
||||
List[str]: 订单ID列表
|
||||
"""
|
||||
try:
|
||||
key = f"community:{community_id}:new_orders"
|
||||
# 获取订单列表,并不移除
|
||||
orders = self.client.lrange(key, 0, count-1)
|
||||
key = f"user:{user_id}:community:{community_id}:new_orders"
|
||||
# 获取订单列表,
|
||||
orders = self.client.lpop(key, count)
|
||||
return orders
|
||||
except Exception as e:
|
||||
logging.error(f"获取社区新订单列表失败: {str(e)}")
|
||||
return []
|
||||
|
||||
def remove_orders(self, community_id: int) -> bool:
|
||||
"""
|
||||
从社区队列中移除订单
|
||||
|
||||
Args:
|
||||
community_id: 社区ID
|
||||
|
||||
Returns:
|
||||
bool: 是否移除成功
|
||||
"""
|
||||
try:
|
||||
key = f"community:{community_id}:new_orders"
|
||||
# 使用 ltrim 移除队列中的所有元素
|
||||
self.client.ltrim(key, 0, -1)
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error(f"从队列中移除订单失败: {str(e)}")
|
||||
return False
|
||||
|
||||
# 创建全局实例
|
||||
redis_client = RedisClient()
|
||||
@ -1,6 +1,6 @@
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from app.api.endpoints import wechat,user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_order, point, config, merchant_category, log, account,merchant_pay_order, message, bank_card, withdraw, mp, point_product, point_product_order, coupon_activity, ocr, dashboard, wecom, feedback, timeperiod
|
||||
from app.api.endpoints import wechat,user, address, community, station, order, coupon, community_building, upload, merchant, merchant_product, merchant_order, point, config, merchant_category, log, account,merchant_pay_order, message, bank_card, withdraw, mp, point_product, point_product_order, coupon_activity, ocr, dashboard, wecom, feedback, timeperiod, community_timeperiod
|
||||
from app.models.database import Base, engine
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
@ -77,6 +77,7 @@ app.include_router(log.router, prefix="/api/logs", tags=["系统日志"])
|
||||
app.include_router(ocr.router, prefix="/api/ai/ocr", tags=["图像识别"])
|
||||
app.include_router(feedback.router, prefix="/api/feedback", tags=["反馈"])
|
||||
app.include_router(timeperiod.router, prefix="/api/time-periods", tags=["配送时段"])
|
||||
app.include_router(community_timeperiod.router, prefix="/api/community-time-periods", tags=["社区配送时段"])
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
|
||||
56
app/models/community_timeperiod.py
Normal file
56
app/models/community_timeperiod.py
Normal file
@ -0,0 +1,56 @@
|
||||
from sqlalchemy import Column, Integer, ForeignKey, DateTime, UniqueConstraint
|
||||
from sqlalchemy.sql import func
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional, List
|
||||
from datetime import datetime
|
||||
from .database import Base
|
||||
from .timeperiod import TimePeriodInfo
|
||||
|
||||
# 数据库模型
|
||||
class CommunityTimePeriodDB(Base):
|
||||
"""社区配送时段关联表"""
|
||||
__tablename__ = "community_time_periods"
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
community_id = Column(Integer, ForeignKey("communities.id"), nullable=False, index=True)
|
||||
time_period_id = Column(Integer, ForeignKey("time_periods.id"), nullable=False)
|
||||
capacity = Column(Integer, default=0, nullable=False) # 运力(订单量),0表示无限制
|
||||
create_time = Column(DateTime(timezone=True), server_default=func.now())
|
||||
update_time = Column(DateTime(timezone=True), onupdate=func.now())
|
||||
|
||||
# 确保每个社区的每个时段只有一条记录
|
||||
__table_args__ = (
|
||||
UniqueConstraint('community_id', 'time_period_id', name='uix_community_time_period'),
|
||||
)
|
||||
|
||||
# Pydantic 模型
|
||||
class CommunityTimePeriodCreate(BaseModel):
|
||||
community_id: int = Field(..., description="社区ID")
|
||||
time_period_id: int = Field(..., description="配送时段ID")
|
||||
capacity: int = Field(0, description="运力(订单量),0表示无限制")
|
||||
|
||||
class CommunityTimePeriodUpdate(BaseModel):
|
||||
capacity: int = Field(..., description="运力(订单量),0表示无限制")
|
||||
|
||||
class CommunityTimePeriodInfo(BaseModel):
|
||||
id: int
|
||||
community_id: int
|
||||
time_period_id: int
|
||||
capacity: int
|
||||
create_time: datetime
|
||||
update_time: Optional[datetime] = None
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
|
||||
class CommunityTimePeriodWithDetail(CommunityTimePeriodInfo):
|
||||
time_period: Optional[TimePeriodInfo] = None
|
||||
|
||||
class CommunityTimePeriodWithCapacity(BaseModel):
|
||||
community_id: int
|
||||
time_period_id: int
|
||||
capacity: int
|
||||
|
||||
class CommunityTimePeriodBatchCreate(BaseModel):
|
||||
community_id: int = Field(..., description="社区ID")
|
||||
time_period_capacity_list: List[CommunityTimePeriodWithCapacity] = Field(..., description="配送时段ID列表")
|
||||
Loading…
Reference in New Issue
Block a user