新增物料类型处理逻辑,确保在保存和编辑称重记录时自动设置默认物料类型。更新前端表单以支持密炼物料的选择和显示,优化用户体验。添加分类字典和数据字典的事件广播功能,增强系统的实时数据同步能力。
This commit is contained in:
@@ -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.WeightRecord;
|
||||
|
||||
public class MixerMaterialPickerDialogViewModel : 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<SelectableMixerMaterial> Materials { get; } = new();
|
||||
|
||||
public IReadOnlyList<SelectableMixerMaterial> SelectedMaterials =>
|
||||
Materials.Where(m => m.IsSelected).ToList();
|
||||
|
||||
public int SelectedCount => Materials.Count(m => m.IsSelected);
|
||||
|
||||
public string SelectedDisplayText
|
||||
{
|
||||
get
|
||||
{
|
||||
var names = Materials.Where(m => m.IsSelected).Select(m => m.Source.MaterialName).ToList();
|
||||
return names.Count == 0 ? "请在上方列表中勾选物料,可多选" : string.Join(";", names);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSelectedMaterials => Materials.Any(m => m.IsSelected);
|
||||
|
||||
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 DelegateCommand ClearSelectionCommand { get; }
|
||||
|
||||
public MixerMaterialPickerDialogViewModel(
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_mixerMaterialService = mixerMaterialService;
|
||||
SearchCommand = new DelegateCommand(async () => await LoadAsync());
|
||||
ConfirmCommand = new DelegateCommand(Confirm, () => HasSelectedMaterials);
|
||||
CancelCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||
ClearSelectionCommand = new DelegateCommand(ClearSelection);
|
||||
_ = LoadAsync();
|
||||
}
|
||||
|
||||
private async Task LoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
var selectedIds = Materials.Where(m => m.IsSelected).Select(m => m.Source.Id).ToHashSet();
|
||||
var result = await _mixerMaterialService.PageAsync(1, 500,
|
||||
materialCode: SearchCode?.Trim(),
|
||||
materialName: SearchName?.Trim());
|
||||
Materials.Clear();
|
||||
foreach (var mat in result.Records)
|
||||
{
|
||||
var item = new SelectableMixerMaterial(mat);
|
||||
if (selectedIds.Contains(mat.Id)) item.IsSelected = true;
|
||||
item.SelectionChanged += NotifySelectionChanged;
|
||||
Materials.Add(item);
|
||||
}
|
||||
NotifySelectionChanged();
|
||||
}
|
||||
catch
|
||||
{
|
||||
Materials.Clear();
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void NotifySelectionChanged()
|
||||
{
|
||||
RaisePropertyChanged(nameof(SelectedCount));
|
||||
RaisePropertyChanged(nameof(SelectedDisplayText));
|
||||
RaisePropertyChanged(nameof(HasSelectedMaterials));
|
||||
ConfirmCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private void ClearSelection()
|
||||
{
|
||||
foreach (var m in Materials) m.IsSelected = false;
|
||||
}
|
||||
|
||||
private void Confirm()
|
||||
{
|
||||
if (!HasSelectedMaterials) return;
|
||||
Result = true;
|
||||
CloseAction?.Invoke();
|
||||
}
|
||||
|
||||
public class SelectableMixerMaterial : System.ComponentModel.INotifyPropertyChanged
|
||||
{
|
||||
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
|
||||
public event Action? SelectionChanged;
|
||||
|
||||
private bool _isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set
|
||||
{
|
||||
if (_isSelected == value) return;
|
||||
_isSelected = value;
|
||||
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(nameof(IsSelected)));
|
||||
SelectionChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public MesMixerMaterial Source { get; }
|
||||
public SelectableMixerMaterial(MesMixerMaterial source) => Source = source;
|
||||
}
|
||||
}
|
||||
@@ -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.WeightRecord;
|
||||
|
||||
namespace YY.Admin.ViewModels.WeightRecord;
|
||||
|
||||
@@ -12,6 +13,16 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable<
|
||||
{
|
||||
private readonly IWeightRecordService _weightRecordService;
|
||||
private readonly IJeecgDictSyncService _dictSyncService;
|
||||
private readonly IMixerMaterialService _mixerMaterialService;
|
||||
|
||||
private string? _mixerMaterialIds;
|
||||
private string? _mixerMaterialNames;
|
||||
|
||||
public string MixerMaterialDisplay => !string.IsNullOrWhiteSpace(_mixerMaterialNames)
|
||||
? _mixerMaterialNames
|
||||
: "点击右侧「选择」选取密炼物料(可多选)";
|
||||
|
||||
public bool HasSelectedMixerMaterials => !string.IsNullOrWhiteSpace(_mixerMaterialNames);
|
||||
|
||||
private MesXslWeightRecord? _record;
|
||||
public MesXslWeightRecord? Record
|
||||
@@ -31,20 +42,56 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable<
|
||||
|
||||
public DelegateCommand SaveCommand { get; }
|
||||
public DelegateCommand CancelCommand { get; }
|
||||
public DelegateCommand OpenMixerMaterialPickerCommand { get; }
|
||||
public DelegateCommand ClearMixerMaterialCommand { get; }
|
||||
|
||||
public WeightRecordEditDialogViewModel(
|
||||
IWeightRecordService weightRecordService,
|
||||
IJeecgDictSyncService dictSyncService,
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_weightRecordService = weightRecordService;
|
||||
_dictSyncService = dictSyncService;
|
||||
_mixerMaterialService = mixerMaterialService;
|
||||
SaveCommand = new DelegateCommand(async () => await SaveAsync());
|
||||
CancelCommand = new DelegateCommand(() => CloseAction?.Invoke());
|
||||
OpenMixerMaterialPickerCommand = new DelegateCommand(async () => await OpenMixerMaterialPickerAsync());
|
||||
ClearMixerMaterialCommand = new DelegateCommand(ClearMixerMaterialSelection);
|
||||
_ = LoadDictOptionsAsync();
|
||||
}
|
||||
|
||||
private async Task OpenMixerMaterialPickerAsync()
|
||||
{
|
||||
MixerMaterialPickerDialogViewModel? pickerVm = null;
|
||||
bool confirmed;
|
||||
try
|
||||
{
|
||||
confirmed = await HandyControl.Controls.Dialog.Show<MixerMaterialPickerDialogView>()
|
||||
.Initialize<MixerMaterialPickerDialogViewModel>(vm => { pickerVm = vm; })
|
||||
.GetResultAsync<bool>();
|
||||
}
|
||||
catch { return; }
|
||||
|
||||
if (!confirmed || pickerVm == null) return;
|
||||
var selected = pickerVm.SelectedMaterials;
|
||||
if (selected.Count == 0) return;
|
||||
|
||||
_mixerMaterialIds = string.Join(";", selected.Select(m => m.Source.Id ?? ""));
|
||||
_mixerMaterialNames = string.Join(";", selected.Select(m => m.Source.MaterialName ?? ""));
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
}
|
||||
|
||||
private void ClearMixerMaterialSelection()
|
||||
{
|
||||
_mixerMaterialIds = null;
|
||||
_mixerMaterialNames = null;
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
}
|
||||
|
||||
private async Task LoadDictOptionsAsync()
|
||||
{
|
||||
try
|
||||
@@ -69,7 +116,8 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable<
|
||||
Record = new MesXslWeightRecord
|
||||
{
|
||||
WeighDate = DateTime.Today,
|
||||
InoutDirection = "1"
|
||||
InoutDirection = "1",
|
||||
MaterialType = "1"
|
||||
};
|
||||
RaisePropertyChanged(nameof(IsAddMode));
|
||||
RaisePropertyChanged(nameof(DialogTitle));
|
||||
@@ -87,16 +135,20 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable<
|
||||
PlateNumber = record.PlateNumber,
|
||||
SenderUnit = record.SenderUnit,
|
||||
ReceiverUnit = record.ReceiverUnit,
|
||||
GoodsName = record.GoodsName,
|
||||
GrossWeight = record.GrossWeight,
|
||||
TareWeight = record.TareWeight,
|
||||
NetWeight = record.NetWeight,
|
||||
DriverName = record.DriverName,
|
||||
DriverPhone = record.DriverPhone,
|
||||
BillType = record.BillType,
|
||||
MaterialType = record.MaterialType,
|
||||
TenantId = record.TenantId,
|
||||
UpdateTime = record.UpdateTime
|
||||
};
|
||||
_mixerMaterialIds = record.MixerMaterialIds;
|
||||
_mixerMaterialNames = record.MixerMaterialNames;
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
RaisePropertyChanged(nameof(IsAddMode));
|
||||
RaisePropertyChanged(nameof(DialogTitle));
|
||||
}
|
||||
@@ -120,6 +172,12 @@ public class WeightRecordEditDialogViewModel : BaseViewModel, IDialogResultable<
|
||||
if (Record.GrossWeight.HasValue && Record.TareWeight.HasValue)
|
||||
Record.NetWeight = Math.Round(Record.GrossWeight.Value - Record.TareWeight.Value, 2);
|
||||
|
||||
// 写入密炼物料
|
||||
Record.MixerMaterialIds = _mixerMaterialIds;
|
||||
Record.MixerMaterialNames = _mixerMaterialNames;
|
||||
if (string.IsNullOrWhiteSpace(Record.MaterialType))
|
||||
Record.MaterialType = "1";
|
||||
|
||||
try
|
||||
{
|
||||
bool ok;
|
||||
|
||||
@@ -47,14 +47,15 @@ public class WeightRecordListViewModel : BaseViewModel
|
||||
private string? _filterInoutDirection;
|
||||
public string? FilterInoutDirection { get => _filterInoutDirection; set => SetProperty(ref _filterInoutDirection, value); }
|
||||
|
||||
private string? _filterGoodsName;
|
||||
public string? FilterGoodsName { get => _filterGoodsName; set => SetProperty(ref _filterGoodsName, value); }
|
||||
|
||||
private string? _filterDriverName;
|
||||
public string? FilterDriverName { get => _filterDriverName; set => SetProperty(ref _filterDriverName, value); }
|
||||
|
||||
private string? _filterMixerMaterialName;
|
||||
public string? FilterMixerMaterialName { get => _filterMixerMaterialName; set => SetProperty(ref _filterMixerMaterialName, value); }
|
||||
|
||||
public ObservableCollection<KeyValuePair<string, string>> InoutDirectionOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> BillTypeOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> MaterialTypeOptions { get; } = new();
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
@@ -79,7 +80,7 @@ public class WeightRecordListViewModel : BaseViewModel
|
||||
ResetCommand = new DelegateCommand(async () =>
|
||||
{
|
||||
FilterBillNo = null; FilterPlateNumber = null; FilterInoutDirection = null;
|
||||
FilterGoodsName = null; FilterDriverName = null;
|
||||
FilterDriverName = null; FilterMixerMaterialName = null;
|
||||
PageNo = 1;
|
||||
await LoadAsync();
|
||||
});
|
||||
@@ -133,6 +134,11 @@ public class WeightRecordListViewModel : BaseViewModel
|
||||
BillTypeOptions.Clear();
|
||||
foreach (var item in billTypeOptions) BillTypeOptions.Add(item);
|
||||
if (BillTypeOptions.Count == 0) AddDefaultBillTypeOptions();
|
||||
|
||||
var materialTypeOptions = await _dictSyncService.GetDictOptionsAsync("xslmes_weight_material_type", includeAll: true);
|
||||
MaterialTypeOptions.Clear();
|
||||
foreach (var item in materialTypeOptions) MaterialTypeOptions.Add(item);
|
||||
if (MaterialTypeOptions.Count == 0) AddDefaultMaterialTypeOptions();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -141,6 +147,7 @@ public class WeightRecordListViewModel : BaseViewModel
|
||||
InoutDirectionOptions.Add(new KeyValuePair<string, string>("进厂", "1"));
|
||||
InoutDirectionOptions.Add(new KeyValuePair<string, string>("出厂", "2"));
|
||||
AddDefaultBillTypeOptions();
|
||||
AddDefaultMaterialTypeOptions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,21 +160,31 @@ public class WeightRecordListViewModel : BaseViewModel
|
||||
BillTypeOptions.Add(new KeyValuePair<string, string>("已称皮重", "3"));
|
||||
}
|
||||
|
||||
private void AddDefaultMaterialTypeOptions()
|
||||
{
|
||||
MaterialTypeOptions.Clear();
|
||||
MaterialTypeOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
||||
MaterialTypeOptions.Add(new KeyValuePair<string, string>("自动", "1"));
|
||||
MaterialTypeOptions.Add(new KeyValuePair<string, string>("手动", "2"));
|
||||
}
|
||||
|
||||
public async Task LoadAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
IsLoading = true;
|
||||
var result = await _weightRecordService.PageAsync(
|
||||
PageNo, PageSize, FilterBillNo, FilterPlateNumber, FilterInoutDirection, FilterGoodsName, FilterDriverName);
|
||||
PageNo, PageSize, FilterBillNo, FilterPlateNumber, FilterInoutDirection, filterDriverName: FilterDriverName, filterMixerMaterialName: FilterMixerMaterialName);
|
||||
|
||||
// 填充字典显示文本
|
||||
var dictMap = InoutDirectionOptions.ToDictionary(x => x.Value, x => x.Key);
|
||||
var billTypeMap = BillTypeOptions.ToDictionary(x => x.Value, x => x.Key);
|
||||
var materialTypeMap = MaterialTypeOptions.ToDictionary(x => x.Value, x => x.Key);
|
||||
foreach (var r in result.Records)
|
||||
{
|
||||
r.InoutDirectionText = dictMap.TryGetValue(r.InoutDirection ?? "", out var txt) ? txt : r.InoutDirection ?? "";
|
||||
r.BillTypeText = billTypeMap.TryGetValue(r.BillType ?? "", out var billTypeTxt) ? billTypeTxt : r.BillType ?? "";
|
||||
r.MaterialTypeText = materialTypeMap.TryGetValue(r.MaterialType ?? "", out var materialTypeTxt) ? materialTypeTxt : r.MaterialType ?? "";
|
||||
}
|
||||
|
||||
Records = new ObservableCollection<MesXslWeightRecord>(result.Records);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using HandyControl.Controls;
|
||||
using HandyControl.Tools.Extension;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Windows.Threading;
|
||||
using YY.Admin.Core;
|
||||
using YY.Admin.Core.Entity;
|
||||
@@ -19,6 +21,8 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
private readonly IWeightRecordService _weightRecordService;
|
||||
private readonly IJeecgDictSyncService _dictSyncService;
|
||||
private readonly IVehicleService _vehicleService;
|
||||
private readonly IMixerMaterialService _mixerMaterialService;
|
||||
private readonly string _unitCacheFilePath;
|
||||
|
||||
// ─── 车辆档案匹配 ───
|
||||
private MesXslVehicle? _matchedVehicle;
|
||||
@@ -115,6 +119,7 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
{
|
||||
ClearFormByDirectionSwitch();
|
||||
}
|
||||
TryApplyCachedUnitByDirection(value);
|
||||
_ = LoadRecentWeightRecordsAsync(PlateNumber);
|
||||
}
|
||||
}
|
||||
@@ -142,6 +147,8 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
|
||||
private MesXslSupplier? _selectedSupplier;
|
||||
private MesXslCustomer? _selectedCustomer;
|
||||
private string? _cachedInboundReceiverUnit;
|
||||
private string? _cachedOutboundSenderUnit;
|
||||
|
||||
public bool HasSelectedSupplier => _selectedSupplier != null;
|
||||
public bool HasSelectedCustomer => _selectedCustomer != null;
|
||||
@@ -176,8 +183,52 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private string? _goodsName;
|
||||
public string? GoodsName { get => _goodsName; set => SetProperty(ref _goodsName, value); }
|
||||
// ─── 密炼物料选择 ───
|
||||
|
||||
private string? _mixerMaterialIds;
|
||||
private string? _mixerMaterialNames;
|
||||
private bool _isMixerMaterialManual;
|
||||
|
||||
public bool IsMixerMaterialManual
|
||||
{
|
||||
get => _isMixerMaterialManual;
|
||||
set
|
||||
{
|
||||
if (!SetProperty(ref _isMixerMaterialManual, value)) return;
|
||||
// 切换为手动填写时,清空 ID,避免保存时出现“名称手填 + ID遗留”不一致
|
||||
if (value)
|
||||
{
|
||||
_mixerMaterialIds = null;
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
}
|
||||
RaisePropertyChanged(nameof(IsMixerMaterialReadOnly));
|
||||
OpenMixerMaterialPickerCommand.RaiseCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsMixerMaterialReadOnly => !IsMixerMaterialManual;
|
||||
|
||||
public string? MixerMaterialNames
|
||||
{
|
||||
get => _mixerMaterialNames;
|
||||
set
|
||||
{
|
||||
if (!SetProperty(ref _mixerMaterialNames, value)) return;
|
||||
// 手动填写时,名称由人工输入,ID 不再有效
|
||||
if (IsMixerMaterialManual)
|
||||
{
|
||||
_mixerMaterialIds = null;
|
||||
}
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
}
|
||||
}
|
||||
|
||||
public string MixerMaterialDisplay => !string.IsNullOrWhiteSpace(_mixerMaterialNames)
|
||||
? _mixerMaterialNames
|
||||
: "点击右侧「选择」选取密炼物料(可多选)";
|
||||
|
||||
public bool HasSelectedMixerMaterials => !string.IsNullOrWhiteSpace(_mixerMaterialNames);
|
||||
|
||||
private double? _grossWeight;
|
||||
public double? GrossWeight
|
||||
@@ -234,19 +285,30 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
public DelegateCommand UseDetectedPlateCommand { get; }
|
||||
public DelegateCommand OpenSupplierPickerCommand { get; }
|
||||
public DelegateCommand OpenCustomerPickerCommand { get; }
|
||||
public DelegateCommand OpenMixerMaterialPickerCommand { get; }
|
||||
public DelegateCommand ClearSupplierCommand { get; }
|
||||
public DelegateCommand ClearCustomerCommand { get; }
|
||||
public DelegateCommand ClearMixerMaterialCommand { get; }
|
||||
|
||||
public WeightRecordOperationViewModel(
|
||||
IWeightRecordService weightRecordService,
|
||||
IJeecgDictSyncService dictSyncService,
|
||||
IVehicleService vehicleService,
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
IContainerExtension container,
|
||||
IRegionManager regionManager) : base(container, regionManager)
|
||||
{
|
||||
_weightRecordService = weightRecordService;
|
||||
_dictSyncService = dictSyncService;
|
||||
_vehicleService = vehicleService;
|
||||
_mixerMaterialService = mixerMaterialService;
|
||||
var cacheDir = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
|
||||
"YY.Admin",
|
||||
"cache");
|
||||
Directory.CreateDirectory(cacheDir);
|
||||
_unitCacheFilePath = Path.Combine(cacheDir, "weight-record-unit-cache.json");
|
||||
LoadUnitCache();
|
||||
|
||||
CaptureGrossWeightCommand = new DelegateCommand(CaptureGrossWeight, CanCaptureGrossWeight)
|
||||
.ObservesProperty(() => IsWeightStable)
|
||||
@@ -262,11 +324,15 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
.ObservesProperty(() => HasPlate);
|
||||
OpenSupplierPickerCommand = new DelegateCommand(async () => await OpenSupplierPickerAsync());
|
||||
OpenCustomerPickerCommand = new DelegateCommand(async () => await OpenCustomerPickerAsync());
|
||||
OpenMixerMaterialPickerCommand = new DelegateCommand(async () => await OpenMixerMaterialPickerAsync(), () => !IsMixerMaterialManual)
|
||||
.ObservesProperty(() => IsMixerMaterialManual);
|
||||
ClearSupplierCommand = new DelegateCommand(ClearSupplierSelection);
|
||||
ClearCustomerCommand = new DelegateCommand(ClearCustomerSelection);
|
||||
ClearMixerMaterialCommand = new DelegateCommand(ClearMixerMaterialSelection);
|
||||
|
||||
_ = LoadDictOptionsAsync();
|
||||
_ = LoadRecentWeightRecordsAsync(PlateNumber);
|
||||
TryApplyCachedUnitByDirection(InoutDirection);
|
||||
|
||||
// 启动串口模拟定时器(200ms 刷新一次,约 5Hz)
|
||||
_serialTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
|
||||
@@ -447,12 +513,15 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
PlateNumber = PlateNumber,
|
||||
SenderUnit = SenderUnit,
|
||||
ReceiverUnit = ReceiverUnit,
|
||||
GoodsName = GoodsName,
|
||||
GrossWeight = GrossWeight,
|
||||
TareWeight = TareWeight,
|
||||
NetWeight = NetWeight,
|
||||
DriverName = DriverName,
|
||||
DriverPhone = DriverPhone
|
||||
DriverPhone = DriverPhone,
|
||||
MixerMaterialIds = _mixerMaterialIds,
|
||||
MixerMaterialNames = _mixerMaterialNames,
|
||||
// 勾选“手动”=2;未勾选=1(自动)
|
||||
MaterialType = IsMixerMaterialManual ? "2" : "1"
|
||||
};
|
||||
|
||||
try
|
||||
@@ -462,6 +531,7 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
: await _weightRecordService.AddAsync(entity);
|
||||
if (ok)
|
||||
{
|
||||
CacheUnitByDirection();
|
||||
if (isCompleteSelectedRecord)
|
||||
{
|
||||
Growl.Success("皮重回填成功,单据已更新为称重完成!");
|
||||
@@ -482,11 +552,14 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
SelectedRecentWeightRecord = null;
|
||||
IsPlateNumberLocked = false;
|
||||
PlateNumber = null; DetectedPlate = string.Empty; HasPlate = false;
|
||||
SenderUnit = null; ReceiverUnit = null; GoodsName = null;
|
||||
SenderUnit = null; ReceiverUnit = null;
|
||||
DriverName = null; DriverPhone = null;
|
||||
ClearSupplierSelection();
|
||||
ClearCustomerSelection();
|
||||
ClearMixerMaterialSelection();
|
||||
ClearVehicleMatch();
|
||||
// 保存后立即按当前方向回填缓存,避免必须重进页面才显示
|
||||
TryApplyCachedUnitByDirection(InoutDirection);
|
||||
RaisePropertyChanged(nameof(NetWeightDisplay));
|
||||
}
|
||||
else
|
||||
@@ -511,7 +584,7 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
WeighDate = DateTime.Today;
|
||||
InoutDirection = "1";
|
||||
PlateNumber = null; SenderUnit = null; ReceiverUnit = null;
|
||||
GoodsName = null; GrossWeight = null; TareWeight = null; NetWeight = null;
|
||||
GrossWeight = null; TareWeight = null; NetWeight = null;
|
||||
DriverName = null; DriverPhone = null;
|
||||
GrossWeightCaptured = false; TareWeightCaptured = false;
|
||||
DetectedPlate = string.Empty; HasPlate = false;
|
||||
@@ -519,11 +592,123 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
IsPlateNumberLocked = false;
|
||||
ClearSupplierSelection();
|
||||
ClearCustomerSelection();
|
||||
ClearMixerMaterialSelection();
|
||||
ClearVehicleMatch();
|
||||
RaisePropertyChanged(nameof(NetWeightDisplay));
|
||||
AddLog("表单已清空");
|
||||
}
|
||||
|
||||
private void CacheUnitByDirection()
|
||||
{
|
||||
var changed = false;
|
||||
// 按需求:进厂缓存收货单位;出厂缓存发货单位
|
||||
if (string.Equals(InoutDirection, "1", StringComparison.Ordinal))
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(ReceiverUnit) && !string.Equals(_cachedInboundReceiverUnit, ReceiverUnit, StringComparison.Ordinal))
|
||||
{
|
||||
_cachedInboundReceiverUnit = ReceiverUnit;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else if (string.Equals(InoutDirection, "2", StringComparison.Ordinal)
|
||||
&& !string.IsNullOrWhiteSpace(SenderUnit)
|
||||
&& !string.Equals(_cachedOutboundSenderUnit, SenderUnit, StringComparison.Ordinal))
|
||||
{
|
||||
_cachedOutboundSenderUnit = SenderUnit;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
SaveUnitCache();
|
||||
}
|
||||
}
|
||||
|
||||
private void TryApplyCachedUnitByDirection(string? inoutDirection)
|
||||
{
|
||||
// 切换方向时动态切换缓存展示:
|
||||
// 进厂只展示“收货单位缓存”,出厂只展示“发货单位缓存”
|
||||
if (string.Equals(inoutDirection, "1", StringComparison.Ordinal))
|
||||
{
|
||||
// 进厂:清空发货单位展示
|
||||
_selectedSupplier = null;
|
||||
SenderUnit = null;
|
||||
RaisePropertyChanged(nameof(SenderUnitDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedSupplier));
|
||||
|
||||
// 进厂:带出收货单位缓存(无缓存则清空)
|
||||
if (!string.IsNullOrWhiteSpace(_cachedInboundReceiverUnit))
|
||||
{
|
||||
ReceiverUnit = _cachedInboundReceiverUnit;
|
||||
AddLog($"已带出进厂收货单位缓存:{_cachedInboundReceiverUnit}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedCustomer = null;
|
||||
ReceiverUnit = null;
|
||||
RaisePropertyChanged(nameof(ReceiverUnitDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedCustomer));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (string.Equals(inoutDirection, "2", StringComparison.Ordinal))
|
||||
{
|
||||
// 出厂:清空收货单位展示
|
||||
_selectedCustomer = null;
|
||||
ReceiverUnit = null;
|
||||
RaisePropertyChanged(nameof(ReceiverUnitDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedCustomer));
|
||||
|
||||
// 出厂:带出发货单位缓存(无缓存则清空)
|
||||
if (!string.IsNullOrWhiteSpace(_cachedOutboundSenderUnit))
|
||||
{
|
||||
SenderUnit = _cachedOutboundSenderUnit;
|
||||
AddLog($"已带出出厂发货单位缓存:{_cachedOutboundSenderUnit}");
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectedSupplier = null;
|
||||
SenderUnit = null;
|
||||
RaisePropertyChanged(nameof(SenderUnitDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedSupplier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadUnitCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(_unitCacheFilePath)) return;
|
||||
var json = File.ReadAllText(_unitCacheFilePath);
|
||||
var cache = JsonSerializer.Deserialize<UnitDirectionCache>(json);
|
||||
if (cache == null) return;
|
||||
_cachedInboundReceiverUnit = string.IsNullOrWhiteSpace(cache.InboundReceiverUnit) ? null : cache.InboundReceiverUnit;
|
||||
_cachedOutboundSenderUnit = string.IsNullOrWhiteSpace(cache.OutboundSenderUnit) ? null : cache.OutboundSenderUnit;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 缓存读取失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveUnitCache()
|
||||
{
|
||||
try
|
||||
{
|
||||
var cache = new UnitDirectionCache
|
||||
{
|
||||
InboundReceiverUnit = _cachedInboundReceiverUnit,
|
||||
OutboundSenderUnit = _cachedOutboundSenderUnit,
|
||||
};
|
||||
var json = JsonSerializer.Serialize(cache);
|
||||
File.WriteAllText(_unitCacheFilePath, json);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 缓存写入失败不影响主流程
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OpenSupplierPickerAsync()
|
||||
{
|
||||
SupplierPickerDialogViewModel? pickerVm = null;
|
||||
@@ -582,6 +767,42 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
RaisePropertyChanged(nameof(HasSelectedCustomer));
|
||||
}
|
||||
|
||||
private async Task OpenMixerMaterialPickerAsync()
|
||||
{
|
||||
MixerMaterialPickerDialogViewModel? pickerVm = null;
|
||||
bool confirmed;
|
||||
try
|
||||
{
|
||||
confirmed = await HandyControl.Controls.Dialog.Show<MixerMaterialPickerDialogView>()
|
||||
.Initialize<MixerMaterialPickerDialogViewModel>(vm => { pickerVm = vm; })
|
||||
.GetResultAsync<bool>();
|
||||
}
|
||||
catch { return; }
|
||||
|
||||
if (!confirmed || pickerVm == null) return;
|
||||
var selected = pickerVm.SelectedMaterials;
|
||||
if (selected.Count == 0) return;
|
||||
|
||||
_mixerMaterialIds = string.Join(";", selected.Select(m => m.Source.Id ?? ""));
|
||||
MixerMaterialNames = string.Join(";", selected.Select(m => m.Source.MaterialName ?? ""));
|
||||
if (IsMixerMaterialManual)
|
||||
{
|
||||
IsMixerMaterialManual = false;
|
||||
}
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
AddLog($"已选密炼物料:{_mixerMaterialNames}");
|
||||
}
|
||||
|
||||
private void ClearMixerMaterialSelection()
|
||||
{
|
||||
_mixerMaterialIds = null;
|
||||
MixerMaterialNames = null;
|
||||
IsMixerMaterialManual = false;
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
}
|
||||
|
||||
private void AddLog(string message)
|
||||
{
|
||||
var entry = $"{DateTime.Now:HH:mm:ss} {message}";
|
||||
@@ -681,9 +902,13 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
RaisePropertyChanged(nameof(ReceiverUnitDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedSupplier));
|
||||
RaisePropertyChanged(nameof(HasSelectedCustomer));
|
||||
GoodsName = selected.Source.GoodsName;
|
||||
DriverName = selected.Source.DriverName;
|
||||
DriverPhone = selected.Source.DriverPhone;
|
||||
_mixerMaterialIds = selected.Source.MixerMaterialIds;
|
||||
MixerMaterialNames = selected.Source.MixerMaterialNames;
|
||||
IsMixerMaterialManual = string.Equals(selected.Source.MaterialType, "2", StringComparison.Ordinal);
|
||||
RaisePropertyChanged(nameof(MixerMaterialDisplay));
|
||||
RaisePropertyChanged(nameof(HasSelectedMixerMaterials));
|
||||
|
||||
var isOutbound = string.Equals(InoutDirection, "2", StringComparison.Ordinal);
|
||||
if (isOutbound)
|
||||
@@ -715,7 +940,6 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
PlateNumber = null;
|
||||
SenderUnit = null;
|
||||
ReceiverUnit = null;
|
||||
GoodsName = null;
|
||||
DriverName = null;
|
||||
DriverPhone = null;
|
||||
GrossWeight = null;
|
||||
@@ -727,6 +951,7 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
IsPlateNumberLocked = false;
|
||||
ClearSupplierSelection();
|
||||
ClearCustomerSelection();
|
||||
ClearMixerMaterialSelection();
|
||||
ClearVehicleMatch();
|
||||
RaisePropertyChanged(nameof(NetWeightDisplay));
|
||||
AddLog("已切换进出方向,当前表单数据已清空");
|
||||
@@ -889,6 +1114,12 @@ public class WeightRecordOperationViewModel : BaseViewModel
|
||||
}
|
||||
}
|
||||
|
||||
public class UnitDirectionCache
|
||||
{
|
||||
public string? InboundReceiverUnit { get; set; }
|
||||
public string? OutboundSenderUnit { get; set; }
|
||||
}
|
||||
|
||||
public class WeightRecordSimpleItem
|
||||
{
|
||||
public MesXslWeightRecord? Source { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user