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
|
|||
|
|