2026-10-15 06:50:38 -04:00
|
|
|
|
"""审批管理的请求/响应模型(2026-10-15 复核审批补充需求)。"""
|
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime
|
2026-10-20 06:30:51 -04:00
|
|
|
|
from typing import Any, Literal
|
2026-10-15 06:50:38 -04:00
|
|
|
|
|
|
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
|
|
|
|
|
|
|
|
|
|
from app.core.response import PageQuery
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApprovalStepOut(BaseModel):
|
|
|
|
|
|
"""节点记录(时间线;action=3 自动通过 operator 记「系统」)。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
|
|
|
|
|
|
id: int
|
|
|
|
|
|
node: int
|
|
|
|
|
|
action: int
|
|
|
|
|
|
opinion: str | None = None
|
|
|
|
|
|
operator_id: int | None = None
|
|
|
|
|
|
operator_name: str
|
|
|
|
|
|
create_time: datetime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApprovalOrderOut(BaseModel):
|
|
|
|
|
|
"""审批单列表行。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(from_attributes=True)
|
|
|
|
|
|
|
|
|
|
|
|
id: int
|
|
|
|
|
|
order_no: str
|
|
|
|
|
|
order_type: int
|
|
|
|
|
|
ref_id: int
|
|
|
|
|
|
refer_no: str
|
2026-10-20 06:30:51 -04:00
|
|
|
|
version_no: int
|
2026-10-15 06:50:38 -04:00
|
|
|
|
status: int
|
|
|
|
|
|
submitter_id: int | None = None
|
|
|
|
|
|
submitter_name: str
|
|
|
|
|
|
create_time: datetime
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApprovalOrderDetailOut(ApprovalOrderOut):
|
2026-10-20 06:30:51 -04:00
|
|
|
|
"""审批单详情:附节点时间线与审批内容。
|
|
|
|
|
|
|
|
|
|
|
|
``content_source`` 语义:``snapshot``=提交时快照(可信);
|
|
|
|
|
|
``live``=历史单无快照、回退读当前业务内容(仅供参考);
|
|
|
|
|
|
``missing``=引用对象已不存在且无快照。
|
|
|
|
|
|
"""
|
2026-10-15 06:50:38 -04:00
|
|
|
|
|
|
|
|
|
|
steps: list[ApprovalStepOut] = Field(default_factory=list)
|
2026-10-20 06:30:51 -04:00
|
|
|
|
snapshot: dict[str, Any] | None = Field(
|
2026-10-22 07:43:20 -04:00
|
|
|
|
default=None,
|
|
|
|
|
|
description="提交时内容快照(信封:schema_version/order_type/captured_at/data)",
|
2026-10-20 06:30:51 -04:00
|
|
|
|
)
|
|
|
|
|
|
content_source: Literal["snapshot", "live", "missing"] = Field(
|
|
|
|
|
|
default="missing", description="审批内容来源:提交时快照/当前内容回退/缺失"
|
|
|
|
|
|
)
|
2026-10-15 06:50:38 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApprovalQuery(PageQuery):
|
|
|
|
|
|
"""审批单列表查询条件。"""
|
|
|
|
|
|
|
|
|
|
|
|
keyword: str | None = Field(default=None, max_length=32, description="审批单号/引用单号,模糊")
|
|
|
|
|
|
status: int | None = Field(default=None, ge=1, le=5, description="状态筛选")
|
2026-10-20 06:30:51 -04:00
|
|
|
|
order_type: int | None = Field(default=None, ge=1, le=3, description="对象类型筛选")
|
2026-10-15 06:50:38 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ApprovalActionIn(BaseModel):
|
|
|
|
|
|
"""节点动作:1 通过 / 2 驳回(驳回须填意见——空驳无从追溯)。"""
|
|
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(str_strip_whitespace=True)
|
|
|
|
|
|
|
|
|
|
|
|
action: int = Field(ge=1, le=2, description="1通过 2驳回")
|
|
|
|
|
|
opinion: str | None = Field(default=None, max_length=255, description="审批意见")
|
|
|
|
|
|
|
|
|
|
|
|
@model_validator(mode="after")
|
|
|
|
|
|
def _check_opinion(self) -> "ApprovalActionIn":
|
|
|
|
|
|
if self.action == 2 and not self.opinion:
|
|
|
|
|
|
raise ValueError("驳回必须填写审批意见")
|
|
|
|
|
|
return self
|