| 
									
										
										
										
											2025-04-30 16:57:46 +08:00
										 |  |  |  | #!/usr/bin/env python | 
					
						
							|  |  |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | """
 | 
					
						
							|  |  |  |  | 天风任务API模型模块 | 
					
						
							|  |  |  |  | 包含天风任务管理API的请求和响应数据模型 | 
					
						
							|  |  |  |  | """
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | from typing import Optional, List, Dict, Any | 
					
						
							|  |  |  |  | import re | 
					
						
							|  |  |  |  | from pydantic import BaseModel, Field, validator | 
					
						
							|  |  |  |  | from routes.model.task_edit_model import TaskInputParam | 
					
						
							|  |  |  |  | from routes.model.base import PageResult, PaginationParams, SortParams | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class CreateTaskRequest(BaseModel): | 
					
						
							|  |  |  |  |     """创建任务请求模型""" | 
					
						
							|  |  |  |  |     label: str = Field(..., description="任务名称", min_length=2, max_length=50) | 
					
						
							|  |  |  |  |     taskType: int = Field(..., description="任务类型:1-普通任务,2-定时任务") | 
					
						
							|  |  |  |  |     mapId: Optional[str] = Field(..., description="地图ID") | 
					
						
							|  |  |  |  |     remark: Optional[str] = Field(None, description="任务备注") | 
					
						
							|  |  |  |  |     period: Optional[int] = Field(None, description="周期时间(毫秒),定时任务必填") | 
					
						
							|  |  |  |  |     delay: Optional[int] = Field(3000, description="延迟时间(毫秒),默认3000") | 
					
						
							|  |  |  |  |     releaseSites: Optional[bool] = Field(True, description="是否释放站点,默认true") | 
					
						
							|  |  |  |  |     token: Optional[str] = Field(None, description="用户token值,用于认证") | 
					
						
							|  |  |  |  |     tenantId: str = Field("default", description="租户ID,用于多租户隔离") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @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() | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('taskType') | 
					
						
							|  |  |  |  |     def validate_task_type(cls, v): | 
					
						
							|  |  |  |  |         """验证任务类型""" | 
					
						
							|  |  |  |  |         if v not in [1, 2]: | 
					
						
							|  |  |  |  |             raise ValueError('任务类型必须为1(普通任务)或2(定时任务)') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('period', always=True) | 
					
						
							|  |  |  |  |     def validate_period(cls, v, values): | 
					
						
							|  |  |  |  |         """验证周期时间""" | 
					
						
							|  |  |  |  |         if 'taskType' in values and values['taskType'] == 2 and not v: | 
					
						
							|  |  |  |  |             raise ValueError('定时任务必须指定周期时间') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class TaskDefCreateRequest(BaseModel): | 
					
						
							|  |  |  |  |     """任务定义创建请求模型""" | 
					
						
							|  |  |  |  |     label: str = Field(..., description="任务名称", min_length=2, max_length=50) | 
					
						
							|  |  |  |  |     task_type: int = Field(..., description="任务类型:1-普通任务,2-定时任务") | 
					
						
							|  |  |  |  |     remark: Optional[str] = Field(None, description="任务备注") | 
					
						
							|  |  |  |  |     period: Optional[int] = Field(None, description="周期时间(毫秒),定时任务必填") | 
					
						
							|  |  |  |  |     delay: Optional[int] = Field(3000, description="延迟时间(毫秒),默认3000") | 
					
						
							|  |  |  |  |     release_sites: Optional[bool] = Field(True, description="是否释放站点,默认true") | 
					
						
							|  |  |  |  |     token: Optional[str] = Field(None, description="用户token值,用于认证") | 
					
						
							|  |  |  |  |     tenant_id: str = Field("default", description="租户ID,用于多租户隔离") | 
					
						
							|  |  |  |  |     category_id: Optional[str] = Field(None, description="分类ID") | 
					
						
							|  |  |  |  |     template_id: Optional[str] = Field(None, description="模板ID") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @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() | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('task_type') | 
					
						
							|  |  |  |  |     def validate_task_type(cls, v): | 
					
						
							|  |  |  |  |         """验证任务类型""" | 
					
						
							|  |  |  |  |         if v not in [1, 2]: | 
					
						
							|  |  |  |  |             raise ValueError('任务类型必须为1(普通任务)或2(定时任务)') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('period', always=True) | 
					
						
							|  |  |  |  |     def validate_period(cls, v, values): | 
					
						
							|  |  |  |  |         """验证周期时间""" | 
					
						
							|  |  |  |  |         if 'task_type' in values and values['task_type'] == 2 and not v: | 
					
						
							|  |  |  |  |             raise ValueError('定时任务必须指定周期时间') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  | class TaskDefUpdateRequest(BaseModel): | 
					
						
							|  |  |  |  |     """任务定义更新请求模型""" | 
					
						
							|  |  |  |  |     label: Optional[str] = Field(None, description="任务名称", min_length=2, max_length=50) | 
					
						
							|  |  |  |  |     task_type: Optional[int] = Field(None, description="任务类型:1-普通任务,2-定时任务") | 
					
						
							|  |  |  |  |     remark: Optional[str] = Field(None, description="任务备注") | 
					
						
							|  |  |  |  |     period: Optional[int] = Field(None, description="周期时间(毫秒),定时任务必填") | 
					
						
							|  |  |  |  |     delay: Optional[int] = Field(None, description="延迟时间(毫秒)") | 
					
						
							|  |  |  |  |     release_sites: Optional[bool] = Field(None, description="是否释放站点") | 
					
						
							|  |  |  |  |     category_id: Optional[str] = Field(None, description="分类ID") | 
					
						
							|  |  |  |  |     template_id: Optional[str] = Field(None, description="模板ID") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('label') | 
					
						
							|  |  |  |  |     def label_must_not_be_empty_or_whitespace(cls, v): | 
					
						
							|  |  |  |  |         """验证任务名称不为空且不只包含空白字符""" | 
					
						
							|  |  |  |  |         if v is None: | 
					
						
							|  |  |  |  |             return v | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         if v.strip() == "": | 
					
						
							|  |  |  |  |             raise ValueError('任务名称不能为空') | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         # 检查是否只包含空白字符 | 
					
						
							|  |  |  |  |         if re.match(r'^\s+$', v): | 
					
						
							|  |  |  |  |             raise ValueError('任务名称不能只包含空格') | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |         # 检查是否包含特殊字符 | 
					
						
							|  |  |  |  |         if re.search(r'[<>:"/\\|?*]', v): | 
					
						
							|  |  |  |  |             raise ValueError('任务名称不能包含特殊字符 < > : " / \\ | ? *') | 
					
						
							|  |  |  |  |          | 
					
						
							|  |  |  |  |         return v.strip() | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('task_type') | 
					
						
							|  |  |  |  |     def validate_task_type(cls, v): | 
					
						
							|  |  |  |  |         """验证任务类型""" | 
					
						
							|  |  |  |  |         if v is None: | 
					
						
							|  |  |  |  |             return v | 
					
						
							|  |  |  |  |              | 
					
						
							|  |  |  |  |         if v not in [1, 2]: | 
					
						
							|  |  |  |  |             raise ValueError('任务类型必须为1(普通任务)或2(定时任务)') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class DeleteTaskRequest(BaseModel): | 
					
						
							|  |  |  |  |     """删除任务请求模型""" | 
					
						
							|  |  |  |  |     ids: List[str] = Field(..., description="要删除的任务ID数组") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('ids') | 
					
						
							|  |  |  |  |     def ids_must_not_be_empty(cls, v): | 
					
						
							|  |  |  |  |         """验证ID列表不为空""" | 
					
						
							|  |  |  |  |         if not v: | 
					
						
							|  |  |  |  |             raise ValueError('删除任务ID列表不能为空') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class RunTaskRequest(BaseModel): | 
					
						
							|  |  |  |  |     """运行任务请求模型""" | 
					
						
							|  |  |  |  |     taskId: str = Field(..., description="要运行的任务ID") | 
					
						
							|  |  |  |  |     params: List[TaskInputParam] = Field(..., description="任务运行参数,根据任务定义中的inputParams字段确定") | 
					
						
							|  |  |  |  |     priority: Optional[int] = Field(1, description="任务优先级,默认为1") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class ExportBatchRequest(BaseModel): | 
					
						
							|  |  |  |  |     """批量导出任务请求模型""" | 
					
						
							|  |  |  |  |     ids: List[str] = Field(..., description="要导出的任务ID数组") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('ids') | 
					
						
							|  |  |  |  |     def ids_must_not_be_empty(cls, v): | 
					
						
							|  |  |  |  |         """验证ID列表不为空""" | 
					
						
							|  |  |  |  |         if not v: | 
					
						
							|  |  |  |  |             raise ValueError('导出任务ID列表不能为空') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class BatchTaskRequest(BaseModel): | 
					
						
							|  |  |  |  |     """批量任务操作请求模型""" | 
					
						
							|  |  |  |  |     operation: str = Field(..., description="操作类型:delete-删除,update_status-更新状态") | 
					
						
							|  |  |  |  |     ids: List[str] = Field(..., description="要操作的任务ID数组") | 
					
						
							|  |  |  |  |     status: Optional[str] = Field(None, description="当操作类型为update_status时,指定要更新的状态") | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('operation') | 
					
						
							|  |  |  |  |     def validate_operation(cls, v): | 
					
						
							|  |  |  |  |         """验证操作类型""" | 
					
						
							|  |  |  |  |         if v not in ["delete", "update_status"]: | 
					
						
							|  |  |  |  |             raise ValueError('操作类型必须为delete或update_status') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('ids') | 
					
						
							|  |  |  |  |     def ids_must_not_be_empty(cls, v): | 
					
						
							|  |  |  |  |         """验证ID列表不为空""" | 
					
						
							|  |  |  |  |         if not v: | 
					
						
							|  |  |  |  |             raise ValueError('操作任务ID列表不能为空') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     @validator('status', always=True) | 
					
						
							|  |  |  |  |     def validate_status(cls, v, values): | 
					
						
							|  |  |  |  |         """验证状态值""" | 
					
						
							|  |  |  |  |         if 'operation' in values and values['operation'] == 'update_status' and not v: | 
					
						
							|  |  |  |  |             raise ValueError('更新状态操作必须指定状态值') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class BatchTaskResponse(BaseModel): | 
					
						
							|  |  |  |  |     """批量任务操作响应模型""" | 
					
						
							|  |  |  |  |     success_count: int = Field(..., description="成功处理的任务数量") | 
					
						
							|  |  |  |  |     failed_ids: List[str] = Field(..., description="处理失败的任务ID列表") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class TaskResponse(BaseModel): | 
					
						
							|  |  |  |  |     """任务响应模型""" | 
					
						
							|  |  |  |  |     id: str = Field(..., description="任务ID") | 
					
						
							| 
									
										
										
										
											2025-07-14 10:29:37 +08:00
										 |  |  |  |     label: str = Field(..., description="任务名称", min_length=1, max_length=100) | 
					
						
							| 
									
										
										
										
											2025-04-30 16:57:46 +08:00
										 |  |  |  |     version: int = Field(..., description="任务版本号") | 
					
						
							|  |  |  |  |     status: int = Field(..., description="任务状态") | 
					
						
							|  |  |  |  |     createDate: Any = Field(None, description="创建日期") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class TaskRunResponse(BaseModel): | 
					
						
							|  |  |  |  |     """任务运行响应模型""" | 
					
						
							|  |  |  |  |     taskRecordId: str = Field(..., description="任务记录ID") | 
					
						
							|  |  |  |  |     status: int = Field(..., description="任务状态") | 
					
						
							|  |  |  |  |     createTime: Any = Field(..., description="创建时间") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | class TaskListParams(PaginationParams, SortParams): | 
					
						
							|  |  |  |  |     """任务列表查询参数模型""" | 
					
						
							|  |  |  |  |     keyword: Optional[str] = Field(None, description="关键字搜索(任务名称)") | 
					
						
							|  |  |  |  |     status: Optional[int] = Field(None, description="任务状态筛选") | 
					
						
							| 
									
										
										
										
											2025-07-14 10:29:37 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | class SetTaskErrorRequest(BaseModel): | 
					
						
							|  |  |  |  |     """设置任务错误状态请求模型""" | 
					
						
							|  |  |  |  |     error_reason: str = Field(..., description="错误原因", example="系统异常导致任务失败") | 
					
						
							| 
									
										
										
										
											2025-10-13 14:52:58 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | class SwitchRobotRequest(BaseModel): | 
					
						
							|  |  |  |  |     """换机器人请求模型""" | 
					
						
							|  |  |  |  |     # 选择机器人相关参数(必填) | 
					
						
							|  |  |  |  |     robot_name: Optional[str] = Field(None, description="机器人名称") | 
					
						
							|  |  |  |  |     robot_group: Optional[str] = Field(None, description="机器人组") | 
					
						
							|  |  |  |  |     robot_label_group: Optional[str] = Field(None, description="机器人标签组") | 
					
						
							|  |  |  |  |     switch_reason: str = Field(..., description="更换原因") | 
					
						
							|  |  |  |  |     has_cargo: bool = Field(..., description="是否载货,true-已载货,false-未载货") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # 已载货时的额外参数 | 
					
						
							|  |  |  |  |     site_id: Optional[str] = Field(None, description="库位ID(已载货时必填)") | 
					
						
							|  |  |  |  |     action: Optional[str] = Field(None, description="执行动作(已载货时必填),如:pick/drop") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @validator('site_id', always=True) | 
					
						
							|  |  |  |  |     def validate_site_id(cls, v, values): | 
					
						
							|  |  |  |  |         """验证库位ID:已载货时必填""" | 
					
						
							|  |  |  |  |         if values.get('has_cargo') and not v: | 
					
						
							|  |  |  |  |             raise ValueError('已载货时必须指定库位ID') | 
					
						
							|  |  |  |  |         return v | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     @validator('action', always=True) | 
					
						
							|  |  |  |  |     def validate_action(cls, v, values): | 
					
						
							|  |  |  |  |         """验证执行动作:已载货时必填""" | 
					
						
							|  |  |  |  |         if values.get('has_cargo') and not v: | 
					
						
							|  |  |  |  |             raise ValueError('已载货时必须指定执行动作') | 
					
						
							|  |  |  |  |         return v |