diff --git a/DMS.Application/Events/MqttAliasChangedEventArgs.cs b/DMS.Application/Events/MqttAliasChangedEventArgs.cs new file mode 100644 index 0000000..bb53c0d --- /dev/null +++ b/DMS.Application/Events/MqttAliasChangedEventArgs.cs @@ -0,0 +1,18 @@ +using DMS.Core.Enums; +using DMS.Core.Models; + +namespace DMS.Application.Events; + +public class MqttAliasChangedEventArgs : EventArgs +{ + public ActionChangeType ChangeType { get; } + public MqttAlias MqttAlias { get; } + public MqttAliasPropertyType PropertyType { get; } + + public MqttAliasChangedEventArgs(ActionChangeType changeType, MqttAlias mqttAlias, MqttAliasPropertyType propertyType = MqttAliasPropertyType.All) + { + ChangeType = changeType; + MqttAlias = mqttAlias; + PropertyType = propertyType; + } +} diff --git a/DMS.Application/Interfaces/Database/IMqttAliasAppService.cs b/DMS.Application/Interfaces/Database/IMqttAliasAppService.cs index 68bf403..fc09b93 100644 --- a/DMS.Application/Interfaces/Database/IMqttAliasAppService.cs +++ b/DMS.Application/Interfaces/Database/IMqttAliasAppService.cs @@ -9,29 +9,25 @@ namespace DMS.Application.Interfaces.Database; /// public interface IMqttAliasAppService { - /// - /// 异步获取指定变量的所有MQTT别名关联。 - /// - Task> GetAliasesForVariableAsync(int variableId); /// /// 异步为变量分配或更新一个MQTT别名。 /// - /// 变量ID。 - /// MQTT服务器ID。 - /// 要设置的别名。 - Task AssignAliasAsync(int variableId, int mqttServerId, string alias); + /// + Task AssignAliasAsync(MqttAlias mqttAlias); /// /// 异步更新一个已存在的MQTT别名。 /// /// 别名关联的ID。 /// 新的别名字符串。 - Task UpdateAliasAsync(int aliasId, string newAlias); + Task UpdateAliasAsync(MqttAlias mqttAlias); /// /// 异步移除一个MQTT别名关联。 /// /// 要移除的别名关联的ID。 - Task RemoveAliasAsync(int aliasId); + Task RemoveAliasAsync(int aliasId); + + Task> GetAllAsync(); } \ No newline at end of file diff --git a/DMS.Application/Interfaces/IAppDataStorageService.cs b/DMS.Application/Interfaces/IAppDataStorageService.cs index 4d23d0a..81a2271 100644 --- a/DMS.Application/Interfaces/IAppDataStorageService.cs +++ b/DMS.Application/Interfaces/IAppDataStorageService.cs @@ -43,7 +43,7 @@ public interface IAppDataStorageService /// /// 安全字典,用于存储所有MQTT变量别名的数据 /// - ConcurrentDictionary VariableMqttAliases { get; } + ConcurrentDictionary MqttAliases { get; } /// /// 安全字典,用于存储所有触发器定义数据 diff --git a/DMS.Application/Interfaces/IEventService.cs b/DMS.Application/Interfaces/IEventService.cs index 9102600..8799036 100644 --- a/DMS.Application/Interfaces/IEventService.cs +++ b/DMS.Application/Interfaces/IEventService.cs @@ -68,6 +68,18 @@ public interface IEventService /// MQTT服务器改变事件参数 void RaiseMqttServerChanged(object sender, MqttServerChangedEventArgs e); + /// + /// Mqtt别名改变事件 + /// + event EventHandler OnMqttAliasChanged; + + /// + /// 触发Mqtt别名改变事件 + /// + /// 事件发送者 + /// Mqtt别名改变事件参数 + void RaiseMqttAliasChanged(object sender, MqttAliasChangedEventArgs e); + #endregion diff --git a/DMS.Application/Interfaces/Management/IMqttAliasManagementService.cs b/DMS.Application/Interfaces/Management/IMqttAliasManagementService.cs new file mode 100644 index 0000000..0dbcb53 --- /dev/null +++ b/DMS.Application/Interfaces/Management/IMqttAliasManagementService.cs @@ -0,0 +1,11 @@ +using DMS.Core.Models; + +namespace DMS.Application.Interfaces.Management; + +public interface IMqttAliasManagementService +{ + Task AssignAliasAsync(MqttAlias alias); + Task UpdateAsync(MqttAlias alias); + Task DeleteAsync(int id); + Task> LoadAllMqttAliasAsync(); +} diff --git a/DMS.Application/Services/AppDataStorageService.cs b/DMS.Application/Services/AppDataStorageService.cs index 241e0b8..7816ccc 100644 --- a/DMS.Application/Services/AppDataStorageService.cs +++ b/DMS.Application/Services/AppDataStorageService.cs @@ -40,7 +40,7 @@ public class AppDataStorageService : IAppDataStorageService /// /// 安全字典,用于存储所有MQTT变量别名的数据 /// - public ConcurrentDictionary VariableMqttAliases { get; } = new(); + public ConcurrentDictionary MqttAliases { get; } = new(); diff --git a/DMS.Application/Services/DataLoaderService.cs b/DMS.Application/Services/DataLoaderService.cs index 53da267..511172e 100644 --- a/DMS.Application/Services/DataLoaderService.cs +++ b/DMS.Application/Services/DataLoaderService.cs @@ -27,6 +27,7 @@ public class DataLoaderService : IDataLoaderService private readonly IMenuAppService _menuService; private readonly IMqttAppService _mqttAppService; private readonly INlogAppService _nlogAppService; + private readonly IMqttAliasManagementService _mqttAliasManagementService; private readonly ITriggerManagementService _triggerManagementService; // 添加触发器管理服务 private readonly IEventService _eventService; // 添加事件服务 @@ -43,6 +44,7 @@ public class DataLoaderService : IDataLoaderService IMenuAppService menuService, IMqttAppService mqttAppService, INlogAppService nlogAppService, + IMqttAliasManagementService mqttAliasManagementService, ITriggerManagementService triggerManagementService, // 添加触发器管理服务参数 IEventService eventService) // 添加事件服务参数 { @@ -55,6 +57,7 @@ public class DataLoaderService : IDataLoaderService _menuService = menuService; _mqttAppService = mqttAppService; _nlogAppService = nlogAppService; + this._mqttAliasManagementService = mqttAliasManagementService; _triggerManagementService = triggerManagementService; // 初始化触发器管理服务 _eventService = eventService; // 初始化事件服务 } @@ -81,7 +84,7 @@ public class DataLoaderService : IDataLoaderService await LoadAllNlogsAsync(LoadLogCount); // 获取变量MQTT别名 - await LoadAllVariableMqttAliases(); + await _mqttAliasManagementService.LoadAllMqttAliasAsync(); // 加载所有触发器 await LoadAllTriggersAsync(); @@ -103,26 +106,7 @@ public class DataLoaderService : IDataLoaderService } } - private async Task LoadAllVariableMqttAliases() - { - var variableMqttAliases = await _repositoryManager.VariableMqttAliases.GetAllAsync(); - foreach (var variableMqttAlias in variableMqttAliases) - { - _appDataStorageService.VariableMqttAliases.TryAdd(variableMqttAlias.Id, variableMqttAlias); - if (_appDataStorageService.Variables.TryGetValue(variableMqttAlias.VariableId, out var variable)) - { - variableMqttAlias.Variable = _mapper.Map(variable); - variable.MqttAliases?.Add(variableMqttAlias); - } - - if (_appDataStorageService.MqttServers.TryGetValue(variableMqttAlias.MqttServerId, out var mqttServer)) - { - variableMqttAlias.MqttServer = mqttServer; - mqttServer.VariableAliases?.Add(variableMqttAlias); - } - } - } /// /// 异步加载所有设备数据 diff --git a/DMS.Application/Services/Database/MqttAliasAppService.cs b/DMS.Application/Services/Database/MqttAliasAppService.cs index 21b74d8..4cb8c2a 100644 --- a/DMS.Application/Services/Database/MqttAliasAppService.cs +++ b/DMS.Application/Services/Database/MqttAliasAppService.cs @@ -3,9 +3,6 @@ using DMS.Application.Interfaces; using DMS.Application.Interfaces.Database; using DMS.Core.Interfaces; using DMS.Core.Models; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace DMS.Application.Services.Database; @@ -15,111 +12,47 @@ namespace DMS.Application.Services.Database; public class MqttAliasAppService : IMqttAliasAppService { private readonly IRepositoryManager _repoManager; + private readonly IAppDataStorageService _appDataStorageService; private readonly IMapper _mapper; /// /// 构造函数。 /// - public MqttAliasAppService(IRepositoryManager repoManager, IMapper mapper) + public MqttAliasAppService(IRepositoryManager repoManager,IAppDataStorageService appDataStorageService, IMapper mapper) { _repoManager = repoManager; + _appDataStorageService = appDataStorageService; _mapper = mapper; } - /// - /// 异步获取指定变量的所有MQTT别名关联。 - /// - public async Task> GetAliasesForVariableAsync(int variableId) - { - // 从仓储获取别名,并确保加载了关联的MqttServer信息 - var aliases = await _repoManager.VariableMqttAliases.GetAliasesForVariableAsync(variableId); - return aliases.ToList(); - } - /// /// 异步为变量分配或更新一个MQTT别名。 /// - public async Task AssignAliasAsync(int variableId, int mqttServerId, string alias) + public async Task AssignAliasAsync(MqttAlias mqttAlias) { - try - { - await _repoManager.BeginTranAsync(); - - // 检查是否已存在该变量与该服务器的关联 - var existingAlias = await _repoManager.VariableMqttAliases.GetByVariableAndServerAsync(variableId, mqttServerId); - - if (existingAlias != null) - { - // 如果存在,则更新别名 - existingAlias.Alias = alias; - await _repoManager.VariableMqttAliases.UpdateAsync(existingAlias); - } - else - { - // 如果不存在,则创建新的关联 - // 获取关联的Variable和MqttServer实体 - var variable = await _repoManager.Variables.GetByIdAsync(variableId); - var mqttServer = await _repoManager.MqttServers.GetByIdAsync(mqttServerId); - - var newAlias = new MqttAlias - { - VariableId = variableId, - MqttServerId = mqttServerId, - Alias = alias, - Variable = variable, - MqttServer = mqttServer - }; - await _repoManager.VariableMqttAliases.AddAsync(newAlias); - } - - await _repoManager.CommitAsync(); - } - catch (Exception ex) - { - await _repoManager.RollbackAsync(); - throw new ApplicationException("分配/更新MQTT别名失败。", ex); - } + return await _repoManager.MqttAliases.AddAsync(mqttAlias); } /// /// 异步更新一个已存在的MQTT别名。 /// - public async Task UpdateAliasAsync(int aliasId, string newAlias) + public async Task UpdateAliasAsync(MqttAlias mqttAlias) { - try - { - await _repoManager.BeginTranAsync(); - var aliasToUpdate = await _repoManager.VariableMqttAliases.GetByIdAsync(aliasId); - if (aliasToUpdate == null) - { - throw new KeyNotFoundException($"未找到ID为 {aliasId} 的MQTT别名关联。"); - } - aliasToUpdate.Alias = newAlias; - await _repoManager.VariableMqttAliases.UpdateAsync(aliasToUpdate); - await _repoManager.CommitAsync(); - } - catch (Exception ex) - { - await _repoManager.RollbackAsync(); - throw new ApplicationException("更新MQTT别名失败。", ex); - } + return await _repoManager.MqttAliases.UpdateAsync(mqttAlias); } /// /// 异步移除一个MQTT别名关联。 /// - public async Task RemoveAliasAsync(int aliasId) + public async Task RemoveAliasAsync(int aliasId) { - try - { - await _repoManager.BeginTranAsync(); - await _repoManager.VariableMqttAliases.DeleteByIdAsync(aliasId); - await _repoManager.CommitAsync(); - } - catch (Exception ex) - { - await _repoManager.RollbackAsync(); - throw new ApplicationException("移除MQTT别名失败。", ex); - } + return await _repoManager.MqttAliases.DeleteByIdAsync(aliasId); + } + + public async Task> GetAllAsync() + { + var mqttAliases = await _repoManager.MqttAliases.GetAllAsync(); + + return mqttAliases; } } \ No newline at end of file diff --git a/DMS.Application/Services/EventService.cs b/DMS.Application/Services/EventService.cs index 08609a4..3b7f56d 100644 --- a/DMS.Application/Services/EventService.cs +++ b/DMS.Application/Services/EventService.cs @@ -134,6 +134,21 @@ public class EventService : IEventService OnMqttServerChanged?.Invoke(sender, e); } + /// + /// Mqtt别名改变事件 + /// + public event EventHandler OnMqttAliasChanged; + + /// + /// 触发Mqtt别名改变事件 + /// + /// 事件发送者 + /// Mqtt别名改变事件参数 + public void RaiseMqttAliasChanged(object sender, MqttAliasChangedEventArgs e) + { + OnMqttAliasChanged?.Invoke(sender, e); + } + #endregion #region 数据加载事件 diff --git a/DMS.Application/Services/Management/MqttAliasManagementService.cs b/DMS.Application/Services/Management/MqttAliasManagementService.cs new file mode 100644 index 0000000..16818fa --- /dev/null +++ b/DMS.Application/Services/Management/MqttAliasManagementService.cs @@ -0,0 +1,140 @@ +using AutoMapper; +using DMS.Application.Events; +using DMS.Application.Interfaces; +using DMS.Application.Interfaces.Database; +using DMS.Application.Interfaces.Management; +using DMS.Core.Enums; +using DMS.Core.Models; + +namespace DMS.Application.Services.Management; + +public class MqttAliasManagementService : IMqttAliasManagementService +{ + private readonly IMqttAliasAppService _appService; + private readonly IEventService _eventService; + private readonly IAppDataStorageService _storageService; + private readonly IMapper _mapper; + + public MqttAliasManagementService(IMqttAliasAppService appService, IEventService eventService, + IAppDataStorageService storageService, IMapper mapper) + { + _appService = appService; + _eventService = eventService; + _storageService = storageService; + _mapper = mapper; + } + + public async Task AssignAliasAsync(MqttAlias alias) + { + var newAlias = await _appService.AssignAliasAsync(alias); + if (newAlias != null) + { + // Add to cache + if (_storageService.MqttServers.TryGetValue(newAlias.MqttServerId, out var server)) + { + server.VariableAliases.Add(newAlias); + } + + // Add to cache + if (_storageService.Variables.TryGetValue(newAlias.VariableId, out var variable)) + { + variable.MqttAliases.Add(newAlias); + } + + _eventService.RaiseMqttAliasChanged(this, new MqttAliasChangedEventArgs(ActionChangeType.Added, newAlias)); + } + + return newAlias; + } + + public async Task> LoadAllMqttAliasAsync() + { + var mqttAliases = await _appService.GetAllAsync(); + foreach (var mqttAlias in mqttAliases) + { + // Add to cache + if (_storageService.MqttServers.TryGetValue(mqttAlias.MqttServerId, out var server)) + { + mqttAlias.MqttServer = server; + server.VariableAliases.Add(mqttAlias); + } + + // Add to cache + if (_storageService.Variables.TryGetValue(mqttAlias.VariableId, out var variable)) + { + mqttAlias.Variable= variable; + variable.MqttAliases.Add(mqttAlias); + } + _storageService.MqttAliases.TryAdd(mqttAlias.Id, mqttAlias); + _eventService.RaiseMqttAliasChanged(this, new MqttAliasChangedEventArgs(ActionChangeType.Added, mqttAlias)); + } + + return mqttAliases; + } + + public async Task UpdateAsync(MqttAlias alias) + { + int res = await _appService.UpdateAliasAsync(alias); + if (res>0) + { + // Add to cache + if (_storageService.MqttAliases.TryGetValue(alias.Id, out var mqttAlias)) + { + mqttAlias.Alias = alias.Alias; + } + } + return res; + } + + + + public async Task DeleteAsync(int id) + { + var res = await DeleteBatchAsync(new List { id }); + return res > 0; + } + + public async Task DeleteBatchAsync(List ids) + { + int counter = 0; + foreach (var id in ids) + { + if (!_storageService.MqttAliases.TryGetValue(id, out var mqttAlias)) + { + continue; + } + + var variableId = mqttAlias.VariableId; + var mqttServerId = mqttAlias.MqttServerId; + + var result = await _appService.RemoveAliasAsync(id); + if (result == 0) continue; + + // Remove from cache + if (_storageService.MqttServers.TryGetValue(mqttServerId, out var server)) + { + var aliasToRemove = server.VariableAliases.FirstOrDefault(a => a.Id == id); + if (aliasToRemove != null) + { + server.VariableAliases.Remove(aliasToRemove); + + } + } + // Remove from cache + if (_storageService.Variables.TryGetValue(mqttServerId, out var variable)) + { + var aliasToRemove = variable.MqttAliases.FirstOrDefault(a => a.Id == id); + if (aliasToRemove != null) + { + variable.MqttAliases.Remove(aliasToRemove); + + } + } + + _eventService.RaiseMqttAliasChanged( + this, new MqttAliasChangedEventArgs(ActionChangeType.Deleted, mqttAlias)); + counter++; + } + return counter; + } +} \ No newline at end of file diff --git a/DMS.Core/Enums/MqttAliasPropertyType.cs b/DMS.Core/Enums/MqttAliasPropertyType.cs new file mode 100644 index 0000000..3b0c903 --- /dev/null +++ b/DMS.Core/Enums/MqttAliasPropertyType.cs @@ -0,0 +1,7 @@ +namespace DMS.Core.Enums; + +public enum MqttAliasPropertyType +{ + Alias, + All +} diff --git a/DMS.Core/Interfaces/IRepositoryManager.cs b/DMS.Core/Interfaces/IRepositoryManager.cs index 2dd019c..abd2261 100644 --- a/DMS.Core/Interfaces/IRepositoryManager.cs +++ b/DMS.Core/Interfaces/IRepositoryManager.cs @@ -33,7 +33,7 @@ public interface IRepositoryManager : IDisposable /// /// 获取变量MQTT别名仓储的实例。 /// - IVariableMqttAliasRepository VariableMqttAliases { get; set; } + IVariableMqttAliasRepository MqttAliases { get; set; } /// /// 获取菜单仓储的实例。 diff --git a/DMS.Core/Interfaces/Repositories/IVariableMqttAliasRepository.cs b/DMS.Core/Interfaces/Repositories/IVariableMqttAliasRepository.cs index 43fc1cf..8565faf 100644 --- a/DMS.Core/Interfaces/Repositories/IVariableMqttAliasRepository.cs +++ b/DMS.Core/Interfaces/Repositories/IVariableMqttAliasRepository.cs @@ -6,15 +6,6 @@ namespace DMS.Core.Interfaces.Repositories { public interface IVariableMqttAliasRepository : IBaseRepository { - /// - /// 异步获取指定变量的所有MQTT别名关联。 - /// - Task> GetAliasesForVariableAsync(int variableId); - - /// - /// 异步根据变量和服务器获取别名关联。 - /// - Task GetByVariableAndServerAsync(int variableId, int mqttServerId); /// /// 异步获取所有变量与MQTT别名关联。 diff --git a/DMS.Core/Models/MqttAlias.cs b/DMS.Core/Models/MqttAlias.cs index 3393e3d..fb9f75d 100644 --- a/DMS.Core/Models/MqttAlias.cs +++ b/DMS.Core/Models/MqttAlias.cs @@ -35,4 +35,16 @@ public class MqttAlias /// 关联的MQTT服务器导航属性。 /// public MqttServer MqttServer { get; set; } + + public MqttAlias() + { + + } + + public MqttAlias(int variableId, int mqttServerId, string alias) + { + VariableId = variableId; + MqttServerId = mqttServerId; + Alias = alias; + } } \ No newline at end of file diff --git a/DMS.Infrastructure/Entities/DbVariableMqttAlias.cs b/DMS.Infrastructure/Entities/DbVariableMqttAlias.cs index 46dcbb9..bc2590a 100644 --- a/DMS.Infrastructure/Entities/DbVariableMqttAlias.cs +++ b/DMS.Infrastructure/Entities/DbVariableMqttAlias.cs @@ -3,7 +3,7 @@ using SqlSugar; namespace DMS.Infrastructure.Entities; /// -/// 数据库实体:对应数据库中的 VariableMqttAliases 表。 +/// 数据库实体:对应数据库中的 MqttAliases 表。 /// public class DbVariableMqttAlias { diff --git a/DMS.Infrastructure/Repositories/RepositoryManager.cs b/DMS.Infrastructure/Repositories/RepositoryManager.cs index 9f45ff5..558d5d8 100644 --- a/DMS.Infrastructure/Repositories/RepositoryManager.cs +++ b/DMS.Infrastructure/Repositories/RepositoryManager.cs @@ -49,7 +49,7 @@ public class RepositoryManager : IRepositoryManager VariableTables = variableTables; Variables = variables; MqttServers = mqttServers; - VariableMqttAliases = variableMqttAliases; + MqttAliases = variableMqttAliases; Menus = menus; VariableHistories = variableHistories; Users = users; @@ -86,7 +86,7 @@ public class RepositoryManager : IRepositoryManager /// /// 获取变量MQTT别名仓储实例。 /// - public IVariableMqttAliasRepository VariableMqttAliases { get; set; } + public IVariableMqttAliasRepository MqttAliases { get; set; } /// /// 获取菜单仓储实例。 /// diff --git a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs index 1ac75d5..11c1acc 100644 --- a/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableMqttAliasRepository.cs @@ -111,77 +111,4 @@ public class VariableMqttAliasRepository : BaseRepository, var addedEntities = await base.AddBatchAsync(dbEntities); return _mapper.Map>(addedEntities); } - - /// - /// 异步获取指定变量的所有MQTT别名关联。 - /// - public async Task> GetAliasesForVariableAsync(int variableId) - { - // 查询别名关联,并包含关联的Variable和MqttServer信息 - var dbList = await _dbContext.GetInstance().Queryable() - .Where(x => x.VariableId == variableId) - .ToListAsync(); - - // 手动加载关联的Variable和MqttServer实体 - var variableIds = dbList.Select(x => x.VariableId).Distinct().ToList(); - var mqttServerIds = dbList.Select(x => x.MqttServerId).Distinct().ToList(); - - var variables = await _dbContext.GetInstance().Queryable() - .In(x => x.Id, variableIds) - .ToListAsync(); - - var mqttServers = await _dbContext.GetInstance().Queryable() - .In(x => x.Id, mqttServerIds) - .ToListAsync(); - - // 将关联实体映射到领域模型 - var variableDict = variables.ToDictionary(v => v.Id, v => _mapper.Map(v)); - var mqttServerDict = mqttServers.ToDictionary(m => m.Id, m => _mapper.Map(m)); - - // 映射主实体并设置导航属性 - var result = _mapper.Map>(dbList); - foreach (var alias in result) - { - if (variableDict.TryGetValue(alias.VariableId, out var variable)) - { - alias.Variable = variable; - } - - if (mqttServerDict.TryGetValue(alias.MqttServerId, out var mqttServer)) - { - alias.MqttServer = mqttServer; - } - } - - return result; - } - - /// - /// 异步根据变量和服务器获取别名关联。 - /// - public async Task GetByVariableAndServerAsync(int variableId, int mqttServerId) - { - var dbAlias = await _dbContext.GetInstance().Queryable() - .Where(x => x.VariableId == variableId && x.MqttServerId == mqttServerId) - .FirstAsync(); - - if (dbAlias == null) - return null; - - // 手动加载关联的Variable和MqttServer实体 - var variable = await _dbContext.GetInstance().Queryable() - .Where(x => x.Id == variableId) - .FirstAsync(); - - var mqttServer = await _dbContext.GetInstance().Queryable() - .Where(x => x.Id == mqttServerId) - .FirstAsync(); - - // 映射主实体并设置导航属性 - var result = _mapper.Map(dbAlias); - result.Variable = _mapper.Map(variable); - result.MqttServer = _mapper.Map(mqttServer); - - return result; - } } \ No newline at end of file diff --git a/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs b/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs index addcea6..c565474 100644 --- a/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs +++ b/DMS.Infrastructure/Services/Mqtt/MqttServiceManager.cs @@ -270,9 +270,12 @@ namespace DMS.Infrastructure.Services.Mqtt StringBuilder sb = new StringBuilder(); 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.DisplayValue)); - sb.Append(variableMqtt.MqttServer.MessageFooter); + if (!String.IsNullOrWhiteSpace(variableMqtt.MqttServer.MessageHeader)) + sb.Append(variableMqtt.MqttServer.MessageHeader.Replace("{timestamp}", timestamp.ToString())); + if (!String.IsNullOrWhiteSpace(variableMqtt.MqttServer.MessageContent)) + sb.Append(variableMqtt.MqttServer.MessageContent.Replace("{name}", variableMqtt.Alias).Replace("{value}", variableMqtt.Variable.DisplayValue)); + if (!String.IsNullOrWhiteSpace(variableMqtt.MqttServer.MessageFooter)) + sb.Append(variableMqtt.MqttServer.MessageFooter); return sb.ToString(); } diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs index 78b42bb..47534d0 100644 --- a/DMS.WPF/App.xaml.cs +++ b/DMS.WPF/App.xaml.cs @@ -264,6 +264,8 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // 注册触发器管理服务 services.AddSingleton(); // 注册触发器评估服务 @@ -301,6 +303,7 @@ public partial class App : System.Windows.Application services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); // 注册触发器数据服务 services.AddSingleton(); diff --git a/DMS.WPF/Interfaces/IDataStorageService.cs b/DMS.WPF/Interfaces/IDataStorageService.cs index d0df143..5cbbd66 100644 --- a/DMS.WPF/Interfaces/IDataStorageService.cs +++ b/DMS.WPF/Interfaces/IDataStorageService.cs @@ -42,6 +42,11 @@ public interface IDataStorageService /// ObservableCollection Nlogs { get; set; } + /// + /// MQTT别名列表。 + /// + ObservableDictionary MqttAliases { get; set; } + /// /// 触发器列表。 /// diff --git a/DMS.WPF/Interfaces/IMqttAliasDataService.cs b/DMS.WPF/Interfaces/IMqttAliasDataService.cs new file mode 100644 index 0000000..53fbdd5 --- /dev/null +++ b/DMS.WPF/Interfaces/IMqttAliasDataService.cs @@ -0,0 +1,36 @@ +using System.Collections.ObjectModel; +using DMS.Application.DTOs; +using DMS.WPF.ItemViewModel; + +namespace DMS.WPF.Interfaces; + +/// +/// MQTT别名数据服务接口。 +/// +public interface IMqttAliasDataService +{ + /// + /// 加载所有MQTT别名数据。 + /// + Task LoadMqttAliases(); + + /// + /// 添加MQTT别名。 + /// + Task AssignAliasAsync(MqttAliasItem mqttAlias); + + /// + /// 更新MQTT别名。 + /// + Task UpdateMqttAlias(MqttAliasItem mqttAlias); + + /// + /// 删除MQTT别名。 + /// + Task DeleteMqttAlias(MqttAliasItem mqttAlias); + + /// + /// 根据ID获取MQTT别名。 + /// + Task GetMqttAliasById(int id); +} \ No newline at end of file diff --git a/DMS.WPF/Interfaces/IWPFDataService.cs b/DMS.WPF/Interfaces/IWPFDataService.cs index b7b8aa7..9097991 100644 --- a/DMS.WPF/Interfaces/IWPFDataService.cs +++ b/DMS.WPF/Interfaces/IWPFDataService.cs @@ -31,6 +31,11 @@ public interface IWPFDataService /// IMqttDataService MqttDataService { get; } + /// + /// MQTT别名数据服务。 + /// + IMqttAliasDataService MqttAliasDataService { get; } + /// /// 日志数据服务。 /// diff --git a/DMS.WPF/ItemViewModel/VariableItem.cs b/DMS.WPF/ItemViewModel/VariableItem.cs index d252088..2b233ef 100644 --- a/DMS.WPF/ItemViewModel/VariableItem.cs +++ b/DMS.WPF/ItemViewModel/VariableItem.cs @@ -106,7 +106,7 @@ public partial class VariableItem : ObservableObject /// 一个变量可以有多个MQTT别名。 /// [ObservableProperty] - private List? _mqttAliases=new List(); + private List _mqttAliases=new List(); /// /// 获取或设置变量的信号类型 (如:AI, DI, AO, DO)。 diff --git a/DMS.WPF/Profiles/MappingProfile.cs b/DMS.WPF/Profiles/MappingProfile.cs index 5b076dd..cbf3cde 100644 --- a/DMS.WPF/Profiles/MappingProfile.cs +++ b/DMS.WPF/Profiles/MappingProfile.cs @@ -14,21 +14,25 @@ namespace DMS.WPF.Profiles CreateMap() .ReverseMap(); CreateMap() + .ForMember(dest => dest.MqttAliases, opt => opt.Ignore()) .ReverseMap(); CreateMap() .ReverseMap(); CreateMap() .ReverseMap(); CreateMap(); - CreateMap().ReverseMap(); - + CreateMap() + .ReverseMap(); + CreateMap() .ReverseMap(); - - CreateMap().ReverseMap(); + + CreateMap() + .ForMember(dest => dest.VariableAliases, opt => opt.Ignore()) + .ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap() diff --git a/DMS.WPF/Services/DataEventService.cs b/DMS.WPF/Services/DataEventService.cs index 94adb87..ebab5ef 100644 --- a/DMS.WPF/Services/DataEventService.cs +++ b/DMS.WPF/Services/DataEventService.cs @@ -142,6 +142,9 @@ public class DataEventService : IDataEventService _wpfDataService.MqttDataService.LoadMqttServers(); _logger?.LogDebug("MQTT服务器数据加载完成"); + _wpfDataService.MqttAliasDataService.LoadMqttAliases(); + _logger?.LogDebug("MQTT别名加载完成"); + _wpfDataService.LogDataService.LoadAllLog(); _logger?.LogDebug("日志数据加载完成"); diff --git a/DMS.WPF/Services/DataStorageService.cs b/DMS.WPF/Services/DataStorageService.cs index 5f7c9e3..93a1f04 100644 --- a/DMS.WPF/Services/DataStorageService.cs +++ b/DMS.WPF/Services/DataStorageService.cs @@ -46,6 +46,11 @@ public class DataStorageService : IDataStorageService /// public ObservableCollection Nlogs { get; set; } + /// + /// MQTT别名列表。 + /// + public ObservableDictionary MqttAliases { get; set; } + /// /// 触发器列表。 /// @@ -60,6 +65,7 @@ public class DataStorageService : IDataStorageService Menus=new ObservableCollection(); MenuTrees=new ObservableCollection(); Nlogs=new ObservableCollection(); + MqttAliases=new ObservableDictionary(); Triggers = new ObservableDictionary(); } diff --git a/DMS.WPF/Services/MqttAliasDataService.cs b/DMS.WPF/Services/MqttAliasDataService.cs new file mode 100644 index 0000000..1607f51 --- /dev/null +++ b/DMS.WPF/Services/MqttAliasDataService.cs @@ -0,0 +1,174 @@ +using AutoMapper; +using DMS.Application.DTOs; +using DMS.Application.Interfaces; +using DMS.Application.Interfaces.Management; +using DMS.WPF.Interfaces; +using DMS.WPF.ItemViewModel; + +namespace DMS.WPF.Services; + +/// +/// MQTT别名数据服务类,负责管理MQTT别名相关的数据和操作。 +/// +public class MqttAliasDataService : IMqttAliasDataService +{ + private readonly IMapper _mapper; + private readonly IAppDataStorageService _appDataStorageService; + private readonly IMqttAliasManagementService _mqttAliasManagementService; + private readonly IDataStorageService _dataStorageService; + + /// + /// MqttAliasDataService类的构造函数。 + /// + /// AutoMapper 实例。 + /// 应用数据存储服务实例。 + /// MQTT别名管理服务实例。 + /// 数据存储服务实例。 + public MqttAliasDataService(IMapper mapper, + IAppDataStorageService appDataStorageService, + IMqttAliasManagementService mqttAliasManagementService, + IDataStorageService dataStorageService) + { + _mapper = mapper; + _appDataStorageService = appDataStorageService; + _mqttAliasManagementService = mqttAliasManagementService; + _dataStorageService = dataStorageService; + } + + /// + /// 加载所有MQTT别名数据。 + /// + public async Task LoadMqttAliases() + { + try + { + // 清空现有数据 + _dataStorageService.MqttAliases.Clear(); + + // 加载MQTT别名数据 + foreach (var mqttAlias in _appDataStorageService.MqttAliases.Values) + { + MqttAliasItem mqttAliasItem = _mapper.Map(mqttAlias); + if(_dataStorageService.MqttAliases.TryAdd(mqttAlias.Id, mqttAliasItem)) + { + + if (_dataStorageService.MqttServers.TryGetValue(mqttAlias.MqttServerId,out var mqttServerItem)) + { + mqttServerItem.VariableAliases.Add(mqttAliasItem); + mqttAliasItem.MqttServer = mqttServerItem; + } + + if (_dataStorageService.Variables.TryGetValue(mqttAlias.VariableId,out var variableItem)) + { + variableItem.MqttAliases.Add(mqttAliasItem); + mqttAliasItem.Variable = variableItem; + } + + } + + } + } + catch (Exception ex) + { + // 记录异常或处理错误 + Console.WriteLine($"加载MQTT别名数据时发生错误: {ex.Message}"); + } + } + + /// + /// 添加MQTT别名。 + /// + public async Task AssignAliasAsync(MqttAliasItem mqttAlias) + { + var addMqttAlias = await _mqttAliasManagementService.AssignAliasAsync(_mapper.Map(mqttAlias)); + + + if (_dataStorageService.MqttAliases.ContainsKey(addMqttAlias.Id)) + { + return null; + } + mqttAlias.Id = addMqttAlias.Id; + + _dataStorageService.MqttAliases.Add(mqttAlias.Id, mqttAlias); + if (_dataStorageService.MqttServers.TryGetValue(mqttAlias.MqttServerId, out var mqttServerItem)) + { + mqttAlias.MqttServer = mqttServerItem; + mqttServerItem.VariableAliases.Add(mqttAlias); + } + if (_dataStorageService.Variables.TryGetValue(mqttAlias.VariableId, out var variableItem)) + { + mqttAlias.Variable = variableItem; + variableItem.MqttAliases.Add(mqttAlias); + } + + return mqttAlias; + } + + /// + /// 更新MQTT别名。 + /// + public async Task UpdateMqttAlias(MqttAliasItem mqttAlias) + { + var result = await _mqttAliasManagementService.UpdateAsync(_mapper.Map(mqttAlias)); + + if (result > 0) + { + // 更新界面数据 + if (_dataStorageService.MqttAliases.TryGetValue(mqttAlias.Id, out var existingAlias)) + { + // 更新现有别名的属性 + existingAlias.VariableId = mqttAlias.VariableId; + existingAlias.MqttServerId = mqttAlias.MqttServerId; + existingAlias.Alias = mqttAlias.Alias; + existingAlias.MqttServerName = mqttAlias.MqttServerName; + } + } + + return result > 0; + } + + /// + /// 删除MQTT别名。 + /// + public async Task DeleteMqttAlias(MqttAliasItem mqttAlias) + { + // 从数据库和内存中删除MQTT别名 + var result = await _mqttAliasManagementService.UpdateAsync(new MqttAlias + { + Id = mqttAlias.Id, + VariableId = mqttAlias.VariableId, + MqttServerId = mqttAlias.MqttServerId, + Alias = null // Setting alias to null effectively removes the alias + }); + + if (result > 0) + { + // 从界面删除MQTT别名 + _dataStorageService.MqttAliases.Remove(mqttAlias.Id); + } + + return result > 0; + } + + /// + /// 根据ID获取MQTT别名。 + /// + public async Task GetMqttAliasById(int id) + { + if (_dataStorageService.MqttAliases.TryGetValue(id, out var mqttAliasItem)) + { + return mqttAliasItem; + } + + // 如果内存中没有,则从数据库查询 + var mqttAlias = await _mqttAliasManagementService.AssignAliasAsync(new MqttAlias { Id = id }); + if (mqttAlias != null) + { + var mappedItem = _mapper.Map(mqttAlias); + _dataStorageService.MqttAliases.TryAdd(mappedItem.Id, mappedItem); + return mappedItem; + } + + return null; + } +} \ No newline at end of file diff --git a/DMS.WPF/Services/WPFDataService.cs b/DMS.WPF/Services/WPFDataService.cs index 8e0464a..81b1467 100644 --- a/DMS.WPF/Services/WPFDataService.cs +++ b/DMS.WPF/Services/WPFDataService.cs @@ -39,6 +39,11 @@ public class WPFDataService : IWPFDataService /// public IMqttDataService MqttDataService { get; } + /// + /// MQTT别名数据服务。 + /// + public IMqttAliasDataService MqttAliasDataService { get; } + /// /// 日志数据服务。 /// @@ -61,7 +66,8 @@ public class WPFDataService : IWPFDataService IMqttDataService mqttDataService, ILogDataService logDataService, IVariableTableDataService variableTableDataService, - ITriggerDataService triggerDataService) + ITriggerDataService triggerDataService, + IMqttAliasDataService mqttAliasDataService) { _mapper = mapper; _appDataCenterService = appDataCenterService; @@ -72,5 +78,6 @@ public class WPFDataService : IWPFDataService LogDataService = logDataService; VariableTableDataService = variableTableDataService; TriggerDataService = triggerDataService; + MqttAliasDataService = mqttAliasDataService; } } diff --git a/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs b/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs index ff3c386..4a2e7a3 100644 --- a/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs +++ b/DMS.WPF/ViewModels/MqttServerDetailViewModel.cs @@ -222,42 +222,36 @@ namespace DMS.WPF.ViewModels { return; } - foreach (var item in resMqttAliaes) + + int counter = 0; + foreach (var mqttAliasItem in resMqttAliaes) { foreach (var selectItem in selectedMqttAliaes) { - if (item.Id == selectItem.Id) + if (mqttAliasItem.Id == selectItem.Id) { - selectItem.Alias = item.Alias; + selectItem.Alias = mqttAliasItem.Alias; } } + + // 保存更改到数据服务 + var result = await _wpfDataService.MqttAliasDataService.UpdateMqttAlias(mqttAliasItem); + if (result) + { + counter++; + } + } - //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; - // } + if (counter>0) + { + _notificationService.ShowSuccess($"成功修改发送名称:{counter}个"); + } + else + { + _notificationService.ShowError("更新发送名称失败。"); + } } catch (Exception e) { diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index 28b4a3a..3a211d0 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -627,48 +627,14 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable // 为每个变量分配MQTT别名 foreach (var editedVariableMqtt in editedVariableMqtts) { - await _mqttAliasAppService.AssignAliasAsync( - editedVariableMqtt.VariableId, - selectedMqtt.Id, - editedVariableMqtt.Alias); - - totalAffectedCount++; - - // 更新内存中的 Variable 对象 - var originalVariable = validVariables.FirstOrDefault(v => v.Id == editedVariableMqtt.VariableId); - if (originalVariable == null) + var mqttAliasItem = await _wpfDataService.MqttAliasDataService.AssignAliasAsync(editedVariableMqtt); + if (mqttAliasItem is not null) { - continue; + totalAffectedCount++; } + - if (originalVariable.MqttAliases == null) - { - originalVariable.MqttAliases = new(); - } - // 检查是否已存在该变量与该MQTT服务器的关联 - var existingVariableMqtt - = originalVariable.MqttAliases.FirstOrDefault(vm => vm.MqttServerId == selectedMqtt.Id); - - if (existingVariableMqtt == null) - { - // 如果不存在,则添加新的关联 - var variableMqtt = new MqttAliasItem - { - VariableId = originalVariable.Id, - MqttServerId = selectedMqtt.Id, - Alias = editedVariableMqtt.Alias, - MqttServer = selectedMqtt, - Variable = originalVariable - }; - originalVariable.MqttAliases.Add(variableMqtt); - selectedMqtt.VariableAliases.Add(variableMqtt); - } - else - { - // 如果存在,则更新别名 - existingVariableMqtt.Alias = editedVariableMqtt.Alias; - } } if (totalAffectedCount > 0)