新增物料类型处理逻辑,确保在保存和编辑称重记录时自动设置默认物料类型。更新前端表单以支持密炼物料的选择和显示,优化用户体验。添加分类字典和数据字典的事件广播功能,增强系统的实时数据同步能力。
This commit is contained in:
@@ -142,6 +142,14 @@ public class StompWebSocketService : ISignalRService
|
||||
await SendFrameAsync(
|
||||
BuildSubscribeFrame("sub-mes-mixer-material", "/topic/sync/mes-mixer-materials"),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
// 分类字典变更:订阅 /topic/sync/sys-categories
|
||||
await SendFrameAsync(
|
||||
BuildSubscribeFrame("sub-sys-categories", "/topic/sync/sys-categories"),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
// 数据字典变更:订阅 /topic/sync/sys-dicts
|
||||
await SendFrameAsync(
|
||||
BuildSubscribeFrame("sub-sys-dicts", "/topic/sync/sys-dicts"),
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 订阅服务端 PONG 回复(应用层假在线检测)
|
||||
await SendFrameAsync(
|
||||
|
||||
@@ -13,9 +13,11 @@ using YY.Admin.Infrastructure.Hubs;
|
||||
using YY.Admin.Infrastructure.Network;
|
||||
using YY.Admin.Infrastructure.Storage;
|
||||
using YY.Admin.Infrastructure.Sync;
|
||||
using YY.Admin.Services.Service.Category;
|
||||
using YY.Admin.Services.Service.Customer;
|
||||
using YY.Admin.Services.Service.Supplier;
|
||||
using YY.Admin.Services.Service.Dict;
|
||||
using YY.Admin.Services.Service.MixerMaterial;
|
||||
using YY.Admin.Services.Service.Supplier;
|
||||
using YY.Admin.Services.Service.Vehicle;
|
||||
using YY.Admin.Services.Service.WeightRecord;
|
||||
|
||||
@@ -50,6 +52,10 @@ public class SyncModule : IModule
|
||||
// 密炼物料信息:API直连 + STOMP实时通知
|
||||
containerRegistry.RegisterSingleton<IMixerMaterialService, MixerMaterialService>();
|
||||
containerRegistry.RegisterSingleton<MixerMaterialSyncCoordinator>();
|
||||
// 分类字典:启动同步 + 断线重连补刷
|
||||
containerRegistry.RegisterSingleton<CategorySyncCoordinator>();
|
||||
// 数据字典:启动同步 + 断线重连补刷
|
||||
containerRegistry.RegisterSingleton<DictSyncCoordinator>();
|
||||
|
||||
var serviceCollection = new ServiceCollection();
|
||||
serviceCollection.AddTransient<DisconnectGuardHandler>();
|
||||
@@ -104,6 +110,10 @@ public class SyncModule : IModule
|
||||
_ = containerProvider.Resolve<WeightRecordSyncCoordinator>();
|
||||
// 强制实例化密炼物料同步协调器
|
||||
_ = containerProvider.Resolve<MixerMaterialSyncCoordinator>();
|
||||
// 强制实例化分类字典同步协调器
|
||||
_ = containerProvider.Resolve<CategorySyncCoordinator>();
|
||||
// 强制实例化数据字典同步协调器
|
||||
_ = containerProvider.Resolve<DictSyncCoordinator>();
|
||||
}
|
||||
|
||||
private static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
|
||||
|
||||
@@ -64,6 +64,42 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- Button Text(透明背景链接风格按钮) -->
|
||||
<Style x:Key="ButtonText" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderBrush" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
||||
<Setter Property="Padding" Value="4 2"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Padding="{TemplateBinding Padding}">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Opacity" Value="0.75"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Opacity" Value="0.5"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value="0.4"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<!-- TreeView -->
|
||||
<Style x:Key="CusTreeViewItemBaseStyle" BasedOn="{StaticResource TreeViewItemBaseStyle}" TargetType="TreeViewItem">
|
||||
<Setter Property="Template">
|
||||
|
||||
@@ -62,6 +62,28 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
public ObservableCollection<KeyValuePair<string, string>> MajorCategoryOptions { get; } = new();
|
||||
public ObservableCollection<KeyValuePair<string, string>> MinorCategoryOptions { get; } = new();
|
||||
|
||||
public ObservableCollection<CategoryFilterNode> TreeNodes { get; } = new();
|
||||
|
||||
private CategoryFilterNode? _selectedTreeNode;
|
||||
public CategoryFilterNode? SelectedTreeNode
|
||||
{
|
||||
get => _selectedTreeNode;
|
||||
set => SetProperty(ref _selectedTreeNode, value);
|
||||
}
|
||||
|
||||
private bool _isTreeAllExpanded = true;
|
||||
public bool IsTreeAllExpanded
|
||||
{
|
||||
get => _isTreeAllExpanded;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _isTreeAllExpanded, value))
|
||||
RaisePropertyChanged(nameof(ToggleExpandButtonText));
|
||||
}
|
||||
}
|
||||
|
||||
public string ToggleExpandButtonText => _isTreeAllExpanded ? "折叠全部" : "展开全部";
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
public DelegateCommand AddCommand { get; }
|
||||
@@ -69,6 +91,7 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
public DelegateCommand<MesMixerMaterial> DeleteCommand { get; }
|
||||
public DelegateCommand PrevPageCommand { get; }
|
||||
public DelegateCommand NextPageCommand { get; }
|
||||
public DelegateCommand ToggleExpandCommand { get; }
|
||||
|
||||
public MixerMaterialListViewModel(
|
||||
IMixerMaterialService mixerMaterialService,
|
||||
@@ -83,10 +106,12 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
FilterMaterialCode = null;
|
||||
FilterMaterialName = null;
|
||||
FilterErpCode = null;
|
||||
FilterMajorCategoryId = null;
|
||||
_filterMajorCategoryId = null;
|
||||
RaisePropertyChanged(nameof(FilterMajorCategoryId));
|
||||
FilterMinorCategoryId = null;
|
||||
PageNo = 1;
|
||||
SelectedTreeNode = null;
|
||||
await LoadMinorCategoryOptionsAsync();
|
||||
PageNo = 1;
|
||||
await LoadAsync();
|
||||
});
|
||||
AddCommand = new DelegateCommand(async () => await ShowAddDialogAsync());
|
||||
@@ -94,6 +119,7 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
DeleteCommand = new DelegateCommand<MesMixerMaterial>(async m => await DeleteAsync(m));
|
||||
PrevPageCommand = new DelegateCommand(async () => { if (PageNo > 1) { PageNo--; await LoadAsync(); } });
|
||||
NextPageCommand = new DelegateCommand(async () => { if ((long)PageNo * PageSize < Total) { PageNo++; await LoadAsync(); } });
|
||||
ToggleExpandCommand = new DelegateCommand(ToggleExpand);
|
||||
|
||||
_materialChangedToken = _eventAggregator
|
||||
.GetEvent<MixerMaterialChangedEvent>()
|
||||
@@ -106,6 +132,7 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
{
|
||||
try
|
||||
{
|
||||
await LoadCategoryTreeAsync();
|
||||
await LoadMajorCategoryOptionsAsync();
|
||||
await LoadMinorCategoryOptionsAsync();
|
||||
await UIHelper.WaitForRenderAsync();
|
||||
@@ -117,6 +144,70 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadCategoryTreeAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
var tree = await _mixerMaterialService.GetMaterialCategoryTreeAsync();
|
||||
TreeNodes.Clear();
|
||||
var root = new CategoryFilterNode("", "全部", null, false, null, []) { IsExpanded = true };
|
||||
foreach (var major in tree)
|
||||
{
|
||||
var majorNode = new CategoryFilterNode(major.Id, major.Name ?? major.Code ?? major.Id, major.Code, true, null, []);
|
||||
foreach (var minor in major.Children)
|
||||
{
|
||||
majorNode.Children.Add(new CategoryFilterNode(minor.Id, minor.Name ?? minor.Code ?? minor.Id, minor.Code, false, major.Id, []));
|
||||
}
|
||||
root.Children.Add(majorNode);
|
||||
}
|
||||
TreeNodes.Add(root);
|
||||
IsTreeAllExpanded = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine($"加载物料分类树失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleExpand()
|
||||
{
|
||||
var expand = !_isTreeAllExpanded;
|
||||
foreach (var root in TreeNodes)
|
||||
{
|
||||
root.IsExpanded = true; // 根节点始终展开
|
||||
foreach (var major in root.Children)
|
||||
major.IsExpanded = expand;
|
||||
}
|
||||
IsTreeAllExpanded = expand;
|
||||
}
|
||||
|
||||
public async Task OnTreeNodeSelectedAsync(CategoryFilterNode? node)
|
||||
{
|
||||
SelectedTreeNode = node;
|
||||
if (node == null || node.Id == "")
|
||||
{
|
||||
_filterMajorCategoryId = null;
|
||||
RaisePropertyChanged(nameof(FilterMajorCategoryId));
|
||||
FilterMinorCategoryId = null;
|
||||
}
|
||||
else if (node.IsMajor)
|
||||
{
|
||||
_filterMajorCategoryId = node.Id;
|
||||
RaisePropertyChanged(nameof(FilterMajorCategoryId));
|
||||
FilterMinorCategoryId = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
_filterMajorCategoryId = node.ParentId;
|
||||
RaisePropertyChanged(nameof(FilterMajorCategoryId));
|
||||
FilterMinorCategoryId = node.Id;
|
||||
}
|
||||
|
||||
await LoadMinorCategoryOptionsAsync();
|
||||
PageNo = 1;
|
||||
await LoadAsync();
|
||||
}
|
||||
|
||||
private async Task LoadMajorCategoryOptionsAsync()
|
||||
{
|
||||
MajorCategoryOptions.Clear();
|
||||
@@ -132,11 +223,11 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
{
|
||||
MinorCategoryOptions.Clear();
|
||||
MinorCategoryOptions.Add(new KeyValuePair<string, string>("全部", ""));
|
||||
if (string.IsNullOrWhiteSpace(FilterMajorCategoryId))
|
||||
if (string.IsNullOrWhiteSpace(_filterMajorCategoryId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
var options = await _mixerMaterialService.GetMinorCategoryOptionsAsync(FilterMajorCategoryId!);
|
||||
var options = await _mixerMaterialService.GetMinorCategoryOptionsAsync(_filterMajorCategoryId!);
|
||||
foreach (var item in options)
|
||||
{
|
||||
MinorCategoryOptions.Add(item);
|
||||
@@ -155,7 +246,7 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
{
|
||||
IsLoading = true;
|
||||
var result = await _mixerMaterialService.PageAsync(
|
||||
PageNo, PageSize, FilterMaterialCode, FilterMaterialName, FilterErpCode, FilterMajorCategoryId, FilterMinorCategoryId);
|
||||
PageNo, PageSize, FilterMaterialCode, FilterMaterialName, FilterErpCode, _filterMajorCategoryId, FilterMinorCategoryId);
|
||||
Materials = new ObservableCollection<MesMixerMaterial>(result.Records);
|
||||
Total = result.Total;
|
||||
}
|
||||
@@ -228,5 +319,40 @@ public class MixerMaterialListViewModel : BaseViewModel
|
||||
_materialChangedToken = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryFilterNode : System.ComponentModel.INotifyPropertyChanged
|
||||
{
|
||||
public event System.ComponentModel.PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public string Id { get; }
|
||||
public string DisplayName { get; }
|
||||
public string? Code { get; }
|
||||
public bool IsMajor { get; }
|
||||
public string? ParentId { get; }
|
||||
public ObservableCollection<CategoryFilterNode> Children { get; }
|
||||
|
||||
private bool _isExpanded;
|
||||
public bool IsExpanded
|
||||
{
|
||||
get => _isExpanded;
|
||||
set
|
||||
{
|
||||
if (_isExpanded != value)
|
||||
{
|
||||
_isExpanded = value;
|
||||
PropertyChanged?.Invoke(this, new System.ComponentModel.PropertyChangedEventArgs(nameof(IsExpanded)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CategoryFilterNode(string id, string? displayName, string? code, bool isMajor, string? parentId, List<CategoryFilterNode> children)
|
||||
{
|
||||
Id = id;
|
||||
DisplayName = displayName ?? id;
|
||||
Code = code;
|
||||
IsMajor = isMajor;
|
||||
ParentId = parentId;
|
||||
Children = new ObservableCollection<CategoryFilterNode>(children);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using HandyControl.Controls;
|
||||
using Prism.Events;
|
||||
using System.Collections.ObjectModel;
|
||||
using YY.Admin.Core;
|
||||
using YY.Admin.Core.Events;
|
||||
using YY.Admin.Core.Helper;
|
||||
using YY.Admin.Services.Service.Category;
|
||||
using YY.Admin.Services.Service.Category.Dto;
|
||||
@@ -11,6 +13,7 @@ namespace YY.Admin.ViewModels.SysManage;
|
||||
public class CategoryDictionaryManagementViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IJeecgCategorySyncService _categorySyncService;
|
||||
private SubscriptionToken? _categoryChangedToken;
|
||||
|
||||
private PaginationDataGridViewModel<JeecgCategoryItemOutput> _paginationDataGridViewModel;
|
||||
public PaginationDataGridViewModel<JeecgCategoryItemOutput> PaginationDataGridViewModel
|
||||
@@ -28,7 +31,6 @@ public class CategoryDictionaryManagementViewModel : BaseViewModel
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
public DelegateCommand SyncCommand { get; }
|
||||
public ObservableCollection<CategoryTreeNode> TreeNodes { get; } = [];
|
||||
|
||||
private CategoryTreeNode? _selectedTreeNode;
|
||||
@@ -49,7 +51,10 @@ public class CategoryDictionaryManagementViewModel : BaseViewModel
|
||||
|
||||
SearchCommand = new DelegateCommand(async () => await SearchAsync());
|
||||
ResetCommand = new DelegateCommand(async () => await ResetAsync());
|
||||
SyncCommand = new DelegateCommand(async () => await SyncAsync());
|
||||
|
||||
_categoryChangedToken = _eventAggregator
|
||||
.GetEvent<CategoryChangedEvent>()
|
||||
.Subscribe(async _ => await OnCategoryChangedAsync(), ThreadOption.UIThread);
|
||||
|
||||
_ = InitializeAsync();
|
||||
}
|
||||
@@ -84,21 +89,6 @@ public class CategoryDictionaryManagementViewModel : BaseViewModel
|
||||
await SearchAsync();
|
||||
}
|
||||
|
||||
private async Task SyncAsync()
|
||||
{
|
||||
var count = await _categorySyncService.SyncFromJeecgAsync();
|
||||
if (count > 0)
|
||||
{
|
||||
Growl.Success($"同步完成,共处理 {count} 条分类字典数据");
|
||||
}
|
||||
else
|
||||
{
|
||||
Growl.Warning("未同步到分类字典,请确认后端可访问");
|
||||
}
|
||||
await LoadTreeAsync();
|
||||
await SearchAsync();
|
||||
}
|
||||
|
||||
public async Task OnTreeSelectedAsync(CategoryTreeNode? node)
|
||||
{
|
||||
SelectedTreeNode = node;
|
||||
@@ -131,6 +121,22 @@ public class CategoryDictionaryManagementViewModel : BaseViewModel
|
||||
return node;
|
||||
}
|
||||
|
||||
private async Task OnCategoryChangedAsync()
|
||||
{
|
||||
await LoadTreeAsync();
|
||||
await PaginationDataGridViewModel.LoadDataAsync();
|
||||
}
|
||||
|
||||
protected override void CleanUp()
|
||||
{
|
||||
base.CleanUp();
|
||||
if (_categoryChangedToken != null)
|
||||
{
|
||||
_eventAggregator.GetEvent<CategoryChangedEvent>().Unsubscribe(_categoryChangedToken);
|
||||
_categoryChangedToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class CategoryTreeNode
|
||||
{
|
||||
public string Id { get; set; } = string.Empty;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using HandyControl.Controls;
|
||||
using Prism.Events;
|
||||
using System.Collections.ObjectModel;
|
||||
using YY.Admin.Core;
|
||||
using YY.Admin.Core.Events;
|
||||
using YY.Admin.Core.Extension;
|
||||
using YY.Admin.Core.Helper;
|
||||
using YY.Admin.Services.Service;
|
||||
@@ -10,6 +12,16 @@ namespace YY.Admin.ViewModels.SysManage;
|
||||
public class DataDictionaryManagementViewModel : BaseViewModel
|
||||
{
|
||||
private readonly IJeecgDictSyncService _dictSyncService;
|
||||
private SubscriptionToken? _dictChangedToken;
|
||||
|
||||
public ObservableCollection<DictTreeNode> TreeNodes { get; } = [];
|
||||
|
||||
private DictTreeNode? _selectedTreeNode;
|
||||
public DictTreeNode? SelectedTreeNode
|
||||
{
|
||||
get => _selectedTreeNode;
|
||||
set => SetProperty(ref _selectedTreeNode, value);
|
||||
}
|
||||
|
||||
private PaginationDataGridViewModel<JeecgDictItemOutput> _paginationDataGridViewModel;
|
||||
public PaginationDataGridViewModel<JeecgDictItemOutput> PaginationDataGridViewModel
|
||||
@@ -33,7 +45,6 @@ public class DataDictionaryManagementViewModel : BaseViewModel
|
||||
|
||||
public DelegateCommand SearchCommand { get; }
|
||||
public DelegateCommand ResetCommand { get; }
|
||||
public DelegateCommand SyncCommand { get; }
|
||||
|
||||
public DataDictionaryManagementViewModel(
|
||||
IJeecgDictSyncService dictSyncService,
|
||||
@@ -46,13 +57,17 @@ public class DataDictionaryManagementViewModel : BaseViewModel
|
||||
|
||||
SearchCommand = new DelegateCommand(async () => await SearchAsync());
|
||||
ResetCommand = new DelegateCommand(async () => await ResetAsync());
|
||||
SyncCommand = new DelegateCommand(async () => await SyncAsync());
|
||||
|
||||
_dictChangedToken = _eventAggregator
|
||||
.GetEvent<DictChangedEvent>()
|
||||
.Subscribe(async _ => await OnDictChangedAsync(), ThreadOption.UIThread);
|
||||
|
||||
_ = InitializeAsync();
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
await LoadDictTreeAsync();
|
||||
await UIHelper.WaitForRenderAsync();
|
||||
await PaginationDataGridViewModel.LoadDataAsync();
|
||||
}
|
||||
@@ -74,21 +89,54 @@ public class DataDictionaryManagementViewModel : BaseViewModel
|
||||
private async Task ResetAsync()
|
||||
{
|
||||
Input = new PageJeecgDictItemInput();
|
||||
SelectedTreeNode = null;
|
||||
await UIHelper.WaitForRenderAsync();
|
||||
await SearchAsync();
|
||||
}
|
||||
|
||||
private async Task SyncAsync()
|
||||
public async Task OnDictTreeSelectedAsync(DictTreeNode? node)
|
||||
{
|
||||
var count = await _dictSyncService.SyncFromJeecgAsync();
|
||||
if (count > 0)
|
||||
{
|
||||
Growl.Success($"同步完成,共处理 {count} 条数据字典项");
|
||||
}
|
||||
else
|
||||
{
|
||||
Growl.Warning("未同步到数据字典,请确认后端可访问");
|
||||
}
|
||||
SelectedTreeNode = node;
|
||||
Input.DictCode = node?.DictCode;
|
||||
await SearchAsync();
|
||||
}
|
||||
|
||||
private async Task LoadDictTreeAsync()
|
||||
{
|
||||
var groups = await _dictSyncService.GetDictGroupsAsync();
|
||||
TreeNodes.Clear();
|
||||
foreach (var group in groups)
|
||||
{
|
||||
TreeNodes.Add(new DictTreeNode(group.Key, group.Value));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnDictChangedAsync()
|
||||
{
|
||||
await LoadDictTreeAsync();
|
||||
await PaginationDataGridViewModel.LoadDataAsync();
|
||||
}
|
||||
|
||||
protected override void CleanUp()
|
||||
{
|
||||
base.CleanUp();
|
||||
if (_dictChangedToken != null)
|
||||
{
|
||||
_eventAggregator.GetEvent<DictChangedEvent>().Unsubscribe(_dictChangedToken);
|
||||
_dictChangedToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class DictTreeNode
|
||||
{
|
||||
public string DictCode { get; }
|
||||
public string DictName { get; }
|
||||
public string DisplayName => $"[{DictCode}] {DictName}";
|
||||
|
||||
public DictTreeNode(string dictCode, string dictName)
|
||||
{
|
||||
DictCode = dictCode;
|
||||
DictName = dictName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -96,70 +96,126 @@
|
||||
</hc:UniformSpacingPanel>
|
||||
</Border>
|
||||
|
||||
<DataGrid Grid.Row="2"
|
||||
ItemsSource="{Binding Materials}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
CanUserAddRows="False"
|
||||
SelectionMode="Extended"
|
||||
SelectionUnit="FullRow"
|
||||
RowHeaderWidth="55"
|
||||
GridLinesVisibility="Horizontal"
|
||||
HorizontalGridLinesBrush="#FFEDEDED"
|
||||
VerticalGridLinesBrush="Transparent"
|
||||
HeadersVisibility="All"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}"
|
||||
Style="{StaticResource CusDataGridStyle}"
|
||||
hc:DataGridAttach.ShowSelectAllButton="True"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<DataGrid.RowHeaderTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
|
||||
</DataTemplate>
|
||||
</DataGrid.RowHeaderTemplate>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="物料编码" Binding="{Binding MaterialCode}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料名称" Binding="{Binding MaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||
<DataGridTextColumn Header="ERP编号" Binding="{Binding ErpCode}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料大类" Binding="{Binding MajorCategoryText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料小类" Binding="{Binding MinorCategoryText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料描述" Binding="{Binding MaterialDesc}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="160"/>
|
||||
<DataGridTextColumn Header="物料别名" Binding="{Binding AliasName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="投管状态" Binding="{Binding FeedManageStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="使用状态" Binding="{Binding UseStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="比重" Binding="{Binding SpecificGravity, StringFormat=N4}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>
|
||||
<DataGridTextColumn Header="保质期(天)" Binding="{Binding ShelfLifeDays}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTemplateColumn Header="操作" Width="150" CellStyle="{StaticResource CusOperDataGridCellStyle}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<hc:UniformSpacingPanel Spacing="5">
|
||||
<Border Style="{DynamicResource DataGridOpeButtonStyle}">
|
||||
<Border.InputBindings>
|
||||
<MouseBinding Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" MouseAction="LeftClick"/>
|
||||
</Border.InputBindings>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="SquareEditOutline" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="修改" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border Style="{DynamicResource DataGridOpeButtonStyle}">
|
||||
<Border.InputBindings>
|
||||
<MouseBinding Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" MouseAction="LeftClick"/>
|
||||
</Border.InputBindings>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="TrashCanOutline" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="删除" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</hc:UniformSpacingPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Grid Grid.Row="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="220"/>
|
||||
<ColumnDefinition Width="10"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Grid.Column="0" BorderBrush="#FFEDEDED" BorderThickness="1" CornerRadius="4">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0"
|
||||
Background="#FFF5F5F5"
|
||||
BorderBrush="#FFEDEDED"
|
||||
BorderThickness="0 0 0 1"
|
||||
Padding="10 7"
|
||||
CornerRadius="4 4 0 0">
|
||||
<Grid>
|
||||
<TextBlock Text="物料分类"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="12"
|
||||
Foreground="#FF333333"
|
||||
VerticalAlignment="Center"/>
|
||||
<Button HorizontalAlignment="Right"
|
||||
Command="{Binding ToggleExpandCommand}"
|
||||
Style="{StaticResource ButtonText}"
|
||||
Padding="4 2">
|
||||
<TextBlock Text="{Binding ToggleExpandButtonText}" FontSize="11"/>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<TreeView Grid.Row="1"
|
||||
x:Name="CategoryTreeView"
|
||||
Padding="4"
|
||||
BorderThickness="0"
|
||||
ItemsSource="{Binding TreeNodes}"
|
||||
SelectedItemChanged="CategoryTreeView_SelectedItemChanged">
|
||||
<TreeView.ItemContainerStyle>
|
||||
<Style TargetType="TreeViewItem" BasedOn="{StaticResource TreeViewItemBaseStyle}">
|
||||
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
||||
</Style>
|
||||
</TreeView.ItemContainerStyle>
|
||||
<TreeView.ItemTemplate>
|
||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||
<TextBlock Text="{Binding DisplayName}" Padding="2"/>
|
||||
</HierarchicalDataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<DataGrid Grid.Column="2"
|
||||
ItemsSource="{Binding Materials}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
CanUserAddRows="False"
|
||||
SelectionMode="Extended"
|
||||
SelectionUnit="FullRow"
|
||||
RowHeaderWidth="55"
|
||||
GridLinesVisibility="Horizontal"
|
||||
HorizontalGridLinesBrush="#FFEDEDED"
|
||||
VerticalGridLinesBrush="Transparent"
|
||||
HeadersVisibility="All"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}"
|
||||
Style="{StaticResource CusDataGridStyle}"
|
||||
hc:DataGridAttach.ShowSelectAllButton="True"
|
||||
VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<DataGrid.RowHeaderTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
|
||||
</DataTemplate>
|
||||
</DataGrid.RowHeaderTemplate>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="物料编码" Binding="{Binding MaterialCode}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料名称" Binding="{Binding MaterialName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||
<DataGridTextColumn Header="ERP编号" Binding="{Binding ErpCode}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料大类" Binding="{Binding MajorCategoryText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料小类" Binding="{Binding MinorCategoryText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="物料描述" Binding="{Binding MaterialDesc}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="160"/>
|
||||
<DataGridTextColumn Header="物料别名" Binding="{Binding AliasName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="投管状态" Binding="{Binding FeedManageStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="使用状态" Binding="{Binding UseStatusText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="比重" Binding="{Binding SpecificGravity, StringFormat=N4}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="90"/>
|
||||
<DataGridTextColumn Header="保质期(天)" Binding="{Binding ShelfLifeDays}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTemplateColumn Header="操作" Width="150" CellStyle="{StaticResource CusOperDataGridCellStyle}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<hc:UniformSpacingPanel Spacing="5">
|
||||
<Border Style="{DynamicResource DataGridOpeButtonStyle}">
|
||||
<Border.InputBindings>
|
||||
<MouseBinding Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" MouseAction="LeftClick"/>
|
||||
</Border.InputBindings>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="SquareEditOutline" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="修改" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border Style="{DynamicResource DataGridOpeButtonStyle}">
|
||||
<Border.InputBindings>
|
||||
<MouseBinding Command="{Binding DataContext.DeleteCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
|
||||
CommandParameter="{Binding}" MouseAction="LeftClick"/>
|
||||
</Border.InputBindings>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="TrashCanOutline" VerticalAlignment="Center"/>
|
||||
<TextBlock Text="删除" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</hc:UniformSpacingPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||
<TextBlock Text="{Binding Total, StringFormat=共 {0} 条}" VerticalAlignment="Center" Margin="0,0,16,0"
|
||||
@@ -171,4 +227,3 @@
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using YY.Admin.ViewModels.MixerMaterial;
|
||||
|
||||
namespace YY.Admin.Views.MixerMaterial;
|
||||
|
||||
@@ -8,5 +10,10 @@ public partial class MixerMaterialListView : UserControl
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
private void CategoryTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
|
||||
{
|
||||
if (DataContext is MixerMaterialListViewModel vm && e.NewValue is MixerMaterialListViewModel.CategoryFilterNode node)
|
||||
_ = vm.OnTreeNodeSelectedAsync(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,12 +65,6 @@
|
||||
<TextBlock Text="重置" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource ButtonSuccess}" Command="{Binding SyncCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="CloudSyncOutline"/>
|
||||
<TextBlock Text="同步分类字典" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</hc:UniformSpacingPanel>
|
||||
</Border>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<UserControl x:Class="YY.Admin.Views.SysManage.DataDictionaryManagementView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:core="clr-namespace:YY.Admin.Core;assembly=YY.Admin.Core"
|
||||
@@ -11,113 +11,157 @@
|
||||
|
||||
<Grid Style="{StaticResource BaseViewStyle}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" CornerRadius="4" Margin="0 0 -10 0">
|
||||
<hc:Row>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.DictCode, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典编码"
|
||||
hc:InfoElement.Title="字典编码"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.DictName, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典名称"
|
||||
hc:InfoElement.Title="字典名称"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.ItemText, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典项文本"
|
||||
hc:InfoElement.Title="字典项文本"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.ItemValue, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典项值"
|
||||
hc:InfoElement.Title="字典项值"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:ComboBox
|
||||
SelectedValue="{Binding Input.Status, Converter={StaticResource EnumToIntConverter}, ConverterParameter={x:Type core:StatusEnum}}"
|
||||
ItemsSource="{Binding StatusList}"
|
||||
DisplayMemberPath="Key"
|
||||
SelectedValuePath="Value"
|
||||
hc:InfoElement.Placeholder="请选择状态"
|
||||
hc:InfoElement.Title="状态"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
</Border>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="260"/>
|
||||
<ColumnDefinition Width="10"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Border Grid.Row="1" Margin="0,10">
|
||||
<hc:UniformSpacingPanel Spacing="10">
|
||||
<Button Style="{StaticResource ButtonPrimary}" Command="{Binding SearchCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Search"/>
|
||||
<TextBlock Text="搜索" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource ButtonDefault}" Command="{Binding ResetCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Refresh"/>
|
||||
<TextBlock Text="重置" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource ButtonSuccess}" Command="{Binding SyncCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="CloudSyncOutline"/>
|
||||
<TextBlock Text="同步数据字典" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</hc:UniformSpacingPanel>
|
||||
</Border>
|
||||
<!-- 左侧字典列表 -->
|
||||
<Border Grid.Column="0"
|
||||
BorderBrush="#FFEDEDED"
|
||||
BorderThickness="1"
|
||||
CornerRadius="4">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<DataGrid
|
||||
Grid.Row="2"
|
||||
AutoGenerateColumns="False"
|
||||
HeadersVisibility="All"
|
||||
ItemsSource="{Binding PaginationDataGridViewModel.Data}"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}"
|
||||
Style="{StaticResource CusDataGridStyle}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding DictCode}" Header="字典编码" Width="150" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding DictName}" Header="字典名称" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemText}" Header="字典项文本" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemValue}" Header="字典项值" Width="140" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemDescription}" Header="描述" Width="220" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding SortOrder}" Header="排序" Width="80" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding Status, Converter={StaticResource EnumDescriptionConverter}}" Header="状态" Width="80" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding CreateTime, StringFormat='yyyy-MM-dd HH:mm:ss'}" Header="创建时间" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding UpdateTime, StringFormat='yyyy-MM-dd HH:mm:ss'}" Header="更新时间" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
<Border Grid.Row="0"
|
||||
Background="#FFF5F5F5"
|
||||
BorderBrush="#FFEDEDED"
|
||||
BorderThickness="0 0 0 1"
|
||||
Padding="12 8"
|
||||
CornerRadius="4 4 0 0">
|
||||
<TextBlock Text="字典列表"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="13"
|
||||
Foreground="#FF333333"/>
|
||||
</Border>
|
||||
|
||||
<components:PaginationDataGridControl Grid.Row="3" DataContext="{Binding PaginationDataGridViewModel}"/>
|
||||
<ListBox Grid.Row="1"
|
||||
x:Name="DictListBox"
|
||||
ItemsSource="{Binding TreeNodes}"
|
||||
SelectedItem="{Binding SelectedTreeNode, Mode=TwoWay}"
|
||||
SelectionChanged="DictListBox_SelectionChanged"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<ListBox.ItemContainerStyle>
|
||||
<Style TargetType="ListBoxItem">
|
||||
<Setter Property="Padding" Value="12 8"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
</Style>
|
||||
</ListBox.ItemContainerStyle>
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<TextBlock Text="{Binding DictCode}"
|
||||
FontWeight="SemiBold"
|
||||
FontSize="12"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
<TextBlock Text="{Binding DictName}"
|
||||
FontSize="11"
|
||||
Foreground="#FF888888"
|
||||
Margin="0 2 0 0"
|
||||
TextTrimming="CharacterEllipsis"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 右侧字典详情 -->
|
||||
<Grid Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border Grid.Row="0" CornerRadius="4" Margin="0 0 -10 0">
|
||||
<hc:Row>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.ItemText, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典项文本"
|
||||
hc:InfoElement.Title="字典项文本"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:TextBox
|
||||
Text="{Binding Input.ItemValue, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="请输入字典项值"
|
||||
hc:InfoElement.Title="字典项值"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=6, Xl=4}">
|
||||
<hc:ComboBox
|
||||
SelectedValue="{Binding Input.Status, Converter={StaticResource EnumToIntConverter}, ConverterParameter={x:Type core:StatusEnum}}"
|
||||
ItemsSource="{Binding StatusList}"
|
||||
DisplayMemberPath="Key"
|
||||
SelectedValuePath="Value"
|
||||
hc:InfoElement.Placeholder="请选择状态"
|
||||
hc:InfoElement.Title="状态"
|
||||
hc:InfoElement.TitleWidth="70"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0 0 10 10"/>
|
||||
</hc:Col>
|
||||
</hc:Row>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1" Margin="0,10">
|
||||
<hc:UniformSpacingPanel Spacing="10">
|
||||
<Button Style="{StaticResource ButtonPrimary}" Command="{Binding SearchCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Search"/>
|
||||
<TextBlock Text="搜索" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
<Button Style="{StaticResource ButtonDefault}" Command="{Binding ResetCommand}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Refresh"/>
|
||||
<TextBlock Text="重置" Style="{StaticResource IconButtonStyle}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</hc:UniformSpacingPanel>
|
||||
</Border>
|
||||
|
||||
<DataGrid
|
||||
Grid.Row="2"
|
||||
AutoGenerateColumns="False"
|
||||
HeadersVisibility="All"
|
||||
ItemsSource="{Binding PaginationDataGridViewModel.Data}"
|
||||
ColumnHeaderStyle="{StaticResource CusDataGridColumnHeaderStyle}"
|
||||
Style="{StaticResource CusDataGridStyle}">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemText}" Header="字典项文本" Width="200" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemValue}" Header="字典项值" Width="160" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding ItemDescription}" Header="描述" Width="220" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding SortOrder}" Header="排序" Width="80" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding Status, Converter={StaticResource EnumDescriptionConverter}}" Header="状态" Width="80" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding CreateTime, StringFormat='yyyy-MM-dd HH:mm:ss'}" Header="创建时间" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
<DataGridTextColumn IsReadOnly="True" Binding="{Binding UpdateTime, StringFormat='yyyy-MM-dd HH:mm:ss'}" Header="更新时间" Width="170" CellStyle="{StaticResource CusDataGridCellStyle}"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<components:PaginationDataGridControl Grid.Row="1" DataContext="{Binding PaginationDataGridViewModel}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
using System.Windows.Controls;
|
||||
using YY.Admin.ViewModels.SysManage;
|
||||
|
||||
namespace YY.Admin.Views.SysManage
|
||||
{
|
||||
/// <summary>
|
||||
/// DataDictionaryManagementView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class DataDictionaryManagementView : UserControl
|
||||
{
|
||||
public DataDictionaryManagementView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private async void DictListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is DataDictionaryManagementViewModel vm)
|
||||
{
|
||||
var node = (sender as ListBox)?.SelectedItem as DataDictionaryManagementViewModel.DictTreeNode;
|
||||
await vm.OnDictTreeSelectedAsync(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
<UserControl x:Class="YY.Admin.Views.WeightRecord.MixerMaterialPickerDialogView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:prism="http://prismlibrary.com/"
|
||||
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||
mc:Ignorable="d"
|
||||
Width="720">
|
||||
|
||||
<Grid Background="{DynamicResource ThirdlyRegionBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="360"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<hc:SimplePanel Margin="20,16,20,12">
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Border Width="32" Height="32" CornerRadius="6" Background="{DynamicResource PrimaryBrush}" Margin="0,0,10,0">
|
||||
<md:PackIcon Kind="Flask" Width="18" Height="18" Foreground="White"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<TextBlock Text="选择密炼物料(可多选)" FontSize="16" FontWeight="SemiBold"
|
||||
Foreground="{DynamicResource PrimaryTextBrush}" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
<Button Width="22" Height="22" Command="hc:ControlCommands.Close"
|
||||
Style="{StaticResource ButtonIcon}"
|
||||
Foreground="{DynamicResource PrimaryBrush}"
|
||||
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"
|
||||
Padding="0" HorizontalAlignment="Right" VerticalAlignment="Center"/>
|
||||
</hc:SimplePanel>
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<Border Grid.Row="1" Background="{DynamicResource RegionBrush}" Padding="16,10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="80"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<hc:TextBox Grid.Column="0"
|
||||
Text="{Binding SearchCode, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="物料编码..."
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0,0,8,0">
|
||||
<hc:TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
|
||||
</hc:TextBox.InputBindings>
|
||||
</hc:TextBox>
|
||||
<hc:TextBox Grid.Column="1"
|
||||
Text="{Binding SearchName, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Placeholder="物料名称..."
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0,0,8,0">
|
||||
<hc:TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
|
||||
</hc:TextBox.InputBindings>
|
||||
</hc:TextBox>
|
||||
<Button Grid.Column="2" Command="{Binding SearchCommand}"
|
||||
IsEnabled="{Binding IsLoading, Converter={StaticResource Boolean2BooleanReConverter}}"
|
||||
Style="{StaticResource ButtonPrimary}" Height="32">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<md:PackIcon Kind="Magnify" Width="14" Height="14" VerticalAlignment="Center" Margin="0,0,4,0"/>
|
||||
<TextBlock Text="搜索" FontSize="13" VerticalAlignment="Center"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- 物料列表(多选) -->
|
||||
<DataGrid x:Name="MaterialsGrid"
|
||||
Grid.Row="2"
|
||||
Margin="16,8,16,0"
|
||||
ItemsSource="{Binding Materials}"
|
||||
AutoGenerateColumns="False"
|
||||
CanUserAddRows="False"
|
||||
CanUserDeleteRows="False"
|
||||
CanUserResizeRows="False"
|
||||
HeadersVisibility="Column"
|
||||
SelectionMode="Single"
|
||||
SelectionUnit="FullRow"
|
||||
IsReadOnly="False"
|
||||
GridLinesVisibility="Horizontal"
|
||||
HorizontalGridLinesBrush="#FFEDEFF2"
|
||||
VerticalGridLinesBrush="Transparent"
|
||||
Background="White"
|
||||
RowBackground="White"
|
||||
AlternatingRowBackground="#FAFCFF"
|
||||
RowHeight="32"
|
||||
ColumnHeaderHeight="34"
|
||||
RowHeaderWidth="0">
|
||||
<DataGrid.Resources>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#EAF3FF"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#1F1F1F"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="#EAF3FF"/>
|
||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" Color="#1F1F1F"/>
|
||||
</DataGrid.Resources>
|
||||
<DataGrid.ColumnHeaderStyle>
|
||||
<Style TargetType="DataGridColumnHeader">
|
||||
<Setter Property="Background" Value="#F5F7FA"/>
|
||||
<Setter Property="Foreground" Value="#606266"/>
|
||||
<Setter Property="FontSize" Value="13"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
<Setter Property="Padding" Value="8,0"/>
|
||||
<Setter Property="BorderBrush" Value="#EBEEF5"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
</Style>
|
||||
</DataGrid.ColumnHeaderStyle>
|
||||
<DataGrid.RowStyle>
|
||||
<Style TargetType="DataGridRow">
|
||||
<Setter Property="Background" Value="White"/>
|
||||
<Setter Property="Foreground" Value="#262626"/>
|
||||
<Setter Property="BorderBrush" Value="#FFEDEFF2"/>
|
||||
<Setter Property="BorderThickness" Value="0,0,0,1"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="True">
|
||||
<Setter Property="Background" Value="#EAF3FF"/>
|
||||
</DataTrigger>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#F5F9FF"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
<DataGrid.CellStyle>
|
||||
<Style TargetType="DataGridCell">
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Padding" Value="6,0"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
</Style>
|
||||
</DataGrid.CellStyle>
|
||||
<DataGrid.Columns>
|
||||
<DataGridTemplateColumn Header="选择" Width="50" CanUserSort="False">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<CheckBox IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
<DataGridTextColumn Header="物料编码" Binding="{Binding Source.MaterialCode}" Width="120" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="物料名称" Binding="{Binding Source.MaterialName}" Width="*" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="大类" Binding="{Binding Source.MajorCategoryText}" Width="110" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="小类" Binding="{Binding Source.MinorCategoryText}" Width="110" IsReadOnly="True"/>
|
||||
<DataGridTextColumn Header="状态" Binding="{Binding Source.UseStatusText}" Width="70" IsReadOnly="True"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<Border Grid.Row="3" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="0,1,0,0"
|
||||
Padding="16,12">
|
||||
<Grid>
|
||||
<!-- 已选提示 + 清除 -->
|
||||
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" MaxWidth="380">
|
||||
<Border Background="{DynamicResource PrimaryBrush}" CornerRadius="10" Padding="8,2" Margin="0,0,8,0"
|
||||
Visibility="{Binding HasSelectedMaterials, Converter={StaticResource Boolean2VisibilityConverter}}">
|
||||
<TextBlock Foreground="White" FontSize="12" FontWeight="SemiBold"
|
||||
Text="{Binding SelectedCount, StringFormat=已选 {0} 项}"/>
|
||||
</Border>
|
||||
<TextBlock VerticalAlignment="Center" FontSize="13" TextTrimming="CharacterEllipsis"
|
||||
Text="{Binding SelectedDisplayText}">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource SecondaryTextBrush}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasSelectedMaterials}" Value="True">
|
||||
<Setter Property="Foreground" Value="{DynamicResource PrimaryBrush}"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
<!-- 按钮 -->
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Button Content="清除选择" Command="{Binding ClearSelectionCommand}"
|
||||
Style="{StaticResource ButtonDefault}" Width="88" Margin="0,0,8,0" Height="34"
|
||||
Visibility="{Binding HasSelectedMaterials, Converter={StaticResource Boolean2VisibilityConverter}}"/>
|
||||
<Button Content="取 消" Command="{Binding CancelCommand}"
|
||||
Style="{StaticResource ButtonDefault}" Width="88" Margin="0,0,12,0" Height="34"/>
|
||||
<Button Content="确认选择" Command="{Binding ConfirmCommand}"
|
||||
Style="{StaticResource ButtonPrimary}" Width="100" Height="34"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace YY.Admin.Views.WeightRecord;
|
||||
|
||||
public partial class MixerMaterialPickerDialogView : UserControl
|
||||
{
|
||||
public MixerMaterialPickerDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -101,15 +101,45 @@
|
||||
Margin="0,0,0,16"/>
|
||||
</hc:Col>
|
||||
|
||||
<!-- 货物名称 -->
|
||||
<hc:Col Span="12">
|
||||
<hc:TextBox Text="{Binding Record.GoodsName, UpdateSourceTrigger=PropertyChanged}"
|
||||
hc:InfoElement.Title="货物名称"
|
||||
hc:InfoElement.TitleWidth="80"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.Placeholder="请输入货物名称"
|
||||
hc:InfoElement.ShowClearButton="True"
|
||||
Margin="0,0,0,16"/>
|
||||
<!-- 密炼物料 -->
|
||||
<hc:Col Span="24">
|
||||
<Grid Margin="0,0,0,16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="80"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="32"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="密炼物料" VerticalAlignment="Center"
|
||||
FontSize="14" Foreground="{DynamicResource PrimaryTextBrush}"/>
|
||||
<Border Grid.Column="1" CornerRadius="4" Height="32"
|
||||
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"
|
||||
Background="{DynamicResource RegionBrush}">
|
||||
<TextBlock Text="{Binding MixerMaterialDisplay}" VerticalAlignment="Center"
|
||||
Margin="8,0" FontSize="13" TextTrimming="CharacterEllipsis">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource SecondaryTextBrush}"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasSelectedMixerMaterials}" Value="True">
|
||||
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextBrush}"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Border>
|
||||
<Button Grid.Column="2" Content="选 择"
|
||||
Command="{Binding OpenMixerMaterialPickerCommand}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
Height="32" Margin="6,0,0,0" FontSize="12"/>
|
||||
<Button Grid.Column="3" Command="{Binding ClearMixerMaterialCommand}"
|
||||
Style="{StaticResource ButtonIcon}"
|
||||
Height="32" Width="28" Margin="4,0,0,0" Padding="0"
|
||||
ToolTip="清除选择"
|
||||
Foreground="{DynamicResource SecondaryTextBrush}"
|
||||
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
|
||||
</Grid>
|
||||
</hc:Col>
|
||||
|
||||
<!-- 毛重 -->
|
||||
|
||||
@@ -59,12 +59,12 @@
|
||||
hc:InfoElement.ShowClearButton="True"/>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=4, Xl=4}">
|
||||
<hc:TextBox Text="{Binding FilterGoodsName, UpdateSourceTrigger=PropertyChanged}"
|
||||
<hc:TextBox Text="{Binding FilterDriverName, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0 0 10 10"
|
||||
hc:InfoElement.Title="货物名称"
|
||||
hc:InfoElement.Title="司机"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.TitleWidth="65"
|
||||
hc:InfoElement.Placeholder="请输入货物名称"
|
||||
hc:InfoElement.Placeholder="请输入司机姓名"
|
||||
hc:InfoElement.ShowClearButton="True">
|
||||
<hc:TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
|
||||
@@ -72,12 +72,12 @@
|
||||
</hc:TextBox>
|
||||
</hc:Col>
|
||||
<hc:Col Layout="{hc:ColLayout Xs=12, Sm=8, Md=6, Lg=4, Xl=4}">
|
||||
<hc:TextBox Text="{Binding FilterDriverName, UpdateSourceTrigger=PropertyChanged}"
|
||||
<hc:TextBox Text="{Binding FilterMixerMaterialName, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0 0 10 10"
|
||||
hc:InfoElement.Title="司机"
|
||||
hc:InfoElement.Title="密炼物料"
|
||||
hc:InfoElement.TitlePlacement="Left"
|
||||
hc:InfoElement.TitleWidth="65"
|
||||
hc:InfoElement.Placeholder="请输入司机姓名"
|
||||
hc:InfoElement.Placeholder="请输入物料名称"
|
||||
hc:InfoElement.ShowClearButton="True">
|
||||
<hc:TextBox.InputBindings>
|
||||
<KeyBinding Key="Enter" Command="{Binding SearchCommand}"/>
|
||||
@@ -142,7 +142,8 @@
|
||||
<DataGridTextColumn Header="车牌号" Binding="{Binding PlateNumber}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="110"/>
|
||||
<DataGridTextColumn Header="发货单位" Binding="{Binding SenderUnit}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||
<DataGridTextColumn Header="收货单位" Binding="{Binding ReceiverUnit}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="140"/>
|
||||
<DataGridTextColumn Header="货物名称" Binding="{Binding GoodsName}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="120"/>
|
||||
<DataGridTextColumn Header="密炼物料" Binding="{Binding MixerMaterialNames}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="160"/>
|
||||
<DataGridTextColumn Header="类型" Binding="{Binding MaterialTypeText}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="80"/>
|
||||
<DataGridTextColumn Header="毛重(KG)" Binding="{Binding GrossWeight, StringFormat=N2}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="皮重(KG)" Binding="{Binding TareWeight, StringFormat=N2}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
<DataGridTextColumn Header="净重(KG)" Binding="{Binding NetWeight, StringFormat=N2}" CellStyle="{StaticResource CusDataGridCellStyle}" Width="100"/>
|
||||
|
||||
@@ -389,16 +389,6 @@
|
||||
</hc:Col>
|
||||
<!-- 发货单位(供应商弹窗选择) -->
|
||||
<hc:Col Span="24">
|
||||
<hc:Col.Style>
|
||||
<Style TargetType="hc:Col">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding InoutDirection}" Value="2">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</hc:Col.Style>
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="75"/>
|
||||
@@ -439,16 +429,6 @@
|
||||
</hc:Col>
|
||||
<!-- 收货单位(客户弹窗选择) -->
|
||||
<hc:Col Span="24">
|
||||
<hc:Col.Style>
|
||||
<Style TargetType="hc:Col">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding InoutDirection}" Value="2">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</hc:Col.Style>
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="75"/>
|
||||
@@ -487,6 +467,46 @@
|
||||
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
|
||||
</Grid>
|
||||
</hc:Col>
|
||||
<!-- 密炼物料选择 -->
|
||||
<hc:Col Span="24">
|
||||
<Grid Margin="0,0,0,8">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="75"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="56"/>
|
||||
<ColumnDefinition Width="60"/>
|
||||
<ColumnDefinition Width="32"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="密炼物料" VerticalAlignment="Center"
|
||||
FontSize="14" Foreground="{DynamicResource PrimaryTextBrush}"/>
|
||||
<Border Grid.Column="1" CornerRadius="4" Height="32"
|
||||
BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"
|
||||
Background="{DynamicResource ThirdlyRegionBrush}">
|
||||
<TextBox Text="{Binding MixerMaterialNames, UpdateSourceTrigger=PropertyChanged}"
|
||||
IsReadOnly="{Binding IsMixerMaterialReadOnly}"
|
||||
VerticalContentAlignment="Center"
|
||||
Margin="8,0"
|
||||
BorderThickness="0"
|
||||
Background="Transparent"
|
||||
FontSize="13"
|
||||
ToolTip="勾选“手动”可直接输入密炼物料名称"/>
|
||||
</Border>
|
||||
<CheckBox Grid.Column="2" Content="手动"
|
||||
IsChecked="{Binding IsMixerMaterialManual}"
|
||||
VerticalAlignment="Center"
|
||||
HorizontalAlignment="Center"/>
|
||||
<Button Grid.Column="3" Content="选 择"
|
||||
Command="{Binding OpenMixerMaterialPickerCommand}"
|
||||
Style="{StaticResource ButtonDefault}"
|
||||
Height="32" Margin="6,0,0,0" FontSize="12"/>
|
||||
<Button Grid.Column="4" Command="{Binding ClearMixerMaterialCommand}"
|
||||
Style="{StaticResource ButtonIcon}"
|
||||
Height="32" Width="28" Margin="4,0,0,0" Padding="0"
|
||||
ToolTip="清除选择"
|
||||
Foreground="{DynamicResource SecondaryTextBrush}"
|
||||
hc:IconElement.Geometry="{StaticResource ErrorGeometry}"/>
|
||||
</Grid>
|
||||
</hc:Col>
|
||||
<!-- 司机 -->
|
||||
<hc:Col Span="12">
|
||||
<hc:TextBox Text="{Binding DriverName, UpdateSourceTrigger=PropertyChanged}"
|
||||
|
||||
Reference in New Issue
Block a user