235 lines
8.8 KiB
C#
235 lines
8.8 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.Services;
|
|
using Plugin.Cowain.Wcs.ViewModels.ProcessGraph;
|
|
using System;
|
|
using System.Collections.ObjectModel;
|
|
using System.Diagnostics;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Input;
|
|
|
|
namespace Plugin.Cowain.Wcs.ViewModels;
|
|
|
|
public partial class ProcessEdit6180DialogViewModel : ObservableObject, IDialogContext
|
|
{
|
|
private class FlowDataDto
|
|
{
|
|
public List<StationNode6180ViewModel> Nodes { get; set; } = new();
|
|
public List<Connection6180ViewModel> Connections { get; set; } = new();
|
|
}
|
|
|
|
|
|
public NodifyObservableCollection<StationNode6180ViewModel> Nodes { get; } = new NodifyObservableCollection<StationNode6180ViewModel>();
|
|
public NodifyObservableCollection<Connection6180ViewModel> Connections { get; } = new();
|
|
|
|
public PendingConnection6180ViewModel PendingConnection { get; }
|
|
|
|
public event EventHandler<object?>? RequestClose;
|
|
[ObservableProperty]
|
|
private StationNode6180ViewModel? _selectedNode;
|
|
|
|
[ObservableProperty]
|
|
private ObservableCollection<StationNode6180ViewModel> _selectedNodes = new ObservableCollection<StationNode6180ViewModel>();
|
|
|
|
|
|
[ObservableProperty]
|
|
private Connection6180ViewModel? _selectedConnection;
|
|
|
|
|
|
|
|
[ObservableProperty]
|
|
private ObservableCollection<Connection6180ViewModel> _selectedConnections = new ObservableCollection<Connection6180ViewModel>();
|
|
|
|
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>() { RgvCommand6180Enum.MoveFrom.ToString(), RgvCommand6180Enum.Pick.ToString(), RgvCommand6180Enum.MoveTo.ToString(), RgvCommand6180Enum.Place.ToString() };
|
|
|
|
|
|
private IProcessFlow6180Service _processFlowService;
|
|
public ProcessEdit6180DialogViewModel(List<StationViewModel>? stations, ProcessViewModel? process, IProcessFlow6180Service processFlowService)
|
|
{
|
|
Stations = stations;
|
|
_process = process;
|
|
_processFlowService = processFlowService;
|
|
PendingConnection = new PendingConnection6180ViewModel(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(StationNode6180ViewModel 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 Connection6180ViewModel(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 Connection6180ViewModel(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 StationNode6180ViewModel { 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);
|
|
}
|
|
|
|
}
|