From ff318a8dfd9eb1d692ea4b4587b9a4cde05969e3 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 13 Feb 2025 12:06:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=96=E6=B6=88=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/order.py | 133 +++++++++++++++++++++++++++++-------- app/models/order.py | 4 +- 2 files changed, 109 insertions(+), 28 deletions(-) diff --git a/app/api/endpoints/order.py b/app/api/endpoints/order.py index 9330ac5..ee4cd63 100644 --- a/app/api/endpoints/order.py +++ b/app/api/endpoints/order.py @@ -91,13 +91,13 @@ def calculate_price(price_request: OrderPriceCalculateRequest,user: UserDB,db: S # 3. 如果没有优惠券,且用户有积分,则使用积分抵扣 elif user.points > 0: # 计算最大可抵扣金额(1元=10积分) - max_points_discount = user.points / 10 - points_discount = min(remaining_amount, max_points_discount) + max_points_discount = user.points / settings.POINT_RATIO + points_discount_amount = min(remaining_amount, max_points_discount) - result.price_info.points_discount_amount = points_discount - result.price_info.points_used = int(points_discount * 10) - result.used_points = int(points_discount * 10) # 记录使用的积分数 - remaining_amount -= points_discount + result.price_info.points_discount_amount = points_discount_amount + result.price_info.points_used = float(points_discount_amount * settings.POINT_RATIO) + result.used_points = float(points_discount_amount * settings.POINT_RATIO) # 记录使用的积分数 + remaining_amount -= points_discount_amount # 计算最终金额 result.price_info.final_amount = remaining_amount @@ -407,6 +407,67 @@ async def get_user_orders( except Exception as e: return error_response(code=500, message=f"获取订单列表失败: {str(e)}") + +@router.post("/{orderid}/user/cancel", response_model=ResponseModel) +async def cancel_order( + orderid: str, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """取消订单""" + # 查询订单 + order = db.query(ShippingOrderDB).filter( + ShippingOrderDB.orderid == orderid, + ShippingOrderDB.userid == current_user.userid + ).first() + + if not order: + return error_response(code=404, message="订单不存在") + + # 检查订单状态是否可取消 + if order.status not in [OrderStatus.CREATED, OrderStatus.RECEIVED]: + return error_response(code=400, message="当前订单状态不可取消") + + try: + # 更新订单状态、取消原因和取消用户 + order.status = OrderStatus.CANCELLED + order.cancel_reason = "用户主动取消" + order.cancel_user_id = current_user.userid # 记录取消订单的用户ID + + # 如果使用了优惠券,返还优惠券 + if order.coupon_id: + coupon = db.query(UserCouponDB).filter( + UserCouponDB.id == order.coupon_id + ).first() + if coupon: + coupon.status = CouponStatus.UNUSED + + # 如果使用了积分,返还积分 + if order.point_discount_amount > 0: + # 返还积分 + return_points = order.point_discount_amount * settings.POINT_RATIO + current_user.points += return_points + + # 记录积分变动 + point_record = PointRecordDB( + user_id=current_user.userid, + points=return_points, + type=PointRecordType.CONSUME_RETURN, + order_id=order.orderid, + description=f"订单取消返还积分" + ) + db.add(point_record) + + db.commit() + return success_response( + message="订单取消成功", + data=OrderInfo.model_validate(order) + ) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"取消订单失败: {str(e)}") + + @router.get("/deliveryman/list", response_model=ResponseModel) async def get_deliveryman_orders( status: Optional[OrderStatus] = None, @@ -500,33 +561,32 @@ async def get_deliveryman_orders( "items": orders }) -@router.post("/{orderid}/cancel", response_model=ResponseModel) -async def cancel_order( +@router.post("/{orderid}/deliveryman/cancel", response_model=ResponseModel) +async def deliveryman_cancel_order( orderid: str, cancel_data: OrderCancel, db: Session = Depends(get_db), - current_user: UserDB = Depends(get_current_user) + deliveryman: UserDB = Depends(get_deliveryman_user) ): - """取消订单""" - # 查询订单 + """配送员取消订单""" order = db.query(ShippingOrderDB).filter( ShippingOrderDB.orderid == orderid, - ShippingOrderDB.userid == current_user.userid + ShippingOrderDB.deliveryman_user_id == deliveryman.userid ).first() if not order: return error_response(code=404, message="订单不存在") - # 检查订单状态是否可取消 - if order.status not in [OrderStatus.CREATED, OrderStatus.RECEIVED]: - return error_response(code=400, message="当前订单状态不可取消") + # 检查订单状态 + if order.status != OrderStatus.CREATED and order.status != OrderStatus.RECEIVED: + return error_response(code=400, message="只有未接单或者已接单的订单才能取消") try: # 更新订单状态、取消原因和取消用户 order.status = OrderStatus.CANCELLED order.cancel_reason = cancel_data.reason - order.cancel_user_id = current_user.userid # 记录取消订单的用户ID - + order.cancel_user_id = deliveryman.userid + # 如果使用了优惠券,返还优惠券 if order.coupon_id: coupon = db.query(UserCouponDB).filter( @@ -534,36 +594,57 @@ async def cancel_order( ).first() if coupon: coupon.status = CouponStatus.UNUSED + + # 如果使用了积分,返还积分 + if order.point_discount_amount > 0: + # 返还积分 + return_points = order.point_discount_amount * settings.POINT_RATIO + + order_user = db.query(UserDB).filter( + UserDB.userid == order.userid + ).first() + + order_user.points += return_points + + # 记录积分变动 + point_record = PointRecordDB( + user_id=order_user.userid, + points=return_points, + type=PointRecordType.CONSUME_RETURN, + order_id=order.orderid, + description=f"订单取消返还积分" + ) + db.add(point_record) db.commit() return success_response( message="订单取消成功", data=OrderInfo.model_validate(order) - ) + ) except Exception as e: db.rollback() - return error_response(code=500, message=f"取消订单失败: {str(e)}") + return error_response(code=500, message=f"取消订单失败: {str(e)}") -@router.post("/{orderid}/complete", response_model=ResponseModel) +@router.post("/{orderid}/deliveryman/complete", response_model=ResponseModel) async def complete_order( orderid: str, complete_data: OrderComplete, db: Session = Depends(get_db), - current_user: UserDB = Depends(get_current_user) + current_user: UserDB = Depends(get_deliveryman_user) ): """完成订单""" # 查询订单 order = db.query(ShippingOrderDB).filter( ShippingOrderDB.orderid == orderid, - ShippingOrderDB.userid == current_user.userid + ShippingOrderDB.deliveryman_user_id == current_user.userid ).first() if not order: return error_response(code=404, message="订单不存在") # 检查订单状态 - if order.status != OrderStatus.RECEIVED: - return error_response(code=400, message="只有已接单的订单才能标记为完成") + if order.status != OrderStatus.DELIVERING: + return error_response(code=400, message="只有配送中的订单才能标记为完成") try: # 根据订单金额决定状态 @@ -598,7 +679,7 @@ async def complete_order( db.rollback() return error_response(code=500, message=f"操作失败: {str(e)}") -@router.post("/{orderid}/receive", response_model=ResponseModel) +@router.post("/{orderid}/deliveryman/receive", response_model=ResponseModel) async def receive_order( orderid: str, db: Session = Depends(get_db), @@ -635,7 +716,7 @@ async def receive_order( db.rollback() return error_response(code=500, message=f"接单失败: {str(e)}") -@router.post("/{orderid}/pickup", response_model=ResponseModel) +@router.post("/{orderid}/deliveryman/pickup", response_model=ResponseModel) async def pickup_order( orderid: str, db: Session = Depends(get_db), diff --git a/app/models/order.py b/app/models/order.py index 6714015..b85c25d 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -124,7 +124,7 @@ class OrderPriceInfo(BaseModel): original_amount: float coupon_discount_amount: float = 0 points_discount_amount: float = 0 - points_used: Optional[int] = None + points_used: Optional[float] = None coupon_id: Optional[int] = None final_amount: float @@ -140,5 +140,5 @@ class OrderPriceResult(BaseModel): """订单价格计算结果""" price_info: OrderPriceInfo used_coupon_id: Optional[int] = None # 使用的优惠券ID - used_points: Optional[int] = None # 使用的积分数 + used_points: Optional[float] = None # 使用的积分数 price_detail_text: Optional[str] = None # 价格详情文本 \ No newline at end of file