diff --git a/DMS.Application/Class1.cs b/DMS.Application/Class1.cs deleted file mode 100644 index 72e9e8c..0000000 --- a/DMS.Application/Class1.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace DMS.Application -{ - public class Class1 - { - - } -} diff --git a/DMS.Application/Interfaces/IDataCenterService.cs b/DMS.Application/Interfaces/IDataCenterService.cs index f039f1a..6727e98 100644 --- a/DMS.Application/Interfaces/IDataCenterService.cs +++ b/DMS.Application/Interfaces/IDataCenterService.cs @@ -1,10 +1,6 @@ +using System.Collections.Concurrent; using DMS.Application.DTOs; using DMS.Application.DTOs.Events; -using DMS.Core.Models; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading.Tasks; namespace DMS.Application.Interfaces; @@ -166,6 +162,60 @@ public interface IDataCenterService #endregion + #region 变量管理 + + /// + /// 异步根据ID获取变量DTO。 + /// + Task GetVariableByIdAsync(int id); + + /// + /// 异步获取所有变量DTO列表。 + /// + Task> GetAllVariablesAsync(); + + /// + /// 异步创建一个新变量。 + /// + Task CreateVariableAsync(VariableDto variableDto); + + /// + /// 异步更新一个已存在的变量。 + /// + Task UpdateVariableAsync(VariableDto variableDto); + + /// + /// 异步批量更新变量。 + /// + Task UpdateVariablesAsync(List variableDtos); + + /// + /// 异步删除一个变量。 + /// + Task DeleteVariableAsync(int id); + + /// + /// 异步批量删除变量。 + /// + Task DeleteVariablesAsync(List ids); + + /// + /// 在内存中添加变量 + /// + void AddVariableToMemory(VariableDto variableDto); + + /// + /// 在内存中更新变量 + /// + void UpdateVariableInMemory(VariableDto variableDto); + + /// + /// 在内存中删除变量 + /// + void RemoveVariableFromMemory(int variableId); + + #endregion + #region 数据存储访问 /// @@ -187,6 +237,10 @@ public interface IDataCenterService /// 获取所有菜单的安全字典。 /// ConcurrentDictionary Menus { get; } + /// + /// 获取所有菜单树的安全字典。 + /// + ConcurrentDictionary MenuTrees { get; } #endregion diff --git a/DMS.Application/Services/DataCenterService.cs b/DMS.Application/Services/DataCenterService.cs index 72df6cc..a3f70be 100644 --- a/DMS.Application/Services/DataCenterService.cs +++ b/DMS.Application/Services/DataCenterService.cs @@ -46,6 +46,11 @@ public class DataCenterService : IDataCenterService /// public ConcurrentDictionary Menus { get; } = new(); + /// + /// 安全字典,用于存储所有菜单数据 + /// + public ConcurrentDictionary MenuTrees { get; } = new(); + #region 事件定义 /// @@ -245,9 +250,9 @@ public class DataCenterService : IDataCenterService if (VariableTables.TryAdd(variableTableDto.Id, variableTableDto)) { OnVariableTableChanged(new VariableTableChangedEventArgs( - DataChangeType.Added, - variableTableDto, - deviceDto)); + DataChangeType.Added, + variableTableDto, + deviceDto)); } } @@ -264,9 +269,9 @@ public class DataCenterService : IDataCenterService VariableTables.AddOrUpdate(variableTableDto.Id, variableTableDto, (key, oldValue) => variableTableDto); OnVariableTableChanged(new VariableTableChangedEventArgs( - DataChangeType.Updated, - variableTableDto, - deviceDto)); + DataChangeType.Updated, + variableTableDto, + deviceDto)); } /// @@ -283,9 +288,9 @@ public class DataCenterService : IDataCenterService } OnVariableTableChanged(new VariableTableChangedEventArgs( - DataChangeType.Deleted, - variableTableDto, - deviceDto)); + DataChangeType.Deleted, + variableTableDto, + deviceDto)); } } @@ -322,7 +327,7 @@ public class DataCenterService : IDataCenterService /// public async Task UpdateMenuAsync(MenuBeanDto menuDto) { - await _menuService.UpdateMenuAsync(menuDto); + await _menuService.UpdateMenuAsync(menuDto); } /// @@ -330,7 +335,7 @@ public class DataCenterService : IDataCenterService /// public async Task DeleteMenuAsync(int id) { - await _menuService.DeleteMenuAsync(id); + await _menuService.DeleteMenuAsync(id); } /// @@ -345,8 +350,6 @@ public class DataCenterService : IDataCenterService { parentMenu = parent; parent.Children.Add(menuDto); - - } OnMenuChanged(new MenuChangedEventArgs(DataChangeType.Added, menuDto, parentMenu)); @@ -391,7 +394,8 @@ public class DataCenterService : IDataCenterService /// public List GetRootMenus() { - return Menus.Values.Where(m => m.ParentId == 0).ToList(); + return Menus.Values.Where(m => m.ParentId == 0) + .ToList(); } /// @@ -401,7 +405,120 @@ public class DataCenterService : IDataCenterService /// 子菜单列表 public List GetChildMenus(int parentId) { - return Menus.Values.Where(m => m.ParentId == parentId).ToList(); + return Menus.Values.Where(m => m.ParentId == parentId) + .ToList(); + } + + #endregion + + #region 变量管理 + + /// + /// 异步根据ID获取变量DTO。 + /// + public async Task GetVariableByIdAsync(int id) + { + return await _variableAppService.GetVariableByIdAsync(id); + } + + /// + /// 异步获取所有变量DTO列表。 + /// + public async Task> GetAllVariablesAsync() + { + return await _variableAppService.GetAllVariablesAsync(); + } + + /// + /// 异步创建一个新变量。 + /// + public async Task CreateVariableAsync(VariableDto variableDto) + { + return await _variableAppService.CreateVariableAsync(variableDto); + } + + /// + /// 异步更新一个已存在的变量。 + /// + public async Task UpdateVariableAsync(VariableDto variableDto) + { + return await _variableAppService.UpdateVariableAsync(variableDto); + } + + /// + /// 异步批量更新变量。 + /// + public async Task UpdateVariablesAsync(List variableDtos) + { + return await _variableAppService.UpdateVariablesAsync(variableDtos); + } + + /// + /// 异步删除一个变量。 + /// + public async Task DeleteVariableAsync(int id) + { + return await _variableAppService.DeleteVariableAsync(id); + } + + /// + /// 异步批量删除变量。 + /// + public async Task DeleteVariablesAsync(List ids) + { + return await _variableAppService.DeleteVariablesAsync(ids); + } + + /// + /// 在内存中添加变量 + /// + public void AddVariableToMemory(VariableDto variableDto) + { + VariableTableDto variableTableDto = null; + if (VariableTables.TryGetValue(variableDto.VariableTableId, out var variableTable)) + { + variableTableDto = variableTable; + variableDto.VariableTable = variableTableDto; + variableTable.Variables.Add(variableDto); + } + + if (Variables.TryAdd(variableDto.Id, variableDto)) + { + OnVariableChanged(new VariableChangedEventArgs(DataChangeType.Added, variableDto, variableTableDto)); + } + } + + /// + /// 在内存中更新变量 + /// + public void UpdateVariableInMemory(VariableDto variableDto) + { + VariableTableDto variableTableDto = null; + if (VariableTables.TryGetValue(variableDto.VariableTableId, out var variableTable)) + { + variableTableDto = variableTable; + } + + Variables.AddOrUpdate(variableDto.Id, variableDto, (key, oldValue) => variableDto); + OnVariableChanged(new VariableChangedEventArgs(DataChangeType.Updated, variableDto, variableTableDto)); + } + + /// + /// 在内存中删除变量 + /// + public void RemoveVariableFromMemory(int variableId) + { + if (Variables.TryRemove(variableId, out var variableDto)) + { + VariableTableDto variableTableDto = null; + if (variableDto != null && VariableTables.TryGetValue(variableDto.VariableTableId, out var variableTable)) + { + variableTableDto = variableTable; + variableTable.Variables.Remove(variableDto); + } + + OnVariableChanged(new VariableChangedEventArgs(DataChangeType.Deleted, variableDto, variableTableDto)); + } } #endregion @@ -483,15 +600,16 @@ public class DataCenterService : IDataCenterService VariableTables.Clear(); Variables.Clear(); Menus.Clear(); + MenuTrees.Clear(); // 加载所有设备 var devices = await _repositoryManager.Devices.GetAllAsync(); var deviceDtos = _mapper.Map>(devices); - + // 加载所有变量表 var variableTables = await _repositoryManager.VariableTables.GetAllAsync(); var variableTableDtos = _mapper.Map>(variableTables); - + // 加载所有变量 var variables = await _repositoryManager.Variables.GetAllAsync(); var variableDtos = _mapper.Map>(variables); @@ -504,9 +622,9 @@ public class DataCenterService : IDataCenterService foreach (var deviceDto in deviceDtos) { deviceDto.VariableTables = variableTableDtos - .Where(vt => vt.DeviceId == deviceDto.Id) - .ToList(); - + .Where(vt => vt.DeviceId == deviceDto.Id) + .ToList(); + // 将设备添加到安全字典 Devices.TryAdd(deviceDto.Id, deviceDto); } @@ -515,9 +633,13 @@ public class DataCenterService : IDataCenterService foreach (var variableTableDto in variableTableDtos) { variableTableDto.Variables = variableDtos - .Where(v => v.VariableTableId == variableTableDto.Id) - .ToList(); - + .Where(v => v.VariableTableId == variableTableDto.Id) + .ToList(); + if (Devices.TryGetValue(variableTableDto.DeviceId, out var deviceDto)) + { + variableTableDto.Device = deviceDto; + } + // 将变量表添加到安全字典 VariableTables.TryAdd(variableTableDto.Id, variableTableDto); } @@ -525,6 +647,10 @@ public class DataCenterService : IDataCenterService // 将变量添加到安全字典 foreach (var variableDto in variableDtos) { + if (VariableTables.TryGetValue(variableDto.VariableTableId, out var variableTable)) + { + variableDto.VariableTable = variableTable; + } Variables.TryAdd(variableDto.Id, variableDto); } @@ -534,22 +660,43 @@ public class DataCenterService : IDataCenterService Menus.TryAdd(menuDto.Id, menuDto); } + // 遍历所有菜单项,构建树形结构 + foreach (var menu in Menus.Values) + { + // 检查是否有父ID,并且父ID不为0(通常0或null表示根节点) + if (Menus.ContainsKey(menu.ParentId) && menu.ParentId != 0) + { + // 尝试从查找表中找到父菜单 + if (Menus.TryGetValue(menu.ParentId, out var parentMenu)) + { + // 将当前菜单添加到父菜单的Children列表中 + parentMenu.Children.Add(menu); + } + // else: 如果找不到父菜单,这可能是一个数据完整性问题,可以根据需要处理 + } + else + { + // 如果没有父ID,则这是一个根菜单 + MenuTrees.TryAdd(menu.Id, menu); + } + } + // 触发数据加载完成事件 OnDataLoadCompleted(new DataLoadCompletedEventArgs( - deviceDtos, - variableTableDtos, - variableDtos, - true)); + deviceDtos, + variableTableDtos, + variableDtos, + true)); } catch (Exception ex) { // 触发数据加载失败事件 OnDataLoadCompleted(new DataLoadCompletedEventArgs( - new List(), - new List(), - new List(), - false, - ex.Message)); + new List(), + new List(), + new List(), + false, + ex.Message)); throw new ApplicationException($"加载所有数据到内存时发生错误,错误信息:{ex.Message}", ex); } } @@ -581,24 +728,26 @@ public class DataCenterService : IDataCenterService // 获取所有设备 var devices = await _repositoryManager.Devices.GetAllAsync(); var deviceDtos = _mapper.Map>(devices); - + // 为每个设备加载关联的变量表和变量 foreach (var deviceDto in deviceDtos) { // 获取设备的所有变量表 var variableTables = await _repositoryManager.VariableTables.GetAllAsync(); - var deviceVariableTables = variableTables.Where(vt => vt.DeviceId == deviceDto.Id).ToList(); + var deviceVariableTables = variableTables.Where(vt => vt.DeviceId == deviceDto.Id) + .ToList(); deviceDto.VariableTables = _mapper.Map>(deviceVariableTables); - + // 为每个变量表加载关联的变量 foreach (var variableTableDto in deviceDto.VariableTables) { var variables = await _repositoryManager.Variables.GetAllAsync(); - var tableVariables = variables.Where(v => v.VariableTableId == variableTableDto.Id).ToList(); + var tableVariables = variables.Where(v => v.VariableTableId == variableTableDto.Id) + .ToList(); variableTableDto.Variables = _mapper.Map>(tableVariables); } } - + return deviceDtos; } catch (Exception ex) @@ -617,15 +766,16 @@ public class DataCenterService : IDataCenterService // 获取所有变量表 var variableTables = await _repositoryManager.VariableTables.GetAllAsync(); var variableTableDtos = _mapper.Map>(variableTables); - + // 为每个变量表加载关联的变量 foreach (var variableTableDto in variableTableDtos) { var variables = await _repositoryManager.Variables.GetAllAsync(); - var tableVariables = variables.Where(v => v.VariableTableId == variableTableDto.Id).ToList(); + var tableVariables = variables.Where(v => v.VariableTableId == variableTableDto.Id) + .ToList(); variableTableDto.Variables = _mapper.Map>(tableVariables); } - + return variableTableDtos; } catch (Exception ex) diff --git a/DMS.WPF/Profiles/MappingProfile.cs b/DMS.WPF/Profiles/MappingProfile.cs index 1b3c28c..ec28880 100644 --- a/DMS.WPF/Profiles/MappingProfile.cs +++ b/DMS.WPF/Profiles/MappingProfile.cs @@ -20,7 +20,6 @@ namespace DMS.WPF.Profiles CreateMap() - .ForMember(dest => dest.Children, opt => opt.Ignore()) .ReverseMap(); CreateMap().ReverseMap(); diff --git a/DMS.WPF/Services/DataServices.cs b/DMS.WPF/Services/DataServices.cs index f660229..852f574 100644 --- a/DMS.WPF/Services/DataServices.cs +++ b/DMS.WPF/Services/DataServices.cs @@ -1,21 +1,10 @@ +using System.Collections.ObjectModel; using AutoMapper; using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Messaging; -using DMS.Application.DTOs; using DMS.Application.Interfaces; using DMS.Core.Enums; -using DMS.Core.Helper; using DMS.Core.Models; -using DMS.Helper; -using DMS.Infrastructure.Entities; -using DMS.Message; -using DMS.WPF.Helper; using DMS.WPF.ViewModels.Items; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using System.Collections.Concurrent; -using System.Collections.ObjectModel; - namespace DMS.WPF.Services; @@ -23,13 +12,11 @@ namespace DMS.WPF.Services; /// 数据服务类,负责从数据库加载和管理各种数据,并提供数据变更通知。 /// 继承自ObservableRecipient,可以接收消息;实现IRecipient,处理加载消息。 /// -public partial class DataServices : ObservableRecipient, IRecipient +public partial class DataServices : ObservableObject { private readonly IMapper _mapper; + private readonly IDataCenterService _dataCenterService; - private readonly IDeviceAppService _deviceAppService; - private readonly IVariableTableAppService _variableTableAppService; - private readonly IVariableAppService _variableAppService; // 设备列表,使用ObservableProperty特性,当值改变时会自动触发属性变更通知。 [ObservableProperty] @@ -56,10 +43,6 @@ public partial class DataServices : ObservableRecipient, IRecipient // private List _mqtts; - public ConcurrentDictionary AllVariables; - private readonly IMenuService _menuService; - private readonly INavigationService _navigationService; - // 设备列表变更事件,当设备列表数据更新时触发。 public event Action> OnDeviceListChanged; @@ -80,17 +63,10 @@ public partial class DataServices : ObservableRecipient, IRecipient /// /// AutoMapper 实例。 /// - public DataServices(IMapper mapper, IDeviceAppService deviceAppService, - IVariableTableAppService variableTableAppService, IVariableAppService variableAppService, - IMenuService menuService, INavigationService navigationService) + public DataServices(IMapper mapper, IDataCenterService dataCenterService) { _mapper = mapper; - _deviceAppService = deviceAppService; - _variableTableAppService = variableTableAppService; - _variableAppService = variableAppService; - _menuService = menuService; - _navigationService = navigationService; - IsActive = true; // 激活消息接收器 + _dataCenterService = dataCenterService; Devices = new ObservableCollection(); VariableTables = new ObservableCollection(); Variables = new ObservableCollection(); @@ -104,372 +80,17 @@ public partial class DataServices : ObservableRecipient, IRecipient /// 异步加载设备数据,并以高效的方式更新UI集合。 /// 此方法会比较新旧数据,只对有变化的设备进行更新、添加或删除,避免不必要的UI刷新。 /// - public async Task LoadDevices() + public async Task LoadAllDatas() { - var deviceDtos = await _deviceAppService.GetAllDevicesAsync(); - var deviceDtoIds = new HashSet(deviceDtos.Select(d => d.Id)); - - // 1. 更新现有项 & 查找需要删除的项 - var itemsToRemove = new List(); - foreach (var existingItem in Devices) - { - if (deviceDtoIds.Contains(existingItem.Id)) - { - // 设备仍然存在,检查是否有更新 - var dto = deviceDtos.First(d => d.Id == existingItem.Id); - - // 逐一比较属性,只有在发生变化时才更新 - if (existingItem.Name != dto.Name) existingItem.Name = dto.Name; - if (existingItem.Protocol != dto.Protocol) existingItem.Protocol = dto.Protocol; - if (existingItem.IpAddress != dto.IpAddress) existingItem.IpAddress = dto.IpAddress; - if (existingItem.Port != dto.Port) existingItem.Port = dto.Port; - if (existingItem.Rack != dto.Rack) existingItem.Rack = dto.Rack; - if (existingItem.Slot != dto.Slot) existingItem.Slot = dto.Slot; - if (existingItem.OpcUaServerUrl != dto.OpcUaServerUrl) existingItem.OpcUaServerUrl = dto.OpcUaServerUrl; - if (existingItem.IsActive != dto.IsActive) existingItem.IsActive = dto.IsActive; - if (existingItem.Status != dto.Status) existingItem.Status = dto.Status; - } - else - { - // 设备在新列表中不存在,标记为待删除 - itemsToRemove.Add(existingItem); - } - } - - // 2. 从UI集合中删除不再存在的项 - foreach (var item in itemsToRemove) - { - Devices.Remove(item); - } - - // 3. 添加新项 - var existingIds = new HashSet(Devices.Select(d => d.Id)); - foreach (var dto in deviceDtos) - { - if (!existingIds.Contains(dto.Id)) - { - // 这是一个新设备,添加到集合中 - var newItem = _mapper.Map(dto); - Devices.Add(newItem); - } - } - } - - - /// - /// 异步加载菜单数据,并以高效的方式更新UI集合。 - /// 此方法会比较新旧数据,只对有变化的菜单项进行更新、添加或删除,避免不必要的UI刷新。 - /// - public async Task LoadMenus() - { - var newMenus = await _menuService.GetAllMenusAsync(); // 获取最新的菜单树 (MenuItemViewModel 列表) - var newMenuIds = new HashSet(newMenus.Select(m => m.Id)); - - // 1. 更新现有项 & 查找需要删除的项 - var itemsToRemove = new List(); - foreach (var existingItem in Menus) - { - if (newMenuIds.Contains(existingItem.Id)) - { - // 菜单项仍然存在,检查是否有更新 - var newDto = newMenus.First(m => m.Id == existingItem.Id); - - // 逐一比较属性,只有在发生变化时才更新 - // 注意:MenuItemViewModel 的属性是 ObservableProperty,直接赋值会触发通知 - if (existingItem.Header != newDto.Header) existingItem.Header = newDto.Header; - if (existingItem.Icon != newDto.Icon) existingItem.Icon = newDto.Icon; - } - else - { - // 菜单项在新列表中不存在,标记为待删除 - itemsToRemove.Add(existingItem); - } - } - - // 2. 从UI集合中删除不再存在的项 - foreach (var item in itemsToRemove) - { - Menus.Remove(item); - } - - // 3. 添加新项 - var existingIds = new HashSet(Menus.Select(m => m.Id)); - foreach (var newDto in newMenus) - { - if (!existingIds.Contains(newDto.Id)) - { - // 这是一个新菜单项,添加到集合中 - // 注意:这里直接添加 IMenuService 返回的 MenuItemViewModel 实例 - Menus.Add(_mapper.Map(newDto)); - } - } - - BuildMenuTree(); - } - - /// - /// 根据扁平菜单列表构建树形结构。 - /// - /// 扁平菜单列表。 - /// 树形结构的根菜单列表。 - private void BuildMenuTree() - { - // 1. 创建一个查找表,以便通过ID快速访问菜单项 - var menuLookup = Menus.ToDictionary(m => m.Id); - - // 存储根菜单项的列表 - // var rootMenus = new List(); - - // 2. 遍历所有菜单项,构建树形结构 - foreach (var menu in Menus) - { - // 检查是否有父ID,并且父ID不为0(通常0或null表示根节点) - if (menu.ParentId.HasValue && menu.ParentId.Value != 0) - { - // 尝试从查找表中找到父菜单 - if (menuLookup.TryGetValue(menu.ParentId.Value, out var parentMenu)) - { - // 将当前菜单添加到父菜单的Children列表中 - parentMenu.Children.Add(menu); - } - // else: 如果找不到父菜单,这可能是一个数据完整性问题,可以根据需要处理 - } - else - { - // 如果没有父ID,则这是一个根菜单 - MenuTrees.Add(menu); - } - } - } - - - public void Receive(LoadMessage message) - { - } - - /// - /// 异步加载变量数据,并以高效的方式更新UI集合。 - /// 此方法会比较新旧数据,只对有变化的变量进行更新、添加或删除,避免不必要的UI刷新。 - /// - public async Task LoadVariables() - { - var variableDtos = await _variableAppService.GetAllVariablesAsync(); // 假设有此方法 - var variableDtoIds = new HashSet(variableDtos.Select(v => v.Id)); - - // 1. 更新现有项 & 查找需要删除的项 - var itemsToRemove = new List(); - foreach (var existingItem in Variables) - { - if (variableDtoIds.Contains(existingItem.Id)) - { - // 变量仍然存在,检查是否有更新 - var dto = variableDtos.First(v => v.Id == existingItem.Id); - - // 逐一比较属性,只有在发生变化时才更新 - if (existingItem.Name != dto.Name) existingItem.Name = dto.Name; - if (existingItem.S7Address != dto.S7Address) existingItem.S7Address = dto.S7Address; - if (existingItem.DataValue != dto.DataValue) existingItem.DataValue = dto.DataValue; - if (existingItem.DisplayValue != dto.DisplayValue) existingItem.DisplayValue = dto.DisplayValue; - // 注意:VariableTable 和 MqttAliases 是复杂对象,需要更深层次的比较或重新映射 - // 为了简化,这里只比较基本类型属性 - if (existingItem.SignalType != dto.SignalType) existingItem.SignalType = dto.SignalType; - if (existingItem.PollLevel != dto.PollLevel) existingItem.PollLevel = dto.PollLevel; - if (existingItem.IsActive != dto.IsActive) existingItem.IsActive = dto.IsActive; - if (existingItem.VariableTableId != dto.VariableTableId) - existingItem.VariableTableId = dto.VariableTableId; - if (existingItem.OpcUaNodeId != dto.OpcUaNodeId) existingItem.OpcUaNodeId = dto.OpcUaNodeId; - if (existingItem.IsHistoryEnabled != dto.IsHistoryEnabled) - existingItem.IsHistoryEnabled = dto.IsHistoryEnabled; - if (existingItem.HistoryDeadband != dto.HistoryDeadband) - existingItem.HistoryDeadband = dto.HistoryDeadband; - if (existingItem.IsAlarmEnabled != dto.IsAlarmEnabled) existingItem.IsAlarmEnabled = dto.IsAlarmEnabled; - if (existingItem.AlarmMinValue != dto.AlarmMinValue) existingItem.AlarmMinValue = dto.AlarmMinValue; - if (existingItem.AlarmMaxValue != dto.AlarmMaxValue) existingItem.AlarmMaxValue = dto.AlarmMaxValue; - if (existingItem.AlarmDeadband != dto.AlarmDeadband) existingItem.AlarmDeadband = dto.AlarmDeadband; - if (existingItem.Protocol != dto.Protocol) existingItem.Protocol = dto.Protocol; - if (existingItem.DataType != dto.DataType) existingItem.DataType = dto.DataType; - if (existingItem.ConversionFormula != dto.ConversionFormula) - existingItem.ConversionFormula = dto.ConversionFormula; - if (existingItem.CreatedAt != dto.CreatedAt) existingItem.CreatedAt = dto.CreatedAt; - if (existingItem.UpdatedAt != dto.UpdatedAt) existingItem.UpdatedAt = dto.UpdatedAt; - if (existingItem.UpdatedBy != dto.UpdatedBy) existingItem.UpdatedBy = dto.UpdatedBy; - if (existingItem.IsModified != dto.IsModified) existingItem.IsModified = dto.IsModified; - if (existingItem.Description != dto.Description) existingItem.Description = dto.Description; - } - else - { - // 变量在新列表中不存在,标记为待删除 - itemsToRemove.Add(existingItem); - } - } - - // 2. 从UI集合中删除不再存在的项 - foreach (var item in itemsToRemove) - { - Variables.Remove(item); - } - - // 3. 添加新项 - var existingIds = new HashSet(Variables.Select(v => v.Id)); - foreach (var dto in variableDtos) - { - if (!existingIds.Contains(dto.Id)) - { - // 这是一个新变量,添加到集合中 - var newItem = _mapper.Map(dto); - Variables.Add(newItem); - } - } - } - - /// - /// 异步加载变量表数据,并以高效的方式更新UI集合。 - /// 此方法会比较新旧数据,只对有变化的变量表进行更新、添加或删除,避免不必要的UI刷新。 - /// - public async Task LoadVariableTables() - { - var variableTableDtos = await _variableTableAppService.GetAllVariableTablesAsync(); // 假设有此方法 - var variableTableDtoIds = new HashSet(variableTableDtos.Select(vt => vt.Id)); - - // 1. 更新现有项 & 查找需要删除的项 - var itemsToRemove = new List(); - foreach (var existingItem in VariableTables) - { - if (variableTableDtoIds.Contains(existingItem.Id)) - { - // 变量表仍然存在,检查是否有更新 - var dto = variableTableDtos.First(vt => vt.Id == existingItem.Id); - - // 逐一比较属性,只有在发生变化时才更新 - if (existingItem.Name != dto.Name) existingItem.Name = dto.Name; - if (existingItem.Description != dto.Description) existingItem.Description = dto.Description; - if (existingItem.IsActive != dto.IsActive) existingItem.IsActive = dto.IsActive; - if (existingItem.DeviceId != dto.DeviceId) existingItem.DeviceId = dto.DeviceId; - if (existingItem.Protocol != dto.Protocol) existingItem.Protocol = dto.Protocol; - } - else - { - // 变量表在新列表中不存在,标记为待删除 - itemsToRemove.Add(existingItem); - } - } - - // 2. 从UI集合中删除不再存在的项 - foreach (var item in itemsToRemove) - { - VariableTables.Remove(item); - } - - // 3. 添加新项 - var existingIds = new HashSet(VariableTables.Select(vt => vt.Id)); - foreach (var dto in variableTableDtos) - { - if (!existingIds.Contains(dto.Id)) - { - // 这是一个新变量表,添加到集合中 - var newItem = _mapper.Map(dto); - var device = Devices.FirstOrDefault(d => d.Id == dto.DeviceId); - if (device != null) - { - newItem.Device = device; - } - VariableTables.Add(newItem); - } - } - } - - /// - /// 将变量表关联到对应的设备上。 - /// - public void AssociateVariableTablesToDevices() - { - // 1. 创建一个字典,按 DeviceId 分组所有变量表,以便高效查找 - var variableTablesGroupedByDevice = _variableTables - .GroupBy(vt => vt.DeviceId) - .ToDictionary(g => g.Key, g => g.ToList()); - - foreach (var device in _devices) - { - // 获取当前设备应该关联的所有变量表 - List associatedVariableTables = new List(); - if (variableTablesGroupedByDevice.TryGetValue(device.Id, out var foundTables)) - { - associatedVariableTables = foundTables; - } - - // 创建一个HashSet,用于快速查找当前设备应有的变量表ID - var shouldHaveVariableTableIds = new HashSet(associatedVariableTables.Select(vt => vt.Id)); - - // 2. 移除不再关联的变量表 - // 从后往前遍历,避免在循环中修改集合导致索引问题 - for (int i = device.VariableTables.Count - 1; i >= 0; i--) - { - var existingVariableTable = device.VariableTables[i]; - if (!shouldHaveVariableTableIds.Contains(existingVariableTable.Id)) - { - device.VariableTables.RemoveAt(i); - } - } - - // 3. 添加新关联的变量表 - var currentlyHasVariableTableIds = new HashSet(device.VariableTables.Select(vt => vt.Id)); - foreach (var newVariableTable in associatedVariableTables) - { - if (!currentlyHasVariableTableIds.Contains(newVariableTable.Id)) - { - device.VariableTables.Add(newVariableTable); - } - // 如果已经存在,则不需要额外操作,因为 LoadVariableTables 已经更新了 _variableTables 中的实例 - } - } - } - - /// - /// 将变量关联到对应的变量表上。 - /// - public void AssociateVariablesToVariableTables() - { - // 1. 创建一个字典,按 VariableTableId 分组所有变量,以便高效查找 - var variablesGroupedByVariableTable = _variables - .GroupBy(v => v.VariableTableId) - .ToDictionary(g => g.Key, g => g.ToList()); - - foreach (var variableTable in _variableTables) - { - // 获取当前变量表应该关联的所有变量 - List associatedVariables = new List(); - if (variablesGroupedByVariableTable.TryGetValue(variableTable.Id, out var foundVariables)) - { - associatedVariables = foundVariables; - } - - // 创建一个HashSet,用于快速查找当前变量表应有的变量ID - var shouldHaveVariableIds = new HashSet(associatedVariables.Select(v => v.Id)); - - // 2. 移除不再关联的变量 - // 从后往前遍历,避免在循环中修改集合导致索引问题 - for (int i = variableTable.Variables.Count - 1; i >= 0; i--) - { - var existingVariable = variableTable.Variables[i]; - if (!shouldHaveVariableIds.Contains(existingVariable.Id)) - { - variableTable.Variables.RemoveAt(i); - } - } - - // 3. 添加新关联的变量 - var currentlyHasVariableIds = new HashSet(variableTable.Variables.Select(v => v.Id)); - foreach (var newVariable in associatedVariables) - { - if (!currentlyHasVariableIds.Contains(newVariable.Id)) - { - variableTable.Variables.Add(newVariable); - } - // 如果已经存在,则不需要额外操作,因为 LoadVariables 已经更新了 _variables 中的实例 - } - } + Devices = _mapper.Map>(_dataCenterService.Devices.Values); + VariableTables= _mapper.Map>(_dataCenterService.VariableTables.Values); + Variables= _mapper.Map>(_dataCenterService.Variables.Values); + Menus= _mapper.Map>(_dataCenterService.Menus.Values); + MenuTrees= _mapper.Map>(_dataCenterService.MenuTrees.Values); + } + public void AddMenuItem(MenuItemViewModel menuItemViewModel) { if (menuItemViewModel == null) diff --git a/DMS.WPF/ViewModels/SplashViewModel.cs b/DMS.WPF/ViewModels/SplashViewModel.cs index 7c2bc15..42c7e6b 100644 --- a/DMS.WPF/ViewModels/SplashViewModel.cs +++ b/DMS.WPF/ViewModels/SplashViewModel.cs @@ -1,4 +1,5 @@ // 文件: DMS.WPF/ViewModels/SplashViewModel.cs + using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using DMS.Application.Interfaces; @@ -24,7 +25,8 @@ public partial class SplashViewModel : ObservableObject [ObservableProperty] private string _loadingMessage = "正在加载..."; - public SplashViewModel(IServiceProvider serviceProvider, IInitializeService initializeService,IDataCenterService dataCenterService, DataServices dataServices) + public SplashViewModel(IServiceProvider serviceProvider, IInitializeService initializeService, + IDataCenterService dataCenterService, DataServices dataServices) { _serviceProvider = serviceProvider; _initializeService = initializeService; @@ -40,20 +42,20 @@ public partial class SplashViewModel : ObservableObject try { LoadingMessage = "正在初始化数据库..."; - _initializeService.InitializeTables(); - _initializeService.InitializeMenus(); - - LoadingMessage = "正在加载系统配置..."; - await _dataServices.LoadDevices(); - await _dataServices.LoadVariableTables(); - await _dataServices.LoadVariables(); - await _dataServices.LoadMenus(); - + _initializeService.InitializeTables(); + _initializeService.InitializeMenus(); await _dataCenterService.LoadAllDataToMemoryAsync(); - - _dataServices.AssociateVariableTablesToDevices(); - _dataServices.AssociateVariablesToVariableTables(); + LoadingMessage = "正在加载系统配置..."; + await _dataServices.LoadAllDatas(); + // await _dataServices.LoadVariableTables(); + // await _dataServices.LoadVariables(); + // await _dataServices.LoadMenus(); + + + // _dataServices.AssociateVariableTablesToDevices(); + // _dataServices.AssociateVariablesToVariableTables(); + // 可以在这里添加加载配置的逻辑 await Task.Delay(500); // 模拟耗时 @@ -80,4 +82,4 @@ public partial class SplashViewModel : ObservableObject return false; } } -} +} \ No newline at end of file