using Serein.Library; using Serein.Library.Api; using Serein.Library.Utils; using Serein.Library.Utils.SereinExpression; using System; using System.ComponentModel; using System.Dynamic; using System.Linq.Expressions; namespace Serein.NodeFlow.Model { /// /// 条件节点(用于条件控件) /// [NodeProperty(ValuePath = NodeValuePath.Node)] public partial class SingleConditionNode : NodeModelBase { /// /// 是否为自定义参数 /// [PropertyInfo(IsNotification = true)] private bool _isExplicitData; /// /// 自定义参数值 /// [PropertyInfo(IsNotification = true)] private string? _explicitData; /// /// 条件表达式 /// [PropertyInfo(IsNotification = true)] private string _expression; } public partial class SingleConditionNode : NodeModelBase { /// /// 条件表达式节点是基础节点 /// public override bool IsBase => true; /// /// 表达式参数索引 /// private const int INDEX_EXPRESSION = 0; public SingleConditionNode(IFlowEnvironment environment):base(environment) { this.IsExplicitData = false; this.ExplicitData = string.Empty; this.Expression = "PASS"; } public override void OnCreating() { // 这里的这个参数是为了方便使用入参控制点,参数无意义 var pd = new ParameterDetails[1]; pd[INDEX_EXPRESSION] = new ParameterDetails { Index = INDEX_EXPRESSION, Name = nameof(Expression), IsExplicitData = false, DataValue = string.Empty, DataType = typeof(string), ExplicitType = typeof(string), ArgDataSourceNodeGuid = string.Empty, ArgDataSourceType = ConnectionArgSourceType.GetPreviousNodeData, NodeModel = this, //Convertor = null, InputType = ParameterValueInputType.Input, Items = null, Description = "条件节点入参控制点" }; this.MethodDetails.ParameterDetailss = [..pd]; } /// /// 导出方法信息 /// /// /// public override NodeInfo SaveCustomData(NodeInfo nodeInfo) { dynamic data = new ExpandoObject(); data.Expression = Expression ?? ""; data.ExplicitData = ExplicitData ?? ""; data.IsExplicitData = IsExplicitData; nodeInfo.CustomData = data; return nodeInfo; } /// /// 加载自定义数据 /// /// public override void LoadCustomData(NodeInfo nodeInfo) { this.Expression = nodeInfo.CustomData?.Expression ?? ""; this.ExplicitData = nodeInfo.CustomData?.ExplicitData ?? ""; this.IsExplicitData = nodeInfo.CustomData?.IsExplicitData ?? false; } /// /// 重写节点的方法执行 /// /// /// public override async Task ExecutingAsync(IDynamicContext context, CancellationToken token) { if (token.IsCancellationRequested) { return new FlowResult(this.Guid, context); } // 接收上一节点参数or自定义参数内容 object? parameter; object? result = null; if (!IsExplicitData) { // 使用自动取参 var pd = MethodDetails.ParameterDetailss[INDEX_EXPRESSION]; var hasNode = context.Env.TryGetNodeModel(pd.ArgDataSourceNodeGuid, out var argSourceNode); if (hasNode) { context.NextOrientation = ConnectionInvokeType.IsError; return new FlowResult(this.Guid, context); } if (hasNode) { return new FlowResult(this.Guid, context); } if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeData) { result = context.GetFlowData(argSourceNode.Guid).Value; // 使用自定义节点的参数 } else if (pd.ArgDataSourceType == ConnectionArgSourceType.GetOtherNodeDataOfInvoke) { CancellationTokenSource cts = new CancellationTokenSource(); var nodeResult = await argSourceNode.ExecutingAsync(context, cts.Token); result = nodeResult.Value; cts?.Cancel(); cts?.Dispose(); } else { result = context.TransmissionData(this.Guid).Value; // 条件节点透传上一节点的数据 } parameter = result; // 使用上一节点的参数 } else { var exp = ExplicitData?.ToString(); if (!string.IsNullOrEmpty(exp) && exp.StartsWith('@')) { parameter = result; // 表达式获取上一节点数据 if (parameter is not null) { parameter = SerinExpressionEvaluator.Evaluate(exp, parameter, out _); } } else { parameter = ExplicitData; // 使用自定义的参数 } } bool judgmentResult = false; try { judgmentResult = SereinConditionParser.To(parameter, Expression); context.NextOrientation = judgmentResult ? ConnectionInvokeType.IsSucceed : ConnectionInvokeType.IsFail; } catch (Exception ex) { context.NextOrientation = ConnectionInvokeType.IsError; context.ExceptionOfRuning = ex; } SereinEnv.WriteLine(InfoType.INFO, $"{result} {Expression} -> " + context.NextOrientation); //return result; return new FlowResult(this.Guid, context, judgmentResult); } } }