From bcdb119d11af6e2e570006bf2112c1413158eca1 Mon Sep 17 00:00:00 2001 From: "David P.G" Date: Fri, 19 Sep 2025 07:27:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=94=BB=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/Database/DeviceAppService.cs | 2 + .../Database/VariableTableAppService.cs | 2 +- .../VariableTableManagementService.cs | 10 +- .../Repositories/IVariableRepository.cs | 7 + .../Repositories/IVariableTableRepository.cs | 7 + .../Repositories/VariableRepository.cs | 99 +--- .../Repositories/VariableTableRepository.cs | 57 +- DMS.WPF/Services/DeviceDataService.cs | 25 +- DMS.WPF/Services/VariableTableDataService.cs | 1 + DMS.WPF/ViewModels/DevicesViewModel.cs | 13 +- DMS.WPF/ViewModels/VariableTableViewModel.cs | 1 + DMS.WPF/Views/DevicesView.xaml | 490 +++++++++--------- 12 files changed, 354 insertions(+), 360 deletions(-) diff --git a/DMS.Application/Services/Database/DeviceAppService.cs b/DMS.Application/Services/Database/DeviceAppService.cs index 11caecf..3b4e9b1 100644 --- a/DMS.Application/Services/Database/DeviceAppService.cs +++ b/DMS.Application/Services/Database/DeviceAppService.cs @@ -188,6 +188,8 @@ public class DeviceAppService : IDeviceAppService // 删除关联的变量表 await _repoManager.VariableTables.DeleteByDeviceIdAsync(deviceId); + // 删除关联的变量 + await _repoManager.Variables.DeleteByVariableTableIdAsync(deviceId); // 删除关联的菜单树 await _repoManager.Menus.DeleteMenuTreeByTargetIdAsync(MenuType.DeviceMenu,deviceId); diff --git a/DMS.Application/Services/Database/VariableTableAppService.cs b/DMS.Application/Services/Database/VariableTableAppService.cs index cb53fba..f1d00d4 100644 --- a/DMS.Application/Services/Database/VariableTableAppService.cs +++ b/DMS.Application/Services/Database/VariableTableAppService.cs @@ -153,7 +153,7 @@ namespace DMS.Application.Services.Database } // 删除关联的变量 - await _repositoryManager.Variables.DeleteByIdAsync(id); + await _repositoryManager.Variables.DeleteByVariableTableIdAsync(id); // 删除关联的MQTT别名 // await _repositoryManager.VariableMqttAlias.DeleteByVariableTableIdAsync(id); diff --git a/DMS.Application/Services/Management/VariableTableManagementService.cs b/DMS.Application/Services/Management/VariableTableManagementService.cs index 4c5e342..fbbf1d3 100644 --- a/DMS.Application/Services/Management/VariableTableManagementService.cs +++ b/DMS.Application/Services/Management/VariableTableManagementService.cs @@ -15,7 +15,6 @@ public class VariableTableManagementService : IVariableTableManagementService { private readonly IVariableTableAppService _variableTableAppService; private readonly IAppDataStorageService _appDataStorageService; - private readonly ConcurrentDictionary _variableTables; /// /// 当变量表数据发生变化时触发 @@ -95,16 +94,13 @@ public class VariableTableManagementService : IVariableTableManagementService } // 确保_variableTables和variableTableDto不为null - if (_variableTables != null && variableTableDto != null) - { - if (_variableTables.TryAdd(variableTableDto.Id, variableTableDto)) + if (_appDataStorageService.VariableTables.TryAdd(variableTableDto.Id, variableTableDto)) { OnVariableTableChanged?.Invoke(this, new VariableTableChangedEventArgs( DataChangeType.Added, variableTableDto, deviceDto)); } - } } /// @@ -118,7 +114,7 @@ public class VariableTableManagementService : IVariableTableManagementService deviceDto = device; } - _variableTables.AddOrUpdate(variableTableDto.Id, variableTableDto, (key, oldValue) => variableTableDto); + _appDataStorageService.VariableTables.AddOrUpdate(variableTableDto.Id, variableTableDto, (key, oldValue) => variableTableDto); OnVariableTableChanged?.Invoke(this,new VariableTableChangedEventArgs( DataChangeType.Updated, variableTableDto, @@ -130,7 +126,7 @@ public class VariableTableManagementService : IVariableTableManagementService /// public void RemoveVariableTableFromMemory(int variableTableId) { - if (_variableTables.TryRemove(variableTableId, out var variableTableDto)) + if (_appDataStorageService.VariableTables.TryRemove(variableTableId, out var variableTableDto)) { DeviceDto deviceDto = null; if (variableTableDto != null && _appDataStorageService.Devices.TryGetValue(variableTableDto.DeviceId, out var device)) diff --git a/DMS.Core/Interfaces/Repositories/IVariableRepository.cs b/DMS.Core/Interfaces/Repositories/IVariableRepository.cs index 9eea0fe..73f0857 100644 --- a/DMS.Core/Interfaces/Repositories/IVariableRepository.cs +++ b/DMS.Core/Interfaces/Repositories/IVariableRepository.cs @@ -5,6 +5,13 @@ namespace DMS.Core.Interfaces.Repositories { public interface IVariableRepository:IBaseRepository { + /// + /// 异步根据变量表ID删除变量。 + /// + /// 变量表的唯一标识符。 + /// 受影响的行数。 + Task DeleteByVariableTableIdAsync(int variableTableId); + /// /// 异步根据OPC UA NodeId获取单个变量实体。 /// diff --git a/DMS.Core/Interfaces/Repositories/IVariableTableRepository.cs b/DMS.Core/Interfaces/Repositories/IVariableTableRepository.cs index 7317589..e3deffe 100644 --- a/DMS.Core/Interfaces/Repositories/IVariableTableRepository.cs +++ b/DMS.Core/Interfaces/Repositories/IVariableTableRepository.cs @@ -6,5 +6,12 @@ namespace DMS.Core.Interfaces.Repositories public interface IVariableTableRepository:IBaseRepository { Task DeleteByDeviceIdAsync(int deviceId); + + /// + /// 异步根据ID获取单个变量表。 + /// + /// 变量表的唯一标识符。 + /// 对应的变量表实体,如果不存在则为null。 + Task> GetByDeviceIdAsync(int deviceId); } } \ No newline at end of file diff --git a/DMS.Infrastructure/Repositories/VariableRepository.cs b/DMS.Infrastructure/Repositories/VariableRepository.cs index b4ba7cd..e06235a 100644 --- a/DMS.Infrastructure/Repositories/VariableRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableRepository.cs @@ -29,88 +29,6 @@ public class VariableRepository : BaseRepository, IVariableRepositor } - /* - /// - /// 为变量添加MQTT服务器关联,并指定别名。(此方法当前被注释,可能为待实现或废弃功能) - /// - /// - /// 要添加MQTT服务器的变量数据列表。 - /// 成功添加或更新关联的数量。 - public async Task AddMqttToVariablesAsync(IEnumerable variableMqttList) - { - await _dbContext.GetInstance().BeginTranAsync(); - - try - { - int affectedCount = 0; - var variableIds = variableMqttList.Select(vm => vm.Variable.Id).Distinct().ToList(); - var mqttIds = variableMqttList.Select(vm => vm.Mqtt.Id).Distinct().ToList(); - - // 1. 一次性查询所有相关的现有别名 - var existingAliases = await _dbContext.GetInstance().Queryable() - .Where(it => variableIds.Contains(it.VariableId) && mqttIds.Contains(it.MqttId)) - .ToListAsync(); - - var existingAliasesDict = existingAliases - .ToDictionary(a => (a.VariableId, a.Mqtt.Id), a => a); - - var toInsert = new List(); - var toUpdate = new List(); - - foreach (var variableMqtt in variableMqttList) - { - var key = (variableMqtt.Variable.Id, variableMqtt.Mqtt.Id); - if (existingAliasesDict.TryGetValue(key, out var existingAlias)) - { - // 如果存在但别名不同,则准备更新 - // if (existingAlias.MqttAlias != variableMqtt.MqttAlias) - // { - // existingAlias.MqttAlias = variableMqtt.MqttAlias; - // existingAlias.UpdateTime = DateTime.Now; - // toUpdate.Add(existingAlias); - // } - } - else - { - // 如果不存在,则准备插入 - toInsert.Add(new DbVariableMqtt - { - VariableId = variableMqtt.Variable.Id, - MqttId = variableMqtt.Mqtt.Id, - // MqttAlias = variableMqtt.MqttAlias, - CreateTime = DateTime.Now, - UpdateTime = DateTime.Now - }); - } - } - - // 2. 批量更新 - if (toUpdate.Any()) - { - var updateResult = await _dbContext.GetInstance().Updateable(toUpdate).ExecuteCommandAsync(); - affectedCount += updateResult; - } - - // 3. 批量插入 - if (toInsert.Any()) - { - var insertResult = await _dbContext.GetInstance().Insertable(toInsert).ExecuteCommandAsync(); - affectedCount += insertResult; - } - - await _dbContext.GetInstance().CommitTranAsync(); - //_logger.LogInformation($"成功为 {variableMqttList.Count()} 个变量请求添加/更新了MQTT服务器关联,实际影响 {affectedCount} 个。"); - return affectedCount; - } - catch (Exception ex) - { - await _dbContext.GetInstance().RollbackTranAsync(); - //_logger.LogError(ex, $"为变量添加MQTT服务器关联时发生错误: {ex.Message}"); - // 根据需要,可以向上层抛出异常 - throw; - } - } -*/ /// /// 异步根据ID获取单个变量。 /// @@ -158,6 +76,23 @@ public class VariableRepository : BaseRepository, IVariableRepositor public async Task DeleteAsync(Variable entity) => await base.DeleteAsync(_mapper.Map(entity)); + /// + /// 异步根据变量表ID删除变量。 + /// + /// 变量表的唯一标识符。 + /// 受影响的行数。 + public async Task DeleteByVariableTableIdAsync(int variableTableId) + { + var stopwatch = new Stopwatch(); + stopwatch.Start(); + var result = await _dbContext.GetInstance().Deleteable() + .Where(v => v.VariableTableId == variableTableId) + .ExecuteCommandAsync(); + stopwatch.Stop(); + _logger.LogInformation($"Delete {typeof(DbVariable)} by VariableTableId={variableTableId}, Count={result}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); + return result; + } + /// /// 异步根据ID删除变量。 /// diff --git a/DMS.Infrastructure/Repositories/VariableTableRepository.cs b/DMS.Infrastructure/Repositories/VariableTableRepository.cs index e4980e4..86dbfc8 100644 --- a/DMS.Infrastructure/Repositories/VariableTableRepository.cs +++ b/DMS.Infrastructure/Repositories/VariableTableRepository.cs @@ -3,8 +3,6 @@ using DMS.Core.Interfaces.Repositories; using DMS.Core.Models; using DMS.Infrastructure.Data; using DMS.Infrastructure.Entities; - - using AutoMapper; using Microsoft.Extensions.Logging; @@ -17,6 +15,7 @@ namespace DMS.Infrastructure.Repositories; public class VariableTableRepository : BaseRepository, IVariableTableRepository { private readonly IMapper _mapper; + private readonly IVariableRepository _variableRepository; /// /// 构造函数,注入 AutoMapper 和 SqlSugarDbContext。 @@ -24,10 +23,26 @@ public class VariableTableRepository : BaseRepository, IVariabl /// AutoMapper 实例,用于实体模型和数据库模型之间的映射。 /// SqlSugar 数据库上下文,用于数据库操作。 /// 日志记录器实例。 - public VariableTableRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger) + public VariableTableRepository(IMapper mapper, SqlSugarDbContext dbContext, ILogger logger, + IVariableRepository variableRepository) : base(dbContext, logger) { _mapper = mapper; + _variableRepository = variableRepository; + } + + /// + /// 异步根据ID获取单个变量表。 + /// + /// 变量表的唯一标识符。 + /// 对应的变量表实体,如果不存在则为null。 + public async Task> GetByDeviceIdAsync(int deviceId) + { + var variableTables = await _dbContext.GetInstance() + .Queryable() + .Where(d => d.DeviceId == deviceId) + .ToListAsync(); + return _mapper.Map>(variableTables); } /// @@ -67,15 +82,23 @@ public class VariableTableRepository : BaseRepository, IVariabl /// /// 要更新的变量表实体。 /// 受影响的行数。 - public async Task UpdateAsync(VariableTable entity) => await base.UpdateAsync(_mapper.Map(entity)); + public async Task UpdateAsync(VariableTable entity) => + await base.UpdateAsync(_mapper.Map(entity)); /// /// 异步删除变量表。 /// /// 要删除的变量表实体。 /// 受影响的行数。 - public async Task DeleteAsync(VariableTable entity) => await base.DeleteAsync(_mapper.Map(entity)); - + public async Task DeleteAsync(VariableTable entity) + { + //删除变量表中的所有变量 + await _variableRepository.DeleteByVariableTableIdAsync(entity.Id); + //删除变量表 + return await base.DeleteAsync(_mapper.Map(entity)); + } + + /// /// 异步根据ID删除变量表。 /// @@ -85,13 +108,17 @@ public class VariableTableRepository : BaseRepository, IVariabl { var stopwatch = new Stopwatch(); stopwatch.Start(); - var result = await _dbContext.GetInstance().Deleteable(new DbVariableTable() { Id = id }) - .ExecuteCommandAsync(); + //删除变量表中的所有变量 + await _variableRepository.DeleteByVariableTableIdAsync(id); + //删除变量表 + var result = await _dbContext.GetInstance() + .Deleteable(new DbVariableTable() { Id = id }) + .ExecuteCommandAsync(); stopwatch.Stop(); _logger.LogInformation($"Delete {typeof(DbVariableTable)},ID={id},耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; } - + /// /// 异步获取指定数量的变量表。 /// @@ -101,7 +128,6 @@ public class VariableTableRepository : BaseRepository, IVariabl { var dbList = await base.TakeAsync(number); return _mapper.Map>(dbList); - } public async Task> AddBatchAsync(List entities) @@ -120,9 +146,14 @@ public class VariableTableRepository : BaseRepository, IVariabl { var stopwatch = new Stopwatch(); stopwatch.Start(); - var result = await _dbContext.GetInstance().Deleteable() - .Where(it => it.DeviceId == deviceId) - .ExecuteCommandAsync(); + int result = 0; + var variableTables = await GetByDeviceIdAsync(deviceId); + foreach (var variableTable in variableTables) + { + var res= await DeleteByIdAsync(variableTable.Id); + result += res; + } + stopwatch.Stop(); _logger.LogInformation($"Delete VariableTable by DeviceId={deviceId}, 耗时:{stopwatch.ElapsedMilliseconds}ms"); return result; diff --git a/DMS.WPF/Services/DeviceDataService.cs b/DMS.WPF/Services/DeviceDataService.cs index 98c1c6b..512dfe1 100644 --- a/DMS.WPF/Services/DeviceDataService.cs +++ b/DMS.WPF/Services/DeviceDataService.cs @@ -4,6 +4,7 @@ using AutoMapper; using CommunityToolkit.Mvvm.ComponentModel; using DMS.Application.DTOs; using DMS.Application.Interfaces; +using DMS.Core.Enums; using DMS.Core.Events; using DMS.WPF.Interfaces; using DMS.WPF.ViewModels.Items; @@ -19,6 +20,7 @@ public class DeviceDataService : IDeviceDataService private readonly IAppDataCenterService _appDataCenterService; private readonly IAppDataStorageService _appDataStorageService; private readonly IDataStorageService _dataStorageService; + private readonly IVariableTableDataService _variableTableDataService; private readonly IEventService _eventService; private readonly INotificationService _notificationService; private readonly IMenuDataService _menuDataService; @@ -31,7 +33,7 @@ public class DeviceDataService : IDeviceDataService /// AutoMapper 实例。 /// 数据服务中心实例。 public DeviceDataService(IMapper mapper, IAppDataCenterService appDataCenterService, - IAppDataStorageService appDataStorageService, IDataStorageService dataStorageService, + IAppDataStorageService appDataStorageService, IDataStorageService dataStorageService,IVariableTableDataService variableTableDataService, IEventService eventService, INotificationService notificationService, IMenuDataService menuDataService, IVariableDataService variableDataService) { @@ -39,6 +41,7 @@ public class DeviceDataService : IDeviceDataService _appDataCenterService = appDataCenterService; _appDataStorageService = appDataStorageService; _dataStorageService = dataStorageService; + _variableTableDataService = variableTableDataService; _eventService = eventService; _notificationService = notificationService; _menuDataService = menuDataService; @@ -138,16 +141,30 @@ public class DeviceDataService : IDeviceDataService /// public async Task DeleteDevice(DeviceItemViewModel device) { + + //从数据库删除设备相关数据 if (!await _appDataCenterService.DeviceManagementService.DeleteDeviceByIdAsync(device.Id)) { return false; } - + //从Application项目删除设备相关数据 _appDataCenterService.DeviceManagementService.RemoveDeviceFromMemory(device.Id); + - // 删除设备 + // 从界面删除设备相关数据集 + foreach (var variableTable in device.VariableTables) + { + await _variableTableDataService.DeleteVariableTable(variableTable); + } - return _dataStorageService.Devices.Remove(device.Id); + var deviceMenu= _dataStorageService.Menus.FirstOrDefault(m => m.MenuType == MenuType.DeviceMenu && m.TargetId == device.Id); + if (deviceMenu != null) + { + _menuDataService.DeleteMenuItem(deviceMenu); + } + _dataStorageService.Devices.Remove(device.Id); + + return true; } /// diff --git a/DMS.WPF/Services/VariableTableDataService.cs b/DMS.WPF/Services/VariableTableDataService.cs index 0861175..d391ed3 100644 --- a/DMS.WPF/Services/VariableTableDataService.cs +++ b/DMS.WPF/Services/VariableTableDataService.cs @@ -120,6 +120,7 @@ public class VariableTableDataService : IVariableTableDataService } _appDataCenterService.VariableTableManagementService.RemoveVariableTableFromMemory(variableTable.Id); + // 删除变量表界面相关的菜单 var variableTableMenu =_dataStorageService.Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu && m.TargetId == variableTable.Id); diff --git a/DMS.WPF/ViewModels/DevicesViewModel.cs b/DMS.WPF/ViewModels/DevicesViewModel.cs index a308413..95c967d 100644 --- a/DMS.WPF/ViewModels/DevicesViewModel.cs +++ b/DMS.WPF/ViewModels/DevicesViewModel.cs @@ -163,10 +163,14 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable /// 删除设备命令。 /// [RelayCommand] - private async Task DeleteDevice() + private async Task DeleteDevice(DeviceItemViewModel parmDeviceItem) { try { + if (parmDeviceItem != null) + { + SelectedDevice = parmDeviceItem; + } if (SelectedDevice == null) { _notificationService.ShowError("你没有选择任何设备,请选择设备后再点击删除设备"); @@ -193,10 +197,15 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable /// 编辑设备命令。 /// [RelayCommand] - private async Task EditDevice() + private async Task EditDevice(DeviceItemViewModel parmDeviceItem) { try { + if (parmDeviceItem != null) + { + SelectedDevice = parmDeviceItem; + } + if (SelectedDevice == null) { _notificationService.ShowError("你没有选择任何设备,请选择设备后再点击编辑设备"); diff --git a/DMS.WPF/ViewModels/VariableTableViewModel.cs b/DMS.WPF/ViewModels/VariableTableViewModel.cs index dbac6c4..cfd0efe 100644 --- a/DMS.WPF/ViewModels/VariableTableViewModel.cs +++ b/DMS.WPF/ViewModels/VariableTableViewModel.cs @@ -247,6 +247,7 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable var improtVariableDtos = _mapper.Map>(improtVariable); foreach (var variableDto in improtVariableDtos) { + variableDto.IsActive = true; variableDto.CreatedAt = DateTime.Now; variableDto.UpdatedAt = DateTime.Now; variableDto.VariableTableId = CurrentVariableTable.Id; diff --git a/DMS.WPF/Views/DevicesView.xaml b/DMS.WPF/Views/DevicesView.xaml index 7e89abb..e6deabb 100644 --- a/DMS.WPF/Views/DevicesView.xaml +++ b/DMS.WPF/Views/DevicesView.xaml @@ -1,17 +1,16 @@ - + @@ -23,19 +22,17 @@ - + - + @@ -46,7 +43,8 @@ - + @@ -55,137 +53,128 @@ - - - + + + - + - - + + - + - - + + - - + + - + - + + + + + + + - - + + - + - + - - - - @@ -335,47 +320,50 @@ - + - + - + - + - + - + - +