549 lines
30 KiB
Python
549 lines
30 KiB
Python
"""运输计划管理 - 运输 Schema"""
|
|
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
from typing import Optional
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from app.schemas.pl.datetime_parse import OptionalPlanDateTime
|
|
from app.schemas.pl.io_order import BrandOption, BrandQtyItem
|
|
from app.schemas.pl.resource_snapshot import PlanResourceSnapshotMixin
|
|
|
|
|
|
# =============================================================================
|
|
# 运输 Schema
|
|
# =============================================================================
|
|
|
|
|
|
class TransportBase(BaseModel):
|
|
vehicle_id: Optional[str] = Field(default=None, alias="vehicleId", description="车辆ID")
|
|
license_plate: Optional[str] = Field(default=None, max_length=20, alias="licensePlate", description="车牌号")
|
|
driver_id: Optional[str] = Field(default=None, alias="driverId", description="司机ID")
|
|
driver_name: Optional[str] = Field(default=None, max_length=100, alias="driverName", description="司机姓名")
|
|
driver_phone: Optional[str] = Field(default=None, max_length=32, alias="driverPhone", description="司机电话")
|
|
carrier_id: Optional[str] = Field(default=None, alias="carrierId", description="承运商ID")
|
|
carrier_name: Optional[str] = Field(default=None, max_length=200, alias="carrierName", description="承运商名称")
|
|
transport_medium: Optional[str] = Field(default=None, max_length=100, alias="transportMedium", description="运输介质")
|
|
start_point: Optional[str] = Field(default=None, max_length=200, alias="startPoint", description="运输起点")
|
|
end_point: Optional[str] = Field(default=None, max_length=200, alias="endPoint", description="运输终点")
|
|
distance_km: Optional[Decimal] = Field(default=None, alias="distanceKm", description="运输公里数")
|
|
unit: Optional[str] = Field(default=None, max_length=20, description="计量单位")
|
|
transport_qty: Optional[Decimal] = Field(default=None, alias="transportQty", description="运输量")
|
|
freight_price: Optional[Decimal] = Field(default=None, alias="freightPrice", description="运输单价")
|
|
freight_amount: Decimal = Field(default=Decimal("0.00"), alias="freightAmount", description="运输费用")
|
|
freight_type: str = Field(default="by_weight", alias="freightType", description="运费计算方式")
|
|
has_invoice: int = Field(default=0, alias="hasInvoice", description="是否开票")
|
|
qr_expire_date: Optional[date] = Field(default=None, alias="qrExpireDate", description="二维码有效期")
|
|
transport_status: str = Field(default="draft", alias="transportStatus", description="运输状态")
|
|
approval_status: str = Field(default="none", alias="approvalStatus", description="审批状态")
|
|
remark: Optional[str] = None
|
|
|
|
|
|
class TransportCreate(TransportBase):
|
|
plan_ids: Optional[list[str]] = Field(default=None, alias="planIds", description="关联计划ID列表")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportStopDibangOption(BaseModel):
|
|
stop_type: str = Field(..., alias="stopType", description="停靠段类型 load-装货 delivery-送货")
|
|
stop_id: str = Field(..., alias="stopId", description="停靠段ID")
|
|
generate_dibang: bool = Field(..., alias="generateDibang", description="是否生成地磅单")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportArrange(BaseModel):
|
|
vehicle_id: str = Field(..., alias="vehicleId", description="车辆ID")
|
|
driver_id: Optional[str] = Field(default=None, alias="driverId", description="司机ID(可选)")
|
|
carrier_id: Optional[str] = Field(default=None, alias="carrierId", description="承运商ID")
|
|
transport_medium: Optional[str] = Field(default=None, alias="transportMedium", description="运输介质")
|
|
pickup_address: Optional[str] = Field(default=None, alias="pickupAddress", description="取货地址")
|
|
pickup_lng: Optional[Decimal] = Field(default=None, alias="pickupLng", description="取货经度")
|
|
pickup_lat: Optional[Decimal] = Field(default=None, alias="pickupLat", description="取货纬度")
|
|
pickup_time: OptionalPlanDateTime = Field(default=None, alias="pickupTime", description="取货时间")
|
|
pickup_contact: Optional[str] = Field(default=None, max_length=200, alias="pickupContact", description="取货联系方式")
|
|
pickup_notes: Optional[str] = Field(default=None, alias="pickupNotes", description="取货注意事项")
|
|
destination_address: Optional[str] = Field(default=None, alias="destinationAddress", description="送货地址")
|
|
destination_lng: Optional[Decimal] = Field(default=None, alias="destinationLng", description="送货经度")
|
|
destination_lat: Optional[Decimal] = Field(default=None, alias="destinationLat", description="送货纬度")
|
|
delivery_time: OptionalPlanDateTime = Field(default=None, alias="deliveryTime", description="送达时间")
|
|
delivery_contact: Optional[str] = Field(default=None, max_length=200, alias="deliveryContact", description="送货联系方式")
|
|
destination_notes: Optional[str] = Field(default=None, alias="destinationNotes", description="送货注意事项")
|
|
start_point: Optional[str] = Field(default=None, alias="startPoint", description="运输起点(兼容,等同取货地址)")
|
|
end_point: Optional[str] = Field(default=None, alias="endPoint", description="运输终点(兼容,等同送货地址)")
|
|
distance_km: Optional[Decimal] = Field(default=None, alias="distanceKm", description="运输公里数")
|
|
unit: Optional[str] = Field(default=None, description="计量单位")
|
|
freight_type: str = Field(default="by_weight", alias="freightType", description="运费计算方式 by_weight/by_trip")
|
|
freight_price: Optional[Decimal] = Field(default=None, alias="freightPrice", description="运输单价")
|
|
freight_amount: Optional[Decimal] = Field(default=None, alias="freightAmount", description="运费金额")
|
|
has_invoice: Optional[int] = Field(default=None, alias="hasInvoice", description="是否开票(已废弃,由运费结算维护)")
|
|
remark: Optional[str] = None
|
|
generate_dibang_plan: bool = Field(default=False, alias="generateDibangPlan", description="是否生成地磅单(兼容旧计划)")
|
|
stop_dibang_options: Optional[list[TransportStopDibangOption]] = Field(
|
|
default=None,
|
|
alias="stopDibangOptions",
|
|
description="按段地磅勾选(一车多卸)",
|
|
)
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportInventoryLinkRead(BaseModel):
|
|
plan_product_id: str = Field(alias="planProductId")
|
|
product_name: str = Field(alias="productName")
|
|
db_purchase_plan_id: str = Field(alias="dbPurchasePlanId")
|
|
db_inventory_id: str = Field(alias="dbInventoryId")
|
|
batch_no: str = Field(alias="batchNo")
|
|
plan_no: str = Field(alias="planNo")
|
|
stop_type: Optional[str] = Field(default=None, alias="stopType")
|
|
stop_id: Optional[str] = Field(default=None, alias="stopId")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportSiteLinkRead(BaseModel):
|
|
plan_product_id: str = Field(alias="planProductId")
|
|
product_name: str = Field(alias="productName")
|
|
site_link_id: str = Field(alias="siteLinkId")
|
|
plan_no: str = Field(alias="planNo")
|
|
business_type: str = Field(alias="businessType")
|
|
site_access_token: Optional[str] = Field(default=None, alias="siteAccessToken")
|
|
site_url: Optional[str] = Field(default=None, alias="siteUrl")
|
|
site_feedback_remark: Optional[str] = Field(default=None, alias="siteFeedbackRemark")
|
|
site_feedback_images: list[str] = Field(default_factory=list, alias="siteFeedbackImages")
|
|
site_feedback_time: Optional[datetime] = Field(default=None, alias="siteFeedbackTime")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportUpdate(BaseModel):
|
|
vehicle_id: Optional[str] = Field(default=None, alias="vehicleId")
|
|
license_plate: Optional[str] = Field(default=None, max_length=20, alias="licensePlate")
|
|
driver_id: Optional[str] = Field(default=None, alias="driverId")
|
|
driver_name: Optional[str] = Field(default=None, max_length=100, alias="driverName")
|
|
driver_phone: Optional[str] = Field(default=None, max_length=32, alias="driverPhone")
|
|
carrier_id: Optional[str] = Field(default=None, alias="carrierId")
|
|
carrier_name: Optional[str] = Field(default=None, max_length=200, alias="carrierName")
|
|
transport_medium: Optional[str] = Field(default=None, max_length=100, alias="transportMedium")
|
|
start_point: Optional[str] = Field(default=None, max_length=200, alias="startPoint")
|
|
end_point: Optional[str] = Field(default=None, max_length=200, alias="endPoint")
|
|
distance_km: Optional[Decimal] = Field(default=None, alias="distanceKm")
|
|
unit: Optional[str] = Field(default=None, max_length=20)
|
|
freight_price: Optional[Decimal] = Field(default=None, alias="freightPrice")
|
|
freight_amount: Optional[Decimal] = Field(default=None, alias="freightAmount")
|
|
freight_type: Optional[str] = Field(default=None, alias="freightType")
|
|
has_invoice: Optional[int] = Field(default=None, alias="hasInvoice")
|
|
qr_expire_date: Optional[date] = Field(default=None, alias="qrExpireDate")
|
|
transport_status: Optional[str] = Field(default=None, alias="transportStatus")
|
|
approval_status: Optional[str] = Field(default=None, alias="approvalStatus")
|
|
remark: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportDriverProductFeedbackRead(BaseModel):
|
|
plan_product_id: str = Field(alias="planProductId")
|
|
product_name: str = Field(default="", alias="productName")
|
|
product_no: Optional[str] = Field(default=None, alias="productNo")
|
|
model: Optional[str] = None
|
|
unit: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
brand_mode: Optional[str] = Field(default=None, alias="brandMode")
|
|
brand_id: Optional[str] = Field(default=None, alias="brandId")
|
|
brand_name: Optional[str] = Field(default=None, alias="brandName")
|
|
actual_qty: Optional[Decimal] = Field(default=None, alias="actualQty")
|
|
brand_summary: Optional[str] = Field(default=None, alias="brandSummary")
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportStopFeedbackRead(BaseModel):
|
|
stop_type: str = Field(alias="stopType")
|
|
stop_id: str = Field(alias="stopId")
|
|
label: str
|
|
customer_name: str = Field(alias="customerName")
|
|
business_type: Optional[str] = Field(default=None, alias="businessType")
|
|
quantity: Optional[Decimal] = None
|
|
attachment_urls: list[str] = Field(default_factory=list, alias="attachmentUrls")
|
|
products: list["TransportDriverStopProductFeedbackRead"] = Field(default_factory=list)
|
|
remark: Optional[str] = None
|
|
feedback_time: Optional[datetime] = Field(default=None, alias="feedbackTime")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportDriverStopProductFeedbackRead(BaseModel):
|
|
stop_product_id: str = Field(alias="stopProductId")
|
|
plan_product_id: str = Field(default="", alias="planProductId")
|
|
product_name: str = Field(default="", alias="productName")
|
|
model: Optional[str] = None
|
|
unit: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
quantity: Optional[Decimal] = None
|
|
actual_qty: Optional[Decimal] = Field(default=None, alias="actualQty")
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportRead(TransportBase, PlanResourceSnapshotMixin):
|
|
id: str
|
|
transport_no: str = Field(alias="transportNo")
|
|
qr_code: Optional[str] = Field(default=None, alias="qrCode")
|
|
feedback_time: Optional[datetime] = Field(default=None, alias="feedbackTime")
|
|
feedback_qty: Optional[Decimal] = Field(default=None, alias="feedbackQty")
|
|
feedback_images: Optional[str] = Field(default=None, alias="feedbackImages")
|
|
feedback_remark: Optional[str] = Field(default=None, alias="feedbackRemark")
|
|
driver_product_feedbacks: list[TransportDriverProductFeedbackRead] = Field(
|
|
default_factory=list, alias="driverProductFeedbacks"
|
|
)
|
|
driver_stop_feedbacks: list[TransportStopFeedbackRead] = Field(
|
|
default_factory=list, alias="driverStopFeedbacks"
|
|
)
|
|
site_stop_feedbacks: list[TransportStopFeedbackRead] = Field(
|
|
default_factory=list, alias="siteStopFeedbacks"
|
|
)
|
|
tenant_no: str = Field(alias="tenantNo")
|
|
order_num: Optional[int] = Field(default=None, alias="orderNum")
|
|
create_by: Optional[str] = Field(default=None, alias="createBy")
|
|
create_dept_id: Optional[str] = Field(default=None, alias="createDeptId")
|
|
create_time: datetime = Field(alias="createTime")
|
|
update_by: Optional[str] = Field(default=None, alias="updateBy")
|
|
update_time: datetime = Field(alias="updateTime")
|
|
del_flag: int = Field(default=0, alias="delFlag")
|
|
model_config = {"from_attributes": True, "populate_by_name": True}
|
|
|
|
|
|
class TransportIoOrderBrief(BaseModel):
|
|
kind: str
|
|
order_id: str = Field(alias="orderId")
|
|
order_no: str = Field(alias="orderNo")
|
|
site_access_token: Optional[str] = Field(default=None, alias="siteAccessToken")
|
|
site_url: Optional[str] = Field(default=None, alias="siteUrl")
|
|
status: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportArrangeResult(TransportRead):
|
|
driver_access_token: Optional[str] = Field(default=None, alias="driverAccessToken")
|
|
driver_url: Optional[str] = Field(default=None, alias="driverUrl")
|
|
site_records: list[TransportSiteLinkRead] = Field(default_factory=list, alias="siteRecords")
|
|
inventory_records: list[TransportInventoryLinkRead] = Field(
|
|
default_factory=list, alias="inventoryRecords"
|
|
)
|
|
io_order: Optional[TransportIoOrderBrief] = Field(default=None, alias="ioOrder")
|
|
model_config = {"from_attributes": True, "populate_by_name": True}
|
|
|
|
|
|
class PlanArrangeInfoRead(BaseModel):
|
|
requires_site_link: bool = Field(default=False, alias="requiresSiteLink")
|
|
driver_url: Optional[str] = Field(default=None, alias="driverUrl")
|
|
license_plate: Optional[str] = Field(default=None, alias="licensePlate")
|
|
site_records: list[TransportSiteLinkRead] = Field(default_factory=list, alias="siteRecords")
|
|
inventory_records: list[TransportInventoryLinkRead] = Field(
|
|
default_factory=list, alias="inventoryRecords"
|
|
)
|
|
io_order: Optional[TransportIoOrderBrief] = Field(default=None, alias="ioOrder")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportWithPlans(TransportRead):
|
|
plan_ids: list[str] = Field(default_factory=list, alias="planIds")
|
|
|
|
|
|
# =============================================================================
|
|
# 司机扫码回传
|
|
# =============================================================================
|
|
|
|
|
|
class TransportFeedback(BaseModel):
|
|
transport_no: str = Field(..., alias="transportNo", description="运输编号")
|
|
verify_code: Optional[str] = Field(default=None, alias="verifyCode", description="验证码")
|
|
feedback_qty: Optional[Decimal] = Field(default=None, alias="feedbackQty", description="回传数量")
|
|
feedback_images: Optional[list[str]] = Field(default=None, alias="feedbackImages", description="回传图片URLs")
|
|
feedback_remark: Optional[str] = Field(default=None, alias="feedbackRemark", description="回传备注")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportProductFeedbackItem(BaseModel):
|
|
plan_product_id: str = Field(..., alias="planProductId")
|
|
actual_qty: Decimal = Field(..., alias="actualQty", ge=0)
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportFeedback(BaseModel):
|
|
feedback_images: Optional[list[str]] = Field(default=None, alias="feedbackImages")
|
|
feedback_remark: Optional[str] = Field(default=None, alias="feedbackRemark")
|
|
feedback_qty: Optional[Decimal] = Field(default=None, alias="feedbackQty", ge=0, description="回传数量")
|
|
products: Optional[list[PublicTransportProductFeedbackItem]] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportDriverStopProductFeedbackItem(BaseModel):
|
|
stop_product_id: str = Field(..., alias="stopProductId")
|
|
actual_qty: Decimal = Field(..., alias="actualQty", ge=0)
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportDriverStopFeedback(BaseModel):
|
|
stop_type: str = Field(..., alias="stopType")
|
|
stop_id: str = Field(..., alias="stopId")
|
|
attachment_urls: list[str] = Field(default_factory=list, alias="attachmentUrls")
|
|
products: Optional[list[PublicTransportDriverStopProductFeedbackItem]] = None
|
|
remark: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportStopProductRead(BaseModel):
|
|
stop_product_id: str = Field(alias="stopProductId")
|
|
plan_product_id: str = Field(default="", alias="planProductId")
|
|
product_name: str = Field(alias="productName")
|
|
alias_name: Optional[str] = Field(default=None, alias="aliasName")
|
|
model: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
unit: Optional[str] = None
|
|
quantity: Optional[Decimal] = None
|
|
remark: Optional[str] = Field(default=None, alias="remark")
|
|
brand_mode: Optional[str] = Field(default=None, alias="brandMode")
|
|
brand_id: Optional[str] = Field(default=None, alias="brandId")
|
|
brand_name: Optional[str] = Field(default=None, alias="brandName")
|
|
brand_options: Optional[list[BrandOption]] = Field(default=None, alias="brandOptions")
|
|
actual_qty: Optional[Decimal] = Field(default=None, alias="actualQty")
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportSiteStopFeedback(BaseModel):
|
|
stop_type: str = Field(..., alias="stopType")
|
|
stop_id: str = Field(..., alias="stopId")
|
|
quantity: Optional[Decimal] = Field(default=None, ge=0)
|
|
attachment_urls: Optional[list[str]] = Field(default=None, alias="attachmentUrls")
|
|
remark: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportStopRead(BaseModel):
|
|
stop_type: str = Field(alias="stopType")
|
|
stop_id: str = Field(alias="stopId")
|
|
seq: int = 0
|
|
label: str
|
|
customer_name: str = Field(alias="customerName")
|
|
address: Optional[str] = None
|
|
contact: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
lng: Optional[Decimal] = None
|
|
lat: Optional[Decimal] = None
|
|
business_type: Optional[str] = Field(default=None, alias="businessType")
|
|
plan_qty: Optional[Decimal] = Field(default=None, alias="planQty")
|
|
quantity: Optional[Decimal] = None
|
|
show_product_qty: bool = Field(default=False, alias="showProductQty")
|
|
products: list[PublicTransportStopProductRead] = Field(default_factory=list)
|
|
attachment_urls: list[str] = Field(default_factory=list, alias="attachmentUrls")
|
|
remark: Optional[str] = None
|
|
feedback_time: Optional[datetime] = Field(default=None, alias="feedbackTime")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportPlanProductRead(BaseModel):
|
|
plan_product_id: str = Field(default="", alias="planProductId")
|
|
product_name: str = Field(alias="productName")
|
|
alias_name: Optional[str] = Field(default=None, alias="aliasName", description="产品别名")
|
|
model: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
unit: Optional[str] = None
|
|
quantity: Optional[Decimal] = None
|
|
remark: Optional[str] = Field(default=None, alias="remark", description="运输计划产品备注")
|
|
brand_mode: Optional[str] = Field(default=None, alias="brandMode")
|
|
brand_id: Optional[str] = Field(default=None, alias="brandId")
|
|
brand_name: Optional[str] = Field(default=None, alias="brandName")
|
|
brand_options: Optional[list[BrandOption]] = Field(default=None, alias="brandOptions")
|
|
actual_qty: Optional[Decimal] = Field(default=None, alias="actualQty")
|
|
brand_qtys: Optional[list[BrandQtyItem]] = Field(default=None, alias="brandQtys")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportPersonnelRead(BaseModel):
|
|
personnel_name: str = Field(alias="personnelName")
|
|
phone_no: Optional[str] = Field(default=None, alias="phoneNo")
|
|
role: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportPageRead(BaseModel):
|
|
plan_no: str = Field(alias="planNo")
|
|
plan_date: Optional[str] = Field(default=None, alias="planDate")
|
|
plan_type: str = Field(alias="planType")
|
|
pickup_address: Optional[str] = Field(default=None, alias="pickupAddress")
|
|
pickup_lng: Optional[Decimal] = Field(default=None, alias="pickupLng")
|
|
pickup_lat: Optional[Decimal] = Field(default=None, alias="pickupLat")
|
|
pickup_time: Optional[datetime] = Field(default=None, alias="pickupTime")
|
|
pickup_contact: Optional[str] = Field(default=None, alias="pickupContact")
|
|
pickup_notes: Optional[str] = Field(default=None, alias="pickupNotes")
|
|
destination_name: Optional[str] = Field(default=None, alias="destinationName")
|
|
destination_address: Optional[str] = Field(default=None, alias="destinationAddress")
|
|
destination_lng: Optional[Decimal] = Field(default=None, alias="destinationLng")
|
|
destination_lat: Optional[Decimal] = Field(default=None, alias="destinationLat")
|
|
delivery_time: Optional[datetime] = Field(default=None, alias="deliveryTime")
|
|
delivery_contact: Optional[str] = Field(default=None, alias="deliveryContact")
|
|
destination_notes: Optional[str] = Field(default=None, alias="destinationNotes")
|
|
license_plate: Optional[str] = Field(default=None, alias="licensePlate")
|
|
driver_name: Optional[str] = Field(default=None, alias="driverName")
|
|
driver_phone: Optional[str] = Field(default=None, alias="driverPhone")
|
|
other_personnel: list[PublicTransportPersonnelRead] = Field(
|
|
default_factory=list, alias="otherPersonnel"
|
|
)
|
|
products: list[PublicTransportPlanProductRead] = Field(default_factory=list)
|
|
stops: list[PublicTransportStopRead] = Field(default_factory=list)
|
|
feedback_remark: Optional[str] = Field(default=None, alias="feedbackRemark")
|
|
feedback_images: list[str] = Field(default_factory=list, alias="feedbackImages")
|
|
feedback_qty: Optional[Decimal] = Field(default=None, alias="feedbackQty", description="回传数量")
|
|
feedback_time: Optional[datetime] = Field(default=None, alias="feedbackTime")
|
|
plan_voided: bool = Field(default=False, alias="planVoided")
|
|
plan_archived: bool = Field(default=False, alias="planArchived")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportHistoryProductRead(BaseModel):
|
|
product_name: str = Field(alias="productName")
|
|
model: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
quantity: Optional[Decimal] = None
|
|
unit: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportHistoryStopProductRead(BaseModel):
|
|
product_name: str = Field(alias="productName")
|
|
model: Optional[str] = None
|
|
package_spec: Optional[str] = Field(default=None, alias="packageSpec")
|
|
quantity: Optional[Decimal] = None
|
|
unit: Optional[str] = None
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportHistoryStopRead(BaseModel):
|
|
stop_type: str = Field(alias="stopType")
|
|
seq: int = 0
|
|
label: str
|
|
customer_name: str = Field(alias="customerName")
|
|
address: Optional[str] = None
|
|
stop_time: Optional[datetime] = Field(default=None, alias="stopTime")
|
|
products: list[PublicTransportHistoryStopProductRead] = Field(default_factory=list)
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportHistoryRecordRead(BaseModel):
|
|
plan_id: str = Field(alias="planId")
|
|
plan_no: str = Field(alias="planNo")
|
|
transport_id: str = Field(alias="transportId")
|
|
driver_access_token: Optional[str] = Field(default=None, alias="driverAccessToken")
|
|
driver_url: Optional[str] = Field(default=None, alias="driverUrl")
|
|
site_access_token: Optional[str] = Field(default=None, alias="siteAccessToken")
|
|
site_url: Optional[str] = Field(default=None, alias="siteUrl")
|
|
license_plate: Optional[str] = Field(default=None, alias="licensePlate")
|
|
pickup_time: Optional[datetime] = Field(default=None, alias="pickupTime")
|
|
delivery_time: Optional[datetime] = Field(default=None, alias="deliveryTime")
|
|
pickup_address: Optional[str] = Field(default=None, alias="pickupAddress")
|
|
destination_address: Optional[str] = Field(default=None, alias="destinationAddress")
|
|
products: list[PublicTransportHistoryProductRead] = Field(default_factory=list)
|
|
stops: list[PublicTransportHistoryStopRead] = Field(default_factory=list)
|
|
plan_voided: bool = Field(default=False, alias="planVoided")
|
|
plan_archived: bool = Field(default=False, alias="planArchived")
|
|
status_label: str = Field(default="进行中", alias="statusLabel")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportHistoryPageRead(BaseModel):
|
|
license_plate: Optional[str] = Field(default=None, alias="licensePlate")
|
|
date: str
|
|
keyword: Optional[str] = None
|
|
records: list[PublicTransportHistoryRecordRead] = Field(default_factory=list)
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportMultiStopSitePageRead(BaseModel):
|
|
plan_no: str = Field(alias="planNo")
|
|
plan_date: Optional[str] = Field(default=None, alias="planDate")
|
|
license_plate: Optional[str] = Field(default=None, alias="licensePlate")
|
|
vehicle_no: Optional[str] = Field(default=None, alias="vehicleNo")
|
|
plan_voided: bool = Field(default=False, alias="planVoided")
|
|
plan_archived: bool = Field(default=False, alias="planArchived")
|
|
stops: list[PublicTransportStopRead] = Field(default_factory=list)
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class PublicTransportSitePageRead(BaseModel):
|
|
business_type: str = Field(alias="businessType")
|
|
date: Optional[str] = None
|
|
partner_company: str = Field(alias="partnerCompany")
|
|
vehicle_no: str = Field(alias="vehicleNo")
|
|
plan_no: Optional[str] = Field(default=None, alias="planNo")
|
|
remark: Optional[str] = None
|
|
pickup_address: Optional[str] = Field(default=None, alias="pickupAddress")
|
|
pickup_lng: Optional[Decimal] = Field(default=None, alias="pickupLng")
|
|
pickup_lat: Optional[Decimal] = Field(default=None, alias="pickupLat")
|
|
pickup_time: Optional[datetime] = Field(default=None, alias="pickupTime")
|
|
pickup_contact: Optional[str] = Field(default=None, alias="pickupContact")
|
|
pickup_notes: Optional[str] = Field(default=None, alias="pickupNotes")
|
|
destination_name: Optional[str] = Field(default=None, alias="destinationName")
|
|
destination_address: Optional[str] = Field(default=None, alias="destinationAddress")
|
|
destination_lng: Optional[Decimal] = Field(default=None, alias="destinationLng")
|
|
destination_lat: Optional[Decimal] = Field(default=None, alias="destinationLat")
|
|
delivery_time: Optional[datetime] = Field(default=None, alias="deliveryTime")
|
|
delivery_contact: Optional[str] = Field(default=None, alias="deliveryContact")
|
|
destination_notes: Optional[str] = Field(default=None, alias="destinationNotes")
|
|
products: list[PublicTransportPlanProductRead] = Field(default_factory=list)
|
|
site_feedback_remark: Optional[str] = Field(default=None, alias="siteFeedbackRemark")
|
|
site_feedback_images: list[str] = Field(default_factory=list, alias="siteFeedbackImages")
|
|
site_feedback_time: Optional[datetime] = Field(default=None, alias="siteFeedbackTime")
|
|
voided: bool = False
|
|
archived: bool = False
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
# =============================================================================
|
|
# 审批
|
|
# =============================================================================
|
|
|
|
|
|
class ApprovalSubmit(BaseModel):
|
|
approver_ids: list[str] = Field(..., alias="approverIds", description="审批人ID列表(按顺序)")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class ApprovalRequest(BaseModel):
|
|
action: str = Field(..., description="审批动作 approve/reject")
|
|
comment: Optional[str] = Field(default=None, description="审批意见")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class ApprovalRecordRead(BaseModel):
|
|
id: str
|
|
transport_id: str = Field(alias="transportId")
|
|
approver_id: str = Field(alias="approverId")
|
|
approver_name: str = Field(alias="approverName")
|
|
approval_order: int = Field(alias="approvalOrder")
|
|
status: str
|
|
comment: Optional[str] = None
|
|
approval_time: Optional[datetime] = Field(default=None, alias="approvalTime")
|
|
tenant_no: str = Field(alias="tenantNo")
|
|
create_time: datetime = Field(alias="createTime")
|
|
model_config = {"from_attributes": True, "populate_by_name": True}
|
|
|
|
|
|
# =============================================================================
|
|
# 列表查询
|
|
# =============================================================================
|
|
|
|
|
|
class TransportListQuery(BaseModel):
|
|
q: Optional[str] = Field(default=None, description="模糊搜索")
|
|
transport_no: Optional[str] = Field(default=None, alias="transportNo", description="运输编号")
|
|
transport_status: Optional[str] = Field(default=None, alias="transportStatus", description="运输状态")
|
|
approval_status: Optional[str] = Field(default=None, alias="approvalStatus", description="审批状态")
|
|
vehicle_id: Optional[str] = Field(default=None, alias="vehicleId", description="车辆ID")
|
|
driver_id: Optional[str] = Field(default=None, alias="driverId", description="司机ID")
|
|
page: int = Field(default=1, ge=1)
|
|
page_size: int = Field(default=20, ge=1, le=500, alias="pageSize")
|
|
model_config = {"populate_by_name": True}
|
|
|
|
|
|
class TransportListResponse(BaseModel):
|
|
total: int
|
|
list: list[TransportRead]
|