383 lines
9.7 KiB
Python
383 lines
9.7 KiB
Python
"""
|
||
订单模块请求模型
|
||
|
||
定义订单管理相关的请求体数据模型,供 orders 路由使用。
|
||
包含订单查询、创建、更新、取消、审批以及供应商对账等操作的请求体。
|
||
"""
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class OrderListQuery(BaseModel):
|
||
"""订单列表查询参数模型。被 GET /api/orders 路由使用。"""
|
||
|
||
order_no: str | None = None
|
||
"""订单编号,模糊匹配"""
|
||
|
||
order_status: str | None = None
|
||
"""订单状态筛选"""
|
||
|
||
customer_name: str | None = None
|
||
"""客户名称,模糊匹配"""
|
||
|
||
customer_mobile: str | None = None
|
||
"""客户手机号,模糊匹配"""
|
||
|
||
salesman_id: int | None = None
|
||
"""业务员 ID 筛选"""
|
||
|
||
factory_id: int | None = None
|
||
"""工厂 ID 筛选"""
|
||
|
||
order_source: str | None = None
|
||
"""订单来源筛选"""
|
||
|
||
order_type: str | None = None
|
||
"""订单类型筛选(industry/daily)"""
|
||
|
||
need_invoice: int | None = None
|
||
"""是否需要发票筛选(0=否,1=是)"""
|
||
|
||
start_time: str | None = None
|
||
"""查询起始时间(ISO 格式)"""
|
||
|
||
end_time: str | None = None
|
||
"""查询截止时间(ISO 格式)"""
|
||
|
||
page_no: int = 1
|
||
"""页码,从 1 开始"""
|
||
|
||
page_size: int = 20
|
||
"""每页条数"""
|
||
|
||
|
||
class OrderItemPayload(BaseModel):
|
||
"""订单商品明细载荷,用于创建/更新订单时携带商品行项。"""
|
||
|
||
product_id: int | None = None
|
||
"""产品 ID,可选(新建时可能尚未关联)"""
|
||
|
||
product_name: str
|
||
"""产品名称"""
|
||
|
||
specification: str
|
||
"""规格"""
|
||
|
||
unit: str
|
||
"""单位"""
|
||
|
||
quantity: float = Field(gt=0)
|
||
"""数量,必须大于 0"""
|
||
|
||
sale_price: float = Field(ge=0)
|
||
"""销售单价"""
|
||
|
||
cost_price: float = Field(ge=0)
|
||
"""成本单价"""
|
||
|
||
rebate_amount: float = Field(default=0, ge=0)
|
||
"""返利金额"""
|
||
|
||
freight_amount: float = Field(default=0, ge=0)
|
||
"""运费"""
|
||
|
||
tax_amount: float = Field(default=0, ge=0)
|
||
"""税额"""
|
||
|
||
other_fee_amount: float = Field(default=0, ge=0)
|
||
"""其他费用"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
demand_specification: str | None = None
|
||
"""需求规格"""
|
||
|
||
# 报价引擎快照字段
|
||
pricing_type: str | None = None
|
||
"""报价类型(创建订单时从报价引擎快照而来)"""
|
||
|
||
length_m: float | None = None
|
||
"""长度(米),报价快照"""
|
||
|
||
width_m: float | None = None
|
||
"""宽度(米),报价快照"""
|
||
|
||
area_sqm: float | None = None
|
||
"""面积(平方米),报价快照"""
|
||
|
||
surcharge_detail: str | None = None
|
||
"""附加费明细,JSON 字符串"""
|
||
|
||
processing_detail: str | None = None
|
||
"""加工费明细,JSON 字符串"""
|
||
|
||
supplier_id: int | None = None
|
||
"""供应商 ID,报价快照"""
|
||
|
||
supplier_model: str | None = None
|
||
"""供应商型号,报价快照"""
|
||
|
||
price_tier: str | None = None
|
||
"""价格档位,报价快照"""
|
||
|
||
|
||
class CreateOrderRequest(BaseModel):
|
||
"""创建订单请求体。被 POST /api/orders 路由使用。"""
|
||
|
||
customer_name: str
|
||
"""客户名称"""
|
||
|
||
customer_mobile: str
|
||
"""客户联系电话"""
|
||
|
||
customer_address: str | None = None
|
||
"""配送地址"""
|
||
|
||
order_source: str | None = None
|
||
"""订单来源"""
|
||
|
||
delivery_type: str | None = None
|
||
"""配送方式"""
|
||
|
||
factory_id: int | None = None
|
||
"""生产工厂 ID"""
|
||
|
||
contract_amount: float = Field(default=0, ge=0)
|
||
"""合同金额(客户应付总额)"""
|
||
|
||
commission_amount: float = Field(default=0, ge=0)
|
||
"""佣金金额"""
|
||
|
||
rebate_total: float = Field(default=0, ge=0)
|
||
"""返利合计"""
|
||
|
||
freight_total: float = Field(default=0, ge=0)
|
||
"""运费合计"""
|
||
|
||
tax_total: float = Field(default=0, ge=0)
|
||
"""税额合计"""
|
||
|
||
other_fee_total: float = Field(default=0, ge=0)
|
||
"""其他费用合计"""
|
||
|
||
payment_method: str | None = None
|
||
"""收款渠道"""
|
||
|
||
tax_amount: float = Field(default=0, ge=0)
|
||
"""含税金额"""
|
||
|
||
need_invoice: int = Field(default=0, ge=0)
|
||
"""是否需要发票(0=否,1=是)"""
|
||
|
||
order_type: str | None = None
|
||
"""订单类型(industry=工业订单,daily=日用品订单)"""
|
||
|
||
self_delivery: int = Field(default=0, ge=0)
|
||
"""是否自发(0=否,1=是)"""
|
||
|
||
tracking_number: str | None = None
|
||
"""快递单号(自发时填写)"""
|
||
|
||
customer_demand: str | None = None
|
||
"""客户需求描述"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
items: list[OrderItemPayload] = Field(default_factory=list)
|
||
"""订单商品明细列表"""
|
||
|
||
|
||
class UpdateOrderRequest(BaseModel):
|
||
"""更新订单请求体。被 PUT /api/orders/{id} 路由使用。"""
|
||
|
||
customer_name: str
|
||
"""客户名称"""
|
||
|
||
customer_mobile: str
|
||
"""客户联系电话"""
|
||
|
||
customer_address: str | None = None
|
||
"""配送地址"""
|
||
|
||
order_source: str | None = None
|
||
"""订单来源"""
|
||
|
||
delivery_type: str | None = None
|
||
"""配送方式"""
|
||
|
||
factory_id: int | None = None
|
||
"""生产工厂 ID"""
|
||
|
||
contract_amount: float = Field(default=0, ge=0)
|
||
"""合同金额(客户应付总额)"""
|
||
|
||
commission_amount: float = Field(default=0, ge=0)
|
||
"""佣金金额"""
|
||
|
||
rebate_total: float = Field(default=0, ge=0)
|
||
"""返利合计"""
|
||
|
||
freight_total: float = Field(default=0, ge=0)
|
||
"""运费合计"""
|
||
|
||
tax_total: float = Field(default=0, ge=0)
|
||
"""税额合计"""
|
||
|
||
other_fee_total: float = Field(default=0, ge=0)
|
||
"""其他费用合计"""
|
||
|
||
payment_method: str | None = None
|
||
"""收款渠道"""
|
||
|
||
tax_amount: float = Field(default=0, ge=0)
|
||
"""含税金额"""
|
||
|
||
need_invoice: int = Field(default=0, ge=0)
|
||
"""是否需要发票(0=否,1=是)"""
|
||
|
||
order_type: str | None = None
|
||
"""订单类型(industry=工业订单,daily=日用品订单)"""
|
||
|
||
self_delivery: int = Field(default=0, ge=0)
|
||
"""是否自发(0=否,1=是)"""
|
||
|
||
tracking_number: str | None = None
|
||
"""快递单号(自发时填写)"""
|
||
|
||
customer_demand: str | None = None
|
||
"""客户需求描述"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
items: list[OrderItemPayload] = Field(default_factory=list)
|
||
"""订单商品明细列表(全量替换)"""
|
||
|
||
|
||
class CancelOrderRequest(BaseModel):
|
||
"""取消订单请求体。被 POST /api/orders/{id}/cancel 路由使用。"""
|
||
|
||
cancel_reason: str
|
||
"""取消原因"""
|
||
|
||
cancel_opinion: str | None = None
|
||
"""取消审批意见"""
|
||
|
||
|
||
class ApproveOrderRequest(BaseModel):
|
||
"""审批订单请求体。被 POST /api/orders/{id}/approve 路由使用。"""
|
||
|
||
approve_result: str
|
||
"""审批结果(pass=通过, reject=退回)"""
|
||
|
||
approve_opinion: str | None = None
|
||
"""审批意见"""
|
||
|
||
factory_id: int | None = None
|
||
"""下发工厂 ID(审批通过时可选,同时选择工厂和司机可跳过待工厂节点)"""
|
||
|
||
driver_id: int | None = None
|
||
"""分配司机 ID(审批通过时可选,同时选择工厂和司机可直接创建物流任务)"""
|
||
|
||
|
||
class SupplierTextRequest(BaseModel):
|
||
"""获取供应商对账文本请求体。被 POST /api/orders/supplier-text 路由使用。"""
|
||
|
||
supplier_id: int
|
||
"""供应商 ID"""
|
||
|
||
|
||
class ConfirmSupplierTextRequest(BaseModel):
|
||
"""确认供应商对账文本请求体。被 POST /api/orders/supplier-text/confirm 路由使用。"""
|
||
|
||
supplier_id: int
|
||
"""供应商 ID"""
|
||
|
||
text_content: str
|
||
"""对账文本内容"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
|
||
class ChangeOrderStatusRequest(BaseModel):
|
||
"""变更订单状态请求体。被 POST /api/orders/{id}/status 路由使用。"""
|
||
|
||
target_status: str
|
||
"""目标状态"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
|
||
class ReviseOrderRequest(BaseModel):
|
||
"""管理员修订订单请求体。被 POST /api/orders/{id}/revise 路由使用。"""
|
||
|
||
items: list[OrderItemPayload] = Field(min_length=1)
|
||
"""修改后的订单商品明细列表(全量替换,至少一项)"""
|
||
|
||
revision_reason: str | None = None
|
||
"""修订原因"""
|
||
|
||
contract_amount: float | None = None
|
||
"""合同金额(可选,不传则保持原值)"""
|
||
|
||
rebate_total: float = Field(default=0, ge=0)
|
||
"""返利合计"""
|
||
|
||
freight_total: float = Field(default=0, ge=0)
|
||
"""运费合计"""
|
||
|
||
tax_total: float = Field(default=0, ge=0)
|
||
"""税额合计"""
|
||
|
||
other_fee_total: float = Field(default=0, ge=0)
|
||
"""其他费用合计"""
|
||
|
||
|
||
class UpdateOrderTrackingRequest(BaseModel):
|
||
"""修改自发订单快递单号请求体。被 PUT /api/orders/{id}/tracking 路由使用。"""
|
||
|
||
tracking_number: str
|
||
"""快递单号"""
|
||
|
||
remark: str | None = None
|
||
|
||
|
||
class LogisticsMatchItem(BaseModel):
|
||
"""批量匹配物流条目。"""
|
||
|
||
tracking_number: str
|
||
"""快递单号"""
|
||
|
||
express_company: str | None = None
|
||
"""快递公司"""
|
||
|
||
recipient_name: str | None = None
|
||
"""收件人姓名(面单场景可能为空)"""
|
||
|
||
order_id: int | None = None
|
||
"""用户确认后填入的目标订单 ID"""
|
||
|
||
|
||
class BatchMatchLogisticsRequest(BaseModel):
|
||
"""批量匹配物流请求体。被 POST /api/orders/batch-match-logistics 路由使用。"""
|
||
|
||
mode: str
|
||
"""模式:text(文本粘贴)| image_table(物流表格截图)| express_images(快递面单照片)"""
|
||
|
||
text: str | None = None
|
||
"""mode=text 时的文本内容"""
|
||
|
||
image_urls: list[str] = Field(default_factory=list)
|
||
"""mode=image_table 或 express_images 时的图片 URL 列表"""
|
||
|
||
|
||
class BatchMatchConfirmRequest(BaseModel):
|
||
"""批量匹配确认请求体。被 POST /api/orders/batch-match-logistics/confirm 路由使用。"""
|
||
|
||
matches: list[LogisticsMatchItem] = Field(min_length=1)
|
||
"""用户确认后的匹配列表,至少一条"""
|