Files
2026-06-08 18:14:59 +08:00

156 lines
6.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
开始节点
"""
import logging
from typing import Any, Dict, List
from ..base import BaseNode, NodeContext, NodeResult
from ..registry import NodeRegistry
logger = logging.getLogger(__name__)
@NodeRegistry.register
class StartNode(BaseNode):
"""
开始节点
工作流的入口节点,接收用户输入
"""
node_type = 'start'
node_name = '开始'
node_category = 'basic'
node_icon = 'play-circle'
node_description = '工作流的开始节点,接收用户输入'
inputs = []
outputs = [
{
'name': 'user_input',
'type': 'string',
'description': '用户输入',
},
{
'name': 'application_id',
'type': 'string',
'description': '子应用ID(在子应用模式下自动注入)',
},
{
'name': 'application_code',
'type': 'string',
'description': '子应用编码(在子应用模式下自动注入)',
},
{
'name': 'form_code',
'type': 'string',
'description': '表单编码(从表单列表调用时自动注入)',
},
]
def execute(self, context: NodeContext) -> NodeResult:
"""执行开始节点"""
output_variables = {}
# 调试日志
logger.info(f"StartNode execute - context.variables: {list(context.variables.keys())}")
logger.info(f"StartNode execute - application_id in variables: {'application_id' in context.variables}")
if 'application_id' in context.variables:
logger.info(f"StartNode execute - application_id value: {context.variables['application_id']}")
# 首先将 user_input 作为开始节点的输出变量
# 这样下游节点可以通过 {{start-xxx.user_input}} 引用
if context.user_input:
output_variables['user_input'] = context.user_input
elif 'user_input' in context.variables:
output_variables['user_input'] = context.variables['user_input']
# 将 application_id 作为开始节点的输出变量
# 这样下游节点可以通过 {{start-xxx.application_id}} 引用
# 主应用模式下为空字符串,子应用模式下为实际的应用ID
output_variables['application_id'] = context.variables.get('application_id', 'main')
# 将 application_code 作为开始节点的输出变量
# 这样下游节点可以通过 {{start-xxx.application_code}} 引用
# 主应用模式下为空字符串,子应用模式下为实际的应用编码
output_variables['application_code'] = context.variables.get('application_code', '')
# 将 form_code 作为开始节点的输出变量
# 这样下游节点可以通过 {{start-xxx.form_code}} 引用
# 从表单列表调用时会自动注入,否则为空字符串
output_variables['form_code'] = context.variables.get('form_code', '')
logger.info(f"StartNode execute - output_variables: {output_variables}")
# 处理前端定义的变量(variables 数组)
# 格式: [{ variable: 'name', type: 'string', label: '名称', required: true, default_value: '' }]
variables = self.config.get('variables', [])
for var in variables:
var_name = var.get('variable', '')
if not var_name:
continue
default_value = var.get('default_value', '')
var_type = var.get('type', 'string')
# 如果 context 中已有该变量(从 inputs 传入),使用传入的值
# 否则使用默认值
if var_name in context.variables and context.variables[var_name]:
value = context.variables[var_name]
else:
value = default_value
# 类型转换
if var_type == 'number' and value:
try:
value = float(value) if '.' in str(value) else int(value)
except (ValueError, TypeError):
pass
elif var_type == 'boolean':
if isinstance(value, str):
value = value.lower() in ('true', '1', 'yes')
context.set_variable(var_name, value)
output_variables[var_name] = value
# 处理自定义输入变量(兼容旧格式 input_variables
input_variables = self.config.get('input_variables', [])
for var in input_variables:
var_name = var.get('name', '')
var_value = var.get('default', '')
if var_name:
# 如果 context 中没有该变量,使用默认值
if var_name not in context.variables or not context.variables[var_name]:
context.set_variable(var_name, var_value)
output_variables[var_name] = context.get_variable(var_name)
return NodeResult(
success=True,
output=output_variables,
output_variables=output_variables,
)
@classmethod
def get_config_schema(cls) -> Dict[str, Any]:
"""获取配置 Schema"""
return {
'type': 'object',
'properties': {
'input_variables': {
'type': 'array',
'title': '输入变量',
'items': {
'type': 'object',
'properties': {
'name': {'type': 'string', 'title': '变量名'},
'type': {'type': 'string', 'title': '类型', 'enum': ['string', 'number', 'boolean']},
'description': {'type': 'string', 'title': '描述'},
'default': {'type': 'string', 'title': '默认值'},
'required': {'type': 'boolean', 'title': '是否必填'},
},
},
},
},
}