From 70dca51987acac8353f99eb59ea3bac4ab8576d1 Mon Sep 17 00:00:00 2001 From: KharchenkoVV Date: Thu, 17 Jun 2021 15:12:39 +0500 Subject: [PATCH] =?UTF-8?q?CS2-24:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D1=8B=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20"=D0=B3=D0=BB=D1=83=D0=B1?= =?UTF-8?q?=D0=B8=D0=BD=D0=B0-=D0=B4=D0=B5=D0=BD=D1=8C"=20=D0=B8=20"=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D1=80=D0=BE=D1=81=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=BA=D0=B8-=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB".?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/WellDepthToDayDto.cs | 11 ++ AsbCloudApp/Data/WellDepthToIntervalDto.cs | 10 ++ AsbCloudApp/Services/IAnalyticsService.cs | 12 +++ AsbCloudInfrastructure/DependencyInjection.cs | 1 + .../Services/AnalyticsService.cs | 102 ++++++++++++++++++ .../Controllers/AnalyticsController.cs | 70 +++++++++++- 6 files changed, 203 insertions(+), 3 deletions(-) create mode 100644 AsbCloudApp/Data/WellDepthToDayDto.cs create mode 100644 AsbCloudApp/Data/WellDepthToIntervalDto.cs create mode 100644 AsbCloudApp/Services/IAnalyticsService.cs create mode 100644 AsbCloudInfrastructure/Services/AnalyticsService.cs diff --git a/AsbCloudApp/Data/WellDepthToDayDto.cs b/AsbCloudApp/Data/WellDepthToDayDto.cs new file mode 100644 index 00000000..7b4bc175 --- /dev/null +++ b/AsbCloudApp/Data/WellDepthToDayDto.cs @@ -0,0 +1,11 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class WellDepthToDayDto + { + public double? WellDepth { get; set; } + public double? BitDepth { get; set; } + public DateTime Date { get; set; } + } +} diff --git a/AsbCloudApp/Data/WellDepthToIntervalDto.cs b/AsbCloudApp/Data/WellDepthToIntervalDto.cs new file mode 100644 index 00000000..8f6aef84 --- /dev/null +++ b/AsbCloudApp/Data/WellDepthToIntervalDto.cs @@ -0,0 +1,10 @@ +using System; + +namespace AsbCloudApp.Data +{ + public class WellDepthToIntervalDto + { + public DateTime IntervalStartDate { get; set; } + public double IntervalDepthProgress { get; set; } + } +} diff --git a/AsbCloudApp/Services/IAnalyticsService.cs b/AsbCloudApp/Services/IAnalyticsService.cs new file mode 100644 index 00000000..3bdaad89 --- /dev/null +++ b/AsbCloudApp/Services/IAnalyticsService.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using AsbCloudApp.Data; + +namespace AsbCloudApp.Services +{ + public interface IAnalyticsService + { + IEnumerable GetWellDepthToDayData(int wellId); + IEnumerable GetWellDepthToIntervalData(int wellId, + double interval = 24, int beginHour = 8, int beginMinutes = 0); + } +} diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index b7b4ef6f..63d56782 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -34,6 +34,7 @@ namespace AsbCloudInfrastructure services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); return services; } diff --git a/AsbCloudInfrastructure/Services/AnalyticsService.cs b/AsbCloudInfrastructure/Services/AnalyticsService.cs new file mode 100644 index 00000000..8a47064a --- /dev/null +++ b/AsbCloudInfrastructure/Services/AnalyticsService.cs @@ -0,0 +1,102 @@ +using System; +using System.Linq; +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using System.Collections.Generic; + +namespace AsbCloudInfrastructure.Services +{ + public class AnalyticsService : IAnalyticsService + { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + + public AnalyticsService(IAsbCloudDbContext db, ITelemetryService telemetryService) + { + this.db = db; + this.telemetryService = telemetryService; + } + + public IEnumerable GetWellDepthToDayData(int wellId) + { + var telemetry = telemetryService.GetTelemetryByWellId(wellId); + + if (telemetry is null) + return null; + + var depthToTimeData = (from d in db.DataSaubBases + where d.IdTelemetry == telemetry.Id + select new WellDepthToDayDto + { + WellDepth = d.WellDepth, + BitDepth =d.BitDepth, + Date = d.Date + }).ToList(); + + var m = (int)Math.Round(1d * depthToTimeData.Count / 2048); + + if (m > 1) + depthToTimeData = depthToTimeData.Where((d, i) => i % m == 0).ToList(); + + return depthToTimeData; + } + + public IEnumerable GetWellDepthToIntervalData(int wellId, + double interval = 24.0, int beginHour = 8, int beginMinutes = 0) + { + var intervalHours = TimeSpan.FromHours(interval); + var parseResult = TimeSpan.TryParse($"{beginHour}:{beginMinutes}", out var workDayBeginTime); + + if (!parseResult) + workDayBeginTime = TimeSpan.FromHours(8); + + var telemetry = telemetryService.GetTelemetryByWellId(wellId); + + if (telemetry is null) + return null; + + var drillingData = (from d in db.DataSaubBases + where d.IdTelemetry == telemetry.Id + select new + { + d.WellDepth, + d.Date + }).ToList(); + + if (!drillingData.Any()) + return null; + + var drillingStartDate = drillingData.First().Date; + var periodStart = drillingStartDate.Hour < 8 + ? new DateTime(drillingStartDate.Year, drillingStartDate.Month, drillingStartDate.Day).AddDays(-1) + workDayBeginTime + : new DateTime(drillingStartDate.Year, drillingStartDate.Month, drillingStartDate.Day) + workDayBeginTime; + + var periodEnd = periodStart + intervalHours; + var onePeriodData = new List<(double?, DateTime)>(); + var drillingPeriods = new List>(); + + foreach (var d in drillingData) + { + if (d.Date < periodEnd) + { + onePeriodData.Add((d.WellDepth, d.Date)); + continue; + } + drillingPeriods.Add(onePeriodData); + onePeriodData.Clear(); + periodStart = d.Date; + periodEnd = periodStart + intervalHours; + onePeriodData.Add((d.WellDepth, d.Date)); + } + + var wellDepthToIntervalData = drillingPeriods.Select(d => new WellDepthToIntervalDto + { + IntervalStartDate = d.FirstOrDefault().Item2, + IntervalDepthProgress = (d.Last().Item1 - d.FirstOrDefault().Item1) ?? 0.0 / interval + }); + + return wellDepthToIntervalData; + } + } +} diff --git a/AsbCloudWebApi/Controllers/AnalyticsController.cs b/AsbCloudWebApi/Controllers/AnalyticsController.cs index 41fcb19d..dc2354ad 100644 --- a/AsbCloudWebApi/Controllers/AnalyticsController.cs +++ b/AsbCloudWebApi/Controllers/AnalyticsController.cs @@ -1,6 +1,7 @@ using System; -using AsbCloudApp.Data; using System.Collections.Generic; +using AsbCloudApp.Data; +using AsbCloudApp.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; @@ -11,6 +12,61 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class AnalyticsController : ControllerBase { + private readonly IAnalyticsService analyticsService; + private readonly IWellService wellService; + + public AnalyticsController(IAnalyticsService analyticsService, IWellService wellService) + { + this.analyticsService = analyticsService; + this.wellService = wellService; + } + + /// + /// Возвращает данные по скважине "глубина-день" + /// + /// id скважины + /// Коллекцию данных по скважине "глубина-день" + [HttpGet] + [Route("{wellId}/wellDepthToDay")] + [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetWellDepthToDay(int wellId) + { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + + var wellDepthToDayData = analyticsService.GetWellDepthToDayData(wellId); + + return Ok(wellDepthToDayData); + } + + /// + /// Возвращает данные по глубине скважины за период + /// + /// id скважины + /// Коллекцию данных по глубине скважины за период + [HttpGet] + [Route("{wellId}/wellDepthToInterval")] + [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] + public IActionResult GetWellDepthToInterval(int wellId) + { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + + var wellDepthToIntervalData = analyticsService.GetWellDepthToIntervalData(wellId); + + return Ok(wellDepthToIntervalData); + } + /// /// Возвращает данные по операциям на скважине за период /// @@ -19,10 +75,18 @@ namespace AsbCloudWebApi.Controllers /// дата окончания интервала /// Коллекцию операций на скважине [HttpGet] - [Route("{wellId}/get")] + [Route("{wellId}/operationsToTime")] [ProducesResponseType(typeof(List), (int)System.Net.HttpStatusCode.OK)] - public IActionResult GetAnalytics(int wellId, DateTime begin = default, DateTime end = default) + public IActionResult GetOperationsToTime(int wellId, DateTime begin = default, DateTime end = default) { + int? idCustomer = User.GetCustomerId(); + + if (idCustomer is null) + return BadRequest(); + + if (!wellService.CheckWellOwnership((int)idCustomer, wellId)) + return Forbid(); + var analytics = new List { new OperationPercentageDto { ProcessName = "Роторное бурение", Percentage = 19.7 },