#!/usr/bin/env python # -*- coding: utf-8 -*- """ 外部任务记录服务模块 提供外部任务记录相关的服务方法 """ import json import uuid from typing import Dict, List, Any, Optional from sqlalchemy import select, and_, or_ import datetime from data.models.external_task_record import VWEDExternalTaskRecord, ExternalTaskTypeEnum, ExternalTaskStatusEnum from data.session import get_async_session from utils.logger import get_logger # 设置日志 logger = get_logger("service.external_task_record_service") class ExternalTaskRecordService: """ 外部任务记录服务类 提供与外部任务记录相关的方法 """ @staticmethod async def create_new_task_record( req_code: str, source_id: str, target_id: str, business_task_type: str, template_id: str, request_params: Dict[str, Any], client_ip: str = None, client_info: str = None ) -> VWEDExternalTaskRecord: """ 创建newTask任务记录 Args: req_code: 请求标识码 source_id: 来源ID target_id: 目标ID business_task_type: 业务任务类型 template_id: 任务模板ID request_params: 请求参数 client_ip: 客户端IP client_info: 客户端信息 Returns: VWEDExternalTaskRecord: 创建的外部任务记录 """ try: async with get_async_session() as session: # 生成唯一ID record_id = str(uuid.uuid4()) # 创建外部任务记录 external_record = VWEDExternalTaskRecord( id=record_id, req_code=req_code, task_type=ExternalTaskTypeEnum.NEW_TASK, task_status=ExternalTaskStatusEnum.PENDING, source_id=source_id, target_id=target_id, business_task_type=business_task_type, template_id=template_id, request_params=json.dumps(request_params, ensure_ascii=False), client_ip=client_ip, client_info=client_info, start_time=datetime.datetime.now() ) session.add(external_record) await session.commit() await session.refresh(external_record) logger.info(f"创建newTask任务记录成功: record_id={record_id}, req_code={req_code}") return external_record except Exception as e: logger.error(f"创建newTask任务记录失败: {str(e)}, req_code={req_code}") raise @staticmethod async def create_agv_scheduling_task_record( req_code: str, task_code: str, business_task_type: str, security_key: str, type_field: str, sub_type: str, area_position_code: str, area_position_name: str, position_code_path: List[Dict[str, Any]], template_id: str, request_params: Dict[str, Any], client_code: str = None, token_code: str = None, client_ip: str = None, client_info: str = None, related_req_code: str = None ) -> VWEDExternalTaskRecord: """ 创建GenAgvSchedulingTask任务记录 Args: req_code: 请求标识码 task_code: 任务代码 business_task_type: 业务任务类型 security_key: 安全密钥 type_field: 类型字段 sub_type: 子类型 area_position_code: 区域位置代码 area_position_name: 区域位置名称 position_code_path: 位置代码路径 template_id: 任务模板ID request_params: 请求参数 client_code: 客户端代码 token_code: 令牌代码 client_ip: 客户端IP client_info: 客户端信息 related_req_code: 关联的ReqCode Returns: VWEDExternalTaskRecord: 创建的外部任务记录 """ try: async with get_async_session() as session: # 生成唯一ID record_id = str(uuid.uuid4()) # 创建外部任务记录 external_record = VWEDExternalTaskRecord( id=record_id, req_code=req_code, task_type=ExternalTaskTypeEnum.GEN_AGV_SCHEDULING_TASK, task_status=ExternalTaskStatusEnum.PENDING, task_code=task_code, business_task_type=business_task_type, security_key=security_key, type_field=type_field, sub_type=sub_type, area_position_code=area_position_code, area_position_name=area_position_name, position_code_path=json.dumps(position_code_path, ensure_ascii=False), client_code=client_code, token_code=token_code, template_id=template_id, request_params=json.dumps(request_params, ensure_ascii=False), client_ip=client_ip, client_info=client_info, related_req_code=related_req_code, start_time=datetime.datetime.now() ) session.add(external_record) await session.commit() await session.refresh(external_record) logger.info(f"创建GenAgvSchedulingTask任务记录成功: record_id={record_id}, req_code={req_code}, task_code={task_code}") return external_record except Exception as e: logger.error(f"创建GenAgvSchedulingTask任务记录失败: {str(e)}, req_code={req_code}") raise @staticmethod async def update_task_record_status( req_code: str, task_status: ExternalTaskStatusEnum, task_record_id: str = None, response_code: int = None, response_message: str = None, response_row_count: int = None, response_data: Dict[str, Any] = None, error_message: str = None, error_stack: str = None ) -> bool: """ 更新外部任务记录状态 Args: req_code: 请求标识码 task_status: 任务状态 task_record_id: 内部任务记录ID response_code: 响应状态码 response_message: 响应消息 response_row_count: 响应行数 response_data: 响应数据 error_message: 错误信息 error_stack: 错误堆栈 Returns: bool: 更新是否成功 """ try: async with get_async_session() as session: # 查询外部任务记录 query = select(VWEDExternalTaskRecord).where( VWEDExternalTaskRecord.id == req_code ) result = await session.execute(query) external_record = result.scalar_one_or_none() if not external_record: logger.error(f"外部任务记录不存在: req_code={req_code}") return False # 更新状态和相关信息 response_data_json = None if response_data: try: response_data_json = json.dumps(response_data, ensure_ascii=False, default=str) except Exception as e: # logger.warning(f"序列化response_data失败: {str(e)}") response_data_json = str(response_data) external_record.update_status(task_status, error_message, response_data_json) if task_record_id: external_record.task_record_id = task_record_id if response_code is not None: external_record.response_code = response_code if response_message: external_record.response_message = json.dumps(response_message, ensure_ascii=False) if response_row_count is not None: external_record.response_row_count = response_row_count if error_stack: external_record.error_stack = error_stack await session.commit() logger.info(f"更新外部任务记录状态成功: req_code={req_code}, status={task_status}") return True except Exception as e: logger.error(f"更新外部任务记录状态失败: {str(e)}, req_code={req_code}") return False @staticmethod async def get_external_task_record(req_code: str) -> Optional[VWEDExternalTaskRecord]: """ 根据ReqCode获取外部任务记录 Args: req_code: 请求标识码 Returns: Optional[VWEDExternalTaskRecord]: 外部任务记录或None """ try: async with get_async_session() as session: query = select(VWEDExternalTaskRecord).where( VWEDExternalTaskRecord.req_code == req_code ).order_by(VWEDExternalTaskRecord.created_at.desc()).limit(1) result = await session.execute(query) return result.scalar_one_or_none() except Exception as e: logger.error(f"获取外部任务记录失败: {str(e)}, req_code={req_code}") return None @staticmethod async def get_related_tasks(req_code: str) -> List[VWEDExternalTaskRecord]: """ 获取关联的任务记录(通过req_code和related_req_code关联) Args: req_code: 请求标识码 Returns: List[VWEDExternalTaskRecord]: 关联的任务记录列表 """ try: async with get_async_session() as session: query = select(VWEDExternalTaskRecord).where( or_( VWEDExternalTaskRecord.req_code == req_code, VWEDExternalTaskRecord.related_req_code == req_code ) ) result = await session.execute(query) return result.scalars().all() except Exception as e: logger.error(f"获取关联任务记录失败: {str(e)}, req_code={req_code}") return [] @staticmethod async def get_task_records_by_task_code(task_code: str) -> List[VWEDExternalTaskRecord]: """ 根据TaskCode获取任务记录 Args: task_code: 任务代码 Returns: List[VWEDExternalTaskRecord]: 任务记录列表 """ try: async with get_async_session() as session: query = select(VWEDExternalTaskRecord).where( VWEDExternalTaskRecord.req_code == task_code ) result = await session.execute(query) return result.scalars().all() except Exception as e: logger.error(f"根据TaskCode获取任务记录失败: {str(e)}, task_code={task_code}") return [] @staticmethod async def check_task_completion_status(task_record_id: str) -> Optional[Dict[str, Any]]: """ 检查任务是否完成(通过内部任务记录ID查询) Args: task_record_id: 内部任务记录ID Returns: Optional[Dict[str, Any]]: 任务状态信息或None """ try: # 这里需要查询内部任务记录表来获取任务状态 # 可以根据实际需求实现具体的查询逻辑 from data.models.taskrecord import VWEDTaskRecord async with get_async_session() as session: query = select(VWEDTaskRecord).where( VWEDTaskRecord.id == task_record_id ) result = await session.execute(query) task_record = result.scalar_one_or_none() if not task_record: return None return { "task_record_id": task_record_id, "status": task_record.status, "ended_on": task_record.ended_on, "ended_reason": task_record.ended_reason, "state_description": task_record.state_description } except Exception as e: logger.error(f"检查任务完成状态失败: {str(e)}, task_record_id={task_record_id}") return None