From ea8352f4de946e496b6441844b0574f47443de6c Mon Sep 17 00:00:00 2001 From: "Egor A. Tiunov" Date: Tue, 20 Feb 2024 16:58:40 +0500 Subject: [PATCH 1/2] =?UTF-8?q?#28835068=20=D0=A1=D0=B2=D0=BE=D0=B4=D0=BD?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=BD=D0=B0=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B5=20=D0=BF=D0=BE=20-=D0=B1=D1=83=D1=80=D0=B8=D0=BB=D1=8C?= =?UTF-8?q?=D1=89=D0=B8=D0=BA=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/CompanyDto.cs | 5 +- .../Data/DrillerDetectedOperationStatDto.cs | 12 + AsbCloudApp/Requests/GetStatRequest.cs | 9 + AsbCloudApp/Services/IScheduleService.cs | 9 + AsbCloudApp/Services/ISubsystemService.cs | 6 +- .../Repository/ScheduleRepository.cs | 16 + .../Services/Subsystems/SubsystemService.cs | 440 ++++++++++-------- .../Subsystems/SubsystemController.cs | 18 +- 8 files changed, 320 insertions(+), 195 deletions(-) create mode 100644 AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs create mode 100644 AsbCloudApp/Requests/GetStatRequest.cs diff --git a/AsbCloudApp/Data/CompanyDto.cs b/AsbCloudApp/Data/CompanyDto.cs index 3c670412..f394e40e 100644 --- a/AsbCloudApp/Data/CompanyDto.cs +++ b/AsbCloudApp/Data/CompanyDto.cs @@ -1,7 +1,4 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using AsbCloudApp.Data.User; +using System.ComponentModel.DataAnnotations; namespace AsbCloudApp.Data { diff --git a/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs b/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs new file mode 100644 index 00000000..d350c838 --- /dev/null +++ b/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using AsbCloudApp.Data.Subsystems; + +namespace AsbCloudApp.Data; + +public record DrillerDetectedOperationStatDto +{ + public DrillerDto driller; + public IEnumerable statistic; + public ScheduleDto schedule; + public IEnumerable well; +} \ No newline at end of file diff --git a/AsbCloudApp/Requests/GetStatRequest.cs b/AsbCloudApp/Requests/GetStatRequest.cs new file mode 100644 index 00000000..607c0fc6 --- /dev/null +++ b/AsbCloudApp/Requests/GetStatRequest.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace AsbCloudApp.Requests; + +public class GetStatRequest: RequestBase +{ + public IEnumerable idWell; + public int? idDriller; +} \ No newline at end of file diff --git a/AsbCloudApp/Services/IScheduleService.cs b/AsbCloudApp/Services/IScheduleService.cs index c4c0c1f5..5a28b4c2 100644 --- a/AsbCloudApp/Services/IScheduleService.cs +++ b/AsbCloudApp/Services/IScheduleService.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Requests; namespace AsbCloudApp.Services { @@ -28,5 +29,13 @@ namespace AsbCloudApp.Services /// /// Task GetOrDefaultDrillerAsync(int idWell, DateTime workTime, CancellationToken token); + + /// + /// Получить расписание смен + /// + /// + /// + /// + Task> GetPageAsync(GetStatRequest request, CancellationToken token); } } diff --git a/AsbCloudApp/Services/ISubsystemService.cs b/AsbCloudApp/Services/ISubsystemService.cs index 737cca4f..7ccc0aa1 100644 --- a/AsbCloudApp/Services/ISubsystemService.cs +++ b/AsbCloudApp/Services/ISubsystemService.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; namespace AsbCloudApp.Services; @@ -26,5 +27,8 @@ public interface ISubsystemService /// /// /// - Task> GetStatByActiveWells(IEnumerable wellIds, CancellationToken token); + Task> GetStatByActiveWells(IEnumerable wellIds, CancellationToken token); + + Task> GetByWellsAsync(GetStatRequest request, + CancellationToken token); } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs index 92676cd4..971cd735 100644 --- a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs +++ b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Requests; using Mapster; namespace AsbCloudInfrastructure.Repository @@ -53,6 +54,21 @@ namespace AsbCloudInfrastructure.Repository return entity?.Driller.Adapt(); } + public async Task> GetPageAsync(GetStatRequest request, CancellationToken token) + { + var idWell = request.idWell; + var idDriller = request.idDriller; + var query = GetQuery().Where(s => request.idWell.Contains(s.IdWell)); + if (idDriller is not null) + { + query.Where(s => s.IdDriller == idDriller); + } + + var result = await query.ToArrayAsync(token); + return result.Select(Convert); + + } + private IQueryable BuildQuery(int idWell, DateTime workTime) { var hoursOffset = wellService.GetTimezone(idWell).Hours; diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs index 93c5ab2f..36f373b0 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs @@ -1,245 +1,309 @@ -using AsbCloudApp.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; using AsbCloudApp.Data.DetectedOperation; using AsbCloudApp.Data.Subsystems; using AsbCloudApp.Exceptions; using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using AsbCloudInfrastructure.Services.DetectOperations; namespace AsbCloudInfrastructure.Services.Subsystems; internal class SubsystemService : ISubsystemService { - private const int IdSubsystemAPD = 1; - private const int IdSubsystemAPDRotor = 11; - private const int IdSubsystemAPDSlide = 12; - private const int IdSubsystemOscillation = 65536; + private const int IdSubsystemAPD = 1; + private const int IdSubsystemAPDRotor = 11; + private const int IdSubsystemAPDSlide = 12; + private const int IdSubsystemOscillation = 65536; - private readonly ICrudRepository subsystemRepository; + private readonly ICrudRepository subsystemRepository; - private readonly IWellService wellService; - private readonly IDetectedOperationService detectedOperationService; + private readonly IWellService wellService; + private readonly IDetectedOperationService detectedOperationService; + private readonly IScheduleRepository scheduleRepository; - private IDictionary subsystems = new Dictionary(); + private IDictionary subsystems = new Dictionary(); - public SubsystemService(ICrudRepository subsystemRepository, - IWellService wellService, - IDetectedOperationService detectedOperationService) - { - this.wellService = wellService; - this.subsystemRepository = subsystemRepository; - this.detectedOperationService = detectedOperationService; - } + public SubsystemService(ICrudRepository subsystemRepository, + IWellService wellService, + IDetectedOperationService detectedOperationService, + IScheduleRepository scheduleRepository) + { + this.wellService = wellService; + this.subsystemRepository = subsystemRepository; + this.detectedOperationService = detectedOperationService; + this.scheduleRepository = scheduleRepository; + } - public async Task> GetStatAsync(SubsystemRequest request, CancellationToken token) - { - var well = await wellService.GetOrDefaultAsync(request.IdWell, token) - ?? throw new ArgumentInvalidException(nameof(request.IdWell), $"Well Id: {request.IdWell} does not exist"); - - if(!well.IdTelemetry.HasValue) - return Enumerable.Empty(); - - var detectedOperationSummaryRequest = new DetectedOperationByWellRequest + // получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод + // [ + // get telemetryId by idWell // IWellService.GetOrDefaultStatAsync + // получить detectedOperation by telemetry //detectedOperationService.GetOperationsAsync + // сгруппировать по бурильщикам + // [ + // рассчитать статистику // CalcStatAsync + // join driller from group + // ] + // join well (cluster, deposit) + // ] + public async Task> GetByWellsAsync(GetStatRequest request, + CancellationToken token) + { + var result = new List(); + var schedulePage = await scheduleRepository.GetPageAsync(request, token); + var wellTree = await wellService.GetAsync(new WellRequest { Ids = request.idWell }, token); + var wellGroup = wellTree.GroupBy(w => w.Id); + + foreach (var schedule in schedulePage) { - IdWell = request.IdWell, - IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, + var idWell = schedule.IdWell; + var well = wellGroup?.FirstOrDefault(w=> w.Key == idWell); - GeDateStart = request.GeDate, - LeDateEnd = request.LeDate, + var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest()); - GeDepthStart = request.GeDepth, - LeDepthEnd = request.LeDepth, - }; + var detectedOperations = await detectedOperationService + .GetOperationsAsync(byWellRequest, token); - var operations = await detectedOperationService.GetOperationsAsync(detectedOperationSummaryRequest, - token); + var groupByDriller = detectedOperations + .Where(operation => operation.Driller is not null) + .GroupBy(operation => operation.Driller); - if (request.IdDriller.HasValue) - operations = operations.Where(o => o.Driller is not null && o.Driller.Id == request.IdDriller.Value); + foreach (var entry in groupByDriller) + { + var drillerOperationsStat = await CalcStatAsync(entry, token); + var dto = new DrillerDetectedOperationStatDto + { + driller = entry.Key!, + statistic = drillerOperationsStat, + schedule = schedule, + well = well! + }; + result.Add(dto); + } + } - if (!operations.Any()) - return Enumerable.Empty(); + return await Task.FromResult(result); + } - var stat = await CalcStatAsync(operations, token); - return stat; - } + public async Task> GetStatAsync(SubsystemRequest request, CancellationToken token) + { + var well = await wellService.GetOrDefaultAsync(request.IdWell, token) + ?? throw new ArgumentInvalidException(nameof(request.IdWell), + $"Well Id: {request.IdWell} does not exist"); - public async Task> GetStatByActiveWells(IEnumerable wellIds, CancellationToken token) - { - var activeWells = await wellService.GetAsync(new() { Ids = wellIds, IdState = 1 }, token); - var result = await GetStatAsync(activeWells, null, null, token); - return result; - } - - private async Task> CalcStatAsync(IEnumerable operations, CancellationToken token) - { - if (!subsystems.Any()) - subsystems = (await subsystemRepository.GetAllAsync(token)).ToDictionary(s => s.Id, s => s); + if (!well.IdTelemetry.HasValue) + return Enumerable.Empty(); - var oscillationStat = CalcOscillationStat(operations); - var apdStat = CalcApdStat(operations); + var detectedOperationSummaryRequest = new DetectedOperationByWellRequest + { + IdWell = request.IdWell, + IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, - var stat = new List { oscillationStat }; - stat.AddRange(apdStat); + GeDateStart = request.GeDate, + LeDateEnd = request.LeDate, - return stat; - } + GeDepthStart = request.GeDepth, + LeDepthEnd = request.LeDepth, + }; - private SubsystemStatDto CalcOscillationStat(IEnumerable operations) - { - operations = operations.Where(o => o.IdCategory == WellOperationCategory.IdSlide); + var operations = await detectedOperationService.GetOperationsAsync(detectedOperationSummaryRequest, + token); - var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(IdSubsystemOscillation, operations); + if (request.IdDriller.HasValue) + operations = operations.Where(o => o.Driller is not null && o.Driller.Id == request.IdDriller.Value); - var oscillationStat = new SubsystemStatDto - { - IdSubsystem = IdSubsystemOscillation, - SubsystemName = subsystems.TryGetValue(IdSubsystemOscillation, out var subsystemDto) ? subsystemDto.Name : "unknown", - UsedTimeHours = usedTimeHours, - SumOperationDepthInterval = operations.Sum(o => o.DepthEnd - o.DepthStart), - SumOperationDurationHours = operations.Sum(o => o.DurationMinutes / 60), - SumDepthInterval = sumDepthInterval, - OperationCount = operationCount, - }; - - oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval; - - return oscillationStat; - } + if (!operations.Any()) + return Enumerable.Empty(); - private IEnumerable CalcApdStat(IEnumerable operations) - { - var apdRotorAndSlide = operations - .Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory)) - .GroupBy(o => o.IdCategory) - .Select(group => - { - var idSubsystem = group.Key switch - { - WellOperationCategory.IdRotor => IdSubsystemAPDRotor, - WellOperationCategory.IdSlide => IdSubsystemAPDSlide, - _ => throw new ArgumentException($"IdCategory: {group.Key} does not supported in this method", nameof(group.Key)) - }; + var stat = await CalcStatAsync(operations, token); + return stat; + } - var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(idSubsystem, group); + public async Task> GetStatByActiveWells(IEnumerable wellIds, + CancellationToken token) + { + var activeWells = await wellService.GetAsync(new() { Ids = wellIds, IdState = 1 }, token); + var result = await GetStatAsync(activeWells, null, null, token); + return result; + } - var subsystemStat = new SubsystemStatDto - { - IdSubsystem = idSubsystem, - SubsystemName = subsystems.TryGetValue(idSubsystem, out var subsystemDto) ? subsystemDto.Name : "unknown", - UsedTimeHours = usedTimeHours, - SumOperationDepthInterval = group.Sum(o => o.DepthEnd - o.DepthStart), - SumOperationDurationHours = group.Sum(o => o.DurationMinutes / 60), - SumDepthInterval = sumDepthInterval, - OperationCount = operationCount, - }; + private async Task> CalcStatAsync( + IEnumerable operations, CancellationToken token) + { + if (!subsystems.Any()) + subsystems = (await subsystemRepository.GetAllAsync(token)).ToDictionary(s => s.Id, s => s); - subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval; + var oscillationStat = CalcOscillationStat(operations); + var apdStat = CalcApdStat(operations); - return subsystemStat; - }); - - if (!apdRotorAndSlide.Any()) - return Enumerable.Empty(); - - var apdSum = new SubsystemStatDto - { - IdSubsystem = IdSubsystemAPD, - SubsystemName = subsystems.TryGetValue(IdSubsystemAPD, out var subsystemDto) ? subsystemDto.Name : "unknown", - UsedTimeHours = apdRotorAndSlide.Sum(part => part.UsedTimeHours), - SumOperationDepthInterval = apdRotorAndSlide.Sum(part => part.SumOperationDepthInterval), - SumOperationDurationHours = apdRotorAndSlide.Sum(part => part.SumOperationDurationHours), - SumDepthInterval = apdRotorAndSlide.Sum(part => part.SumDepthInterval), - OperationCount = apdRotorAndSlide.Sum(part => part.OperationCount), - }; - - apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval; + var stat = new List { oscillationStat }; + stat.AddRange(apdStat); - var apdStat = new List { apdSum }; - apdStat.AddRange(apdRotorAndSlide); + return stat; + } - return apdStat; - } + private SubsystemStatDto CalcOscillationStat(IEnumerable operations) + { + operations = operations.Where(o => o.IdCategory == WellOperationCategory.IdSlide); - private static (double SumDepthInterval, double UsedTimeHours, int Count) AggregateOperations(int idSubsystem, - IEnumerable operations) => - idSubsystem switch - { - IdSubsystemAPDRotor => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoRotor), - IdSubsystemAPDSlide => CalcOperationsByEnableSubsystems(operations, - EnabledSubsystemsFlags.AutoSlide | EnabledSubsystemsFlags.AutoOscillation), - IdSubsystemOscillation => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoOscillation), - _ => throw new ArgumentException($"IdSubsystem: {idSubsystem} does not supported in this method", nameof(idSubsystem)) - }; + var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(IdSubsystemOscillation, operations); - private static (double SumDepthInterval, double UsedTimeHours, int OperationCount) CalcOperationsByEnableSubsystems( - IEnumerable operations, - EnabledSubsystemsFlags enabledSubsystems) - { - var filtered = operations.Where(o => enabledSubsystems.HasEnabledSubsystems(o.EnabledSubsystems)); + var oscillationStat = new SubsystemStatDto + { + IdSubsystem = IdSubsystemOscillation, + SubsystemName = subsystems.TryGetValue(IdSubsystemOscillation, out var subsystemDto) + ? subsystemDto.Name + : "unknown", + UsedTimeHours = usedTimeHours, + SumOperationDepthInterval = operations.Sum(o => o.DepthEnd - o.DepthStart), + SumOperationDurationHours = operations.Sum(o => o.DurationMinutes / 60), + SumDepthInterval = sumDepthInterval, + OperationCount = operationCount, + }; - var sumDepthInterval = filtered.Sum(o => o.DepthEnd - o.DepthStart); - var usedTimeHours = filtered.Sum(o => o.DurationMinutes / 60); - var operationCount = filtered.Count(); + oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval; - return (sumDepthInterval, usedTimeHours, operationCount); - } + return oscillationStat; + } - private async Task> GetStatAsync(IEnumerable wells, - DateTime? geDate, - DateTime? leDate, - CancellationToken token) - { - if (!wells.Any()) - return Enumerable.Empty(); + private IEnumerable CalcApdStat(IEnumerable operations) + { + var apdRotorAndSlide = operations + .Where(o => WellOperationCategory.MechanicalDrillingSubIds.Contains(o.IdCategory)) + .GroupBy(o => o.IdCategory) + .Select(group => + { + var idSubsystem = group.Key switch + { + WellOperationCategory.IdRotor => IdSubsystemAPDRotor, + WellOperationCategory.IdSlide => IdSubsystemAPDSlide, + _ => throw new ArgumentException($"IdCategory: {group.Key} does not supported in this method", + nameof(group.Key)) + }; - var idsTelemetries = wells - .Where(w => w.IdTelemetry is not null) - .Select(w => w.IdTelemetry!.Value) - .Distinct(); + var (sumDepthInterval, usedTimeHours, operationCount) = AggregateOperations(idSubsystem, group); - var wellsStat = new List(); + var subsystemStat = new SubsystemStatDto + { + IdSubsystem = idSubsystem, + SubsystemName = subsystems.TryGetValue(idSubsystem, out var subsystemDto) + ? subsystemDto.Name + : "unknown", + UsedTimeHours = usedTimeHours, + SumOperationDepthInterval = group.Sum(o => o.DepthEnd - o.DepthStart), + SumOperationDurationHours = group.Sum(o => o.DurationMinutes / 60), + SumDepthInterval = sumDepthInterval, + OperationCount = operationCount, + }; - foreach (var well in wells) - { - var hoursOffset = well.Timezone.Hours; + subsystemStat.KUsage = subsystemStat.SumDepthInterval / subsystemStat.SumOperationDepthInterval; - var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset); + return subsystemStat; + }); - var leDateUtc = leDate?.ToUtcDateTimeOffset(hoursOffset); + if (!apdRotorAndSlide.Any()) + return Enumerable.Empty(); - var request = new DetectedOperationByWellRequest - { - IdWell = well.Id, - IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, - GeDateStart = geDateStartUtc, - LeDateEnd = leDateUtc, - }; + var apdSum = new SubsystemStatDto + { + IdSubsystem = IdSubsystemAPD, + SubsystemName = + subsystems.TryGetValue(IdSubsystemAPD, out var subsystemDto) ? subsystemDto.Name : "unknown", + UsedTimeHours = apdRotorAndSlide.Sum(part => part.UsedTimeHours), + SumOperationDepthInterval = apdRotorAndSlide.Sum(part => part.SumOperationDepthInterval), + SumOperationDurationHours = apdRotorAndSlide.Sum(part => part.SumOperationDurationHours), + SumDepthInterval = apdRotorAndSlide.Sum(part => part.SumDepthInterval), + OperationCount = apdRotorAndSlide.Sum(part => part.OperationCount), + }; - var telemetryOperations = await detectedOperationService - .GetOperationsAsync(request, token); + apdSum.KUsage = apdSum.SumDepthInterval / apdSum.SumOperationDepthInterval; - var wellStat = new SubsystemActiveWellStatDto { Well = well }; + var apdStat = new List { apdSum }; + apdStat.AddRange(apdRotorAndSlide); - if (!telemetryOperations.Any()) - continue; + return apdStat; + } - var subsystemStat = await CalcStatAsync(telemetryOperations, token); + private static (double SumDepthInterval, double UsedTimeHours, int Count) AggregateOperations(int idSubsystem, + IEnumerable operations) => + idSubsystem switch + { + IdSubsystemAPDRotor => CalcOperationsByEnableSubsystems(operations, EnabledSubsystemsFlags.AutoRotor), + IdSubsystemAPDSlide => CalcOperationsByEnableSubsystems(operations, + EnabledSubsystemsFlags.AutoSlide | EnabledSubsystemsFlags.AutoOscillation), + IdSubsystemOscillation => CalcOperationsByEnableSubsystems(operations, + EnabledSubsystemsFlags.AutoOscillation), + _ => throw new ArgumentException($"IdSubsystem: {idSubsystem} does not supported in this method", + nameof(idSubsystem)) + }; - if (!subsystemStat.Any()) - continue; + private static (double SumDepthInterval, double UsedTimeHours, int OperationCount) CalcOperationsByEnableSubsystems( + IEnumerable operations, + EnabledSubsystemsFlags enabledSubsystems) + { + var filtered = operations.Where(o => enabledSubsystems.HasEnabledSubsystems(o.EnabledSubsystems)); - wellStat.SubsystemAPD = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPD); - wellStat.SubsystemOscillation = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemOscillation); - wellsStat.Add(wellStat); - } + var sumDepthInterval = filtered.Sum(o => o.DepthEnd - o.DepthStart); + var usedTimeHours = filtered.Sum(o => o.DurationMinutes / 60); + var operationCount = filtered.Count(); - return wellsStat; - } + return (sumDepthInterval, usedTimeHours, operationCount); + } + + private async Task> GetStatAsync(IEnumerable wells, + DateTime? geDate, + DateTime? leDate, + CancellationToken token) + { + if (!wells.Any()) + return Enumerable.Empty(); + + var idsTelemetries = wells + .Where(w => w.IdTelemetry is not null) + .Select(w => w.IdTelemetry!.Value) + .Distinct(); + + var wellsStat = new List(); + + foreach (var well in wells) + { + var hoursOffset = well.Timezone.Hours; + + var geDateStartUtc = geDate?.ToUtcDateTimeOffset(hoursOffset); + + var leDateUtc = leDate?.ToUtcDateTimeOffset(hoursOffset); + + var request = new DetectedOperationByWellRequest + { + IdWell = well.Id, + IdsCategories = WellOperationCategory.MechanicalDrillingSubIds, + GeDateStart = geDateStartUtc, + LeDateEnd = leDateUtc, + }; + + var telemetryOperations = await detectedOperationService + .GetOperationsAsync(request, token); + + var wellStat = new SubsystemActiveWellStatDto { Well = well }; + + if (!telemetryOperations.Any()) + continue; + + var subsystemStat = await CalcStatAsync(telemetryOperations, token); + + if (!subsystemStat.Any()) + continue; + + wellStat.SubsystemAPD = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemAPD); + wellStat.SubsystemOscillation = subsystemStat.FirstOrDefault(s => s.IdSubsystem == IdSubsystemOscillation); + wellsStat.Add(wellStat); + } + + return wellsStat; + } } \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs b/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs index 183073c7..19c21641 100644 --- a/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs +++ b/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs @@ -22,7 +22,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems private readonly ISubsystemService subsystemService; private readonly ITelemetryDataSaubService telemetryDataSaubService; private readonly IWellService wellService; - + public SubsystemController( ISubsystemService subsystemService, IWellService wellService, @@ -32,6 +32,7 @@ namespace AsbCloudWebApi.Controllers.Subsystems this.wellService = wellService; this.telemetryDataSaubService = telemetryDataSaubService; } + /// /// получить статистику /// @@ -61,6 +62,19 @@ namespace AsbCloudWebApi.Controllers.Subsystems return Ok(dateRange); } + [HttpGet("operationsReport/{idWell}")] + [ProducesResponseType(typeof(DrillerDetectedOperationStatDto), (int)System.Net.HttpStatusCode.OK)] + public async Task GetStatDateRangeAsync([FromRoute] int idWell, GetStatRequest request, + CancellationToken token) + { + if (!await UserHasAccessToWellAsync(idWell, token)) + return Forbid(); + + var result = await subsystemService.GetByWellsAsync(request, token); + + return Ok(result); + } + private async Task UserHasAccessToWellAsync(int idWell, CancellationToken token) { var idCompany = User.GetCompanyId(); @@ -71,4 +85,4 @@ namespace AsbCloudWebApi.Controllers.Subsystems return false; } } -} +} \ No newline at end of file From 6b94f79f8d318c18ae85f4f204a9ae615d6a5a57 Mon Sep 17 00:00:00 2001 From: Frolov-Nikita Date: Wed, 21 Feb 2024 18:11:47 +0500 Subject: [PATCH 2/2] =?UTF-8?q?#28835068=20=D0=94=D0=BE=D0=BA=D1=83=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5,=20=D0=BC=D0=B5=D0=BB=D0=BA=D0=B8=D0=B5=20=D0=B8=D0=BC?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Data/DrillerDetectedOperationStatDto.cs | 23 +++++++++++++++---- AsbCloudApp/Requests/GetStatRequest.cs | 15 ++++++++++-- AsbCloudApp/Services/ISubsystemService.cs | 6 +++++ .../Repository/ScheduleRepository.cs | 6 ++--- .../Services/Subsystems/SubsystemService.cs | 14 +++++------ .../Subsystems/SubsystemController.cs | 15 ++++++++---- 6 files changed, 56 insertions(+), 23 deletions(-) diff --git a/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs b/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs index d350c838..96a5a232 100644 --- a/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs +++ b/AsbCloudApp/Data/DrillerDetectedOperationStatDto.cs @@ -3,10 +3,23 @@ using AsbCloudApp.Data.Subsystems; namespace AsbCloudApp.Data; -public record DrillerDetectedOperationStatDto +/// +/// +/// +public class DrillerDetectedOperationStatDto { - public DrillerDto driller; - public IEnumerable statistic; - public ScheduleDto schedule; - public IEnumerable well; + /// + /// + /// + public IEnumerable Statistic { get; set; } = null!; + + /// + /// + /// + public ScheduleDto Schedule { get; set; } = null!; + + /// + /// + /// + public WellDto Well { get; set; } = null!; } \ No newline at end of file diff --git a/AsbCloudApp/Requests/GetStatRequest.cs b/AsbCloudApp/Requests/GetStatRequest.cs index 607c0fc6..8794198b 100644 --- a/AsbCloudApp/Requests/GetStatRequest.cs +++ b/AsbCloudApp/Requests/GetStatRequest.cs @@ -1,9 +1,20 @@ using System.Collections.Generic; +using System.Linq; namespace AsbCloudApp.Requests; +/// +/// +/// public class GetStatRequest: RequestBase { - public IEnumerable idWell; - public int? idDriller; + /// + /// id + /// + public IEnumerable IdsWells { get; set; } = Enumerable.Empty(); + + /// + /// id + /// + public int? IdDriller { get; set; } } \ No newline at end of file diff --git a/AsbCloudApp/Services/ISubsystemService.cs b/AsbCloudApp/Services/ISubsystemService.cs index 7ccc0aa1..b82563f8 100644 --- a/AsbCloudApp/Services/ISubsystemService.cs +++ b/AsbCloudApp/Services/ISubsystemService.cs @@ -29,6 +29,12 @@ public interface ISubsystemService /// Task> GetStatByActiveWells(IEnumerable wellIds, CancellationToken token); + /// + /// Получение статистики по бурильщику + /// + /// + /// + /// Task> GetByWellsAsync(GetStatRequest request, CancellationToken token); } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs index 971cd735..e7c2aa1f 100644 --- a/AsbCloudInfrastructure/Repository/ScheduleRepository.cs +++ b/AsbCloudInfrastructure/Repository/ScheduleRepository.cs @@ -56,9 +56,9 @@ namespace AsbCloudInfrastructure.Repository public async Task> GetPageAsync(GetStatRequest request, CancellationToken token) { - var idWell = request.idWell; - var idDriller = request.idDriller; - var query = GetQuery().Where(s => request.idWell.Contains(s.IdWell)); + var idWell = request.IdsWells; + var idDriller = request.IdDriller; + var query = GetQuery().Where(s => request.IdsWells.Contains(s.IdWell)); if (idDriller is not null) { query.Where(s => s.IdDriller == idDriller); diff --git a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs index 36f373b0..ed2571a9 100644 --- a/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs +++ b/AsbCloudInfrastructure/Services/Subsystems/SubsystemService.cs @@ -56,13 +56,12 @@ internal class SubsystemService : ISubsystemService { var result = new List(); var schedulePage = await scheduleRepository.GetPageAsync(request, token); - var wellTree = await wellService.GetAsync(new WellRequest { Ids = request.idWell }, token); - var wellGroup = wellTree.GroupBy(w => w.Id); + var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token); foreach (var schedule in schedulePage) { var idWell = schedule.IdWell; - var well = wellGroup?.FirstOrDefault(w=> w.Key == idWell); + var well = wells.FirstOrDefault(w=> w.Id == idWell)!; var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest()); @@ -78,16 +77,15 @@ internal class SubsystemService : ISubsystemService var drillerOperationsStat = await CalcStatAsync(entry, token); var dto = new DrillerDetectedOperationStatDto { - driller = entry.Key!, - statistic = drillerOperationsStat, - schedule = schedule, - well = well! + Statistic = drillerOperationsStat, + Schedule = schedule, + Well = well, }; result.Add(dto); } } - return await Task.FromResult(result); + return result; } public async Task> GetStatAsync(SubsystemRequest request, CancellationToken token) diff --git a/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs b/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs index 19c21641..4d16958b 100644 --- a/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs +++ b/AsbCloudWebApi/Controllers/Subsystems/SubsystemController.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -62,13 +63,17 @@ namespace AsbCloudWebApi.Controllers.Subsystems return Ok(dateRange); } - [HttpGet("operationsReport/{idWell}")] - [ProducesResponseType(typeof(DrillerDetectedOperationStatDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetStatDateRangeAsync([FromRoute] int idWell, GetStatRequest request, + [HttpGet("drillerDetectedOperationStat")] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + public async Task GetByWellsAsync(GetStatRequest request, CancellationToken token) { - if (!await UserHasAccessToWellAsync(idWell, token)) - return Forbid(); + if (!request.IdsWells.Any()) + return NoContent(); + + foreach(var idWell in request.IdsWells) + if (!await UserHasAccessToWellAsync(idWell, token)) + return Forbid(); var result = await subsystemService.GetByWellsAsync(request, token);