using HandyControl.Controls; using HandyControl.Tools.Extension; using Prism.Events; using System.Collections.ObjectModel; using System.Diagnostics; using System.Windows; using YY.Admin.Core; using YY.Admin.Core.Events; using YY.Admin.Core.Helper; using YY.Admin.Core.Entity; using YY.Admin.Core.Services; using YY.Admin.Services.Service; using YY.Admin.Views.Vehicle; namespace YY.Admin.ViewModels.Vehicle; public class VehicleListViewModel : BaseViewModel { private readonly IVehicleService _vehicleService; private readonly IJeecgDictSyncService _dictSyncService; private readonly IDialogService _dialogService; private SubscriptionToken? _vehicleChangedToken; private SubscriptionToken? _syncConflictToken; private ObservableCollection _vehicles = new(); public ObservableCollection Vehicles { get => _vehicles; set => SetProperty(ref _vehicles, value); } private long _total; public long Total { get => _total; set => SetProperty(ref _total, value); } private int _pageNo = 1; public int PageNo { get => _pageNo; set => SetProperty(ref _pageNo, value); } private int _pageSize = 20; public int PageSize { get => _pageSize; set => SetProperty(ref _pageSize, value); } private string? _filterPlateNumber; public string? FilterPlateNumber { get => _filterPlateNumber; set => SetProperty(ref _filterPlateNumber, value); } private string? _filterVehicleBelong; public string? FilterVehicleBelong { get => _filterVehicleBelong; set => SetProperty(ref _filterVehicleBelong, value); } private string? _filterStatus; public string? FilterStatus { get => _filterStatus; set => SetProperty(ref _filterStatus, value); } public ObservableCollection> VehicleBelongOptions { get; } = new(); public ObservableCollection> StatusOptions { get; } = new(); public DelegateCommand SearchCommand { get; } public DelegateCommand ResetCommand { get; } public DelegateCommand AddCommand { get; } public DelegateCommand EditCommand { get; } public DelegateCommand DeleteCommand { get; } public DelegateCommand ToggleStatusCommand { get; } public DelegateCommand PrevPageCommand { get; } public DelegateCommand NextPageCommand { get; } public VehicleListViewModel( IVehicleService vehicleService, IJeecgDictSyncService dictSyncService, IContainerExtension container, IDialogService dialogService, IRegionManager regionManager) : base(container, regionManager) { _vehicleService = vehicleService; _dictSyncService = dictSyncService; _dialogService = dialogService; SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); }); ResetCommand = new DelegateCommand(async () => { FilterPlateNumber = null; FilterVehicleBelong = null; FilterStatus = null; PageNo = 1; await LoadAsync(); }); AddCommand = new DelegateCommand(async () => await ShowAddDialogAsync()); EditCommand = new DelegateCommand(async v => await ShowEditDialogAsync(v)); DeleteCommand = new DelegateCommand(async v => await DeleteAsync(v)); ToggleStatusCommand = new DelegateCommand(async v => await ToggleStatusAsync(v)); PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } }); NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } }); _vehicleChangedToken = _eventAggregator .GetEvent() .Subscribe(async p => await OnVehicleChangedAsync(p), ThreadOption.UIThread); _syncConflictToken = _eventAggregator.GetEvent() .Subscribe(OnSyncConflict, ThreadOption.UIThread); _ = InitializeAsync(); } private async Task OnVehicleChangedAsync(VehicleChangedPayload payload) { if (payload.Action == "edit" && !string.IsNullOrWhiteSpace(payload.VehicleId)) { await RefreshSingleAsync(payload.VehicleId!); } else { await LoadAsync(); } } private async Task RefreshSingleAsync(string vehicleId) { try { var updated = await _vehicleService.GetByIdAsync(vehicleId); if (updated == null) return; var idx = Vehicles.ToList().FindIndex(v => string.Equals(v.Id, vehicleId, StringComparison.OrdinalIgnoreCase)); if (idx >= 0) Vehicles[idx] = updated; } catch (Exception ex) { Debug.WriteLine($"[车辆] 单条刷新失败: {ex.Message}"); } } private void OnSyncConflict(SyncConflictPayload payload) { if (!string.Equals(payload.EntityName, "车辆", StringComparison.OrdinalIgnoreCase)) return; var parts = new List(); if (payload.PushedCount > 0) parts.Add($"已同步 {payload.PushedCount} 条本地改动到服务器"); if (payload.NewRecordsPushed > 0) parts.Add($"已上传 {payload.NewRecordsPushed} 条本地新增记录"); if (payload.ConflictCount > 0) parts.Add($"{payload.ConflictCount} 条记录与服务器版本冲突,已保留服务器版本"); if (parts.Count == 0) return; var message = string.Join("\n", parts); if (payload.ConflictCount > 0) Growl.Warning(message); else Growl.Success(message); } private async Task InitializeAsync() { try { await LoadDictOptionsAsync(); await UIHelper.WaitForRenderAsync(); await LoadAsync(); } catch (Exception ex) { Debug.WriteLine($"车辆列表初始化失败: {ex.Message}"); } } private async Task LoadDictOptionsAsync() { try { var belongOptions = await _dictSyncService.GetDictOptionsAsync("xslmes_vehicle_belong", includeAll: true); var statusOptions = await _dictSyncService.GetDictOptionsAsync("xslmes_vehicle_status", includeAll: true); VehicleBelongOptions.Clear(); foreach (var item in belongOptions) { VehicleBelongOptions.Add(item); } StatusOptions.Clear(); foreach (var item in statusOptions) { StatusOptions.Add(item); } if (VehicleBelongOptions.Count == 0) { VehicleBelongOptions.Add(new KeyValuePair("全部", "")); } if (StatusOptions.Count == 0) { StatusOptions.Add(new KeyValuePair("全部", "")); } } catch { VehicleBelongOptions.Clear(); VehicleBelongOptions.Add(new KeyValuePair("全部", "")); VehicleBelongOptions.Add(new KeyValuePair("客户", "1")); VehicleBelongOptions.Add(new KeyValuePair("供应商", "2")); VehicleBelongOptions.Add(new KeyValuePair("本公司", "3")); StatusOptions.Clear(); StatusOptions.Add(new KeyValuePair("全部", "")); StatusOptions.Add(new KeyValuePair("启用", "0")); StatusOptions.Add(new KeyValuePair("停用", "1")); } } public async Task LoadAsync() { try { IsLoading = true; var result = await _vehicleService.PageAsync(PageNo, PageSize, FilterPlateNumber, FilterVehicleBelong, FilterStatus); Vehicles = new ObservableCollection(result.Records); Total = result.Total; } catch (Exception ex) { Growl.Error($"加载车辆列表失败:{ex.Message}"); } finally { IsLoading = false; } } private async Task ShowAddDialogAsync() { try { var result = await HandyControl.Controls.Dialog.Show() .Initialize(vm => vm.InitializeForAdd()) .GetResultAsync(); if (result) await LoadAsync(); } catch (Exception ex) { Growl.Error($"打开新增对话框失败:{ex.Message}"); } } private async Task ShowEditDialogAsync(MesXslVehicle vehicle) { if (vehicle == null) return; try { var result = await HandyControl.Controls.Dialog.Show() .Initialize(vm => vm.InitializeForEdit(vehicle)) .GetResultAsync(); if (result) await LoadAsync(); } catch (Exception ex) { Growl.Error($"打开编辑对话框失败:{ex.Message}"); } } private async Task DeleteAsync(MesXslVehicle vehicle) { if (vehicle?.Id == null) return; var confirm = System.Windows.MessageBox.Show($"确定删除车辆 {vehicle.PlateNumber}?此操作不可恢复!", "确认删除", MessageBoxButton.OKCancel, MessageBoxImage.Question); if (confirm != System.Windows.MessageBoxResult.OK) return; var ok = await _vehicleService.DeleteAsync(vehicle.Id); if (ok) { Growl.Success("删除成功!"); await LoadAsync(); } else { Growl.Error("删除失败!"); } } private async Task ToggleStatusAsync(MesXslVehicle vehicle) { if (vehicle?.Id == null) return; var newStatus = vehicle.Status == "1" ? "0" : "1"; var ok = await _vehicleService.UpdateStatusAsync(vehicle.Id, newStatus); if (ok) { vehicle.Status = newStatus; RaisePropertyChanged(nameof(Vehicles)); } else { Growl.Error("状态切换失败!"); } } protected override void CleanUp() { base.CleanUp(); if (_vehicleChangedToken != null) { _eventAggregator.GetEvent().Unsubscribe(_vehicleChangedToken); _vehicleChangedToken = null; } if (_syncConflictToken != null) { _eventAggregator.GetEvent().Unsubscribe(_syncConflictToken); _syncConflictToken = null; } } }