Files
track/backend/app/schemas/task.py
duxingchen cb97d390ad feat(schemas): 更新 Pydantic Schema,新增请求/响应模型
Task Schema 更新:
- TaskResponse/TaskSummaryResponse 新增 is_rework, reject_reason, received_at, completed_at 字段
- 新增 TaskRejectRequest (品质驳回请求, reason 必填)
- 新增 TaskTransferRequest (裂变转交请求, next_assignees + next_task_name 必填)
- 新增 TaskTransferResponse (裂变转交响应)
- TaskCreate 新增 is_rework 字段

Product Schema 更新:
- ProductResponse/ProductScanResponse 新增 current_location_id 字段
- ProductScanResponse 新增 task_tree 字段 (递归任务树,供十字矩阵树状图)
2026-08-04 17:03:29 +08:00

121 lines
4.2 KiB
Python

"""任务 Pydantic Schemas — 支持无限嵌套子任务、裂变转交、驳回返工"""
from __future__ import annotations
import uuid
from datetime import datetime
from typing import Optional
from pydantic import BaseModel, Field
# ============================================================
# 请求模型
# ============================================================
class TaskCreate(BaseModel):
"""创建任务"""
product_id: uuid.UUID = Field(..., description="所属产品ID")
parent_task_id: uuid.UUID | None = Field(None, description="父任务ID(用于嵌套子任务/裂变分支)")
task_name: str = Field(..., max_length=200, description="任务名称")
assignee_id: str | None = Field(None, max_length=64, description="负责人ID(逻辑外键→老系统)")
notify_parent_on_complete: bool = Field(False, description="完成后是否通知父任务")
is_rework: bool = Field(False, description="是否为返工任务")
model_config = {"from_attributes": True}
class TaskUpdate(BaseModel):
"""更新任务"""
task_name: str | None = Field(None, max_length=200)
assignee_id: str | None = Field(None, max_length=64)
status: str | None = Field(None, max_length=50, description="任务状态")
notify_parent_on_complete: bool | None = Field(None)
model_config = {"from_attributes": True}
class TaskCompleteRequest(BaseModel):
"""完成任务请求 — 携带转交信息(保留兼容旧版单步转交)"""
operator_id: str | None = Field(None, max_length=64, description="操作人ID")
next_assignee_id: str | None = Field(None, max_length=64, description="下一步任务负责人ID")
next_task_name: str | None = Field(None, max_length=200, description="下一步任务名称")
remark: str | None = Field(None, description="完成备注")
class SubtaskCreate(BaseModel):
"""创建子任务"""
task_name: str = Field(..., max_length=200, description="子任务名称")
assignee_id: str | None = Field(None, max_length=64, description="负责人ID")
notify_parent_on_complete: bool = Field(False, description="完成后是否通知父任务")
class TaskRejectRequest(BaseModel):
"""品质驳回请求"""
reason: str = Field(..., min_length=1, max_length=500, description="驳回原因(必填)")
class TaskTransferRequest(BaseModel):
"""完工裂变转交请求"""
next_assignees: list[str] = Field(..., min_length=1, description="下一道工序接收人列表(必填)")
next_task_name: str = Field(..., min_length=1, max_length=200, description="下一道工序名称(必填)")
note: str | None = Field(None, description="交接备注")
# ============================================================
# 响应模型
# ============================================================
class TaskSummaryResponse(BaseModel):
"""任务摘要 — 扫码时用,不含嵌套子任务"""
id: uuid.UUID
product_id: uuid.UUID
parent_task_id: uuid.UUID | None
task_name: str
assignee_id: str | None
status: str
notify_parent_on_complete: bool
is_rework: bool = False
reject_reason: str | None = None
received_at: datetime | None = None
completed_at: datetime | None = None
created_at: datetime
model_config = {"from_attributes": True}
class TaskResponse(BaseModel):
"""任务详情响应 — 递归包含所有子任务"""
id: uuid.UUID
product_id: uuid.UUID
parent_task_id: uuid.UUID | None
task_name: str
assignee_id: str | None
status: str
notify_parent_on_complete: bool
is_rework: bool = False
reject_reason: str | None = None
received_at: datetime | None = None
completed_at: datetime | None = None
created_at: datetime
child_tasks: list[TaskResponse] = []
model_config = {"from_attributes": True}
class TaskCompleteResponse(BaseModel):
"""任务完成响应"""
completed_task: TaskResponse
next_task: TaskResponse | None = None
message: str
class TaskTransferResponse(BaseModel):
"""裂变转交响应"""
completed_task: TaskResponse
created_tasks: list[TaskResponse] = []
message: str
class TaskListResponse(BaseModel):
"""任务列表响应"""
tasks: list[TaskResponse]
total: int