From 5ca85d9edbfed94e68b1e9e01f8c502217b43cdb Mon Sep 17 00:00:00 2001 From: aaron <> Date: Fri, 7 Mar 2025 01:02:59 +0800 Subject: [PATCH] update --- app/api/endpoints/order_additional_fee.py | 178 ++++++++++++++++++++++ app/main.py | 8 +- app/models/order.py | 10 +- app/models/order_additional_fee.py | 54 +++++++ 4 files changed, 243 insertions(+), 7 deletions(-) create mode 100644 app/api/endpoints/order_additional_fee.py create mode 100644 app/models/order_additional_fee.py diff --git a/app/api/endpoints/order_additional_fee.py b/app/api/endpoints/order_additional_fee.py new file mode 100644 index 0000000..3430333 --- /dev/null +++ b/app/api/endpoints/order_additional_fee.py @@ -0,0 +1,178 @@ +from fastapi import APIRouter, Depends, Query +from sqlalchemy.orm import Session +from app.models.order_additional_fee import ( + OrderAdditionalFeeDB, + OrderAdditionalFeeCreate, + OrderAdditionalFeeUpdate, + OrderAdditionalFeeInfo, + AdditionalFeeResult +) +from app.models.order import ShippingOrderDB, OrderStatus +from app.models.database import get_db +from app.api.deps import get_current_user, get_deliveryman_user +from app.models.user import UserDB +from app.core.response import success_response, error_response, ResponseModel +from typing import List, Optional +from datetime import datetime +import aiohttp +from app.core.config import settings + +router = APIRouter() + +@router.post("", response_model=ResponseModel) +async def create_additional_fee_request( + fee_request: OrderAdditionalFeeCreate, + db: Session = Depends(get_db), + deliveryman: UserDB = Depends(get_deliveryman_user) +): + """创建加价请求(配送员)""" + # 检查订单是否存在 + order = db.query(ShippingOrderDB).filter( + ShippingOrderDB.orderid == fee_request.orderid + ).first() + + if not order: + return error_response(code=404, message="订单不存在") + + # 检查是否是该订单的配送员 + if order.deliveryman_user_id != deliveryman.userid: + return error_response(code=403, message="您不是该订单的配送员") + + # 检查是否已经有未处理的加价请求 + existing_request = db.query(OrderAdditionalFeeDB).filter( + OrderAdditionalFeeDB.orderid == fee_request.orderid + ).first() + + if existing_request: + return error_response(code=400, message="该订单已有未处理的加价请求") + + # 创建加价请求 + db_fee_request = OrderAdditionalFeeDB( + orderid=fee_request.orderid, + order_user_id=order.userid, + deliveryman_id=deliveryman.userid, + reason=fee_request.reason, + photo_urls=fee_request.photo_urls, + additional_fee_amount=fee_request.additional_fee_amount, + result=AdditionalFeeResult.PENDING + ) + + db.add(db_fee_request) + + try: + db.commit() + db.refresh(db_fee_request) + + # TODO: 发送通知给用户 + + return success_response(data=OrderAdditionalFeeInfo.model_validate(db_fee_request)) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"创建加价请求失败: {str(e)}") + +@router.get("/order/{orderid}", response_model=ResponseModel) +async def get_order_additional_fees( + orderid: str, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """获取订单的加价请求列表""" + # 检查订单是否存在 + order = db.query(ShippingOrderDB).filter( + ShippingOrderDB.orderid == orderid + ).first() + + if not order: + return error_response(code=404, message="订单不存在") + + # 检查是否是订单相关人员 + if order.userid != current_user.userid and order.deliveryman_user_id != current_user.userid: + return error_response(code=403, message="您无权查看该订单的加价请求") + + # 获取加价请求列表 + fee_requests = db.query(OrderAdditionalFeeDB).filter( + OrderAdditionalFeeDB.orderid == orderid + ).order_by(OrderAdditionalFeeDB.create_time.desc()).all() + + return success_response(data=[ + OrderAdditionalFeeInfo.model_validate(req) for req in fee_requests + ]) + +@router.put("/{request_id}/accept", response_model=ResponseModel) +async def accept_additional_fee( + request_id: int, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """接受加价请求(用户)""" + # 获取加价请求 + fee_request = db.query(OrderAdditionalFeeDB).filter( + OrderAdditionalFeeDB.id == request_id + ).first() + + if not fee_request: + return error_response(code=404, message="加价请求不存在") + + # 检查是否是订单用户 + if fee_request.order_user_id != current_user.userid: + return error_response(code=403, message="您无权处理该加价请求") + + # 检查请求状态 + if fee_request.result != AdditionalFeeResult.PENDING: + return error_response(code=400, message="该加价请求已处理") + + # 更新请求状态 + fee_request.result = AdditionalFeeResult.ACCEPTED + + # 更新订单金额 + order = db.query(ShippingOrderDB).filter( + ShippingOrderDB.orderid == fee_request.orderid + ).first() + + if order: + order.additional_fee_amount = float(fee_request.additional_fee_amount) + order.final_amount = float(order.final_amount) + float(fee_request.additional_fee_amount) + + try: + db.commit() + + # TODO: 发送通知给配送员 + + return success_response(message="已接受加价请求") + except Exception as e: + db.rollback() + return error_response(code=500, message=f"处理加价请求失败: {str(e)}") + +# 更新加价请求 +@router.put("/{request_id}", response_model=ResponseModel) +async def update_additional_fee( + request_id: int, + fee_request: OrderAdditionalFeeUpdate, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """更新加价请求""" + # 获取加价请求 + fee_request = db.query(OrderAdditionalFeeDB).filter( + OrderAdditionalFeeDB.id == request_id + ).first() + + if not fee_request: + return error_response(code=404, message="加价请求不存在") + + # 检查是否是订单用户 + if fee_request.order_user_id != current_user.userid: + return error_response(code=403, message="您无权处理该加价请求") + + # 更新加价请求 + fee_request.reason = fee_request.reason + fee_request.photo_urls = fee_request.photo_urls + fee_request.additional_fee_amount = fee_request.additional_fee_amount + + try: + db.commit() + db.refresh(fee_request) + return success_response(data=OrderAdditionalFeeInfo.model_validate(fee_request)) + except Exception as e: + db.rollback() + return error_response(code=500, message=f"更新加价请求失败: {str(e)}") \ No newline at end of file diff --git a/app/main.py b/app/main.py index 586c72a..5c0ef3e 100644 --- a/app/main.py +++ b/app/main.py @@ -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, community_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, order_additional_fee from app.models.database import Base, engine from fastapi.exceptions import RequestValidationError from fastapi.responses import JSONResponse @@ -61,8 +61,11 @@ app.include_router(account.router, prefix="/api/account", tags=["账户"]) app.include_router(address.router, prefix="/api/address", tags=["配送地址"]) app.include_router(community.router, prefix="/api/community", tags=["社区"]) app.include_router(community_building.router, prefix="/api/community/building", tags=["社区楼栋"]) +app.include_router(timeperiod.router, prefix="/api/time-periods", tags=["配送时段"]) +app.include_router(community_timeperiod.router, prefix="/api/community-time-periods", tags=["社区配送时段"]) app.include_router(station.router, prefix="/api/station", tags=["驿站"]) app.include_router(order.router, prefix="/api/order", tags=["订单"]) +app.include_router(order_additional_fee.router, prefix="/api/order-additional-fee", tags=["订单加价"]) app.include_router(coupon.router, prefix="/api/coupon", tags=["抵扣券"]) app.include_router(coupon_activity.router, prefix="/api/coupon-activities", tags=["抵扣券活动"]) app.include_router(merchant.router, prefix="/api/merchant", tags=["商家"]) @@ -76,8 +79,7 @@ app.include_router(config.router, prefix="/api/config", tags=["系统配置"]) 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(): diff --git a/app/models/order.py b/app/models/order.py index ecc0d8e..3bc7be5 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -71,6 +71,7 @@ class ShippingOrderDB(Base): original_amount = Column(Float, nullable=False) coupon_discount_amount = Column(Float, default=0) point_discount_amount = Column(Float, default=0) + additional_fee_amount = Column(Float, default=0) coupon_id = Column(Integer, ForeignKey("user_coupons.id"), nullable=True) final_amount = Column(Float, nullable=False) status = Column(Enum(OrderStatus), nullable=False, default=OrderStatus.CREATED) @@ -161,11 +162,12 @@ class OrderInfo(BaseModel): pickup_images_count: int package_count: int pickup_code_count: int - original_amount: float - coupon_discount_amount: float + original_amount: float = 0 + coupon_discount_amount: float = 0 point_discount_amount: float = 0 - coupon_id: Optional[int] - final_amount: float + additional_fee_amount: float = 0 + coupon_id: Optional[int] = None + final_amount: float = 0 status: OrderStatus complete_images: Optional[str] = None optimized_complete_images: Optional[List[str]] = None diff --git a/app/models/order_additional_fee.py b/app/models/order_additional_fee.py new file mode 100644 index 0000000..13ac3af --- /dev/null +++ b/app/models/order_additional_fee.py @@ -0,0 +1,54 @@ +from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Enum, DECIMAL, JSON +from sqlalchemy.sql import func +from pydantic import BaseModel, Field +from typing import Optional, List +from datetime import datetime +from .database import Base +import enum + +class AdditionalFeeResult(str, enum.Enum): + PENDING = "PENDING" # 待处理 + ACCEPTED = "ACCEPTED" # 已接受 + REJECTED = "REJECTED" # 已拒绝 + +class OrderAdditionalFeeDB(Base): + __tablename__ = "order_additional_fees" + + id = Column(Integer, primary_key=True, autoincrement=True) + orderid = Column(String(32), ForeignKey("shipping_orders.orderid"), nullable=False, index=True) + order_user_id = Column(Integer, ForeignKey("users.userid"), nullable=False) + deliveryman_id = Column(Integer, ForeignKey("users.userid"), nullable=False) + reason = Column(String(200), nullable=False) + photo_urls = Column(JSON, nullable=True) # 存储照片URL的JSON数组 + additional_fee_amount = Column(DECIMAL(10, 2), nullable=False) + result = Column(Enum(AdditionalFeeResult), nullable=False, default=AdditionalFeeResult.PENDING) + create_time = Column(DateTime(timezone=True), server_default=func.now()) + update_time = Column(DateTime(timezone=True), onupdate=func.now()) + +# Pydantic 模型 +class OrderAdditionalFeeCreate(BaseModel): + orderid: str + reason: str = Field(..., max_length=200) + photo_urls: Optional[List[str]] = None + additional_fee_amount: float = Field(..., gt=0) + +class OrderAdditionalFeeUpdate(BaseModel): + id: int + reason: str + photo_urls: Optional[List[str]] + additional_fee_amount: float + +class OrderAdditionalFeeInfo(BaseModel): + id: int + orderid: str + order_user_id: int + deliveryman_id: int + reason: str + photo_urls: Optional[List[str]] + additional_fee_amount: float + result: AdditionalFeeResult + create_time: datetime + update_time: Optional[datetime] = None + + class Config: + from_attributes = True \ No newline at end of file