using Avalonia.Threading; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Cowain.Base.ViewModels; using Ke.Bee.Localization.Localizer.Abstractions; using Microsoft.Extensions.DependencyInjection; using Plugin.Cowain.Wcs.IServices; using System.Collections.ObjectModel; namespace Plugin.Cowain.Wcs.ViewModels; public partial class WcsRealStation6180ViewModel : PageViewModelBase { [ObservableProperty] private double _cellWidthSize = 130; [ObservableProperty] private double _cellHeightSize = 60; [ObservableProperty] private ObservableCollection? _stations; [ObservableProperty] private ObservableCollection _taskList = new(); [ObservableProperty] private ObservableCollection? _layoutList; [ObservableProperty] private int _height = 400; [ObservableProperty] private int _width = 1000; private readonly ILocalizer _l; private IServiceScopeFactory _scopeFactory; private bool _isProcessing; public WcsRealStation6180ViewModel(ILocalizer localizer, IServiceScopeFactory scopeFactory) { _l = localizer; _scopeFactory = scopeFactory; RefreshCommand.ExecuteAsync(1); DispatcherTimer.Run(new Func(() => { RefreshCommand.ExecuteAsync(1); return true; }), TimeSpan.FromSeconds(1), DispatcherPriority.Default); } [RelayCommand] private async Task RefreshAsync(int pageIndex) { if (_isProcessing) return; _isProcessing = true; try { using var scope = _scopeFactory.CreateScope(); var stationService = scope.ServiceProvider.GetRequiredService(); if (Stations == null) { var stationList = await stationService.GetAllAsync(); Stations = new ObservableCollection(stationList); } var taskService = scope.ServiceProvider.GetRequiredService(); var taskList = await taskService.GetAllAsync(); TaskList.Clear(); foreach (var item in taskList.OrderByDescending(x => x.Id).Take(1)) { item.Actions = new(taskService.ActionToList(item.Action) ?? new List()); item.SelectedAction = item.Actions.FirstOrDefault(x => x.Id == item.ExecuteAction); TaskList?.Add(item); } var rgvService = scope.ServiceProvider.GetRequiredService(); var rgvs = await rgvService.GetAllAsync(); var stations = await stationService.GetAllAsync(); if (LayoutList == null) { LayoutList = new ObservableCollection(); } // 1. 处理站点(StationViewModel) foreach (var station in stations) { var exist = LayoutList.OfType().FirstOrDefault(x => x.Id == station.Id); if (exist != null) { exist.LayOutX = station.LayOutX; exist.LayOutY = station.LayOutY; exist.StationName = station.StationName; exist.StationCode = station.StationCode; exist.Status = station.Status; exist.QrCode = station.QrCode; exist.ProcessName = station.ProcessName; // 可同步更多属性 } else { LayoutList.Add(station); } } // 移除已不存在的站点 for (int i = LayoutList.Count - 1; i >= 0; i--) { if (LayoutList[i] is StationViewModel svm && !stations.Any(x => x.Id == svm.Id)) { LayoutList.RemoveAt(i); } } // 2. 处理RGV(RgvViewModel) foreach (var rgv in rgvs) { // 计算FromStationPoint var fromStation = stations.FirstOrDefault(s => s.Id == rgv.FromStationId1); if (fromStation != null) { double x = fromStation.LayOutX * CellWidthSize + CellWidthSize / 2; double y = fromStation.LayOutY * CellHeightSize + CellHeightSize / 2; rgv.FromStationPoint1 = new Avalonia.Point(x, y); } // 计算ToStationPoint var toStation = stations.FirstOrDefault(s => s.Id == rgv.ToStationId1); if (toStation != null) { double x = toStation.LayOutX * CellWidthSize + CellWidthSize / 2; double y = toStation.LayOutY * CellHeightSize + CellHeightSize / 2; rgv.ToStationPoint1 = new Avalonia.Point(x, y); } // 计算FromStationPoint var fromStation2 = stations.FirstOrDefault(s => s.Id == rgv.FromStationId2); if (fromStation2 != null) { double x = fromStation2.LayOutX * CellWidthSize + CellWidthSize / 2; double y = fromStation2.LayOutY * CellHeightSize + CellHeightSize / 2; rgv.FromStationPoint2 = new Avalonia.Point(x, y); } // 计算ToStationPoint var toStation2 = stations.FirstOrDefault(s => s.Id == rgv.ToStationId2); if (toStation2 != null) { double x = toStation2.LayOutX * CellWidthSize + CellWidthSize / 2; double y = toStation2.LayOutY * CellHeightSize + CellHeightSize / 2; rgv.ToStationPoint2 = new Avalonia.Point(x, y); } var exist = LayoutList.OfType().FirstOrDefault(x => x.Id == rgv.Id); if (exist != null) { exist.LayOutX = rgv.LayOutX; exist.LayOutY = rgv.LayOutY; exist.StationName = rgv.StationName; exist.StationCode = rgv.StationCode; exist.FromStationId1 = rgv.FromStationId1; exist.ToStationId1 = rgv.ToStationId1; exist.FromStationId2 = rgv.FromStationId2; exist.ToStationId2 = rgv.ToStationId2; exist.FromStationPoint1 = rgv.FromStationPoint1; exist.ToStationPoint1 = rgv.ToStationPoint1; } else { LayoutList.Add(rgv); } } // 移除已不存在的RGV for (int i = LayoutList.Count - 1; i >= 0; i--) { if (LayoutList[i] is Rgv6180ViewModel rgvVm && !rgvs.Any(x => x.Id == rgvVm.Id)) { LayoutList.RemoveAt(i); } } double maxRow = LayoutList .Select(e => e.LayOutX) .DefaultIfEmpty(0) .Max(); Width = (int)(maxRow + 1) * (int)CellWidthSize; double maxCol = LayoutList .Select(e => e.LayOutY) .DefaultIfEmpty(0) .Max(); Height = (int)(maxCol + 1) * (int)CellHeightSize; // 示例:随机移动 RGV1 //var rgv1 = LayoutList.OfType().FirstOrDefault(x => x.Id == 1); //if (rgv1 != null) //{ // rgv1.LayOutX = new Random().Next(0, 7); //} } finally { _isProcessing = false; } } }