From 1f0495fbe7782e1b5210fa670fa678d83ccae382 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Sun, 5 Oct 2025 19:57:58 +0800 Subject: [PATCH] =?UTF-8?q?=20=20=20=201=20feat:=20=E4=BC=98=E5=8C=96MQTT?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20=20=20=20=202=20=20=20=20=203=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9MQTT=E5=8F=91=E5=B8=83=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=99=A8=EF=BC=8C=E4=BD=BF=E7=94=A8DisplayValue=E4=BB=A3?= =?UTF-8?q?=E6=9B=BFDataValue=E8=BF=9B=E8=A1=8C=E6=95=B0=E6=8D=AE=E5=8F=91?= =?UTF-8?q?=E5=B8=83=20=20=20=20=204=20-=20=E5=9C=A8MqttServiceManager?= =?UTF-8?q?=E4=B8=AD=E4=BD=BF=E7=94=A8DisplayValue=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=86=85=E5=AE=B9=E6=9B=BF=E6=8D=A2=20=20=20?= =?UTF-8?q?=20=205=20-=20=E5=A2=9E=E5=8A=A0MQTT=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BF=AE=E6=94=B9=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=20=20=20=20=206=20-=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8F=98=E9=87=8FMQTT=E5=8F=91=E5=B8=83=E5=88=AB=E5=90=8D?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=8A=9F=E8=83=BD=EF=BC=8C=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=8F=B3=E9=94=AE=E8=8F=9C=E5=8D=95=E4=BF=AE=E6=94=B9=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E5=90=8D=E7=A7=B0=20=20=20=20=207=20-=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E5=8F=98=E9=87=8F=E5=80=BC=E5=8F=98=E5=8C=96=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=9B=91=E5=90=AC=EF=BC=8C=E5=AE=9E=E6=97=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0UI=E6=98=BE=E7=A4=BA=20=20=20=20=208=20-=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96MQTT=E6=9C=8D=E5=8A=A1=E5=99=A8=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2UI=EF=BC=8C=E6=94=B9=E8=BF=9B=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E5=85=B3=E8=81=94=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=20=20=20=20=209=20-=20=E4=BF=AE=E5=A4=8D=E5=8F=98=E9=87=8F?= =?UTF-8?q?=E8=A1=A8=E5=85=B3=E8=81=94MQTT=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E6=97=B6=E7=9A=84=E9=80=BB=E8=BE=91=E9=97=AE=E9=A2=98=20=20=20?= =?UTF-8?q?=2010=20-=20=E5=AE=8C=E5=96=84=E5=AF=BC=E8=88=AA=E7=94=9F?= =?UTF-8?q?=E5=91=BD=E5=91=A8=E6=9C=9F=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Processors/MqttPublishProcessor.cs | 2 +- .../Services/Mqtt/MqttServiceManager.cs | 2 +- .../ViewModels/MqttServerDetailViewModel.cs | 144 ++++++++++++++++++ DMS.WPF/ViewModels/MqttsViewModel.cs | 15 +- DMS.WPF/ViewModels/VariableTableViewModel.cs | 3 +- DMS.WPF/Views/MqttServerDetailView.xaml | 22 +-- 6 files changed, 173 insertions(+), 15 deletions(-) diff --git a/DMS.Application/Services/Processors/MqttPublishProcessor.cs b/DMS.Application/Services/Processors/MqttPublishProcessor.cs index 665345c..e00a85e 100644 --- a/DMS.Application/Services/Processors/MqttPublishProcessor.cs +++ b/DMS.Application/Services/Processors/MqttPublishProcessor.cs @@ -43,7 +43,7 @@ public class MqttPublishProcessor : IVariableProcessor // 发布变量数据到MQTT服务器 var variableMqttAlias = _mapper.Map(variableMqttAliasDto); - variableMqttAlias.Variable.DataValue=variable.DataValue; + variableMqttAlias.Variable.DisplayValue=variable.DisplayValue; await _mqttServiceManager.PublishVariableDataAsync(variableMqttAlias); } } diff --git a/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs b/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs index 67eba68..764e19b 100644 --- a/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs +++ b/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs @@ -275,7 +275,7 @@ namespace DMS.Infrastructure.Services.Mqtt var now = DateTime.Now; var timestamp = ((DateTimeOffset)now).ToUnixTimeMilliseconds(); sb.Append(variableMqtt.MqttServer.MessageHeader.Replace("{timestamp}", timestamp.ToString())); - sb.Append(variableMqtt.MqttServer.MessageContent.Replace("{name}", variableMqtt.Alias).Replace("{value}", variableMqtt.Variable.DataValue)); + sb.Append(variableMqtt.MqttServer.MessageContent.Replace("{name}", variableMqtt.Alias).Replace("{value}", variableMqtt.Variable.DisplayValue)); sb.Append(variableMqtt.MqttServer.MessageFooter); return sb.ToString(); diff --git a/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs b/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs index c66cd5b..9e2fb92 100644 --- a/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs +++ b/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs @@ -1,8 +1,11 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; +using DMS.Application.Events; +using DMS.Application.Interfaces; using DMS.Application.Interfaces.Management; using DMS.Core.Models; using DMS.WPF.Interfaces; +using DMS.WPF.ViewModels.Dialogs; using DMS.WPF.ViewModels.Items; using Microsoft.Extensions.Logging; using System.Collections.ObjectModel; @@ -18,7 +21,9 @@ namespace DMS.WPF.ViewModels private readonly ILogger _logger; private readonly IDialogService _dialogService; private readonly INotificationService _notificationService; + private readonly IEventService _eventService; private readonly IMqttManagementService _mqttManagementService; + private readonly IWPFDataService _wpfDataService; private readonly IDataStorageService _dataStorageService; private readonly INavigationService _navigationService; @@ -47,20 +52,85 @@ namespace DMS.WPF.ViewModels public MqttServerDetailViewModel(ILogger logger, IDialogService dialogService, INotificationService notificationService, + IEventService eventService, IMqttManagementService mqttManagementService, + IWPFDataService wpfDataService, IDataStorageService dataStorageService, INavigationService navigationService) { _logger = logger; _dialogService = dialogService; _notificationService = notificationService; + this._eventService = eventService; _mqttManagementService = mqttManagementService; + this._wpfDataService = wpfDataService; this._dataStorageService = dataStorageService; _navigationService = navigationService; } + /// + /// 编辑当前MQTT服务器 + /// + [RelayCommand] + private async Task EditMqtt() + { + try + { + if (CurrentMqtt == null) + { + _notificationService.ShowError("没有选中的MQTT服务器,无法编辑。"); + return; + } + + // 创建编辑对话框的视图模型 + var mqttDialogViewModel = new MqttDialogViewModel(CurrentMqtt) + { + Title = "编辑MQTT服务器", + PrimaryButText = "保存修改" + }; + + // 显示对话框 + var updatedMqtt = await _dialogService.ShowDialogAsync(mqttDialogViewModel); + + if (updatedMqtt == null) + { + return; // 用户取消了编辑 + } + + // 更新MQTT服务器 + var result = await _wpfDataService.MqttDataService.UpdateMqttServer(updatedMqtt); + + if (result) + { + // 更新当前视图模型的数据 + CurrentMqtt.ServerName = updatedMqtt.ServerName; + CurrentMqtt.ServerUrl = updatedMqtt.ServerUrl; + CurrentMqtt.Port = updatedMqtt.Port; + CurrentMqtt.ClientId = updatedMqtt.ClientId; + CurrentMqtt.Username = updatedMqtt.Username; + CurrentMqtt.Password = updatedMqtt.Password; + CurrentMqtt.PublishTopic = updatedMqtt.PublishTopic; + CurrentMqtt.SubscribeTopic = updatedMqtt.SubscribeTopic; + CurrentMqtt.MessageHeader = updatedMqtt.MessageHeader; + CurrentMqtt.MessageContent = updatedMqtt.MessageContent; + CurrentMqtt.MessageFooter = updatedMqtt.MessageFooter; + + _notificationService.ShowSuccess($"MQTT服务器编辑成功:{updatedMqtt.ServerName}"); + } + else + { + _notificationService.ShowError("更新MQTT服务器失败。"); + } + } + catch (Exception e) + { + _logger.LogError(e, "编辑MQTT服务器过程中发生错误"); + _notificationService.ShowError($"编辑MQTT服务器过程中发生错误:{e.Message}", e); + } + } + /// /// 重新加载当前MQTT服务器数据 /// @@ -107,7 +177,81 @@ namespace DMS.WPF.ViewModels CurrentMqtt = mqttServerItem; } + _eventService.OnVariableValueChanged += OnVariableValueChanged; + return Task.CompletedTask; + } + + private void OnVariableValueChanged(object? sender, VariableValueChangedEventArgs e) + { + + var variableAlias=CurrentMqtt.VariableAliases.FirstOrDefault(v => v.Variable.Id == e.Variable.Id); + if (variableAlias is not null) + { + variableAlias.Variable.DisplayValue=e.Variable.DisplayValue; + variableAlias.Variable.UpdatedAt=e.Variable.UpdatedAt; + + } + } + + /// + /// 修改变量的MQTT发送名称 + /// + [RelayCommand] + private async Task ModifyAlias(VariableMqttAlias variableAlias) + { + if (variableAlias == null) + { + _notificationService.ShowError("请选择要修改的变量项。"); + return; + } + + try + { + // 创建一个用于输入新名称的简单对话框 + var oldAlias = variableAlias.Alias; + InputDialogViewModel viewModel = new InputDialogViewModel("修改发送名称", "请输入新的MQTT发送名称:", oldAlias); + var dialogResult = await _dialogService.ShowDialogAsync(viewModel); + + if (dialogResult != null) // 用户没有取消操作 + { + var newAlias = dialogResult.Trim(); + + if (string.IsNullOrEmpty(newAlias)) + { + _notificationService.ShowWarn("发送名称不能为空。"); + return; + } + + // 更新变量的发送名称 + variableAlias.Alias = newAlias; + + // 保存更改到数据服务 + var result = await _wpfDataService.UpdateMqttServer(CurrentMqtt); + + if (result) + { + _notificationService.ShowSuccess($"变量 '{variableAlias.Variable.Name}' 的发送名称已更新为 '{newAlias}'"); + } + else + { + _notificationService.ShowError("更新发送名称失败。"); + // 如果更新失败,恢复原来的值 + variableAlias.Alias = oldAlias; + } + } + } + catch (Exception e) + { + _logger.LogError(e, "修改变量发送名称时发生错误"); + _notificationService.ShowError($"修改发送名称时发生错误:{e.Message}"); + } + } + + public override Task OnNavigatedFromAsync(NavigationParameter parameter) + { + + _eventService.OnVariableValueChanged -= OnVariableValueChanged; return Task.CompletedTask; } diff --git a/DMS.WPF/ViewModels/MqttsViewModel.cs b/DMS.WPF/ViewModels/MqttsViewModel.cs index 4e9fe54..b9a30ea 100644 --- a/DMS.WPF/ViewModels/MqttsViewModel.cs +++ b/DMS.WPF/ViewModels/MqttsViewModel.cs @@ -184,7 +184,20 @@ public partial class MqttsViewModel : ViewModelBase // 更新UI _mapper.Map(mqtt, SelectedMqtt); - + + // 更新当前视图模型的数据 + mqtt.ServerName = SelectedMqtt.ServerName; + mqtt.ServerUrl = SelectedMqtt.ServerUrl; + mqtt.Port = SelectedMqtt.Port; + mqtt.ClientId = SelectedMqtt.ClientId; + mqtt.Username = SelectedMqtt.Username; + mqtt.Password = SelectedMqtt.Password; + mqtt.PublishTopic = SelectedMqtt.PublishTopic; + mqtt.SubscribeTopic = SelectedMqtt.SubscribeTopic; + mqtt.MessageHeader = SelectedMqtt.MessageHeader; + mqtt.MessageContent = SelectedMqtt.MessageContent; + mqtt.MessageFooter = SelectedMqtt.MessageFooter; + _notificationService.ShowSuccess($"编辑MQTT服务器成功:{mqtt.ServerName}"); } catch (Exception e) diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index 1f15479..de322c8 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -661,7 +661,8 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable MqttServer = selectedMqtt, Variable = originalVariable }; - // originalVariable.MqttAliases.Add(variableMqtt); + originalVariable.MqttAliases.Add(variableMqtt); + selectedMqtt.VariableAliases.Add(variableMqtt); } else { diff --git a/DMS.WPF/Views/MqttServerDetailView.xaml b/DMS.WPF/Views/MqttServerDetailView.xaml index 7f803e2..dcec0ca 100644 --- a/DMS.WPF/Views/MqttServerDetailView.xaml +++ b/DMS.WPF/Views/MqttServerDetailView.xaml @@ -38,14 +38,8 @@ DefaultLabelPosition="Right" IsOpen="False" HorizontalAlignment="Right"> - - - - - - - + @@ -272,18 +266,24 @@ + + + + + + + - + - - +