using HandyControl.Controls; using HandyControl.Tools.Extension; using System.Collections.ObjectModel; using YY.Admin.Core; using YY.Admin.Core.Entity; using YY.Admin.Core.Services; using YY.Admin.Services.Service; namespace YY.Admin.ViewModels.RawMaterialEntry; public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResultable { private readonly IRawMaterialEntryService _entryService; private readonly IJeecgDictSyncService _dictSyncService; private readonly IMixerMaterialService _mixerMaterialService; // 加载完物料后用于回填 Edit 模式选中项 private string? _pendingMaterialId; private MesXslRawMaterialEntry? _entry; public MesXslRawMaterialEntry? Entry { get => _entry; set => SetProperty(ref _entry, value); } private MesMixerMaterial? _selectedMaterial; public MesMixerMaterial? SelectedMaterial { get => _selectedMaterial; set { if (!SetProperty(ref _selectedMaterial, value) || value == null || Entry == null) return; Entry.MaterialId = value.Id; Entry.MaterialCode = value.MaterialCode; Entry.MaterialName = value.MaterialName; RaisePropertyChanged(nameof(Entry)); // 新增模式自动生成条码/批次号 if (IsAddMode && !string.IsNullOrEmpty(value.MaterialCode)) _ = AutoGenerateBarcodeAsync(value.MaterialCode); } } private bool _isGenerating; public bool IsGenerating { get => _isGenerating; set => SetProperty(ref _isGenerating, value); } public bool IsAddMode => string.IsNullOrWhiteSpace(Entry?.Id); public string DialogTitle => IsAddMode ? "新增原料入场记录" : "编辑原料入场记录"; public ObservableCollection MaterialOptions { get; } = new(); public ObservableCollection> TestResultOptions { get; } = new(); public ObservableCollection> TestStatusOptions { get; } = new(); public ObservableCollection> PrintFlagOptions { get; } = new(); public ObservableCollection> StockBalanceOptions { get; } = new(); public ObservableCollection> IsSpecialAdoptionOptions { get; } = new(); public ObservableCollection> StatusOptions { get; } = new(); private bool _result; public bool Result { get => _result; set => SetProperty(ref _result, value); } public Action? CloseAction { get; set; } public DelegateCommand SaveCommand { get; } public DelegateCommand CancelCommand { get; } public RawMaterialEntryEditDialogViewModel( IRawMaterialEntryService entryService, IJeecgDictSyncService dictSyncService, IMixerMaterialService mixerMaterialService, IContainerExtension container, IRegionManager regionManager) : base(container, regionManager) { _entryService = entryService; _dictSyncService = dictSyncService; _mixerMaterialService = mixerMaterialService; SaveCommand = new DelegateCommand(async () => await SaveAsync()); CancelCommand = new DelegateCommand(() => CloseAction?.Invoke()); _ = LoadAllAsync(); } private async Task LoadAllAsync() { await Task.WhenAll(LoadDictOptionsAsync(), LoadMaterialOptionsAsync()); } private async Task LoadMaterialOptionsAsync() { try { // 每次打开弹窗都主动拉一次,确保直接写库的数据也能同步到 await _mixerMaterialService.SyncFromRemoteAsync(); var result = await _mixerMaterialService.PageAsync(1, 2000); MaterialOptions.Clear(); foreach (var m in result.Records) MaterialOptions.Add(m); // Edit 模式:物料加载完后回填选中项 if (_pendingMaterialId != null) { var match = MaterialOptions.FirstOrDefault(m => string.Equals(m.Id, _pendingMaterialId, StringComparison.OrdinalIgnoreCase)); if (match != null) SelectedMaterial = match; _pendingMaterialId = null; } } catch { /* 无法加载物料列表时不阻断表单 */ } } private async Task LoadDictOptionsAsync() { try { var testResultOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_test_result"); var testStatusOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_test_status"); var printFlagOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_print_flag"); var ynOpts = await _dictSyncService.GetDictOptionsAsync("yn"); var statusOpts = await _dictSyncService.GetDictOptionsAsync("xslmes_entry_status"); PopulateOptions(TestResultOptions, testResultOpts, new[] { new KeyValuePair("未检", "0"), new KeyValuePair("合格", "1"), new KeyValuePair("不合格", "2"), }); PopulateOptions(TestStatusOptions, testStatusOpts, new[] { new KeyValuePair("送样", "0"), new KeyValuePair("已批准", "1"), }); PopulateOptions(PrintFlagOptions, printFlagOpts, new[] { new KeyValuePair("未打印", "0"), new KeyValuePair("已打印", "1"), }); PopulateOptions(StockBalanceOptions, ynOpts, new[] { new KeyValuePair("否", "0"), new KeyValuePair("是", "1"), }); PopulateOptions(IsSpecialAdoptionOptions, ynOpts, new[] { new KeyValuePair("否", "0"), new KeyValuePair("是", "1"), }); PopulateOptions(StatusOptions, statusOpts, Array.Empty>()); } catch { FillFallbackOptions(); } } private static void PopulateOptions( ObservableCollection> target, IEnumerable> items, IEnumerable> fallback) { target.Clear(); var list = items.ToList(); foreach (var item in list.Count > 0 ? list : fallback.ToList()) target.Add(item); } private void FillFallbackOptions() { PopulateOptions(TestResultOptions, Array.Empty>(), new[] { new KeyValuePair("未检", "0"), new KeyValuePair("合格", "1"), new KeyValuePair("不合格", "2"), }); PopulateOptions(TestStatusOptions, Array.Empty>(), new[] { new KeyValuePair("送样", "0"), new KeyValuePair("已批准", "1"), }); PopulateOptions(PrintFlagOptions, Array.Empty>(), new[] { new KeyValuePair("未打印", "0"), new KeyValuePair("已打印", "1"), }); var ynDefault = new[] { new KeyValuePair("否", "0"), new KeyValuePair("是", "1") }; PopulateOptions(StockBalanceOptions, Array.Empty>(), ynDefault); PopulateOptions(IsSpecialAdoptionOptions, Array.Empty>(), ynDefault); } private async Task AutoGenerateBarcodeAsync(string materialCode) { IsGenerating = true; try { var code = await _entryService.GenerateBarcodeAsync(materialCode); if (!string.IsNullOrEmpty(code) && Entry != null) { Entry.Barcode = code; Entry.BatchNo = code; RaisePropertyChanged(nameof(Entry)); } } finally { IsGenerating = false; } } public void InitializeForAdd() { _selectedMaterial = null; RaisePropertyChanged(nameof(SelectedMaterial)); Entry = new MesXslRawMaterialEntry { TestResult = "0", TestStatus = "0", PrintFlag = "0", StockBalance = "0", IsSpecialAdoption = "0" }; RaisePropertyChanged(nameof(IsAddMode)); RaisePropertyChanged(nameof(DialogTitle)); } public void InitializeForEdit(MesXslRawMaterialEntry entry) { Entry = new MesXslRawMaterialEntry { Id = entry.Id, Barcode = entry.Barcode, BatchNo = entry.BatchNo, EntryTime = entry.EntryTime, WeightRecordId = entry.WeightRecordId, BillNo = entry.BillNo, MaterialId = entry.MaterialId, MaterialCode = entry.MaterialCode, MaterialName = entry.MaterialName, SupplyCustomer = entry.SupplyCustomer, SupplierId = entry.SupplierId, SupplierName = entry.SupplierName, ManufacturerMaterialName = entry.ManufacturerMaterialName, ShelfLife = entry.ShelfLife, TotalWeight = entry.TotalWeight, TotalPortions = entry.TotalPortions, PortionWeight = entry.PortionWeight, PortionPackages = entry.PortionPackages, TestResult = entry.TestResult, TestStatus = entry.TestStatus, PrintFlag = entry.PrintFlag, StockBalance = entry.StockBalance, WarehouseLocation = entry.WarehouseLocation, UnloadOperator = entry.UnloadOperator, IsSpecialAdoption = entry.IsSpecialAdoption, SpecialAdoptionOperator = entry.SpecialAdoptionOperator, SpecialAdoptionTime = entry.SpecialAdoptionTime, SpecialAdoptionReason = entry.SpecialAdoptionReason, Status = entry.Status, Remark = entry.Remark, TenantId = entry.TenantId, }; // 若物料列表已加载则直接回填,否则记录 pending 等加载完后回填 if (MaterialOptions.Count > 0) { _selectedMaterial = MaterialOptions.FirstOrDefault(m => string.Equals(m.Id, entry.MaterialId, StringComparison.OrdinalIgnoreCase)); RaisePropertyChanged(nameof(SelectedMaterial)); } else { _pendingMaterialId = entry.MaterialId; } RaisePropertyChanged(nameof(IsAddMode)); RaisePropertyChanged(nameof(DialogTitle)); } private async Task SaveAsync() { if (Entry == null) return; try { bool ok; if (IsAddMode) { ok = await _entryService.AddAsync(Entry); if (ok) HandyControl.Controls.MessageBox.Success("新增成功!"); else { HandyControl.Controls.MessageBox.Error("新增失败!"); return; } } else { ok = await _entryService.EditAsync(Entry); if (!ok) { HandyControl.Controls.MessageBox.Error("编辑失败!"); return; } } Result = ok; CloseAction?.Invoke(); } catch (Exception ex) { HandyControl.Controls.MessageBox.Error($"操作失败:{ex.Message}"); } } }