| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Runtime.Serialization;
- using System.Xml.Linq;
- using TeamAAS.FlowEditor.Execution;
- using TeamAAS.FlowEditor.Plugins;
- namespace TeamAAS.FlowEditor.Models
- {
- [Serializable]
- /// <summary>
- /// 流程图模型 - 管理节点和连线的集合
- /// </summary>
- public class FlowGraph : TeamAAS.BindableBase
- {
- /// <summary>
- /// 本流程绑定的执行结果注册表(主页面运行流程 = ResultRegistry.Main,编辑/调试流程 = ResultRegistry.Debug)。
- /// 运行态/编辑态各自独立,互不干扰;监控模式挂接运行态流程时自动指向主面对象。
- /// </summary>
- [Newtonsoft.Json.JsonIgnore]
- [field: NonSerialized]
- public ResultRegistry Registry { get; set; } = ResultRegistry.Debug;
- public string GraphId { get; set; } = System.Guid.NewGuid().ToString("N");
- public string GraphName
- {
- get => _graphName;
- set => SetProperty(ref _graphName, value);
- }
- private string _graphName = "新流程";
- public ObservableCollection<FlowNode> Nodes { get; set; } = new ObservableCollection<FlowNode>();
- public ObservableCollection<FlowConnection> Connections { get; set; } = new ObservableCollection<FlowConnection>();
- /// <summary>
- /// 添加节点
- /// </summary>
- public void AddNode(FlowNode node)
- {
- Nodes.Add(node);
- }
- /// <summary>
- /// 删除节点及其关联连线
- /// </summary>
- public void RemoveNode(string nodeId)
- {
- // 删除关联连线
- var connectionsToRemove = new List<FlowConnection>();
- foreach (var conn in Connections)
- {
- if (conn.SourceNodeId == nodeId || conn.TargetNodeId == nodeId)
- connectionsToRemove.Add(conn);
- }
- foreach (var conn in connectionsToRemove)
- Connections.Remove(conn);
- // 删除节点 + 清理 ResultRegistry 中的执行结果
- for (int i = Nodes.Count - 1; i >= 0; i--)
- {
- if (Nodes[i].NodeId == nodeId)
- {
- Registry?.RemoveNodeResult(GraphId, Nodes[i].NodeName);
- Nodes.RemoveAt(i);
- break;
- }
- }
- }
- /// <summary>
- /// 检查连线是否合法(不自连、非End下游、不重复、不成环)— 只检查不添加
- /// </summary>
- public bool CanConnect(FlowConnection connection)
- {
- // 不允许自连接
- if (connection.SourceNodeId == connection.TargetNodeId)
- return false;
- // 结束节点不允许添加下游连线
- var sourceNode = GetNode(connection.SourceNodeId);
- if (sourceNode != null && sourceNode.Category == NodeCategory.End)
- return false;
- // 检查重复 — 同一对节点之间不允许连线(双向检查,防止反向连接)
- foreach (var conn in Connections)
- {
- if ((conn.SourceNodeId == connection.SourceNodeId && conn.TargetNodeId == connection.TargetNodeId) ||
- (conn.SourceNodeId == connection.TargetNodeId && conn.TargetNodeId == connection.SourceNodeId))
- return false;
- }
- // 检查是否形成环(多级链路:A→B→C 后不允许 C→A)
- if (WouldCreateCycle(connection.SourceNodeId, connection.TargetNodeId))
- return false;
- return true;
- }
- /// <summary>
- /// 添加连线(自动检查重复和环)
- /// </summary>
- public bool TryAddConnection(FlowConnection connection)
- {
- if (!CanConnect(connection))
- return false;
- Connections.Add(connection);
- return true;
- }
- /// <summary>
- /// 删除连线
- /// </summary>
- public void RemoveConnection(string connectionId)
- {
- for (int i = Connections.Count - 1; i >= 0; i--)
- {
- if (Connections[i].ConnectionId == connectionId)
- {
- Connections.RemoveAt(i);
- break;
- }
- }
- }
- /// <summary>
- /// 检查添加连线后是否形成环
- /// </summary>
- private bool WouldCreateCycle(string sourceId, string targetId)
- {
- // 如果 target 能到达 source,则形成环
- return CanReach(targetId, sourceId, new HashSet<string>());
- }
- private bool CanReach(string fromId, string toId, HashSet<string> visited)
- {
- if (fromId == toId) return true;
- if (visited.Contains(fromId)) return false;
- visited.Add(fromId);
- foreach (var conn in Connections)
- {
- if (conn.SourceNodeId == fromId)
- {
- if (CanReach(conn.TargetNodeId, toId, visited))
- return true;
- }
- }
- return false;
- }
- /// <summary>
- /// 获取节点
- /// </summary>
- public FlowNode GetNode(string nodeId)
- {
- foreach (var node in Nodes)
- {
- if (node.NodeId == nodeId) return node;
- }
- return null;
- }
- }
- }
|