From 5db88f5709a0b27171e73c34a4497a5978f5bfcb Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Sat, 6 Sep 2025 19:10:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E9=80=89=E6=8B=A9Mqtt=E6=9C=8D=E5=8A=A1=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DMS.WPF/App.xaml.cs | 21 +- DMS.WPF/Services/DialogService.cs | 5 +- .../MqttAliasBatchEditDialogViewModel.cs | 116 ++++++++--- .../Dialogs/MqttSelectionDialogViewModel.cs | 98 +++++++-- .../ViewModels/Items/VariableItemViewModel.cs | 2 +- .../Items/VariableMqttAliasItemViewModel.cs | 3 +- DMS.WPF/ViewModels/VariableTableViewModel.cs | 190 +++++++++--------- .../Dialogs/MqttAliasBatchEditDialog.xaml | 110 +++++++--- .../Dialogs/MqttAliasBatchEditDialog.xaml.cs | 30 ++- .../Views/Dialogs/MqttSelectionDialog.xaml | 54 +++-- .../Views/Dialogs/MqttSelectionDialog.xaml.cs | 46 ++--- 11 files changed, 455 insertions(+), 220 deletions(-) diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index 64c8e68..77c4b1f 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -195,7 +195,16 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddTransient(); + services.AddTransient(provider => + new VariableTableViewModel( + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService() + )); services.AddSingleton(); services.AddSingleton(provider => new MqttsViewModel( @@ -210,10 +219,18 @@ public partial class App : System.Windows.Application ); services.AddScoped(); - // 注册对话框模型 + // 注册对话框视图模型 + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); // 注册View视图 services.AddSingleton(); diff --git a/DMS.WPF/Services/DialogService.cs b/DMS.WPF/Services/DialogService.cs index 1db379f..5fdb4bb 100644 --- a/DMS.WPF/Services/DialogService.cs +++ b/DMS.WPF/Services/DialogService.cs @@ -23,7 +23,10 @@ namespace DMS.WPF.Services { typeof(VariableDialogViewModel), typeof(VariableDialog) }, { typeof(PollLevelDialogViewModel), typeof(PollLevelDialog) }, { typeof(IsActiveDialogViewModel), typeof(IsActiveDialog) }, - { typeof(MqttDialogViewModel), typeof(MqttDialog) }, // Add other mappings here + { typeof(MqttDialogViewModel), typeof(MqttDialog) }, + { typeof(MqttSelectionDialogViewModel), typeof(MqttSelectionDialog) }, + { typeof(MqttAliasBatchEditDialogViewModel), typeof(MqttAliasBatchEditDialog) } + // Add other mappings here // ... other dialogs }; diff --git a/DMS.WPF/ViewModels/Dialogs/MqttAliasBatchEditDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/MqttAliasBatchEditDialogViewModel.cs index f6446f4..35f9ea1 100644 --- a/DMS.WPF/ViewModels/Dialogs/MqttAliasBatchEditDialogViewModel.cs +++ b/DMS.WPF/ViewModels/Dialogs/MqttAliasBatchEditDialogViewModel.cs @@ -1,34 +1,100 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; -using System.Collections.ObjectModel; -using System.Collections.Generic; -using System.Linq; +using DMS.Application.DTOs; using DMS.WPF.ViewModels.Items; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; -namespace DMS.WPF.ViewModels.Dialogs; - -public partial class MqttAliasBatchEditDialogViewModel : ObservableObject +namespace DMS.WPF.ViewModels.Dialogs { - [ObservableProperty] - private string _title = "批量设置MQTT别名"; - - [ObservableProperty] - private ObservableCollection _variablesToEdit; - - public MqttServerItemViewModel SelectedMqtt { get; private set; } - - public MqttAliasBatchEditDialogViewModel(List selectedVariables, MqttServerItemViewModel selectedMqtt) + /// + /// MQTT别名批量编辑对话框的视图模型 + /// + public partial class MqttAliasBatchEditDialogViewModel : DialogViewModelBase> { - SelectedMqtt = selectedMqtt; - Title=$"设置:{SelectedMqtt.ServerName}-MQTT服务器关联变量的别名"; - // VariablesToEdit = new ObservableCollection( - // selectedVariables.Select(v => new VariableMqttAlias(v, selectedMqtt)) - // ); - } + [ObservableProperty] + private ObservableCollection _variableMqttAliases = new(); - public MqttAliasBatchEditDialogViewModel() - { - // For design time - // VariablesToEdit = new ObservableCollection(); + [ObservableProperty] + private MqttServerItemViewModel _selectedMqttServer; + + public MqttAliasBatchEditDialogViewModel( + List variables, + MqttServerItemViewModel mqttServer) + { + _selectedMqttServer = mqttServer; + InitializeVariableMqttAliases(variables); + } + + /// + /// 初始化变量MQTT别名列表 + /// + private void InitializeVariableMqttAliases(List variables) + { + VariableMqttAliases.Clear(); + + foreach (var variable in variables) + { + // 检查该变量是否已经有针对此MQTT服务器的别名 + var existingAlias = variable.MqttAliases?.FirstOrDefault(ma => ma.MqttServerId == SelectedMqttServer.Id); + + var variableMqttAlias = new VariableMqttAliasItemViewModel + { + VariableId = variable.Id, + MqttServerId = SelectedMqttServer.Id, + MqttServerName = SelectedMqttServer.ServerName, + MqttServer = SelectedMqttServer, + Alias = existingAlias?.Alias ?? GenerateDefaultAlias(variable) + }; + + VariableMqttAliases.Add(variableMqttAlias); + } + } + + /// + /// 生成默认别名 + /// + private string GenerateDefaultAlias(VariableItemViewModel variable) + { + // 可以根据需要自定义默认别名生成逻辑 + return $"{variable.Name}_{Guid.NewGuid().ToString("N")[..8]}"; + } + + /// + /// 确认编辑 + /// + [RelayCommand] + private void Confirm() + { + var result = VariableMqttAliases.ToList(); + Close(result); + } + + /// + /// 取消编辑 + /// + [RelayCommand] + private void Cancel() + { + Close(null); + } + + /// + /// 全部应用相同的别名前缀 + /// + [RelayCommand] + private void ApplySamePrefix(string prefix) + { + if (string.IsNullOrWhiteSpace(prefix)) + return; + + foreach (var alias in VariableMqttAliases) + { + alias.Alias = $"{prefix}_{alias.VariableId}"; + } + } } } \ No newline at end of file diff --git a/DMS.WPF/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs index 0efb25d..02fcd2e 100644 --- a/DMS.WPF/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs +++ b/DMS.WPF/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs @@ -1,22 +1,90 @@ -using System.Collections.ObjectModel; using CommunityToolkit.Mvvm.ComponentModel; -using DMS.WPF.Services; +using CommunityToolkit.Mvvm.Input; +using DMS.Application.DTOs; +using DMS.Application.Interfaces; +using DMS.WPF.ViewModels.Items; +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; -namespace DMS.WPF.ViewModels.Dialogs; - -public partial class MqttSelectionDialogViewModel : ObservableObject +namespace DMS.WPF.ViewModels.Dialogs { + /// + /// MQTT服务器选择对话框的视图模型 + /// + public partial class MqttSelectionDialogViewModel : DialogViewModelBase + { + private readonly IMqttAppService _mqttAppService; - // [ObservableProperty] - // private ObservableCollection mqtts; - // - // [ObservableProperty] - // private Mqtt? selectedMqtt; - // - // public MqttSelectionDialogViewModel(DataServices _dataServices) - // { - // Mqtts = new ObservableCollection(_dataServices.Mqtts); - // } + [ObservableProperty] + private ObservableCollection _mqttServers = new(); + [ObservableProperty] + private MqttServerItemViewModel _selectedMqttServer; + public MqttSelectionDialogViewModel(IMqttAppService mqttAppService) + { + _mqttAppService = mqttAppService; + LoadMqttServersAsync(); + } + + /// + /// 异步加载所有MQTT服务器 + /// + private async void LoadMqttServersAsync() + { + try + { + var mqttServerDtos = await _mqttAppService.GetAllMqttServersAsync(); + MqttServers.Clear(); + + foreach (var dto in mqttServerDtos) + { + MqttServers.Add(new MqttServerItemViewModel + { + Id = dto.Id, + ServerName = dto.ServerName, + ServerUrl = dto.ServerUrl, + Port = dto.Port, + Username = dto.Username, + Password = dto.Password, + IsActive = dto.IsActive, + SubscribeTopic = dto.SubscribeTopic, + PublishTopic = dto.PublishTopic, + ClientId = dto.ClientId, + CreatedAt = dto.CreatedAt, + ConnectedAt = dto.ConnectedAt, + ConnectionDuration = dto.ConnectionDuration, + MessageFormat = dto.MessageFormat + }); + } + } + catch (Exception ex) + { + // 记录错误日志 + System.Console.WriteLine($"加载MQTT服务器失败: {ex.Message}"); + } + } + + /// + /// 确认选择 + /// + [RelayCommand] + private void Confirm() + { + if (SelectedMqttServer != null) + { + Close(SelectedMqttServer); + } + } + + /// + /// 取消选择 + /// + [RelayCommand] + private void Cancel() + { + Close(null); + } + } } \ No newline at end of file diff --git a/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs b/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs index 0ff8f44..a20545c 100644 --- a/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs +++ b/DMS.WPF/ViewModels/Items/VariableItemViewModel.cs @@ -60,7 +60,7 @@ public partial class VariableItemViewModel : ObservableObject /// 一个变量可以有多个MQTT别名。 /// [ObservableProperty] - private List? _mqttAliases; + private List? _mqttAliases; /// /// 获取或设置变量的信号类型 (如:AI, DI, AO, DO)。 diff --git a/DMS.WPF/ViewModels/Items/VariableMqttAliasItemViewModel.cs b/DMS.WPF/ViewModels/Items/VariableMqttAliasItemViewModel.cs index 6d94eba..5d612ad 100644 --- a/DMS.WPF/ViewModels/Items/VariableMqttAliasItemViewModel.cs +++ b/DMS.WPF/ViewModels/Items/VariableMqttAliasItemViewModel.cs @@ -18,6 +18,7 @@ public partial class VariableMqttAliasItemViewModel : ObservableObject [ObservableProperty] private string _alias; - + [ObservableProperty] + private MqttServerItemViewModel _mqttServer; } diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index 89da75b..5775c28 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -27,6 +27,8 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable private readonly IDialogService _dialogService; private readonly IVariableAppService _variableAppService; + private readonly IMqttAliasAppService _mqttAliasAppService; + private readonly IMqttAppService _mqttAppService; /// /// 当前正在操作的变量表实体。 @@ -89,11 +91,14 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable private readonly INotificationService _notificationService; public VariableTableViewModel(IMapper mapper, IDialogService dialogService, IVariableAppService variableAppService, + IMqttAliasAppService mqttAliasAppService, IMqttAppService mqttAppService, DataServices dataServices, INotificationService notificationService) { _mapper = mapper; _dialogService = dialogService; _variableAppService = variableAppService; + _mqttAliasAppService = mqttAliasAppService; + _mqttAppService = mqttAppService; _dataServices = dataServices; _notificationService = notificationService; IsLoadCompletion = false; // 初始设置为 false,表示未完成加载 @@ -556,101 +561,96 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable [RelayCommand] public async Task AddMqttServerToVariables(IList variablesToAddMqtt) { - // var validVariables = variablesToAddMqtt?.OfType() - // .ToList(); - // - // // 检查是否有变量被选中 - // if (validVariables == null || !validVariables.Any()) - // { - // NotificationHelper.ShowInfo("请选择要添加MQTT服务器的变量"); - // return; - // } - // - // try - // { - // // 显示MQTT服务器选择对话框,让用户选择一个MQTT服务器 - // var selectedMqtt = await _dialogService.ShowMqttSelectionDialog(); - // if (selectedMqtt == null) - // { - // return; // 用户取消选择 - // } - // - // // 显示批量编辑别名对话框 - // var editedVariableMqtts = await _dialogService.ShowMqttAliasBatchEditDialog(validVariables, selectedMqtt); - // - // if (editedVariableMqtts == null || !editedVariableMqtts.Any()) - // { - // NotificationHelper.ShowInfo("没有变量别名被设置或已取消。"); - // return; - // } - // - // - // int totalAffectedCount = 0; - // // 调用仓库方法来添加或更新MQTT服务器关联和别名 - // var resCount = await _varDataRepository.AddMqttToVariablesAsync(editedVariableMqtts); - // totalAffectedCount += resCount; - // - // - // //更新变量Variable的VariableMqtts列表 - // foreach (var editedVariableMqtt in editedVariableMqtts) - // { - // // 更新内存中的 Variable 对象 - // var originalVariable = VariableTable.Variables.FirstOrDefault(v=>v.Id==editedVariableMqtt.Variable.Id); - // if (originalVariable == null) - // { - // NlogHelper.Warn($"没有在VariableTable.Variables中找到,ID:{editedVariableMqtt.Variable.Id},Name:{editedVariableMqtt.Variable.Name}的对象"); - // continue; - // } - // - // - // if (originalVariable.VariableMqtts == null) - // { - // originalVariable.VariableMqtts = new List(); - // } - // - // // 检查是否已存在该变量与该MQTT服务器的关联 - // var existingVariableMqtt - // = originalVariable.VariableMqtts.FirstOrDefault(vm => vm.MqttId == - // editedVariableMqtt.Mqtt.Id); - // - // if (existingVariableMqtt == null) - // { - // // 如果不存在,则添加新的关联 - // var variableMqtt = new VariableMqtt(originalVariable,editedVariableMqtt.Mqtt) - // { - // VariableId = originalVariable.Id, - // MqttId = editedVariableMqtt.Mqtt.Id, - // MqttAlias = editedVariableMqtt.MqttAlias, - // Mqtt = editedVariableMqtt.Mqtt // 关联Mqtt对象,方便UI显示 - // }; - // originalVariable.VariableMqtts.Add(variableMqtt); - // //更新MQTT服务器对应的的VariableMqtts列表 - // selectedMqtt.VariableMqtts.Add(variableMqtt); - // } - // else - // { - // // 如果存在,则更新别名 - // existingVariableMqtt.MqttAlias = editedVariableMqtt.MqttAlias; - // } - // } - // - // - // if (totalAffectedCount > 0) - // { - // // 刷新界面以反映更改 - // await RefreshDataView(); - // NotificationHelper.ShowSuccess($"已成功为 {totalAffectedCount} 个变量添加/更新MQTT服务器: {selectedMqtt.Name} 的别名。"); - // } - // else - // { - // NotificationHelper.ShowInfo($"没有新的变量关联或别名更新到MQTT服务器: {selectedMqtt.Name}。"); - // } - // } - // catch (Exception ex) - // { - // // 捕获并显示错误通知 - // NotificationHelper.ShowError($"添加MQTT服务器失败: {ex.Message}", ex); - // } + var validVariables = variablesToAddMqtt?.OfType() + .ToList(); + + // 检查是否有变量被选中 + if (validVariables == null || !validVariables.Any()) + { + _notificationService.ShowInfo("请选择要添加MQTT服务器的变量"); + return; + } + + try + { + // 显示MQTT服务器选择对话框,让用户选择一个MQTT服务器 + var mqttSelectionViewModel = new MqttSelectionDialogViewModel(_mqttAppService); + var selectedMqtt = await _dialogService.ShowDialogAsync(mqttSelectionViewModel); + if (selectedMqtt == null) + { + return; // 用户取消选择 + } + + // 显示批量编辑别名对话框 + var mqttAliasBatchEditViewModel = new MqttAliasBatchEditDialogViewModel(validVariables, selectedMqtt); + var editedVariableMqtts = await _dialogService.ShowDialogAsync(mqttAliasBatchEditViewModel); + + if (editedVariableMqtts == null || !editedVariableMqtts.Any()) + { + _notificationService.ShowInfo("没有变量别名被设置或已取消。"); + return; + } + + int totalAffectedCount = 0; + + // 为每个变量分配MQTT别名 + foreach (var editedVariableMqtt in editedVariableMqtts) + { + await _mqttAliasAppService.AssignAliasAsync( + editedVariableMqtt.VariableId, + selectedMqtt.Id, + editedVariableMqtt.Alias); + + totalAffectedCount++; + + // 更新内存中的 Variable 对象 + var originalVariable = validVariables.FirstOrDefault(v => v.Id == editedVariableMqtt.VariableId); + if (originalVariable == null) + { + continue; + } + + if (originalVariable.MqttAliases == null) + { + originalVariable.MqttAliases = new (); + } + + // 检查是否已存在该变量与该MQTT服务器的关联 + var existingVariableMqtt = originalVariable.MqttAliases.FirstOrDefault(vm => vm.MqttServerId == selectedMqtt.Id); + + if (existingVariableMqtt == null) + { + // 如果不存在,则添加新的关联 + var variableMqtt = new VariableMqttAliasItemViewModel + { + VariableId = originalVariable.Id, + MqttServerId = selectedMqtt.Id, + Alias = editedVariableMqtt.Alias, + MqttServer = selectedMqtt + }; + // originalVariable.MqttAliases.Add(variableMqtt); + } + else + { + // 如果存在,则更新别名 + existingVariableMqtt.Alias = editedVariableMqtt.Alias; + } + } + + if (totalAffectedCount > 0) + { + _notificationService.ShowSuccess($"已成功为 {totalAffectedCount} 个变量添加/更新MQTT服务器: {selectedMqtt.ServerName} 的别名。"); + } + else + { + _notificationService.ShowInfo($"没有新的变量关联或别名更新到MQTT服务器: {selectedMqtt.ServerName}。"); + } + } + catch (Exception ex) + { + // 捕获并显示错误通知 + _notificationService.ShowError($"添加MQTT服务器失败: {ex.Message}", ex); + } } /// diff --git a/DMS.WPF/Views/Dialogs/MqttAliasBatchEditDialog.xaml b/DMS.WPF/Views/Dialogs/MqttAliasBatchEditDialog.xaml index a2610d2..e38d583 100644 --- a/DMS.WPF/Views/Dialogs/MqttAliasBatchEditDialog.xaml +++ b/DMS.WPF/Views/Dialogs/MqttAliasBatchEditDialog.xaml @@ -1,38 +1,86 @@ - - - 设置的别名,当变量向MQTT服务器发送数据时就会按照设置设置好的别名发送,请在MQTT服务端,按照设置的名称接受。 - + + + + + + + + + + + + + + + + + + Margin="0,0,0,10" + MinHeight="300" + MaxHeight="500"> - - - - - - - - - + + - + + + + + + + + + + + + + + +