VWED_server/data/models/external_task_record.py

137 lines
6.2 KiB
Python
Raw Normal View History

2025-08-13 15:27:04 +08:00
#!/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='任务代码TaskCodeGenAgvSchedulingTask专用')
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='来源IDSourceID')
target_id = Column(String(255), comment='目标IDTargetID')
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='位置代码路径JSONPositionCodePath')
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()