Правки после ревью

This commit is contained in:
Степанов Дмитрий 2024-04-08 14:32:00 +03:00
parent c4bb5f9040
commit 979ed91e78
8 changed files with 108 additions and 108 deletions

View File

@ -1,7 +1,27 @@
using System;
namespace AsbCloudApp.Data.GTR;
/// <summary>
/// ГТИ
/// </summary>
public class GtrWitsDto
{
/// <summary>
/// Дата получения записи
/// </summary>
public DateTimeOffset DateTime { get; set; }
/// <summary>
/// Забой (скважины), м
/// </summary>
public float? DEPTMEAS { get; set; }
/// <summary>
/// Долото, м
/// </summary>
public float DEPTBITM { get; set; }
/// <summary>
/// Вес на крюке
/// </summary>

View File

@ -24,10 +24,11 @@ namespace AsbCloudApp.Repositories
/// <summary>
/// получить данные ГТИ
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<GtrWitsDto>> GetAsync(GtrRequest request, CancellationToken token);
Task<IEnumerable<GtrWitsDto>> GetAsync(int idWell, GtrRequest request, CancellationToken token);
/// <summary>
/// получить данные для клиента

View File

@ -5,7 +5,7 @@ namespace AsbCloudApp.Requests;
/// <summary>
/// Параметры запроса для получения загруженных данных ГТИ по скважине
/// </summary>
public class GtrRequestBase
public class GtrRequest
{
/// <summary>
/// Дата начала выборки.По умолчанию: текущее время - IntervalSec
@ -22,20 +22,4 @@ public class GtrRequestBase
/// </summary>
[Obsolete]
public int ApproxPointsCount { get; set; } = 1024;
}
/// <summary>
/// Параметры запроса для получения загруженных данных ГТИ по скважине
/// </summary>
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; }
}

View File

@ -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<IEnumerable<GtrWitsDto>> GetAsync(GtrRequest request, CancellationToken token)
public async Task<IEnumerable<GtrWitsDto>> GetAsync(int idWell, GtrRequest request, CancellationToken token) =>
await GetAsync<WitsItemFloat, float>(idWell, request, token);
private async Task<IEnumerable<GtrWitsDto>> GetAsync<TEntity, TType>(int idWell, GtrRequest request, CancellationToken token)
where TEntity : WitsItemBase<TType>
where TType : notnull
{
var interval = TimeSpan.FromSeconds(10);
var query = BuildQuery<WitsItemFloat, float>(request);
var entities = await query.AsNoTracking().ToArrayAsync(token);
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
if (telemetry is null)
return Enumerable.Empty<GtrWitsDto>();
var timezone = telemetryService.GetTimezone(telemetry.Id);
var timezoneOffset = TimeSpan.FromHours(timezone.Hours);
var query = BuildQuery<TEntity, TType>(telemetry.Id, request);
if (!await query.AnyAsync(token))
return Enumerable.Empty<GtrWitsDto>();
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<GtrWitsDto>();
dto.DateTime = items.Last().DateTime.ToOffset(timezoneOffset);
return dto;
});
return dtos;
}
private static GtrWitsDto Convert(IEnumerable<WitsItemFloat> scr)
{
var values = scr.GroupBy(e => (e.IdRecord, e.IdItem))
.ToDictionary(g => WitsParameters[g.Key], g => g.LastOrDefault()?.Value);
var dto = values.Adapt<GtrWitsDto>();
return dto;
}
private IQueryable<TEntity> BuildQuery<TEntity, TType>(GtrRequest request)
private IQueryable<TEntity> BuildQuery<TEntity, TType>(int idTelemetry, GtrRequest request)
where TEntity : WitsItemBase<TType>
where TType : notnull
{
var query = db.Set<TEntity>().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<TEntity>()
.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<IEnumerable<WitsRecordDto>> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
{
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);

View File

@ -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<IApiResponse<IEnumerable<GtrWitsDto>>> GetAllAsync(int idWell, [Query] GtrRequestBase request);
Task<IApiResponse<IEnumerable<GtrWitsDto>>> GetAllAsync(int idWell, [Query] GtrRequest request);
}

View File

@ -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);

View File

@ -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;
}
/// <summary>
/// Получить значение от ГТИ
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet]
[Permission]
[ProducesResponseType(typeof(IEnumerable<GtrWitsDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> 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("Нет доступа к скважине");
}
}

View File

@ -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;
}
/// <summary>
/// Получить значение от ГТИ
/// </summary>
/// <param name="idWell"></param>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet]
[Permission]
[ProducesResponseType(typeof(IEnumerable<GtrWitsDto>), StatusCodes.Status200OK)]
public async Task<IActionResult> GetAllAsync(int idWell, [FromQuery] GtrRequest request, CancellationToken token)
{
await AssertUserHasAccessToWellAsync(idWell, token);
var dtos = await gtrRepository.GetAsync(idWell, request, token);
return Ok(dtos);
}
/// <summary>
/// Получить загруженные данные ГТИ по скважине
@ -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("Нет доступа к скважине");
}
}
}