2562 lines
94 KiB
Python
2562 lines
94 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
块处理器模块
|
||
提供对不同类型块的执行处理
|
||
"""
|
||
|
||
import json
|
||
import logging
|
||
from abc import ABC, abstractmethod
|
||
from typing import Dict, List, Any, Optional, Type, Callable
|
||
from datetime import datetime
|
||
|
||
from services.execution.task_context import TaskContext
|
||
|
||
# 获取日志记录器
|
||
logger = logging.getLogger(__name__)
|
||
|
||
# 块处理器注册表
|
||
_block_handlers = {}
|
||
|
||
class BlockHandler(ABC):
|
||
"""
|
||
块处理器抽象基类
|
||
所有具体的块处理器都应该继承这个类
|
||
"""
|
||
|
||
@abstractmethod
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""
|
||
执行块
|
||
|
||
Args:
|
||
block: 块定义
|
||
input_params: 解析后的输入参数
|
||
context: 任务上下文
|
||
|
||
Returns:
|
||
Dict[str, Any]: 执行结果,必须包含success字段
|
||
"""
|
||
pass
|
||
|
||
async def _record_task_log(
|
||
self,
|
||
block: Dict[str, Any],
|
||
result: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> None:
|
||
"""
|
||
记录任务日志
|
||
|
||
Args:
|
||
block: 块定义
|
||
result: 执行结果
|
||
context: 任务上下文
|
||
"""
|
||
from sqlalchemy import insert
|
||
from data.models.tasklog import VWEDTaskLog
|
||
from data.session import get_async_session
|
||
import uuid
|
||
from datetime import datetime
|
||
|
||
try:
|
||
# 创建任务日志记录
|
||
task_log_id = str(uuid.uuid4())
|
||
async with get_async_session() as session:
|
||
stmt = insert(VWEDTaskLog).values(
|
||
id=task_log_id,
|
||
create_time=datetime.now(),
|
||
level=1 if result.get("success", False) else 3, # 1: 信息, 3: 错误
|
||
message=json.dumps(result, ensure_ascii=False),
|
||
task_block_id=block.get("id", "unknown"),
|
||
task_id=context.task_def_id,
|
||
task_record_id=context.task_record_id
|
||
)
|
||
await session.execute(stmt)
|
||
await session.commit()
|
||
except Exception as e:
|
||
logger.error(f"记录任务日志失败: {str(e)}")
|
||
|
||
# 注册装饰器
|
||
def register_handler(block_type: str):
|
||
"""
|
||
注册块处理器的装饰器
|
||
|
||
Args:
|
||
block_type: 块类型
|
||
"""
|
||
def decorator(cls):
|
||
_block_handlers[block_type] = cls()
|
||
return cls
|
||
return decorator
|
||
|
||
# 获取块处理器
|
||
def get_block_handler(block_type: str) -> Optional[BlockHandler]:
|
||
"""
|
||
获取块处理器
|
||
|
||
Args:
|
||
block_type: 块类型
|
||
|
||
Returns:
|
||
Optional[BlockHandler]: 对应的块处理器,如果不存在则返回None
|
||
"""
|
||
return _block_handlers.get(block_type)
|
||
|
||
# # =============================================子任务组件类========================================================
|
||
# # 子任务块处理器
|
||
# @register_handler("SubTaskBp")
|
||
# class SubTaskBlockHandler(BlockHandler):
|
||
# """子任务块处理器"""
|
||
#
|
||
# async def execute(
|
||
# self,
|
||
# block: Dict[str, Any],
|
||
# input_params: Dict[str, Any],
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """执行子任务块"""
|
||
# from sqlalchemy import select, insert
|
||
# from data.models.taskdef import VWEDTaskDef
|
||
# from data.models.taskrecord import VWEDTaskRecord
|
||
# from data.session import get_async_session
|
||
# from services.execution.task_executor import TaskExecutor
|
||
# import uuid
|
||
# import asyncio
|
||
#
|
||
# try:
|
||
# # 获取子任务ID
|
||
# subtask_id = block.get("refTaskDefId")
|
||
#
|
||
# if not subtask_id:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": "缺少子任务ID"
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 获取执行参数(确保默认值)
|
||
# is_async = input_params.get("ifAsync", False) # 是否异步执行,默认False
|
||
# specified_task_record_id = input_params.get("taskRecordId", None) # 指定的任务记录ID,默认None
|
||
#
|
||
# # 从input_params中提取出子任务需要的参数
|
||
# # 排除控制参数
|
||
# control_params = ["ifAsync", "taskRecordId"]
|
||
# subtask_params = {}
|
||
# for key, value in input_params.items():
|
||
# if key not in control_params:
|
||
# subtask_params[key] = value
|
||
#
|
||
# logger.info(f"开始执行子任务: {subtask_id}, 异步执行: {is_async}, 指定ID: {specified_task_record_id}")
|
||
#
|
||
# # 确定任务记录ID
|
||
# task_record_id = None
|
||
# if specified_task_record_id:
|
||
# # 检查指定的任务记录是否存在
|
||
# async with get_async_session() as session:
|
||
# result = await session.execute(
|
||
# select(VWEDTaskRecord).where(VWEDTaskRecord.id == specified_task_record_id)
|
||
# )
|
||
# existing_record = result.scalars().first()
|
||
#
|
||
# if existing_record:
|
||
# # 如果指定的任务记录ID已存在,则报错
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"指定的任务记录ID已存在: {specified_task_record_id}"
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
# else:
|
||
# # 使用指定的ID创建新任务
|
||
# task_record_id = specified_task_record_id
|
||
# logger.info(f"使用指定ID创建新任务记录: {task_record_id}")
|
||
#
|
||
# if not task_record_id:
|
||
# # 如果未指定ID或指定的ID不存在,生成新ID
|
||
# task_record_id = str(uuid.uuid4())
|
||
# logger.info(f"使用生成的任务记录ID: {task_record_id}")
|
||
#
|
||
# # 获取根任务记录ID - 如果当前任务有父任务,则根任务是父任务的根任务,否则是当前任务
|
||
# root_task_record_id = context.get_variable("rootTaskRecordId", context.task_record_id)
|
||
#
|
||
# # 查询任务定义
|
||
# async with get_async_session() as session:
|
||
# result = await session.execute(
|
||
# select(VWEDTaskDef).where(VWEDTaskDef.id == subtask_id)
|
||
# )
|
||
# task_def = result.scalars().first()
|
||
#
|
||
# if not task_def:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"找不到子任务定义: {subtask_id}"
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 获取任务定义详情
|
||
# task_def_detail = task_def.detail
|
||
#
|
||
# # 创建任务记录 - 设置所有关键参数
|
||
# record_values = {
|
||
# "id": task_record_id,
|
||
# "def_id": subtask_id,
|
||
# "def_label": task_def.label,
|
||
# "def_version": task_def.version,
|
||
# "created_on": datetime.now(),
|
||
# "status": 0, # 初始状态
|
||
# "input_params": json.dumps(subtask_params, ensure_ascii=False),
|
||
# "parent_task_record_id": context.task_record_id, # 设置父任务ID
|
||
# "root_task_record_id": root_task_record_id, # 设置根任务ID
|
||
# "periodic_task": task_def.periodic_task if hasattr(task_def, "periodic_task") else 0, # 继承周期任务属性
|
||
# "task_def_detail": task_def_detail # 设置任务定义详情
|
||
# }
|
||
#
|
||
# # 执行插入
|
||
# await session.execute(
|
||
# insert(VWEDTaskRecord).values(record_values)
|
||
# )
|
||
# await session.commit()
|
||
#
|
||
# # 创建任务执行器
|
||
# executor = TaskExecutor(task_record_id)
|
||
#
|
||
# # 根据是否异步执行采取不同的处理方式
|
||
# if is_async:
|
||
# # 异步执行:启动任务但不等待结果
|
||
# # 初始化执行器
|
||
# init_success = await executor.initialize()
|
||
# if not init_success:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"初始化子任务执行器失败: {executor.error_message}"
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 创建异步任务但不等待
|
||
# asyncio.create_task(executor.execute())
|
||
#
|
||
# # 执行完成后记录日志
|
||
# result = {
|
||
# "success": True,
|
||
# "message": f"子任务已异步启动: {task_record_id}",
|
||
# "output": {
|
||
# "subtaskId": subtask_id,
|
||
# "taskRecordId": task_record_id,
|
||
# "async": True
|
||
# }
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
# else:
|
||
# # 同步执行:等待任务执行完成后返回结果
|
||
# # 初始化执行器
|
||
# init_success = await executor.initialize()
|
||
# if not init_success:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"初始化子任务执行器失败: {executor.error_message}"
|
||
# }
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 执行子任务并等待结果
|
||
# execute_result = await executor.execute()
|
||
#
|
||
# # 处理子任务执行结果
|
||
# success = execute_result.get("success", False)
|
||
# message = execute_result.get("message", "子任务执行完成")
|
||
#
|
||
# # 记录子任务结果到上下文变量
|
||
# context.set_variable("subtaskResult", execute_result)
|
||
#
|
||
# # 获取子任务输出
|
||
# output = execute_result.get("result", {})
|
||
#
|
||
# # 将子任务输出合并到当前上下文变量
|
||
# if isinstance(output, dict):
|
||
# for key, value in output.items():
|
||
# variable_name = f"subtask_{key}"
|
||
# context.set_variable(variable_name, value)
|
||
#
|
||
# # 执行完成后记录日志
|
||
# result = {
|
||
# "success": success,
|
||
# "message": message,
|
||
# "output": {
|
||
# "subtaskId": subtask_id,
|
||
# "taskRecordId": task_record_id,
|
||
# "async": False,
|
||
# "output": output
|
||
# }
|
||
# }
|
||
# 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("RootBp")
|
||
class RootBlockHandler(BlockHandler):
|
||
"""根块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行根块"""
|
||
try:
|
||
from services.execution.block_executor import BlockExecutor
|
||
|
||
# 创建块执行器
|
||
executor = BlockExecutor(context)
|
||
|
||
# 执行根块的子块
|
||
result = await executor.execute_children(block)
|
||
|
||
# 记录执行结果
|
||
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("SetTaskVariablesBp")
|
||
# class SetTaskVariablesBlockHandler(BlockHandler):
|
||
# """设置任务变量块处理器"""
|
||
#
|
||
# async def execute(
|
||
# self,
|
||
# block: Dict[str, Any],
|
||
# input_params: Dict[str, Any],
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """执行设置任务变量块"""
|
||
# try:
|
||
# # 获取函数名和参数
|
||
# function_name = input_params.get("functionName")
|
||
# function_args = input_params.get("functionArgs", {})
|
||
#
|
||
# if not function_name:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": "缺少函数名"
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 调用脚本执行方法
|
||
# exec_result = await self._execute_script(function_name, function_args, context)
|
||
#
|
||
# # 如果执行成功,将变量保存到任务记录
|
||
# if exec_result.get("success", False):
|
||
# await self._save_variables_to_database(context)
|
||
#
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, exec_result, context)
|
||
# return exec_result
|
||
# except Exception as e:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"设置任务变量失败: {str(e)}"
|
||
# }
|
||
# # 记录异常
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# async def _execute_script(
|
||
# self,
|
||
# function_name: str,
|
||
# function_args: Any,
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """
|
||
# 执行指定的脚本函数
|
||
#
|
||
# Args:
|
||
# function_name: 要执行的函数名
|
||
# function_args: 函数参数
|
||
# context: 任务上下文
|
||
#
|
||
# Returns:
|
||
# Dict[str, Any]: 执行结果
|
||
# """
|
||
# # 固定加载scripts/user_save/test1.py文件
|
||
# script_file = r"D:\jsw_code\project\VWED_task\scripts\user_save\test1.py"
|
||
# logger.info(f"正在加载脚本文件: {script_file}")
|
||
#
|
||
# try:
|
||
# # 动态加载脚本模块
|
||
# import importlib.util
|
||
# import sys
|
||
# import os
|
||
#
|
||
# # 检查文件是否存在
|
||
# if not os.path.exists(script_file):
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"脚本文件不存在: {script_file}"
|
||
# }
|
||
#
|
||
# # 加载模块
|
||
# spec = importlib.util.spec_from_file_location("user_script", script_file)
|
||
# if not spec:
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"无法加载脚本规范: {script_file}"
|
||
# }
|
||
# module = importlib.util.module_from_spec(spec)
|
||
# sys.modules["user_script"] = module
|
||
# spec.loader.exec_module(module)
|
||
#
|
||
# # 检查函数是否存在
|
||
# if not hasattr(module, function_name):
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"函数 {function_name} 在脚本 {script_file} 中不存在"
|
||
# }
|
||
# # 获取函数对象
|
||
# func = getattr(module, function_name)
|
||
#
|
||
# # 准备函数参数(处理不同类型的参数传递方式)
|
||
# args = []
|
||
# kwargs = {}
|
||
#
|
||
# # 如果function_args是字典,将其作为关键字参数传递
|
||
# if isinstance(function_args, dict):
|
||
# kwargs = function_args
|
||
# # 如果function_args是列表,将其作为位置参数传递
|
||
# elif isinstance(function_args, list):
|
||
# args = function_args
|
||
# # 如果function_args是其他类型,将其作为单个位置参数传递
|
||
# elif function_args is not None:
|
||
# args = [function_args]
|
||
#
|
||
# # 调用函数
|
||
# logger.info(f"调用函数 {function_name} 参数: args={args}, kwargs={kwargs}")
|
||
# result_value = func(*args, **kwargs)
|
||
#
|
||
# # 检查是否是异步函数并等待结果
|
||
# import inspect
|
||
# if inspect.iscoroutine(result_value):
|
||
# import asyncio
|
||
# result_value = await result_value
|
||
#
|
||
# logger.info(f"函数 {function_name} 执行结果: {result_value}")
|
||
#
|
||
# # 设置返回值到上下文 - 与ScriptBp不同,这里会更新所有变量
|
||
# if isinstance(result_value, dict):
|
||
# # 如果返回值是字典,将字典中的每个键值对设置为任务变量
|
||
# for key, value in result_value.items():
|
||
# context.set_variable(key, value)
|
||
#
|
||
# result_message = f"脚本函数 {function_name} 执行成功,已更新 {len(result_value)} 个变量"
|
||
# else:
|
||
# # 如果返回值不是字典,将整个返回值设置为scriptResult变量
|
||
# context.set_variable("scriptResult", result_value)
|
||
# result_message = f"脚本函数 {function_name} 执行成功,结果已保存为scriptResult变量"
|
||
#
|
||
# # 构建成功结果
|
||
# return {
|
||
# "success": True,
|
||
# "message": result_message,
|
||
# "output": {
|
||
# "result": result_value,
|
||
# "functionName": function_name
|
||
# }
|
||
# }
|
||
#
|
||
# except Exception as e:
|
||
# logger.error(f"执行脚本函数时发生异常: {str(e)}", exc_info=True)
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"执行脚本函数 {function_name} 失败: {str(e)}"
|
||
# }
|
||
#
|
||
# async def _save_variables_to_database(self, context: TaskContext) -> None:
|
||
# """
|
||
# 将任务变量保存到数据库的任务记录中
|
||
#
|
||
# Args:
|
||
# context: 任务上下文
|
||
# """
|
||
# try:
|
||
# from sqlalchemy import update
|
||
# from data.models.taskrecord import VWEDTaskRecord
|
||
# from data.session import get_async_session
|
||
# import json
|
||
#
|
||
# # 获取任务记录ID
|
||
# task_record_id = context.task_record_id
|
||
#
|
||
# if not task_record_id:
|
||
# logger.error("无法保存变量,任务记录ID为空")
|
||
# return
|
||
#
|
||
# # 将任务变量转换为JSON字符串
|
||
# variables_json = json.dumps(context.variables, ensure_ascii=False)
|
||
#
|
||
# # 更新数据库记录
|
||
# async with get_async_session() as session:
|
||
# stmt = update(VWEDTaskRecord).where(VWEDTaskRecord.id == task_record_id).values(
|
||
# variables=variables_json
|
||
# )
|
||
# await session.execute(stmt)
|
||
# await session.commit()
|
||
#
|
||
# logger.info(f"已将任务变量保存到数据库记录 {task_record_id}")
|
||
#
|
||
# except Exception as e:
|
||
# logger.error(f"保存任务变量到数据库失败: {str(e)}")
|
||
#
|
||
# # 脚本块处理器
|
||
# @register_handler("ScriptBp")
|
||
# class ScriptBlockHandler(BlockHandler):
|
||
# """脚本块处理器"""
|
||
#
|
||
# async def execute(
|
||
# self,
|
||
# block: Dict[str, Any],
|
||
# input_params: Dict[str, Any],
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """执行脚本块"""
|
||
# try:
|
||
# # 获取函数名和参数
|
||
# function_name = input_params.get("functionName")
|
||
# function_args = input_params.get("functionArgs", {})
|
||
#
|
||
# if not function_name:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": "缺少函数名"
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 调用脚本执行方法
|
||
# exec_result = await self._execute_script(function_name, function_args, context)
|
||
#
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, exec_result, context)
|
||
# return exec_result
|
||
# except Exception as e:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"脚本执行失败: {str(e)}"
|
||
# }
|
||
# # 记录异常
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# async def _execute_script(
|
||
# self,
|
||
# function_name: str,
|
||
# function_args: Any,
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """
|
||
# 执行指定的脚本函数
|
||
#
|
||
# Args:
|
||
# function_name: 要执行的函数名
|
||
# function_args: 函数参数
|
||
# context: 任务上下文
|
||
#
|
||
# Returns:
|
||
# Dict[str, Any]: 执行结果
|
||
# """
|
||
# # 固定加载scripts/user_save/test1.py文件
|
||
# script_file = r"D:\jsw_code\project\VWED_task\scripts\user_save\test1.py"
|
||
# logger.info(f"正在加载脚本文件: {script_file}")
|
||
#
|
||
# try:
|
||
# # 动态加载脚本模块
|
||
# import importlib.util
|
||
# import sys
|
||
# import os
|
||
#
|
||
# # 检查文件是否存在
|
||
# if not os.path.exists(script_file):
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"脚本文件不存在: {script_file}"
|
||
# }
|
||
#
|
||
# # 加载模块
|
||
# spec = importlib.util.spec_from_file_location("user_script", script_file)
|
||
# if not spec:
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"无法加载脚本规范: {script_file}"
|
||
# }
|
||
# module = importlib.util.module_from_spec(spec)
|
||
# sys.modules["user_script"] = module
|
||
# spec.loader.exec_module(module)
|
||
# # 检查函数是否存在
|
||
# if not hasattr(module, function_name):
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"函数 {function_name} 在脚本 {script_file} 中不存在"
|
||
# }
|
||
# # 获取函数对象
|
||
# func = getattr(module, function_name)
|
||
#
|
||
# # 准备函数参数(处理不同类型的参数传递方式)
|
||
# args = []
|
||
# kwargs = {}
|
||
#
|
||
# # 如果function_args是字典,将其作为关键字参数传递
|
||
# if isinstance(function_args, dict):
|
||
# kwargs = function_args
|
||
# # 如果function_args是列表,将其作为位置参数传递
|
||
# elif isinstance(function_args, list):
|
||
# args = function_args
|
||
# # 如果function_args是其他类型,将其作为单个位置参数传递
|
||
# elif function_args is not None:
|
||
# args = [function_args]
|
||
#
|
||
# # 调用函数
|
||
# logger.info(f"调用函数 {function_name} 参数: args={args}, kwargs={kwargs}")
|
||
# result_value = func(*args, **kwargs)
|
||
#
|
||
# # 检查是否是异步函数并等待结果
|
||
# import inspect
|
||
# if inspect.iscoroutine(result_value):
|
||
# import asyncio
|
||
# result_value = await result_value
|
||
#
|
||
# logger.info(f"函数 {function_name} 执行结果: {result_value}")
|
||
#
|
||
# # 设置返回值到上下文
|
||
# context.set_variable("scriptResult", result_value)
|
||
#
|
||
# # 构建成功结果
|
||
# return {
|
||
# "success": True,
|
||
# "message": f"脚本函数 {function_name} 执行成功",
|
||
# "output": {
|
||
# "result": result_value,
|
||
# "functionName": function_name
|
||
# }
|
||
# }
|
||
#
|
||
# except Exception as e:
|
||
# logger.error(f"执行脚本函数时发生异常: {str(e)}", exc_info=True)
|
||
# return {
|
||
# "success": False,
|
||
# "message": f"执行脚本函数 {function_name} 失败: {str(e)}"
|
||
# }
|
||
|
||
# 打印块处理器
|
||
@register_handler("PrintBp")
|
||
class PrintBlockHandler(BlockHandler):
|
||
"""打印块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行打印块"""
|
||
try:
|
||
# 获取消息参数
|
||
message = input_params.get("message", "")
|
||
|
||
# 记录日志
|
||
logger.info(f"任务 {context.task_record_id} 打印: {message}")
|
||
|
||
# 返回结果
|
||
result = {
|
||
"success": True,
|
||
"message": "打印成功",
|
||
"output": {
|
||
"message": 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("IfBp")
|
||
class IfBlockHandler(BlockHandler):
|
||
"""条件判断块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行条件判断块"""
|
||
try:
|
||
# 获取条件参数
|
||
condition = input_params.get("condition")
|
||
|
||
# 判断条件
|
||
result = bool(condition)
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 检查块中所有可用的分支
|
||
children = block.get("children", {})
|
||
has_true_branch = "true" in children and children["true"]
|
||
has_false_branch = "false" in children and children["false"]
|
||
has_default_branch = "default" in children and children["default"]
|
||
|
||
logger.info(f"条件判断块执行 - ID: {block.get('id')}, 条件结果: {result}")
|
||
logger.info(f"可用分支情况 - true分支: {has_true_branch}, false分支: {has_false_branch}, default分支: {has_default_branch}")
|
||
# 根据条件执行不同分支
|
||
if result:
|
||
# 条件为真,优先执行true分支,如果没有则尝试执行default分支
|
||
if has_true_branch:
|
||
logger.info(f"条件为真,执行true分支")
|
||
branch_name = "true"
|
||
elif has_default_branch:
|
||
logger.info(f"条件为真但无true分支,执行default分支")
|
||
branch_name = "default"
|
||
else:
|
||
logger.info(f"条件为真但无可执行分支")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件为真,但没有找到true或default分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
else:
|
||
# 条件为假,优先执行false分支
|
||
if has_false_branch:
|
||
logger.info(f"条件为假,执行false分支")
|
||
branch_name = "false"
|
||
else:
|
||
logger.info(f"条件为假且无false分支,不执行任何分支")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件为假,没有找到false分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
# 执行选定的分支
|
||
if branch_name:
|
||
branch_result = await executor.execute_children(block, branch_name)
|
||
if not branch_result.get("success", False):
|
||
logger.error(f"分支 {branch_name} 执行失败: {branch_result.get('message')}")
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
logger.info(f"分支 {branch_name} 执行成功")
|
||
exec_result = {
|
||
"success": True,
|
||
"message": f"条件判断成功,执行{branch_name}分支完成",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": branch_name,
|
||
"executed": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
|
||
# 正常情况不应该到达这里
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "条件判断完成,未执行任何分支",
|
||
"output": {
|
||
"condition": result,
|
||
"branch": "none",
|
||
"executed": False
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
except Exception as e:
|
||
logger.error(f"条件判断执行异常: {str(e)}")
|
||
exec_result = {
|
||
"success": False,
|
||
"message": f"条件判断失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
|
||
# 循环块处理器
|
||
@register_handler("WhileBp")
|
||
class WhileBlockHandler(BlockHandler):
|
||
"""循环块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行循环块"""
|
||
try:
|
||
# 获取循环条件和相关配置
|
||
loop_condition = input_params.get("loopCondition", False)
|
||
run_once = input_params.get("runOnce", False) # 是否至少执行一次
|
||
retry_period = input_params.get("retryPeriod", 0) # 循环间隔(毫秒)
|
||
print_continuously = input_params.get("printContinuously", False) # 是否持续打印日志
|
||
|
||
# 设置最大迭代次数,防止无限循环
|
||
max_iterations = 1000
|
||
iterations = 0
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 检查是否至少需要执行一次
|
||
if run_once:
|
||
# 执行一次循环体,无论条件是否满足
|
||
logger.info(f"执行while循环体(至少执行一次模式)")
|
||
branch_result = await executor.execute_children(block, "default")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
iterations += 1
|
||
|
||
# 根据条件循环执行
|
||
while loop_condition and iterations < max_iterations:
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 检查是否有中断或返回信号
|
||
if context.get_variable("__BREAK__", False):
|
||
logger.info(f"检测到中断信号,提前结束循环,已完成 {iterations} 次")
|
||
context.set_variable("__BREAK__", False) # 重置中断信号
|
||
break
|
||
|
||
if context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束循环,已完成 {iterations} 次")
|
||
# 不重置返回信号,它需要向上传播
|
||
break
|
||
|
||
# 如果不是第一次执行且有重试间隔,则等待
|
||
if iterations > 0 and retry_period > 0:
|
||
import asyncio
|
||
await asyncio.sleep(retry_period / 1000)
|
||
|
||
# 执行循环体
|
||
if print_continuously or iterations == 0:
|
||
logger.info(f"执行while循环体,第 {iterations+1} 次迭代")
|
||
|
||
branch_result = await executor.execute_children(block, "default")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
iterations += 1
|
||
|
||
# 重新获取循环条件
|
||
loop_condition = input_params.get("loopCondition", False)
|
||
|
||
# 检查是否达到最大迭代次数
|
||
if iterations >= max_iterations:
|
||
logger.warning(f"循环达到最大迭代次数 {max_iterations},可能存在无限循环")
|
||
result = {
|
||
"success": False,
|
||
"message": f"循环达到最大迭代次数 {max_iterations},可能存在无限循环"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 循环结束后,执行exit分支
|
||
if "exit" in block.get("children", {}) and block["children"]["exit"]:
|
||
logger.info(f"循环结束,执行exit分支")
|
||
exit_result = await executor.execute_children(block, "exit")
|
||
if not exit_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exit_result, context)
|
||
return exit_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"循环执行成功,共执行 {iterations} 次",
|
||
"output": {
|
||
"iterations": iterations
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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("WaitBp")
|
||
class WaitBlockHandler(BlockHandler):
|
||
"""等待块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行等待块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 获取等待时间参数(毫秒)
|
||
timeout = input_params.get("timeout", 1000)
|
||
|
||
# 转换为秒
|
||
timeout_sec = timeout / 1000
|
||
|
||
# 等待
|
||
await asyncio.sleep(timeout_sec)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"等待 {timeout} 毫秒完成",
|
||
"output": {
|
||
"timeout": timeout
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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
|
||
|
||
|
||
|
||
# 添加HTTP请求相关处理器
|
||
|
||
# HTTP GET请求处理器
|
||
# @register_handler("GetBp")
|
||
# class HttpGetBlockHandler(BlockHandler):
|
||
# """HTTP GET请求处理器"""
|
||
#
|
||
# async def execute(
|
||
# self,
|
||
# block: Dict[str, Any],
|
||
# input_params: Dict[str, Any],
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """执行HTTP GET请求"""
|
||
# import aiohttp
|
||
# import asyncio
|
||
# import json
|
||
#
|
||
# try:
|
||
# # 获取请求参数
|
||
# url = input_params.get("url")
|
||
#
|
||
# # 处理headers参数
|
||
# headers = {}
|
||
# header_param = input_params.get("header", {})
|
||
#
|
||
# # 如果header是字符串,尝试解析JSON
|
||
# if isinstance(header_param, str):
|
||
# try:
|
||
# header_data = json.loads(header_param)
|
||
# # 检查解析后的数据是否为列表格式 [{"key0":"value0", "value0":"value"}, ...]
|
||
# if isinstance(header_data, list):
|
||
# for item in header_data:
|
||
# # 寻找以key开头的键,如key0, key1等
|
||
# for key in [k for k in item if k.startswith('key')]:
|
||
# if key in item and item[key]:
|
||
# # 对应的value键应该是value0, value1等
|
||
# value_key = 'value' + key[3:]
|
||
# if value_key in item and item[value_key]:
|
||
# headers[item[key]] = item[value_key]
|
||
# # 如果是字典格式,直接使用
|
||
# elif isinstance(header_data, dict):
|
||
# headers = header_data
|
||
# except json.JSONDecodeError:
|
||
# logger.warning(f"无法解析headers JSON: {header_param}")
|
||
# elif isinstance(header_param, dict):
|
||
# headers = header_param
|
||
#
|
||
# retry = input_params.get("retry", False)
|
||
#
|
||
# # 确保retry_times为整数
|
||
# retry_times = input_params.get("retryTimes", 3)
|
||
# if isinstance(retry_times, str):
|
||
# try:
|
||
# retry_times = int(retry_times)
|
||
# except ValueError:
|
||
# retry_times = 3
|
||
#
|
||
# # 确保retry_interval为整数
|
||
# retry_interval = input_params.get("retryInterval", 1000)
|
||
# if isinstance(retry_interval, str):
|
||
# try:
|
||
# retry_interval = int(retry_interval)
|
||
# except ValueError:
|
||
# retry_interval = 1000
|
||
#
|
||
# if not url:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": "缺少请求URL"
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 执行HTTP请求
|
||
# attempt = 0
|
||
# max_attempts = 1 if not retry else retry_times + 1
|
||
#
|
||
# while attempt < max_attempts:
|
||
# try:
|
||
# async with aiohttp.ClientSession() as session:
|
||
# async with session.get(url, headers=headers) as response:
|
||
# # 读取响应内容
|
||
# response_text = await response.text()
|
||
#
|
||
# # 尝试解析JSON
|
||
# try:
|
||
# response_json = await response.json()
|
||
# context.set_variable("response", response_json)
|
||
# except:
|
||
# # 不是有效的JSON,保存为文本
|
||
# context.set_variable("response", response_text)
|
||
#
|
||
# result = {
|
||
# "success": True,
|
||
# "message": f"HTTP GET请求成功,状态码: {response.status}",
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
# except Exception as e:
|
||
# attempt += 1
|
||
# if attempt >= max_attempts:
|
||
# raise
|
||
#
|
||
# # 重试间隔
|
||
# await asyncio.sleep(retry_interval / 1000)
|
||
#
|
||
# except Exception as e:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"HTTP GET请求失败: {str(e)}"
|
||
# }
|
||
# # 记录异常
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # HTTP POST请求处理器
|
||
# @register_handler("PostBp")
|
||
# class HttpPostBlockHandler(BlockHandler):
|
||
# """HTTP POST请求处理器"""
|
||
#
|
||
# async def execute(
|
||
# self,
|
||
# block: Dict[str, Any],
|
||
# input_params: Dict[str, Any],
|
||
# context: TaskContext
|
||
# ) -> Dict[str, Any]:
|
||
# """执行HTTP POST请求"""
|
||
# import aiohttp
|
||
# import asyncio
|
||
# import json
|
||
#
|
||
# try:
|
||
# # 获取请求参数
|
||
# url = input_params.get("url")
|
||
# params = input_params.get("param", "{}")
|
||
#
|
||
# # 处理headers参数
|
||
# headers = {}
|
||
# header_param = input_params.get("header", {})
|
||
#
|
||
# # 如果header是字符串,尝试解析JSON
|
||
# if isinstance(header_param, str):
|
||
# try:
|
||
# header_data = json.loads(header_param)
|
||
# # 检查解析后的数据是否为列表格式 [{"key0":"value0", "value0":"value"}, ...]
|
||
# if isinstance(header_data, list):
|
||
# for item in header_data:
|
||
# # 寻找以key开头的键,如key0, key1等
|
||
# for key in [k for k in item if k.startswith('key')]:
|
||
# if key in item and item[key]:
|
||
# # 对应的value键应该是value0, value1等
|
||
# value_key = 'value' + key[3:]
|
||
# if value_key in item and item[value_key]:
|
||
# headers[item[key]] = item[value_key]
|
||
# # 如果是字典格式,直接使用
|
||
# elif isinstance(header_data, dict):
|
||
# headers = header_data
|
||
# except json.JSONDecodeError:
|
||
# logger.warning(f"无法解析headers JSON: {header_param}")
|
||
# elif isinstance(header_param, dict):
|
||
# headers = header_param
|
||
#
|
||
# media_type = input_params.get("mediaType", "JSON")
|
||
# retry = input_params.get("retry", False)
|
||
#
|
||
# # 确保retry_times为整数
|
||
# retry_times = input_params.get("retryTimes", 3)
|
||
# if isinstance(retry_times, str):
|
||
# try:
|
||
# retry_times = int(retry_times)
|
||
# except ValueError:
|
||
# retry_times = 3
|
||
#
|
||
# # 确保retry_interval为整数
|
||
# retry_interval = input_params.get("retryInterval", 1000)
|
||
# if isinstance(retry_interval, str):
|
||
# try:
|
||
# retry_interval = int(retry_interval)
|
||
# except ValueError:
|
||
# retry_interval = 1000
|
||
#
|
||
# if not url:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": "缺少请求URL"
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# # 准备请求数据
|
||
# try:
|
||
# if isinstance(params, str):
|
||
# data = json.loads(params)
|
||
# else:
|
||
# data = params
|
||
# except:
|
||
# data = params # 如果无法解析为JSON,使用原始字符串
|
||
#
|
||
# # 设置Content-Type
|
||
# content_type = "application/json"
|
||
# if media_type == "HTML":
|
||
# content_type = "text/html"
|
||
# elif media_type == "XML":
|
||
# content_type = "application/xml"
|
||
# elif media_type == "XWWWFORMURLENCODED":
|
||
# content_type = "application/x-www-form-urlencoded"
|
||
# elif media_type == "JAVASCRIPT":
|
||
# content_type = "application/javascript"
|
||
#
|
||
# if "Content-Type" not in headers:
|
||
# headers["Content-Type"] = content_type
|
||
#
|
||
# # 执行HTTP请求
|
||
# attempt = 0
|
||
# max_attempts = 1 if not retry else retry_times + 1
|
||
# while attempt < max_attempts:
|
||
# try:
|
||
# async with aiohttp.ClientSession() as session:
|
||
# async with session.post(url, json=data, headers=headers) as response:
|
||
# # 读取响应内容
|
||
# response_text = await response.text()
|
||
#
|
||
# # 尝试解析JSON
|
||
# try:
|
||
# response_json = await response.json()
|
||
# context.set_variable("response", response_json)
|
||
# except:
|
||
# # 不是有效的JSON,保存为文本
|
||
# context.set_variable("response", response_text)
|
||
#
|
||
# result = {
|
||
# "success": True,
|
||
# "message": f"HTTP POST请求成功,状态码: {response.status}, 响应内容详情: {response_text}",
|
||
# }
|
||
# # 记录执行结果
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
# except Exception as e:
|
||
# attempt += 1
|
||
# if attempt >= max_attempts:
|
||
# raise
|
||
#
|
||
# # 重试间隔
|
||
# await asyncio.sleep(retry_interval / 1000)
|
||
#
|
||
# except Exception as e:
|
||
# result = {
|
||
# "success": False,
|
||
# "message": f"HTTP POST请求失败: {str(e)}"
|
||
# }
|
||
# # 记录异常
|
||
# await self._record_task_log(block, result, context)
|
||
# return result
|
||
#
|
||
# 添加基础模块处理器
|
||
|
||
# 创建唯一ID处理器
|
||
@register_handler("CreateUuidBp")
|
||
class CreateUuidBlockHandler(BlockHandler):
|
||
"""创建唯一ID处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""创建唯一ID"""
|
||
import uuid
|
||
|
||
try:
|
||
# 生成UUID
|
||
generated_uuid = str(uuid.uuid4())
|
||
|
||
# 设置上下文变量
|
||
result = {
|
||
"success": True,
|
||
"message": "创建唯一ID成功",
|
||
"output": {
|
||
"uuid": generated_uuid,
|
||
|
||
}
|
||
}
|
||
context.set_block_output(block.get("name"), {"uuid": generated_uuid})
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"创建唯一ID失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 当前时间戳处理器
|
||
@register_handler("CurrentTimeStampBp")
|
||
class CurrentTimeStampBlockHandler(BlockHandler):
|
||
"""当前时间戳处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""获取当前时间戳"""
|
||
import time
|
||
|
||
try:
|
||
# 获取当前时间戳(毫秒)
|
||
current_timestamp = int(time.time() * 1000)
|
||
|
||
# 设置上下文变量
|
||
context.set_variable("currentTimeStamp", current_timestamp)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "获取当前时间戳成功",
|
||
"output": {
|
||
"timestamp": current_timestamp
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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("TimestampBp")
|
||
class TimestampBlockHandler(BlockHandler):
|
||
"""当前时间处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""获取当前时间"""
|
||
from datetime import datetime
|
||
|
||
try:
|
||
# 获取当前时间
|
||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||
|
||
# 设置上下文变量
|
||
context.set_variable("timestamp", current_time)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "获取当前时间成功",
|
||
"output": {
|
||
"timestamp": current_time
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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
|
||
|
||
# 字符串转JSON对象处理器
|
||
@register_handler("StringToJsonObjectBp")
|
||
class StringToJsonObjectBlockHandler(BlockHandler):
|
||
"""字符串转JSON对象处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""将字符串转换为JSON对象"""
|
||
import json
|
||
|
||
try:
|
||
# 获取输入参数
|
||
convert_string = input_params.get("convertString", "")
|
||
|
||
if not convert_string:
|
||
result = {
|
||
"success": False,
|
||
"message": "转换字符串为空"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 转换为JSON对象
|
||
json_object = json.loads(convert_string)
|
||
|
||
# 设置输出参数
|
||
output = {
|
||
"convertObject": json_object
|
||
}
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "字符串转换为JSON对象成功",
|
||
"output": output
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except json.JSONDecodeError as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"字符串解析为JSON对象失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"字符串转换为JSON对象失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 字符串转JSON数组处理器
|
||
@register_handler("StringToJsonArrayBp")
|
||
class StringToJsonArrayBlockHandler(BlockHandler):
|
||
"""字符串转JSON数组处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""将字符串转换为JSON数组"""
|
||
import json
|
||
|
||
try:
|
||
# 获取输入参数
|
||
convert_string = input_params.get("convertString", "")
|
||
|
||
if not convert_string:
|
||
result = {
|
||
"success": False,
|
||
"message": "转换字符串为空"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 转换为JSON数组
|
||
json_array = json.loads(convert_string)
|
||
|
||
# 验证是否为数组
|
||
if not isinstance(json_array, list):
|
||
result = {
|
||
"success": False,
|
||
"message": "转换结果不是JSON数组"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 设置输出参数
|
||
output = {
|
||
"convertArray": json_array
|
||
}
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "字符串转换为JSON数组成功",
|
||
"output": output
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except json.JSONDecodeError as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"字符串解析为JSON数组失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"字符串转换为JSON数组失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 添加流程控制模块处理器
|
||
|
||
# If-Else处理器
|
||
@register_handler("IfElseBp")
|
||
class IfElseBlockHandler(BlockHandler):
|
||
"""If-Else处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行If-Else条件判断块"""
|
||
try:
|
||
# 获取条件参数
|
||
condition = input_params.get("conditionIf")
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 根据条件执行不同分支
|
||
if condition:
|
||
# 执行if分支
|
||
branch_result = await executor.execute_children(block, "if")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件为真,执行if分支成功",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
else:
|
||
# 执行else分支
|
||
branch_result = await executor.execute_children(block, "else")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件为假,执行else分支成功",
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"If-Else条件判断执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# If-Else-If处理器
|
||
@register_handler("IfElseIfBp")
|
||
class IfElseIfBlockHandler(BlockHandler):
|
||
"""If-Else-If处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行If-Else-If条件判断块"""
|
||
try:
|
||
# 获取条件参数
|
||
condition_if = input_params.get("conditionIf")
|
||
condition_else_if = input_params.get("conditionElseIf")
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 根据条件执行不同分支
|
||
if condition_if:
|
||
# 执行if分支
|
||
branch_result = await executor.execute_children(block, "if")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件if为真,执行if分支成功",
|
||
"output": {
|
||
"condition": "if",
|
||
"branch": "if"
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
elif condition_else_if:
|
||
# 执行else_if分支
|
||
branch_result = await executor.execute_children(block, "else_if")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "条件else-if为真,执行else-if分支成功",
|
||
"output": {
|
||
"condition": "else_if",
|
||
"branch": "else_if"
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
else:
|
||
# 执行else分支
|
||
branch_result = await executor.execute_children(block, "else")
|
||
if not branch_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, branch_result, context)
|
||
return branch_result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "所有条件为假,执行else分支成功",
|
||
"output": {
|
||
"condition": "else",
|
||
"branch": "else"
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"If-Else-If条件判断执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 遍历数组处理器
|
||
@register_handler("IterateListBp")
|
||
class IterateListBlockHandler(BlockHandler):
|
||
"""遍历数组处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行数组遍历块"""
|
||
try:
|
||
# 获取数组参数
|
||
array_data = input_params.get("list", [])
|
||
|
||
# 如果不是数组,尝试转换
|
||
if not isinstance(array_data, list):
|
||
import json
|
||
try:
|
||
if isinstance(array_data, str):
|
||
array_data = json.loads(array_data)
|
||
else:
|
||
result = {
|
||
"success": False,
|
||
"message": "提供的参数不是有效的数组"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except:
|
||
result = {
|
||
"success": False,
|
||
"message": "提供的参数无法解析为数组"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 遍历数组
|
||
results = []
|
||
for index, item in enumerate(array_data):
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 设置循环变量
|
||
context.set_variable("index", index)
|
||
context.set_variable("item", item)
|
||
|
||
# 执行循环体
|
||
loop_result = await executor.execute_children(block, "default")
|
||
|
||
# 收集结果
|
||
results.append({
|
||
"index": index,
|
||
"success": loop_result.get("success", False),
|
||
"result": loop_result
|
||
})
|
||
|
||
# 如果执行失败,提前退出
|
||
if not loop_result.get("success", False):
|
||
result = {
|
||
"success": False,
|
||
"message": f"数组遍历在索引 {index} 处执行失败",
|
||
"output": {
|
||
"iterationResults": results,
|
||
"failedAt": index
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"数组遍历成功,遍历了 {len(array_data)} 个元素",
|
||
"output": {
|
||
"iterationResults": results,
|
||
"count": len(array_data)
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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("DelayBp")
|
||
class DelayBlockHandler(BlockHandler):
|
||
"""延迟处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行延迟块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 获取延迟时间参数(毫秒)
|
||
delay_time = input_params.get("timeMillis", 1000)
|
||
|
||
# 转换为秒
|
||
delay_sec = delay_time / 1000
|
||
|
||
# 等待
|
||
await asyncio.sleep(delay_sec)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": f"延迟 {delay_time} 毫秒完成",
|
||
"output": {
|
||
"delayTime": delay_time
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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
|
||
|
||
# Break处理器
|
||
@register_handler("BreakBp")
|
||
class BreakBlockHandler(BlockHandler):
|
||
"""Break处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行break块,用于跳出循环"""
|
||
try:
|
||
# 设置上下文中的break标志
|
||
context.set_variable("__BREAK__", True)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "Break执行成功,将跳出当前循环",
|
||
"output": {
|
||
"breakSignal": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"Break执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 添加数据库操作相关处理器
|
||
|
||
# 执行SQL处理器
|
||
@register_handler("JdbcExecuteBp")
|
||
class JdbcExecuteBlockHandler(BlockHandler):
|
||
"""执行SQL处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行SQL语句"""
|
||
from sqlalchemy import text
|
||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||
from sqlalchemy.orm import sessionmaker
|
||
import os
|
||
|
||
try:
|
||
# 获取SQL语句
|
||
sql = input_params.get("sql")
|
||
|
||
if not sql:
|
||
result = {
|
||
"success": False,
|
||
"message": "缺少SQL语句"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 获取数据库连接信息
|
||
# 通常从配置中获取,这里简化使用环境变量或默认值
|
||
db_url = os.environ.get("DATABASE_URL", "sqlite+aiosqlite:///database.db")
|
||
|
||
# 创建异步引擎和会话
|
||
engine = create_async_engine(db_url)
|
||
async_session = sessionmaker(
|
||
engine, expire_on_commit=False, class_=AsyncSession
|
||
)
|
||
|
||
# 执行SQL
|
||
async with async_session() as session:
|
||
result = await session.execute(text(sql))
|
||
await session.commit()
|
||
|
||
# 获取受影响的行数
|
||
row_count = result.rowcount if hasattr(result, 'rowcount') else 0
|
||
|
||
exec_result = {
|
||
"success": True,
|
||
"message": f"SQL执行成功,影响了 {row_count} 行",
|
||
"output": {
|
||
"rowCount": row_count
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"SQL执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 查询SQL处理器
|
||
@register_handler("JdbcQueryBp")
|
||
class JdbcQueryBlockHandler(BlockHandler):
|
||
"""查询SQL处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行SQL查询"""
|
||
from sqlalchemy import text
|
||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||
from sqlalchemy.orm import sessionmaker
|
||
import os
|
||
import json
|
||
|
||
try:
|
||
# 获取SQL语句
|
||
sql = input_params.get("sql")
|
||
|
||
if not sql:
|
||
return {
|
||
"success": False,
|
||
"message": "缺少SQL语句"
|
||
}
|
||
|
||
# 获取数据库连接信息
|
||
# 通常从配置中获取,这里简化使用环境变量或默认值
|
||
db_url = os.environ.get("DATABASE_URL", "sqlite+aiosqlite:///database.db")
|
||
|
||
# 创建异步引擎和会话
|
||
engine = create_async_engine(db_url)
|
||
async_session = sessionmaker(
|
||
engine, expire_on_commit=False, class_=AsyncSession
|
||
)
|
||
|
||
# 执行SQL查询
|
||
async with async_session() as session:
|
||
result = await session.execute(text(sql))
|
||
|
||
# 处理结果
|
||
if result.returns_rows:
|
||
# 获取列名
|
||
columns = result.keys()
|
||
|
||
# 转换为字典列表
|
||
rows = [dict(zip(columns, row)) for row in result.fetchall()]
|
||
|
||
# 转换为JSON字符串
|
||
result_json = json.dumps(rows)
|
||
|
||
# 设置上下文变量
|
||
context.set_variable("resultSet", result_json)
|
||
|
||
exec_result = {
|
||
"success": True,
|
||
"message": f"SQL查询成功,返回 {len(rows)} 条记录",
|
||
"output": {
|
||
"rowCount": len(rows),
|
||
"resultSet": rows,
|
||
"resultJson": result_json
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
else:
|
||
# 非查询语句,没有返回行
|
||
context.set_variable("resultSet", "[]")
|
||
|
||
exec_result = {
|
||
"success": True,
|
||
"message": "SQL执行成功,没有返回数据",
|
||
"output": {
|
||
"rowCount": 0,
|
||
"resultSet": [],
|
||
"resultJson": "[]"
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"SQL查询失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 检查任务实例ID是否存在处理器
|
||
@register_handler("CheckTaskRecordIdIsExistBp")
|
||
class CheckTaskRecordIdIsExistBlockHandler(BlockHandler):
|
||
"""检查任务实例ID是否存在处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""检查任务记录ID是否存在"""
|
||
from sqlalchemy import text, select
|
||
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
||
from sqlalchemy.orm import sessionmaker
|
||
from data.models import VWEDTaskRecord
|
||
import os
|
||
|
||
try:
|
||
# 获取任务记录ID
|
||
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
|
||
|
||
# 获取数据库连接信息
|
||
# 通常从配置中获取,这里简化使用环境变量或默认值
|
||
db_url = os.environ.get("DATABASE_URL", "sqlite+aiosqlite:///database.db")
|
||
|
||
# 创建异步引擎和会话
|
||
engine = create_async_engine(db_url)
|
||
async_session = sessionmaker(
|
||
engine, expire_on_commit=False, class_=AsyncSession
|
||
)
|
||
|
||
# 查询任务记录
|
||
async with async_session() as session:
|
||
query = select(VWEDTaskRecord).where(VWEDTaskRecord.id == task_record_id)
|
||
result = await session.execute(query)
|
||
record = result.scalar_one_or_none()
|
||
|
||
exists = record is not None
|
||
|
||
# 设置上下文变量
|
||
context.set_variable("taskRecordIdIsExist", exists)
|
||
|
||
exec_result = {
|
||
"success": True,
|
||
"message": f"任务记录ID {'存在' if exists else '不存在'}",
|
||
"output": {
|
||
"exists": exists,
|
||
"taskRecordId": task_record_id
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, exec_result, context)
|
||
return exec_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"检查任务记录ID是否存在失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 增强现有脚本处理器和添加脚本变量处理器
|
||
|
||
# 返回块处理器
|
||
@register_handler("ReturnBp")
|
||
class ReturnBlockHandler(BlockHandler):
|
||
"""Return处理器,用于提前返回结果"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""执行return块,用于提前返回流程执行结果"""
|
||
try:
|
||
# 设置上下文中的return标志
|
||
context.set_variable("__RETURN__", True)
|
||
|
||
# 获取可能的返回数据
|
||
return_data = input_params.get("data", {})
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "Return执行成功,将提前结束流程",
|
||
"output": {
|
||
"returnSignal": True,
|
||
"returnData": return_data
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"Return执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 串行执行块处理器
|
||
@register_handler("SerialFlowBp")
|
||
class SerialFlowBlockHandler(BlockHandler):
|
||
"""串行执行块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""串行执行子块"""
|
||
try:
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 执行default分支下的所有子块
|
||
result = await executor.execute_children(block, "default")
|
||
|
||
# 检查是否成功
|
||
if not result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
final_result = {
|
||
"success": True,
|
||
"message": "串行执行完成",
|
||
"output": result.get("output", {})
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"串行执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 并行执行块处理器
|
||
@register_handler("ParallelFlowBp")
|
||
class ParallelFlowBlockHandler(BlockHandler):
|
||
"""并行执行块处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""并行执行子块"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
|
||
# 获取子块
|
||
children = block.get("children", {}).get("default", [])
|
||
|
||
if not children:
|
||
result = {
|
||
"success": True,
|
||
"message": "没有子块需要执行",
|
||
"output": {}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 为每个子块创建一个执行任务
|
||
tasks = []
|
||
results = []
|
||
|
||
for child_block in children:
|
||
# 为每个子块创建一个新的执行上下文(共享同一个任务上下文)
|
||
executor = BlockExecutor(context)
|
||
|
||
# 将子块包装为一个异步任务
|
||
task = asyncio.create_task(executor.execute_block(child_block))
|
||
tasks.append(task)
|
||
|
||
# 等待所有任务完成
|
||
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
|
||
|
||
# 处理任务结果
|
||
all_success = True
|
||
for i, result in enumerate(completed_tasks):
|
||
if isinstance(result, Exception):
|
||
results.append({
|
||
"success": False,
|
||
"message": f"子块执行异常: {str(result)}",
|
||
"index": i
|
||
})
|
||
all_success = False
|
||
else:
|
||
results.append(result)
|
||
if not result.get("success", False):
|
||
all_success = False
|
||
|
||
# 所有并行子块执行完成后,检查是否有后续处理
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 根据执行结果处理后续分支
|
||
if all_success:
|
||
# 执行成功分支
|
||
if "success" in block.get("children", {}) and block["children"]["success"]:
|
||
logger.info(f"并行执行成功,执行success分支")
|
||
success_result = await executor.execute_children(block, "success")
|
||
if not success_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, success_result, context)
|
||
return success_result
|
||
else:
|
||
# 执行失败分支
|
||
if "fail" in block.get("children", {}) and block["children"]["fail"]:
|
||
logger.info(f"并行执行部分失败,执行fail分支")
|
||
fail_result = await executor.execute_children(block, "fail")
|
||
if not fail_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, fail_result, context)
|
||
return fail_result
|
||
|
||
# 执行完成分支(无论成功失败)
|
||
if "complete" in block.get("children", {}) and block["children"]["complete"]:
|
||
logger.info(f"并行执行完成,执行complete分支")
|
||
complete_result = await executor.execute_children(block, "complete")
|
||
if not complete_result.get("success", False):
|
||
# 记录执行结果
|
||
await self._record_task_log(block, complete_result, context)
|
||
return complete_result
|
||
|
||
final_result = {
|
||
"success": all_success,
|
||
"message": "并行执行完成" if all_success else "并行执行部分失败",
|
||
"output": {
|
||
"results": results,
|
||
"allSuccess": all_success
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"并行执行失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 并发执行N次处理器
|
||
@register_handler("ParallelRepeatNBp")
|
||
class ParallelRepeatNBlockHandler(BlockHandler):
|
||
"""并发执行N次处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""并发执行子块N次"""
|
||
import asyncio
|
||
|
||
try:
|
||
# 获取执行次数
|
||
num = int(input_params.get("num", 1))
|
||
# 限制最大执行次数
|
||
num = min(num, 100)
|
||
|
||
if num <= 0:
|
||
result = {
|
||
"success": True,
|
||
"message": "执行次数必须大于0",
|
||
"output": {}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
|
||
# 为每次执行创建一个执行任务
|
||
tasks = []
|
||
results = []
|
||
|
||
for i in range(num):
|
||
# 为每次执行创建一个新的执行上下文(共享同一个任务上下文)
|
||
executor = BlockExecutor(context)
|
||
context.set_variable("index", i)
|
||
|
||
# 执行default分支下的子块
|
||
task = asyncio.create_task(executor.execute_children(block, "default"))
|
||
tasks.append(task)
|
||
|
||
# 等待所有任务完成
|
||
completed_tasks = await asyncio.gather(*tasks, return_exceptions=True)
|
||
|
||
# 处理任务结果
|
||
all_success = True
|
||
for i, result in enumerate(completed_tasks):
|
||
if isinstance(result, Exception):
|
||
results.append({
|
||
"success": False,
|
||
"message": f"第{i+1}次执行异常: {str(result)}",
|
||
"index": i
|
||
})
|
||
all_success = False
|
||
else:
|
||
results.append(result)
|
||
if not result.get("success", False):
|
||
all_success = False
|
||
|
||
final_result = {
|
||
"success": all_success,
|
||
"message": f"并发执行{num}次完成" if all_success else f"并发执行{num}次部分失败",
|
||
"output": {
|
||
"results": results,
|
||
"iterations": num
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"并发执行N次失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 重复执行N次处理器
|
||
@register_handler("RepeatNumBp")
|
||
class RepeatNumBlockHandler(BlockHandler):
|
||
"""重复执行N次处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""重复执行子块N次"""
|
||
try:
|
||
# 获取执行次数
|
||
num = int(input_params.get("num", 1))
|
||
# 限制最大执行次数
|
||
num = min(num, 1000)
|
||
|
||
if num <= 0:
|
||
result = {
|
||
"success": True,
|
||
"message": "执行次数必须大于0",
|
||
"output": {}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 创建块执行器
|
||
from services.execution.block_executor import BlockExecutor
|
||
executor = BlockExecutor(context)
|
||
|
||
# 循环执行
|
||
results = []
|
||
for i in range(num):
|
||
# 检查是否取消
|
||
if context.is_task_canceled():
|
||
result = {
|
||
"success": False,
|
||
"message": "任务已被取消"
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 检查是否有中断或返回信号
|
||
if context.get_variable("__BREAK__", False):
|
||
logger.info(f"检测到中断信号,提前结束重复执行,已完成 {i}/{num} 次")
|
||
context.set_variable("__BREAK__", False) # 重置中断信号
|
||
break
|
||
|
||
if context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束重复执行,已完成 {i}/{num} 次")
|
||
# 不需要重置返回信号,它需要向上传播
|
||
break
|
||
|
||
# 设置当前索引
|
||
context.set_variable("index", i)
|
||
|
||
# 执行子块
|
||
result = await executor.execute_children(block, "default")
|
||
results.append({
|
||
"index": i,
|
||
"success": result.get("success", False),
|
||
"result": result
|
||
})
|
||
|
||
# 如果执行失败,提前退出
|
||
if not result.get("success", False):
|
||
failed_result = {
|
||
"success": False,
|
||
"message": f"重复执行在第 {i+1} 次时失败",
|
||
"output": {
|
||
"results": results,
|
||
"iterations": i + 1,
|
||
"totalIterations": num,
|
||
"failedAt": i
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, failed_result, context)
|
||
return failed_result
|
||
|
||
# 执行完成分支
|
||
if "complete" in block.get("children", {}) and block["children"]["complete"] and results:
|
||
# 设置迭代信息
|
||
context.set_variable("count", len(results))
|
||
context.set_variable("lastIndex", len(results) - 1)
|
||
|
||
complete_result = await executor.execute_children(block, "complete")
|
||
if not complete_result.get("success", False):
|
||
failed_complete = {
|
||
"success": False,
|
||
"message": f"完成分支执行失败: {complete_result.get('message')}",
|
||
"output": {
|
||
"results": results,
|
||
"iterations": len(results),
|
||
"totalIterations": num
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, failed_complete, context)
|
||
return failed_complete
|
||
|
||
final_result = {
|
||
"success": True,
|
||
"message": f"重复执行成功,共执行 {len(results)} 次",
|
||
"output": {
|
||
"results": results,
|
||
"iterations": len(results),
|
||
"totalIterations": num
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
await self._record_task_log(block, final_result, context)
|
||
return final_result
|
||
except Exception as e:
|
||
result = {
|
||
"success": False,
|
||
"message": f"重复执行N次失败: {str(e)}"
|
||
}
|
||
# 记录异常
|
||
await self._record_task_log(block, result, context)
|
||
return result
|
||
|
||
# 抛出异常处理器
|
||
@register_handler("ThrowExceptionBp")
|
||
class ThrowExceptionBlockHandler(BlockHandler):
|
||
"""抛出异常处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""抛出异常"""
|
||
try:
|
||
# 获取异常提示文本
|
||
message = input_params.get("message", "未知异常")
|
||
|
||
# 记录日志
|
||
logger.error(f"主动抛出异常: {message}")
|
||
|
||
# 这里实际上是返回失败结果,而不是真正抛出异常
|
||
# 这样可以更好地控制任务流程
|
||
result = {
|
||
"success": False,
|
||
"message": f"主动抛出异常: {message}",
|
||
"output": {
|
||
"exceptionMessage": 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("StopOtherBranch")
|
||
class StopOtherBranchBlockHandler(BlockHandler):
|
||
"""停止其他并行分支处理器"""
|
||
|
||
async def execute(
|
||
self,
|
||
block: Dict[str, Any],
|
||
input_params: Dict[str, Any],
|
||
context: TaskContext
|
||
) -> Dict[str, Any]:
|
||
"""停止其他并行分支"""
|
||
try:
|
||
# 设置停止信号
|
||
context.set_variable("__STOP_OTHER_BRANCHES__", True)
|
||
|
||
result = {
|
||
"success": True,
|
||
"message": "停止其他并行分支信号已设置",
|
||
"output": {
|
||
"stopSignal": True
|
||
}
|
||
}
|
||
# 记录执行结果
|
||
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
|
||
|