dingdanquanliucheng/backend/app/schemas/logistics.py
taiyi a5edb8be4d feat: 司机端拍照识别物流运单号并支持一对多录入
新增 logistics_waybill 表存储一个任务关联的多个运单号,
司机在揽货时可通过拍照调用快递100 OCR 自动识别运单号,
支持连续拍多张统一提交、手动输入兜底、编辑删除,
揽货时必填至少一个运单号并自动同步到 logistics_task。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-07 14:03:36 +08:00

159 lines
3.8 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.

"""
物流模块请求模型
定义物流任务管理相关的请求体数据模型,供 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)
"""运单号列表,至少一条"""