307 lines
11 KiB
C#
307 lines
11 KiB
C#
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<MesXslVehicle> _vehicles = new();
|
|
public ObservableCollection<MesXslVehicle> 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<KeyValuePair<string, string>> VehicleBelongOptions { get; } = new();
|
|
|
|
public ObservableCollection<KeyValuePair<string, string>> StatusOptions { get; } = new();
|
|
|
|
public DelegateCommand SearchCommand { get; }
|
|
public DelegateCommand ResetCommand { get; }
|
|
public DelegateCommand AddCommand { get; }
|
|
public DelegateCommand<MesXslVehicle> EditCommand { get; }
|
|
public DelegateCommand<MesXslVehicle> DeleteCommand { get; }
|
|
public DelegateCommand<MesXslVehicle> 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<MesXslVehicle>(async v => await ShowEditDialogAsync(v));
|
|
DeleteCommand = new DelegateCommand<MesXslVehicle>(async v => await DeleteAsync(v));
|
|
ToggleStatusCommand = new DelegateCommand<MesXslVehicle>(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<VehicleChangedEvent>()
|
|
.Subscribe(async p => await OnVehicleChangedAsync(p), ThreadOption.UIThread);
|
|
|
|
_syncConflictToken = _eventAggregator.GetEvent<SyncConflictEvent>()
|
|
.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<string>();
|
|
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<string, string>("全部", ""));
|
|
}
|
|
if (StatusOptions.Count == 0)
|
|
{
|
|
StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
VehicleBelongOptions.Clear();
|
|
VehicleBelongOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
|
VehicleBelongOptions.Add(new KeyValuePair<string, string>("客户", "1"));
|
|
VehicleBelongOptions.Add(new KeyValuePair<string, string>("供应商", "2"));
|
|
VehicleBelongOptions.Add(new KeyValuePair<string, string>("本公司", "3"));
|
|
|
|
StatusOptions.Clear();
|
|
StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
|
StatusOptions.Add(new KeyValuePair<string, string>("启用", "0"));
|
|
StatusOptions.Add(new KeyValuePair<string, string>("停用", "1"));
|
|
}
|
|
}
|
|
|
|
public async Task LoadAsync()
|
|
{
|
|
try
|
|
{
|
|
IsLoading = true;
|
|
var result = await _vehicleService.PageAsync(PageNo, PageSize, FilterPlateNumber, FilterVehicleBelong, FilterStatus);
|
|
Vehicles = new ObservableCollection<MesXslVehicle>(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<VehicleEditDialogView>()
|
|
.Initialize<VehicleEditDialogViewModel>(vm => vm.InitializeForAdd())
|
|
.GetResultAsync<bool>();
|
|
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<VehicleEditDialogView>()
|
|
.Initialize<VehicleEditDialogViewModel>(vm => vm.InitializeForEdit(vehicle))
|
|
.GetResultAsync<bool>();
|
|
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<VehicleChangedEvent>().Unsubscribe(_vehicleChangedToken);
|
|
_vehicleChangedToken = null;
|
|
}
|
|
|
|
if (_syncConflictToken != null)
|
|
{
|
|
_eventAggregator.GetEvent<SyncConflictEvent>().Unsubscribe(_syncConflictToken);
|
|
_syncConflictToken = null;
|
|
}
|
|
}
|
|
}
|