新增原料入场记录独立页面,更新导航和菜单配置以支持新功能。优化原料入场记录编辑对话框,增强物料选择和显示逻辑,提升用户体验。
This commit is contained in:
@@ -125,7 +125,12 @@ namespace YY.Admin.ViewModels.Control
|
||||
// 已实现页面:原料入场记录
|
||||
["RawMaterialEntryListView"] = "RawMaterialEntryListView",
|
||||
["/xslmes/mesXslRawMaterialEntry"] = "RawMaterialEntryListView",
|
||||
["mesXslRawMaterialEntry"] = "RawMaterialEntryListView"
|
||||
["mesXslRawMaterialEntry"] = "RawMaterialEntryListView",
|
||||
|
||||
// 已实现页面:新增原料入场记录
|
||||
["RawMaterialEntryOperationView"] = "RawMaterialEntryOperationView",
|
||||
["/xslmes/rawMaterialEntryOperation"] = "RawMaterialEntryOperationView",
|
||||
["rawMaterialEntryOperation"] = "RawMaterialEntryOperationView"
|
||||
};
|
||||
|
||||
private MenuItem? _selectedMenuItem;
|
||||
|
||||
@@ -5,6 +5,7 @@ using YY.Admin.Core;
|
||||
using YY.Admin.Core.Entity;
|
||||
using YY.Admin.Core.Services;
|
||||
using YY.Admin.Services.Service;
|
||||
using YY.Admin.Views.RawMaterialEntry;
|
||||
|
||||
namespace YY.Admin.ViewModels.RawMaterialEntry;
|
||||
|
||||
@@ -31,10 +32,14 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
set
|
||||
{
|
||||
if (!SetProperty(ref _selectedMaterial, value) || value == null || Entry == null) return;
|
||||
Entry.MaterialId = value.Id;
|
||||
Entry.MaterialId = value.Id;
|
||||
Entry.MaterialCode = value.MaterialCode;
|
||||
Entry.MaterialName = value.MaterialName;
|
||||
Entry.ManufacturerMaterialName = value.AliasName;
|
||||
RecalculateShelfLife(value);
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
RaisePropertyChanged(nameof(SelectedMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterial));
|
||||
|
||||
// 新增模式自动生成条码/批次号
|
||||
if (IsAddMode && !string.IsNullOrEmpty(value.MaterialCode))
|
||||
@@ -51,6 +56,57 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
|
||||
public bool IsAddMode => string.IsNullOrWhiteSpace(Entry?.Id);
|
||||
public string DialogTitle => IsAddMode ? "新增原料入场记录" : "编辑原料入场记录";
|
||||
public string SelectedMaterialDisplay => _selectedMaterial == null
|
||||
? "请选择密炼物料"
|
||||
: $"[{_selectedMaterial.MaterialCode}] {_selectedMaterial.MaterialName}";
|
||||
public bool HasSelectedMaterial => _selectedMaterial != null;
|
||||
|
||||
public string? IsSpecialAdoptionValue
|
||||
{
|
||||
get => Entry?.IsSpecialAdoption;
|
||||
set
|
||||
{
|
||||
if (Entry == null || Entry.IsSpecialAdoption == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry.IsSpecialAdoption = value;
|
||||
if (!string.Equals(value, "1", StringComparison.Ordinal))
|
||||
{
|
||||
Entry.SpecialAdoptionOperator = null;
|
||||
Entry.SpecialAdoptionTime = null;
|
||||
Entry.SpecialAdoptionReason = null;
|
||||
}
|
||||
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
RaisePropertyChanged(nameof(IsSpecialAdoptionValue));
|
||||
}
|
||||
}
|
||||
|
||||
public double? TotalWeightInput
|
||||
{
|
||||
get => Entry?.TotalWeight;
|
||||
set
|
||||
{
|
||||
if (Entry == null || Entry.TotalWeight == value) return;
|
||||
Entry.TotalWeight = value;
|
||||
RecalculatePortionWeight();
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
}
|
||||
}
|
||||
|
||||
public int? TotalPortionsInput
|
||||
{
|
||||
get => Entry?.TotalPortions;
|
||||
set
|
||||
{
|
||||
if (Entry == null || Entry.TotalPortions == value) return;
|
||||
Entry.TotalPortions = value;
|
||||
RecalculatePortionWeight();
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<MesMixerMaterial> MaterialOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> TestResultOptions { get; } = new();
|
||||
@@ -59,6 +115,8 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
public ObservableCollection<KeyValuePair<string, string>> StockBalanceOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> IsSpecialAdoptionOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> StatusOptions { get; } = new();
|
||||
public ObservableCollection<RawMaterialSplitDetailItem> SplitCodeDetails { get; } = new();
|
||||
public double SplitCodeTableHeight => CalculateSplitCodeTableHeight();
|
||||
|
||||
private bool _result;
|
||||
public bool Result { get => _result; set => SetProperty(ref _result, value); }
|
||||
@@ -66,6 +124,13 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
|
||||
public DelegateCommand SaveCommand { get; }
|
||||
public DelegateCommand CancelCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
public DelegateCommand AddSplitDetailCommand { get; }
|
||||
public DelegateCommand<RawMaterialSplitDetailItem> RemoveSplitDetailCommand { get; }
|
||||
public DelegateCommand OpenMaterialPickerCommand { get; }
|
||||
public DelegateCommand ClearMaterialCommand { get; }
|
||||
public DelegateCommand OpenWeightRecordPickerCommand { get; }
|
||||
public DelegateCommand ClearWeightRecordCommand { get; }
|
||||
|
||||
public RawMaterialEntryEditDialogViewModel(
|
||||
IRawMaterialEntryService entryService,
|
||||
@@ -79,6 +144,14 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
_mixerMaterialService = mixerMaterialService;
|
||||
SaveCommand = new DelegateCommand(async () => await SaveAsync());
|
||||
CancelCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||
ResetCommand = new DelegateCommand(InitializeForAdd);
|
||||
AddSplitDetailCommand = new DelegateCommand(AddSplitDetailRow);
|
||||
RemoveSplitDetailCommand = new DelegateCommand<RawMaterialSplitDetailItem>(RemoveSplitDetailRow);
|
||||
OpenMaterialPickerCommand = new DelegateCommand(async () => await OpenMaterialPickerAsync());
|
||||
ClearMaterialCommand = new DelegateCommand(ClearMaterialSelection);
|
||||
OpenWeightRecordPickerCommand = new DelegateCommand(async () => await OpenWeightRecordPickerAsync());
|
||||
ClearWeightRecordCommand = new DelegateCommand(ClearWeightRecordSelection);
|
||||
SplitCodeDetails.CollectionChanged += (_, _) => RaisePropertyChanged(nameof(SplitCodeTableHeight));
|
||||
_ = LoadAllAsync();
|
||||
}
|
||||
|
||||
@@ -148,8 +221,13 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
new KeyValuePair<string, string>("是", "1"),
|
||||
});
|
||||
PopulateOptions(StatusOptions, statusOpts, Array.Empty<KeyValuePair<string, string>>());
|
||||
ApplyDefaultEntryStatusForAdd();
|
||||
}
|
||||
catch
|
||||
{
|
||||
FillFallbackOptions();
|
||||
ApplyDefaultEntryStatusForAdd();
|
||||
}
|
||||
catch { FillFallbackOptions(); }
|
||||
}
|
||||
|
||||
private static void PopulateOptions(
|
||||
@@ -206,13 +284,20 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
{
|
||||
_selectedMaterial = null;
|
||||
RaisePropertyChanged(nameof(SelectedMaterial));
|
||||
RaisePropertyChanged(nameof(SelectedMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterial));
|
||||
Entry = new MesXslRawMaterialEntry
|
||||
{
|
||||
TestResult = "0", TestStatus = "0", PrintFlag = "0",
|
||||
StockBalance = "0", IsSpecialAdoption = "0"
|
||||
EntryTime = DateTime.Now,
|
||||
IsSpecialAdoption = "0"
|
||||
};
|
||||
InitializeSplitCodeDetailsFromEntry();
|
||||
ApplyDefaultEntryStatusForAdd();
|
||||
RaisePropertyChanged(nameof(IsAddMode));
|
||||
RaisePropertyChanged(nameof(DialogTitle));
|
||||
RaisePropertyChanged(nameof(TotalWeightInput));
|
||||
RaisePropertyChanged(nameof(TotalPortionsInput));
|
||||
RaisePropertyChanged(nameof(IsSpecialAdoptionValue));
|
||||
}
|
||||
|
||||
public void InitializeForEdit(MesXslRawMaterialEntry entry)
|
||||
@@ -233,6 +318,7 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
SpecialAdoptionReason = entry.SpecialAdoptionReason, Status = entry.Status, Remark = entry.Remark,
|
||||
TenantId = entry.TenantId,
|
||||
};
|
||||
InitializeSplitCodeDetailsFromEntry();
|
||||
|
||||
// 若物料列表已加载则直接回填,否则记录 pending 等加载完后回填
|
||||
if (MaterialOptions.Count > 0)
|
||||
@@ -240,6 +326,8 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
_selectedMaterial = MaterialOptions.FirstOrDefault(m =>
|
||||
string.Equals(m.Id, entry.MaterialId, StringComparison.OrdinalIgnoreCase));
|
||||
RaisePropertyChanged(nameof(SelectedMaterial));
|
||||
RaisePropertyChanged(nameof(SelectedMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterial));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -248,6 +336,9 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
|
||||
RaisePropertyChanged(nameof(IsAddMode));
|
||||
RaisePropertyChanged(nameof(DialogTitle));
|
||||
RaisePropertyChanged(nameof(TotalWeightInput));
|
||||
RaisePropertyChanged(nameof(TotalPortionsInput));
|
||||
RaisePropertyChanged(nameof(IsSpecialAdoptionValue));
|
||||
}
|
||||
|
||||
private async Task SaveAsync()
|
||||
@@ -255,6 +346,8 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
if (Entry == null) return;
|
||||
try
|
||||
{
|
||||
ApplyFirstSplitDetailToEntry();
|
||||
RecalculatePortionWeight();
|
||||
bool ok;
|
||||
if (IsAddMode)
|
||||
{
|
||||
@@ -268,6 +361,13 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
if (!ok) { HandyControl.Controls.MessageBox.Error("编辑失败!"); return; }
|
||||
}
|
||||
Result = ok;
|
||||
if (IsAddMode && CloseAction == null)
|
||||
{
|
||||
// 独立新增页面:保存成功后自动清空表单,便于连续录入
|
||||
InitializeForAdd();
|
||||
return;
|
||||
}
|
||||
|
||||
CloseAction?.Invoke();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -275,4 +375,232 @@ public class RawMaterialEntryEditDialogViewModel : BaseViewModel, IDialogResulta
|
||||
HandyControl.Controls.MessageBox.Error($"操作失败:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OpenWeightRecordPickerAsync()
|
||||
{
|
||||
WeightRecordPickerDialogViewModel? pickerVm = null;
|
||||
bool confirmed;
|
||||
try
|
||||
{
|
||||
confirmed = await HandyControl.Controls.Dialog.Show<WeightRecordPickerDialogView>()
|
||||
.Initialize<WeightRecordPickerDialogViewModel>(vm =>
|
||||
{
|
||||
pickerVm = vm;
|
||||
vm.Initialize(Entry?.BillNo);
|
||||
})
|
||||
.GetResultAsync<bool>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirmed || pickerVm?.SelectedRecord == null || Entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = pickerVm.SelectedRecord;
|
||||
Entry.WeightRecordId = selected.Id;
|
||||
Entry.BillNo = selected.BillNo;
|
||||
Entry.SupplierName = selected.SenderUnit;
|
||||
Entry.SupplierId = null;
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
}
|
||||
|
||||
private async Task OpenMaterialPickerAsync()
|
||||
{
|
||||
RawMaterialEntryMaterialPickerDialogViewModel? pickerVm = null;
|
||||
bool confirmed;
|
||||
try
|
||||
{
|
||||
confirmed = await HandyControl.Controls.Dialog.Show<RawMaterialEntryMaterialPickerDialogView>()
|
||||
.Initialize<RawMaterialEntryMaterialPickerDialogViewModel>(vm =>
|
||||
{
|
||||
pickerVm = vm;
|
||||
vm.Initialize(Entry?.MaterialCode, Entry?.MaterialName);
|
||||
})
|
||||
.GetResultAsync<bool>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirmed || pickerVm?.SelectedMaterial == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SelectedMaterial = pickerVm.SelectedMaterial;
|
||||
}
|
||||
|
||||
private void ClearMaterialSelection()
|
||||
{
|
||||
_selectedMaterial = null;
|
||||
RaisePropertyChanged(nameof(SelectedMaterial));
|
||||
RaisePropertyChanged(nameof(SelectedMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterial));
|
||||
|
||||
if (Entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry.MaterialId = null;
|
||||
Entry.MaterialCode = null;
|
||||
Entry.MaterialName = null;
|
||||
Entry.ManufacturerMaterialName = null;
|
||||
Entry.ShelfLife = null;
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
}
|
||||
|
||||
private void ClearWeightRecordSelection()
|
||||
{
|
||||
if (Entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry.WeightRecordId = null;
|
||||
Entry.BillNo = null;
|
||||
Entry.SupplierId = null;
|
||||
Entry.SupplierName = null;
|
||||
RaisePropertyChanged(nameof(Entry));
|
||||
}
|
||||
|
||||
private void RecalculateShelfLife(MesMixerMaterial? material)
|
||||
{
|
||||
if (Entry == null || material?.ShelfLifeDays == null || material.ShelfLifeDays <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry.ShelfLife = DateTime.Now.Date.AddDays(material.ShelfLifeDays.Value).ToString("yyyy-MM-dd");
|
||||
}
|
||||
|
||||
private void RecalculatePortionWeight()
|
||||
{
|
||||
if (Entry == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Entry.TotalWeight.HasValue && Entry.TotalPortions.HasValue && Entry.TotalPortions.Value > 0)
|
||||
{
|
||||
Entry.PortionWeight = Math.Round(Entry.TotalWeight.Value / Entry.TotalPortions.Value, 2, MidpointRounding.AwayFromZero);
|
||||
return;
|
||||
}
|
||||
|
||||
Entry.PortionWeight = null;
|
||||
}
|
||||
|
||||
private void ApplyDefaultEntryStatusForAdd()
|
||||
{
|
||||
if (!IsAddMode || Entry == null || !string.IsNullOrWhiteSpace(Entry.Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pending = StatusOptions.FirstOrDefault(x =>
|
||||
string.Equals(x.Key?.Trim(), "待处理", StringComparison.OrdinalIgnoreCase));
|
||||
if (!string.IsNullOrWhiteSpace(pending.Value))
|
||||
{
|
||||
Entry.Status = pending.Value;
|
||||
return;
|
||||
}
|
||||
|
||||
// 字典未就绪时使用常见默认值
|
||||
Entry.Status = "0";
|
||||
}
|
||||
|
||||
private void InitializeSplitCodeDetailsFromEntry()
|
||||
{
|
||||
SplitCodeDetails.Clear();
|
||||
SplitCodeDetails.Add(new RawMaterialSplitDetailItem
|
||||
{
|
||||
Portions = Entry?.TotalPortions,
|
||||
PortionWeight = Entry?.PortionWeight,
|
||||
PortionPackages = Entry?.PortionPackages,
|
||||
WarehouseLocation = Entry?.WarehouseLocation
|
||||
});
|
||||
RaisePropertyChanged(nameof(SplitCodeTableHeight));
|
||||
}
|
||||
|
||||
private void AddSplitDetailRow()
|
||||
{
|
||||
SplitCodeDetails.Add(new RawMaterialSplitDetailItem());
|
||||
RaisePropertyChanged(nameof(SplitCodeTableHeight));
|
||||
}
|
||||
|
||||
private void RemoveSplitDetailRow(RawMaterialSplitDetailItem? item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SplitCodeDetails.Remove(item);
|
||||
if (SplitCodeDetails.Count == 0)
|
||||
{
|
||||
SplitCodeDetails.Add(new RawMaterialSplitDetailItem());
|
||||
}
|
||||
RaisePropertyChanged(nameof(SplitCodeTableHeight));
|
||||
}
|
||||
|
||||
private void ApplyFirstSplitDetailToEntry()
|
||||
{
|
||||
if (Entry == null || SplitCodeDetails.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var first = SplitCodeDetails[0];
|
||||
Entry.TotalPortions = first.Portions;
|
||||
Entry.PortionWeight = first.PortionWeight;
|
||||
Entry.PortionPackages = first.PortionPackages;
|
||||
Entry.WarehouseLocation = first.WarehouseLocation;
|
||||
}
|
||||
|
||||
private double CalculateSplitCodeTableHeight()
|
||||
{
|
||||
const double headerHeight = 36d;
|
||||
const double rowHeight = 36d;
|
||||
const double framePadding = 16d;
|
||||
const double minRows = 1d;
|
||||
const double maxRows = 6d;
|
||||
var rowCount = Math.Clamp(SplitCodeDetails.Count, (int)minRows, (int)maxRows);
|
||||
return headerHeight + rowCount * rowHeight + framePadding;
|
||||
}
|
||||
}
|
||||
|
||||
public class RawMaterialSplitDetailItem : BindableBase
|
||||
{
|
||||
private int? _portions;
|
||||
public int? Portions
|
||||
{
|
||||
get => _portions;
|
||||
set => SetProperty(ref _portions, value);
|
||||
}
|
||||
|
||||
private double? _portionWeight;
|
||||
public double? PortionWeight
|
||||
{
|
||||
get => _portionWeight;
|
||||
set => SetProperty(ref _portionWeight, value);
|
||||
}
|
||||
|
||||
private int? _portionPackages;
|
||||
public int? PortionPackages
|
||||
{
|
||||
get => _portionPackages;
|
||||
set => SetProperty(ref _portionPackages, value);
|
||||
}
|
||||
|
||||
private string? _warehouseLocation;
|
||||
public string? WarehouseLocation
|
||||
{
|
||||
get => _warehouseLocation;
|
||||
set => SetProperty(ref _warehouseLocation, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ using YY.Admin.Core.Events;
|
||||
using YY.Admin.Core.Helper;
|
||||
using YY.Admin.Core.Entity;
|
||||
using YY.Admin.Core.Services;
|
||||
using YY.Admin.Event;
|
||||
using YY.Admin.Services.Service;
|
||||
using YY.Admin.Module;
|
||||
using YY.Admin.Views.RawMaterialEntry;
|
||||
|
||||
namespace YY.Admin.ViewModels.RawMaterialEntry;
|
||||
@@ -77,7 +79,7 @@ public class RawMaterialEntryListViewModel : BaseViewModel
|
||||
PageNo = 1;
|
||||
await LoadAsync();
|
||||
});
|
||||
AddCommand = new DelegateCommand(async () => await ShowAddDialogAsync());
|
||||
AddCommand = new DelegateCommand(OpenAddPage);
|
||||
EditCommand = new DelegateCommand<MesXslRawMaterialEntry>(async e => await ShowEditDialogAsync(e));
|
||||
DeleteCommand = new DelegateCommand<MesXslRawMaterialEntry>(async e => await DeleteAsync(e));
|
||||
PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } });
|
||||
@@ -149,16 +151,14 @@ public class RawMaterialEntryListViewModel : BaseViewModel
|
||||
finally { IsLoading = false; }
|
||||
}
|
||||
|
||||
private async Task ShowAddDialogAsync()
|
||||
private void OpenAddPage()
|
||||
{
|
||||
try
|
||||
_eventAggregator.GetEvent<TabSourceSelectedEvent>().Publish(new TabSource
|
||||
{
|
||||
var result = await HandyControl.Controls.Dialog.Show<RawMaterialEntryEditDialogView>()
|
||||
.Initialize<RawMaterialEntryEditDialogViewModel>(vm => vm.InitializeForAdd())
|
||||
.GetResultAsync<bool>();
|
||||
if (result) await LoadAsync();
|
||||
}
|
||||
catch (Exception ex) { Growl.Error($"打开新增对话框失败:{ex.Message}"); }
|
||||
Name = "新增原料入场记录",
|
||||
Icon = "\ue7ce",
|
||||
ViewName = "RawMaterialEntryOperationView"
|
||||
});
|
||||
}
|
||||
|
||||
private async Task ShowEditDialogAsync(MesXslRawMaterialEntry entry)
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
using HandyControl.Tools.Extension;
|
||||
using System.Collections.ObjectModel;
|
||||
using YY.Admin.Core;
|
||||
using YY.Admin.Core.Entity;
|
||||
using YY.Admin.Core.Services;
|
||||
|
||||
namespace YY.Admin.ViewModels.RawMaterialEntry;
|
||||
|
||||
public class RawMaterialEntryMaterialPickerDialogViewModel : BaseViewModel, IDialogResultable<bool>
|
||||
{
|
||||
private readonly IMixerMaterialService _mixerMaterialService;
|
||||
|
||||
private string? _searchCode;
|
||||
public string? SearchCode
|
||||
{
|
||||
get => _searchCode;
|
||||
set => SetProperty(ref _searchCode, value);
|
||||
}
|
||||
|
||||
private string? _searchName;
|
||||
public string? SearchName
|
||||
{
|
||||
get => _searchName;
|
||||
set => SetProperty(ref _searchName, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<MesMixerMaterial> Materials { get; } = new();
|
||||
|
||||
private MesMixerMaterial? _selectedMaterial;
|
||||
public MesMixerMaterial? SelectedMaterial
|
||||
{
|
||||
get => _selectedMaterial;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _selectedMaterial, value);
|
||||
ConfirmCommand.RaiseCanExecuteChanged();
|
||||
RaisePropertyChanged(nameof(SelectedMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterial));
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedMaterialDisplay => _selectedMaterial != null
|
||||
? $"[{_selectedMaterial.MaterialCode}] {_selectedMaterial.MaterialName}"
|
||||
: "选中密炼物料后点击「确认选择」";
|
||||
|
||||
public bool HasSelectedMaterial => _selectedMaterial != null;
|
||||
|
||||
private bool _result;
|
||||
public bool Result
|
||||
{
|
||||
get => _result;
|
||||
set => SetProperty(ref _result, value);
|
||||
}
|
||||
|
||||
public Action? CloseAction { get; set; }
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ConfirmCommand { get; }
|
||||
public DelegateCommand CancelCommand { get; }
|
||||
|
||||
public RawMaterialEntryMaterialPickerDialogViewModel(
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_mixerMaterialService = mixerMaterialService;
|
||||
SearchCommand = new DelegateCommand(async () => await LoadAsync());
|
||||
ConfirmCommand = new DelegateCommand(Confirm, () => SelectedMaterial != null);
|
||||
CancelCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||
_ = LoadAsync();
|
||||
}
|
||||
|
||||
public void Initialize(string? materialCode, string? materialName)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(materialCode))
|
||||
{
|
||||
SearchCode = materialCode.Trim();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(materialName))
|
||||
{
|
||||
SearchName = materialName.Trim();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
var result = await _mixerMaterialService.PageAsync(
|
||||
1,
|
||||
500,
|
||||
materialCode: SearchCode?.Trim(),
|
||||
materialName: SearchName?.Trim());
|
||||
|
||||
Materials.Clear();
|
||||
foreach (var item in result.Records)
|
||||
{
|
||||
Materials.Add(item);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(SearchCode))
|
||||
{
|
||||
SelectedMaterial = Materials.FirstOrDefault(x =>
|
||||
string.Equals(x.MaterialCode, SearchCode, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Materials.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Confirm()
|
||||
{
|
||||
if (SelectedMaterial == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result = true;
|
||||
CloseAction?.Invoke();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using YY.Admin.Core.Services;
|
||||
using YY.Admin.Services.Service;
|
||||
|
||||
namespace YY.Admin.ViewModels.RawMaterialEntry;
|
||||
|
||||
public class RawMaterialEntryOperationViewModel : RawMaterialEntryEditDialogViewModel
|
||||
{
|
||||
public RawMaterialEntryOperationViewModel(
|
||||
IRawMaterialEntryService entryService,
|
||||
IJeecgDictSyncService dictSyncService,
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager)
|
||||
: base(entryService, dictSyncService, mixerMaterialService, container, regionManager)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using HandyControl.Tools.Extension;
|
||||
using System.Collections.ObjectModel;
|
||||
using YY.Admin.Core;
|
||||
using YY.Admin.Core.Entity;
|
||||
using YY.Admin.Core.Services;
|
||||
|
||||
namespace YY.Admin.ViewModels.RawMaterialEntry;
|
||||
|
||||
public class WeightRecordPickerDialogViewModel : BaseViewModel, IDialogResultable<bool>
|
||||
{
|
||||
private readonly IWeightRecordService _weightRecordService;
|
||||
|
||||
private string? _searchBillNo;
|
||||
public string? SearchBillNo
|
||||
{
|
||||
get => _searchBillNo;
|
||||
set => SetProperty(ref _searchBillNo, value);
|
||||
}
|
||||
|
||||
private string? _searchPlateNumber;
|
||||
public string? SearchPlateNumber
|
||||
{
|
||||
get => _searchPlateNumber;
|
||||
set => SetProperty(ref _searchPlateNumber, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<MesXslWeightRecord> Records { get; } = new();
|
||||
|
||||
private MesXslWeightRecord? _selectedRecord;
|
||||
public MesXslWeightRecord? SelectedRecord
|
||||
{
|
||||
get => _selectedRecord;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _selectedRecord, value);
|
||||
ConfirmCommand.RaiseCanExecuteChanged();
|
||||
RaisePropertyChanged(nameof(SelectedRecordDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedRecord));
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedRecordDisplay => _selectedRecord != null
|
||||
? $"[{_selectedRecord.BillNo}] 供应商:{_selectedRecord.SenderUnit ?? "-"}"
|
||||
: "选中榜单后点击「确认选择」";
|
||||
|
||||
public bool HasSelectedRecord => _selectedRecord != null;
|
||||
|
||||
private bool _result;
|
||||
public bool Result
|
||||
{
|
||||
get => _result;
|
||||
set => SetProperty(ref _result, value);
|
||||
}
|
||||
|
||||
public Action? CloseAction { get; set; }
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ConfirmCommand { get; }
|
||||
public DelegateCommand CancelCommand { get; }
|
||||
|
||||
public WeightRecordPickerDialogViewModel(
|
||||
IWeightRecordService weightRecordService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_weightRecordService = weightRecordService;
|
||||
SearchCommand = new DelegateCommand(async () => await LoadAsync());
|
||||
ConfirmCommand = new DelegateCommand(Confirm, () => SelectedRecord != null);
|
||||
CancelCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||
_ = LoadAsync();
|
||||
}
|
||||
|
||||
public void Initialize(string? billNo)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(billNo))
|
||||
{
|
||||
SearchBillNo = billNo.Trim();
|
||||
_ = LoadAsync();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
var result = await _weightRecordService.PageAsync(
|
||||
1,
|
||||
200,
|
||||
filterBillNo: SearchBillNo?.Trim(),
|
||||
filterPlateNumber: SearchPlateNumber?.Trim(),
|
||||
filterInoutDirection: "1");
|
||||
|
||||
Records.Clear();
|
||||
foreach (var record in result.Records)
|
||||
{
|
||||
Records.Add(record);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(SearchBillNo))
|
||||
{
|
||||
SelectedRecord = Records.FirstOrDefault(x =>
|
||||
string.Equals(x.BillNo, SearchBillNo, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Records.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Confirm()
|
||||
{
|
||||
if (SelectedRecord == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result = true;
|
||||
CloseAction?.Invoke();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user