137 lines
6.2 KiB
Python
137 lines
6.2 KiB
Python
|
#!/usr/bin/env python
|
|||
|
# -*- coding: utf-8 -*-
|
|||
|
|
|||
|
"""
|
|||
|
外部任务执行记录模型
|
|||
|
用于记录外部接口调用的任务执行情况
|
|||
|
"""
|
|||
|
|
|||
|
import datetime
|
|||
|
from sqlalchemy import Column, String, Integer, Text, Boolean, Index, Enum as SQLEnum
|
|||
|
from sqlalchemy.dialects.mysql import DATETIME, LONGTEXT
|
|||
|
from data.models.base import BaseModel
|
|||
|
import enum
|
|||
|
|
|||
|
class ExternalTaskTypeEnum(enum.Enum):
|
|||
|
"""外部任务类型枚举"""
|
|||
|
NEW_TASK = "newTask" # /newTask 接口
|
|||
|
GEN_AGV_SCHEDULING_TASK = "GenAgvSchedulingTask" # /GenAgvSchedulingTask 接口
|
|||
|
|
|||
|
class ExternalTaskStatusEnum(enum.Enum):
|
|||
|
"""外部任务状态枚举"""
|
|||
|
PENDING = "pending" # 待执行
|
|||
|
RUNNING = "running" # 执行中
|
|||
|
SUCCESS = "success" # 执行成功
|
|||
|
FAILED = "failed" # 执行失败
|
|||
|
CANCELLED = "cancelled" # 已取消
|
|||
|
|
|||
|
class VWEDExternalTaskRecord(BaseModel):
|
|||
|
"""
|
|||
|
外部任务执行记录模型
|
|||
|
对应vwed_external_task_record表
|
|||
|
功能:记录外部接口调用的任务执行情况和关联关系
|
|||
|
"""
|
|||
|
__tablename__ = 'vwed_external_task_record'
|
|||
|
|
|||
|
__table_args__ = (
|
|||
|
Index('idx_external_task_req_code', 'req_code'),
|
|||
|
Index('idx_external_task_task_code', 'task_code'),
|
|||
|
Index('idx_external_task_type', 'task_type'),
|
|||
|
Index('idx_external_task_status', 'task_status'),
|
|||
|
Index('idx_external_task_record_id', 'task_record_id'),
|
|||
|
Index('idx_external_task_related_req_code', 'related_req_code'),
|
|||
|
Index('idx_external_task_created_at', 'created_at'),
|
|||
|
{
|
|||
|
'mysql_engine': 'InnoDB',
|
|||
|
'mysql_charset': 'utf8mb4',
|
|||
|
'mysql_collate': 'utf8mb4_general_ci',
|
|||
|
'info': {'order_by': 'created_at DESC'}
|
|||
|
}
|
|||
|
)
|
|||
|
|
|||
|
# 主键和基本信息
|
|||
|
id = Column(String(255), primary_key=True, nullable=False, comment='主键ID')
|
|||
|
req_code = Column(String(255), nullable=False, comment='请求标识码(ReqCode)')
|
|||
|
task_type = Column(SQLEnum(ExternalTaskTypeEnum), nullable=False, comment='外部任务类型(newTask或GenAgvSchedulingTask)')
|
|||
|
task_status = Column(SQLEnum(ExternalTaskStatusEnum), nullable=False, default=ExternalTaskStatusEnum.PENDING, comment='任务状态')
|
|||
|
|
|||
|
# 关联字段 - 用于两个任务之间的关联
|
|||
|
task_code = Column(String(255), comment='任务代码(TaskCode,GenAgvSchedulingTask专用)')
|
|||
|
related_req_code = Column(String(255), comment='关联的ReqCode(用于关联newTask和GenAgvSchedulingTask)')
|
|||
|
|
|||
|
# TaskEditService.run_task 返回的任务记录ID
|
|||
|
task_record_id = Column(String(255), comment='内部任务记录ID(用于检测任务是否结束)')
|
|||
|
|
|||
|
# newTask 接口专用字段
|
|||
|
source_id = Column(String(255), comment='来源ID(SourceID)')
|
|||
|
target_id = Column(String(255), comment='目标ID(TargetID)')
|
|||
|
business_task_type = Column(String(50), comment='业务任务类型(TaskType,如GT2MP)')
|
|||
|
|
|||
|
# GenAgvSchedulingTask 接口专用字段
|
|||
|
security_key = Column(String(255), comment='安全密钥(SecurityKey)')
|
|||
|
type_field = Column(String(50), comment='类型字段(Type)')
|
|||
|
sub_type = Column(String(50), comment='子类型(SubType)')
|
|||
|
area_position_code = Column(String(255), comment='区域位置代码(AreaPositonCode)')
|
|||
|
area_position_name = Column(String(255), comment='区域位置名称(AreaPositonName)')
|
|||
|
position_code_path = Column(LONGTEXT, comment='位置代码路径JSON(PositionCodePath)')
|
|||
|
client_code = Column(String(255), comment='客户端代码(ClientCode)')
|
|||
|
token_code = Column(String(255), comment='令牌代码(TokenCode)')
|
|||
|
|
|||
|
# 请求和响应信息
|
|||
|
request_params = Column(LONGTEXT, comment='完整请求参数JSON')
|
|||
|
response_data = Column(LONGTEXT, comment='完整响应数据JSON')
|
|||
|
response_code = Column(Integer, comment='响应状态码')
|
|||
|
response_message = Column(Text, comment='响应消息')
|
|||
|
response_row_count = Column(Integer, comment='响应行数(rowCount)')
|
|||
|
|
|||
|
# 执行时间信息
|
|||
|
start_time = Column(DATETIME(fsp=6), comment='任务开始时间')
|
|||
|
end_time = Column(DATETIME(fsp=6), comment='任务结束时间')
|
|||
|
duration = Column(Integer, comment='执行时长(毫秒)')
|
|||
|
|
|||
|
# 客户端信息
|
|||
|
client_ip = Column(String(50), comment='客户端IP地址')
|
|||
|
client_info = Column(Text, comment='客户端信息JSON')
|
|||
|
|
|||
|
# 任务模板信息
|
|||
|
template_id = Column(String(255), comment='使用的任务模板ID')
|
|||
|
|
|||
|
# 错误信息
|
|||
|
error_message = Column(Text, comment='错误信息')
|
|||
|
error_stack = Column(LONGTEXT, comment='错误堆栈信息')
|
|||
|
|
|||
|
# 备注信息
|
|||
|
remarks = Column(Text, comment='备注信息')
|
|||
|
|
|||
|
def __repr__(self):
|
|||
|
return f"<VWEDExternalTaskRecord(id='{self.id}', req_code='{self.req_code}', task_type='{self.task_type}', status='{self.task_status}')>"
|
|||
|
|
|||
|
def is_completed(self):
|
|||
|
"""判断任务是否已完成(成功或失败)"""
|
|||
|
return self.task_status in [ExternalTaskStatusEnum.SUCCESS, ExternalTaskStatusEnum.FAILED, ExternalTaskStatusEnum.CANCELLED]
|
|||
|
|
|||
|
def update_status(self, status, error_message=None, response_data=None):
|
|||
|
"""更新任务状态"""
|
|||
|
self.task_status = status
|
|||
|
if error_message:
|
|||
|
self.error_message = error_message
|
|||
|
if response_data:
|
|||
|
self.response_data = response_data
|
|||
|
|
|||
|
# 更新时间信息
|
|||
|
now = datetime.datetime.now()
|
|||
|
if status == ExternalTaskStatusEnum.RUNNING and not self.start_time:
|
|||
|
self.start_time = now
|
|||
|
elif status in [ExternalTaskStatusEnum.SUCCESS, ExternalTaskStatusEnum.FAILED, ExternalTaskStatusEnum.CANCELLED]:
|
|||
|
if not self.end_time:
|
|||
|
self.end_time = now
|
|||
|
if self.start_time and not self.duration:
|
|||
|
self.duration = int((self.end_time - self.start_time).total_seconds() * 1000) # 毫秒
|
|||
|
|
|||
|
def get_related_task(self, session):
|
|||
|
"""获取关联的任务记录"""
|
|||
|
if not self.related_req_code:
|
|||
|
return None
|
|||
|
return session.query(VWEDExternalTaskRecord).filter(
|
|||
|
VWEDExternalTaskRecord.req_code == self.related_req_code
|
|||
|
).first()
|