1302 lines
54 KiB
Python
1302 lines
54 KiB
Python
#!/usr/bin/env python
|
||
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
块执行器模块
|
||
提供任务块的执行能力
|
||
"""
|
||
|
||
import json
|
||
import uuid
|
||
from datetime import datetime
|
||
from typing import Dict, List, Any, Optional
|
||
from sqlalchemy import select, insert, text
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
import re
|
||
from data.models.blockrecord import VWEDBlockRecord
|
||
from data.models.taskdef import VWEDTaskDef
|
||
from data.models.taskrecord import VWEDTaskRecord
|
||
from data.session import get_async_session
|
||
from services.execution.task_context import TaskContext
|
||
from services.execution.handlers.base import get_block_handler
|
||
from utils.logger import get_logger
|
||
from data.enum.task_block_record_enum import TaskBlockRecordStatus
|
||
from data.enum.task_input_param_enum import TaskInputParamType, TaskInputParamVariables
|
||
|
||
|
||
# 获取日志记录器
|
||
logger = get_logger("services.execution.block_executor")
|
||
|
||
class BlockExecutor:
|
||
"""
|
||
块执行器类
|
||
负责执行任务中的各类块,并记录执行状态
|
||
"""
|
||
|
||
def __init__(self, task_context: TaskContext):
|
||
"""
|
||
初始化块执行器
|
||
|
||
Args:
|
||
task_context: 任务上下文
|
||
"""
|
||
self.task_context = task_context
|
||
self.is_canceled = False
|
||
|
||
def cancel(self) -> None:
|
||
"""
|
||
取消块执行
|
||
"""
|
||
self.is_canceled = True
|
||
self.task_context.mark_canceled()
|
||
|
||
async def execute_block(self, block: Dict[str, Any]) -> Dict[str, Any]:
|
||
"""
|
||
执行任务块
|
||
|
||
Args:
|
||
block: 任务块定义
|
||
|
||
Returns:
|
||
Dict[str, Any]: 执行结果
|
||
"""
|
||
# 检查是否已取消
|
||
if self.is_canceled or self.task_context.is_task_canceled():
|
||
return {
|
||
"success": False,
|
||
"message": "任务已被取消",
|
||
"block_id": block.get("id", "unknown")
|
||
}
|
||
if block is None:
|
||
return {
|
||
"success": False,
|
||
"message": "核心执行逻辑中的逻辑块不能为空!"
|
||
}
|
||
block_id = block.get("id", "unknown")
|
||
block_type = block.get("blockType", "unknown")
|
||
block_name = block.get("name", f"block-{block_id}")
|
||
|
||
logger.info(f"开始执行任务块: {block_name}, 类型: {block_type}, ID: {block_id}")
|
||
|
||
try:
|
||
# 设置当前块到上下文中
|
||
self.task_context.set_current_block(block_id, block_name)
|
||
|
||
# 创建块记录
|
||
block_record_id = await self._create_block_record(block)
|
||
|
||
# 记录执行路径
|
||
self.task_context.add_execution_path(block_id)
|
||
# 解析输入参数
|
||
input_params = await self._parse_input_params(block.get("inputParams", {}))
|
||
|
||
# 获取块处理器
|
||
handler = get_block_handler(block_type)
|
||
if not handler:
|
||
error_msg = f"不支持的块类型: {block_type}"
|
||
logger.error(error_msg)
|
||
await self._update_block_record(block_record_id, TaskBlockRecordStatus.FAILED, error_msg)
|
||
return {"success": False, "message": error_msg, "block_id": block_id}
|
||
|
||
# 执行块
|
||
try:
|
||
# 更新块状态为执行中
|
||
await self._update_block_record(block_record_id, TaskBlockRecordStatus.RUNNING, "执行中")
|
||
# 执行块处理器
|
||
result = await handler.execute(block, input_params, self.task_context)
|
||
# 检查结果
|
||
if result.get("success", False):
|
||
# 更新块状态为成功
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.SUCCESS,
|
||
"执行成功",
|
||
result.get("output", {})
|
||
)
|
||
|
||
return result
|
||
else:
|
||
# 更新块状态为失败
|
||
error_msg = result.get("message", "执行失败")
|
||
await self._update_block_record(block_record_id, TaskBlockRecordStatus.FAILED, error_msg)
|
||
|
||
# 设置错误信息
|
||
self.task_context.set_error(error_msg, block_id)
|
||
|
||
return result
|
||
except Exception as e:
|
||
# 处理执行异常
|
||
error_msg = f"块执行异常: {str(e)}"
|
||
logger.error(f"块 {block_id} ({block_type}) 执行异常: {str(e)}")
|
||
|
||
# 更新块状态为异常
|
||
await self._update_block_record(block_record_id, TaskBlockRecordStatus.FAILED, error_msg)
|
||
|
||
# 设置错误信息
|
||
self.task_context.set_error(error_msg, block_id)
|
||
|
||
return {
|
||
"success": False,
|
||
"message": error_msg,
|
||
"block_id": block_id,
|
||
"error": str(e)
|
||
}
|
||
|
||
except Exception as e:
|
||
logger.error(f"块 {block_id} ({block_type}) 处理失败: {str(e)}")
|
||
|
||
# 设置错误信息
|
||
self.task_context.set_error(f"块处理失败: {str(e)}", block_id)
|
||
|
||
return {
|
||
"success": False,
|
||
"message": f"块处理失败: {str(e)}",
|
||
"block_id": block_id,
|
||
"error": str(e)
|
||
}
|
||
|
||
async def execute_children(self, block: Dict[str, Any], branch: str = "default") -> Dict[str, Any]:
|
||
"""
|
||
执行子块
|
||
|
||
Args:
|
||
block: 父块定义
|
||
branch: 分支名称
|
||
|
||
Returns:
|
||
Dict[str, Any]: 执行结果
|
||
"""
|
||
try:
|
||
block_id = block.get('id', 'unknown')
|
||
|
||
logger.info(f"开始执行 execute_children 方法 - 块ID: {block_id}, 分支: {branch}")
|
||
|
||
# 获取指定分支下的子块
|
||
children = block.get("children", {}).get(branch, [])
|
||
|
||
if not children:
|
||
logger.info(f"块 {block_id} 的 {branch} 分支下没有子块")
|
||
return {
|
||
"success": True,
|
||
"message": f"没有子块需要执行: {branch}",
|
||
"output": {
|
||
"executed": False,
|
||
"branch": branch
|
||
}
|
||
}
|
||
|
||
logger.info(f"开始执行块 {block_id} 的 {branch} 分支下的 {len(children)} 个子块")
|
||
|
||
# 检查父块输出,判断是否需要跳过执行
|
||
parent_output = self.task_context.get_block_output(block_id)
|
||
# 检查是否有executed标志,若为False则不执行任何子块
|
||
# 这主要用于条件块等流程控制,当条件不满足时避免执行子块
|
||
if parent_output and isinstance(parent_output, dict) and parent_output.get("executed") is False:
|
||
logger.info(f"块 {block_id} 的输出包含executed=False标志,跳过执行子块")
|
||
# 虽然不执行子块,但仍然为每个子块创建记录并标记为"未执行"状态
|
||
results = []
|
||
for i, child_block in enumerate(children):
|
||
child_id = child_block.get('id', 'unknown')
|
||
child_type = child_block.get('blockType', 'unknown')
|
||
child_name = child_block.get('name', f"block-{child_id}")
|
||
|
||
logger.info(f"为未执行的子块创建记录 [{i+1}/{len(children)}] - 名称: {child_name}, ID: {child_id}, 类型: {child_type}")
|
||
|
||
# 创建子块记录
|
||
block_record_id = await self._create_block_record(child_block)
|
||
|
||
# 更新块记录状态为"未执行"
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.NOT_EXECUTED, # 使用1006表示"未执行"状态
|
||
"条件不满足,块未执行",
|
||
)
|
||
|
||
# 添加到结果集
|
||
results.append({
|
||
"child_id": child_id,
|
||
"success": True, # 标记为成功,因为这不是执行失败
|
||
"output": {"executed": False, "reason": "parent_condition_not_met"}
|
||
})
|
||
|
||
return {
|
||
"success": True,
|
||
"message": f"根据父块标志跳过子块执行: {branch}",
|
||
"output": {
|
||
"executed": False,
|
||
"branch": branch,
|
||
"results": results
|
||
}
|
||
}
|
||
|
||
# 获取跳转目标块ID
|
||
# 收集所有子块执行结果
|
||
results = []
|
||
print("children", children, "=============================================")
|
||
# 依次执行子块
|
||
for i, child_block in enumerate(children):
|
||
# 检查是否有中断或返回信号
|
||
if self.task_context.get_variable("__RETURN__", False):
|
||
logger.info(f"检测到返回信号,提前结束块 {block_id} 的 {branch} 分支执行,已处理 {i}/{len(children)} 个子块")
|
||
break
|
||
|
||
child_id = child_block.get('id', 'unknown')
|
||
child_type = child_block.get('blockType', 'unknown')
|
||
child_name = child_block.get('name', f"b{child_id}")
|
||
skip_to_block_name = self.task_context.get_skip_to()
|
||
start_execution = skip_to_block_name is None # 如果没有设置跳转目标,就从头开始执行
|
||
# 检查是否是跳转目标块
|
||
if skip_to_block_name and child_name == skip_to_block_name:
|
||
logger.info(f"找到跳转目标块: {child_name}, ID: {child_id}")
|
||
start_execution = True
|
||
# 清除跳转标记,避免影响后续执行
|
||
self.task_context.clear_skip_to()
|
||
# 如果当前还未开始执行(处于跳过状态),为块创建"未执行"记录
|
||
if not start_execution:
|
||
logger.info(f"跳过执行子块 [{i+1}/{len(children)}] - 名称: {child_name}, ID: {child_id}, 类型: {child_type}")
|
||
|
||
# 创建子块记录但标记为未执行
|
||
block_record_id = await self._create_block_record(child_block)
|
||
|
||
# 设置为跳过状态
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.NOT_EXECUTED, # 未执行状态
|
||
"由于跳转设置,此块被跳过",
|
||
)
|
||
|
||
# 添加到结果集
|
||
results.append({
|
||
"child_id": child_id,
|
||
"success": True,
|
||
"output": {"executed": False, "reason": "skipped_by_jump"}
|
||
})
|
||
|
||
continue
|
||
|
||
logger.info(f"执行子块 [{i+1}/{len(children)}] - 名称: {child_name}, ID: {child_id}, 类型: {child_type}")
|
||
|
||
# 创建子块记录
|
||
block_record_id = await self._create_block_record(child_block)
|
||
logger.debug(f"为子块 {child_id} 创建记录, 记录ID: {block_record_id}")
|
||
|
||
try:
|
||
# 更新块记录状态为执行中
|
||
await self._update_block_record(block_record_id, TaskBlockRecordStatus.RUNNING, "执行中")
|
||
|
||
# 解析子块的输入参数
|
||
raw_params = child_block.get("inputParams", {})
|
||
# 解析参数
|
||
parsed_params = await self._parse_input_params(raw_params)
|
||
|
||
# 获取处理器
|
||
handler = get_block_handler(child_type)
|
||
if not handler:
|
||
error_msg = f"未找到块类型 {child_type} 的处理器"
|
||
logger.error(error_msg)
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.FAILED, # 失败
|
||
error_msg,
|
||
)
|
||
return {
|
||
"success": False,
|
||
"message": error_msg,
|
||
"block_id": child_id
|
||
}
|
||
|
||
# 执行块
|
||
logger.info(f"开始执行子块 {child_id} 的处理逻辑")
|
||
result = await handler.execute(child_block, parsed_params, self.task_context)
|
||
print("result", result, "=============================================")
|
||
# 检查是否执行成功
|
||
if not result.get("success", False):
|
||
if result.get("is_canceled", False):
|
||
logger.warning(f"子块 {child_id} 执行失败: {result.get('message', '未知错误')}")
|
||
# 更新块记录状态为取消
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.CANCELED, # 取消
|
||
result.get("message", "执行失败"),
|
||
)
|
||
return {
|
||
"success": False,
|
||
"message": f"子块 {child_id} 执行失败: {result.get('message', '未知错误')}",
|
||
"block_id": child_id,
|
||
"is_canceled": True,
|
||
"output": result.get("output", {})
|
||
}
|
||
else:
|
||
logger.error(f"子块 {child_id} 执行失败: {result.get('message', '未知错误')}")
|
||
# 更新块记录状态为失败
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.FAILED, # 失败
|
||
result.get("message", "执行失败"),
|
||
)
|
||
|
||
return {
|
||
"success": False,
|
||
"message": f"子块 {child_id} 执行失败: {result.get('message', '未知错误')}",
|
||
"block_id": child_id,
|
||
"output": result.get("output", {})
|
||
}
|
||
|
||
# 更新块记录状态为成功
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.SUCCESS, # 成功
|
||
"执行成功",
|
||
result.get("output", {})
|
||
)
|
||
|
||
# 添加到结果集
|
||
results.append({
|
||
"child_id": child_id,
|
||
"success": True,
|
||
"output": result.get("output", {})
|
||
})
|
||
|
||
|
||
except Exception as e:
|
||
# 处理执行过程中的异常
|
||
error_msg = f"子块 {child_id} 执行异常: {str(e)}"
|
||
logger.error(error_msg)
|
||
|
||
# 更新块记录状态为失败
|
||
await self._update_block_record(
|
||
block_record_id,
|
||
TaskBlockRecordStatus.FAILED, # 失败
|
||
error_msg,
|
||
)
|
||
|
||
# 设置错误信息到上下文
|
||
self.task_context.set_error(error_msg, child_id)
|
||
|
||
return {
|
||
"success": False,
|
||
"message": error_msg,
|
||
"block_id": child_id,
|
||
"error": str(e)
|
||
}
|
||
# 所有子块执行完成
|
||
print("results", results, "=============================================")
|
||
return {
|
||
"success": True,
|
||
"message": f"分支 {branch} 的所有子块执行完成",
|
||
"output": {
|
||
"executed": True,
|
||
"branch": branch,
|
||
"results": results
|
||
}
|
||
}
|
||
|
||
except Exception as e:
|
||
# 处理execute_children方法自身的异常
|
||
error_msg = f"execute_children 方法异常: {str(e)}"
|
||
logger.error(error_msg)
|
||
|
||
# 设置错误信息到上下文
|
||
self.task_context.set_error(error_msg, block.get('id', 'unknown'))
|
||
|
||
return {
|
||
"success": False,
|
||
"message": error_msg,
|
||
"error": str(e)
|
||
}
|
||
|
||
async def _create_block_record(self, block: Dict[str, Any]) -> str:
|
||
"""
|
||
创建块记录
|
||
|
||
Args:
|
||
block: 任务块定义
|
||
|
||
Returns:
|
||
str: 块记录ID
|
||
"""
|
||
try:
|
||
block_id = block.get("id", "unknown")
|
||
block_type = block.get("blockType", "unknown")
|
||
block_name = block.get("name", f"block-{block_id}")
|
||
# 创建块记录
|
||
record_id = str(uuid.uuid4())
|
||
|
||
# 预处理输入参数,处理不能直接JSON序列化的类型
|
||
input_params = self._process_json_data(block.get("inputParams", {}))
|
||
|
||
# 提取输入参数的具体值
|
||
input_params_value = {}
|
||
if input_params:
|
||
try:
|
||
# 对于每个参数,提取其value值
|
||
for key, value_info in input_params.items():
|
||
if isinstance(value_info, dict) and "value" in value_info:
|
||
input_params_value[key] = value_info["value"]
|
||
else:
|
||
input_params_value[key] = value_info
|
||
except Exception as e:
|
||
logger.warning(f"提取输入参数值失败: {str(e)}")
|
||
input_params_value = input_params
|
||
|
||
async with get_async_session() as session:
|
||
stmt = insert(VWEDBlockRecord).values(
|
||
id=record_id,
|
||
task_record_id=self.task_context.task_record_id,
|
||
task_id=self.task_context.task_def_id,
|
||
block_id=str(block_id),
|
||
block_name=block_name,
|
||
block_execute_name=block_type,
|
||
block_config_id=block.get("configId", ""),
|
||
status=TaskBlockRecordStatus.RUNNING, # 开始执行
|
||
input_params=json.dumps(input_params, ensure_ascii=False),
|
||
block_input_params=json.dumps(block.get("inputParams", {}), ensure_ascii=False),
|
||
block_input_params_value=json.dumps(input_params_value, ensure_ascii=False),
|
||
block_internal_variables=json.dumps(self._process_json_data(self.task_context.variables), ensure_ascii=False),
|
||
internal_variables=json.dumps(self._process_json_data(self.task_context.variables), ensure_ascii=False),
|
||
started_on=datetime.now()
|
||
)
|
||
await session.execute(stmt)
|
||
await session.commit()
|
||
|
||
return record_id
|
||
|
||
except Exception as e:
|
||
logger.error(f"创建块记录失败: {str(e)}")
|
||
raise
|
||
|
||
async def _update_block_record(
|
||
self,
|
||
block_record_id: str,
|
||
status: int,
|
||
message: str = None,
|
||
output: Dict[str, Any] = None,
|
||
) -> None:
|
||
"""
|
||
更新块记录
|
||
|
||
Args:
|
||
block_record_id: 块记录ID
|
||
status: 状态码
|
||
message: 状态消息
|
||
output: 输出结果
|
||
"""
|
||
try:
|
||
async with get_async_session() as session:
|
||
# 查询块记录
|
||
result = await session.execute(
|
||
select(VWEDBlockRecord).where(VWEDBlockRecord.id == block_record_id)
|
||
)
|
||
block_record: VWEDBlockRecord = result.scalars().first()
|
||
if not block_record:
|
||
logger.error(f"块记录不存在: {block_record_id}")
|
||
return
|
||
|
||
# 更新状态
|
||
block_record.status = status
|
||
# 更新消息
|
||
if message:
|
||
block_record.ended_reason = message
|
||
block_record.remark = message
|
||
|
||
# 获取块ID和名称
|
||
block_id = block_record.block_id
|
||
block_name = block_record.block_name
|
||
|
||
# 直接获取任务上下文中来自此块的变量
|
||
block_variables = self.task_context.get_block_variables(block_id=block_id)
|
||
logger.info(f"块 {block_name} (ID: {block_id}) 设置的变量: {list(block_variables.keys())}")
|
||
|
||
# 更新内部变量(当前上下文中的所有变量)
|
||
block_output = self.task_context.get_block_output(block_name)
|
||
# 处理输出并存储
|
||
# if block_output:
|
||
processed_output = self._process_json_data(block_output)
|
||
# 构建输出结构 {"blocks": {"块名称": 输出内容}}
|
||
full_output = {TaskInputParamVariables.BLOCKS: {block_name: processed_output}}
|
||
output_full_json = json.dumps(full_output, ensure_ascii=False)
|
||
output_value_json = json.dumps(processed_output, ensure_ascii=False)
|
||
block_record.output_params = output_full_json
|
||
block_record.block_out_params_value = output_value_json
|
||
block_record.internal_variables = self.task_context.variables.__str__()
|
||
|
||
logger.info(f"为块 {block_name} 存储输出: {list(processed_output.keys()) if isinstance(processed_output, dict) else type(processed_output)}")
|
||
|
||
# 更新结束时间(如果状态为完成或失败)
|
||
if status in [TaskBlockRecordStatus.SUCCESS, TaskBlockRecordStatus.FAILED]:
|
||
block_record.ended_on = datetime.now()
|
||
await session.commit()
|
||
|
||
except Exception as e:
|
||
logger.error(f"更新块记录失败: {str(e)}")
|
||
raise
|
||
|
||
def _process_json_data(self, data):
|
||
"""
|
||
处理数据以确保能够被JSON序列化
|
||
|
||
Args:
|
||
data: 需要处理的数据
|
||
|
||
Returns:
|
||
处理后的数据
|
||
"""
|
||
if data is None:
|
||
return None
|
||
|
||
if isinstance(data, dict):
|
||
# 处理字典
|
||
return {k: self._process_json_data(v) for k, v in data.items()}
|
||
elif isinstance(data, list):
|
||
# 处理列表
|
||
return [self._process_json_data(item) for item in data]
|
||
elif isinstance(data, datetime):
|
||
# 处理日期时间对象
|
||
return data.strftime("%Y-%m-%d %H:%M:%S")
|
||
elif isinstance(data, (int, float, str, bool)) or data is None:
|
||
# 这些类型可以直接序列化
|
||
return data
|
||
else:
|
||
# 其他类型转换为字符串
|
||
return str(data)
|
||
|
||
async def _parse_input_params(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
||
"""
|
||
解析输入参数
|
||
处理表达式、变量引用等
|
||
|
||
Args:
|
||
params: 原始参数
|
||
|
||
Returns:
|
||
Dict[str, Any]: 解析后的参数
|
||
"""
|
||
def extract_items(input_str):
|
||
"""将形如"[taskInputs.a,taskInputs.b]"的字符串转换为["taskInputs.a", "taskInputs.b"]"""
|
||
# 使用正则表达式匹配中括号内的内容,然后分割
|
||
match = re.search(r'\[(.*)\]', input_str)
|
||
if match:
|
||
# 获取括号内的内容并按逗号分割
|
||
items = []
|
||
for item in match.group(1).split(','):
|
||
try:
|
||
json.loads(item)
|
||
json_item = eval(item)
|
||
except Exception as e:
|
||
json_item = item.strip()
|
||
items.append(json_item)
|
||
return items
|
||
return input_str
|
||
|
||
if not params:
|
||
return {}
|
||
|
||
parsed_params = {}
|
||
|
||
for key, value_info in params.items():
|
||
# 处理不同类型的参数
|
||
param_type = value_info.get("type", TaskInputParamType.SIMPLE)
|
||
param_value = value_info.get("value")
|
||
if param_type == TaskInputParamType.SIMPLE:
|
||
# 简单值,直接使用
|
||
parsed_params[key] = param_value
|
||
elif param_type == TaskInputParamType.EXPRESSION:
|
||
# 表达式,需要从上下文中获取值
|
||
param_value = extract_items(param_value)
|
||
if isinstance(param_value, list):
|
||
parsed_params[key] = [await self._parse_expression(key, c) for c in param_value]
|
||
else:
|
||
express_result = await self._parse_expression(key, param_value)
|
||
parsed_params[key] = express_result
|
||
elif param_type == TaskInputParamType.JSON:
|
||
# JSON值,需要解析
|
||
# 先同步解析JSON结构
|
||
parsed_value = self._parse_json_value(param_value)
|
||
# 再处理其中可能包含的表达式标记
|
||
parsed_params[key] = await self._process_json_expressions(parsed_value)
|
||
else:
|
||
# 默认处理
|
||
parsed_params[key] = param_value
|
||
|
||
return parsed_params
|
||
|
||
async def _process_json_expressions(self, data: Any) -> Any:
|
||
"""
|
||
处理JSON中的表达式标记
|
||
|
||
Args:
|
||
data: JSON数据
|
||
|
||
Returns:
|
||
Any: 处理后的数据
|
||
"""
|
||
# 处理列表
|
||
if isinstance(data, list):
|
||
return await self._process_nested_json(data)
|
||
|
||
# # 处理字典
|
||
# elif isinstance(data, dict):
|
||
# result = {}
|
||
# for key, value in data.items():
|
||
# result[key] = await self._process_json_expressions(value)
|
||
# return result
|
||
|
||
|
||
# 其他类型直接返回
|
||
return data
|
||
|
||
async def _parse_expression(self, key: str, expression_value: Any) -> Any:
|
||
"""
|
||
解析表达式类型的参数值
|
||
|
||
Args:
|
||
key: 参数键名
|
||
expression_value: 表达式值
|
||
|
||
Returns:
|
||
Any: 解析后的值
|
||
"""
|
||
if not isinstance(expression_value, str):
|
||
return expression_value
|
||
# 检查是否包含加号,表示需要合并多个对象
|
||
if "+" in expression_value and "." in expression_value:
|
||
return await self._parse_combined_expression(expression_value)
|
||
# 检查是否是数据库表引用的表达式 (如: vwed_taskdef.id)
|
||
elif expression_value.startswith(TaskInputParamVariables.VWED_) and "." in expression_value:
|
||
return await self._parse_db_reference(expression_value)
|
||
# 检查是否是块输出引用 (如: blocks.blockName.fieldName)
|
||
elif expression_value.startswith(TaskInputParamVariables.BLOCKS):
|
||
return self._parse_block_reference(expression_value)
|
||
# 检查是否是任务输入参数引用 (如: taskInputs.paramName)
|
||
elif expression_value.startswith(TaskInputParamVariables.TASK_INPUTS):
|
||
return await self._parse_task_inputs_reference(expression_value)
|
||
# 检查是否是字符串工具函数调用 (如: StringUtils.isBlank("你好"))
|
||
elif expression_value.startswith(TaskInputParamVariables.STRING_UTILS):
|
||
return await self._parse_string_utils_expression(expression_value)
|
||
else:
|
||
# 非数据库表引用,尝试从上下文变量中获取
|
||
return expression_value
|
||
|
||
def _split_expression_by_plus(self, expression: str) -> List[str]:
|
||
"""
|
||
按照加号分割表达式,但忽略引号内的加号
|
||
|
||
Args:
|
||
expression: 需要分割的表达式
|
||
|
||
Returns:
|
||
List[str]: 分割后的表达式部分列表
|
||
"""
|
||
parts = []
|
||
current_part = ""
|
||
in_quotes = False
|
||
quote_char = None
|
||
num_error = 0
|
||
num_left_quote = 0
|
||
for index, char in enumerate(expression):
|
||
# 处理引号
|
||
if char in ['(', ")"]:
|
||
num_error += 1
|
||
if num_error == 1 and char in ['”', "“"]:
|
||
raise Exception(f"表达式 {expression} 格式不规范")
|
||
if char in ['"', "'"]:
|
||
if not in_quotes: # 开始引号
|
||
in_quotes = True
|
||
quote_char = char
|
||
elif char == quote_char: # 结束引号
|
||
in_quotes = False
|
||
quote_char = None
|
||
num_left_quote += 1
|
||
current_part += char
|
||
if num_left_quote == 1 and char == ",":
|
||
raise Exception(f"表达式 {expression} 格式不规范")
|
||
elif char == '+' and not in_quotes: # 只处理引号外的加号作为分隔符
|
||
if current_part.strip():
|
||
parts.append(current_part.strip())
|
||
current_part = ""
|
||
else:
|
||
current_part += char
|
||
|
||
# 添加最后一部分
|
||
if current_part.strip():
|
||
parts.append(current_part.strip())
|
||
|
||
return parts
|
||
|
||
async def _parse_combined_expression(self, expression: str) -> Any:
|
||
"""
|
||
解析组合表达式,如 "a + b + c"
|
||
|
||
Args:
|
||
expression: 需要解析的表达式
|
||
|
||
Returns:
|
||
Any: 解析结果
|
||
"""
|
||
# 分割表达式,获取各部分,但需要处理引号内的加号
|
||
parts = self._split_expression_by_plus(expression)
|
||
|
||
result_values = []
|
||
# 处理每个部分
|
||
for part in parts:
|
||
part_value = None
|
||
|
||
# 检查是否是数据库表引用
|
||
if part.startswith(TaskInputParamVariables.VWED_) and "." in part:
|
||
part_value = await self._parse_db_reference(part)
|
||
# 检查是否是块输出引用b_reference(part)
|
||
# 检查是否是块输出引用
|
||
elif part.startswith(TaskInputParamVariables.BLOCKS):
|
||
part_value = self._parse_block_reference(part)
|
||
# 检查是否是任务输入参数引用
|
||
elif part.startswith(TaskInputParamVariables.TASK_INPUTS):
|
||
part_value = await self._parse_task_inputs_reference(part)
|
||
# 检查是否是字符串工具函数调用
|
||
elif part.startswith(TaskInputParamVariables.STRING_UTILS):
|
||
part_value = await self._parse_string_utils_expression(part)
|
||
else:
|
||
# 从上下文变量中获取
|
||
part_value = self.task_context.get_variable(part)
|
||
|
||
# 添加到结果列表
|
||
if part_value is not None:
|
||
result_values.append(part_value)
|
||
# 合并结果
|
||
if result_values:
|
||
# 检查结果类型并合并
|
||
if all(isinstance(v, (int, float)) for v in result_values):
|
||
# 数字类型,执行加法运算
|
||
result = sum(result_values)
|
||
logger.info(f"表达式 {expression} 计算结果(数字相加): {result}")
|
||
return result
|
||
else:
|
||
# 包含非数字类型,转为字符串并连接
|
||
result = "".join(str(v) for v in result_values)
|
||
logger.info(f"表达式 {expression} 计算结果(字符串拼接): {result}")
|
||
return result
|
||
else:
|
||
# 没有有效结果
|
||
logger.warning(f"表达式 {expression} 计算结果为空")
|
||
return None
|
||
|
||
def _parse_block_reference(self, reference: str) -> Any:
|
||
"""
|
||
解析块引用表达式,如 blocks.blockName.fieldName
|
||
|
||
Args:
|
||
reference: 块引用表达式
|
||
|
||
Returns:
|
||
Any: 引用的值
|
||
"""
|
||
_, block_name, field_name = reference.split(".")
|
||
block_output = self.task_context.get_block_output(block_name)
|
||
if block_output is None:
|
||
raise Exception(f"{reference} 获取块引用失败 表达式: {reference} 有误")
|
||
try:
|
||
return block_output[field_name]
|
||
except Exception as e:
|
||
raise Exception(f"{field_name} 变量不存在!")
|
||
|
||
async def _parse_db_reference(self, reference: str) -> Any:
|
||
"""
|
||
解析数据库引用表达式,如 vwed_taskdef.id
|
||
|
||
Args:
|
||
reference: 数据库引用表达式
|
||
|
||
Returns:
|
||
Any: 查询结果
|
||
"""
|
||
try:
|
||
# 提取表名和字段名
|
||
table_name, field_name = reference.split(".", 1)
|
||
|
||
# 从上下文中获取当前任务的相关ID
|
||
task_def_id = self.task_context.task_def_id
|
||
task_record_id = self.task_context.task_record_id
|
||
|
||
# 构建SQL查询
|
||
async with get_async_session() as session:
|
||
# 根据表名确定查询方式
|
||
if table_name == VWEDTaskRecord.__tablename__:
|
||
return await self._query_task_record(session, field_name, task_record_id)
|
||
elif table_name == VWEDTaskDef.__tablename__:
|
||
return await self._query_task_def(session, field_name, task_def_id)
|
||
else:
|
||
return await self._query_other_table(session, table_name, field_name, task_def_id, task_record_id)
|
||
except Exception as e:
|
||
# 查询失败时记录错误并返回None
|
||
logger.error(f"查询表达式 {reference} 失败: {str(e)}")
|
||
raise Exception(f"{field_name} 查询相关字段不存在")
|
||
|
||
async def _query_task_record(self, session: AsyncSession, field_name: str, task_record_id: str) -> Any:
|
||
"""
|
||
查询任务记录表
|
||
|
||
Args:
|
||
session: 数据库会话
|
||
field_name: 字段名
|
||
task_record_id: 任务记录ID
|
||
|
||
Returns:
|
||
Any: 查询结果
|
||
"""
|
||
# 解析字段名,检查是否包含查询条件
|
||
field_parts = field_name.split(":")
|
||
actual_field = field_parts[0].strip()
|
||
|
||
# 构建查询条件
|
||
conditions = []
|
||
query_params = {}
|
||
|
||
# 默认使用任务记录ID
|
||
conditions.append("id = :task_record_id")
|
||
query_params["task_record_id"] = task_record_id
|
||
|
||
# 如果有额外的条件(格式为 field_name:condition=value)
|
||
if len(field_parts) > 1:
|
||
for condition_part in field_parts[1:]:
|
||
if "=" in condition_part:
|
||
cond_name, cond_value = condition_part.split("=", 1)
|
||
cond_name = cond_name.strip()
|
||
cond_value = cond_value.strip()
|
||
|
||
# 添加条件
|
||
param_name = f"param_{len(query_params)}"
|
||
conditions.append(f"{cond_name} = :{param_name}")
|
||
query_params[param_name] = cond_value
|
||
|
||
# 构建完整SQL
|
||
query = f"SELECT {actual_field} FROM {VWEDTaskRecord.__tablename__} WHERE {' AND '.join(conditions)}"
|
||
# 执行查询
|
||
result = await session.execute(text(query), query_params)
|
||
|
||
# 获取查询结果
|
||
row = result.first()
|
||
if row and len(row) > 0:
|
||
# 获取字段值
|
||
db_value = str(row[0])
|
||
logger.info(f"从数据库 {VWEDTaskRecord.__tablename__}.{actual_field} 获取值: {db_value}")
|
||
return db_value
|
||
else:
|
||
# 如果没有找到记录,记录警告
|
||
logger.warning(f"在表 {VWEDTaskRecord.__tablename__} 中未找到符合条件的字段 {actual_field}")
|
||
return None
|
||
|
||
async def _query_task_def(self, session: AsyncSession, field_name: str, task_def_id: str) -> Any:
|
||
"""
|
||
查询任务定义表
|
||
|
||
Args:
|
||
session: 数据库会话
|
||
field_name: 字段名
|
||
task_def_id: 任务定义ID
|
||
|
||
Returns:
|
||
Any: 查询结果
|
||
"""
|
||
# 解析字段名,检查是否包含查询条件
|
||
field_parts = field_name.split(":")
|
||
actual_field = field_parts[0].strip()
|
||
|
||
# 构建查询条件
|
||
conditions = []
|
||
params = {}
|
||
|
||
# 默认使用任务定义ID
|
||
conditions.append("id = :def_id")
|
||
params["def_id"] = task_def_id
|
||
|
||
# 如果有额外的条件
|
||
if len(field_parts) > 1:
|
||
for condition_part in field_parts[1:]:
|
||
if "=" in condition_part:
|
||
cond_name, cond_value = condition_part.split("=", 1)
|
||
cond_name = cond_name.strip()
|
||
cond_value = cond_value.strip()
|
||
|
||
# 添加条件
|
||
param_name = f"param_{len(params)}"
|
||
conditions.append(f"{cond_name} = :{param_name}")
|
||
params[param_name] = cond_value
|
||
|
||
# 构建完整SQL
|
||
query = f"SELECT {actual_field} FROM {VWEDTaskDef.__tablename__} WHERE {' AND '.join(conditions)}"
|
||
# 执行查询
|
||
result = await session.execute(text(query), params)
|
||
row = result.first()
|
||
|
||
if row and len(row) > 0:
|
||
db_value = row[0]
|
||
logger.info(f"从数据库 {VWEDTaskDef.__tablename__}.{actual_field} 获取值: {db_value}")
|
||
return db_value
|
||
else:
|
||
logger.warning(f"在表 {VWEDTaskDef.__tablename__} 中未找到符合条件的字段 {actual_field}")
|
||
return None
|
||
|
||
async def _query_other_table(self, session: AsyncSession, table_name: str, field_name: str,
|
||
task_def_id: str, task_record_id: str) -> Any:
|
||
"""
|
||
查询其他表
|
||
|
||
Args:
|
||
session: 数据库会话
|
||
table_name: 表名
|
||
field_name: 字段名
|
||
task_def_id: 任务定义ID
|
||
task_record_id: 任务记录ID
|
||
|
||
Returns:
|
||
Any: 查询结果
|
||
"""
|
||
# 解析字段名,检查是否包含查询条件
|
||
field_parts = field_name.split(":")
|
||
actual_field = field_parts[0].strip()
|
||
|
||
# 构建查询条件
|
||
conditions = []
|
||
params = {}
|
||
|
||
# 如果有额外的条件(格式为 field_name:condition=value)
|
||
if len(field_parts) > 1:
|
||
for condition_part in field_parts[1:]:
|
||
if "=" in condition_part:
|
||
cond_name, cond_value = condition_part.split("=", 1)
|
||
cond_name = cond_name.strip()
|
||
cond_value = cond_value.strip()
|
||
|
||
# 添加条件
|
||
param_name = f"param_{len(params)}"
|
||
conditions.append(f"{cond_name} = :{param_name}")
|
||
params[param_name] = cond_value
|
||
|
||
# 默认关联条件
|
||
if task_record_id:
|
||
conditions.append("task_record_id = :record_id")
|
||
params["record_id"] = task_record_id
|
||
|
||
if task_def_id:
|
||
conditions.append("task_id = :def_id")
|
||
params["def_id"] = task_def_id
|
||
|
||
# 如果没有有效条件,尝试使用其他默认条件
|
||
if not conditions:
|
||
conditions.append("1=1 LIMIT 1") # 简单的兜底条件
|
||
|
||
# 完成查询语句 - 使用AND连接条件更符合预期
|
||
query = f"SELECT {actual_field} FROM {table_name} WHERE {' AND '.join(conditions)}"
|
||
|
||
# 执行查询
|
||
result = await session.execute(text(query), params)
|
||
row = result.first()
|
||
|
||
if row and len(row) > 0:
|
||
db_value = row[0]
|
||
logger.info(f"从数据库 {table_name}.{actual_field} 获取值: {db_value}")
|
||
return db_value
|
||
else:
|
||
logger.warning(f"在表 {table_name} 中未找到符合条件的字段 {actual_field}")
|
||
return None
|
||
|
||
def _parse_json_value(self, json_value: Any) -> Any:
|
||
"""
|
||
解析JSON类型的值,支持嵌套结构和表达式类型
|
||
|
||
Args:
|
||
json_value: JSON值
|
||
|
||
Returns:
|
||
Any: 解析后的值
|
||
"""
|
||
if json_value is None:
|
||
return None
|
||
|
||
# 如果是字符串类型,尝试解析成JSON
|
||
if isinstance(json_value, str):
|
||
try:
|
||
parsed_value = json.loads(json_value)
|
||
# 改为同步处理方法,避免返回协程对象
|
||
return parsed_value
|
||
except json.JSONDecodeError:
|
||
print(f"解析JSON失败: {json_value}")
|
||
return json_value
|
||
else:
|
||
# 已经是Python对象,处理嵌套结构xx
|
||
return json_value
|
||
|
||
|
||
async def _process_nested_json(self, data: Any) -> Any:
|
||
"""
|
||
异步处理嵌套的JSON数据,解析其中的表达式类型
|
||
|
||
Args:
|
||
data: 需要处理的数据
|
||
|
||
Returns:
|
||
Any: 处理后的数据
|
||
"""
|
||
# 处理列表
|
||
if isinstance(data, list):
|
||
result = []
|
||
for item in data:
|
||
# 递归处理列表中的每个元素
|
||
processed_item = await self._process_nested_json(item)
|
||
result.append(processed_item)
|
||
return result
|
||
|
||
# 处理字典
|
||
elif isinstance(data, dict):
|
||
# 检查是否是表达式类型的对象
|
||
if "type" in data and data.get("type") == TaskInputParamType.EXPRESSION:
|
||
# 解析表达式类型的值
|
||
expr_value = data.get("value0")
|
||
key_name = data.get("key0", "unknown_key") # 获取键名,用于日志
|
||
logger.info(f"在JSON中发现表达式类型值,键: {key_name}, 表达式: {expr_value}")
|
||
try:
|
||
# 解析表达式获取实际值
|
||
return await self._parse_expression(key_name, expr_value)
|
||
except Exception as e:
|
||
logger.error(f"解析表达式 {expr_value} 失败: {str(e)}")
|
||
return expr_value # 解析失败时返回原始表达式
|
||
|
||
# 普通字典,递归处理每个键值对
|
||
result = {}
|
||
for key, value in data.items():
|
||
processed_value = await self._process_nested_json(value)
|
||
result[key] = processed_value
|
||
return result
|
||
|
||
# 对于字符串,检查是否是标记的表达式
|
||
elif isinstance(data, str) and data.startswith("__EXPRESSION__") and data.endswith("__"):
|
||
# 提取表达式值
|
||
expr_value = data[14:-2] # 去掉前缀"__EXPRESSION__"和后缀"__"
|
||
try:
|
||
# 解析表达式获取实际值
|
||
return await self._parse_expression("extracted_expr", expr_value)
|
||
except Exception as e:
|
||
logger.error(f"解析提取的表达式 {expr_value} 失败: {str(e)}")
|
||
return expr_value
|
||
|
||
# 其他基本类型直接返回
|
||
return data
|
||
|
||
# def _get_possible_output_keys(self, block_name: str) -> List[str]:
|
||
# """
|
||
# 根据块名称获取可能的输出键
|
||
#
|
||
# Args:
|
||
# block_name: 块名称
|
||
#
|
||
# Returns:
|
||
# List[str]: 可能的输出键列表
|
||
# """
|
||
# # 块类型与可能的输出变量名映射
|
||
# output_keys_map = {
|
||
# "CreateUuidBp": ["createUuid", "uuid"],
|
||
# "CurrentTimeStampBp": ["currentTimeStamp"],
|
||
# "TimestampBp": ["timestamp"],
|
||
# "StringToJsonObjectBp": ["jsonObject"],
|
||
# "StringToJsonArrayBp": ["jsonArray"],
|
||
# "JdbcQueryBp": ["jdbcQueryResult"],
|
||
# "HttpGetBp": ["httpResponse", "response"],
|
||
# "HttpPostBp": ["httpResponse", "response"],
|
||
# "ScriptBp": ["scriptResult"],
|
||
# # 添加更多块类型和对应的输出变量名
|
||
# }
|
||
#
|
||
# # 从块名中提取类型
|
||
# for block_type, keys in output_keys_map.items():
|
||
# if block_type in block_name:
|
||
# return keys
|
||
#
|
||
# # 如果没有找到匹配的块类型,返回空列表
|
||
# return []
|
||
#
|
||
async def _parse_task_inputs_reference(self, reference: str) -> Any:
|
||
"""
|
||
解析任务输入参数引用表达式,如 taskInputs.paramName
|
||
|
||
Args:
|
||
reference: 任务输入参数引用表达式
|
||
|
||
Returns:
|
||
Any: 引用的值
|
||
"""
|
||
try:
|
||
# 分割表达式,获取参数名
|
||
parts = reference.split(".")
|
||
if len(parts) != 2:
|
||
logger.error(f"任务输入参数引用格式不正确: {reference},应为 'taskInputs.paramName'")
|
||
raise Exception(f"{reference} 任务输入参数引用格式不正确")
|
||
|
||
param_name = parts[1]
|
||
|
||
# 从数据库中查询任务记录的输入参数
|
||
task_record_id = self.task_context.task_record_id
|
||
if not task_record_id:
|
||
logger.error("无法获取任务记录ID")
|
||
raise Exception(f"{reference} 无法获取任务记录ID")
|
||
|
||
async with get_async_session() as session:
|
||
# 查询当前任务的blockrecord
|
||
from sqlalchemy import select
|
||
|
||
# 首先尝试查找根块的记录
|
||
query = select(VWEDTaskRecord).where(
|
||
VWEDTaskRecord.id == task_record_id,
|
||
)
|
||
result = await session.execute(query)
|
||
task_record = result.scalars().first()
|
||
# 获取input_params字段
|
||
input_params_json = task_record.input_params
|
||
if not input_params_json:
|
||
logger.error(f"任务记录 {task_record_id} 的块记录没有输入参数")
|
||
raise Exception(f"{reference} 无法获取任务记录ID")
|
||
|
||
try:
|
||
# 解析JSON字符串为Python对象
|
||
input_params = json.loads(input_params_json)
|
||
# 检查输入参数的格式
|
||
if not isinstance(input_params, list):
|
||
logger.error(f"任务输入参数格式不正确,应为列表: {input_params}")
|
||
raise Exception(f"{reference} 任务输入参数格式不正确,应为列表")
|
||
# 查找参数名匹配的参数项
|
||
for param in input_params:
|
||
if isinstance(param, dict) and param.get("name") == param_name:
|
||
# 获取参数值
|
||
param_value = param.get("defaultValue")
|
||
param_type = param.get("type")
|
||
from routes.model.task_edit_model import InputParamType
|
||
# 根据参数类型进行转换
|
||
if param_type == InputParamType.INTEGER:
|
||
try:
|
||
return int(param_value)
|
||
except (ValueError, TypeError):
|
||
return param_value
|
||
elif param_type == InputParamType.FLOAT:
|
||
try:
|
||
return float(param_value)
|
||
except (ValueError, TypeError):
|
||
return param_value
|
||
elif param_type == InputParamType.BOOLEAN:
|
||
if param_value.lower() in ["true", "1", "yes", "y"]:
|
||
return True
|
||
elif param_value.lower() in ["false", "0", "no", "n"]:
|
||
return False
|
||
else:
|
||
return param_value
|
||
else:
|
||
# 其他类型,直接返回值
|
||
return param_value
|
||
|
||
# 如果没有找到匹配的参数名
|
||
logger.warning(f"在任务输入参数中找不到参数: {param_name}")
|
||
return None
|
||
|
||
except json.JSONDecodeError as e:
|
||
logger.error(f"解析input_params JSON失败: {str(e)}")
|
||
return None
|
||
|
||
except Exception as e:
|
||
logger.error(f"获取任务输入参数 {reference} 失败: {str(e)}")
|
||
raise Exception(f"{reference} 获取任务输入参数失败")
|
||
|
||
async def _parse_string_utils_expression(self, expression_value: str) -> Any:
|
||
"""
|
||
解析StringUtils表达式,调用内置字符串函数
|
||
|
||
Args:
|
||
expression_value: StringUtils表达式,形如 StringUtils.isBlank("你好")
|
||
|
||
Returns:
|
||
Any: 函数执行结果
|
||
|
||
Raises:
|
||
ValueError: 如果表达式格式不正确或函数不存在
|
||
Exception: 函数执行过程中的任何错误
|
||
"""
|
||
try:
|
||
# 导入内置函数模块
|
||
from utils.built_in_functions import call_function
|
||
|
||
# 验证表达式格式
|
||
if not expression_value.startswith(TaskInputParamVariables.STRING_UTILS + "."):
|
||
raise ValueError(f"无效的StringUtils表达式: {expression_value}")
|
||
# 提取函数名和参数部分
|
||
function_pattern = rf"{TaskInputParamVariables.STRING_UTILS}\.(\w+)\((.*)\)$"
|
||
match = re.match(function_pattern, expression_value)
|
||
|
||
if not match:
|
||
raise ValueError(f"StringUtils表达式格式错误: {expression_value}")
|
||
|
||
function_name, params_str = match.groups()
|
||
|
||
# 构建函数ID (匹配BUILT_IN_FUNCTIONS中的id格式)
|
||
function_id = f"{function_name}()"
|
||
print(f"params_str: {params_str}=======================================")
|
||
# 解析参数列表
|
||
params = self._parse_params_string(params_str)
|
||
print(f"params: {params}=======================================")
|
||
# 处理每个参数,解析可能的嵌套表达式
|
||
processed_params = []
|
||
for param in params:
|
||
# 检查参数是否为字符串字面量(被引号包围)
|
||
if (param.startswith('"') and param.endswith('"')) or (param.startswith("'") and param.endswith("'")):
|
||
processed_params.append(param[1:-1]) # 去掉引号
|
||
else:
|
||
# 递归解析可能的嵌套表达式
|
||
processed_params.append(await self._parse_expression("", param))
|
||
print(f"processed_params: {processed_params}=======================================")
|
||
# 调用内置函数并返回结果
|
||
return await call_function(function_id, *processed_params)
|
||
|
||
except Exception as e:
|
||
logger.error(f"执行StringUtils表达式失败: {expression_value}, 错误: {str(e)}")
|
||
raise Exception(f"{expression_value} 执行StringUtils表达式失败 错误: {str(e)}")
|
||
|
||
def _parse_params_string(self, params_str: str) -> List[str]:
|
||
"""
|
||
解析函数参数字符串,处理嵌套括号和引号的情况
|
||
|
||
Args:
|
||
params_str: 参数字符串,例如: '"hello"' 或 'blocks.b1.uuid, "world"'
|
||
|
||
Returns:
|
||
List[str]: 解析后的参数列表
|
||
"""
|
||
if not params_str.strip():
|
||
return []
|
||
|
||
# params = []
|
||
params = params_str.split(",")
|
||
# current_param = ""
|
||
# bracket_depth = 0
|
||
# quote_char = None
|
||
# for index, char in enumerate(params_str):
|
||
# if char == ',' and bracket_depth == 0 and quote_char is None:
|
||
# # 遇到顶层逗号,完成当前参数
|
||
# params.append(current_param.strip())
|
||
# current_param = ""
|
||
# if index == 0 and char in ['“', "”"]:
|
||
# raise Exception(f"表达式 {params_str} 格式不规范")
|
||
|
||
# elif char in ['"', "'"]:
|
||
# if quote_char is None:
|
||
# quote_char = char
|
||
# elif char == quote_char:
|
||
# quote_char = None
|
||
|
||
# # 处理括号
|
||
# if quote_char is None: # 只在非引号内计算括号深度
|
||
# if char == '(':
|
||
# bracket_depth += 1
|
||
# elif char == ')':
|
||
# bracket_depth -= 1
|
||
# current_param += char
|
||
|
||
# # 添加最后一个参数
|
||
# if current_param.strip():
|
||
# params.append(current_param.strip())
|
||
|
||
return params |