254 lines
11 KiB
Python
254 lines
11 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
天风任务编辑API模型模块
|
||
包含任务编辑相关的请求和响应数据模型
|
||
"""
|
||
|
||
from typing import Optional, List, Dict, Any, Union
|
||
from enum import Enum
|
||
from datetime import datetime
|
||
from pydantic import BaseModel, Field, validator
|
||
import re
|
||
|
||
from routes.model.base import PageResult, PaginationParams
|
||
|
||
# 参数类型枚举
|
||
class ParamType(str, Enum):
|
||
ROBOT_ID = "robotId"
|
||
ROBOT_GROUP = "robotGroup"
|
||
SITE_ID = "siteId"
|
||
AREA = "area"
|
||
STATION = "station"
|
||
BUILT_IN_FUNCTION = "builtInFunction"
|
||
|
||
# 参数值类型枚举
|
||
class ParamValueType(str, Enum):
|
||
SIMPLE = "Simple"
|
||
EXPRESSION = "Expression"
|
||
JSON = "JSON"
|
||
|
||
# 任务参数模型
|
||
class TaskParam(BaseModel):
|
||
"""任务参数模型"""
|
||
name: str = Field(..., description="参数名称")
|
||
type: str = Field(..., description="参数类型")
|
||
label: str = Field(..., description="参数显示名称")
|
||
required: bool = Field(False, description="是否必填")
|
||
defaultValue: Optional[Any] = Field(None, description="默认值")
|
||
remark: Optional[str] = Field(None, description="备注说明")
|
||
description: Optional[str] = Field(None, description="详细描述")
|
||
options: List[Dict[str, Any]] = Field(default=[], description="可选值列表")
|
||
|
||
# 参数值模型
|
||
class ParamValue(BaseModel):
|
||
"""参数值模型"""
|
||
type: ParamValueType = Field(..., description="值类型")
|
||
value: Any = Field(..., description="参数值")
|
||
required: Optional[bool] = Field(None, description="是否必填")
|
||
|
||
# 块基本模型
|
||
class BlockBase(BaseModel):
|
||
"""块基本模型"""
|
||
id: int = Field(..., description="块ID")
|
||
name: str = Field(..., description="块名称")
|
||
blockType: str = Field(..., description="块类型")
|
||
inputParams: Dict[str, ParamValue] = Field(default={}, description="输入参数")
|
||
children: Dict[str, List[Any]] = Field(default={}, description="子块列表")
|
||
selected: bool = Field(False, description="是否选中")
|
||
expanded: bool = Field(True, description="是否展开")
|
||
refTaskDefId: Optional[str] = Field(None, description="引用的任务定义ID")
|
||
|
||
# 任务详细定义模型
|
||
class TaskDetail(BaseModel):
|
||
"""任务详细定义模型"""
|
||
inputParams: List[TaskParam] = Field(default=[], description="输入参数列表")
|
||
outputParams: List[TaskParam] = Field(default=[], description="输出参数列表")
|
||
rootBlock: BlockBase = Field(..., description="根块配置")
|
||
|
||
# 任务定义模型
|
||
class TaskDefinition(BaseModel):
|
||
"""任务定义模型"""
|
||
id: str = Field(..., description="任务ID")
|
||
label: str = Field(..., description="任务名称")
|
||
detail: TaskDetail = Field(..., description="任务详细定义")
|
||
version: Optional[int] = Field(None, description="任务版本号")
|
||
delay: Optional[int] = Field(None, description="延迟时间(毫秒)")
|
||
if_enable: Optional[int] = Field(None, description="是否启用")
|
||
period: Optional[int] = Field(None, description="周期时间(毫秒)")
|
||
periodic_task: Optional[int] = Field(None, description="是否为周期任务")
|
||
remark: Optional[str] = Field(None, description="备注")
|
||
status: Optional[int] = Field(None, description="任务状态")
|
||
template_name: Optional[str] = Field(None, description="模板名称")
|
||
template_description: Optional[str] = Field(None, description="模板描述")
|
||
create_date: Optional[datetime] = Field(None, description="创建时间")
|
||
created_by: Optional[str] = Field(None, description="创建者")
|
||
update_date: Optional[datetime] = Field(None, description="更新时间")
|
||
updated_by: Optional[str] = Field(None, description="更新者")
|
||
|
||
# 任务基本信息模型
|
||
class TaskBasicInfo(BaseModel):
|
||
"""任务基本信息"""
|
||
label: str = Field(..., description="任务名称")
|
||
remark: Optional[str] = Field(None, description="备注")
|
||
releaseSites: bool = Field(True, description="是否释放站点")
|
||
|
||
@validator('label')
|
||
def label_must_not_be_empty_or_whitespace(cls, v):
|
||
"""验证任务名称不为空且不只包含空白字符"""
|
||
if not v or v.strip() == "":
|
||
raise ValueError('任务名称不能为空')
|
||
|
||
# 检查是否只包含空白字符
|
||
if re.match(r'^\s+$', v):
|
||
raise ValueError('任务名称不能只包含空格')
|
||
|
||
# 检查是否包含特殊字符
|
||
if re.search(r'[<>:"/\\|?*]', v):
|
||
raise ValueError('任务名称不能包含特殊字符 < > : " / \\ | ? *')
|
||
|
||
return v.strip()
|
||
|
||
# 任务备份请求模型
|
||
class TaskBackupRequest(BaseModel):
|
||
"""任务备份请求模型"""
|
||
backup_name: Optional[str] = Field(None, description="备份后的任务名称")
|
||
remark: Optional[str] = Field(None, description="备份任务的备注信息")
|
||
|
||
# 子任务列表查询参数
|
||
class SubTaskListParams(PaginationParams):
|
||
"""子任务列表查询参数"""
|
||
keyword: Optional[str] = Field(None, description="搜索关键词")
|
||
exclude_id: str = Field(..., description="要排除的任务ID,必填")
|
||
|
||
# 子任务列表项模型
|
||
class SubTaskListItem(BaseModel):
|
||
"""子任务列表项模型"""
|
||
id: str = Field(..., description="任务ID")
|
||
label: str = Field(..., description="任务名称")
|
||
version: int = Field(..., description="版本号")
|
||
templateName: str = Field(..., description="模板名称")
|
||
remark: Optional[str] = Field(None, description="备注")
|
||
createDate: str = Field(..., description="创建时间")
|
||
createdBy: str = Field(..., description="创建者")
|
||
status: int = Field(..., description="状态")
|
||
inputParams: List[TaskParam] = Field(..., description="输入参数")
|
||
|
||
# 子任务列表响应模型
|
||
class SubTaskListResponse(BaseModel):
|
||
"""子任务列表响应模型"""
|
||
total: int = Field(..., description="总记录数")
|
||
list: List[SubTaskListItem] = Field(..., description="子任务列表")
|
||
|
||
# 常用参数字段模型
|
||
class CommonParamField(BaseModel):
|
||
"""常用参数字段模型"""
|
||
id: str = Field(..., description="字段ID")
|
||
label: str = Field(..., description="字段标签")
|
||
type: str = Field(..., description="字段类型")
|
||
description: Optional[str] = Field(None, description="字段描述")
|
||
example: Optional[str] = Field(None, description="示例值")
|
||
placeholder: Optional[str] = Field(None, description="占位提示")
|
||
order: int = Field(..., description="排序")
|
||
values: List[Dict[str, Any]] = Field(default=[], description="可选值列表")
|
||
|
||
# 输入参数类型信息模型
|
||
class InputParamTypeInfo(BaseModel):
|
||
"""输入参数类型信息模型"""
|
||
types: List[Dict[str, Any]] = Field(..., description="参数类型列表")
|
||
fields: List[Dict[str, Any]] = Field(..., description="字段配置列表")
|
||
|
||
# 输入参数类型枚举
|
||
class InputParamType(str, Enum):
|
||
"""输入参数类型枚举"""
|
||
STRING = "STRING" # 字符串
|
||
BOOLEAN = "BOOLEAN" # 布尔
|
||
INTEGER = "INTEGER" # 整数
|
||
FLOAT = "FLOAT" # 浮点数
|
||
OBJECT = "OBJECT" # JSON对象
|
||
ARRAY = "ARRAY" # JSON数组
|
||
|
||
class TaskInputParam(BaseModel):
|
||
"""任务输入参数模型"""
|
||
name: str = Field(..., description="参数名称")
|
||
type: InputParamType = Field(..., description="参数类型")
|
||
label: str = Field(..., description="参数显示名称")
|
||
required: bool = Field(False, description="是否必填")
|
||
defaultValue: str = Field("", description="默认值")
|
||
remark: str = Field("", description="参数说明")
|
||
|
||
class TaskInputParamNew(BaseModel):
|
||
"""任务输入参数模型"""
|
||
name: str = Field(..., description="参数名称")
|
||
type: InputParamType = Field(..., description="参数类型")
|
||
label: str = Field(..., description="参数显示名称")
|
||
required: bool = Field(False, description="是否必填")
|
||
defaultValue: str = Field(..., description="默认值")
|
||
remark: str = Field("", description="参数说明")
|
||
|
||
# 任务运行请求模型
|
||
class TaskEditRunRequest(BaseModel):
|
||
"""任务运行请求模型"""
|
||
taskId: str = Field(..., description="要运行的任务ID")
|
||
params: List[TaskInputParamNew] = Field(None, description="任务运行参数,根据任务定义中的inputParams字段确定")
|
||
source_type: Optional[int] = Field(..., description="任务来源类型(1: 系统调度, 2: 呼叫机, 3: 第三方系统, 4: 手持电脑)")
|
||
source_system: Optional[str] = Field(..., description="来源系统标识(如:WMS、MES等系统编号)")
|
||
source_device: Optional[str] = Field(..., description="下达任务的硬件设备标识(设备ID、MAC地址等)")
|
||
|
||
|
||
# 重新定义更准确的任务参数模型,确保包含所有必要字段
|
||
class TaskParamSave(BaseModel):
|
||
"""任务参数保存模型"""
|
||
name: str = Field(..., description="参数名称")
|
||
type: str = Field(..., description="参数类型")
|
||
label: str = Field(..., description="参数显示名称")
|
||
remark: str = Field("", description="备注说明")
|
||
defaultValue: str = Field("", description="默认值")
|
||
required: bool = Field(False, description="是否必填")
|
||
|
||
# 重新定义块参数值模型
|
||
class BlockParamValue(BaseModel):
|
||
"""块参数值模型"""
|
||
type: ParamValueType = Field(..., description="值类型")
|
||
value: Any = Field(..., description="参数值")
|
||
required: Optional[bool] = Field(None, description="是否必填")
|
||
|
||
# 递归定义块模型
|
||
class BlockModel(BaseModel):
|
||
"""块模型,可以递归包含子块"""
|
||
id: int = Field(..., description="块ID")
|
||
name: str = Field(..., description="块名称")
|
||
blockType: str = Field(..., description="块类型")
|
||
inputParams: Dict[str, BlockParamValue] = Field(default_factory=dict, description="输入参数")
|
||
children: Dict[str, List['BlockModel']] = Field(default_factory=dict, description="子块列表")
|
||
refTaskDefId: str = Field("", description="引用的任务定义ID")
|
||
selected: bool = Field(False, description="是否选中")
|
||
expanded: bool = Field(True, description="是否展开")
|
||
|
||
# 支持递归定义
|
||
BlockModel.update_forward_refs()
|
||
|
||
# 任务详细定义保存模型
|
||
class TaskDetailSave(BaseModel):
|
||
"""任务详细定义保存模型"""
|
||
inputParams: List[TaskParamSave] = Field(default_factory=list, description="输入参数列表")
|
||
outputParams: List[TaskParamSave] = Field(default_factory=list, description="输出参数列表")
|
||
rootBlock: BlockModel = Field(..., description="根块配置")
|
||
|
||
# 任务保存请求模型
|
||
class TaskSaveRequest(BaseModel):
|
||
"""任务保存请求模型"""
|
||
id: str = Field(..., description="任务ID")
|
||
detail: TaskDetailSave = Field(..., description="任务详细定义")
|
||
|
||
@validator('detail')
|
||
def validate_detail(cls, v):
|
||
"""验证任务详细定义"""
|
||
# 验证rootBlock的blockType是否为RootBp
|
||
if v.rootBlock.blockType != 'RootBp':
|
||
raise ValueError('rootBlock的blockType必须为RootBp')
|
||
|
||
return v
|
||
|