From 6ca1bc0ef315170cb84ac9158d1b58a90edcd1e4 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Sun, 5 Jan 2025 11:43:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E8=AE=A1=E7=AE=97=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E4=BB=B7=E6=A0=BC=E7=9A=84=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 | 53 ++++++++++++++++++++++++++++++++++++-- app/core/config.py | 6 ++++- app/models/order.py | 18 ++++++++++--- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/app/api/endpoints/order.py b/app/api/endpoints/order.py index 519275a..2c0750d 100644 --- a/app/api/endpoints/order.py +++ b/app/api/endpoints/order.py @@ -7,7 +7,9 @@ from app.models.order import ( OrderCreate, OrderInfo, OrderPackageInfo, - generate_order_id + generate_order_id, + OrderPriceCalculateRequest, + OrderPriceInfo ) from app.models.database import get_db from app.api.deps import get_current_user @@ -15,6 +17,7 @@ from app.models.user import UserDB from app.core.response import success_response, error_response, ResponseModel from app.models.coupon import UserCouponDB, CouponStatus from datetime import datetime, timezone +from app.core.config import settings router = APIRouter() @@ -132,4 +135,50 @@ async def get_user_orders( ShippingOrderDB.create_time.desc() ).offset(skip).limit(limit).all() - return success_response(data=[OrderInfo.model_validate(o) for o in orders]) \ No newline at end of file + return success_response(data=[OrderInfo.model_validate(o) for o in orders]) + +@router.post("/calculate-price", response_model=ResponseModel) +async def calculate_order_price( + request: OrderPriceCalculateRequest, + db: Session = Depends(get_db), + current_user: UserDB = Depends(get_current_user) +): + """计算订单价格""" + package_count = len(request.packages) + + # 计算原始金额 + original_amount = settings.ORDER_BASE_PRICE + if package_count > settings.ORDER_EXTRA_PACKAGE_THRESHOLD: + extra_packages = package_count - settings.ORDER_EXTRA_PACKAGE_THRESHOLD + original_amount += extra_packages * settings.ORDER_EXTRA_PACKAGE_PRICE + + # 计算优惠券折扣 + coupon_discount = 0 + used_coupon_id = None + + # 查询用户所有可用的优惠券 + available_coupons = db.query(UserCouponDB).filter( + UserCouponDB.user_id == current_user.userid, + UserCouponDB.status == CouponStatus.UNUSED + ).order_by( + UserCouponDB.coupon_amount.desc() # 优先使用面额大的优惠券 + ).all() + + # 选择最优惠的券 + if available_coupons: + user_coupon = available_coupons[0] # 取面额最大的优惠券 + coupon_discount = user_coupon.coupon_amount + used_coupon_id = user_coupon.id + + # 计算最终金额 + final_amount = max(0, original_amount - coupon_discount) + + price_info = OrderPriceInfo( + package_count=package_count, + original_amount=original_amount, + coupon_discount_amount=coupon_discount, + coupon_id=used_coupon_id, + final_amount=final_amount + ) + + return success_response(data=price_info) \ No newline at end of file diff --git a/app/core/config.py b/app/core/config.py index eb5c3aa..e769c39 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -6,7 +6,11 @@ class Settings(BaseSettings): API_V1_STR: str = "/api/v1" PROJECT_NAME: str = "FastAPI 项目" - + # 订单价格配置 + ORDER_BASE_PRICE: float = 3.0 # 基础费用 + ORDER_EXTRA_PACKAGE_PRICE: float = 0.5 # 额外包裹费用 + ORDER_EXTRA_PACKAGE_THRESHOLD: int = 5 # 额外收费阈值 + # JWT 配置 SECRET_KEY: str = "your-secret-key-here" ACCESS_TOKEN_EXPIRE_MINUTES: Optional[int] = None # None 表示永不过期 diff --git a/app/models/order.py b/app/models/order.py index 4f66c66..5e3c03f 100644 --- a/app/models/order.py +++ b/app/models/order.py @@ -67,6 +67,18 @@ class OrderPackageInfo(BaseModel): def generate_order_id() -> str: """生成订单号:日期+时间戳""" now = datetime.now() - date_str = now.strftime('%Y%m%d') - timestamp = int(now.timestamp() * 1000) - return f"{date_str}{timestamp}" \ No newline at end of file + # 生成8位日期 + 6位序号,共14位 + date_str = now.strftime('%Y%m%d') # 8位日期 + # 生成6位序号(毫秒级时间戳后6位) + timestamp = str(int(now.timestamp() * 1000))[-6:] + return f"{date_str}{timestamp}" + +class OrderPriceCalculateRequest(BaseModel): + packages: List[OrderPackage] + +class OrderPriceInfo(BaseModel): + package_count: int + original_amount: float + coupon_discount_amount: float + coupon_id: Optional[int] = None + final_amount: float \ No newline at end of file