| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- """运输计划管理 - 计划 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.resource_snapshot import PlanResourceSnapshotMixin
- # =============================================================================
- # 计划产品明细 Schema
- # =============================================================================
- class PlanProductBase(BaseModel):
- product_id: str = Field(..., alias="productId", description="产品ID")
- product_no: str = Field(..., max_length=50, alias="productNo", description="产品编号")
- product_name: str = Field(..., max_length=200, alias="productName", description="产品名称")
- brand_mode: Optional[str] = Field(default=None, alias="brandMode", description="required/any")
- brand_id: Optional[str] = Field(default=None, alias="brandId", description="指定品牌ID")
- brand_name: Optional[str] = Field(default=None, alias="brandName", description="品牌名快照")
- model: Optional[str] = Field(default=None, max_length=100, description="规格型号")
- unit: str = Field(default="吨", max_length=20, description="单位")
- category_name: Optional[str] = Field(default=None, max_length=200, alias="categoryName", description="产品分类")
- package_spec: Optional[str] = Field(default=None, max_length=200, alias="packageSpec", description="包装规格")
- delivery_method: Optional[str] = Field(default=None, max_length=50, alias="deliveryMethod", description="送货方式")
- quantity: Optional[Decimal] = Field(default=None, description="合同数量")
- actual_qty: Optional[Decimal] = Field(default=None, alias="actualQty", description="实际数量")
- tax_price: Optional[Decimal] = Field(default=None, alias="taxPrice", description="含税单价")
- tax_amount: Optional[Decimal] = Field(default=None, alias="taxAmount", description="税费")
- tax_subtotal: Optional[Decimal] = Field(default=None, alias="taxSubtotal", description="含税总价")
- is_explosive: int = Field(default=0, alias="isExplosive", description="是否易制爆")
- is_toxic: int = Field(default=0, alias="isToxic", description="是否易制毒")
- purchase_cert_url: Optional[str] = Field(
- default=None, alias="purchaseCertUrl", description="购买证URL,逗号分隔"
- )
- transport_cert_url: Optional[str] = Field(
- default=None, alias="transportCertUrl", description="运输证URL,逗号分隔"
- )
- legal_use_cert_url: Optional[str] = Field(
- default=None, alias="legalUseCertUrl", description="合法使用证明URL,逗号分隔"
- )
- inbound_estimate_qty: Optional[Decimal] = Field(default=None, alias="inboundEstimateQty", description="入库预估数")
- inbound_qty: Optional[Decimal] = Field(default=None, alias="inboundQty", description="入库数")
- inbound_price: Optional[Decimal] = Field(default=None, alias="inboundPrice", description="入库价")
- inbound_amount: Optional[Decimal] = Field(default=None, alias="inboundAmount", description="入库金额")
- outbound_estimate_qty: Optional[Decimal] = Field(default=None, alias="outboundEstimateQty", description="出库预估数")
- outbound_qty: Optional[Decimal] = Field(default=None, alias="outboundQty", description="出库数")
- outbound_price: Optional[Decimal] = Field(default=None, alias="outboundPrice", description="出库单价")
- outbound_amount: Optional[Decimal] = Field(default=None, alias="outboundAmount", description="出库金额")
- remark: Optional[str] = Field(default=None, max_length=512, description="备注")
- class PlanProductCreate(PlanProductBase):
- model_config = {"populate_by_name": True}
- class PlanProductUpdate(BaseModel):
- product_id: Optional[str] = Field(default=None, alias="productId")
- product_no: Optional[str] = Field(default=None, max_length=50, alias="productNo")
- product_name: Optional[str] = Field(default=None, max_length=200, alias="productName")
- model: Optional[str] = Field(default=None, max_length=100)
- unit: Optional[str] = Field(default=None, max_length=20)
- is_explosive: Optional[int] = Field(default=None, alias="isExplosive")
- is_toxic: Optional[int] = Field(default=None, alias="isToxic")
- purchase_cert_url: Optional[str] = Field(default=None, alias="purchaseCertUrl")
- transport_cert_url: Optional[str] = Field(default=None, alias="transportCertUrl")
- legal_use_cert_url: Optional[str] = Field(default=None, alias="legalUseCertUrl")
- inbound_estimate_qty: Optional[Decimal] = Field(default=None, alias="inboundEstimateQty")
- inbound_qty: Optional[Decimal] = Field(default=None, alias="inboundQty")
- inbound_price: Optional[Decimal] = Field(default=None, alias="inboundPrice")
- inbound_amount: Optional[Decimal] = Field(default=None, alias="inboundAmount")
- outbound_estimate_qty: Optional[Decimal] = Field(default=None, alias="outboundEstimateQty")
- outbound_qty: Optional[Decimal] = Field(default=None, alias="outboundQty")
- outbound_price: Optional[Decimal] = Field(default=None, alias="outboundPrice")
- outbound_amount: Optional[Decimal] = Field(default=None, alias="outboundAmount")
- model_config = {"populate_by_name": True}
- class PlanArchiveBrandQtyItem(BaseModel):
- brand_id: str = Field(default="", alias="brandId")
- brand_name: Optional[str] = Field(default=None, alias="brandName")
- qty: Decimal = Field(..., ge=0)
- model_config = {"populate_by_name": True}
- class PlanProductRead(PlanProductBase):
- id: str
- plan_id: str = Field(alias="planId")
- tenant_no: str = Field(alias="tenantNo")
- create_time: datetime = Field(alias="createTime")
- update_time: datetime = Field(alias="updateTime")
- brand_qtys: Optional[list[PlanArchiveBrandQtyItem]] = Field(
- default=None, alias="brandQtys", description="归档品牌数量明细"
- )
- model_config = {"from_attributes": True, "populate_by_name": True}
- # =============================================================================
- # 计划主表 Schema
- # =============================================================================
- class PlanBase(BaseModel):
- belongs_company: str = Field(..., alias="belongsCompany", description="归属公司 shanxia-安庆山峡 yundong-安徽云栋")
- plan_type: str = Field(
- default="",
- alias="planType",
- description="单据类型 direct-直销单 inbound-入库单 outbound-出库单;未选择可为空",
- )
- follow_status: str = Field(
- default="pending_arrange",
- alias="followStatus",
- description="跟进状态 wait_notice/pending_arrange/arranged/completed/cancelled",
- )
- transport_status: str = Field(default="pending", alias="transportStatus", description="运输安排状态")
- archive_status: str = Field(default="unarchived", alias="archiveStatus", description="归档状态")
- complete_status: str = Field(default="no", alias="completeStatus", description="完成状态")
- contract_id: Optional[str] = Field(default=None, alias="contractId", description="CRM合同ID")
- contract_no: Optional[str] = Field(default=None, max_length=50, alias="contractNo", description="合同编号")
- supplier_id: Optional[str] = Field(default=None, alias="supplierId", description="供应商ID")
- supplier_name: Optional[str] = Field(default=None, max_length=200, alias="supplierName", description="供应商名称")
- destination_id: Optional[str] = Field(default=None, alias="destinationId", description="目的地ID")
- destination_name: Optional[str] = Field(default=None, max_length=200, alias="destinationName", description="目的地名称")
- customer_id: Optional[str] = Field(default=None, alias="customerId", description="客户ID")
- customer_name: Optional[str] = Field(default=None, max_length=200, alias="customerName", description="客户名称")
- contact_name: Optional[str] = Field(default=None, max_length=100, alias="contactName", description="联系人")
- contact_phone: Optional[str] = Field(default=None, max_length=32, alias="contactPhone", description="联系电话")
- party_a: Optional[str] = Field(default=None, max_length=200, alias="partyA", description="甲方")
- party_b: Optional[str] = Field(default=None, max_length=200, alias="partyB", description="乙方")
- contract_start_date: Optional[date] = Field(default=None, alias="contractStartDate", description="合同开始日期")
- contract_end_date: Optional[date] = Field(default=None, alias="contractEndDate", description="合同结束日期")
- delivery_method: Optional[str] = Field(default=None, alias="deliveryMethod", description="送货方式")
- settlement_method: Optional[str] = Field(default=None, max_length=50, alias="settlementMethod", description="结算方式")
- has_freight: int = Field(default=0, alias="hasFreight", description="是否有运输费用")
- pickup_address: Optional[str] = Field(default=None, max_length=500, 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, max_length=500, alias="pickupNotes", description="取货注意事项")
- destination_address: Optional[str] = Field(default=None, max_length=500, 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, max_length=500, alias="destinationNotes", description="目的地注意事项")
- notify_message: Optional[str] = Field(default=None, alias="notifyMessage", description="通知信息")
- follow_user_id: Optional[str] = Field(default=None, alias="followUserId", description="跟进人ID")
- follow_user_name: Optional[str] = Field(default=None, max_length=100, alias="followUserName", description="跟进人姓名")
- remark: Optional[str] = None
- class PlanContractLink(BaseModel):
- contract_id: str = Field(..., alias="contractId", description="CRM合同ID")
- contract_no: Optional[str] = Field(default=None, max_length=50, alias="contractNo", description="合同编号")
- model_config = {"populate_by_name": True}
- class PlanCreate(PlanBase):
- create_date: Optional[date] = Field(
- default=None, alias="createDate", description="创建日期;缺省则服务端用当天"
- )
- plan_date: Optional[date] = Field(default=None, alias="planDate", description="计划日期(非必填)")
- products: Optional[list[PlanProductCreate]] = Field(default=None, description="产品明细列表")
- supplier_contracts: Optional[list[PlanContractLink]] = Field(
- default=None, alias="supplierContracts", description="供方合同列表"
- )
- demander_contracts: Optional[list[PlanContractLink]] = Field(
- default=None, alias="demanderContracts", description="需方合同列表"
- )
- model_config = {"populate_by_name": True}
- class PlanTransportCreateBlock(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")
- distance_km: Optional[Decimal] = Field(default=None, alias="distanceKm", description="运输公里数")
- freight_type: str = Field(default="by_weight", alias="freightType", description="运费计算方式")
- transport_qty: Optional[Decimal] = Field(default=None, alias="transportQty", description="运输量")
- 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
- model_config = {"populate_by_name": True}
- class PlanUpdate(BaseModel):
- create_date: Optional[date] = Field(default=None, alias="createDate")
- plan_date: Optional[date] = Field(default=None, alias="planDate")
- belongs_company: Optional[str] = Field(default=None, alias="belongsCompany")
- plan_type: Optional[str] = Field(default=None, alias="planType")
- follow_status: Optional[str] = Field(default=None, alias="followStatus")
- transport_status: Optional[str] = Field(default=None, alias="transportStatus")
- supplier_id: Optional[str] = Field(default=None, alias="supplierId")
- supplier_name: Optional[str] = Field(default=None, max_length=200, alias="supplierName")
- destination_id: Optional[str] = Field(default=None, alias="destinationId")
- destination_name: Optional[str] = Field(default=None, max_length=200, alias="destinationName")
- customer_id: Optional[str] = Field(default=None, alias="customerId")
- customer_name: Optional[str] = Field(default=None, max_length=200, alias="customerName")
- contact_name: Optional[str] = Field(default=None, max_length=100, alias="contactName")
- contact_phone: Optional[str] = Field(default=None, max_length=32, alias="contactPhone")
- party_a: Optional[str] = Field(default=None, max_length=200, alias="partyA")
- party_b: Optional[str] = Field(default=None, max_length=200, alias="partyB")
- contract_start_date: Optional[date] = Field(default=None, alias="contractStartDate")
- contract_end_date: Optional[date] = Field(default=None, alias="contractEndDate")
- delivery_method: Optional[str] = Field(default=None, alias="deliveryMethod")
- settlement_method: Optional[str] = Field(default=None, max_length=50, alias="settlementMethod")
- has_freight: Optional[int] = Field(default=None, alias="hasFreight")
- pickup_address: Optional[str] = Field(default=None, max_length=500, alias="pickupAddress")
- pickup_lng: Optional[Decimal] = Field(default=None, alias="pickupLng")
- pickup_lat: Optional[Decimal] = Field(default=None, alias="pickupLat")
- pickup_time: OptionalPlanDateTime = Field(default=None, alias="pickupTime")
- pickup_contact: Optional[str] = Field(default=None, max_length=200, alias="pickupContact")
- pickup_notes: Optional[str] = Field(default=None, max_length=500, alias="pickupNotes")
- destination_address: Optional[str] = Field(default=None, max_length=500, alias="destinationAddress")
- destination_lng: Optional[Decimal] = Field(default=None, alias="destinationLng")
- destination_lat: Optional[Decimal] = Field(default=None, alias="destinationLat")
- delivery_time: OptionalPlanDateTime = Field(default=None, alias="deliveryTime")
- delivery_contact: Optional[str] = Field(default=None, max_length=200, alias="deliveryContact")
- destination_notes: Optional[str] = Field(default=None, max_length=500, alias="destinationNotes")
- notify_message: Optional[str] = Field(default=None, alias="notifyMessage")
- follow_user_id: Optional[str] = Field(default=None, alias="followUserId")
- follow_user_name: Optional[str] = Field(default=None, alias="followUserName")
- remark: Optional[str] = None
- products: Optional[list[PlanProductCreate]] = None
- supplier_contracts: Optional[list[PlanContractLink]] = Field(
- default=None, alias="supplierContracts", description="供方合同列表"
- )
- demander_contracts: Optional[list[PlanContractLink]] = Field(
- default=None, alias="demanderContracts", description="需方合同列表"
- )
- transport: Optional[PlanTransportCreateBlock] = Field(default=None, description="运输预选/更新(有车牌时同步车辆与运费)")
- model_config = {"populate_by_name": True}
- class HazardCertReadyBody(BaseModel):
- ready: bool = Field(..., description="true=确认证书齐备 false=取消齐备")
- model_config = {"populate_by_name": True}
- class PlanRead(PlanBase, PlanResourceSnapshotMixin):
- id: str
- plan_no: str = Field(alias="planNo")
- create_date: date = Field(alias="createDate")
- plan_date: Optional[date] = Field(default=None, alias="planDate")
- hazard_cert_ready: int = Field(default=0, alias="hazardCertReady", description="危化品证书是否已人工确认齐备")
- hazard_cert_ready_by: Optional[str] = Field(default=None, alias="hazardCertReadyBy", description="危化品证书确认人")
- hazard_cert_ready_time: Optional[datetime] = Field(default=None, alias="hazardCertReadyTime", description="危化品证书确认时间")
- vehicle_id: Optional[str] = Field(default=None, alias="vehicleId")
- license_plate: Optional[str] = Field(default=None, alias="licensePlate")
- driver_id: Optional[str] = Field(default=None, alias="driverId")
- driver_name: Optional[str] = Field(default=None, alias="driverName")
- personnel_summary: Optional[str] = Field(default=None, alias="personnelSummary")
- transport_id: Optional[str] = Field(default=None, alias="transportId")
- transport_no: Optional[str] = Field(default=None, alias="transportNo")
- total_amount: Decimal = Field(alias="totalAmount")
- freight_amount: Decimal = Field(alias="freightAmount")
- 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")
- supplier_contracts: list[PlanContractLink] = Field(
- default_factory=list, alias="supplierContracts", description="供方合同列表"
- )
- demander_contracts: list[PlanContractLink] = Field(
- default_factory=list, alias="demanderContracts", description="需方合同列表"
- )
- model_config = {"from_attributes": True, "populate_by_name": True}
- class PlanWithProducts(PlanRead):
- products: list[PlanProductRead] = []
- class PlanInboundSlipTemplateSave(BaseModel):
- slip_template_content: str = Field(..., alias="slipTemplateContent", description="入库单打印模板HTML")
- model_config = {"populate_by_name": True}
- class PlanDeliverySlipTemplateSave(BaseModel):
- delivery_slip_template_content: str = Field(
- ..., alias="slipTemplateContent", description="送(提)货单打印模板HTML"
- )
- model_config = {"populate_by_name": True}
- class PlanSubpackSlipTemplateSave(BaseModel):
- subpack_slip_template_content: str = Field(
- ..., alias="slipTemplateContent", description="分装单打印模板HTML"
- )
- model_config = {"populate_by_name": True}
- # =============================================================================
- # 从合同创建计划
- # =============================================================================
- class CreateFromContractRequest(BaseModel):
- contract_id: str = Field(..., alias="contractId", description="CRM合同ID")
- create_date: Optional[date] = Field(
- default=None, alias="createDate", description="创建日期;缺省当天"
- )
- plan_date: Optional[date] = Field(default=None, alias="planDate", description="计划日期(非必填)")
- follow_user_id: Optional[str] = Field(default=None, alias="followUserId", description="跟进人ID")
- follow_user_name: Optional[str] = Field(default=None, max_length=100, alias="followUserName", description="跟进人姓名")
- model_config = {"populate_by_name": True}
- class PlanCreateFull(PlanCreate):
- contract_id: Optional[str] = Field(default=None, alias="contractId", description="旧字段:单一合同ID,已废弃为唯一源")
- transport: Optional[PlanTransportCreateBlock] = Field(default=None, description="运输安排(有车牌时创建运输)")
- model_config = {"populate_by_name": True}
- # =============================================================================
- # 计划列表查询
- # =============================================================================
- class PlanListQuery(BaseModel):
- q: Optional[str] = Field(default=None, description="模糊搜索计划号/客户名称/产品名称/车牌号")
- plan_no: Optional[str] = Field(default=None, alias="planNo", description="计划编号")
- plan_type: Optional[str] = Field(default=None, alias="planType", description="单据类型")
- follow_status: Optional[str] = Field(default=None, alias="followStatus", description="跟进状态")
- transport_status: Optional[str] = Field(default=None, alias="transportStatus", description="运输状态")
- archive_status: Optional[str] = Field(default=None, alias="archiveStatus", description="归档状态")
- customer_name: Optional[str] = Field(default=None, alias="customerName", description="客户名称")
- product_name: Optional[str] = Field(default=None, alias="productName", description="产品名称")
- license_plate: Optional[str] = Field(default=None, alias="licensePlate", description="车牌号")
- plan_date_from: Optional[date] = Field(default=None, alias="planDateFrom", description="计划日期开始")
- plan_date_to: Optional[date] = Field(default=None, alias="planDateTo", description="计划日期结束")
- has_hazard_product: Optional[int] = Field(
- default=None, alias="hasHazardProduct", description="1=仅含易制毒/易制爆产品的计划"
- )
- cert_upload_status: Optional[str] = Field(
- default=None,
- alias="certUploadStatus",
- description="incomplete=至少一张必需危化证书未上传",
- )
- page: int = Field(default=1, ge=1, description="页码")
- page_size: int = Field(default=20, ge=1, le=100, alias="pageSize", description="每页数量")
- model_config = {"populate_by_name": True}
- class PlanProductCertItem(BaseModel):
- id: str = Field(..., description="计划产品明细ID")
- purchase_cert_url: Optional[str] = Field(default=None, alias="purchaseCertUrl", description="购买证URL,逗号分隔")
- transport_cert_url: Optional[str] = Field(default=None, alias="transportCertUrl", description="运输证URL,逗号分隔")
- legal_use_cert_url: Optional[str] = Field(default=None, alias="legalUseCertUrl", description="合法使用证明URL,逗号分隔")
- model_config = {"populate_by_name": True}
- class PlanProductCertsUpdate(BaseModel):
- products: list[PlanProductCertItem] = Field(..., description="危化品证书更新列表")
- model_config = {"populate_by_name": True}
- class PlanArchiveProductItem(BaseModel):
- id: str = Field(..., description="计划产品明细ID pl_plan_product.id")
- actual_qty: Decimal = Field(..., alias="actualQty", ge=0, description="实际数量")
- brand_qtys: Optional[list[PlanArchiveBrandQtyItem]] = Field(default=None, alias="brandQtys")
- model_config = {"populate_by_name": True}
- class PlanArchiveFreightBlock(BaseModel):
- has_freight: int = Field(default=1, alias="hasFreight", description="是否有运输费用 0-否 1-是")
- distance_km: Optional[Decimal] = Field(default=None, alias="distanceKm")
- freight_type: str = Field(default="by_weight", alias="freightType")
- freight_price: Optional[Decimal] = Field(default=None, alias="freightPrice")
- freight_amount: Optional[Decimal] = Field(default=None, alias="freightAmount")
- transport_qty: Optional[Decimal] = Field(default=None, alias="transportQty")
- has_invoice: Optional[int] = Field(default=None, alias="hasInvoice")
- model_config = {"populate_by_name": True}
- class PlanArchiveBody(BaseModel):
- products: list[PlanArchiveProductItem] = Field(..., min_length=1)
- freight: Optional[PlanArchiveFreightBlock] = None
- model_config = {"populate_by_name": True}
- class PlanDriverFeedbackProductItem(BaseModel):
- plan_product_id: str = Field(alias="planProductId")
- actual_qty: Decimal = Field(alias="actualQty", ge=0)
- brand_qtys: Optional[list[PlanArchiveBrandQtyItem]] = Field(default=None, alias="brandQtys")
- model_config = {"populate_by_name": True}
- class PlanDriverFeedbackUpdateBody(BaseModel):
- feedback_remark: Optional[str] = Field(default=None, alias="feedbackRemark", max_length=500, description="回传备注")
- feedback_images: Optional[list[str]] = Field(default=None, alias="feedbackImages", description="回传附件URLs")
- feedback_time: OptionalPlanDateTime = Field(default=None, alias="feedbackTime", description="回传时间")
- products: Optional[list[PlanDriverFeedbackProductItem]] = None
- feedback_qty: Optional[Decimal] = Field(default=None, alias="feedbackQty", ge=0, description="回传数量")
- model_config = {"populate_by_name": True}
- class PlanSiteFeedbackUpdateBody(BaseModel):
- site_feedback_remark: Optional[str] = Field(
- default=None, alias="siteFeedbackRemark", max_length=500, description="现场回执备注"
- )
- site_feedback_images: Optional[list[str]] = Field(
- default=None, alias="siteFeedbackImages", description="现场回执附件URLs"
- )
- site_feedback_time: OptionalPlanDateTime = Field(
- default=None, alias="siteFeedbackTime", description="现场回执保存时间"
- )
- model_config = {"populate_by_name": True}
- class PlanListResponse(BaseModel):
- total: int
- list: list[PlanWithProducts]
|