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] /// /// 流程图模型 - 管理节点和连线的集合 /// public class FlowGraph : TeamAAS.BindableBase { /// /// 本流程绑定的执行结果注册表(主页面运行流程 = ResultRegistry.Main,编辑/调试流程 = ResultRegistry.Debug)。 /// 运行态/编辑态各自独立,互不干扰;监控模式挂接运行态流程时自动指向主面对象。 /// [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 Nodes { get; set; } = new ObservableCollection(); public ObservableCollection Connections { get; set; } = new ObservableCollection(); /// /// 添加节点 /// public void AddNode(FlowNode node) { Nodes.Add(node); } /// /// 删除节点及其关联连线 /// public void RemoveNode(string nodeId) { // 删除关联连线 var connectionsToRemove = new List(); 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; } } } /// /// 检查连线是否合法(不自连、非End下游、不重复、不成环)— 只检查不添加 /// 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; } /// /// 添加连线(自动检查重复和环) /// public bool TryAddConnection(FlowConnection connection) { if (!CanConnect(connection)) return false; Connections.Add(connection); return true; } /// /// 删除连线 /// public void RemoveConnection(string connectionId) { for (int i = Connections.Count - 1; i >= 0; i--) { if (Connections[i].ConnectionId == connectionId) { Connections.RemoveAt(i); break; } } } /// /// 检查添加连线后是否形成环 /// private bool WouldCreateCycle(string sourceId, string targetId) { // 如果 target 能到达 source,则形成环 return CanReach(targetId, sourceId, new HashSet()); } private bool CanReach(string fromId, string toId, HashSet 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; } /// /// 获取节点 /// public FlowNode GetNode(string nodeId) { foreach (var node in Nodes) { if (node.NodeId == nodeId) return node; } return null; } } }