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