Files
WCS/Plugins/Wcs/Plugin.Cowain.Wcs/ViewModels/ProcessEditDialogViewModel.cs
2026-03-02 10:56:30 +08:00

232 lines
8.6 KiB
C#

using Avalonia;
using Avalonia.Threading;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Cowain.Base.Helpers;
using Irihi.Avalonia.Shared.Contracts;
using Newtonsoft.Json;
using Plugin.Cowain.Wcs.IServices;
using Plugin.Cowain.Wcs.Models.Enum;
using Plugin.Cowain.Wcs.ViewModels.ProcessGraph;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Input;
namespace Plugin.Cowain.Wcs.ViewModels;
public partial class ProcessEditDialogViewModel : ObservableObject, IDialogContext
{
private class FlowDataDto
{
public List<StationNodeViewModel> Nodes { get; set; } = new();
public List<ConnectionViewModel> Connections { get; set; } = new();
}
public NodifyObservableCollection<StationNodeViewModel> Nodes { get; } = new NodifyObservableCollection<StationNodeViewModel>();
public NodifyObservableCollection<ConnectionViewModel> Connections { get; } = new();
public PendingConnectionViewModel PendingConnection { get; }
public event EventHandler<object?>? RequestClose;
[ObservableProperty]
private StationNodeViewModel? _selectedNode;
[ObservableProperty]
private ObservableCollection<StationNodeViewModel> _selectedNodes = new ObservableCollection<StationNodeViewModel>();
[ObservableProperty]
private ConnectionViewModel? _selectedConnection;
[ObservableProperty]
private ObservableCollection<ConnectionViewModel> _selectedConnections = new ObservableCollection<ConnectionViewModel>();
public List<StationViewModel>? Stations { get; }
private ProcessViewModel? _process;
public ICommand DeleteSelectionCommand { get; }
public static List<string> ActionList =>
Enum.GetNames(typeof(RgvCommandEnum)).ToList(); // 直接获取枚举名称字符串列表
public static List<string> StationStateList =>
Enum.GetNames(typeof(StationStateEnum)).ToList(); // 直接获取枚举名称字符串列表
private List<string> actions = new List<string>() { RgvCommandEnum.MoveFrom.ToString(), RgvCommandEnum.Pick.ToString(), RgvCommandEnum.MoveTo.ToString(), RgvCommandEnum.Place.ToString() };
private IProcessFlowService _processFlowService;
public ProcessEditDialogViewModel(List<StationViewModel>? stations, ProcessViewModel? process, IProcessFlowService processFlowService)
{
Stations = stations;
_process = process;
_processFlowService = processFlowService;
PendingConnection = new PendingConnectionViewModel(this);
DeleteSelectionCommand = new RelayCommand(DeleteSelection, () => SelectedNodes.Count > 0 || SelectedConnections.Count > 0);
GlobalData.Instance.AddOrUpdate("Stations", Stations);
Nodes.WhenRemoved(x => DisconnectStation(x))
.WhenCleared(x =>
{
Connections.Clear();
});
DispatcherTimer.RunOnce((async () =>
{
await InitFlowDataAsync();
}), TimeSpan.FromSeconds(0), DispatcherPriority.Default);
}
/// <summary>
/// 删除工站同时,删除与之相关的连接
/// </summary>
/// <param name="state"></param>
public void DisconnectStation(StationNodeViewModel state)
{
var transitions = Connections.Where(t => t.Source.NodeId == state.Id || t.Target.NodeId == state.Id).ToList();
transitions.ForEach(t => Connections.Remove(t));
}
public void Connect(ConnectorViewModel source, ConnectorViewModel target)
{
var conn = new ConnectionViewModel(source, target);
Connections.Add(conn);
}
private async Task InitFlowDataAsync()
{
if (_process == null || string.IsNullOrWhiteSpace(_process.FlowData))
return;
try
{
var flow = JsonConvert.DeserializeObject<FlowDataDto>(_process.FlowData);
if (flow != null)
{
Nodes.Clear();
foreach (var node in flow.Nodes)
{
Nodes.Add(node);
}
var flows = await _processFlowService.GetAllAsync();
var existingFlows = flows.Where(f => f.ProcessId == _process.Id);
Connections.Clear();
foreach (var conn in flow.Connections)
{
// 根据 Source 和 Target 的 StationId 找到 Nodes 中对应的 ConnectorViewModel
var sourceNode = Nodes.FirstOrDefault(n => n.Id == conn.Source.NodeId);
var targetNode = Nodes.FirstOrDefault(n => n.Id == conn.Target.NodeId);
if (sourceNode != null && targetNode != null)
{
// 这里假设连接都是 Output -> Input
var newConn = new ConnectionViewModel(sourceNode.Output, targetNode.Input);
newConn.ProcessFlow = conn.ProcessFlow;
var existFlow = existingFlows.FirstOrDefault(f =>
f.FromStationId1 == newConn.ProcessFlow.FromStationId1 &&
f.ToStationId1 == newConn.ProcessFlow.ToStationId1 &&
f.FromStationId2 == newConn.ProcessFlow.FromStationId2 &&
f.ToStationId2 == newConn.ProcessFlow.ToStationId2);
if (existFlow != null)
{
// 更新已有流程
newConn.ProcessFlow.Id = existFlow.Id;
newConn.ProcessFlow.FromStatus1 = existFlow.FromStatus1;
newConn.ProcessFlow.ToStatus1 = existFlow.ToStatus1;
newConn.ProcessFlow.FromStatus2 = existFlow.FromStatus2;
newConn.ProcessFlow.ToStatus2 = existFlow.ToStatus2;
newConn.ProcessFlow.Priority = existFlow.Priority;
}
Connections.Add(newConn);
}
}
}
}
catch (Exception ex)
{
// 可根据需要添加日志或通知
Debug.WriteLine($"InitFlowData 反序列化失败: {ex.Message}");
}
}
private void DeleteSelection()
{
foreach (var connection in SelectedConnections.ToList())
{
connection.Source.IsConnected = false;
connection.Target.IsConnected = false;
Connections.Remove(connection);
}
var selected = SelectedNodes.ToList();
for (int i = 0; i < selected.Count; i++)
{
Nodes.Remove(selected[i]);
}
}
[RelayCommand]
private void AddStation(Point point)
{
Nodes.Add(new StationNodeViewModel { Location = point });
}
public void Close()
{
RequestClose?.Invoke(this, false);
}
[RelayCommand]
private void Ok()
{
if (_process != null)
{
foreach (var conn in Connections)
{
// 设置工艺流转的起止工站ID
if (conn.ProcessFlow != null)
{
conn.ProcessFlow.FromStationId1 = conn.Source.NodeId == Guid.Empty ? 0 : Nodes.FirstOrDefault(n => n.Id == conn.Source.NodeId)?.Station1Id ?? 0;
conn.ProcessFlow.ToStationId1 = conn.Target.NodeId == Guid.Empty ? 0 : Nodes.FirstOrDefault(n => n.Id == conn.Target.NodeId)?.Station1Id ?? 0;
conn.ProcessFlow.FromStationId2 = conn.Source.NodeId == Guid.Empty ? 0 : Nodes.FirstOrDefault(n => n.Id == conn.Source.NodeId)?.Station2Id ?? 0;
conn.ProcessFlow.ToStationId2 = conn.Target.NodeId == Guid.Empty ? 0 : Nodes.FirstOrDefault(n => n.Id == conn.Target.NodeId)?.Station2Id ?? 0;
if (conn.ProcessFlow.FromStationId2 == 0)
{
conn.ProcessFlow.FromStatus2 = StationStateEnum.UnKnown.ToString();
}
if (conn.ProcessFlow.ToStationId2 == 0)
{
conn.ProcessFlow.ToStatus2 = StationStateEnum.UnKnown.ToString();
}
conn.ProcessFlow.Action = JsonConvert.SerializeObject(actions);
conn.ProcessFlow.ProcessId = _process.Id;
}
}
var flow = new FlowDataDto
{
Nodes = Nodes.ToList(),
Connections = Connections.ToList()
};
_process.FlowData = JsonConvert.SerializeObject(flow);
}
RequestClose?.Invoke(this, true);
}
[RelayCommand]
private void Cancel()
{
RequestClose?.Invoke(this, false);
}
}