From c4bb5f90407395aef884882582c86c6e97f00b88 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?= Date: Thu, 4 Apr 2024 07:41:00 +0300 Subject: [PATCH 1/3] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BE?= =?UTF-8?q?=D1=82=20=D0=93=D0=A2=D0=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен новый Dto 2. Обновлён репозиторий 3. Обновление API --- AsbCloudApp/Data/GTR/GtrWitsDto.cs | 214 ++++++++++++++++++ AsbCloudApp/Repositories/IGtrRepository.cs | 12 + ...GtrWithGetDataRequest.cs => GtrRequest.cs} | 19 +- .../Repository/GtrWitsRepository.cs | 89 ++++++++ .../Clients/IGtrWitsClient.cs | 13 ++ .../Controllers/GtrControllerTests.cs | 68 ++++++ .../Controllers/GtrWitsController.cs | 65 ++++++ .../Controllers/SAUB/GtrWitsController.cs | 2 +- 8 files changed, 480 insertions(+), 2 deletions(-) create mode 100644 AsbCloudApp/Data/GTR/GtrWitsDto.cs rename AsbCloudApp/Requests/{GtrWithGetDataRequest.cs => GtrRequest.cs} (63%) create mode 100644 AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs create mode 100644 AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs create mode 100644 AsbCloudWebApi/Controllers/GtrWitsController.cs diff --git a/AsbCloudApp/Data/GTR/GtrWitsDto.cs b/AsbCloudApp/Data/GTR/GtrWitsDto.cs new file mode 100644 index 00000000..a8ecb939 --- /dev/null +++ b/AsbCloudApp/Data/GTR/GtrWitsDto.cs @@ -0,0 +1,214 @@ +namespace AsbCloudApp.Data.GTR; + +public class GtrWitsDto +{ + /// + /// Вес на крюке + /// + public float? HKLA { get; set; } + + /// + /// Высота крюка + /// + public float? BLKPOS { get; set; } + + /// + /// Нагрузка на долото + /// + public float? WOBA { get; set; } + + /// + /// Момент на роторе/ВСП + /// + public float? TORQA { get; set; } + + /// + /// Давление на входе (на стояке) + /// + public float? SPPA { get; set; } + + /// + /// Обороты ротора/ВСП + /// + public float? RPMA { get; set; } + + /// + /// Механическая скорость + /// + public float? ROPA { get; set; } + + /// + /// Скорость инструмента вверх + /// + public float? RSUX { get; set; } + + /// + /// Скорость инструмента вниз + /// + public float? RSDX { get; set; } + + /// + /// Расход на входе + /// + public float? MFIA { get; set; } + + /// + /// Расход на выходе + /// + public float? MFOA { get; set; } + + /// + /// Температура на входе + /// + public float? MTIA { get; set; } + + /// + /// Температура на выходе + /// + public float? MTOA { get; set; } + + /// + /// Ходы насоса №1 + /// + public float? SPM1 { get; set; } + + /// + /// Ходы насоса №2 + /// + public float? SPM2 { get; set; } + + /// + /// Ходы насоса №3 + /// + public float? SPM3 { get; set; } + + /// + /// Общий объем бурового раствора на поверхности + /// + public float? TVOLACT { get; set; } + + /// + /// Объем бурового раствора в доливной емкости №1 + /// + public float? TTVOL1 { get; set; } + + /// + /// Объем бурового раствора в доливной емкости №2 + /// + public float? TTVOL2 { get; set; } + + /// + /// Объем бурового раствора в емкости №1 + /// + public float? TVOL01 { get; set; } + + /// + /// Объем бурового раствора в емкости №2 + /// + public float? TVOL02 { get; set; } + + /// + /// Объем бурового раствора в емкости №3 + /// + public float? TVOL03 { get; set; } + + /// + /// Объем бурового раствора в емкости №4 + /// + public float? TVOL04 { get; set; } + + /// + /// Объем бурового раствора в емкости №5 + /// + public float? TVOL05 { get; set; } + + /// + /// Объем бурового раствора в емкости №6 + /// + public float? TVOL06 { get; set; } + + /// + /// Объем бурового раствора в емкости №7 + /// + public float? TVOL07 { get; set; } + + /// + /// Объем бурового раствора в емкости №8 + /// + public float? TVOL08 { get; set; } + + /// + /// Объем бурового раствора в емкости №9 + /// + public float? TVOL09 { get; set; } + + /// + /// Объем бурового раствора в емкости №10 + /// + public float? TVOL10 { get; set; } + + /// + /// Объем бурового раствора в емкости №11 + /// + public float? TVOL11 { get; set; } + + /// + /// Объем бурового раствора в емкости №12 + /// + public float? TVOL12 { get; set; } + + /// + /// Объем бурового раствора в емкости №13 + /// + public float? TVOL13 { get; set; } + + /// + /// Объем бурового раствора в емкости №14 + /// + public float? TVOL14 { get; set; } + + /// + /// Плотность (удельный вес) бурового раствора на выходе + /// + public float? MDOA { get; set; } + + /// + /// Плотность (удельный вес) бурового раствора на входе + /// + public float? MDIA { get; set; } + + /// + /// Процентное содержание метана + /// + public float? METHANE { get; set; } + + /// + /// Процентное содержание этана + /// + public float? ETHANE { get; set; } + + /// + /// Процентное содержание пропана + /// + public float? PROPANE { get; set; } + + /// + /// Процентное содержание бутана + /// + public float? IBUTANE { get; set; } + + /// + /// Процентное содержание пентана + /// + public float? NBUTANE { get; set; } + + /// + /// Процентное содержание углеводородов + /// + public float? HydrocarbonPercentage => METHANE + ETHANE + PROPANE + IBUTANE + NBUTANE; + + /// + /// Процентное содержание газов + /// + public float? GASA { get; set; } +} \ No newline at end of file diff --git a/AsbCloudApp/Repositories/IGtrRepository.cs b/AsbCloudApp/Repositories/IGtrRepository.cs index 0d597dde..1aadfb96 100644 --- a/AsbCloudApp/Repositories/IGtrRepository.cs +++ b/AsbCloudApp/Repositories/IGtrRepository.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Requests; namespace AsbCloudApp.Repositories { @@ -19,6 +20,14 @@ namespace AsbCloudApp.Repositories /// /// Task SaveDataAsync(int idTelemetry, IEnumerable dtos, CancellationToken token); + + /// + /// получить данные ГТИ + /// + /// + /// + /// + Task> GetAsync(GtrRequest request, CancellationToken token); /// /// получить данные для клиента @@ -29,6 +38,7 @@ namespace AsbCloudApp.Repositories /// кол-во элементов до которых эти данные прореживаются /// /// + [Obsolete] Task> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600d, int approxPointsCount = 1024, CancellationToken token = default); @@ -39,6 +49,7 @@ namespace AsbCloudApp.Repositories /// /// /// + [Obsolete] IEnumerable GetLastDataByRecordId(int idWell, int idRecord); /// @@ -46,6 +57,7 @@ namespace AsbCloudApp.Repositories /// /// /// + [Obsolete] IEnumerable GetLastData(int idWell); } } diff --git a/AsbCloudApp/Requests/GtrWithGetDataRequest.cs b/AsbCloudApp/Requests/GtrRequest.cs similarity index 63% rename from AsbCloudApp/Requests/GtrWithGetDataRequest.cs rename to AsbCloudApp/Requests/GtrRequest.cs index 8e93a02c..8ba678b2 100644 --- a/AsbCloudApp/Requests/GtrWithGetDataRequest.cs +++ b/AsbCloudApp/Requests/GtrRequest.cs @@ -5,7 +5,7 @@ namespace AsbCloudApp.Requests; /// /// Параметры запроса для получения загруженных данных ГТИ по скважине /// -public class GtrWithGetDataRequest +public class GtrRequestBase { /// /// Дата начала выборки.По умолчанию: текущее время - IntervalSec @@ -20,5 +20,22 @@ public class GtrWithGetDataRequest /// /// Желаемое количество точек. Если в выборке точек будет больше, то выборка будет прорежена. /// + [Obsolete] public int ApproxPointsCount { get; set; } = 1024; +} + +/// +/// Параметры запроса для получения загруженных данных ГТИ по скважине +/// +public class GtrRequest : GtrRequestBase +{ + public GtrRequest(int idWell, GtrRequestBase request) + { + IdWell = idWell; + Begin = request.Begin; + IntervalSec = request.IntervalSec; + ApproxPointsCount = request.ApproxPointsCount; + } + + public int IdWell { get; set; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs index 2a871553..5d0cda7b 100644 --- a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs +++ b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs @@ -12,11 +12,58 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Requests; +using Mapster; namespace AsbCloudInfrastructure.Repository { public class GtrWitsRepository : IGtrRepository { + private static IDictionary<(int, int), string> WitsParameters = new Dictionary<(int, int), string> + { + { (1, 14), nameof(GtrWitsDto.HKLA) }, + { (1, 12), nameof(GtrWitsDto.BLKPOS) }, + { (1, 16), nameof(GtrWitsDto.WOBA) }, + { (1, 18), nameof(GtrWitsDto.TORQA) }, + { (1, 21), nameof(GtrWitsDto.SPPA) }, + { (2, 15), nameof(GtrWitsDto.RPMA) }, + { (1, 13), nameof(GtrWitsDto.ROPA) }, + { (3, 16), nameof(GtrWitsDto.RSUX) }, + { (3, 17), nameof(GtrWitsDto.RSDX) }, + { (1, 30), nameof(GtrWitsDto.MFIA) }, + { (1, 29), nameof(GtrWitsDto.MFOA)}, + { (1, 34), nameof(GtrWitsDto.MTIA) }, + { (1, 33), nameof(GtrWitsDto.MTOA) }, + { (1, 23), nameof(GtrWitsDto.SPM1) }, + { (1, 24), nameof(GtrWitsDto.SPM2) }, + { (1, 25), nameof(GtrWitsDto.SPM3) }, + { (1, 26), nameof(GtrWitsDto.TVOLACT) }, + { (11, 29), nameof(GtrWitsDto.TTVOL1) }, + { (11, 30), nameof(GtrWitsDto.TTVOL2) }, + { (11, 15), nameof(GtrWitsDto.TVOL01) }, + { (11, 16), nameof(GtrWitsDto.TVOL02) }, + { (11, 17), nameof(GtrWitsDto.TVOL03) }, + { (11, 18), nameof(GtrWitsDto.TVOL04) }, + { (11, 19), nameof(GtrWitsDto.TVOL05) }, + { (11, 20), nameof(GtrWitsDto.TVOL06) }, + { (11, 21), nameof(GtrWitsDto.TVOL07) }, + { (11, 22), nameof(GtrWitsDto.TVOL08) }, + { (11, 23), nameof(GtrWitsDto.TVOL09) }, + { (11, 24), nameof(GtrWitsDto.TVOL10) }, + { (11, 25), nameof(GtrWitsDto.TVOL11) }, + { (11, 26), nameof(GtrWitsDto.TVOL12) }, + { (11, 27), nameof(GtrWitsDto.TVOL13) }, + { (11, 28), nameof(GtrWitsDto.TVOL14) }, + { (1, 31), nameof(GtrWitsDto.MDOA) }, + { (1, 32), nameof(GtrWitsDto.MDIA) }, + { (12, 12), nameof(GtrWitsDto.METHANE) }, + { (12, 13), nameof(GtrWitsDto.ETHANE) }, + { (12, 14), nameof(GtrWitsDto.PROPANE) }, + { (12, 15), nameof(GtrWitsDto.IBUTANE) }, + { (12, 16), nameof(GtrWitsDto.NBUTANE) }, + { (1, 40), nameof(GtrWitsDto.GASA) }, + }; + private readonly IAsbCloudDbContext db; private readonly ITelemetryService telemetryService; private static ConcurrentDictionary> cache = new(); @@ -28,6 +75,48 @@ namespace AsbCloudInfrastructure.Repository this.db = db; this.telemetryService = telemetryService; } + + public async Task> GetAsync(GtrRequest request, CancellationToken token) + { + var interval = TimeSpan.FromSeconds(10); + var query = BuildQuery(request); + var entities = await query.AsNoTracking().ToArrayAsync(token); + + var dtos = entities + .GroupBy(e => e.DateTime.Ticks / interval.Ticks) + .Select(Convert); + + return dtos; + } + + private static GtrWitsDto Convert(IEnumerable scr) + { + var values = scr.GroupBy(e => (e.IdRecord, e.IdItem)) + .ToDictionary(g => WitsParameters[g.Key], g => g.LastOrDefault()?.Value); + + var dto = values.Adapt(); + + return dto; + } + + private IQueryable BuildQuery(GtrRequest request) + where TEntity : WitsItemBase + where TType : notnull + { + var query = db.Set().OrderBy(e => e.DateTime) + .Where(e => e.Telemetry != null && + e.Telemetry.Well != null && + e.Telemetry.Well.Id == request.IdWell) + .Where(e => e.DateTime >= DateTime.UtcNow.AddSeconds(-request.IntervalSec)); + + if (request.Begin.HasValue) + { + var dateBeginUtc = request.Begin.Value.ToUniversalTime(); + query = query.Where(e => e.DateTime >= dateBeginUtc); + } + + return query; + } public async Task> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) { diff --git a/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs b/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs new file mode 100644 index 00000000..17f76a33 --- /dev/null +++ b/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs @@ -0,0 +1,13 @@ +using AsbCloudApp.Data.GTR; +using AsbCloudApp.Requests; +using Refit; + +namespace AsbCloudWebApi.IntegrationTests.Clients; + +public interface IGtrWitsClient +{ + private const string BaseRoute = "/api/well/{idWell}/gtrWits"; + + [Get(BaseRoute)] + Task>> GetAllAsync(int idWell, [Query] GtrRequestBase request); +} \ No newline at end of file diff --git a/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs b/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs new file mode 100644 index 00000000..eb1e96d8 --- /dev/null +++ b/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs @@ -0,0 +1,68 @@ +using System.Net; +using AsbCloudApp.Requests; +using AsbCloudDb.Model.GTR; +using AsbCloudWebApi.IntegrationTests.Clients; +using Xunit; + +namespace AsbCloudWebApi.IntegrationTests.Controllers; + +public class GtrControllerTests : BaseIntegrationTest +{ + private readonly IGtrWitsClient client; + + public GtrControllerTests(WebAppFactoryFixture factory) + : base(factory) + { + client = factory.GetAuthorizedHttpClient(string.Empty); + } + + [Fact] + public async Task GetAll_returns_success() + { + //arrange + var well = dbContext.Wells.First(); + + var witsItems = CreateWitsItems(well.IdTelemetry!.Value); + dbContext.WitsItemFloat.AddRange(witsItems); + await dbContext.SaveChangesAsync(); + + var request = new GtrRequestBase(); + + //act + var response = await client.GetAllAsync(well.Id, request); + + //assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.NotNull(response.Content); + Assert.True(response.Content.Any()); + } + + private static IEnumerable CreateWitsItems(int idTelemetry) => + new[] + { + new WitsItemFloat + { + IdRecord = 1, + IdItem = 14, + Value = 4, + IdTelemetry = idTelemetry, + DateTime = DateTimeOffset.UtcNow + }, + new WitsItemFloat + { + IdRecord = 1, + IdItem = 14, + Value = 5, + IdTelemetry = idTelemetry, + DateTime = DateTimeOffset.UtcNow + }, + new WitsItemFloat + { + IdRecord = 1, + IdItem = 12, + Value = 5, + IdTelemetry = idTelemetry, + DateTime = DateTimeOffset.UtcNow.AddSeconds(10) + } + }; +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/GtrWitsController.cs b/AsbCloudWebApi/Controllers/GtrWitsController.cs new file mode 100644 index 00000000..69d8a7d2 --- /dev/null +++ b/AsbCloudWebApi/Controllers/GtrWitsController.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.GTR; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace AsbCloudWebApi.Controllers; + +[ApiController] +[Route("api/well/{idWell}/[controller]")] +[Authorize] +public class GtrWitsController : ControllerBase +{ + private readonly IWellService wellService; + private readonly IGtrRepository gtrRepository; + + public GtrWitsController(IWellService wellService, + IGtrRepository gtrRepository) + { + this.wellService = wellService; + this.gtrRepository = gtrRepository; + } + + /// + /// Получить значение от ГТИ + /// + /// + /// + /// + /// + [HttpGet] + [Permission] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task GetAllAsync(int idWell, [FromQuery] GtrRequestBase request, CancellationToken token) + { + await AssertUserHasAccessToWellAsync(idWell, token); + + var requestToRepository = new GtrRequest(idWell, request); + + var dtos = await gtrRepository.GetAsync(requestToRepository, token); + + return Ok(dtos); + } + + private async Task AssertUserHasAccessToWellAsync(int idWell, CancellationToken token) + { + var idUser = User.GetUserId(); + var idCompany = User.GetCompanyId(); + + if (!idUser.HasValue) + throw new ForbidException("Нет доступа к скважине"); + + if (!idCompany.HasValue) + throw new ForbidException("Нет доступа к скважине"); + + if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token)) + throw new ForbidException("Нет доступа к скважине"); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs b/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs index f4cfe0b4..95662fe2 100644 --- a/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs @@ -46,7 +46,7 @@ namespace AsbCloudWebApi.Controllers.SAUB /// [HttpGet("{idWell}")] public async Task>> GetDataAsync([Required] int idWell, - [FromQuery] GtrWithGetDataRequest request, + [FromQuery] GtrRequest request, CancellationToken token) { int? idCompany = User.GetCompanyId(); From 979ed91e786f7e027a64c2b093d3a4eb0c665eeb 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?= Date: Mon, 8 Apr 2024 14:32:00 +0300 Subject: [PATCH 2/3] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=BE=D1=81=D0=BB=D0=B5=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AsbCloudApp/Data/GTR/GtrWitsDto.cs | 20 ++++++ AsbCloudApp/Repositories/IGtrRepository.cs | 3 +- AsbCloudApp/Requests/GtrRequest.cs | 18 +---- .../Repository/GtrWitsRepository.cs | 68 +++++++++++++------ .../Clients/IGtrWitsClient.cs | 4 +- .../Controllers/GtrControllerTests.cs | 2 +- .../Controllers/GtrWitsController.cs | 65 ------------------ .../Controllers/SAUB/GtrWitsController.cs | 36 ++++++++++ 8 files changed, 108 insertions(+), 108 deletions(-) delete mode 100644 AsbCloudWebApi/Controllers/GtrWitsController.cs diff --git a/AsbCloudApp/Data/GTR/GtrWitsDto.cs b/AsbCloudApp/Data/GTR/GtrWitsDto.cs index a8ecb939..20d08dd6 100644 --- a/AsbCloudApp/Data/GTR/GtrWitsDto.cs +++ b/AsbCloudApp/Data/GTR/GtrWitsDto.cs @@ -1,7 +1,27 @@ +using System; + namespace AsbCloudApp.Data.GTR; +/// +/// ГТИ +/// public class GtrWitsDto { + /// + /// Дата получения записи + /// + public DateTimeOffset DateTime { get; set; } + + /// + /// Забой (скважины), м + /// + public float? DEPTMEAS { get; set; } + + /// + /// Долото, м + /// + public float DEPTBITM { get; set; } + /// /// Вес на крюке /// diff --git a/AsbCloudApp/Repositories/IGtrRepository.cs b/AsbCloudApp/Repositories/IGtrRepository.cs index 1aadfb96..706b6be2 100644 --- a/AsbCloudApp/Repositories/IGtrRepository.cs +++ b/AsbCloudApp/Repositories/IGtrRepository.cs @@ -24,10 +24,11 @@ namespace AsbCloudApp.Repositories /// /// получить данные ГТИ /// + /// /// /// /// - Task> GetAsync(GtrRequest request, CancellationToken token); + Task> GetAsync(int idWell, GtrRequest request, CancellationToken token); /// /// получить данные для клиента diff --git a/AsbCloudApp/Requests/GtrRequest.cs b/AsbCloudApp/Requests/GtrRequest.cs index 8ba678b2..43de25c4 100644 --- a/AsbCloudApp/Requests/GtrRequest.cs +++ b/AsbCloudApp/Requests/GtrRequest.cs @@ -5,7 +5,7 @@ namespace AsbCloudApp.Requests; /// /// Параметры запроса для получения загруженных данных ГТИ по скважине /// -public class GtrRequestBase +public class GtrRequest { /// /// Дата начала выборки.По умолчанию: текущее время - IntervalSec @@ -22,20 +22,4 @@ public class GtrRequestBase /// [Obsolete] public int ApproxPointsCount { get; set; } = 1024; -} - -/// -/// Параметры запроса для получения загруженных данных ГТИ по скважине -/// -public class GtrRequest : GtrRequestBase -{ - public GtrRequest(int idWell, GtrRequestBase request) - { - IdWell = idWell; - Begin = request.Begin; - IntervalSec = request.IntervalSec; - ApproxPointsCount = request.ApproxPointsCount; - } - - public int IdWell { get; set; } } \ No newline at end of file diff --git a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs index 5d0cda7b..022532f2 100644 --- a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs +++ b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs @@ -21,6 +21,8 @@ namespace AsbCloudInfrastructure.Repository { private static IDictionary<(int, int), string> WitsParameters = new Dictionary<(int, int), string> { + { (1, 8), nameof(GtrWitsDto.DEPTBITM) }, + { (1, 10), nameof(GtrWitsDto.DEPTMEAS) }, { (1, 14), nameof(GtrWitsDto.HKLA) }, { (1, 12), nameof(GtrWitsDto.BLKPOS) }, { (1, 16), nameof(GtrWitsDto.WOBA) }, @@ -75,39 +77,60 @@ namespace AsbCloudInfrastructure.Repository this.db = db; this.telemetryService = telemetryService; } - - public async Task> GetAsync(GtrRequest request, CancellationToken token) + + public async Task> GetAsync(int idWell, GtrRequest request, CancellationToken token) => + await GetAsync(idWell, request, token); + + private async Task> GetAsync(int idWell, GtrRequest request, CancellationToken token) + where TEntity : WitsItemBase + where TType : notnull { - var interval = TimeSpan.FromSeconds(10); - var query = BuildQuery(request); - var entities = await query.AsNoTracking().ToArrayAsync(token); + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); + if (telemetry is null) + return Enumerable.Empty(); + + var timezone = telemetryService.GetTimezone(telemetry.Id); + var timezoneOffset = TimeSpan.FromHours(timezone.Hours); + + var query = BuildQuery(telemetry.Id, request); + + if (!await query.AnyAsync(token)) + return Enumerable.Empty(); + + var interval = TimeSpan.FromSeconds(10); + + var entities = await query + .OrderBy(e => e.DateTime) + .AsNoTracking() + .ToArrayAsync(token); + var dtos = entities .GroupBy(e => e.DateTime.Ticks / interval.Ticks) - .Select(Convert); + .Select(groupByInterval => + { + var items = groupByInterval.Select(e => e); + var values = items.GroupBy(e => (e.IdRecord, e.IdItem)) + .Where(parameter => parameter.Any()) + .ToDictionary(parameter => WitsParameters[parameter.Key], g => g.Last().Value.ToString()); + + var dto = values.Adapt(); + dto.DateTime = items.Last().DateTime.ToOffset(timezoneOffset); + return dto; + }); return dtos; } - private static GtrWitsDto Convert(IEnumerable scr) - { - var values = scr.GroupBy(e => (e.IdRecord, e.IdItem)) - .ToDictionary(g => WitsParameters[g.Key], g => g.LastOrDefault()?.Value); - - var dto = values.Adapt(); - - return dto; - } - - private IQueryable BuildQuery(GtrRequest request) + private IQueryable BuildQuery(int idTelemetry, GtrRequest request) where TEntity : WitsItemBase where TType : notnull { - var query = db.Set().OrderBy(e => e.DateTime) - .Where(e => e.Telemetry != null && - e.Telemetry.Well != null && - e.Telemetry.Well.Id == request.IdWell) - .Where(e => e.DateTime >= DateTime.UtcNow.AddSeconds(-request.IntervalSec)); + var dateIntervalStart = DateTime.UtcNow.AddSeconds(-request.IntervalSec); + + var query = db.Set() + .Where(e => e.IdTelemetry == idTelemetry) + .Where(e => e.DateTime >= dateIntervalStart); if (request.Begin.HasValue) { @@ -118,6 +141,7 @@ namespace AsbCloudInfrastructure.Repository return query; } + [Obsolete] public async Task> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) { var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); diff --git a/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs b/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs index 17f76a33..517b98ef 100644 --- a/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs +++ b/AsbCloudWebApi.IntegrationTests/Clients/IGtrWitsClient.cs @@ -6,8 +6,8 @@ namespace AsbCloudWebApi.IntegrationTests.Clients; public interface IGtrWitsClient { - private const string BaseRoute = "/api/well/{idWell}/gtrWits"; + private const string BaseRoute = "/api/gtrWits"; [Get(BaseRoute)] - Task>> GetAllAsync(int idWell, [Query] GtrRequestBase request); + Task>> GetAllAsync(int idWell, [Query] GtrRequest request); } \ No newline at end of file diff --git a/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs b/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs index eb1e96d8..e951c13e 100644 --- a/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs +++ b/AsbCloudWebApi.IntegrationTests/Controllers/GtrControllerTests.cs @@ -26,7 +26,7 @@ public class GtrControllerTests : BaseIntegrationTest dbContext.WitsItemFloat.AddRange(witsItems); await dbContext.SaveChangesAsync(); - var request = new GtrRequestBase(); + var request = new GtrRequest(); //act var response = await client.GetAllAsync(well.Id, request); diff --git a/AsbCloudWebApi/Controllers/GtrWitsController.cs b/AsbCloudWebApi/Controllers/GtrWitsController.cs deleted file mode 100644 index 69d8a7d2..00000000 --- a/AsbCloudWebApi/Controllers/GtrWitsController.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data.GTR; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Repositories; -using AsbCloudApp.Requests; -using AsbCloudApp.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace AsbCloudWebApi.Controllers; - -[ApiController] -[Route("api/well/{idWell}/[controller]")] -[Authorize] -public class GtrWitsController : ControllerBase -{ - private readonly IWellService wellService; - private readonly IGtrRepository gtrRepository; - - public GtrWitsController(IWellService wellService, - IGtrRepository gtrRepository) - { - this.wellService = wellService; - this.gtrRepository = gtrRepository; - } - - /// - /// Получить значение от ГТИ - /// - /// - /// - /// - /// - [HttpGet] - [Permission] - [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] - public async Task GetAllAsync(int idWell, [FromQuery] GtrRequestBase request, CancellationToken token) - { - await AssertUserHasAccessToWellAsync(idWell, token); - - var requestToRepository = new GtrRequest(idWell, request); - - var dtos = await gtrRepository.GetAsync(requestToRepository, token); - - return Ok(dtos); - } - - private async Task AssertUserHasAccessToWellAsync(int idWell, CancellationToken token) - { - var idUser = User.GetUserId(); - var idCompany = User.GetCompanyId(); - - if (!idUser.HasValue) - throw new ForbidException("Нет доступа к скважине"); - - if (!idCompany.HasValue) - throw new ForbidException("Нет доступа к скважине"); - - if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token)) - throw new ForbidException("Нет доступа к скважине"); - } -} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs b/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs index 95662fe2..8f38b2ad 100644 --- a/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/GtrWitsController.cs @@ -8,7 +8,9 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Exceptions; using AsbCloudApp.Requests; +using Microsoft.AspNetCore.Http; namespace AsbCloudWebApi.Controllers.SAUB { @@ -36,6 +38,25 @@ namespace AsbCloudWebApi.Controllers.SAUB this.wellService = wellService; this.telemetryHubContext = telemetryHubContext; } + + /// + /// Получить значение от ГТИ + /// + /// + /// + /// + /// + [HttpGet] + [Permission] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + public async Task GetAllAsync(int idWell, [FromQuery] GtrRequest request, CancellationToken token) + { + await AssertUserHasAccessToWellAsync(idWell, token); + + var dtos = await gtrRepository.GetAsync(idWell, request, token); + + return Ok(dtos); + } /// /// Получить загруженные данные ГТИ по скважине @@ -114,6 +135,21 @@ namespace AsbCloudWebApi.Controllers.SAUB .SendAsync(SignalRMethodGetDataName, dtos), CancellationToken.None); return Ok(); } + + private async Task AssertUserHasAccessToWellAsync(int idWell, CancellationToken token) + { + var idUser = User.GetUserId(); + var idCompany = User.GetCompanyId(); + + if (!idUser.HasValue) + throw new ForbidException("Нет доступа к скважине"); + + if (!idCompany.HasValue) + throw new ForbidException("Нет доступа к скважине"); + + if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token)) + throw new ForbidException("Нет доступа к скважине"); + } } } From a91d4888e62503f3db0b19f0b868bd9eb84be4d4 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?= Date: Wed, 10 Apr 2024 09:09:48 +0300 Subject: [PATCH 3/3] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=D0=BE=D0=B2=20Wits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Repository/GtrWitsRepository.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs index 022532f2..57b36ef2 100644 --- a/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs +++ b/AsbCloudInfrastructure/Repository/GtrWitsRepository.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Exceptions; using AsbCloudApp.Requests; using Mapster; @@ -19,7 +20,7 @@ namespace AsbCloudInfrastructure.Repository { public class GtrWitsRepository : IGtrRepository { - private static IDictionary<(int, int), string> WitsParameters = new Dictionary<(int, int), string> + private static IDictionary<(int IdRecord, int IdItem), string> WitsParameters = new Dictionary<(int, int), string> { { (1, 8), nameof(GtrWitsDto.DEPTBITM) }, { (1, 10), nameof(GtrWitsDto.DEPTMEAS) }, @@ -90,8 +91,10 @@ namespace AsbCloudInfrastructure.Repository if (telemetry is null) return Enumerable.Empty(); - var timezone = telemetryService.GetTimezone(telemetry.Id); - var timezoneOffset = TimeSpan.FromHours(timezone.Hours); + if (telemetry.TimeZone is null) + throw new ArgumentInvalidException(nameof(idWell),$"Telemetry id: {telemetry.Id} can't find timezone"); + + var timezoneOffset = TimeSpan.FromHours(telemetry.TimeZone.Hours); var query = BuildQuery(telemetry.Id, request); @@ -100,7 +103,10 @@ namespace AsbCloudInfrastructure.Repository var interval = TimeSpan.FromSeconds(10); + var idsRecord = WitsParameters.Select(p => p.Key.IdRecord); + var entities = await query + .Where(e => idsRecord.Contains(e.IdRecord)) .OrderBy(e => e.DateTime) .AsNoTracking() .ToArrayAsync(token);