diff --git a/DMS.Application/DTOs/TriggerVariableDto.cs b/DMS.Application/DTOs/TriggerVariableDto.cs new file mode 100644 index 0000000..5a61948 --- /dev/null +++ b/DMS.Application/DTOs/TriggerVariableDto.cs @@ -0,0 +1,36 @@ +using System; +using DMS.Core.Models.Triggers; + +namespace DMS.Application.DTOs +{ + public class TriggerVariableDto + { + public int Id { get; set; } + + public int TriggerDefinitionId { get; set; } + + public int VariableId { get; set; } + + // 从核心模型转换为DTO + public static implicit operator TriggerVariableDto(TriggerVariable triggerVariable) + { + return new TriggerVariableDto + { + Id = triggerVariable.Id, + TriggerDefinitionId = triggerVariable.TriggerDefinitionId, + VariableId = triggerVariable.VariableId + }; + } + + // 从DTO转换为核心模型 + public static implicit operator TriggerVariable(TriggerVariableDto dto) + { + return new TriggerVariable + { + Id = dto.Id, + TriggerDefinitionId = dto.TriggerDefinitionId, + VariableId = dto.VariableId + }; + } + } +} \ No newline at end of file diff --git a/DMS.Infrastructure/Profiles/MappingProfile.cs b/DMS.Infrastructure/Profiles/MappingProfile.cs index 42b1dee..7cccef2 100644 --- a/DMS.Infrastructure/Profiles/MappingProfile.cs +++ b/DMS.Infrastructure/Profiles/MappingProfile.cs @@ -48,5 +48,7 @@ public class MappingProfile : Profile CreateMap() .ForMember(dest => dest.Variables, opt => opt.Ignore()) // 忽略Variables属性映射,因为可能需要特殊处理 .ReverseMap(); + + CreateMap().ReverseMap(); } -} +} \ No newline at end of file diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index a3157bd..a5f1211 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -355,6 +355,7 @@ public partial class App : System.Windows.Application services.AddTransient(); services.AddTransient(); services.AddTransient(); // 注册 TriggerEditorViewModel + services.AddTransient(); // 注册 TriggerSelectionDialogViewModel // 注册工厂 services.AddTransient(); diff --git a/DMS.WPF/Services/DialogService.cs b/DMS.WPF/Services/DialogService.cs index a16bc53..95daa11 100644 --- a/DMS.WPF/Services/DialogService.cs +++ b/DMS.WPF/Services/DialogService.cs @@ -26,7 +26,8 @@ namespace DMS.WPF.Services { typeof(EmailAccountDialogViewModel), typeof(EmailAccountDialog) }, { typeof(EmailTemplateDialogViewModel), typeof(EmailTemplateDialog) }, { typeof(TriggerDialogViewModel), typeof(TriggerDialog) }, - { typeof(InputDialogViewModel), typeof(InputDialog) } + { typeof(InputDialogViewModel), typeof(InputDialog) }, + { typeof(TriggerSelectionDialogViewModel), typeof(TriggerSelectionDialog) } // Add other mappings here // ... other dialogs }; diff --git a/DMS.WPF/ViewModels/Dialogs/TriggerSelectionDialogViewModel.cs b/DMS.WPF/ViewModels/Dialogs/TriggerSelectionDialogViewModel.cs new file mode 100644 index 0000000..aaa1035 --- /dev/null +++ b/DMS.WPF/ViewModels/Dialogs/TriggerSelectionDialogViewModel.cs @@ -0,0 +1,87 @@ +using CommunityToolkit.Mvvm.ComponentModel; +using CommunityToolkit.Mvvm.Input; +using DMS.Application.Interfaces; +using DMS.Application.Interfaces.Database; +using DMS.Core.Models.Triggers; +using DMS.WPF.ItemViewModel; +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; + +namespace DMS.WPF.ViewModels.Dialogs +{ + /// + /// 触发器选择对话框的视图模型 + /// + public partial class TriggerSelectionDialogViewModel : DialogViewModelBase + { + private readonly ITriggerAppService _triggerAppService; + + [ObservableProperty] + private ObservableCollection _triggers = new(); + + [ObservableProperty] + private TriggerItem _selectedTrigger; + + public TriggerSelectionDialogViewModel(ITriggerAppService triggerAppService) + { + _triggerAppService = triggerAppService; + LoadTriggersAsync(); + } + + /// + /// 异步加载所有触发器 + /// + private async void LoadTriggersAsync() + { + try + { + var triggers = await _triggerAppService.GetAllTriggersAsync(); + Triggers.Clear(); + + foreach (var trigger in triggers) + { + Triggers.Add(new TriggerItem + { + Id = trigger.Id, + Name = trigger.Name, + Description = trigger.Description, + IsActive = trigger.IsActive, + Action = trigger.Action, + ActionConfigurationJson = trigger.ActionConfigurationJson, + SuppressionDuration = trigger.SuppressionDuration, + LastTriggeredAt = trigger.LastTriggeredAt, + CreatedAt = trigger.CreatedAt, + UpdatedAt = trigger.UpdatedAt + }); + } + } + catch (Exception ex) + { + // 记录错误日志 + System.Console.WriteLine($"加载触发器失败: {ex.Message}"); + } + } + + /// + /// 确认选择 + /// + [RelayCommand] + private void Confirm() + { + if (SelectedTrigger != null) + { + Close(SelectedTrigger); + } + } + + /// + /// 取消选择 + /// + [RelayCommand] + private void Cancel() + { + Close(null); + } + } +} \ No newline at end of file diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index 3a211d0..28d7d4e 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -93,11 +93,15 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable private readonly INotificationService _notificationService; + private readonly ITriggerAppService _triggerAppService; + private readonly ITriggerVariableAppService _triggerVariableAppService; + public VariableTableViewModel(IMapper mapper, IDialogService dialogService, IVariableManagementService variableManagementService, IEventService eventService, IMqttAliasAppService mqttAliasAppService, IMqttAppService mqttAppService, IWPFDataService wpfDataService, IDataStorageService dataStorageService, - INotificationService notificationService) + INotificationService notificationService, ITriggerAppService triggerAppService, + ITriggerVariableAppService triggerVariableAppService) { _mapper = mapper; _dialogService = dialogService; @@ -108,6 +112,8 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable _wpfDataService = wpfDataService; _dataStorageService = dataStorageService; _notificationService = notificationService; + _triggerAppService = triggerAppService; + _triggerVariableAppService = triggerVariableAppService; IsLoadCompletion = false; // 初始设置为 false,表示未完成加载 @@ -172,7 +178,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 编辑选定的变量数据。 - /// 此命令通常绑定到UI中的“编辑”按钮或双击事件。 + /// 此命令通常绑定到UI中的"编辑"按钮或双击事件。 /// /// 当前操作的变量表,用于更新其内部的变量数据。 [RelayCommand] @@ -232,7 +238,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 从TIA Portal导出的变量表Excel文件中导入变量数据。 - /// 此命令通常绑定到UI中的“从TIA导入”按钮。 + /// 此命令通常绑定到UI中的"从TIA导入"按钮。 /// [RelayCommand] private async void ImprotFromTiaVarTable() @@ -297,7 +303,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 从OPC UA服务器导入变量数据。 - /// 此命令通常绑定到UI中的“从OPC UA导入”按钮。 + /// 此命令通常绑定到UI中的"从OPC UA导入"按钮。 /// [RelayCommand] private async void ImportFromOpcUaServer() @@ -390,7 +396,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 添加新的变量数据。 /// - /// 此命令通常绑定到UI中的“添加”按钮。 + /// 此命令通常绑定到UI中的"添加"按钮。 /// 当前操作的变量表,用于设置新变量的所属ID。 [RelayCommand] private async void AddVariable() @@ -438,7 +444,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 删除选定的变量数据。 - /// 此命令通常绑定到UI中的“删除”按钮。 + /// 此命令通常绑定到UI中的"删除"按钮。 /// /// 要删除的变量数据列表。 [RelayCommand] @@ -495,7 +501,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 更改选定变量的轮询频率。 - /// 此命令通常绑定到UI中的“修改轮询频率”按钮。 + /// 此命令通常绑定到UI中的"修改轮询频率"按钮。 /// /// 要修改轮询频率的变量数据列表。 [RelayCommand] @@ -586,7 +592,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable /// /// 为选定的变量添加MQTT服务器。 - /// 此命令通常绑定到UI中的“添加MQTT服务器”按钮。 + /// 此命令通常绑定到UI中的"添加MQTT服务器"按钮。 /// /// 要添加MQTT服务器的变量数据列表。 [RelayCommand] @@ -632,9 +638,6 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable { totalAffectedCount++; } - - - } if (totalAffectedCount > 0) @@ -654,6 +657,69 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable } } + /// + /// 为选定的变量添加触发器。 + /// 此命令通常绑定到UI中的"添加触发器"按钮。 + /// + /// 要添加触发器的变量数据列表。 + [RelayCommand] + public async Task AddTriggerToVariables(IList variablesToAddTrigger) + { + var validVariables = variablesToAddTrigger?.OfType() + .ToList(); + + // 检查是否有变量被选中 + if (validVariables == null || !validVariables.Any()) + { + _notificationService.ShowInfo("请选择要添加触发器的变量"); + return; + } + + try + { + // 显示触发器选择对话框,让用户选择一个触发器 + var triggerSelectionViewModel = new TriggerSelectionDialogViewModel(_triggerAppService); + var selectedTrigger = await _dialogService.ShowDialogAsync(triggerSelectionViewModel); + if (selectedTrigger == null) + { + return; // 用户取消选择 + } + + int totalAffectedCount = 0; + + // 为每个选中的变量分配触发器 + foreach (var variable in validVariables) + { + var triggerVariable = new DMS.Core.Models.Triggers.TriggerVariable + { + TriggerDefinitionId = selectedTrigger.Id, + VariableId = variable.Id + }; + + var triggerVariableItem = await _triggerVariableAppService.AssignTriggerVariableAsync(triggerVariable); + if (triggerVariableItem is not null) + { + totalAffectedCount++; + } + } + + if (totalAffectedCount > 0) + { + _notificationService.ShowSuccess( + $"已成功为 {totalAffectedCount} 个变量添加触发器: {selectedTrigger.Name}"); + } + else + { + _notificationService.ShowInfo($"没有新的变量关联到触发器: {selectedTrigger.Name}。"); + } + } + catch (Exception ex) + { + // 捕获并显示错误通知 + _notificationService.ShowError($"添加触发器失败: {ex.Message}", ex); + } + } + /// /// 修改选定变量的启用状态。 /// @@ -855,7 +921,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // { // // 显示失败通知 // NotificationHelper.ShowError($"变量表:{VariableTable.Name},状态修改失败,状态:{active}"); - // // _logger.LogInformation($"变量表:{VariableTable.Name},状态修改失败,状态:{active}"); // 可以选择记录日志 + // // _logger.LogInformation($"变量表:{VariableTable.Name},状态修改失败,状态:{active}") // 可以选择记录日志 // } } diff --git a/DMS.WPF/Views/Dialogs/TriggerSelectionDialog.xaml b/DMS.WPF/Views/Dialogs/TriggerSelectionDialog.xaml new file mode 100644 index 0000000..92ba1b1 --- /dev/null +++ b/DMS.WPF/Views/Dialogs/TriggerSelectionDialog.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + +