from fastapi import APIRouter, Depends, Query from sqlalchemy.orm import Session from app.models.point_product_order import ( PointProductOrderDB, PointProductOrderCreate, PointProductOrderInfo, PointProductOrderStatus ) from app.models.point_product import PointProductDB from app.models.database import get_db from app.api.deps import get_current_user, get_admin_user, get_deliveryman_user from app.models.user import UserDB from app.core.response import success_response, error_response, ResponseModel from app.core.point_manager import PointManager from typing import Optional from datetime import datetime from app.models.order import ShippingOrderDB, OrderStatus router = APIRouter() @router.get("/pre_order", response_model=ResponseModel) async def pre_order( order: PointProductOrderCreate, db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """预下单""" # 检查今日是否有配送订单 orders = db.query(ShippingOrderDB).filter( ShippingOrderDB.userid == current_user.userid, ShippingOrderDB.status.in_([OrderStatus.CREATED, OrderStatus.RECEIVED]), ShippingOrderDB.create_time.date() == datetime.now().date() ).all() if len(orders) == 0: return error_response(code=400, message="今日暂无配送订单") product = db.query(PointProductDB).filter( PointProductDB.id == order.product_id, PointProductDB.is_active == True ).first() if not product: return error_response(code=404, message="商品不存在或已下架") # 计算所需总积分 order_point_amount = product.point_amount * order.quantity return success_response(data={ "order_point_amount": order_point_amount, "orders": orders }) @router.post("", response_model=ResponseModel) async def create_point_product_order( order: PointProductOrderCreate, db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """创建积分商品订单""" # 查询商品信息 product = db.query(PointProductDB).filter( PointProductDB.id == order.product_id, PointProductDB.is_active == True ).first() if not product: return error_response(code=404, message="商品不存在或已下架") # 计算所需总积分 total_points = product.point_amount * order.quantity # 检查用户积分是否足够 if current_user.points < total_points: return error_response(code=400, message="积分不足") # 检查配送订单是否存在 if order.delivery_order_id is None: return error_response(code=400, message="配送订单不能为空") delivery_order = db.query(ShippingOrderDB).filter( ShippingOrderDB.orderid == order.delivery_order_id, ShippingOrderDB.status.in_([OrderStatus.CREATED, OrderStatus.RECEIVED]), ShippingOrderDB.create_time.date() == datetime.now().date() ).first() if not delivery_order: return error_response(code=404, message="配送订单不存在") # 检查配送订单是否已支付 if delivery_order.status != OrderStatus.UNPAID: return error_response(code=400, message="配送订单已支付") # 创建订单 db_order = PointProductOrderDB( orderid=PointProductOrderDB.generate_order_id(), user_id=current_user.userid, product_id=product.id, product_name=product.name, product_image=product.product_image, product_description=product.description, product_point_amount=product.point_amount, quantity=order.quantity, order_point_amount=total_points, delivery_order_id=order.delivery_order_id, status=PointProductOrderStatus.PENDING ) try: # 保存订单 db.add(db_order) db.commit() db.refresh(db_order) # 扣减用户积分 point_manager = PointManager(db) point_manager.deduct_points( user_id=current_user.userid, points=total_points, description=f"兑换积分商品", order_id=db_order.orderid ) return success_response(data=PointProductOrderInfo.model_validate(db_order)) except Exception as e: db.rollback() return error_response(code=500, message=f"创建订单失败: {str(e)}") @router.get("", response_model=ResponseModel) async def get_point_product_orders( status: Optional[PointProductOrderStatus] = None, skip: int = Query(0, ge=0), limit: int = Query(20, ge=1, le=100), db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """获取积分商品订单列表""" query = db.query(PointProductOrderDB).filter( PointProductOrderDB.user_id == current_user.userid ) if status: query = query.filter(PointProductOrderDB.status == status) total = query.count() orders = query.order_by(PointProductOrderDB.create_time.desc())\ .offset(skip)\ .limit(limit)\ .all() return success_response(data={ "total": total, "items": [PointProductOrderInfo.model_validate(o) for o in orders] }) @router.get("/{orderid}", response_model=ResponseModel) async def get_point_product_order( orderid: str, db: Session = Depends(get_db), current_user: UserDB = Depends(get_current_user) ): """获取积分商品订单详情""" order = db.query(PointProductOrderDB).filter( PointProductOrderDB.orderid == orderid, PointProductOrderDB.user_id == current_user.userid ).first() if not order: return error_response(code=404, message="订单不存在") return success_response(data=PointProductOrderInfo.model_validate(order)) # 接受订单 @router.post("/{orderid}/accept", response_model=ResponseModel) async def accept_point_product_order( orderid: str, db: Session = Depends(get_db), deliveryman: UserDB = Depends(get_deliveryman_user) ): order = db.query(PointProductOrderDB).filter( PointProductOrderDB.orderid == orderid, PointProductOrderDB.status == PointProductOrderStatus.PENDING ).first() if not order: return error_response(code=404, message="订单不存在") if order.status != PointProductOrderStatus.PENDING: return error_response(code=400, message="订单状态不正确") # 更新订单状态 order.status = PointProductOrderStatus.CONFIRMED db.commit() db.refresh(order) return success_response(data=PointProductOrderInfo.model_validate(order)) # 拒绝订单 @router.post("/{orderid}/reject", response_model=ResponseModel) async def reject_point_product_order( orderid: str, db: Session = Depends(get_db), deliveryman: UserDB = Depends(get_deliveryman_user) ): order = db.query(PointProductOrderDB).filter( PointProductOrderDB.orderid == orderid, PointProductOrderDB.status == PointProductOrderStatus.PENDING ).first() if not order: return error_response(code=404, message="订单不存在") if order.status != PointProductOrderStatus.PENDING: return error_response(code=400, message="订单状态不正确") # 更新订单状态 order.status = PointProductOrderStatus.CANCELLED db.commit() db.refresh(order) return success_response(data=PointProductOrderInfo.model_validate(order))