deliveryman-api/app/models/order.py
2025-01-11 23:25:45 +08:00

120 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from datetime import datetime
from typing import Optional, List
from sqlalchemy import Column, String, Integer, Float, DateTime, ForeignKey, Enum
from sqlalchemy.sql import func
from pydantic import BaseModel, Field
from .database import Base
import enum
class OrderStatus(str, enum.Enum):
CREATED = "created" # 已下单
ACCEPTED = "accepted" # 已接单
UNPAID = "unpaid" # 未支付
COMPLETED = "completed" # 已完成
CANCELLED = "cancelled" # 已取消
class DeliveryMethod(str, enum.Enum):
DELIVERY_TO_DOOR = "delivery_to_door" # 放在门口
DELIVERY_TO_ROOM = "delivery_to_room" # 投递到家
# 数据库模型
class ShippingOrderDB(Base):
__tablename__ = "shipping_orders"
orderid = Column(String(32), primary_key=True)
userid = Column(Integer, ForeignKey("users.userid"), index=True)
addressid = Column(Integer, ForeignKey("delivery_addresses.id"), index=True)
package_count = Column(Integer, nullable=False)
original_amount = Column(Float, nullable=False)
coupon_discount_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)
cancel_reason = Column(String(200), nullable=True) # 取消原因
complete_images = Column(String(1000), nullable=True) # 完成订单的图片URL多个URL用逗号分隔
create_time = Column(DateTime(timezone=True), server_default=func.now())
delivery_method = Column(Enum(DeliveryMethod), nullable=False, default=DeliveryMethod.DELIVERY_TO_DOOR)
class ShippingOrderPackageDB(Base):
__tablename__ = "shipping_order_packages"
id = Column(Integer, primary_key=True, autoincrement=True)
orderid = Column(String(32), ForeignKey("shipping_orders.orderid"), index=True)
station_id = Column(Integer, ForeignKey("stations.id"), index=True)
pickup_codes = Column(String(100), nullable=False)
create_time = Column(DateTime(timezone=True), server_default=func.now())
# Pydantic 模型
class OrderPackage(BaseModel):
station_id: int
pickup_codes: str = Field(..., max_length=100)
# 先定义 OrderPriceCalculateRequest
class OrderPriceCalculateRequest(BaseModel):
packages: List[OrderPackage]
# 然后再定义 OrderCreate
class OrderCreate(BaseModel):
addressid: int
price_request: OrderPriceCalculateRequest
delivery_method: DeliveryMethod = Field(
default=DeliveryMethod.DELIVERY_TO_DOOR,
description="配送方式:放在门口或投递到家"
)
class OrderInfo(BaseModel):
orderid: str
userid: int
addressid: int
package_count: int
original_amount: float
coupon_discount_amount: float
coupon_id: Optional[int]
final_amount: float
status: OrderStatus
complete_images: Optional[List[str]] = None
create_time: datetime
delivery_method: DeliveryMethod
def __init__(self, **data):
super().__init__(**data)
# 将逗号分隔的图片URL字符串转换为列表
if self.complete_images and isinstance(self.complete_images, str):
self.complete_images = self.complete_images.split(",")
class Config:
from_attributes = True
class OrderPackageInfo(BaseModel):
id: int
orderid: str
station_id: int
pickup_codes: str
create_time: datetime
class Config:
from_attributes = True
def generate_order_id() -> str:
"""生成订单号:日期+时间戳"""
now = datetime.now()
# 生成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 OrderPriceInfo(BaseModel):
package_count: int
original_amount: float
coupon_discount_amount: float
coupon_id: Optional[int] = None
final_amount: float
# 添加取消订单请求模型
class OrderCancel(BaseModel):
reason: str = Field(..., max_length=200, description="取消原因")
# 完成订单请求模型
class OrderComplete(BaseModel):
images: Optional[List[str]] = Field(None, max_items=5) # 最多5张图片可选