新增 logistics_waybill 表存储一个任务关联的多个运单号, 司机在揽货时可通过拍照调用快递100 OCR 自动识别运单号, 支持连续拍多张统一提交、手动输入兜底、编辑删除, 揽货时必填至少一个运单号并自动同步到 logistics_task。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
159 lines
3.8 KiB
Python
159 lines
3.8 KiB
Python
"""
|
||
物流模块请求模型
|
||
|
||
定义物流任务管理相关的请求体数据模型,供 logistics 路由使用。
|
||
包含物流任务的查询、创建、司机操作以及物流轨迹记录等操作。
|
||
"""
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
class LogisticsTaskListQuery(BaseModel):
|
||
"""物流任务列表查询参数模型。被 GET /api/logistics/tasks 路由使用。"""
|
||
|
||
order_id: int | None = None
|
||
"""关联订单 ID 筛选"""
|
||
|
||
task_no: str | None = None
|
||
"""任务编号,模糊匹配"""
|
||
|
||
status: str | None = None
|
||
"""任务状态筛选"""
|
||
|
||
driver_id: int | None = None
|
||
"""司机 ID 筛选"""
|
||
|
||
factory_id: int | None = None
|
||
"""工厂 ID 筛选"""
|
||
|
||
page_no: int = 1
|
||
"""页码,从 1 开始"""
|
||
|
||
page_size: int = 20
|
||
"""每页条数"""
|
||
|
||
|
||
class CreateLogisticsTaskRequest(BaseModel):
|
||
"""创建物流任务请求体。被 POST /api/logistics/tasks 路由使用。"""
|
||
|
||
order_id: int
|
||
"""关联订单 ID"""
|
||
|
||
driver_id: int = Field(gt=0)
|
||
"""司机 ID,必须大于 0"""
|
||
|
||
pickup_address: str
|
||
"""提货地址"""
|
||
|
||
delivery_address: str
|
||
"""送货地址"""
|
||
|
||
pickup_content: str
|
||
"""提货内容描述"""
|
||
|
||
quantity: float = Field(gt=0)
|
||
"""提货数量,必须大于 0"""
|
||
|
||
factory_id: int | None = None
|
||
"""工厂 ID"""
|
||
|
||
tracking_number: str | None = None
|
||
"""物流追踪单号"""
|
||
|
||
express_company: str | None = None
|
||
"""快递公司"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
|
||
class LogisticsFilePayload(BaseModel):
|
||
"""物流文件载荷,用于上传物流过程中的照片或视频附件。"""
|
||
|
||
file_url: str
|
||
"""文件 URL"""
|
||
|
||
file_name: str
|
||
"""文件名称"""
|
||
|
||
file_type: str | None = None
|
||
"""文件类型(如 image / video)"""
|
||
|
||
file_size: int | None = Field(default=None, gt=0)
|
||
"""文件大小(字节)"""
|
||
|
||
|
||
class DriverTaskOperateRequest(BaseModel):
|
||
"""司机任务操作请求体(接单/提货/送达等)。被 POST /api/logistics/tasks/{id}/operate 路由使用。"""
|
||
|
||
photo_files: list[LogisticsFilePayload] = Field(default_factory=list)
|
||
"""操作时上传的照片文件列表"""
|
||
|
||
video_files: list[LogisticsFilePayload] = Field(default_factory=list)
|
||
"""操作时上传的视频文件列表"""
|
||
|
||
remark: str | None = None
|
||
"""备注"""
|
||
|
||
|
||
class CreateLogisticsTraceRequest(BaseModel):
|
||
"""创建物流轨迹请求体。被 POST /api/logistics/traces 路由使用。"""
|
||
|
||
task_id: int = Field(gt=0)
|
||
"""关联物流任务 ID"""
|
||
|
||
node_time: str
|
||
"""节点时间(ISO 格式)"""
|
||
|
||
node_desc: str
|
||
"""节点描述"""
|
||
|
||
node_type: str
|
||
"""节点类型(如揽收、中转、派送等)"""
|
||
|
||
source_platform: str
|
||
"""来源平台"""
|
||
|
||
|
||
class UpdateTrackingRequest(BaseModel):
|
||
"""修改物流单号请求体。被 PUT /api/logistics/tasks/{id}/tracking 路由使用。"""
|
||
|
||
tracking_number: str
|
||
"""新的物流追踪单号"""
|
||
|
||
express_company: str | None = None
|
||
"""快递公司"""
|
||
|
||
remark: str | None = None
|
||
"""修改原因/备注"""
|
||
|
||
|
||
class RecognizeWaybillRequest(BaseModel):
|
||
"""快递100面单识别请求。被 POST /api/driver/recognize-waybill 路由使用。"""
|
||
|
||
image_url: str
|
||
"""面单照片 URL"""
|
||
|
||
|
||
class WaybillItem(BaseModel):
|
||
"""单条运单号信息。被 SubmitWaybillsRequest 使用。"""
|
||
|
||
tracking_number: str
|
||
"""运单号"""
|
||
|
||
express_company: str | None = None
|
||
"""快递公司编码"""
|
||
|
||
express_name: str | None = None
|
||
"""快递公司名称"""
|
||
|
||
image_url: str | None = None
|
||
"""面单照片 URL"""
|
||
|
||
|
||
class SubmitWaybillsRequest(BaseModel):
|
||
"""批量提交运单号请求体。被 POST /api/driver/tasks/{id}/waybills 路由使用。"""
|
||
|
||
waybills: list[WaybillItem] = Field(min_length=1)
|
||
"""运单号列表,至少一条"""
|