#!/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"" 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()