- approval_orders/approval_steps 服务层:submit_order(不 commit 不嵌套 audit,业务写路径统一收口)+ act 节点动作 + 分页/详情 - 开关关闭=提单即两级「自动通过」留痕(action=3,operator 记系统); 开启=财务→领导流转,一驳全驳,驳回必填意见 - 节点准入严格按角色(status=1 仅财务、status=2 仅领导),admin 不代办; 模块准入 require_roles 依赖工厂(admin/finance/leader,营销后勤待 澄清 #6 后放开) - 业务接入:创建/编辑带方案即提单(空方案不提单);再编辑自动撤回旧 在途单(node=0/action=4 留痕);AP 编号冲突 create 内可重取(外层 重试兜底)、update 直接抛出防静默丢失 - conftest 兜底清理增审批单(AP 前缀)与开关参数种子基线恢复 - 集成 11 例:自动通过/两节点流转/驳回留痕/缺意见 400/节点准入 403/ admin 不代办/重复操作 400/撤旧建新/模块准入 Co-Authored-By: Claude Code <noreply@anthropic.com>
67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
"""审批管理的请求/响应模型(2026-10-15 复核审批补充需求)。"""
|
||
|
||
from datetime import datetime
|
||
|
||
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
|
||
status: int
|
||
submitter_id: int | None = None
|
||
submitter_name: str
|
||
create_time: datetime
|
||
|
||
|
||
class ApprovalOrderDetailOut(ApprovalOrderOut):
|
||
"""审批单详情:附节点时间线。"""
|
||
|
||
steps: list[ApprovalStepOut] = Field(default_factory=list)
|
||
|
||
|
||
class ApprovalQuery(PageQuery):
|
||
"""审批单列表查询条件。"""
|
||
|
||
keyword: str | None = Field(default=None, max_length=32, description="审批单号/引用单号,模糊")
|
||
status: int | None = Field(default=None, ge=1, le=5, description="状态筛选")
|
||
order_type: int | None = Field(default=None, ge=1, le=2, description="对象类型筛选")
|
||
|
||
|
||
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
|