165 lines
6.0 KiB
Python
165 lines
6.0 KiB
Python
# app/schemas/automation.py
|
|
|
|
from datetime import datetime
|
|
from typing import List, Optional, Dict, Any
|
|
from pydantic import BaseModel, Field
|
|
from app.models.enums import TaskStatus, ScenarioScope, ActionType
|
|
|
|
# ----------------------------
|
|
# Scenario Schemas
|
|
# ----------------------------
|
|
|
|
class ScenarioBase(BaseModel):
|
|
title: str = Field(..., max_length=255, description="场景标题")
|
|
trigger: Dict[str, Any] = Field(..., description="触发条件(事件/时间)")
|
|
actions: List[Dict[str, Any]] = Field(default_factory=list, description="执行动作模板列表")
|
|
notes: Optional[str] = Field(None, description="备注")
|
|
is_global: bool = Field(True, description="是否全局场景")
|
|
owner_user_id: Optional[str] = Field(None, max_length=64, description="归属用户ID(非全局时有效)")
|
|
enabled: bool = Field(True, description="是否启用")
|
|
scope: ScenarioScope = Field(ScenarioScope.ALL, description="作用角色范围")
|
|
|
|
|
|
class ScenarioCreate(ScenarioBase):
|
|
pass
|
|
|
|
|
|
class ScenarioUpdate(BaseModel):
|
|
id: int = Field(..., description="场景ID")
|
|
title: Optional[str] = Field(None, max_length=255)
|
|
trigger: Optional[Dict[str, Any]] = None
|
|
actions: Optional[List[Dict[str, Any]]] = None
|
|
notes: Optional[str] = None
|
|
is_global: Optional[bool] = None
|
|
owner_user_id: Optional[str] = Field(None, max_length=64)
|
|
enabled: Optional[bool] = None
|
|
scope: Optional[ScenarioScope] = None
|
|
|
|
# model_config = {"extra": "forbid"} # 禁止传入未定义字段
|
|
|
|
|
|
class ScenarioCopy(BaseModel):
|
|
id: int = Field(..., description="场景ID")
|
|
# model_config = {"extra": "forbid"} # 禁止传入未定义字段
|
|
|
|
|
|
class ScenarioRead(ScenarioBase):
|
|
id: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ----------------------------
|
|
# Task Schemas
|
|
# ----------------------------
|
|
|
|
class TaskBase(BaseModel):
|
|
title: str = Field(..., max_length=255, description="待办标题")
|
|
# actions: List[Dict[str, Any]] = Field(default_factory=list, description="动作列表(动态组件渲染用)")
|
|
event_data: Optional[Dict[str, Any]] = Field(default_factory=dict, description="事件数据")
|
|
notes: Optional[str] = Field(None, description="备注")
|
|
reason: Optional[str] = Field(None, description="触发原因")
|
|
|
|
# 关联字段
|
|
source_scenario_id: Optional[int] = Field(None, description="来源场景ID")
|
|
owner_user_id: Optional[str] = Field(None, max_length=64, description="归属用户ID")
|
|
|
|
# 分配与状态
|
|
assignee_user_id: Optional[str] = Field(None, max_length=64, description="指派人用户ID")
|
|
assignee_username: Optional[str] = Field(None, max_length=64, description="指派人用户名")
|
|
status: TaskStatus = Field(TaskStatus.PENDING, description="任务状态")
|
|
|
|
# 自动化控制
|
|
due_at: Optional[datetime] = Field(None, description="截止时间")
|
|
auto_closeable: bool = Field(True, description="是否允许自动消除")
|
|
closed_by: Optional[str] = Field(None, max_length=32, description="关闭方式: manual/auto/expired")
|
|
|
|
|
|
class TaskCreate(TaskBase):
|
|
pass
|
|
|
|
|
|
class TaskUpdate(BaseModel):
|
|
title: Optional[str] = Field(None, max_length=255)
|
|
content: Optional[List[Dict[str, Any]]] = None
|
|
notes: Optional[str] = None
|
|
source_scenario_id: Optional[int] = None
|
|
related_order_id: Optional[str] = Field(None, max_length=64)
|
|
related_customer_id: Optional[str] = Field(None, max_length=64)
|
|
group_id: Optional[str] = Field(None, max_length=64)
|
|
assignee_user_id: Optional[str] = Field(None, max_length=64)
|
|
assignee_username: Optional[str] = Field(None, max_length=64)
|
|
status: Optional[TaskStatus] = None
|
|
due_at: Optional[datetime] = None
|
|
auto_closeable: Optional[bool] = None
|
|
closed_by: Optional[str] = Field(None, max_length=32)
|
|
completed_at: Optional[datetime] = None
|
|
|
|
# model_config = {"extra": "forbid"}
|
|
|
|
|
|
class TaskRead(TaskBase):
|
|
id: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
completed_at: Optional[datetime] = None
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ----------------------------
|
|
# Action Schemas
|
|
# ----------------------------
|
|
|
|
class ActionBase(BaseModel):
|
|
type: Optional[ActionType] = Field(None, description="操作类型")
|
|
detail: Dict[str, Any] = Field(default_factory=dict, description="操作详情")
|
|
done: bool = Field(False, description="是否已完成")
|
|
done_at: Optional[datetime] = Field(None, description="完成时间")
|
|
result: Dict[str, Any] = Field(default_factory=dict, description="操作结果")
|
|
userid: Optional[str] = Field(None, max_length=64, description="操作用户ID")
|
|
username: Optional[str] = Field(None, max_length=64, description="操作用户名称")
|
|
notes: Optional[str] = Field(None, description="操作备注")
|
|
task_id: int = Field(..., description="所属任务ID")
|
|
action_template_id: Optional[str] = Field(None, max_length=64, description="操作模板ID")
|
|
|
|
|
|
class ActionCreate(ActionBase):
|
|
pass
|
|
|
|
|
|
class ActionUpdate(BaseModel):
|
|
type: Optional[ActionType] = None
|
|
detail: Optional[Dict[str, Any]] = None
|
|
done: Optional[bool] = None
|
|
done_at: Optional[datetime] = None
|
|
result: Optional[Dict[str, Any]] = None
|
|
userid: Optional[str] = Field(None, max_length=64)
|
|
username: Optional[str] = Field(None, max_length=64)
|
|
notes: Optional[str] = None
|
|
task_id: Optional[int] = None
|
|
action_template_id: Optional[str] = Field(None, max_length=64)
|
|
|
|
model_config = {"extra": "forbid"}
|
|
|
|
|
|
class ActionRead(ActionBase):
|
|
id: int
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
class NotifyAction(BaseModel):
|
|
platform: str = Field(..., description="平台类型")
|
|
webhook_url: str = Field(..., description="Webhook URL")
|
|
template: str = Field(..., description="模板内容")
|
|
need_at: bool = Field(False, description="是否需要@用户")
|
|
|
|
__meta_mapping__ = {
|
|
"template": {"type": "text"}
|
|
}
|
|
|