You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.0 KiB

using AuroraDesk.Core.Entities;
using AuroraDesk.Core.Interfaces;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
namespace AuroraDesk.Infrastructure.Services;
/// <summary>
/// 节点画布服务实现
/// </summary>
public class NodeCanvasService : INodeCanvasService
{
private readonly ILogger<NodeCanvasService>? _logger;
private readonly ObservableCollection<Node> _nodes = new();
private readonly ObservableCollection<Connection> _connections = new();
public ObservableCollection<Node> Nodes => _nodes;
public ObservableCollection<Connection> Connections => _connections;
public NodeCanvasService(ILogger<NodeCanvasService>? logger = null)
{
_logger = logger;
}
public void AddNode(Node node)
{
if (node == null)
throw new ArgumentNullException(nameof(node));
if (!_nodes.Contains(node))
{
_nodes.Add(node);
_logger?.LogDebug("添加节点: {NodeId}, Title: {Title}", node.Id, node.Title);
}
}
public void RemoveNode(Node node)
{
if (node == null) return;
// 移除与节点相关的所有连接
var connectionsToRemove = _connections
.Where(c => c.SourcePoint?.Node == node || c.TargetPoint?.Node == node)
.ToList();
foreach (var connection in connectionsToRemove)
{
RemoveConnection(connection);
}
_nodes.Remove(node);
_logger?.LogDebug("移除节点: {NodeId}, Title: {Title}", node.Id, node.Title);
}
public void UpdateNodePosition(Node node, double x, double y)
{
if (node == null) return;
node.X = x;
node.Y = y;
_logger?.LogTrace("更新节点位置: {NodeId}, X: {X}, Y: {Y}", node.Id, x, y);
}
public bool CreateConnection(ConnectionPoint sourcePoint, ConnectionPoint targetPoint)
{
if (sourcePoint == null || targetPoint == null)
return false;
// 验证连接点类型
if (sourcePoint.Type != ConnectionPointType.Output ||
targetPoint.Type != ConnectionPointType.Input)
{
_logger?.LogWarning("连接点类型不匹配: Source={SourceType}, Target={TargetType}",
sourcePoint.Type, targetPoint.Type);
return false;
}
// 不能连接到同一个节点
if (sourcePoint.Node == targetPoint.Node)
{
_logger?.LogWarning("不能连接到同一个节点");
return false;
}
// 检查是否已经存在相同的连接
var existingConnection = _connections.FirstOrDefault(c =>
c.SourcePoint == sourcePoint && c.TargetPoint == targetPoint);
if (existingConnection != null)
{
_logger?.LogWarning("连接已存在");
return false;
}
// 检查目标连接点是否已经被连接(可以支持一对多,这里先实现一对一)
var targetAlreadyConnected = _connections.Any(c => c.TargetPoint == targetPoint);
if (targetAlreadyConnected)
{
_logger?.LogWarning("目标连接点已被连接");
return false;
}
var connection = new Connection
{
SourcePoint = sourcePoint,
TargetPoint = targetPoint
};
if (connection.IsValid())
{
_connections.Add(connection);
sourcePoint.IsConnected = true;
targetPoint.IsConnected = true;
_logger?.LogDebug("创建连接: {ConnectionId}, Source={SourceId}, Target={TargetId}",
connection.Id, sourcePoint.Id, targetPoint.Id);
return true;
}
_logger?.LogWarning("连接验证失败");
return false;
}
public void RemoveConnection(Connection connection)
{
if (connection == null) return;
if (_connections.Remove(connection))
{
if (connection.SourcePoint != null)
connection.SourcePoint.IsConnected = false;
if (connection.TargetPoint != null)
connection.TargetPoint.IsConnected = false;
_logger?.LogDebug("移除连接: {ConnectionId}", connection.Id);
}
}
public IEnumerable<Connection> GetNodeConnections(Node node)
{
if (node == null)
return Enumerable.Empty<Connection>();
return _connections.Where(c =>
c.SourcePoint?.Node == node || c.TargetPoint?.Node == node);
}
public void Clear()
{
1 month ago
// 先重置所有连接点的状态
foreach (var connection in _connections.ToList())
{
if (connection.SourcePoint != null)
connection.SourcePoint.IsConnected = false;
if (connection.TargetPoint != null)
connection.TargetPoint.IsConnected = false;
}
_connections.Clear();
_nodes.Clear();
_logger?.LogDebug("清空画布");
}
}