#!/usr/bin/env python # -*- coding: utf-8 -*- """ 库位处理器模块 提供与库位操作相关的各种处理器 """ import logging import json import asyncio import aiohttp import uuid from typing import Dict, Any, List, Optional from services.execution.task_context import TaskContext from .base import BlockHandler, register_handler from config.settings import settings from utils.logger import get_logger from .model.block_name import StorageBlockName # 获取日志记录器 logger = get_logger("services.execution.handlers.storage_location") # 提取公共的API调用函数 async def call_storage_api(api_name: str, params: Dict[str, Any]) -> Dict[str, Any]: """ 调用库位服务API的通用函数 Args: api_name: API名称,对应API_ENDPOINTS中的键 params: API参数 Returns: API响应结果 """ # 获取API端点和方法 endpoint = settings.STORAGE_API_ENDPOINTS.get(api_name) method = settings.STORAGE_API_METHODS.get(api_name) if not endpoint or not method: logger.error(f"未找到API端点或方法:{api_name}") return { "success": False, "message": f"未找到API配置: {api_name}" } # 检查是否启用测试模式 if settings.STORAGE_API_MOCK_MODE: logger.info(f"[测试模式] 模拟调用API: {api_name}, 参数: {params}") # 构造测试模式下的响应 test_response = generate_mock_response(api_name, params) return test_response # 构建完整的URL url = f"{settings.STORAGE_API_BASE_URL}{endpoint}" # 准备请求头 headers = {"Content-Type": "application/json"} if settings.STORAGE_API_TOKEN: headers["Authorization"] = f"Bearer {settings.STORAGE_API_TOKEN}" logger.info(f"调用外部API {api_name} - {method} {url}, 参数: {params}") try: async with aiohttp.ClientSession() as session: # 根据HTTP方法选择相应的请求方式 if method == "GET": # 对于GET请求,将params转换为URL参数 async with session.get( url, params=params, headers=headers, timeout=settings.STORAGE_API_TIMEOUT ) as response: result = await response.json() elif method == "POST": # 对于POST请求,将params作为JSON数据发送 async with session.post( url, json=params, headers=headers, timeout=settings.STORAGE_API_TIMEOUT ) as response: result = await response.json() elif method == "PUT": # 对于PUT请求,将params作为JSON数据发送 async with session.put( url, json=params, headers=headers, timeout=settings.STORAGE_API_TIMEOUT ) as response: result = await response.json() else: logger.error(f"不支持的HTTP方法: {method}") return { "success": False, "message": f"不支持的HTTP方法: {method}" } # 检查响应状态码 if response.status != 200: logger.error(f"API调用失败: {url}, 状态码: {response.status}, 响应: {result}") return { "success": False, "message": f"API调用失败, 状态码: {response.status}", "data": result } logger.info(f"API调用成功: {url}, 响应: {result}") return result except aiohttp.ClientError as e: logger.error(f"API调用客户端错误: {url}, 错误: {str(e)}") return { "success": False, "message": f"API调用客户端错误: {str(e)}" } except asyncio.TimeoutError: logger.error(f"API调用超时: {url}") return { "success": False, "message": "API调用超时" } except json.JSONDecodeError: logger.error(f"API响应解析失败: {url}") return { "success": False, "message": "API响应格式错误,无法解析JSON" } except Exception as e: logger.error(f"API调用异常: {url}, 错误: {str(e)}") return { "success": False, "message": f"API调用异常: {str(e)}" } def generate_mock_response(api_name: str, params: Dict[str, Any]) -> Dict[str, Any]: """ 生成测试模式下的模拟响应 Args: api_name: API名称 params: API参数 Returns: 模拟的API响应 """ # 基本响应结构 response = { "success": True, "message": f"[测试模式] {api_name} 操作成功", "data": {} } # 根据不同API返回不同的模拟数据 if api_name.startswith("get_idle_site"): # 获取库位类API response["data"] = { "siteId": f"MOCK-SITE-{str(uuid.uuid4())[:8]}" } elif api_name == "get_idle_crowded_site": # 获取密集库位 response["data"] = { "siteId": f"MOCK-CROWDED-{str(uuid.uuid4())[:8]}" } elif api_name == "get_locked_sites_by_task_record_id": # 获取任务锁定的库位 response["data"] = { "lockedSiteIdList": [f"MOCK-LOCKED-{str(uuid.uuid4())[:8]}" for _ in range(3)] } elif api_name == "get_site_attr": # 获取库位属性 attr_name = params.get("attrName", "unknown") response["data"] = { "attrValue": f"MOCK-VALUE-FOR-{attr_name}" } elif api_name == "query_idle_site": # 查询空闲库位 response["data"] = { "site": { "id": f"MOCK-QUERY-{str(uuid.uuid4())[:8]}", "groupName": "MOCK-GROUP", "type": 0, "filled": params.get("filled", False), "locked": params.get("locked", False), "content": params.get("content", "") } } elif api_name == "set_site_locked": # 锁定库位 response["data"] = {"success": True} # 记录模拟调用结果 logger.info(f"[测试模式] 生成模拟响应: {api_name}, 响应: {response}") return response # 创建一个基础库位处理器类,包含通用方法 class StorageBlockHandler(BlockHandler): """库位处理器基类,提供公共的API调用方法""" async def _call_external_api(self, api_name: str, params: Dict[str, Any]) -> Dict[str, Any]: """调用外部API的通用方法""" return await call_storage_api(api_name, params) # 批量设置库位处理器 @register_handler(StorageBlockName.BATCH_SETTING_SITE) class BatchSettingSiteBlockHandler(StorageBlockHandler): """批量设置库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """执行批量设置库位操作""" try: # 获取关键参数用于验证 site_ids = input_params.get("siteIds", []) group_names = input_params.get("groupNames", []) filled = input_params.get("filled") # 参数检查 if not site_ids and not group_names: result = { "success": False, "message": "库位ID和库区集不能同时为空" } await self._record_task_log(block, result, context) return result if filled is None: result = { "success": False, "message": "占用参数不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API执行批量设置,传递所有input_params result = await self._call_external_api("batch_setting_site", input_params) if result.get("success", False): result["message"] = f"批量设置库位成功,共设置 {len(site_ids) or len(group_names)} 个库位" else: result["message"] = f"批量设置库位失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"批量设置库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 获取密集库位处理器 @register_handler(StorageBlockName.GET_IDLE_CROWDED_SITE) class GetIdleCrowdedSiteBlockHandler(StorageBlockHandler): """获取密集库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """执行获取密集库位操作""" try: # 获取关键参数用于验证 group_name = input_params.get("groupName", []) filled = input_params.get("filled") retry = input_params.get("retry", False) retry_num = input_params.get("retryNum", 1) # 参数检查 if not group_name: result = { "success": False, "message": "库区集不能为空" } await self._record_task_log(block, result, context) return result if filled is None: result = { "success": False, "message": "取/放参数不能为空" } await self._record_task_log(block, result, context) return result # 确保retry_num是整数类型 try: retry_num = int(retry_num) except (ValueError, TypeError): logger.warning(f"retry_num参数类型错误或无法转换为整数: {retry_num}, 将使用默认值1") retry_num = 1 input_params["retryNum"] = retry_num # 确保retry_period是数字 retry_period = input_params.get("retryPeriod") if retry_period is not None: try: retry_sleep = float(retry_period) / 1000 except (ValueError, TypeError): logger.warning(f"retry_period参数类型错误或无法转换为数字: {retry_period}, 使用默认值1秒") retry_sleep = 1 else: retry_sleep = 1 # 调用外部API执行获取密集库位 attempts = 1 # 确保max_attempts是整数 max_attempts = retry_num if retry and retry_num is not None else 1 result = None while attempts <= max_attempts: result = await self._call_external_api("get_idle_crowded_site", input_params) if result.get("success", False) and result.get("data", {}).get("siteId"): # 获取成功 site_id = result.get("data", {}).get("siteId") # 设置上下文变量 context.set_variable("siteId", site_id) context.set_block_output(block.get("name"), {"siteId": site_id}) result["message"] = f"获取密集库位成功,库位ID: {site_id}" break else: # 获取失败,判断是否需要重试 if retry and attempts < max_attempts: logger.info(f"获取密集库位失败,第 {attempts} 次重试,等待 {retry_sleep} 秒后重试") await asyncio.sleep(retry_sleep) attempts += 1 else: result["message"] = f"获取密集库位失败: {result.get('message', '未找到合适的库位')}" break # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"获取密集库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 获取库位处理器 @register_handler(StorageBlockName.GET_IDLE_SITE) class GetIdleSiteBlockHandler(StorageBlockHandler): """获取库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """执行获取库位操作""" try: # 获取关键参数用于验证 locked = input_params.get("locked") retry_period = input_params.get("retryPeriod") # 必填参数检查 if locked is None: result = { "success": False, "message": "是否已锁定参数不能为空" } await self._record_task_log(block, result, context) return result # 确保retry_period是数字类型 if retry_period is not None: try: retry_period = float(retry_period) input_params["retryPeriod"] = retry_period retry_sleep = retry_period / 1000 except (ValueError, TypeError): logger.warning(f"retry_period参数类型错误或无法转换为数字: {retry_period}, 将使用默认值1000") retry_sleep = 1 input_params["retryPeriod"] = 1000 else: retry_sleep = 1 input_params["retryPeriod"] = 1000 # 设置重试计数器(用于日志记录) retry_count = 0 while True: # 无限循环,直到找到库位 # 尝试获取库位 result = await self._call_external_api("get_idle_site", input_params) if result.get("success", False) and result.get("data", {}).get("siteId"): # 获取成功 site_id = result.get("data", {}).get("siteId") # 设置上下文变量 context.set_variable("siteId", site_id) context.set_block_output(block.get("name"), {"siteId": site_id}) # 根据重试次数设置不同的成功消息 if retry_count == 0: result["message"] = f"获取库位成功,库位ID: {site_id}" else: result["message"] = f"第{retry_count}次重试获取库位成功,库位ID: {site_id}" # 记录执行结果并退出循环 await self._record_task_log(block, result, context) return result else: # 获取失败,记录日志并继续重试 retry_count += 1 logger.info(f"获取库位失败,第{retry_count}次重试,等待 {retry_sleep} 秒后继续") # 更新临时结果消息(仅用于日志记录) temp_result = { "success": False, "message": f"第{retry_count}次尝试获取库位失败: {result.get('message', '未找到合适的库位')},将继续重试" } await self._record_task_log(block, temp_result, context) # 等待指定时间后继续重试 await asyncio.sleep(retry_sleep) except Exception as e: result = { "success": False, "message": f"获取库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 获取任务实例加锁库位处理器 @register_handler(StorageBlockName.GET_LOCKED_SITES_BY_TASK_RECORD_ID) class GetLockedSitesByTaskRecordIdBlockHandler(StorageBlockHandler): """根据任务实例ID获取所有加锁库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """获取任务实例关联的所有已锁库位""" try: # 获取参数进行验证 task_record_id = input_params.get("taskRecordId") # 必填参数检查 if not task_record_id: result = { "success": False, "message": "任务实例ID不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API获取库位列表 result = await self._call_external_api("get_locked_sites_by_task_record_id", input_params) if result.get("success", False): # 获取成功,设置上下文变量 locked_site_list = result.get("data", {}).get("lockedSiteIdList", []) context.set_variable("lockedSiteIdList", locked_site_list) context.set_block_output(block.get("name"), {"lockedSiteIdList": locked_site_list}) result["message"] = f"获取任务锁定库位成功,共 {len(locked_site_list)} 个库位" else: result["message"] = f"获取任务锁定库位失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"获取任务锁定库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 获取库位扩展属性处理器 @register_handler(StorageBlockName.GET_SITE_ATTR) class GetSiteAttrBlockHandler(StorageBlockHandler): """获取库位扩展属性处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """获取库位扩展属性值""" try: # 获取参数进行验证 site_id = input_params.get("siteId") attr_name = input_params.get("attrName") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result if not attr_name: result = { "success": False, "message": "属性名称不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API获取属性值 result = await self._call_external_api("get_site_attr", input_params) if result.get("success", False): # 获取成功,设置上下文变量 attr_value = result.get("data", {}).get("attrValue") context.set_variable("attrValue", attr_value) context.set_block_output(block.get("name"), {"attrValue": attr_value}) result["message"] = f"获取库位属性值成功,{attr_name}: {attr_value}" else: result["message"] = f"获取库位属性值失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"获取库位属性值执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 查询库位处理器 @register_handler(StorageBlockName.QUERY_IDLE_SITE) class QueryIdleSiteBlockHandler(StorageBlockHandler): """查询库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """查询库位""" try: # 直接调用外部API查询库位 result = await self._call_external_api("query_idle_site", input_params) if result.get("success", False) and result.get("data", {}).get("site"): # 查询成功,设置上下文变量 site = result.get("data", {}).get("site") context.set_variable("site", site) context.set_block_output(block.get("name"), {"site": site}) site_id = site.get("id", "未知") result["message"] = f"查询库位成功,库位ID: {site_id}" else: result["message"] = f"查询库位失败: {result.get('message', '未找到符合条件的库位')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"查询库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 设置库位扩展属性处理器 @register_handler(StorageBlockName.SET_SITE_ATTR) class SetSiteAttrBlockHandler(StorageBlockHandler): """设置库位扩展属性处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """设置库位扩展属性值""" try: # 获取参数进行验证 site_id = input_params.get("siteId") attr_name = input_params.get("attrName") attr_value = input_params.get("attrValue") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result if not attr_name: result = { "success": False, "message": "属性名称不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API设置属性值 result = await self._call_external_api("set_site_attr", input_params) if result.get("success", False): value_display = attr_value if attr_value is not None else "null" result["message"] = f"设置库位属性值成功,{site_id}.{attr_name} = {value_display}" else: result["message"] = f"设置库位属性值失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"设置库位属性值执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 设置库位货物处理器 @register_handler(StorageBlockName.SET_SITE_CONTENT) class SetSiteContentBlockHandler(StorageBlockHandler): """设置库位货物处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """设置库位货物""" try: # 获取参数进行验证 site_id = input_params.get("siteId") content = input_params.get("content") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result if content is None: result = { "success": False, "message": "货物不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API设置库位货物 result = await self._call_external_api("set_site_content", input_params) if result.get("success", False): result["message"] = f"设置库位货物成功,{site_id} 货物: {content}" else: result["message"] = f"设置库位货物失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"设置库位货物执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 设置库位为空处理器 @register_handler(StorageBlockName.SET_SITE_EMPTY) class SetSiteEmptyBlockHandler(StorageBlockHandler): """设置库位为空处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """设置库位为空""" try: # 获取参数进行验证 site_id = input_params.get("siteId") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API设置库位为空 result = await self._call_external_api("set_site_empty", input_params) if result.get("success", False): result["message"] = f"设置库位为空成功,库位ID: {site_id}" else: result["message"] = f"设置库位为空失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"设置库位为空执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 设置库位为占用处理器 @register_handler(StorageBlockName.SET_SITE_FILLED) class SetSiteFilledBlockHandler(StorageBlockHandler): """设置库位为占用处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """设置库位为占用""" try: # 获取参数进行验证 site_id = input_params.get("siteId") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API设置库位为占用 result = await self._call_external_api("set_site_filled", input_params) if result.get("success", False): result["message"] = f"设置库位为占用成功,库位ID: {site_id}" else: result["message"] = f"设置库位为占用失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"设置库位为占用执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 锁定库位处理器 @register_handler(StorageBlockName.SET_SITE_LOCKED) class SetSiteLockedBlockHandler(StorageBlockHandler): """锁定库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """锁定库位""" try: # 获取参数进行验证 site_id = input_params.get("siteId") locked_id = input_params.get("lockedId") if_fair = input_params.get("ifFair", False) # 是否为公平锁 retryTimes = input_params.get("retryTimes", 0) # 重试次数,默认为0表示不重试 # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result # 如果未指定锁定者ID,则使用当前任务ID if not locked_id: locked_id = context.get_task_record_id() input_params["lockedId"] = locked_id # 确保retry_num是整数类型 try: retry_num = int(retryTimes) except (ValueError, TypeError): logger.warning(f"retry_num参数类型错误或无法转换为整数: {retryTimes}, 将使用默认值0") retry_num = 0 input_params["retryNum"] = retry_num # 处理公平锁参数 if if_fair is not None: input_params["ifFair"] = if_fair # 实现重试逻辑 attempts = 0 max_attempts = retry_num # 包括首次尝试 retry_sleep = 1 # 默认重试间隔为1秒 while attempts < max_attempts: attempts += 1 # 调用外部API锁定库位 result = await self._call_external_api("set_site_locked", input_params) if result.get("success", False): # 获取锁定结果 success = result.get("data", {}).get("success", False) # 设置上下文变量 context.set_variable("success", success) context.set_block_output(block.get("name"), {"success": success}) if success: # 锁定成功 if attempts == 1: result["message"] = f"锁定库位成功,库位ID: {site_id}" else: result["message"] = f"第{attempts}次尝试锁定库位成功,库位ID: {site_id}" break else: # 锁定失败但API调用成功,检查是否需要重试 if attempts < max_attempts: logger.info(f"锁定库位失败,库位ID: {site_id},第 {attempts} 次尝试,等待 {retry_sleep} 秒后重试") # 记录临时结果(仅用于日志记录) temp_result = { "success": False, "message": f"第{attempts}次尝试锁定库位失败: 库位 {site_id} 可能已被其他任务锁定,将继续重试" } await self._record_task_log(block, temp_result, context) await asyncio.sleep(retry_sleep) else: # 达到最大重试次数,返回最终失败结果 result["message"] = f"锁定库位失败,库位ID: {site_id},可能已被其他任务锁定,重试 {retry_num} 次后仍然失败" else: # API调用失败,检查是否需要重试 if attempts < max_attempts: logger.info(f"API调用失败,第 {attempts} 次尝试,等待 {retry_sleep} 秒后重试") # 记录临时结果(仅用于日志记录) temp_result = { "success": False, "message": f"第{attempts}次API调用失败: {result.get('message', '未知错误')},将继续重试" } await self._record_task_log(block, temp_result, context) await asyncio.sleep(retry_sleep) else: # 达到最大重试次数,返回最终失败结果 result["message"] = f"锁定库位失败: {result.get('message', '未知错误')},重试 {retry_num} 次后仍然失败" # 记录最终执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"锁定库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 设置库位标签处理器 @register_handler(StorageBlockName.SET_SITE_TAGS) class SetSiteTagsBlockHandler(StorageBlockHandler): """设置库位标签处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """设置库位标签""" try: # 获取参数进行验证 site_id = input_params.get("siteId") tags = input_params.get("tags") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result # 直接调用外部API设置库位标签 result = await self._call_external_api("set_site_tags", input_params) if result.get("success", False): tags_display = tags if tags else "空" result["message"] = f"设置库位标签成功,库位ID: {site_id},标签: {tags_display}" else: result["message"] = f"设置库位标签失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"设置库位标签执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result # 解锁库位处理器 @register_handler(StorageBlockName.SET_SITE_UNLOCKED) class SetSiteUnlockedBlockHandler(StorageBlockHandler): """解锁库位处理器""" async def execute( self, block: Dict[str, Any], input_params: Dict[str, Any], context: TaskContext ) -> Dict[str, Any]: """解锁库位""" try: # 获取参数进行验证 site_id = input_params.get("siteId") un_locked_id = input_params.get("unLockedId") # 必填参数检查 if not site_id: result = { "success": False, "message": "库位ID不能为空" } await self._record_task_log(block, result, context) return result # 如果未指定解锁者ID,则使用当前任务ID if not un_locked_id: un_locked_id = context.get_task_record_id() input_params["unLockedId"] = un_locked_id logger.info(f"未指定解锁者ID,使用当前任务ID: {un_locked_id}") # 调用外部API解锁库位 result = await self._call_external_api("set_site_unlocked", input_params) if result.get("success", False): # 设置上下文变量 context.set_variable("unlockSuccess", True) context.set_block_output(block.get("name"), {"unlockSuccess": True}) result["message"] = f"解锁库位成功,库位ID: {site_id}" else: # 设置上下文变量 context.set_variable("unlockSuccess", False) context.set_block_output(block.get("name"), {"unlockSuccess": False}) result["message"] = f"解锁库位失败: {result.get('message', '未知错误')}" # 记录执行结果 await self._record_task_log(block, result, context) return result except Exception as e: result = { "success": False, "message": f"解锁库位执行异常: {str(e)}" } # 记录异常 await self._record_task_log(block, result, context) return result