Files
qhmes/yy-admin-master/YY.Admin/ViewModels/Customer/CustomerListViewModel.cs

289 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.Services.Service.Customer;
using YY.Admin.Views.Customer;
namespace YY.Admin.ViewModels.Customer;
public class CustomerListViewModel : BaseViewModel
{
private readonly ICustomerService _customerService;
private readonly IJeecgDictSyncService _dictSyncService;
private readonly IDialogService _dialogService;
private SubscriptionToken? _customerChangedToken;
private SubscriptionToken? _syncConflictToken;
private ObservableCollection<MesXslCustomer> _customers = new();
public ObservableCollection<MesXslCustomer> Customers
{
get => _customers;
set => SetProperty(ref _customers, 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? _filterCustomerCode;
public string? FilterCustomerCode { get => _filterCustomerCode; set => SetProperty(ref _filterCustomerCode, value); }
private string? _filterCustomerName;
public string? FilterCustomerName { get => _filterCustomerName; set => SetProperty(ref _filterCustomerName, value); }
private string? _filterStatus;
public string? FilterStatus { get => _filterStatus; set => SetProperty(ref _filterStatus, value); }
private string? _filterCustomerRegion;
public string? FilterCustomerRegion { get => _filterCustomerRegion; set => SetProperty(ref _filterCustomerRegion, value); }
public ObservableCollection<KeyValuePair<string, string>> StatusOptions { get; } = new();
public ObservableCollection<KeyValuePair<string, string>> CustomerRegionOptions { get; } = new();
public DelegateCommand SearchCommand { get; }
public DelegateCommand ResetCommand { get; }
public DelegateCommand AddCommand { get; }
public DelegateCommand<MesXslCustomer> EditCommand { get; }
public DelegateCommand<MesXslCustomer> DeleteCommand { get; }
public DelegateCommand<MesXslCustomer> ToggleStatusCommand { get; }
public DelegateCommand PrevPageCommand { get; }
public DelegateCommand NextPageCommand { get; }
public CustomerListViewModel(
ICustomerService customerService,
IJeecgDictSyncService dictSyncService,
IContainerExtension container,
IDialogService dialogService,
IRegionManager regionManager) : base(container, regionManager)
{
_customerService = customerService;
_dictSyncService = dictSyncService;
_dialogService = dialogService;
SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); });
ResetCommand = new DelegateCommand(async () =>
{
FilterCustomerCode = null; FilterCustomerName = null;
FilterStatus = null; FilterCustomerRegion = null;
PageNo = 1; await LoadAsync();
});
AddCommand = new DelegateCommand(async () => await ShowAddDialogAsync());
EditCommand = new DelegateCommand<MesXslCustomer>(async c => await ShowEditDialogAsync(c));
DeleteCommand = new DelegateCommand<MesXslCustomer>(async c => await DeleteAsync(c));
ToggleStatusCommand = new DelegateCommand<MesXslCustomer>(async c => await ToggleStatusAsync(c));
PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } });
NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } });
_customerChangedToken = _eventAggregator.GetEvent<CustomerChangedEvent>()
.Subscribe(async p => await OnCustomerChangedAsync(p), ThreadOption.UIThread);
_syncConflictToken = _eventAggregator.GetEvent<SyncConflictEvent>()
.Subscribe(OnSyncConflict, ThreadOption.UIThread);
_ = InitializeAsync();
}
private async Task OnCustomerChangedAsync(CustomerChangedPayload payload)
{
if (payload.Action == "edit" && !string.IsNullOrWhiteSpace(payload.CustomerId))
{
await RefreshSingleAsync(payload.CustomerId!);
}
else
{
await LoadAsync();
}
}
private async Task RefreshSingleAsync(string customerId)
{
try
{
var updated = await _customerService.GetByIdAsync(customerId);
if (updated == null) return;
var idx = Customers.ToList().FindIndex(c => string.Equals(c.Id, customerId, StringComparison.OrdinalIgnoreCase));
if (idx >= 0)
Customers[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 statusOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_customer_status", includeAll: true);
var regionOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_customer_region", includeAll: true);
StatusOptions.Clear();
foreach (var item in statusOpts) StatusOptions.Add(item);
CustomerRegionOptions.Clear();
foreach (var item in regionOpts) CustomerRegionOptions.Add(item);
if (StatusOptions.Count == 0)
{
StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
StatusOptions.Add(new KeyValuePair<string, string>("启用", "0"));
StatusOptions.Add(new KeyValuePair<string, string>("停用", "1"));
}
if (CustomerRegionOptions.Count == 0)
CustomerRegionOptions.Add(new KeyValuePair<string, string>("全部", ""));
}
catch
{
StatusOptions.Clear();
StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
StatusOptions.Add(new KeyValuePair<string, string>("启用", "0"));
StatusOptions.Add(new KeyValuePair<string, string>("停用", "1"));
CustomerRegionOptions.Clear();
CustomerRegionOptions.Add(new KeyValuePair<string, string>("全部", ""));
}
}
public async Task LoadAsync()
{
try
{
IsLoading = true;
var result = await _customerService.PageAsync(PageNo, PageSize,
FilterCustomerCode, FilterCustomerName, FilterStatus, FilterCustomerRegion);
Customers = new ObservableCollection<MesXslCustomer>(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<CustomerEditDialogView>()
.Initialize<CustomerEditDialogViewModel>(vm => vm.InitializeForAdd())
.GetResultAsync<bool>();
if (result) await LoadAsync();
}
catch (Exception ex)
{
Growl.Error($"打开新增对话框失败:{ex.Message}");
}
}
private async Task ShowEditDialogAsync(MesXslCustomer customer)
{
if (customer == null) return;
try
{
var result = await HandyControl.Controls.Dialog.Show<CustomerEditDialogView>()
.Initialize<CustomerEditDialogViewModel>(vm => vm.InitializeForEdit(customer))
.GetResultAsync<bool>();
if (result) await LoadAsync();
}
catch (Exception ex)
{
Growl.Error($"打开编辑对话框失败:{ex.Message}");
}
}
private async Task DeleteAsync(MesXslCustomer customer)
{
if (customer?.Id == null) return;
var confirm = System.Windows.MessageBox.Show(
$"确定删除客户【{customer.CustomerName}】?此操作不可恢复!",
"确认删除", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if (confirm != System.Windows.MessageBoxResult.OK) return;
var ok = await _customerService.DeleteAsync(customer.Id);
if (ok) { Growl.Success("删除成功!"); await LoadAsync(); }
else Growl.Error("删除失败!");
}
private async Task ToggleStatusAsync(MesXslCustomer customer)
{
if (customer?.Id == null) return;
var newStatus = customer.Status == "1" ? "0" : "1";
var ok = await _customerService.UpdateStatusAsync(customer.Id, newStatus);
if (ok)
{
// 客户列表离线场景下只改行对象字段DataGrid 对计算列(StatusText)可能不会立即重绘。
// 这里统一重载一次列表,确保状态、筛选结果和分页统计立即一致。
await LoadAsync();
}
else Growl.Error("状态切换失败!");
}
protected override void CleanUp()
{
base.CleanUp();
if (_customerChangedToken != null)
{
_eventAggregator.GetEvent<CustomerChangedEvent>().Unsubscribe(_customerChangedToken);
_customerChangedToken = null;
}
if (_syncConflictToken != null)
{
_eventAggregator.GetEvent<SyncConflictEvent>().Unsubscribe(_syncConflictToken);
_syncConflictToken = null;
}
}
}