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

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; namespace AsbCloudApp.Data.GTR;
/// <summary>
/// ГТИ
/// </summary>
public class GtrWitsDto 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>
/// Вес на крюке /// Вес на крюке
/// </summary> /// </summary>

View File

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

View File

@ -5,7 +5,7 @@ namespace AsbCloudApp.Requests;
/// <summary> /// <summary>
/// Параметры запроса для получения загруженных данных ГТИ по скважине /// Параметры запроса для получения загруженных данных ГТИ по скважине
/// </summary> /// </summary>
public class GtrRequestBase public class GtrRequest
{ {
/// <summary> /// <summary>
/// Дата начала выборки.По умолчанию: текущее время - IntervalSec /// Дата начала выборки.По умолчанию: текущее время - IntervalSec
@ -23,19 +23,3 @@ public class GtrRequestBase
[Obsolete] [Obsolete]
public int ApproxPointsCount { get; set; } = 1024; 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> 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, 14), nameof(GtrWitsDto.HKLA) },
{ (1, 12), nameof(GtrWitsDto.BLKPOS) }, { (1, 12), nameof(GtrWitsDto.BLKPOS) },
{ (1, 16), nameof(GtrWitsDto.WOBA) }, { (1, 16), nameof(GtrWitsDto.WOBA) },
@ -76,38 +78,59 @@ namespace AsbCloudInfrastructure.Repository
this.telemetryService = telemetryService; 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 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 interval = TimeSpan.FromSeconds(10);
var query = BuildQuery<WitsItemFloat, float>(request);
var entities = await query.AsNoTracking().ToArrayAsync(token); var entities = await query
.OrderBy(e => e.DateTime)
.AsNoTracking()
.ToArrayAsync(token);
var dtos = entities var dtos = entities
.GroupBy(e => e.DateTime.Ticks / interval.Ticks) .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; return dtos;
} }
private static GtrWitsDto Convert(IEnumerable<WitsItemFloat> scr) private IQueryable<TEntity> BuildQuery<TEntity, TType>(int idTelemetry, GtrRequest request)
{
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)
where TEntity : WitsItemBase<TType> where TEntity : WitsItemBase<TType>
where TType : notnull where TType : notnull
{ {
var query = db.Set<TEntity>().OrderBy(e => e.DateTime) var dateIntervalStart = DateTime.UtcNow.AddSeconds(-request.IntervalSec);
.Where(e => e.Telemetry != null &&
e.Telemetry.Well != null && var query = db.Set<TEntity>()
e.Telemetry.Well.Id == request.IdWell) .Where(e => e.IdTelemetry == idTelemetry)
.Where(e => e.DateTime >= DateTime.UtcNow.AddSeconds(-request.IntervalSec)); .Where(e => e.DateTime >= dateIntervalStart);
if (request.Begin.HasValue) if (request.Begin.HasValue)
{ {
@ -118,6 +141,7 @@ namespace AsbCloudInfrastructure.Repository
return query; return query;
} }
[Obsolete]
public async Task<IEnumerable<WitsRecordDto>> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default) public async Task<IEnumerable<WitsRecordDto>> GetAsync(int idWell, DateTime? dateBegin, double intervalSec = 600, int approxPointsCount = 1024, CancellationToken token = default)
{ {
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);

View File

@ -6,8 +6,8 @@ namespace AsbCloudWebApi.IntegrationTests.Clients;
public interface IGtrWitsClient public interface IGtrWitsClient
{ {
private const string BaseRoute = "/api/well/{idWell}/gtrWits"; private const string BaseRoute = "/api/gtrWits";
[Get(BaseRoute)] [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); dbContext.WitsItemFloat.AddRange(witsItems);
await dbContext.SaveChangesAsync(); await dbContext.SaveChangesAsync();
var request = new GtrRequestBase(); var request = new GtrRequest();
//act //act
var response = await client.GetAllAsync(well.Id, request); 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.ComponentModel.DataAnnotations;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Requests; using AsbCloudApp.Requests;
using Microsoft.AspNetCore.Http;
namespace AsbCloudWebApi.Controllers.SAUB namespace AsbCloudWebApi.Controllers.SAUB
{ {
@ -37,6 +39,25 @@ namespace AsbCloudWebApi.Controllers.SAUB
this.telemetryHubContext = telemetryHubContext; 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> /// <summary>
/// Получить загруженные данные ГТИ по скважине /// Получить загруженные данные ГТИ по скважине
/// </summary> /// </summary>
@ -114,6 +135,21 @@ namespace AsbCloudWebApi.Controllers.SAUB
.SendAsync(SignalRMethodGetDataName, dtos), CancellationToken.None); .SendAsync(SignalRMethodGetDataName, dtos), CancellationToken.None);
return Ok(); 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("Нет доступа к скважине");
}
} }
} }