using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using Abp.Application.Services.Dto; using Abp.Auditing; using Abp.AutoMapper; using Abp.Domain.Repositories; using Abp.Linq.Extensions; using Abp.UI; using DynamicExpresso; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using ToolLibrary.LogHelper; using YunDa.SOMS.Application.Core; using YunDa.SOMS.Application.Core.Session; using YunDa.SOMS.Application.Core.SwaggerHelper; using YunDa.SOMS.DataTransferObject; using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection.Configurations; using YunDa.SOMS.DataTransferObject.DataMonitoring.SecondaryCircuitInspection; using YunDa.SOMS.DataTransferObject.DataMonitoring.TelemeteringConfigurationDto; using YunDa.SOMS.DataTransferObject.DataMonitoring.TelesignalisationConfigurationDto; using YunDa.SOMS.Entities.DataMonitoring; using YunDa.SOMS.DataTransferObject.GeneralInformation.FiberConnectionDto; using YunDa.SOMS.DataTransferObject.System.UserDto; using Abp.EntityFrameworkCore.Repositories; using YunDa.SOMS.DataTransferObject.Account; using Microsoft.AspNetCore.Authorization; using YunDa.SOMS.Redis.Repositories; using YunDa.SOMS.DataTransferObject.GeneralInformation.EquipmentLiveDataDto; using Abp.Domain.Uow; namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection { /// /// 二次回路事件驱动配置应用服务实现 /// [Description("二次回路事件驱动配置管理服务")] public class SecondaryCircuitEventDrivenConfigAppService : SOMSAppServiceBase, ISecondaryCircuitEventDrivenConfigAppService { private readonly IRepository _eventDrivenConfigRepository; private readonly IRepository _inspectionItemRepository; private readonly IRepository _inspectionEventItemRepository; private readonly IRepository _telemetryConfigRepository; private readonly IRepository _telesignalConfigRepository; private readonly IRedisRepository _telemeteringRedisRepository; private readonly IRedisRepository _telesignalisationRedisRepository; private LoginUserOutput _currentUser = null; private IUnitOfWorkManager _unitOfWorkManager = null; public SecondaryCircuitEventDrivenConfigAppService( IRepository eventDrivenConfigRepository, IRepository inspectionItemRepository, IRepository inspectionEventItemRepository, IRepository telemetryConfigRepository, IRepository telesignalConfigRepository, IRedisRepository telemeteringRedisRepository, IRedisRepository telesignalisationRedisRepository, IUnitOfWorkManager unitOfWorkManager, ISessionAppService sessionAppService) : base(sessionAppService) { _unitOfWorkManager = unitOfWorkManager; _eventDrivenConfigRepository = eventDrivenConfigRepository; _inspectionItemRepository = inspectionItemRepository; _inspectionEventItemRepository = inspectionEventItemRepository; _telemetryConfigRepository = telemetryConfigRepository; _telesignalConfigRepository = telesignalConfigRepository; _telemeteringRedisRepository = telemeteringRedisRepository; _telesignalisationRedisRepository = telesignalisationRedisRepository; } #region 增/改 /// /// 创建或更新事件驱动配置 /// [HttpPost, Audited, Description("创建或更新事件驱动配置")] [ShowApi] [AllowAnonymous] public async Task> CreateOrUpdateAsync( EditSecondaryCircuitEventDrivenConfigInput input, CancellationToken cancellationToken = default) { if (input == null) return null; if (_currentUser == null) _currentUser = base.GetCurrentUser(); return input.Id.HasValue ? await this.UpdateAsync(input, cancellationToken).ConfigureAwait(false) : await this.CreateAsync(input, cancellationToken).ConfigureAwait(false); } /// /// 创建事件驱动配置 /// private async Task> CreateAsync( EditSecondaryCircuitEventDrivenConfigInput input, CancellationToken cancellationToken = default) { var rst = new RequestResult(); try { // 验证配置有效性 var validationResult = await ValidateConfigurationInternalAsync(input, cancellationToken); if (!validationResult.IsValid) { rst.Message = string.Join("; ", validationResult.Errors); return rst; } // 验证配置名称是否重复(排除当前记录) var nameExists = await _eventDrivenConfigRepository.GetAll() .AnyAsync(x => x.Name == input.Name && x.Id != input.Id, cancellationToken); if (nameExists) { rst.Message = "已存在相同名称的事件驱动配置"; return rst; } input.CreationTime = DateTime.Now; input.CreatorUserId = _currentUser.Id; var entity = ObjectMapper.Map(input); using var uow = _unitOfWorkManager.Begin(); entity = await _eventDrivenConfigRepository.InsertAsync(entity).ConfigureAwait(false); uow.Complete(); // 创建巡检项关联 if (input.SecondaryCircuitInspectionEventItems != null && input.SecondaryCircuitInspectionEventItems.Count > 0) { var secondaryCircuitInspectionEventItems = _inspectionItemRepository.GetAll() .Where(t => input.SecondaryCircuitInspectionEventItems.Contains(t.Id)) .Select(t => t.Id); foreach (var item in secondaryCircuitInspectionEventItems) { var secondaryCircuitInspectionEventItem = new SecondaryCircuitInspectionEventItem(entity.Id, item); _inspectionEventItemRepository.Insert(secondaryCircuitInspectionEventItem); } } // 创建遥测配置关联 if (input.TelemetryConfigs != null && input.TelemetryConfigs.Count > 0) { foreach (var telemetryConfigId in input.TelemetryConfigs) { var telemetryConfig = new SecondaryCircuitInspectionTelemetryConfig { SecondaryCircuitEventDrivenConfigId = entity.Id, TelemetryConfigurationId = telemetryConfigId, IsActive = true }; await _telemetryConfigRepository.InsertAsync(telemetryConfig).ConfigureAwait(false); } } // 创建遥信配置关联 if (input.TelesignalConfigs != null && input.TelesignalConfigs.Count > 0) { foreach (var telesignalConfigId in input.TelesignalConfigs) { var telesignalConfig = new SecondaryCircuitInspectionTelesignalConfig { SecondaryCircuitEventDrivenConfigId = entity.Id, TelesignalConfigurationId = telesignalConfigId, IsActive = true }; await _telesignalConfigRepository.InsertAsync(telesignalConfig).ConfigureAwait(false); } } rst.ResultData = ObjectMapper.Map(entity); rst.Flag = true; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "创建事件驱动配置", ex); } return rst; } /// /// 更新事件驱动配置 /// private async Task> UpdateAsync( EditSecondaryCircuitEventDrivenConfigInput input, CancellationToken cancellationToken = default) { var rst = new RequestResult(); try { var entity = await _eventDrivenConfigRepository.FirstOrDefaultAsync(u => u.Id == input.Id).ConfigureAwait(false); if (entity == null) { rst.Message = "事件驱动配置不存在"; return rst; } // 验证配置有效性 var validationResult = await ValidateConfigurationInternalAsync(input, cancellationToken); if (!validationResult.IsValid) { rst.Message = string.Join("; ", validationResult.Errors); return rst; } input.CreationTime = entity.CreationTime; input.CreatorUserId = entity.CreatorUserId.Value; input.LastModificationTime = DateTime.Now; input.LastModifierUserId = _currentUser.Id; ObjectMapper.Map(input, entity); await _eventDrivenConfigRepository.UpdateAsync(entity); // 更新巡检项关联(删除后重新插入) if (input.SecondaryCircuitInspectionEventItems != null && input.SecondaryCircuitInspectionEventItems.Count > 0) { // 删除现有关联 await _inspectionEventItemRepository.BatchDeleteAsync(t => t.InpectionEventDrivenId == entity.Id); // 重新插入 var secondaryCircuitInspectionEventItems = _inspectionItemRepository.GetAll() .Where(t => input.SecondaryCircuitInspectionEventItems.Contains(t.Id)) .Select(t => t.Id); foreach (var item in secondaryCircuitInspectionEventItems) { var secondaryCircuitInspectionEventItem = new SecondaryCircuitInspectionEventItem(entity.Id, item); _inspectionEventItemRepository.Insert(secondaryCircuitInspectionEventItem); } } // 更新遥测配置关联(删除后重新插入) // 删除现有遥测配置关联 await _telemetryConfigRepository.BatchDeleteAsync(t => t.SecondaryCircuitEventDrivenConfigId == entity.Id); // 重新插入遥测配置关联 if (input.TelemetryConfigs != null && input.TelemetryConfigs.Count > 0) { foreach (var telemetryConfigId in input.TelemetryConfigs) { var telemetryConfig = new SecondaryCircuitInspectionTelemetryConfig { SecondaryCircuitEventDrivenConfigId = entity.Id, TelemetryConfigurationId = telemetryConfigId, IsActive = true }; await _telemetryConfigRepository.InsertAsync(telemetryConfig).ConfigureAwait(false); } } // 更新遥信配置关联(删除后重新插入) // 删除现有遥信配置关联 await _telesignalConfigRepository.BatchDeleteAsync(t => t.SecondaryCircuitEventDrivenConfigId == entity.Id); // 重新插入遥信配置关联 if (input.TelesignalConfigs != null && input.TelesignalConfigs.Count > 0) { foreach (var telesignalConfigId in input.TelesignalConfigs) { var telesignalConfig = new SecondaryCircuitInspectionTelesignalConfig { SecondaryCircuitEventDrivenConfigId = entity.Id, TelesignalConfigurationId = telesignalConfigId, IsActive = true }; await _telesignalConfigRepository.InsertAsync(telesignalConfig).ConfigureAwait(false); } } rst.ResultData = ObjectMapper.Map(entity); rst.Flag = true; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "更新事件驱动配置", ex); } return rst; } #endregion #region 查 /// /// 查询所有事件驱动配置(不分页) /// [HttpPost, Description("查询所有事件驱动配置(不分页)")] public RequestResult> FindDatasNoPageList( SecondaryCircuitEventDrivenConfigSearchInput searchCondition) { var rst = new RequestResult>(); try { var query = _eventDrivenConfigRepository.GetAll() .Include(x => x.TelemetryConfigs) .ThenInclude(t => t.TelemeteringConfiguration) .Include(x => x.TelesignalConfigs) .ThenInclude(t => t.TelesignalisationConfiguration) .Where(x => x.IsActive); // 应用搜索条件 if (searchCondition != null) { if (!string.IsNullOrWhiteSpace(searchCondition.Name)) { query = query.Where(x => x.Name.Contains(searchCondition.Name) || x.Remark.Contains(searchCondition.Name)); } if (searchCondition.Priority.HasValue) { query = query.Where(x => x.Priority == searchCondition.Priority.Value); } } var entities = query.OrderBy(x => x.SortOrder).ThenBy(x => x.Name).ToList(); // 映射到输出DTO var outputList = new List(); foreach (var entity in entities) { var output = ObjectMapper.Map(entity); // 映射遥测配置关联 if (entity.TelemetryConfigs != null && entity.TelemetryConfigs.Any()) { output.TelemetryConfigs = entity.TelemetryConfigs.Select(tc => new SecondaryCircuitInspectionTelemetryConfigOutput { Id = tc.Id, SecondaryCircuitInspectionItemId = tc.SecondaryCircuitInspectionItemId, TelemetryConfigurationId = tc.TelemetryConfigurationId ?? Guid.Empty, TelemetryConfigurationName = tc.TelemeteringConfiguration?.Name, EquipmentInfoId = tc.TelemeteringConfiguration?.EquipmentInfoId, EquipmentInfoName = tc.TelemeteringConfiguration?.EquipmentInfo?.Name, TelemetryConfiguration = ObjectMapper.Map(tc.TelemeteringConfiguration), IsActive = tc.IsActive }).ToList(); } else { output.TelemetryConfigs = new List(); } // 映射遥信配置关联 if (entity.TelesignalConfigs != null && entity.TelesignalConfigs.Any()) { output.TelesignalConfigs = entity.TelesignalConfigs.Select(tc => new SecondaryCircuitInspectionTelesignalConfigOutput { Id = tc.Id, SecondaryCircuitInspectionItemId = tc.SecondaryCircuitInspectionItemId, TelesignalConfigurationId = tc.TelesignalConfigurationId ?? Guid.Empty, TelesignalConfigurationName = tc.TelesignalisationConfiguration?.Name, EquipmentInfoId = tc.TelesignalisationConfiguration?.EquipmentInfoId, EquipmentInfoName = tc.TelesignalisationConfiguration?.EquipmentInfo?.Name, TelesignalConfiguration = ObjectMapper.Map(tc.TelesignalisationConfiguration), IsActive = tc.IsActive }).ToList(); } else { output.TelesignalConfigs = new List(); } outputList.Add(output); } rst.ResultData = outputList; rst.Flag = true; } catch (Exception ex) { rst.Message = ex.Message; Log4Helper.Error(this.GetType(), "查询所有事件驱动配置(不分页)", ex); } return rst; } #endregion #region 删 /// /// 删除事件驱动配置 /// [HttpPost, Description("删除事件驱动配置")] [ShowApi] [AllowAnonymous] public async Task DeleteAsync( Guid id, CancellationToken cancellationToken = default) { var rst = new RequestEasyResult(); try { var entity = await _eventDrivenConfigRepository.FirstOrDefaultAsync(u => u.Id == id).ConfigureAwait(false); if (entity == null) { rst.Message = "事件驱动配置不存在"; return rst; } //var items = _inspectionEventItemRepository.GetAll().Where(t => t.InpectionEventDrivenId == id).Select(t=>t.Id); //if (items!=null&& items.Any()) //{ // _inspectionEventItemRepository.BatchDeleteAsync(t=>); // foreach (var item in items) // { // } //} await _eventDrivenConfigRepository.DeleteAsync(entity).ConfigureAwait(false); rst.Flag = true; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "删除事件驱动配置", ex); } return rst; } /// /// 批量删除事件驱动配置 /// [HttpPost, Description("批量删除事件驱动配置")] [ShowApi] public async Task BatchDeleteAsync( List ids, CancellationToken cancellationToken = default) { var rst = new RequestEasyResult(); try { if (ids == null || !ids.Any()) { rst.Message = "请选择要删除的配置"; return rst; } var entities = await _eventDrivenConfigRepository.GetAll() .Where(x => ids.Contains(x.Id)) .ToListAsync(cancellationToken); foreach (var entity in entities) { await _eventDrivenConfigRepository.DeleteAsync(entity); } rst.Flag = true; rst.Message = $"成功删除 {entities.Count} 个事件驱动配置"; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "批量删除事件驱动配置", ex); } return rst; } #endregion #region 其他操作 /// /// 启用/禁用事件驱动配置 /// [HttpPost, Description("启用/禁用事件驱动配置")] [ShowApi] public async Task SetActiveStatusAsync( Guid id, bool isActive, CancellationToken cancellationToken = default) { var rst = new RequestEasyResult(); try { var entity = await _eventDrivenConfigRepository.FirstOrDefaultAsync(u => u.Id == id).ConfigureAwait(false); if (entity == null) { rst.Message = "事件驱动配置不存在"; return rst; } entity.IsActive = isActive; await _eventDrivenConfigRepository.UpdateAsync(entity); rst.Flag = true; rst.Message = isActive ? "启用成功" : "禁用成功"; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "启用/禁用事件驱动配置", ex); } return rst; } #endregion #region 事件驱动巡检项管理 /// /// 获取事件驱动配置的巡检项列表 /// [HttpPost, Description("获取事件驱动配置的巡检项列表")] [ShowApi] public async Task>> GetEventItemsAsync( Guid eventDrivenConfigId, CancellationToken cancellationToken = default) { var rst = new RequestResult>(); try { var items = await _inspectionEventItemRepository.GetAll() .Include(x => x.InspectionItem) .Where(x => x.InpectionEventDrivenId == eventDrivenConfigId) .ToListAsync(cancellationToken); rst.ResultData = ObjectMapper.Map>(items); rst.Flag = true; } catch (Exception ex) { rst.Message = ex.Message; Log4Helper.Error(this.GetType(), "获取事件驱动配置的巡检项列表", ex); } return rst; } /// /// 删除事件驱动配置的巡检项 /// [HttpPost, Description("删除事件驱动配置的巡检项")] [ShowApi] public async Task RemoveEventItemAsync( Guid eventItemId, CancellationToken cancellationToken = default) { var rst = new RequestEasyResult(); try { await _inspectionEventItemRepository.DeleteAsync(eventItemId); await CurrentUnitOfWork.SaveChangesAsync(); rst.Flag = true; rst.Message = "删除成功"; } catch (Exception ex) { rst.Message = ex.ToString(); Log4Helper.Error(this.GetType(), "删除事件驱动配置的巡检项", ex); } return rst; } #endregion #region 表达式评估 #endregion #region 私有方法 /// /// 验证配置有效性 /// private async Task<(bool IsValid, List Errors)> ValidateConfigurationInternalAsync( EditSecondaryCircuitEventDrivenConfigInput input, CancellationToken cancellationToken = default) { var errors = new List(); // 验证触发表达式 if (string.IsNullOrWhiteSpace(input.TriggerExpression)) { errors.Add("触发表达式不能为空"); } // 验证时间参数 if (input.MandatoryWaitSeconds < 1 || input.MandatoryWaitSeconds > 3600) { errors.Add("强制等待时间必须在1-3600秒之间"); } if (input.DelayTriggerSeconds < 0 || input.DelayTriggerSeconds > 3600) { errors.Add("延时触发时间必须在0-3600秒之间"); } if (input.TimeWindowSeconds < 1 || input.TimeWindowSeconds > 3600) { errors.Add("时间窗口必须在1-3600秒之间"); } return (errors.Count == 0, errors); } public RequestPageResult FindDatas(PageSearchCondition searchCondition) { throw new NotImplementedException(); } #endregion #region 辅助类 /// /// 表达式评估结果 /// public class ExpressionEvaluationResult { /// /// 是否成功 /// public bool IsSuccess { get; set; } /// /// 原始表达式 /// public string OriginalExpression { get; set; } /// /// 可评估表达式(地址已替换为值) /// public string EvaluableExpression { get; set; } /// /// 评估结果 /// public bool Result { get; set; } /// /// 提取的地址列表 /// public List ExtractedAddresses { get; set; } /// /// 地址对应的值 /// public Dictionary AddressValues { get; set; } /// /// 错误信息 /// public string ErrorMessage { get; set; } /// /// 评估时间 /// public DateTime EvaluationTime { get; set; } } /// /// 事件驱动巡检项输出DTO /// public class SecondaryCircuitInspectionEventItemOutput { public Guid Id { get; set; } public Guid? InpectionEventDrivenId { get; set; } public Guid? InspectionItemId { get; set; } public string InspectionItemName { get; set; } public int ExecutionOrder { get; set; } public bool IsActive { get; set; } public decimal WeightCoefficient { get; set; } public DateTime? LastExecutionTime { get; set; } public SecondaryCircuitInspectionResultStatus LastExecutionResult { get; set; } public string LastExecutionErrorMessage { get; set; } public int TotalExecutionCount { get; set; } public int SuccessExecutionCount { get; set; } public int AbnormalExecutionCount { get; set; } public int ErrorExecutionCount { get; set; } public long AverageExecutionDurationMs { get; set; } } #endregion } }