Files
qhmes/yy-admin-master/YY.Admin/ViewModels/RawMaterialCard/RawMaterialCardListViewModel.cs

338 lines
13 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.Entity;
using YY.Admin.Core.Events;
using YY.Admin.Core.Helper;
using YY.Admin.Core.Services;
using YY.Admin.Services.Service;
using YY.Admin.Views.Print;
using YY.Admin.Views.RawMaterialCard;
namespace YY.Admin.ViewModels.RawMaterialCard;
public class RawMaterialCardListViewModel : BaseViewModel
{
private readonly IRawMaterialCardService _cardService;
private readonly IJeecgDictSyncService _dictSyncService;
private readonly IPrintDotService _printDotService;
private SubscriptionToken? _changedToken;
private SubscriptionToken? _syncConflictToken;
private ObservableCollection<MesXslRawMaterialCard> _cards = new();
public ObservableCollection<MesXslRawMaterialCard> Cards
{
get => _cards;
set => SetProperty(ref _cards, 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? _filterBarcode;
public string? FilterBarcode { get => _filterBarcode; set => SetProperty(ref _filterBarcode, value); }
private string? _filterBatchNo;
public string? FilterBatchNo { get => _filterBatchNo; set => SetProperty(ref _filterBatchNo, value); }
private string? _filterMaterialName;
public string? FilterMaterialName { get => _filterMaterialName; set => SetProperty(ref _filterMaterialName, value); }
private string? _filterSupplierName;
public string? FilterSupplierName { get => _filterSupplierName; set => SetProperty(ref _filterSupplierName, value); }
private string? _filterStatus;
public string? FilterStatus { get => _filterStatus; set => SetProperty(ref _filterStatus, value); }
public ObservableCollection<KeyValuePair<string, string>> StatusOptions { get; } = new();
public ObservableCollection<KeyValuePair<string, string>> TestResultOptions { get; } = new();
public DelegateCommand SearchCommand { get; }
public DelegateCommand ResetCommand { get; }
public DelegateCommand AddCommand { get; }
public DelegateCommand<MesXslRawMaterialCard> EditCommand { get; }
public DelegateCommand<MesXslRawMaterialCard> DeleteCommand { get; }
public DelegateCommand<MesXslRawMaterialCard> PrintCommand { get; }
public DelegateCommand<MesXslRawMaterialCard> TogglePriorityCommand { get; }
public DelegateCommand PrevPageCommand { get; }
public DelegateCommand NextPageCommand { get; }
public RawMaterialCardListViewModel(
IRawMaterialCardService cardService,
IJeecgDictSyncService dictSyncService,
IPrintDotService printDotService,
IContainerExtension container,
IRegionManager regionManager) : base(container, regionManager)
{
_cardService = cardService;
_dictSyncService = dictSyncService;
_printDotService = printDotService;
SearchCommand = new DelegateCommand(async () => { PageNo = 1; await LoadAsync(); });
ResetCommand = new DelegateCommand(async () =>
{
FilterBarcode = null; FilterBatchNo = null; FilterMaterialName = null;
FilterSupplierName = null; FilterStatus = null; PageNo = 1;
await LoadAsync();
});
AddCommand = new DelegateCommand(async () => await ShowAddDialogAsync());
EditCommand = new DelegateCommand<MesXslRawMaterialCard>(async c => await ShowEditDialogAsync(c));
DeleteCommand = new DelegateCommand<MesXslRawMaterialCard>(async c => await DeleteAsync(c));
PrintCommand = new DelegateCommand<MesXslRawMaterialCard>(async c => await ShowPrintPreviewAsync(c));
TogglePriorityCommand = new DelegateCommand<MesXslRawMaterialCard>(async c => await TogglePriorityAsync(c));
PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } });
NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } });
_changedToken = _eventAggregator.GetEvent<RawMaterialCardChangedEvent>()
.Subscribe(async p => await OnChangedAsync(p), ThreadOption.UIThread);
_syncConflictToken = _eventAggregator.GetEvent<SyncConflictEvent>()
.Subscribe(OnSyncConflict, ThreadOption.UIThread);
_ = InitializeAsync();
}
private async Task OnChangedAsync(RawMaterialCardChangedPayload payload)
{
if (payload.Action == "edit" && !string.IsNullOrWhiteSpace(payload.CardId))
await RefreshSingleAsync(payload.CardId!);
else
await LoadAsync();
}
private async Task RefreshSingleAsync(string cardId)
{
try
{
var updated = await _cardService.GetByIdAsync(cardId);
if (updated == null) return;
var idx = Cards.ToList().FindIndex(c => string.Equals(c.Id, cardId, StringComparison.OrdinalIgnoreCase));
if (idx >= 0) Cards[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_card_status", includeAll: true);
var testResultOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_test_result", includeAll: true);
StatusOptions.Clear();
foreach (var item in statusOpts) StatusOptions.Add(item);
if (StatusOptions.Count == 0) StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
TestResultOptions.Clear();
foreach (var item in testResultOpts) TestResultOptions.Add(item);
if (TestResultOptions.Count == 0) TestResultOptions.Add(new KeyValuePair<string, string>("全部", ""));
}
catch
{
StatusOptions.Clear();
StatusOptions.Add(new KeyValuePair<string, string>("全部", ""));
StatusOptions.Add(new KeyValuePair<string, string>("正常", "1"));
StatusOptions.Add(new KeyValuePair<string, string>("异常", "0"));
TestResultOptions.Clear();
TestResultOptions.Add(new KeyValuePair<string, string>("全部", ""));
TestResultOptions.Add(new KeyValuePair<string, string>("未检", "0"));
TestResultOptions.Add(new KeyValuePair<string, string>("合格", "1"));
TestResultOptions.Add(new KeyValuePair<string, string>("不合格", "2"));
}
}
public async Task LoadAsync()
{
try
{
IsLoading = true;
var result = await _cardService.PageAsync(PageNo, PageSize,
FilterBarcode, FilterBatchNo, FilterMaterialName, FilterSupplierName, FilterStatus);
Cards = new ObservableCollection<MesXslRawMaterialCard>(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<RawMaterialCardEditDialogView>()
.Initialize<RawMaterialCardEditDialogViewModel>(vm => vm.InitializeForAdd())
.GetResultAsync<bool>();
if (result) await LoadAsync();
}
catch (Exception ex)
{
Growl.Error($"打开新增对话框失败:{ex.Message}");
}
}
private async Task ShowEditDialogAsync(MesXslRawMaterialCard card)
{
if (card == null) return;
try
{
var result = await HandyControl.Controls.Dialog.Show<RawMaterialCardEditDialogView>()
.Initialize<RawMaterialCardEditDialogViewModel>(vm => vm.InitializeForEdit(card))
.GetResultAsync<bool>();
if (result) await LoadAsync();
}
catch (Exception ex)
{
Growl.Error($"打开编辑对话框失败:{ex.Message}");
}
}
private async Task DeleteAsync(MesXslRawMaterialCard card)
{
if (card?.Id == null) return;
var confirm = System.Windows.MessageBox.Show(
$"确定删除原材料卡片(条码:{card.Barcode})?此操作不可恢复!",
"确认删除", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if (confirm != System.Windows.MessageBoxResult.OK) return;
var ok = await _cardService.DeleteAsync(card.Id);
if (ok) { Growl.Success("删除成功!"); await LoadAsync(); }
else Growl.Error("删除失败!");
}
private async Task TogglePriorityAsync(MesXslRawMaterialCard card)
{
if (card?.Id == null) return;
var newVal = card.PriorityPickup == "1" ? "0" : "1";
var ok = await _cardService.UpdatePriorityAsync(card.Id, newVal);
if (ok)
{
card.PriorityPickup = newVal;
RaisePropertyChanged(nameof(Cards));
}
else
{
Growl.Error("优先出库设置失败!");
}
}
private async Task ShowPrintPreviewAsync(MesXslRawMaterialCard card)
{
if (card?.Id == null) return;
try
{
IsLoading = true;
var (templateJson, printDataJson, errorMessage) = await _cardService.PrepareNativePrintAsync(card.Id);
if (errorMessage != null)
{
Growl.Error(errorMessage);
return;
}
// 构造一个最简的 PrintTemplate 对象用于传入 PrintPreviewWindow供显示标题 / 纸张信息)
var tpl = BuildPrintTemplateFromJson(templateJson);
var win = new PrintPreviewWindow(tpl, templateJson, _printDotService, null, printDataJson)
{
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
};
win.Show();
}
catch (Exception ex)
{
Growl.Error($"打开打印预览失败:{ex.Message}");
}
finally
{
IsLoading = false;
}
}
private static PrintTemplate BuildPrintTemplateFromJson(string templateJson)
{
try
{
var root = System.Text.Json.JsonDocument.Parse(templateJson).RootElement;
double w = 210, h = 297;
if (root.TryGetProperty("page", out var page))
{
if (page.TryGetProperty("width", out var wEl)) w = wEl.GetDouble();
if (page.TryGetProperty("height", out var hEl)) h = hEl.GetDouble();
}
return new PrintTemplate
{
TemplateName = "原材料卡片",
TemplateCode = "MES_RAW_MATERIAL_CARD",
PaperWidthMm = w,
PaperHeightMm = h,
PaperOrientation = w > h ? "横向" : "纵向",
};
}
catch
{
return new PrintTemplate { TemplateName = "原材料卡片", TemplateCode = "MES_RAW_MATERIAL_CARD" };
}
}
protected override void CleanUp()
{
base.CleanUp();
if (_changedToken != null)
{
_eventAggregator.GetEvent<RawMaterialCardChangedEvent>().Unsubscribe(_changedToken);
_changedToken = null;
}
if (_syncConflictToken != null)
{
_eventAggregator.GetEvent<SyncConflictEvent>().Unsubscribe(_syncConflictToken);
_syncConflictToken = null;
}
}
}