From 2ee10e8e704639ad7a43acde9691deb3d408605e Mon Sep 17 00:00:00 2001 From: Olga Nemt Date: Mon, 21 Aug 2023 15:51:51 +0500 Subject: [PATCH 1/7] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0=20=D0=BF=D0=BE=20=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=BA=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D0=B2:=20=D0=B2=20=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D0=B0=D0=BA=D1=82=D0=BE=D0=B2=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BB=D0=B6=D0=BD=D1=8B=20=D0=BF=D0=BE=D0=BF=D0=B0=D0=B4?= =?UTF-8?q?=D0=B0=D1=82=D1=8C=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D1=8B=D0=B5=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/WellContactService.cs | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellContactService.cs b/AsbCloudInfrastructure/Services/WellContactService.cs index a8e280da..261ed9f9 100644 --- a/AsbCloudInfrastructure/Services/WellContactService.cs +++ b/AsbCloudInfrastructure/Services/WellContactService.cs @@ -29,18 +29,21 @@ namespace AsbCloudInfrastructure.Services { Caption = c.Caption, Id = c.Id, - Users = c.Users.Select(u => new UserContactDto() - { - Id = u.Id, - Name = u.Name, - Patronymic = u.Patronymic, - Surname = u.Surname, - Company = u.Company.Adapt(), - Email = u.Email, - Phone = u.Phone, - Position = u.Position, - IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId) - }) + Users = c.Users + .Where(u => u.IdState == 1) + .OrderBy(u => u.Surname) + .Select(u => new UserContactDto() + { + Id = u.Id, + Name = u.Name, + Patronymic = u.Patronymic, + Surname = u.Surname, + Company = u.Company.Adapt(), + Email = u.Email, + Phone = u.Phone, + Position = u.Position, + IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId) + }) }); var entities = await query.AsNoTracking() From 6aa643b0d35d055fb59d57ede60766cc7036cecd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=90=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=B0=D0=BD=D0=B4=D1=80=D0=BE=D0=B2=D0=B8=D1=87?= Date: Wed, 23 Aug 2023 11:38:54 +0500 Subject: [PATCH 2/7] =?UTF-8?q?=D0=9D=D0=B5=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=BE=20=D1=81=D1=87=D0=B8=D1=82=D0=B0=D0=BB?= =?UTF-8?q?=D1=81=D1=8F=20Count=20=D0=BF=D1=80=D0=B8=20=D1=84=D0=BE=D1=80?= =?UTF-8?q?=D0=BC=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=BA=D0=B0=20=D1=81=D1=83=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BD=D1=8B=D1=85=20=D0=BE=D1=82=D1=87=D1=91=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20+=20=D1=84=D0=B8=D0=BA=D1=81=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=B2=D1=80?= =?UTF-8?q?=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B8=D0=BD?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D0=B2=D0=B0=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AutoGeneratedDailyReportService.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs index 03a19c44..0e364319 100644 --- a/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs +++ b/AsbCloudInfrastructure/Services/AutoGeneratedDailyReports/AutoGeneratedDailyReportService.cs @@ -66,8 +66,6 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService if (datesRange is null) return result; - - result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays)); if (request.StartDate.HasValue) { @@ -87,6 +85,9 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService datesRange.To = finishDate; } + if (datesRange.From.AddDays(result.Skip) <= datesRange.To) + result.Count = (int)(Math.Ceiling((datesRange.To - DateTime.UnixEpoch).TotalDays) - Math.Floor((datesRange.From - DateTime.UnixEpoch).TotalDays)); + for (int day = result.Skip; (day - result.Skip) < result.Take && (datesRange.From.AddDays(day)) <= datesRange.To; day++) { var reportDate = DateOnly.FromDateTime(datesRange.From.AddDays(day)); @@ -149,8 +150,8 @@ public class AutoGeneratedDailyReportService : IAutoGeneratedDailyReportService return new DatesRangeDto { - From = factOperations.Min(o => o.DateStart), - To = factOperations.Max(o => o.DateStart) + From = factOperations.Min(o => o.DateStart).Date, + To = factOperations.Max(o => o.DateStart).Date }; } From 7293dc11e333f1d05299b6afeda1e7311e230223 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 11 Sep 2023 12:27:48 +0500 Subject: [PATCH 3/7] TelemetryDataBaseService Add GetAsync method with new request --- AsbCloudApp/Requests/TelemetryRequest.cs | 59 +++++++++++++++++++ AsbCloudApp/Services/ITelemetryDataService.cs | 2 + .../Services/SAUB/TelemetryDataBaseService.cs | 54 ++++++++++++++++- .../SAUB/TelemetryDataBaseController.cs | 31 ++++++++++ 4 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 AsbCloudApp/Requests/TelemetryRequest.cs diff --git a/AsbCloudApp/Requests/TelemetryRequest.cs b/AsbCloudApp/Requests/TelemetryRequest.cs new file mode 100644 index 00000000..66b43cb5 --- /dev/null +++ b/AsbCloudApp/Requests/TelemetryRequest.cs @@ -0,0 +1,59 @@ +using System; +using System.ComponentModel.DataAnnotations; + +namespace AsbCloudApp.Requests; + +/// +/// Параметры запроса телеметрии +/// +public class TelemetryDataRequest +{ + /// + /// Максимально допустимое кол-во строк данных + /// + public const int MaxTake = 3072; + + /// + /// greater or equal then Date + /// + public DateTimeOffset? GeDate { get; set; } + + /// + /// less or equal then Date + /// + public DateTimeOffset? LeDate { get; set; } + + /// + /// Делитель для прореживания выборки. + /// + /// 1 - без прореживания (default); + /// 2 - каждое 2-е значение; + /// 10 - каждое 10-е значение; + /// + /// + [Range(0, 300)] + public int Divider { get; set; } = 1; + + /// + /// сортировка/выравнивание данных в запросе по дате + /// + /// 0 - более ранние данные вперед; + /// 1 - более поздние данные вперед; + /// + /// + [Range(0, 1)] + public int Order { get; set; } = 0; + + /// + /// Пропустить с начала + /// + [Range(0, int.MaxValue)] + public int Skip { get; set; } = 0; + + /// + /// Кол-во возвращаемых, но не больше MaxTake + /// + [Range(1, MaxTake)] + public int Take { get; set; } = 1024; + +} diff --git a/AsbCloudApp/Services/ITelemetryDataService.cs b/AsbCloudApp/Services/ITelemetryDataService.cs index c1704509..a2034c7f 100644 --- a/AsbCloudApp/Services/ITelemetryDataService.cs +++ b/AsbCloudApp/Services/ITelemetryDataService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Threading; @@ -25,6 +26,7 @@ namespace AsbCloudApp.Services Task> GetAsync(int idWell, DateTime dateBegin = default, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default); + Task> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token); /// /// Получение статистики за период diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index 8d76ee70..634e2cd1 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb; using AsbCloudDb.Model; @@ -137,10 +138,57 @@ namespace AsbCloudInfrastructure.Services.SAUB } var entities = await query - .OrderBy(d => d.DateTime) .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); + .ToArrayAsync(token); + + var dtos = entities.Select(e => Convert(e, timezone.Hours)); + + return dtos; + } + + /// + public virtual async Task> GetAsync(int idWell, AsbCloudApp.Requests.TelemetryDataRequest request, CancellationToken token) + { + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); + if (telemetry is null) + return Enumerable.Empty(); + + var timezone = telemetryService.GetTimezone(telemetry.Id); + + var dbSet = db.Set(); + + var query = dbSet + .Where(d => d.IdTelemetry == telemetry.Id) + .AsNoTracking(); + + if (request.GeDate.HasValue) + query = query.Where(d => d.DateTime >= request.GeDate); + + if (request.LeDate.HasValue) + query = query.Where(d => d.DateTime >= request.LeDate); + + if (request.Divider > 1) + query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0); + + switch (request.Order) + { + case 1:// Поздние вперед + query = query + .OrderByDescending(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take) + .OrderBy(d => d.DateTime); + break; + default:// Ранние вперед + query = query + .OrderBy(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take); + break; + } + + var entities = await query + .ToArrayAsync(token); var dtos = entities.Select(e => Convert(e, timezone.Hours)); diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs index f80693a1..cd9eb7b5 100644 --- a/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryDataBaseController.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudWebApi.SignalR; using Microsoft.AspNetCore.Authorization; @@ -96,6 +97,36 @@ namespace AsbCloudWebApi.Controllers.SAUB return Ok(content); } + /// + /// Новая версия. Возвращает данные САУБ по скважине. + /// По умолчанию за последние 10 минут. + /// + /// id скважины + /// + /// Токен завершения задачи + /// + [HttpGet("{idWell}/data")] + [Permission] + public virtual async Task>> GetData2Async(int idWell, + [FromQuery]TelemetryDataRequest request, + CancellationToken token) + { + int? idCompany = User.GetCompanyId(); + + if (idCompany is null) + return Forbid(); + + bool isCompanyOwnsWell = await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + idWell, token).ConfigureAwait(false); + + if (!isCompanyOwnsWell) + return Forbid(); + + var content = await telemetryDataService.GetAsync(idWell, request, token); + + return Ok(content); + } + /// /// Возвращает диапазон дат за которые есть телеметрия за период времени /// From 1c1a33aeeea738c91b1b5ac6d9e3cf75e3a6a3cb Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 11 Sep 2023 13:48:47 +0500 Subject: [PATCH 4/7] TelemetryDataBaseService.GetAsync Add cache --- .../Services/SAUB/TelemetryDataBaseService.cs | 4 ++ .../Services/SAUB/TelemetryDataCache.cs | 50 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index 634e2cd1..cdb0daf7 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -155,6 +155,10 @@ namespace AsbCloudInfrastructure.Services.SAUB var timezone = telemetryService.GetTimezone(telemetry.Id); + var cache = telemetryDataCache.GetOrDefault(telemetry.Id, request); + if(cache is not null) + return cache; + var dbSet = db.Set(); var query = dbSet diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 53089f17..6b468682 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection; using AsbCloudInfrastructure.Background; using System.Threading; using AsbCloudApp.Data; +using AsbCloudApp.Requests; namespace AsbCloudInfrastructure.Services.SAUB { @@ -228,5 +229,54 @@ namespace AsbCloudInfrastructure.Services.SAUB }; return item; } + + public IEnumerable? GetOrDefault(int idTelemetry, TelemetryDataRequest request) + { + if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem)) + return null; + + IEnumerable data = cacheItem.LastData; + + if (!data.Any()) + return null; + + if (request.GeDate.HasValue) + { + if (data.First().DateTime > request.GeDate.Value) + return null; + + data = data.Where(d => d.DateTime >= request.GeDate); + } + else + { + if (request.Order == 0) + return null; + } + + if (request.LeDate.HasValue) + data = data.Where(d => d.DateTime >= request.LeDate); + + if (request.Divider > 1) + data = data.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0); + + switch (request.Order) + { + case 1: // Поздние вперед + data = data + .OrderByDescending(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take) + .OrderBy(d => d.DateTime); + break; + default: // Ранние вперед + data = data + .OrderBy(d => d.DateTime) + .Skip(request.Skip) + .Take(request.Take); + break; + } + + return data; + } } } From 5e0ab46e578aab13b238aee92787d57bc45bc6a2 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Mon, 11 Sep 2023 15:21:36 +0500 Subject: [PATCH 5/7] Fix TelemetryDataBaseService.GetAsync Db dateTime timezone TimestampBehavior --- .../Services/SAUB/TelemetryDataBaseService.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index cdb0daf7..bfb173da 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -166,10 +166,16 @@ namespace AsbCloudInfrastructure.Services.SAUB .AsNoTracking(); if (request.GeDate.HasValue) - query = query.Where(d => d.DateTime >= request.GeDate); + { + var geDate = request.GeDate.Value.UtcDateTime; + query = query.Where(d => d.DateTime >= geDate); + } if (request.LeDate.HasValue) - query = query.Where(d => d.DateTime >= request.LeDate); + { + var leDate = request.LeDate.Value.UtcDateTime; + query = query.Where(d => d.DateTime <= leDate); + } if (request.Divider > 1) query = query.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0); From c0db1a02d3fab6b8c2835b277bcd6e7c0459e465 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Tue, 12 Sep 2023 16:22:01 +0500 Subject: [PATCH 6/7] TelemetryDataCache.GetOrDefault(..) Fix Timezone issue --- .../Services/SAUB/TelemetryDataCache.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 6b468682..c99b6c95 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -22,6 +22,7 @@ namespace AsbCloudInfrastructure.Services.SAUB { public TDto? FirstByDate { get; init; } public CyclycArray LastData { get; init; } = null!; + public double TimezoneHours { get; init; } = 5; } private IServiceProvider provider = null!; @@ -226,6 +227,7 @@ namespace AsbCloudInfrastructure.Services.SAUB { FirstByDate = first, LastData = cacheItem, + TimezoneHours = hoursOffset, }; return item; } @@ -234,7 +236,7 @@ namespace AsbCloudInfrastructure.Services.SAUB { if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem)) return null; - + IEnumerable data = cacheItem.LastData; if (!data.Any()) @@ -242,19 +244,23 @@ namespace AsbCloudInfrastructure.Services.SAUB if (request.GeDate.HasValue) { - if (data.First().DateTime > request.GeDate.Value) + var geDate = request.GeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours); + if (data.First().DateTime > geDate) return null; - data = data.Where(d => d.DateTime >= request.GeDate); + data = data.Where(d => d.DateTime >= geDate); } else { if (request.Order == 0) return null; - } + } - if (request.LeDate.HasValue) + if (request.LeDate.HasValue) + { + var leDate = request.LeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours); data = data.Where(d => d.DateTime >= request.LeDate); + } if (request.Divider > 1) data = data.Where((d) => (((d.DateTime.DayOfYear * 24 + d.DateTime.Hour) * 60 + d.DateTime.Minute) * 60 + d.DateTime.Second) % request.Divider == 0); From adeaab52c487165235ba42dd73cae6d0c692be31 Mon Sep 17 00:00:00 2001 From: ngfrolov Date: Tue, 12 Sep 2023 17:49:24 +0500 Subject: [PATCH 7/7] WellboreService.GetWellboresAsync(..) fix timezones --- AsbCloudInfrastructure/Services/WellboreService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AsbCloudInfrastructure/Services/WellboreService.cs b/AsbCloudInfrastructure/Services/WellboreService.cs index 79ef8a3c..5e0e439e 100644 --- a/AsbCloudInfrastructure/Services/WellboreService.cs +++ b/AsbCloudInfrastructure/Services/WellboreService.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -58,8 +59,8 @@ public class WellboreService : IWellboreService Id = group.Key, Name = sections[group.Key].Caption, Well = well.Adapt(), - DateStart = group.Min(operation => operation.DateStart), - DateEnd = group.Max(operation => operation.DateStart.AddHours(operation.DurationHours)), + DateStart = group.Min(operation => operation.DateStart).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)), + DateEnd = group.Max(operation => operation.DateStart.AddHours(operation.DurationHours)).ToUtcDateTimeOffset(well.Timezone.Hours).ToOffset(TimeSpan.FromHours(well.Timezone.Hours)), DepthStart = group.Min(operation => operation.DepthStart), DepthEnd = group.Max(operation => operation.DepthEnd), });