diff --git a/src/YunDa.Application/YunDa.SOMS.Application/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfigAppService.cs b/src/YunDa.Application/YunDa.SOMS.Application/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfigAppService.cs index 8999fcc..8a10adc 100644 --- a/src/YunDa.Application/YunDa.SOMS.Application/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfigAppService.cs +++ b/src/YunDa.Application/YunDa.SOMS.Application/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfigAppService.cs @@ -48,6 +48,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection private readonly IRepository _inspectionEventItemRepository; private readonly IRepository _telemetryConfigRepository; private readonly IRepository _telesignalConfigRepository; + private readonly IRepository _telemeteringConfigurationRepository; + private readonly IRepository _telesignalisationConfigurationRepository; private readonly IRedisRepository _telemeteringRedisRepository; private readonly IRedisRepository _telesignalisationRedisRepository; private readonly IRepository _equipmentInfoRepository; @@ -75,6 +77,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection IRepository inspectionEventItemRepository, IRepository telemetryConfigRepository, IRepository telesignalConfigRepository, + IRepository telemeteringConfigurationRepository, + IRepository telesignalisationConfigurationRepository, IRedisRepository telemeteringRedisRepository, IRedisRepository telesignalisationRedisRepository, IRepository equipmentInfoRepository, @@ -88,6 +92,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection _inspectionEventItemRepository = inspectionEventItemRepository; _telemetryConfigRepository = telemetryConfigRepository; _telesignalConfigRepository = telesignalConfigRepository; + _telemeteringConfigurationRepository = telemeteringConfigurationRepository; + _telesignalisationConfigurationRepository = telesignalisationConfigurationRepository; _telemeteringRedisRepository = telemeteringRedisRepository; _telesignalisationRedisRepository = telesignalisationRedisRepository; _equipmentInfoRepository = equipmentInfoRepository; @@ -946,22 +952,8 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection RequestPageResult rst = new RequestPageResult(); try { - // Build query with eager loading of related entities - var query = _eventDrivenConfigRepository.GetAll() - .Include(x => x.SecondaryCircuitInspectionEventItems) - .ThenInclude(t => t.InspectionItem) - .ThenInclude(t => t.TelemetryConfigs) - .ThenInclude(t => t.TelemeteringConfiguration) - .Include(x => x.SecondaryCircuitInspectionEventItems) - .ThenInclude(t => t.InspectionItem) - .ThenInclude(t => t.TelesignalConfigs) - .ThenInclude(t => t.TelesignalisationConfiguration) - .Include(x => x.TelemetryConfigs) - .ThenInclude(t => t.TelemeteringConfiguration) - .Include(x => x.TelesignalConfigs) - .ThenInclude(t => t.TelesignalisationConfiguration) - .AsQueryable() - ; + // Step 1: Build query for main entities WITHOUT joins + var query = _eventDrivenConfigRepository.GetAll(); // Apply search conditions if (input.SearchCondition != null) @@ -996,103 +988,244 @@ namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection query = query.PageBy(skipCount, input.PageSize); } + // Execute query to get main entities var entities = await query.ToListAsync(cancellationToken).ConfigureAwait(false); - // Load equipment info dictionary for efficient lookups - var equipmentInfoDict = await _equipmentInfoRepository.GetAll() - .ToDictionaryAsync(e => e.Id, e => e.Name, cancellationToken) + if (!entities.Any()) + { + rst.PageSize = input.PageSize; + rst.PageIndex = input.PageIndex; + rst.TotalCount = totalCount; + rst.Flag = true; + rst.ResultData = new List(); + return rst; + } + + // Step 2: Collect all IDs for subsequent queries + var configIds = entities.Select(e => e.Id).ToList(); + + // Step 3: Query SecondaryCircuitInspectionEventItems for these configs + var eventItems = await _inspectionEventItemRepository.GetAll() + .Where(ei => configIds.Contains(ei.InpectionEventDrivenId.Value)) + .ToListAsync(cancellationToken) .ConfigureAwait(false); - // Map entities to output DTOs + var inspectionItemIds = eventItems + .Where(ei => ei.InspectionItemId.HasValue) + .Select(ei => ei.InspectionItemId.Value) + .Distinct() + .ToList(); + + // Step 4: Query InspectionItems + var inspectionItems = inspectionItemIds.Any() + ? await _inspectionItemRepository.GetAll() + .Where(ii => inspectionItemIds.Contains(ii.Id)) + .ToListAsync(cancellationToken) + .ConfigureAwait(false) + : new List(); + + // Step 5: Query TelemetryConfigs (both from EventDrivenConfig and InspectionItems) + var telemetryConfigs = await _telemetryConfigRepository.GetAll() + .Where(tc => configIds.Contains(tc.SecondaryCircuitEventDrivenConfigId.Value) || + inspectionItemIds.Contains(tc.SecondaryCircuitInspectionItemId.Value)) + .ToListAsync(cancellationToken) + .ConfigureAwait(false); + + var telemetryConfigIds = telemetryConfigs + .Where(tc => tc.TelemetryConfigurationId.HasValue) + .Select(tc => tc.TelemetryConfigurationId.Value) + .Distinct() + .ToList(); + + // Step 6: Query TelesignalConfigs (both from EventDrivenConfig and InspectionItems) + var telesignalConfigs = await _telesignalConfigRepository.GetAll() + .Where(tc => configIds.Contains(tc.SecondaryCircuitEventDrivenConfigId.Value) || + inspectionItemIds.Contains(tc.SecondaryCircuitInspectionItemId.Value)) + .ToListAsync(cancellationToken) + .ConfigureAwait(false); + + var telesignalConfigIds = telesignalConfigs + .Where(tc => tc.TelesignalConfigurationId.HasValue) + .Select(tc => tc.TelesignalConfigurationId.Value) + .Distinct() + .ToList(); + + // Step 7: Query TelemeteringConfiguration entities + var telemeteringConfigurations = telemetryConfigIds.Any() + ? await _telemeteringConfigurationRepository.GetAll() + .Where(tc => telemetryConfigIds.Contains(tc.Id)) + .ToListAsync(cancellationToken) + .ConfigureAwait(false) + : new List(); + + // Step 8: Query TelesignalisationConfiguration entities + var telesignalisationConfigurations = telesignalConfigIds.Any() + ? await _telesignalisationConfigurationRepository.GetAll() + .Where(tc => telesignalConfigIds.Contains(tc.Id)) + .ToListAsync(cancellationToken) + .ConfigureAwait(false) + : new List(); + + // Step 9: Get all equipment IDs and load equipment info dictionary + var equipmentIds = telemeteringConfigurations + .Where(tc => tc.EquipmentInfoId.HasValue) + .Select(tc => tc.EquipmentInfoId.Value) + .Concat(telesignalisationConfigurations + .Where(tc => tc.EquipmentInfoId.HasValue) + .Select(tc => tc.EquipmentInfoId.Value)) + .Distinct() + .ToList(); + + var equipmentInfoDict = equipmentIds.Any() + ? await _equipmentInfoRepository.GetAll() + .Where(e => equipmentIds.Contains(e.Id)) + .ToDictionaryAsync(e => e.Id, e => e.Name, cancellationToken) + .ConfigureAwait(false) + : new Dictionary(); + + // Step 10: Create lookup dictionaries for efficient in-memory correlation + var telemeteringConfigDict = telemeteringConfigurations.ToDictionary(tc => tc.Id); + var telesignalisationConfigDict = telesignalisationConfigurations.ToDictionary(tc => tc.Id); + var inspectionItemDict = inspectionItems.ToDictionary(ii => ii.Id); + var eventItemsByConfigId = eventItems + .Where(ei => ei.InpectionEventDrivenId.HasValue) + .GroupBy(ei => ei.InpectionEventDrivenId.Value) + .ToDictionary(g => g.Key, g => g.ToList()); + var telemetryConfigsByEventConfigId = telemetryConfigs + .Where(tc => tc.SecondaryCircuitEventDrivenConfigId.HasValue) + .GroupBy(tc => tc.SecondaryCircuitEventDrivenConfigId.Value) + .ToDictionary(g => g.Key, g => g.ToList()); + var telemetryConfigsByInspectionItemId = telemetryConfigs + .Where(tc => tc.SecondaryCircuitInspectionItemId.HasValue) + .GroupBy(tc => tc.SecondaryCircuitInspectionItemId.Value) + .ToDictionary(g => g.Key, g => g.ToList()); + var telesignalConfigsByEventConfigId = telesignalConfigs + .Where(tc => tc.SecondaryCircuitEventDrivenConfigId.HasValue) + .GroupBy(tc => tc.SecondaryCircuitEventDrivenConfigId.Value) + .ToDictionary(g => g.Key, g => g.ToList()); + var telesignalConfigsByInspectionItemId = telesignalConfigs + .Where(tc => tc.SecondaryCircuitInspectionItemId.HasValue) + .GroupBy(tc => tc.SecondaryCircuitInspectionItemId.Value) + .ToDictionary(g => g.Key, g => g.ToList()); + + // Step 11: Map entities to output DTOs using in-memory correlation var outputList = new List(); foreach (var entity in entities) { var output = ObjectMapper.Map(entity); - output.SecondaryCircuitInspectionEventItems = ObjectMapper.Map>( - entity.SecondaryCircuitInspectionEventItems.Select(t => t.InspectionItem)); - // Enrich nested inspection items with telemetry and telesignal config details - foreach (var eventItem in entity.SecondaryCircuitInspectionEventItems) + // Get event items for this config + var configEventItems = eventItemsByConfigId.ContainsKey(entity.Id) + ? eventItemsByConfigId[entity.Id] + : new List(); + + // Map inspection items + var inspectionItemOutputs = new List(); + foreach (var eventItem in configEventItems) { - if (eventItem.InspectionItem == null) continue; + if (!eventItem.InspectionItemId.HasValue || !inspectionItemDict.ContainsKey(eventItem.InspectionItemId.Value)) + continue; - var outputItem = output.SecondaryCircuitInspectionEventItems.FirstOrDefault(x => x.Id == eventItem.InspectionItem.Id); - if (outputItem == null) continue; + var inspectionItem = inspectionItemDict[eventItem.InspectionItemId.Value]; + var inspectionItemOutput = ObjectMapper.Map(inspectionItem); - // Enrich telemetry configs for nested inspection item - if (eventItem.InspectionItem.TelemetryConfigs != null && eventItem.InspectionItem.TelemetryConfigs.Any()) + // Get telemetry configs for this inspection item + var itemTelemetryConfigs = telemetryConfigsByInspectionItemId.ContainsKey(inspectionItem.Id) + ? telemetryConfigsByInspectionItemId[inspectionItem.Id] + : new List(); + + inspectionItemOutput.TelemetryConfigs = itemTelemetryConfigs + .Where(tc => tc.TelemetryConfigurationId.HasValue && telemeteringConfigDict.ContainsKey(tc.TelemetryConfigurationId.Value)) + .Select(tc => + { + var telemetryConfig = telemeteringConfigDict[tc.TelemetryConfigurationId.Value]; + return new SecondaryCircuitInspectionTelemetryConfigOutput + { + Id = tc.Id, + EquipmentInfoId = telemetryConfig.EquipmentInfoId ?? Guid.Empty, + EquipmentInfoName = telemetryConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telemetryConfig.EquipmentInfoId.Value) + ? equipmentInfoDict[telemetryConfig.EquipmentInfoId.Value] + : string.Empty, + TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty, + TelemetryConfigurationName = telemetryConfig.Name, + TelemetryConfigurationIsmsId = telemetryConfig.ismsbaseYCId + }; + }).ToList(); + inspectionItemOutput.TelemetryConfigCount = inspectionItemOutput.TelemetryConfigs.Count; + + // Get telesignal configs for this inspection item + var itemTelesignalConfigs = telesignalConfigsByInspectionItemId.ContainsKey(inspectionItem.Id) + ? telesignalConfigsByInspectionItemId[inspectionItem.Id] + : new List(); + + inspectionItemOutput.TelesignalConfigs = itemTelesignalConfigs + .Where(tc => tc.TelesignalConfigurationId.HasValue && telesignalisationConfigDict.ContainsKey(tc.TelesignalConfigurationId.Value)) + .Select(tc => + { + var telesignalConfig = telesignalisationConfigDict[tc.TelesignalConfigurationId.Value]; + return new SecondaryCircuitInspectionTelesignalConfigOutput + { + Id = tc.Id, + EquipmentInfoId = telesignalConfig.EquipmentInfoId ?? Guid.Empty, + EquipmentInfoName = telesignalConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telesignalConfig.EquipmentInfoId.Value) + ? equipmentInfoDict[telesignalConfig.EquipmentInfoId.Value] + : string.Empty, + TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty, + TelesignalConfigurationName = telesignalConfig.Name, + TelesignalConfigurationIsmsId = telesignalConfig.ismsbaseYXId + }; + }).ToList(); + inspectionItemOutput.TelesignalConfigCount = inspectionItemOutput.TelesignalConfigs.Count; + + inspectionItemOutputs.Add(inspectionItemOutput); + } + output.SecondaryCircuitInspectionEventItems = inspectionItemOutputs; + + // Map telemetry configs directly associated with event driven config + var configTelemetryConfigs = telemetryConfigsByEventConfigId.ContainsKey(entity.Id) + ? telemetryConfigsByEventConfigId[entity.Id] + : new List(); + + output.TelemetryConfigs = configTelemetryConfigs + .Where(tc => tc.TelemetryConfigurationId.HasValue && telemeteringConfigDict.ContainsKey(tc.TelemetryConfigurationId.Value)) + .Select(tc => { - outputItem.TelemetryConfigs = eventItem.InspectionItem.TelemetryConfigs.Select(tc => new SecondaryCircuitInspectionTelemetryConfigOutput + var telemetryConfig = telemeteringConfigDict[tc.TelemetryConfigurationId.Value]; + return new SecondaryCircuitInspectionTelemetryConfigOutput { Id = tc.Id, - EquipmentInfoId = tc.TelemeteringConfiguration.EquipmentInfoId.Value, - EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelemeteringConfiguration.EquipmentInfoId.Value) - ? equipmentInfoDict[tc.TelemeteringConfiguration.EquipmentInfoId.Value] + EquipmentInfoId = telemetryConfig.EquipmentInfoId ?? Guid.Empty, + EquipmentInfoName = telemetryConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telemetryConfig.EquipmentInfoId.Value) + ? equipmentInfoDict[telemetryConfig.EquipmentInfoId.Value] : string.Empty, TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty, - TelemetryConfigurationName = tc.TelemeteringConfiguration?.Name, - TelemetryConfigurationIsmsId = tc.TelemeteringConfiguration?.ismsbaseYCId - }).ToList(); - outputItem.TelemetryConfigCount = outputItem.TelemetryConfigs.Count; - } + TelemetryConfigurationName = telemetryConfig.Name, + TelemetryConfigurationIsmsId = telemetryConfig.ismsbaseYCId + }; + }).ToList(); - // Enrich telesignal configs for nested inspection item - if (eventItem.InspectionItem.TelesignalConfigs != null && eventItem.InspectionItem.TelesignalConfigs.Any()) + // Map telesignal configs directly associated with event driven config + var configTelesignalConfigs = telesignalConfigsByEventConfigId.ContainsKey(entity.Id) + ? telesignalConfigsByEventConfigId[entity.Id] + : new List(); + + output.TelesignalConfigs = configTelesignalConfigs + .Where(tc => tc.TelesignalConfigurationId.HasValue && telesignalisationConfigDict.ContainsKey(tc.TelesignalConfigurationId.Value)) + .Select(tc => { - outputItem.TelesignalConfigs = eventItem.InspectionItem.TelesignalConfigs.Select(tc => new SecondaryCircuitInspectionTelesignalConfigOutput + var telesignalConfig = telesignalisationConfigDict[tc.TelesignalConfigurationId.Value]; + return new SecondaryCircuitInspectionTelesignalConfigOutput { Id = tc.Id, - EquipmentInfoId = tc.TelesignalisationConfiguration.EquipmentInfoId.Value, - EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelesignalisationConfiguration.EquipmentInfoId.Value) - ? equipmentInfoDict[tc.TelesignalisationConfiguration.EquipmentInfoId.Value] + EquipmentInfoId = telesignalConfig.EquipmentInfoId ?? Guid.Empty, + EquipmentInfoName = telesignalConfig.EquipmentInfoId.HasValue && equipmentInfoDict.ContainsKey(telesignalConfig.EquipmentInfoId.Value) + ? equipmentInfoDict[telesignalConfig.EquipmentInfoId.Value] : string.Empty, TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty, - TelesignalConfigurationName = tc.TelesignalisationConfiguration?.Name, - TelesignalConfigurationIsmsId = tc.TelesignalisationConfiguration?.ismsbaseYXId - }).ToList(); - outputItem.TelesignalConfigCount = outputItem.TelesignalConfigs.Count; - } - } - - // Map telemetry configs - if (entity.TelemetryConfigs != null && entity.TelemetryConfigs.Any()) - { - output.TelemetryConfigs = entity.TelemetryConfigs.Select(tc => new SecondaryCircuitInspectionTelemetryConfigOutput - { - Id = tc.Id, - EquipmentInfoId = tc.TelemeteringConfiguration.EquipmentInfoId.Value, - EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelemeteringConfiguration.EquipmentInfoId.Value) - ? equipmentInfoDict[tc.TelemeteringConfiguration.EquipmentInfoId.Value] - : string.Empty, - TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty, - TelemetryConfigurationName = tc.TelemeteringConfiguration?.Name, - TelemetryConfigurationIsmsId = tc.TelemeteringConfiguration?.ismsbaseYCId + TelesignalConfigurationName = telesignalConfig.Name, + TelesignalConfigurationIsmsId = telesignalConfig.ismsbaseYXId + }; }).ToList(); - } - else - { - output.TelemetryConfigs = new List(); - } - - // Map telesignal configs - if (entity.TelesignalConfigs != null && entity.TelesignalConfigs.Any()) - { - output.TelesignalConfigs = entity.TelesignalConfigs.Select(tc => new SecondaryCircuitInspectionTelesignalConfigOutput - { - Id = tc.Id, - EquipmentInfoId = tc.TelesignalisationConfiguration.EquipmentInfoId.Value, - EquipmentInfoName = equipmentInfoDict.ContainsKey(tc.TelesignalisationConfiguration.EquipmentInfoId.Value) - ? equipmentInfoDict[tc.TelesignalisationConfiguration.EquipmentInfoId.Value] - : string.Empty, - TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty, - TelesignalConfigurationName = tc.TelesignalisationConfiguration?.Name, - TelesignalConfigurationIsmsId = tc.TelesignalisationConfiguration?.ismsbaseYXId - }).ToList(); - } - else - { - output.TelesignalConfigs = new List(); - } outputList.Add(output); } diff --git a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/NetworkCableAppService.cs b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/NetworkCableAppService.cs index 4b45871..85a5374 100644 --- a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/NetworkCableAppService.cs +++ b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/NetworkCableAppService.cs @@ -28,6 +28,7 @@ using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.DataMonitoring; using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.GeneralInformation; +using JsonException = System.Text.Json.JsonException; namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo { diff --git a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalCableAppService.cs b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalCableAppService.cs index bc2e318..f38b0ef 100644 --- a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalCableAppService.cs +++ b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalCableAppService.cs @@ -29,6 +29,7 @@ using YunDa.SOMS.DataTransferObject; using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.GeneralInformation; +using JsonException = System.Text.Json.JsonException; namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo { diff --git a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalFiberAppService.cs b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalFiberAppService.cs index c89c3ec..f03ff62 100644 --- a/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalFiberAppService.cs +++ b/src/YunDa.Application/YunDa.SOMS.Application/ExternalDataManager/BjYounuo/OpticalFiberAppService.cs @@ -29,6 +29,7 @@ using YunDa.SOMS.DataTransferObject; using YunDa.SOMS.DataTransferObject.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.ExternalEntities.BeijingYounuo; using YunDa.SOMS.Entities.GeneralInformation; +using JsonException = System.Text.Json.JsonException; namespace YunDa.SOMS.Application.ExternalDataManager.BjYounuo { diff --git a/src/YunDa.Application/YunDa.SOMS.Application/GeneralInformation/SettingAndFaultRpt/TransformInfomationAppService.cs b/src/YunDa.Application/YunDa.SOMS.Application/GeneralInformation/SettingAndFaultRpt/TransformInfomationAppService.cs index e9f92d9..cf1c404 100644 --- a/src/YunDa.Application/YunDa.SOMS.Application/GeneralInformation/SettingAndFaultRpt/TransformInfomationAppService.cs +++ b/src/YunDa.Application/YunDa.SOMS.Application/GeneralInformation/SettingAndFaultRpt/TransformInfomationAppService.cs @@ -64,7 +64,7 @@ namespace YunDa.SOMS.Application.GeneralInformation.SettingAndFaultRpt private readonly SOMSAuditingStore _SOMSAuditingStore; private string _ISMSGateWayIp = "http://127.0.0.1:38094"; - private string _ISMSftpIp = "192.168.65.33"; + private string _ISMSftpIp = "192.168.81.21"; private string _ISMSftpUser = "admin"; private string _ISMSftpPassword = "yunda123"; public TransformInfomationAppService(ISessionAppService sessionAppService diff --git a/src/YunDa.Application/YunDa.SOMS.DataTransferObject/DataMonitoring/SecondaryCircuitInspection/Configurations/EditSecondaryCircuitEventDrivenConfigInput.cs b/src/YunDa.Application/YunDa.SOMS.DataTransferObject/DataMonitoring/SecondaryCircuitInspection/Configurations/EditSecondaryCircuitEventDrivenConfigInput.cs index b1c7cc9..3beb6ef 100644 --- a/src/YunDa.Application/YunDa.SOMS.DataTransferObject/DataMonitoring/SecondaryCircuitInspection/Configurations/EditSecondaryCircuitEventDrivenConfigInput.cs +++ b/src/YunDa.Application/YunDa.SOMS.DataTransferObject/DataMonitoring/SecondaryCircuitInspection/Configurations/EditSecondaryCircuitEventDrivenConfigInput.cs @@ -38,14 +38,12 @@ namespace YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspectio /// 格式示例: Js代码 /// [Required(ErrorMessage = "触发表达式不能为空")] - [StringLength(500, ErrorMessage = "触发表达式长度不能超过500个字符")] public string TriggerExpression { get; set; } /// /// 强制等待时间(秒)- 防止连续触发 /// - [Range(1, 3600, ErrorMessage = "强制等待时间必须在1-3600秒之间")] public int? MandatoryWaitSeconds { get; set; } = 30; /// diff --git a/src/YunDa.Application/YunDa.SOMS.DataTransferObject/MaintenanceAndOperations/SecondaryEquipment/DzInfo.cs b/src/YunDa.Application/YunDa.SOMS.DataTransferObject/MaintenanceAndOperations/SecondaryEquipment/DzInfo.cs index bc53294..a932d70 100644 --- a/src/YunDa.Application/YunDa.SOMS.DataTransferObject/MaintenanceAndOperations/SecondaryEquipment/DzInfo.cs +++ b/src/YunDa.Application/YunDa.SOMS.DataTransferObject/MaintenanceAndOperations/SecondaryEquipment/DzInfo.cs @@ -38,6 +38,9 @@ namespace YunDa.SOMS.DataTransferObject.MaintenanceAndOperations.SecondaryEquipm [BsonDateTimeOptions(Kind = DateTimeKind.Local)] [MongoDBDescendingIndex] public DateTime Time { get; set; } + public string DiagnoseResultName{ get; set; } + public string DiaStatus { get; set; } + } diff --git a/src/YunDa.Application/YunDa.SOMS.MongoDB.Application/YunDa.SOMS.MongoDB.Application.xml b/src/YunDa.Application/YunDa.SOMS.MongoDB.Application/YunDa.SOMS.MongoDB.Application.xml index d7807cb..0a98e6a 100644 --- a/src/YunDa.Application/YunDa.SOMS.MongoDB.Application/YunDa.SOMS.MongoDB.Application.xml +++ b/src/YunDa.Application/YunDa.SOMS.MongoDB.Application/YunDa.SOMS.MongoDB.Application.xml @@ -1236,6 +1236,12 @@ + + + 测试报警api + + + 获取报警信息 @@ -1538,6 +1544,26 @@ + + + 查询温度测量结果(热成像设备) + + 查询条件 + + + + + 从巡检结果数据中解析温度数据 + + 原始巡检结果数据 + 预置点信息 + 温度测量结果列表 + + + + 计算字符串相似度 + + 添加多条机器人巡检任务报警结果 diff --git a/src/YunDa.Domain/YunDa.SOMS.Entities/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfig.cs b/src/YunDa.Domain/YunDa.SOMS.Entities/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfig.cs index eff11a0..e518b8e 100644 --- a/src/YunDa.Domain/YunDa.SOMS.Entities/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfig.cs +++ b/src/YunDa.Domain/YunDa.SOMS.Entities/DataMonitoring/SecondaryCircuitInspection/SecondaryCircuitEventDrivenConfig.cs @@ -27,7 +27,6 @@ namespace YunDa.SOMS.Entities.DataMonitoring.SecondaryCircuitInspection /// 格式示例: {16385_0}==1&&{752}>1000 /// [Required] - [StringLength(500)] public virtual string TriggerExpression { get; set; } diff --git a/src/YunDa.Domain/YunDa.SOMS.EntityFrameworkCore/EntityFrameworkCore/DbContextOptionsConfigurer.cs b/src/YunDa.Domain/YunDa.SOMS.EntityFrameworkCore/EntityFrameworkCore/DbContextOptionsConfigurer.cs index 6cccb3e..9317a84 100644 --- a/src/YunDa.Domain/YunDa.SOMS.EntityFrameworkCore/EntityFrameworkCore/DbContextOptionsConfigurer.cs +++ b/src/YunDa.Domain/YunDa.SOMS.EntityFrameworkCore/EntityFrameworkCore/DbContextOptionsConfigurer.cs @@ -1,46 +1,85 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; using Pomelo.EntityFrameworkCore.MySql; using Pomelo.EntityFrameworkCore.MySql.Infrastructure; using System; namespace YunDa.SOMS.EntityFrameworkCore.EntityFrameworkCore { - public static class DbContextOptionsConfigurer + public static class DbContextOptionsConfigurer +{ + public static void Configure( + DbContextOptionsBuilder dbContextOptions, + string connectionString, + ILoggerFactory loggerFactory = null, + bool isDevelopment = false) { - public static void Configure( - DbContextOptionsBuilder dbContextOptions, - string connectionString, - ILoggerFactory loggerFactory = null) - { - dbContextOptions.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString), - builder => - { - builder.CommandTimeout(600); - //builder.EnableRetryOnFailure( - // maxRetryCount: 3, - // maxRetryDelay: TimeSpan.FromSeconds(5), - // errorNumbersToAdd: null - //); - } - ) - .EnableSensitiveDataLogging() // 显示敏感数据(如参数值) - .EnableDetailedErrors() // 显示详细错误信息 - .LogTo( - Console.WriteLine, // 可以改为你的日志方法 - new[] { - DbLoggerCategory.Database.Command.Name, - DbLoggerCategory.Database.Connection.Name, - DbLoggerCategory.Database.Transaction.Name, - DbLoggerCategory.Query.Name - }, - LogLevel.Information // 或 LogLevel.Debug 获取更详细信息 - ); - - // 如果传入了 loggerFactory,使用它 - if (loggerFactory != null) + // 缓存 ServerVersion 以避免重复检测 + var serverVersion = ServerVersion.AutoDetect(connectionString); + + dbContextOptions.UseMySql(connectionString, serverVersion, + builder => { - dbContextOptions.UseLoggerFactory(loggerFactory); + builder.CommandTimeout(600); + + // 启用连接重试机制(生产环境推荐) + //builder.EnableRetryOnFailure( + // maxRetryCount: 3, + // maxRetryDelay: TimeSpan.FromSeconds(5), + // errorNumbersToAdd: null + //); + + // 性能优化选项 + builder.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery); // 避免笛卡尔爆炸 + builder.MigrationsAssembly(typeof(SOMSDbContext).Assembly.GetName().Name); } + ); + + // 仅在开发环境启用详细日志 + if (isDevelopment) + { + dbContextOptions + .EnableSensitiveDataLogging() + .EnableDetailedErrors() + .LogTo( + Console.WriteLine, + new[] { + DbLoggerCategory.Database.Command.Name, + DbLoggerCategory.Database.Connection.Name, + DbLoggerCategory.Database.Transaction.Name, + DbLoggerCategory.Query.Name + }, + LogLevel.Information + ); } + else + { + // 生产环境:只记录警告和错误 + dbContextOptions.LogTo( + Console.WriteLine, + new[] { + DbLoggerCategory.Database.Command.Name, + DbLoggerCategory.Database.Connection.Name + }, + LogLevel.Warning + ); + } + + // 使用外部 LoggerFactory(如果提供) + if (loggerFactory != null) + { + dbContextOptions.UseLoggerFactory(loggerFactory); + } + + // 性能优化配置 + dbContextOptions + .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking) // 默认无跟踪查询 + .ConfigureWarnings(warnings => + { + // 忽略常见的非关键警告 + warnings.Ignore(CoreEventId.FirstWithoutOrderByAndFilterWarning); + warnings.Ignore(CoreEventId.RowLimitingOperationWithoutOrderByWarning); + }); } +} } \ No newline at end of file diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/Models/DZMessage.cs b/src/YunDa.Server/YunDa.Server.ISMSTcp/Models/DZMessage.cs index 7682df2..0ad6fb0 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/Models/DZMessage.cs +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/Models/DZMessage.cs @@ -22,7 +22,7 @@ namespace YunDa.Server.ISMSTcp.Models /// /// 定值 /// - public decimal Value { get; set; } + public string Value { get; set; } /// /// 单位 diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/DataProcessor.cs b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/DataProcessor.cs index dadf75f..1ae050c 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/DataProcessor.cs +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/DataProcessor.cs @@ -258,23 +258,6 @@ namespace YunDa.Server.ISMSTcp.Services if (contentToken is JArray contentArray && contentArray.Count > 0) { - //2025-10-25 所有值加1 send CallYXByDevice|B001208 - //foreach (var item in contentArray) - //{ - // if (item["YX_ID"].Value() == "YXB001103058") - // { - // int kk = 0; - // } - // if (item["V"] != null && item["V"].Type == JTokenType.String) - // { - // string val = item["V"].Value(); - // if(int.TryParse(val, out int value)) - // { - // //item["V"] = (value + 1).ToString(); - // } - - // } - //} List telesignalisationModels = new List(); @@ -1136,9 +1119,9 @@ namespace YunDa.Server.ISMSTcp.Services // 检查Value是否为非数字值(如"退出"等中文字符) if (!string.IsNullOrEmpty(valueString) && !decimal.TryParse(valueString, out _)) { - _logger.LogWarning("DZ数据Value字段包含非数字值: {Value},将设置为0", valueString); + _logger.LogWarning("DZ数据Value字段包含非数字值: {Value}", valueString); // 将非数字值替换为0 - jObject["Value"] = 0; + jObject["Value"] = valueString; } } return item; diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/SecondaryCircuitInspectionPlanService.cs b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/SecondaryCircuitInspectionPlanService.cs index 43f8f11..7e59b65 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/SecondaryCircuitInspectionPlanService.cs +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/SecondaryCircuitInspectionPlanService.cs @@ -233,7 +233,7 @@ namespace YunDa.Server.ISMSTcp.Services _ = Task.Run(async () => { while (true) - {//每30秒更新一下配置 + {//每10分钟更新一下配置 await UpdatePlans(); @@ -241,7 +241,7 @@ namespace YunDa.Server.ISMSTcp.Services //await CheckAiChannel(); - await Task.Delay(30000); + await Task.Delay(TimeSpan.FromMinutes(10)); } }); @@ -256,11 +256,11 @@ namespace YunDa.Server.ISMSTcp.Services { await CheckPlan(); - await Task.Delay(10000); + await Task.Delay(TimeSpan.FromSeconds(60)); } else { - await Task.Delay(10000); + await Task.Delay(TimeSpan.FromSeconds(60)); } } @@ -278,14 +278,14 @@ namespace YunDa.Server.ISMSTcp.Services } else { - await Task.Delay(10000); + await Task.Delay(TimeSpan.FromSeconds(60)); } } }); //执行计划(两个线程同时执行) - int threadNumber = _isDebug ? 1 : 3; + int threadNumber = _isDebug ? 1 : 1; for (int i = 0; i < threadNumber; ++i) { @@ -319,7 +319,7 @@ namespace YunDa.Server.ISMSTcp.Services await CallAiAndSave(item); - await Task.Delay(500); + await Task.Delay(5000); } }); } @@ -569,90 +569,67 @@ namespace YunDa.Server.ISMSTcp.Services var sw = Stopwatch.StartNew(); - for (int i = 0; i < item.TimeWindowCount; i++) + for (int i = 0; i < item.TimeWindowCount; i++) { - - var tasks = new List(); - - Task>? t1 = null; - Task>? t2 = null; - Task>? t3 = null; - Task>? t4 = null; - Task>? t5 = null; - Task>? t6 = null; + List? telemetryData = null; + List? teleSignalData = null; + List? settingData = null; + List? presetData = null; + List? gatewayData = null; + List? variantData = null; if (item.TelemetryConfigCount > 0) { - t1 = GetSourceDataAsync>(id, 1); - tasks.Add(t1); + telemetryData = await GetSourceDataAsync>(id, 1); } - if (item.TelesignalConfigCount > 0) { - t2 = GetSourceDataAsync>(id, 2); - tasks.Add(t2); + teleSignalData = await GetSourceDataAsync>(id, 2); } - if (item.DeviceConfigCount > 0) { - t3 = GetSourceDataAsync>(id, 3); - tasks.Add(t3); + settingData = await GetSourceDataAsync>(id, 3); } - if (item.CameraPresetCount > 0) { - t4 = GetSourceDataAsync>(id, 4); - tasks.Add(t4); + presetData = await GetSourceDataAsync>(id, 4); } - if (item.GatewayConfigCount > 0) { - t5 = GetSourceDataAsync>(id, 5); - tasks.Add(t5); + gatewayData = await GetSourceDataAsync>(id, 5); } - if (item.VariantConfigCount > 0) { - t6 = GetSourceDataAsync>(id, 6); - tasks.Add(t6); + variantData = await GetSourceDataAsync>(id, 6); } - await Task.WhenAll(tasks); + jsData.StoreData.TelemetryData = telemetryData; + jsData.StoreData.TeleSignalData = teleSignalData; + jsData.StoreData.SettingData = settingData; + jsData.StoreData.PresetData = presetData; + jsData.StoreData.GatewayData = gatewayData; + jsData.StoreData.VariantData = variantData; - if (t1 != null) jsData.StoreData.TelemetryData = await t1; - if (t2 != null) jsData.StoreData.TeleSignalData = await t2; - if (t3 != null) jsData.StoreData.SettingData = await t3; - if (t4 != null) jsData.StoreData.PresetData = await t4; - if (t5 != null) jsData.StoreData.GatewayData = await t5; - if (t6 != null) jsData.StoreData.VariantData = await t6; - - if(jsData.StoreData.TelemetryData == null && jsData.StoreData.TeleSignalData == null && jsData.StoreData.SettingData == null && + if (jsData.StoreData.TelemetryData == null && jsData.StoreData.TeleSignalData == null && jsData.StoreData.SettingData == null && jsData.StoreData.PresetData == null && jsData.StoreData.GatewayData == null && jsData.StoreData.VariantData == null) { continue; } - var json = JsonConvert.SerializeObject(jsData, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); - var js = $"JSON.parse('{json.Replace("'", "\\'")}')"; - - var jsObj = engine.Evaluate(js).ToObject(); - var jsResult = engine.Invoke("calculate", jsObj).AsObject(); - if (jsResult != null && jsResult.HasProperty("status")) { saveObj = jsResult; - var status = jsResult.Get("status").ToString(); if (status == "正常" || string.IsNullOrWhiteSpace(status)) - {//只要正常,就不用再检测了 + { break; } } diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallJob.cs b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallJob.cs index 2f69ca0..3873885 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallJob.cs +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallJob.cs @@ -59,11 +59,11 @@ namespace YunDa.Server.ISMSTcp.Services if (protectionDeviceCommInfos == null || !protectionDeviceCommInfos.Any()) { _logger.LogWarning("Redis中未获取到保护装置通信信息,跳过本次召唤"); - return; + //return; } // 只处理在线的设备 - var onlineDevices = protectionDeviceCommInfos.Where(d => d.IsOnline).ToList(); + var onlineDevices = protectionDeviceCommInfos.ToList(); _logger.LogInformation("从Redis获取到 {TotalCount} 个保护装置,其中在线设备 {OnlineCount} 个", protectionDeviceCommInfos.Count, onlineDevices.Count); @@ -100,10 +100,13 @@ namespace YunDa.Server.ISMSTcp.Services // 再次检查TCP连接状态(防止在循环过程中连接断开) if (!_tcpClient.IsConnected) { - _logger.LogWarning("TCP连接已断开,停止发送召唤命令"); - failureCount++; - failedDevices.Add($"{device.DeviceId}({device.DeviceName})"); - continue; + _logger.LogWarning("TCP连接已断开,等待5S发送召唤命令"); + Task.Delay(5000).Wait(); + if (!_tcpClient.IsConnected) + { + _logger.LogWarning("TCP连接已断开,停止发送召唤命令"); + continue; + } } // 构造召唤命令:CallYCByDevice|{装置ID} @@ -132,7 +135,7 @@ namespace YunDa.Server.ISMSTcp.Services _yxCount = (_yxCount + 1) % 6; // 每个命令之间间隔100毫秒 - await Task.Delay(100); + await Task.Delay(1000); } catch (Exception ex) { diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallService.cs b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallService.cs index 56ef9e1..850f482 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallService.cs +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/Services/TelemetryCallService.cs @@ -103,14 +103,14 @@ namespace YunDa.Server.ISMSTcp.Services } // 检查设备通信状态 - bool isCommNormal = await _deviceCommunicationStateService.IsDeviceCommunicationNormalAsync(device.Id, cancellationToken); - if (!isCommNormal) - { - _logger.LogWarning("装置通信状态异常,取消数据召唤操作 - 设备ID: {DeviceId} ({DeviceName})", device.Id, device.DeviceName); - commStateSkippedCount++; - commStateSkippedDevices.Add($"{device.Id}({device.DeviceName})"); - continue; - } + //bool isCommNormal = await _deviceCommunicationStateService.IsDeviceCommunicationNormalAsync(device.Id, cancellationToken); + //if (!isCommNormal) + //{ + // _logger.LogWarning("装置通信状态异常,取消数据召唤操作 - 设备ID: {DeviceId} ({DeviceName})", device.Id, device.DeviceName); + // commStateSkippedCount++; + // commStateSkippedDevices.Add($"{device.Id}({device.DeviceName})"); + // continue; + //} // 再次检查TCP连接状态(防止在循环过程中连接断开) if (!_tcpClient.IsConnected) diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.Development.json b/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.Development.json index a657a3f..4bd1758 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.Development.json +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.Development.json @@ -10,8 +10,8 @@ }, "ISMSServer": { "ServerIP": "192.168.81.21", - "HeartbeatIntervalSeconds": 60, - "AutoConnectDelaySeconds": 10 + "HeartbeatIntervalSeconds": 1800, + "AutoConnectDelaySeconds": 60 }, "ScheduledTelemetry": { "IntervalMinutes": 30 diff --git a/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.json b/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.json index 4410f15..9e4c503 100644 --- a/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.json +++ b/src/YunDa.Server/YunDa.Server.ISMSTcp/appsettings.json @@ -14,12 +14,12 @@ "IncompleteDataTimeoutSeconds": 5, "BufferSize": 1024, "EnableHeartbeat": true, - "HeartbeatIntervalSeconds": 30, + "HeartbeatIntervalSeconds": 1800, "HeartbeatTimeoutSeconds": 10, "HeartbeatMessage": "HEARTBEAT_PING", "EnableAutoConnect": true, "AutoConnectDelaySeconds": 3, - "ConnectionTimeoutSeconds": 30, + "ConnectionTimeoutSeconds": 180, "EnableConnectionRetry": true }, "ApiEndpoints": { @@ -34,7 +34,7 @@ }, "ScheduledTelemetry": { "Enabled": true, - "IntervalSeconds": 60, + "IntervalSeconds": 1800, "MaxRetries": 10, "RetryDelayMs": 2000, "CommandDelayMs": 100