Files
zkxw/backend/app/schemas/order.py
T
2026-05-12 16:35:07 +08:00

340 lines
8.7 KiB
Python

"""Pydantic schemas - 订单管理"""
from pydantic import BaseModel, Field
from typing import Optional, List
from datetime import datetime
from decimal import Decimal
class OrderItemBase(BaseModel):
"""订单项基础字段"""
productId: str = Field(..., description="商品ID")
unitId: str = Field(..., description="单位ID")
quantity: Decimal = Field(..., description="数量")
unitPrice: Decimal = Field(..., description="单价")
class OrderItemCreate(OrderItemBase):
"""创建订单项请求"""
note: Optional[str] = None
class OrderItemResponse(BaseModel):
"""订单项响应"""
id: str
productId: str
productName: Optional[str] = None
unitId: str
unitName: Optional[str] = None
quantity: Decimal
unitPrice: Decimal
amount: Decimal
deliveredQuantity: Optional[Decimal] = None
status: str
class Config:
from_attributes = True
class OrderCreate(BaseModel):
"""创建订单请求"""
priceListId: str = Field(..., description="价格清单ID")
items: List[OrderItemCreate] = Field(..., description="订单项列表")
addressId: str = Field(..., description="配送地址ID")
paymentMethod: str = Field(..., description="支付方式: wechat/offline")
remark: Optional[str] = Field(None, description="备注")
class OrderPreviewRequest(BaseModel):
"""订单预览请求"""
priceListId: str = Field(..., description="价格清单ID")
items: List[dict] = Field(..., description="商品列表")
addressId: str = Field(..., description="配送地址ID")
class OrderResponse(BaseModel):
"""订单响应"""
id: str
orderNo: str
regionId: str
regionName: Optional[str] = None
clientId: str
clientName: Optional[str] = None
priceListId: str
priceVersion: int
status: str
paymentMethod: Optional[str] = None
totalAmount: Decimal
paidAmount: Decimal
receivableAmount: Decimal
refundAmount: Decimal
contactPerson: Optional[str] = None
contactPhone: Optional[str] = None
deliveryAddress: Optional[str] = None
remark: Optional[str] = None
lockOperatorId: Optional[str] = None
lockTime: Optional[datetime] = None
createAt: Optional[datetime] = None
paymentTime: Optional[datetime] = None
cancelReason: Optional[str] = None
cancelReviewNote: Optional[str] = None
completedTime: Optional[datetime] = None
class Config:
from_attributes = True
class OrderDetailResponse(OrderResponse):
"""订单详情响应(包含订单项和状态日志)"""
items: List[OrderItemResponse] = []
statusLogs: List[dict] = []
class OrderListResponse(BaseModel):
"""订单列表响应"""
items: List[OrderResponse]
total: int
page: int
pageSize: int
totalPages: int
class OrderPreviewResponse(BaseModel):
"""订单预览响应"""
priceListId: str
priceVersion: int
items: List[dict]
totalAmount: Decimal
address: dict
class OrderCancelRequest(BaseModel):
"""取消订单请求"""
reason: str = Field(..., description="取消原因")
class OrderDirectCancelRequest(BaseModel):
"""直接取消订单请求(未支付订单)"""
reason: str = Field(..., description="取消原因")
class OrderReviewCancelRequest(BaseModel):
"""审核取消订单请求"""
approved: bool = Field(..., description="是否审核通过")
reviewNote: Optional[str] = Field(None, description="审核备注")
class OrderStatusResponse(BaseModel):
"""订单状态更新响应"""
id: str
status: str
message: str = "操作成功"
class OrderStatusLogResponse(BaseModel):
"""订单状态日志响应"""
id: str
fromStatus: Optional[str] = None
toStatus: str
toStatusText: str
operatorName: Optional[str] = None
operatorRole: str
reason: Optional[str] = None
note: Optional[str] = None
createAt: Optional[datetime] = None
class Config:
from_attributes = True
class DeliveryProgressResponse(BaseModel):
"""配送进度响应"""
orderId: str
orderNo: str
status: str
deliveryStatus: Optional[str] = None
items: List[dict] = []
estimatedDeliveryTime: Optional[str] = None
# ============ 订单调整相关 Schema ============
class OrderAdjustItem(BaseModel):
"""订单调整项"""
orderItemId: str = Field(..., description="订单项ID")
adjustType: str = Field(..., description="调整类型: reduce/delete/substitute")
newQuantity: Optional[Decimal] = Field(None, description="新数量(减量时使用)")
newProductId: Optional[str] = Field(None, description="新商品ID(替代时使用)")
reason: str = Field(..., description="调整原因")
class OrderAdjustRequest(BaseModel):
"""订单调整请求"""
adjustments: List[OrderAdjustItem] = Field(..., description="调整项列表")
class OrderAdjustResponse(BaseModel):
"""订单调整响应"""
id: str
orderId: str
orderItemId: Optional[str] = None
adjustType: str
beforeQuantity: Decimal
afterQuantity: Decimal
beforeAmount: Decimal
afterAmount: Decimal
differenceAmount: Decimal
reason: str
operatorName: str
createAt: Optional[datetime] = None
class Config:
from_attributes = True
class OrderAdjustResult(BaseModel):
"""订单调整结果"""
id: str
totalAmount: Decimal
receivableAmount: Decimal
adjustments: List[dict]
message: str = "调整成功"
# ============ 订单锁定相关 Schema ============
class OrderLockRequest(BaseModel):
"""订单锁定请求"""
pass
class OrderLockResponse(BaseModel):
"""订单锁定响应"""
id: str
lockOperatorId: Optional[str] = None
lockTime: Optional[datetime] = None
message: str = "锁定成功"
class OrderUnlockRequest(BaseModel):
"""订单解锁请求"""
pass
class OrderUnlockResponse(BaseModel):
"""订单解锁响应"""
id: str
message: str = "解锁成功"
# ============ 订单状态管理 Schema ============
class OrderForceCompleteRequest(BaseModel):
"""强制完结订单请求"""
reason: Optional[str] = Field(None, description="完结原因")
class OrderForceCompleteResponse(BaseModel):
"""强制完结订单响应"""
id: str
status: str
completedTime: Optional[datetime] = None
message: str = "强制完结成功"
class OrderPartialDeliveredRequest(BaseModel):
"""标记部分送达请求"""
reason: Optional[str] = Field(None, description="原因")
class OrderPartialDeliveredResponse(BaseModel):
"""标记部分送达响应"""
id: str
status: str
message: str = "已标记为部分送达"
class OrderConfirmPartialRequest(BaseModel):
"""确认部分送达请求"""
reason: Optional[str] = Field(None, description="原因")
class OrderConfirmPartialResponse(BaseModel):
"""确认部分送达响应"""
id: str
status: str
receivableAmount: Decimal
message: str = "已确认"
# ============ 配送任务分配 Schema ============
class AssignDelivererRequest(BaseModel):
"""分配配送员请求"""
deliverId: str = Field(..., description="配送员ID")
class AssignDelivererResponse(BaseModel):
"""分配配送员响应"""
id: str
taskNo: str
deliverId: str
deliverName: str
status: str
message: str = "配送员分配成功"
# ============ 配送时效预警 Schema ============
class DeliveryWarningResponse(BaseModel):
"""配送时效预警响应"""
id: str
taskNo: str
orderId: Optional[str] = None
regionId: Optional[str] = None
regionName: Optional[str] = None
clientName: Optional[str] = None
supplierId: Optional[str] = None
supplierName: Optional[str] = None
deliverId: Optional[str] = None
deliverName: Optional[str] = None
status: str
effectiveTime: Optional[datetime] = None
remainingMinutes: int
urgencyLevel: str
isAssigned: bool
createAt: Optional[datetime] = None
class Config:
from_attributes = True
class DeliveryWarningStatistics(BaseModel):
"""配送时效预警统计"""
totalPending: int
criticalCount: int
urgentCount: int
normalCount: int
unassignedCount: int
class ReassignDeliveryRequest(BaseModel):
"""紧急重新分配配送任务请求"""
deliverId: str = Field(..., description="新配送员ID")
reason: Optional[str] = Field(None, description="重新分配原因")
class ReassignDeliveryResponse(BaseModel):
"""紧急重新分配配送任务响应"""
id: str
taskNo: str
newDeliverId: str
newDeliverName: str
oldDeliverId: Optional[str] = None
oldDeliverName: Optional[str] = None
message: str = "任务重新分配成功"