From 0007235171e4c393e936c67d0e14ba4d03a9bc70 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Sun, 19 Oct 2025 17:53:23 +0800 Subject: [PATCH] =?UTF-8?q?=20=20=20=201=20feat:=20=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E5=99=A8=E5=8A=9F=E8=83=BD=E5=A2=9E=E5=BC=BA=E5=8F=8A=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E9=9B=86=E6=88=90=20=20=20=20=202=20=20=20=20=203=20-?= =?UTF-8?q?=20=E6=B7=BB=E5=8A=A0=20CreateTriggerWithMenuDto=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=BC=A0=E8=BE=93=E5=AF=B9=E8=B1=A1=EF=BC=8C=E7=94=A8?= =?UTF-8?q?=E4=BA=8E=E5=90=8C=E6=97=B6=E5=88=9B=E5=BB=BA=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E5=99=A8=E5=8F=8A=E5=85=B3=E8=81=94=E8=8F=9C=E5=8D=95=20=20=20?= =?UTF-8?q?=20=204=20-=20=E5=9C=A8=20TriggerDataService=20=E4=B8=AD?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=20AddTriggerWithMenu=20=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E8=A7=A6=E5=8F=91=E5=99=A8=E4=B8=8E?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=9A=84=E5=90=8C=E6=97=B6=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=20=20=20=20=205=20-=20=E6=9B=B4=E6=96=B0=20TriggersViewModel?= =?UTF-8?q?=20=E4=BB=A5=E4=BD=BF=E7=94=A8=E6=96=B0=E7=9A=84=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8=E5=92=8C=E8=8F=9C=E5=8D=95=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=20=20=20=20=206=20-=20=E5=9C=A8=20MenuType?= =?UTF-8?q?=20=E6=9E=9A=E4=B8=BE=E4=B8=AD=E6=B7=BB=E5=8A=A0=20TriggerMenu?= =?UTF-8?q?=20=E7=B1=BB=E5=9E=8B=20=20=20=20=207=20-=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=20InitializeRepository=20=E4=B8=AD=E8=A7=A6=E5=8F=91=E5=99=A8?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E7=9A=84=E5=9B=BE=E6=A0=87=20=20=20=20=208?= =?UTF-8?q?=20-=20=E6=9B=B4=E6=96=B0=E7=9B=B8=E5=85=B3=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E6=B3=A8=E9=87=8A=EF=BC=8C=E5=B0=86=20Trigge?= =?UTF-8?q?r=20=E6=9B=BF=E6=8D=A2=E4=B8=BA=20TriggerMenu=20=E4=BB=A5?= =?UTF-8?q?=E4=BF=9D=E6=8C=81=E4=B8=80=E8=87=B4=20=20=20=20=209=20-=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=B6=E9=97=B4=E8=AE=B0=E5=BD=95=E6=96=B9?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E4=BD=BF=E7=94=A8=20DateTime.Now=20=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3=20DateTime.UtcNow=20=20=20=2010=20-=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=20TriggerManagementService=20=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E5=99=A8=E5=88=9B=E5=BB=BA=E4=B8=8E=E5=AD=98?= =?UTF-8?q?=E5=82=A8=E6=B5=81=E7=A8=8B=20=20=20=2011=20-=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=A7=A6=E5=8F=91=E5=99=A8=E8=AF=84=E4=BC=B0=E5=92=8C?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E6=9C=8D=E5=8A=A1=E4=B8=AD=E7=9A=84=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=96=87=E6=9C=AC=EF=BC=8C=E7=BB=9F=E4=B8=80=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=20TriggerMenu=20=E6=9C=AF=E8=AF=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DTOs/CreateTriggerWithMenuDto.cs | 21 +++++++++ .../Services/Database/TriggerAppService.cs | 2 +- .../Management/TriggerManagementService.cs | 11 ++--- .../Triggers/Impl/TriggerEvaluationService.cs | 4 +- DMS.Core/Enums/MenuType.cs | 3 +- .../Triggers/ITriggerRepository.cs | 2 +- .../Repositories/InitializeRepository.cs | 2 +- DMS.WPF/Interfaces/ITriggerDataService.cs | 5 ++ DMS.WPF/Services/TriggerDataService.cs | 46 ++++++++++++++++++- DMS.WPF/ViewModels/TriggersViewModel.cs | 36 +++++++++++---- 10 files changed, 110 insertions(+), 22 deletions(-) create mode 100644 DMS.Application/DTOs/CreateTriggerWithMenuDto.cs diff --git a/DMS.Application/DTOs/CreateTriggerWithMenuDto.cs b/DMS.Application/DTOs/CreateTriggerWithMenuDto.cs new file mode 100644 index 0000000..7741b53 --- /dev/null +++ b/DMS.Application/DTOs/CreateTriggerWithMenuDto.cs @@ -0,0 +1,21 @@ +using DMS.Core.Models; +using DMS.Core.Models.Triggers; + +namespace DMS.Application.DTOs +{ + /// + /// 创建触发器及其关联菜单的数据传输对象 + /// + public class CreateTriggerWithMenuDto + { + /// + /// 触发器信息 + /// + public Trigger Trigger { get; set; } + + /// + /// 菜单项信息 + /// + public MenuBean TriggerMenu { get; set; } + } +} \ No newline at end of file diff --git a/DMS.Application/Services/Database/TriggerAppService.cs b/DMS.Application/Services/Database/TriggerAppService.cs index 2f12893..b285ad9 100644 --- a/DMS.Application/Services/Database/TriggerAppService.cs +++ b/DMS.Application/Services/Database/TriggerAppService.cs @@ -177,7 +177,7 @@ namespace DMS.Application.Services.Database // // 获取关联的触发器ID列表 // var triggerIds = await _repositoryManager.GetTriggerIdsByVariableIdAsync(variableId); - // var triggers = new List(); + // var triggers = new List(); // if (triggerIds.Any()) // { // // 获取所有关联的触发器 diff --git a/DMS.Application/Services/Management/TriggerManagementService.cs b/DMS.Application/Services/Management/TriggerManagementService.cs index 6ccd17b..ceea41b 100644 --- a/DMS.Application/Services/Management/TriggerManagementService.cs +++ b/DMS.Application/Services/Management/TriggerManagementService.cs @@ -59,13 +59,10 @@ namespace DMS.Application.Services.Management // 3. 调用仓储保存实体 var createdTrigger = await _repositoryManager.Triggers.AddAsync(triggerEntity); - // 4. 转换回 DTO 并返回 - var result = _mapper.Map(createdTrigger); - // 5. 同步更新AppDataStorageService中的Triggers字典 - _appStorageService.Triggers[result.Id] = result; + _appStorageService.Triggers[createdTrigger.Id] = createdTrigger; - return result; + return createdTrigger; } /// @@ -122,7 +119,7 @@ namespace DMS.Application.Services.Management public async Task> GetTriggersForVariableAsync(int variableId) { // var triggers = await _repositoryManager.Triggers.GetByVariableIdAsync(variableId); - // return _mapper.Map>(triggers); + // return _mapper.Map>(triggers); return null; } @@ -141,7 +138,7 @@ namespace DMS.Application.Services.Management } /// - /// 内部方法:验证 Trigger 的有效性 + /// 内部方法:验证 TriggerMenu 的有效性 /// private void ValidateTriggerDto(Trigger dto) { diff --git a/DMS.Application/Services/Triggers/Impl/TriggerEvaluationService.cs b/DMS.Application/Services/Triggers/Impl/TriggerEvaluationService.cs index aa02d76..4162ed0 100644 --- a/DMS.Application/Services/Triggers/Impl/TriggerEvaluationService.cs +++ b/DMS.Application/Services/Triggers/Impl/TriggerEvaluationService.cs @@ -110,7 +110,7 @@ namespace DMS.Application.Services.Triggers.Impl } // 由于移除了条件,所有激活的触发器都会被触发 - _logger.LogInformation("Trigger activated for trigger ID: {TriggerId}", trigger.Id); + _logger.LogInformation("TriggerMenu activated for trigger ID: {TriggerId}", trigger.Id); return true; } @@ -128,7 +128,7 @@ namespace DMS.Application.Services.Triggers.Impl if(isSuppressed) { - _logger.LogTrace("Trigger is suppressed (until {SuppressionEnd}) for trigger ID: {TriggerId}", suppressionEndTime, trigger.Id); + _logger.LogTrace("TriggerMenu is suppressed (until {SuppressionEnd}) for trigger ID: {TriggerId}", suppressionEndTime, trigger.Id); } return isSuppressed; diff --git a/DMS.Core/Enums/MenuType.cs b/DMS.Core/Enums/MenuType.cs index 04d22e6..ab0408a 100644 --- a/DMS.Core/Enums/MenuType.cs +++ b/DMS.Core/Enums/MenuType.cs @@ -7,5 +7,6 @@ public enum MenuType VariableTableMenu, VariableMenu, MqttMenu, - MqttServerMenu + MqttServerMenu, + TriggerMenu } \ No newline at end of file diff --git a/DMS.Core/Interfaces/Repositories/Triggers/ITriggerRepository.cs b/DMS.Core/Interfaces/Repositories/Triggers/ITriggerRepository.cs index f2ee511..e4d3486 100644 --- a/DMS.Core/Interfaces/Repositories/Triggers/ITriggerRepository.cs +++ b/DMS.Core/Interfaces/Repositories/Triggers/ITriggerRepository.cs @@ -7,7 +7,7 @@ using DMS.Core.Interfaces.Repositories; namespace DMS.Core.Interfaces.Repositories.Triggers { /// - /// 触发器仓储接口 (定义对 Trigger 实体的数据访问方法) + /// 触发器仓储接口 (定义对 TriggerMenu 实体的数据访问方法) /// public interface ITriggerRepository : IBaseRepository { diff --git a/DMS.Infrastructure/Repositories/InitializeRepository.cs b/DMS.Infrastructure/Repositories/InitializeRepository.cs index 5aaf02d..9e858a6 100644 --- a/DMS.Infrastructure/Repositories/InitializeRepository.cs +++ b/DMS.Infrastructure/Repositories/InitializeRepository.cs @@ -140,7 +140,7 @@ public class InitializeRepository : IInitializeRepository }, new DbMenu { - Id = 5, Header = "触发器", Icon = "\uE7BA", ParentId = 0, + Id = 5, Header = "触发器", Icon = "\uE945", ParentId = 0, MenuType = MenuType.MainMenu, TargetViewKey = "TriggersViewModel", DisplayOrder = 5 }, diff --git a/DMS.WPF/Interfaces/ITriggerDataService.cs b/DMS.WPF/Interfaces/ITriggerDataService.cs index 491efee..39f57d3 100644 --- a/DMS.WPF/Interfaces/ITriggerDataService.cs +++ b/DMS.WPF/Interfaces/ITriggerDataService.cs @@ -19,6 +19,11 @@ public interface ITriggerDataService /// Task AddTrigger(TriggerItem triggerItem); + /// + /// 添加触发器及其关联菜单。 + /// + Task AddTriggerWithMenu(CreateTriggerWithMenuDto dto); + /// /// 删除触发器。 /// diff --git a/DMS.WPF/Services/TriggerDataService.cs b/DMS.WPF/Services/TriggerDataService.cs index f3149cd..b256e5e 100644 --- a/DMS.WPF/Services/TriggerDataService.cs +++ b/DMS.WPF/Services/TriggerDataService.cs @@ -1,12 +1,14 @@ -using System.Windows.Threading; using AutoMapper; using DMS.Application.DTOs; using DMS.Application.Interfaces; +using DMS.Application.Services; +using DMS.Core.Enums; using DMS.Core.Events; using DMS.Core.Models.Triggers; using DMS.WPF.Interfaces; using DMS.WPF.ItemViewModel; using Opc.Ua; +using System.Windows.Threading; namespace DMS.WPF.Services; @@ -100,6 +102,48 @@ public class TriggerDataService : ITriggerDataService return true; } + /// + /// 添加触发器及其关联菜单。 + /// + public async Task AddTriggerWithMenu(CreateTriggerWithMenuDto dto) + { + // 添加null检查 + if (dto == null || dto.Trigger == null) + return null; + + try + { + // 首先添加触发器 + var createdTrigger = await _appCenterService.TriggerManagementService.CreateTriggerAsync(dto.Trigger); + if (createdTrigger == null) + return null; + + + var parentMenu=_appStorageService.Menus.Values.OrderBy(m=>m.Id).FirstOrDefault(m=>m.MenuType==MenuType.TriggerMenu); + if (parentMenu is not null) + { + // 将菜单关联到触发器 + dto.TriggerMenu.TargetId = createdTrigger.Id; + dto.TriggerMenu.MenuType = MenuType.TriggerMenu; + + } + + + + + // 添加到UI数据存储 + var addItem = _mapper.Map(createdTrigger); + _dataStorageService.Triggers.Add(createdTrigger.Id, addItem); + + return dto; + } + catch (Exception ex) + { + _notificationService?.ShowError($"添加触发器及菜单时发生错误:{ex.Message}", ex); + return null; + } + } + /// /// 更新触发器。 /// diff --git a/DMS.WPF/ViewModels/TriggersViewModel.cs b/DMS.WPF/ViewModels/TriggersViewModel.cs index 0a85619..9e84720 100644 --- a/DMS.WPF/ViewModels/TriggersViewModel.cs +++ b/DMS.WPF/ViewModels/TriggersViewModel.cs @@ -71,8 +71,8 @@ namespace DMS.WPF.ViewModels IsActive = true, Action = Core.Models.Triggers.ActionType.SendEmail, Description = "新建触发器", - CreatedAt = DateTime.UtcNow, - UpdatedAt = DateTime.UtcNow + CreatedAt = DateTime.Now, + UpdatedAt = DateTime.Now }; TriggerDialogViewModel viewModel = App.Current.Services.GetRequiredService(); @@ -83,13 +83,33 @@ namespace DMS.WPF.ViewModels { try { - // 使用TriggerDataService添加触发器 - var createdTrigger = await _triggerDataService.AddTrigger(newTrigger); - - if (createdTrigger != null ) + // 创建包含菜单信息的 DTO + CreateTriggerWithMenuDto dto = new CreateTriggerWithMenuDto(); + if (_mapper != null) { - // 触发器已添加到数据存储中,只需更新本地集合 - _notificationService.ShowSuccess("触发器创建成功"); + dto.Trigger = _mapper.Map(result); + } + else + { + _notificationService?.ShowError("映射服务未初始化"); + return; + } + + // 创建菜单项 + dto.TriggerMenu = new MenuBean() + { + Header = result.Name ?? result.Description, + Icon = "\uE945", // 使用触发器图标 + TargetViewKey = nameof(TriggerDetailViewModel), + }; + + // 使用TriggerDataService添加触发器和菜单 + var createdTriggerDto = await _triggerDataService.AddTriggerWithMenu(dto); + + if (createdTriggerDto != null && createdTriggerDto.Trigger != null) + { + // 更新UI显示 + _notificationService.ShowSuccess($"触发器创建成功:{createdTriggerDto.Trigger.Name ?? createdTriggerDto.Trigger.Description}"); } else {