From 6c37a4a9279770468746eeecc671dae58f1d3f8a Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Sat, 5 Jul 2025 18:15:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=99=E5=8F=98=E9=87=8F=E6=B7=BB=E5=8A=A0Mq?= =?UTF-8?q?tt=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.xaml.cs | 2 +- Extensions/ObjectExtensions.cs | 56 ++++++++++++++++++- Services/DialogService.cs | 12 ++++ Services/IDialogService.cs | 2 +- .../Dialogs/MqttSelectionDialogViewModel.cs | 41 ++++++++++++++ ViewModels/MqttsViewModel.cs | 1 + ViewModels/VariableTableViewModel.cs | 42 ++++++++++++++ Views/Dialogs/MqttSelectionDialog.xaml | 21 +++++++ Views/VariableTableView.xaml | 6 ++ Views/VariableTableView.xaml.cs | 23 ++++++++ 10 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 ViewModels/Dialogs/MqttSelectionDialogViewModel.cs create mode 100644 Views/Dialogs/MqttSelectionDialog.xaml diff --git a/App.xaml.cs b/App.xaml.cs index a6cc4a5..47f5785 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -52,7 +52,7 @@ public partial class App : Application InitializeMenu() .Await((e) => { NotificationHelper.ShowMessage($"初始化主菜单失败:{e.Message}"); }, () => { MessageHelper.SendLoadMessage(LoadTypes.Menu); }); - + Host.Services.GetRequiredService(); MainWindow = Host.Services.GetRequiredService(); MainWindow.Show(); } diff --git a/Extensions/ObjectExtensions.cs b/Extensions/ObjectExtensions.cs index dd7ffe5..edabfaa 100644 --- a/Extensions/ObjectExtensions.cs +++ b/Extensions/ObjectExtensions.cs @@ -1,5 +1,8 @@ using System.Collections; using System.Reflection; +using PMSWPF.Models; +using PMSWPF.Data.Entities; +using PMSWPF.Helper; namespace PMSWPF.Extensions; @@ -60,6 +63,16 @@ public static class ObjectExtensions PropertyInfo targetProperty = targetType.GetProperty(sourceProperty.Name, BindingFlags.Public | BindingFlags.Instance); + // 特殊处理 Mqtt.ConnTime 和 DbMqtt.CreateTime 的映射 + if (sourceProperty.Name == "ConnTime" && targetType == typeof(DbMqtt)) + { + targetProperty = targetType.GetProperty("CreateTime", BindingFlags.Public | BindingFlags.Instance); + } + else if (sourceProperty.Name == "CreateTime" && targetType == typeof(Mqtt)) + { + targetProperty = targetType.GetProperty("ConnTime", BindingFlags.Public | BindingFlags.Instance); + } + // 确保目标属性存在且可写 if (targetProperty != null && targetProperty.CanWrite) { @@ -78,7 +91,48 @@ public static class ObjectExtensions // 场景 2: 属性类型不同,但可能是泛型 List 类型 else if (isTargetList && isSourceList) { - CopyGenericList(ttarget, sourceProperty, targetProperty, sourceValue); + // 特殊处理 Mqtts 列表的复制 + if (sourceProperty.Name == "Mqtts") + { + if (sourceType == typeof(VariableData) && targetType == typeof(DbVariableData)) + { + // 从 VariableData (List) 转换为 DbVariableData (List) + var sourceMqtts = sourceValue as List; + if (sourceMqtts != null) + { + var targetMqtts = sourceMqtts.Select(m => m.CopyTo()).ToList(); + targetProperty.SetValue(ttarget, targetMqtts); + } + else + { + targetProperty.SetValue(ttarget, null); + } + } + else if (sourceType == typeof(DbVariableData) && targetType == typeof(VariableData)) + { + // 从 DbVariableData (List) 转换为 VariableData (List) + var sourceDbMqtts = sourceValue as List; + if (sourceDbMqtts != null) + { + var targetMqtts = sourceDbMqtts.Select(m => m.CopyTo()).ToList(); + targetProperty.SetValue(ttarget, targetMqtts); + } + else + { + targetProperty.SetValue(ttarget, null); + } + } + else + { + // 其他 List 类型,使用通用复制逻辑 + CopyGenericList(ttarget, sourceProperty, targetProperty, sourceValue); + } + } + else + { + // 其他 List 类型,使用通用复制逻辑 + CopyGenericList(ttarget, sourceProperty, targetProperty, sourceValue); + } } // 场景 3: 属性类型不同,但是属性名称一样 else diff --git a/Services/DialogService.cs b/Services/DialogService.cs index f3373ae..e2a5f38 100644 --- a/Services/DialogService.cs +++ b/Services/DialogService.cs @@ -171,4 +171,16 @@ public class DialogService :IDialogService } return null; } + + public async Task ShowMqttSelectionDialog() + { + var vm = new MqttSelectionDialogViewModel(); + var dialog = new MqttSelectionDialog(vm); + var result = await dialog.ShowAsync(); + if (result == ContentDialogResult.Primary) + { + return vm.SelectedMqtt; + } + return null; + } } \ No newline at end of file diff --git a/Services/IDialogService.cs b/Services/IDialogService.cs index 96b8436..925b516 100644 --- a/Services/IDialogService.cs +++ b/Services/IDialogService.cs @@ -21,5 +21,5 @@ public interface IDialogService Task ShowImportExcelDialog(); ContentDialog ShowProcessingDialog(string title, string message); Task ShowPollLevelDialog(PollLevelType pollLevelType); - + Task ShowMqttSelectionDialog(); } \ No newline at end of file diff --git a/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs b/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs new file mode 100644 index 0000000..c540565 --- /dev/null +++ b/ViewModels/Dialogs/MqttSelectionDialogViewModel.cs @@ -0,0 +1,41 @@ +using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.ComponentModel; +using PMSWPF.Models; +using PMSWPF.Data.Repositories; +using System.Threading.Tasks; + +namespace PMSWPF.ViewModels.Dialogs; + +public partial class MqttSelectionDialogViewModel : ObservableObject +{ + private readonly MqttRepository _mqttRepository; + + [ObservableProperty] + private ObservableCollection mqtts; + + [ObservableProperty] + private Mqtt? selectedMqtt; + + public MqttSelectionDialogViewModel() + { + _mqttRepository = new MqttRepository(); + LoadMqtts(); + } + + private async void LoadMqtts() + { + try + { + var allMqtts = await _mqttRepository.GetAll(); + Mqtts = new ObservableCollection(allMqtts); + } + catch (Exception ex) + { + // 这里需要一个日志记录器,但由于ViewModel中没有直接注入ILogger, + // 暂时使用Console.WriteLine或NotificationHelper + // 更好的做法是注入ILogger或使用静态日志类 + Console.WriteLine($"加载MQTT服务器列表失败: {ex.Message}"); + // 或者使用NotificationHelper.ShowMessage("加载MQTT服务器列表失败", NotificationType.Error); + } + } +} \ No newline at end of file diff --git a/ViewModels/MqttsViewModel.cs b/ViewModels/MqttsViewModel.cs index 23b5305..f5389c3 100644 --- a/ViewModels/MqttsViewModel.cs +++ b/ViewModels/MqttsViewModel.cs @@ -62,6 +62,7 @@ public partial class MqttsViewModel : ViewModelBase } await _mqttRepository.Add(mqtt); + MessageHelper.SendLoadMessage(LoadTypes.Mqtts); } catch (Exception e) { diff --git a/ViewModels/VariableTableViewModel.cs b/ViewModels/VariableTableViewModel.cs index f7c7f39..777de60 100644 --- a/ViewModels/VariableTableViewModel.cs +++ b/ViewModels/VariableTableViewModel.cs @@ -282,6 +282,48 @@ partial class VariableTableViewModel : ViewModelBase } } + [RelayCommand] + public async Task AddMqttServerToVariables(IList variablesToAddMqtt) + { + if (variablesToAddMqtt == null || !variablesToAddMqtt.Any()) + { + NotificationHelper.ShowMessage("请选择要添加MQTT服务器的变量", NotificationType.Warning); + return; + } + + try + { + var selectedMqtt = await _dialogService.ShowMqttSelectionDialog(); + if (selectedMqtt == null) + { + return; // 用户取消选择 + } + + foreach (VariableData variable in variablesToAddMqtt) + { + if (variable.Mqtts == null) + { + variable.Mqtts = new List(); + } + // 避免重复添加 + if (!variable.Mqtts.Any(m => m.Id == selectedMqtt.Id)) + { + variable.Mqtts.Add(selectedMqtt); + variable.IsModified = true; // 标记为已修改 + } + } + + // 批量更新数据库 + await _varDataRepository.UpdateAsync(variablesToAddMqtt.ToList()); + NotificationHelper.ShowMessage($"已成功为 {variablesToAddMqtt.Count} 个变量添加MQTT服务器: {selectedMqtt.Name}", NotificationType.Success); + } + catch (Exception ex) + { + Logger.Error(ex, "添加MQTT服务器到变量时发生错误。"); + NotificationHelper.ShowMessage($"添加MQTT服务器失败: {ex.Message}", NotificationType.Error); + } + } + // [RelayCommand] // private async void ImportFromExcel() // { diff --git a/Views/Dialogs/MqttSelectionDialog.xaml b/Views/Dialogs/MqttSelectionDialog.xaml new file mode 100644 index 0000000..106a67e --- /dev/null +++ b/Views/Dialogs/MqttSelectionDialog.xaml @@ -0,0 +1,21 @@ + + + + + \ No newline at end of file diff --git a/Views/VariableTableView.xaml b/Views/VariableTableView.xaml index 4d729d5..05b3e46 100644 --- a/Views/VariableTableView.xaml +++ b/Views/VariableTableView.xaml @@ -191,6 +191,12 @@ + + + + + diff --git a/Views/VariableTableView.xaml.cs b/Views/VariableTableView.xaml.cs index 2c8f36a..d17848d 100644 --- a/Views/VariableTableView.xaml.cs +++ b/Views/VariableTableView.xaml.cs @@ -145,4 +145,27 @@ public partial class VariableTableView : UserControl NotificationHelper.ShowMessage(msg + e.Message, NotificationType.Error); } } + + private async void AddMqttServerToVariables_Click(object sender, RoutedEventArgs e) + { + try + { + _viewModel = (VariableTableViewModel)this.DataContext; + var selectedVariables = BasicGridView.SelectedItems.Cast().ToList(); + if (selectedVariables.Any()) + { + await _viewModel.AddMqttServerToVariables(selectedVariables); + } + else + { + NotificationHelper.ShowMessage("请选择要添加MQTT服务器的变量", NotificationType.Warning); + } + } + catch (Exception ex) + { + string msg = "添加MQTT服务器时发生了错误:"; + Logger.Error(msg + ex); + NotificationHelper.ShowMessage(msg + ex.Message, NotificationType.Error); + } + } } \ No newline at end of file