From de21b0073c08027375dd0927ab228741720cd525 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Sat, 5 Jul 2025 22:57:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86Mqtt=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E8=AF=A6=E6=83=85=E9=A1=B5=E7=9A=84=E7=AE=80?= =?UTF-8?q?=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.xaml.cs | 1 + Data/Repositories/MqttRepository.cs | 2 +- Data/Repositories/VarDataRepository.cs | 21 +-- Models/Mqtt.cs | 5 + ValueConverts/EnumDescriptionConverter.cs | 2 + ViewModels/MainViewModel.cs | 6 + ViewModels/MqttServerDetailViewModel.cs | 152 ++++++++++++++++++++++ ViewModels/MqttsViewModel.cs | 19 ++- ViewModels/VariableTableViewModel.cs | 2 +- Views/MainView.xaml | 4 + Views/MqttServerDetailView.xaml | 109 ++++++++++++++++ Views/MqttsView.xaml | 7 + 12 files changed, 319 insertions(+), 11 deletions(-) create mode 100644 ViewModels/MqttServerDetailViewModel.cs create mode 100644 Views/MqttServerDetailView.xaml diff --git a/App.xaml.cs b/App.xaml.cs index 57b332f..0fc4f2c 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -89,6 +89,7 @@ public partial class App : Application services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); } private void ConfigureLogging(ILoggingBuilder loggingBuilder) diff --git a/Data/Repositories/MqttRepository.cs b/Data/Repositories/MqttRepository.cs index af357ff..ba3b355 100644 --- a/Data/Repositories/MqttRepository.cs +++ b/Data/Repositories/MqttRepository.cs @@ -55,7 +55,7 @@ public class MqttRepository stopwatch.Start(); using (var _db = DbContext.GetInstance()) { - var result = await _db.Queryable() + var result = await _db.Queryable().Includes(m=>m.VariableDatas) .ToListAsync(); stopwatch.Stop(); Logger.Info($"获取所有Mqtt配置耗时:{stopwatch.ElapsedMilliseconds}ms"); diff --git a/Data/Repositories/VarDataRepository.cs b/Data/Repositories/VarDataRepository.cs index 102d069..aad5bd5 100644 --- a/Data/Repositories/VarDataRepository.cs +++ b/Data/Repositories/VarDataRepository.cs @@ -50,7 +50,8 @@ public class VarDataRepository .ToListAsync(); stopwatch.Stop(); Logger.Info($"获取所有VariableData耗时:{stopwatch.ElapsedMilliseconds}ms"); - return result.Select(d=>d.CopyTo()).ToList(); + return result.Select(d => d.CopyTo()) + .ToList(); } } @@ -139,7 +140,8 @@ public class VarDataRepository stopwatch.Start(); Stopwatch stopwatch2 = new Stopwatch(); stopwatch2.Start(); - var dbList = variableDatas.Select(vb => vb.CopyTo()).ToList(); + var dbList = variableDatas.Select(vb => vb.CopyTo()) + .ToList(); stopwatch2.Stop(); Logger.Info($"复制 VariableData'{variableDatas.Count()}'个, 耗时:{stopwatch2.ElapsedMilliseconds}ms"); @@ -157,13 +159,14 @@ public class VarDataRepository /// /// VariableData实体 /// - public async Task UpdateAsync(VariableData variableData) + public async Task UpdateAsync(VariableData variableData) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); using (var _db = DbContext.GetInstance()) { - var result = await _db.Updateable(variableData.CopyTo()) + var result = await _db.UpdateNav(variableData.CopyTo()) + .Include(d => d.Mqtts) .ExecuteCommandAsync(); stopwatch.Stop(); Logger.Info($"更新VariableData '{variableData.Name}' 耗时:{stopwatch.ElapsedMilliseconds}ms"); @@ -176,7 +179,7 @@ public class VarDataRepository /// /// VariableData实体 /// - public async Task UpdateAsync(List variableDatas) + public async Task UpdateAsync(List variableDatas) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); @@ -195,13 +198,14 @@ public class VarDataRepository /// /// VariableData实体 /// - public async Task UpdateAsync(List variableDatas, SqlSugarClient db) + public async Task UpdateAsync(List variableDatas, SqlSugarClient db) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); var dbVarDatas = variableDatas.Select(vd => vd.CopyTo()); - var result = await db.Updateable(dbVarDatas.ToList()) + var result = await db.UpdateNav(dbVarDatas.ToList()) + .Include(d => d.Mqtts) .ExecuteCommandAsync(); stopwatch.Stop(); @@ -273,7 +277,8 @@ public class VarDataRepository stopwatch.Start(); using var _db = DbContext.GetInstance(); - var dbList = variableDatas.Select(vd => vd.CopyTo()).ToList(); + var dbList = variableDatas.Select(vd => vd.CopyTo()) + .ToList(); var result = await _db.Deleteable(dbList) .ExecuteCommandAsync(); stopwatch.Stop(); diff --git a/Models/Mqtt.cs b/Models/Mqtt.cs index e77d8a7..2bb2e5e 100644 --- a/Models/Mqtt.cs +++ b/Models/Mqtt.cs @@ -76,4 +76,9 @@ public class Mqtt /// MQTT客户端登录用户名。 /// public string UserName { get; set; } + + /// + /// 关联的变量数据列表。 + /// + public List? VariableDatas { get; set; } } \ No newline at end of file diff --git a/ValueConverts/EnumDescriptionConverter.cs b/ValueConverts/EnumDescriptionConverter.cs index abd7a86..33bbfb4 100644 --- a/ValueConverts/EnumDescriptionConverter.cs +++ b/ValueConverts/EnumDescriptionConverter.cs @@ -22,6 +22,8 @@ public class EnumDescriptionConverter : IValueConverter private string GetEnumDescription(object enumObj) { + if (enumObj == null) return null; // Add null check here + var fi = enumObj.GetType().GetField(enumObj.ToString()); var attributes = diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs index 428010f..51b4613 100644 --- a/ViewModels/MainViewModel.cs +++ b/ViewModels/MainViewModel.cs @@ -175,6 +175,12 @@ public partial class MainViewModel : ViewModelBase await AddVariableTable(menu); return; break; + // 导航到Mqtt服务器 + case MenuType.MqttMenu: + var mqttVM = App.Current.Services.GetRequiredService(); + mqttVM.CurrentMqtt=_dataServices.Mqtts.FirstOrDefault(d=>d.Id == menu.DataId); + menu.ViewModel = mqttVM; + break; } diff --git a/ViewModels/MqttServerDetailViewModel.cs b/ViewModels/MqttServerDetailViewModel.cs new file mode 100644 index 0000000..e137213 --- /dev/null +++ b/ViewModels/MqttServerDetailViewModel.cs @@ -0,0 +1,152 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using Microsoft.Extensions.Logging; +using PMSWPF.Models; +using PMSWPF.Services; +using PMSWPF.Helper; +using PMSWPF.Enums; +using System.Collections.ObjectModel; +using System.Linq; +using System.Threading.Tasks; +using System.Collections.Generic; + +namespace PMSWPF.ViewModels +{ + /// + /// MQTT服务器详情视图模型。 + /// 负责管理单个MQTT服务器的配置及其关联的变量数据。 + /// + public partial class MqttServerDetailViewModel : ViewModelBase + { + private readonly ILogger _logger; + private readonly DataServices _dataServices; + private readonly IDialogService _dialogService; + + /// + /// 当前正在编辑的MQTT服务器对象。 + /// + [ObservableProperty] + private Mqtt _currentMqtt; + + /// + /// 与当前MQTT服务器关联的变量数据集合。 + /// + [ObservableProperty] + private ObservableCollection _associatedVariables; + + /// + /// 构造函数。 + /// + /// 日志服务。 + /// 数据服务。 + /// 对话框服务。 + public MqttServerDetailViewModel(ILogger logger, DataServices dataServices, + IDialogService dialogService) + { + _logger = logger; + _dataServices = dataServices; + _dialogService = dialogService; + AssociatedVariables = new ObservableCollection(); + } + + public override void OnLoaded() + { + if (CurrentMqtt.VariableDatas != null) + { + AssociatedVariables = new ObservableCollection(CurrentMqtt.VariableDatas); + } + } + + + /// + /// 保存MQTT服务器及其关联变量的更改。 + /// + [RelayCommand] + private async Task SaveChanges() + { + if (CurrentMqtt == null) return; + + // TODO: 实现保存逻辑。这可能涉及到更新Mqtt对象和更新VariableData对象。 + // 由于Mqtt和VariableData之间的关联可能在数据库中通过中间表维护, + // 这里需要根据实际的数据库操作来调整。 + // 例如,如果Mqtt对象本身包含关联的VariableData列表,则直接保存Mqtt对象即可。 + // 如果是多对多关系,可能需要更新中间表。 + + // 示例:假设Mqtt对象需要更新 + // await _dataServices.UpdateMqttAsync(CurrentMqtt); + + // 示例:假设变量数据也需要保存 + // foreach (var variable in AssociatedVariables.Where(v => v.IsModified)) + // { + // await _dataServices.UpdateVariableDataAsync(variable); + // } + + NotificationHelper.ShowMessage("MQTT服务器详情保存功能待实现。", NotificationType.Info); + _logger.LogInformation("Save changes for MQTT server detail initiated."); + } + + /// + /// 从当前MQTT服务器中移除选定的变量。 + /// + /// 要移除的变量列表。 + [RelayCommand] + private async Task RemoveVariables(System.Collections.IList variablesToRemove) + { + if (CurrentMqtt == null || variablesToRemove == null || variablesToRemove.Count == 0) + { + NotificationHelper.ShowMessage("请选择要移除的变量。", NotificationType.Warning); + return; + } + + var variablesList = variablesToRemove.Cast() + .ToList(); + + var result = await _dialogService.ShowConfrimeDialog( + "确认移除", $"确定要从MQTT服务器 '{CurrentMqtt.Name}' 中移除选定的 {variablesList.Count} 个变量吗?"); + if (result != true) return; + + foreach (var variable in variablesList) // 使用ToList()避免在迭代时修改集合 + { + // 移除变量与当前MQTT服务器的关联 + variable.Mqtts?.Remove(CurrentMqtt); + // 标记变量为已修改,以便保存时更新数据库 + variable.IsModified = true; + AssociatedVariables.Remove(variable); + _logger.LogInformation($"Removed variable {variable.Name} from MQTT server {CurrentMqtt.Name}."); + } + + // TODO: 这里需要调用DataServices来更新数据库中VariableData的Mqtt关联 + // 例如:await _dataServices.UpdateVariableDataAssociationsAsync(variablesToRemove); + NotificationHelper.ShowMessage("变量移除成功,请记得保存更改。", NotificationType.Success); + } + + /// + /// 添加变量到当前MQTT服务器。 + /// + [RelayCommand] + private async Task AddVariables() + { + if (CurrentMqtt == null) return; + + // TODO: 实现选择变量的对话框,让用户选择要添加的变量 + // 例如:var selectedVariables = await _dialogService.ShowVariableSelectionDialogAsync(); + // 这里只是一个占位符,实际需要一个UI来选择变量 + NotificationHelper.ShowMessage("添加变量功能待实现,需要一个变量选择对话框。", NotificationType.Info); + _logger.LogInformation("Add variables to MQTT server initiated."); + + // 假设我们已经通过对话框获取到了一些要添加的变量 + // List newVariables = ...; + // foreach (var variable in newVariables) + // { + // if (variable.Mqtts == null) variable.Mqtts = new List(); + // if (!variable.Mqtts.Any(m => m.Id == CurrentMqtt.Id)) + // { + // variable.Mqtts.Add(CurrentMqtt); + // variable.IsModified = true; // 标记为已修改 + // AssociatedVariables.Add(variable); + // } + // } + // NotificationHelper.ShowMessage("变量添加成功,请记得保存更改。", NotificationType.Success); + } + } +} \ No newline at end of file diff --git a/ViewModels/MqttsViewModel.cs b/ViewModels/MqttsViewModel.cs index b39eb51..2b4ac6d 100644 --- a/ViewModels/MqttsViewModel.cs +++ b/ViewModels/MqttsViewModel.cs @@ -8,6 +8,7 @@ using PMSWPF.Enums; using PMSWPF.Helper; using PMSWPF.Models; using PMSWPF.Services; +using PMSWPF.Views; namespace PMSWPF.ViewModels; @@ -17,6 +18,7 @@ public partial class MqttsViewModel : ViewModelBase private readonly IDialogService _dialogService; private readonly MqttRepository _mqttRepository; private readonly ILogger _logger; + private readonly NavgatorServices _navgatorServices; [ObservableProperty] private ObservableCollection _mqtts; @@ -25,13 +27,14 @@ public partial class MqttsViewModel : ViewModelBase private Mqtt _selectedMqtt; public MqttsViewModel( - ILogger logger, IDialogService dialogService, DataServices dataServices + ILogger logger, IDialogService dialogService, DataServices dataServices, NavgatorServices navgatorServices ) { _mqttRepository = new MqttRepository(); _logger = logger; _dialogService = dialogService; _dataServices = dataServices; + _navgatorServices = navgatorServices; if (dataServices.Mqtts == null || dataServices.Mqtts.Count == 0) { @@ -124,4 +127,18 @@ public partial class MqttsViewModel : ViewModelBase _logger.LogError($"编辑MQTT的过程中发生错误:{e}"); } } + + /// + /// 导航到MQTT服务器详情页面。 + /// + [RelayCommand] + private void NavigateToMqttDetail() + { + // if (SelectedMqtt == null) + // { + // NotificationHelper.ShowMessage("请选择一个MQTT服务器以查看详情。", NotificationType.Warning); + // return; + // } + // _navgatorServices.NavigateTo(SelectedMqtt); + } } \ No newline at end of file diff --git a/ViewModels/VariableTableViewModel.cs b/ViewModels/VariableTableViewModel.cs index 777de60..8dfa127 100644 --- a/ViewModels/VariableTableViewModel.cs +++ b/ViewModels/VariableTableViewModel.cs @@ -309,7 +309,7 @@ partial class VariableTableViewModel : ViewModelBase if (!variable.Mqtts.Any(m => m.Id == selectedMqtt.Id)) { variable.Mqtts.Add(selectedMqtt); - variable.IsModified = true; // 标记为已修改 + // variable.IsModified = true; // 标记为已修改 } } diff --git a/Views/MainView.xaml b/Views/MainView.xaml index 5c7e1c3..f2bcbc7 100644 --- a/Views/MainView.xaml +++ b/Views/MainView.xaml @@ -92,6 +92,10 @@ + + + + diff --git a/Views/MqttServerDetailView.xaml b/Views/MqttServerDetailView.xaml new file mode 100644 index 0000000..8318c2b --- /dev/null +++ b/Views/MqttServerDetailView.xaml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +