delivery.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. """Pydantic schemas - 配送任务管理"""
  2. from pydantic import BaseModel, Field
  3. from typing import Optional, List
  4. from datetime import datetime
  5. from decimal import Decimal
  6. class DeliveryTaskItemResponse(BaseModel):
  7. """配送任务明细响应"""
  8. id: str
  9. taskId: str
  10. orderId: Optional[str] = None
  11. orderItemId: Optional[str] = None
  12. productId: Optional[str] = None
  13. productName: Optional[str] = None
  14. clientId: Optional[str] = None
  15. deliveryAddress: Optional[str] = None
  16. contactPerson: Optional[str] = None
  17. contactPhone: Optional[str] = None
  18. quantity: Decimal
  19. deliveredQuantity: Optional[Decimal] = None
  20. status: str
  21. deliveryTime: Optional[datetime] = None
  22. class Config:
  23. from_attributes = True
  24. class DeliveryTaskResponse(BaseModel):
  25. """配送任务响应"""
  26. id: str
  27. taskNo: str
  28. orderId: Optional[str] = None
  29. regionId: Optional[str] = None
  30. regionName: Optional[str] = None
  31. supplierId: Optional[str] = None
  32. supplierName: Optional[str] = None
  33. deliverId: Optional[str] = None
  34. deliverName: Optional[str] = None
  35. status: str
  36. effectiveTime: Optional[datetime] = None
  37. pickupTime: Optional[datetime] = None
  38. pickupRemark: Optional[str] = None
  39. pickupImageUrl: Optional[str] = None
  40. deliveryTime: Optional[datetime] = None
  41. deliveryRemark: Optional[str] = None
  42. deliveryImageUrl: Optional[str] = None
  43. createAt: Optional[datetime] = None
  44. class Config:
  45. from_attributes = True
  46. class DeliveryTaskDetailResponse(DeliveryTaskResponse):
  47. """配送任务详情响应"""
  48. items: List[DeliveryTaskItemResponse] = []
  49. order: Optional[dict] = None
  50. deliver: Optional[dict] = None
  51. class DeliveryTaskListResponse(BaseModel):
  52. """配送任务列表响应"""
  53. items: List[DeliveryTaskResponse]
  54. total: int
  55. page: int
  56. pageSize: int
  57. totalPages: int
  58. class DeliveryTaskCreateRequest(BaseModel):
  59. """创建配送任务请求"""
  60. orderId: str = Field(..., description="订单ID")
  61. regionId: str = Field(..., description="区域ID")
  62. supplierId: str = Field(..., description="供应商ID")
  63. deliverId: Optional[str] = Field(None, description="配送员ID")
  64. effectiveTime: Optional[datetime] = Field(None, description="配送截止时间")
  65. class DeliveryTaskAssignRequest(BaseModel):
  66. """分配配送员请求"""
  67. deliverId: str = Field(..., description="配送员ID")
  68. class DeliveryTaskPickupRequest(BaseModel):
  69. """确认取货请求"""
  70. pickupRemark: Optional[str] = Field(None, description="取货备注")
  71. pickupImageUrl: Optional[str] = Field(None, description="取货图片URL")
  72. class DeliveryTaskDeliverRequest(BaseModel):
  73. """确认送达请求"""
  74. deliveryRemark: Optional[str] = Field(None, description="送达备注")
  75. deliveryImageUrl: Optional[str] = Field(None, description="送达图片URL")
  76. class DeliveryTaskCancelRequest(BaseModel):
  77. """取消配送任务请求"""
  78. reason: str = Field(..., description="取消原因")
  79. class DeliveryTaskStatusUpdateRequest(BaseModel):
  80. """更新配送任务状态请求"""
  81. status: str = Field(..., description="新状态")
  82. remark: Optional[str] = Field(None, description="备注")
  83. # ============ 供应商端配送任务 Schema ============
  84. class SupplierTaskResponse(BaseModel):
  85. """供应商配送任务响应"""
  86. id: str
  87. taskNo: str
  88. orderId: Optional[str] = None
  89. regionId: Optional[str] = None
  90. regionName: Optional[str] = None
  91. clientName: Optional[str] = None
  92. supplierId: Optional[str] = None
  93. deliverId: Optional[str] = None
  94. deliverName: Optional[str] = None
  95. status: str
  96. effectiveTime: Optional[datetime] = None
  97. pickupTime: Optional[datetime] = None
  98. pickupRemark: Optional[str] = None
  99. deliveryTime: Optional[datetime] = None
  100. totalItems: int = 0
  101. deliveredItems: int = 0
  102. createAt: Optional[datetime] = None
  103. class Config:
  104. from_attributes = True
  105. class SupplierTaskListResponse(BaseModel):
  106. """供应商配送任务列表响应"""
  107. items: List[SupplierTaskResponse]
  108. total: int
  109. page: int
  110. pageSize: int
  111. totalPages: int
  112. class SupplierConfirmPickupRequest(BaseModel):
  113. """供应商确认取货请求"""
  114. pickupRemark: Optional[str] = Field(None, description="取货备注")
  115. class SupplierConfirmPreparedRequest(BaseModel):
  116. """供应商确认备货完成请求"""
  117. preparedRemark: Optional[str] = Field(None, description="备货备注")
  118. # ============ 配送统计 Schema ============
  119. class DeliveryStatisticsResponse(BaseModel):
  120. """配送统计响应"""
  121. totalTasks: int
  122. pendingTasks: int
  123. inProgressTasks: int
  124. completedTasks: int
  125. cancelledTasks: int
  126. averageDeliveryTime: Optional[float] = None
  127. onTimeRate: Optional[float] = None
  128. class DeliveryWarningItem(BaseModel):
  129. """配送预警项"""
  130. taskId: str
  131. taskNo: str
  132. urgencyLevel: str
  133. remainingMinutes: int
  134. orderId: Optional[str] = None
  135. clientName: Optional[str] = None
  136. deliverName: Optional[str] = None
  137. class DeliveryWarningListResponse(BaseModel):
  138. """配送预警列表响应"""
  139. items: List[DeliveryWarningItem] = []
  140. total: int
  141. page: int
  142. pageSize: int
  143. totalPages: int
  144. # ============ 运营端配送任务 Schema (兼容旧命名) ============
  145. class DeliveryAssignRequest(BaseModel):
  146. """分配配送员请求"""
  147. deliverId: str = Field(..., description="配送员ID")
  148. class DeliveryAssignBatchRequest(BaseModel):
  149. """批量分配配送员请求"""
  150. taskIds: List[str] = Field(..., description="配送任务ID列表")
  151. deliverId: str = Field(..., description="配送员ID")
  152. class DeliveryPickupRequest(BaseModel):
  153. """配送员取货确认请求"""
  154. taskId: str = Field(..., description="配送任务ID")
  155. pickupRemark: Optional[str] = Field(None, description="取货备注")
  156. pickupImageUrl: Optional[str] = Field(None, description="取货图片")
  157. class DeliveryDeliverItem(BaseModel):
  158. """送达明细"""
  159. taskItemId: str = Field(..., description="配送任务明细ID")
  160. deliveredQuantity: Decimal = Field(..., description="送达数量")
  161. class DeliveryDeliverRequest(BaseModel):
  162. """确认送达请求"""
  163. taskId: str = Field(..., description="配送任务ID")
  164. items: List[DeliveryDeliverItem] = Field(default_factory=list, description="送达明细列表")
  165. deliveryRemark: Optional[str] = Field(None, description="送达备注")
  166. deliveryImageUrl: Optional[str] = Field(None, description="送达图片")
  167. class DeliveryCancelRequest(BaseModel):
  168. """取消配送任务请求"""
  169. taskId: str = Field(..., description="配送任务ID")
  170. reason: str = Field(..., description="取消原因")
  171. class DeliveryReassignRequest(BaseModel):
  172. """重新分配配送员请求"""
  173. taskId: str = Field(..., description="配送任务ID")
  174. newDeliverId: str = Field(..., description="新配送员ID")
  175. reason: Optional[str] = Field(None, description="重新分配原因")
  176. class DeliveryStatusResponse(BaseModel):
  177. """配送状态更新响应"""
  178. id: str
  179. status: str
  180. message: str = "操作成功"
  181. class DeliveryTaskStatistics(BaseModel):
  182. """配送任务统计"""
  183. total: int = 0
  184. pending: int = 0
  185. picking: int = 0
  186. delivering: int = 0
  187. completed: int = 0
  188. cancelled: int = 0
  189. class DeliveryAttachmentResponse(BaseModel):
  190. """配送附件响应"""
  191. id: str
  192. taskId: str
  193. type: str
  194. url: str
  195. createAt: datetime
  196. class Config:
  197. from_attributes = True
  198. # 兼容别名
  199. DeliveryCompleteRequest = DeliveryTaskDeliverRequest