Merge branch 'dev' into feature/ban_adding_data

This commit is contained in:
ngfrolov 2023-09-13 10:32:15 +05:00
commit 3f92a91913
Signed by: ng.frolov
GPG Key ID: E99907A0357B29A7
8 changed files with 232 additions and 21 deletions

View File

@ -0,0 +1,59 @@
using System;
using System.ComponentModel.DataAnnotations;
namespace AsbCloudApp.Requests;
/// <summary>
/// Параметры запроса телеметрии
/// </summary>
public class TelemetryDataRequest
{
/// <summary>
/// Максимально допустимое кол-во строк данных
/// </summary>
public const int MaxTake = 3072;
/// <summary>
/// greater or equal then Date
/// </summary>
public DateTimeOffset? GeDate { get; set; }
/// <summary>
/// less or equal then Date
/// </summary>
public DateTimeOffset? LeDate { get; set; }
/// <summary>
/// Делитель для прореживания выборки.
/// <list type="bullet">
/// <item>1 - без прореживания (default); </item>
/// <item>2 - каждое 2-е значение; </item>
/// <item>10 - каждое 10-е значение; </item>
/// </list>
/// </summary>
[Range(0, 300)]
public int Divider { get; set; } = 1;
/// <summary>
/// сортировка/выравнивание данных в запросе по дате
/// <list type="bullet">
/// <item>0 - более ранние данные вперед; </item>
/// <item>1 - более поздние данные вперед; </item>
/// </list>
/// </summary>
[Range(0, 1)]
public int Order { get; set; } = 0;
/// <summary>
/// Пропустить с начала
/// </summary>
[Range(0, int.MaxValue)]
public int Skip { get; set; } = 0;
/// <summary>
/// Кол-во возвращаемых, но не больше MaxTake
/// </summary>
[Range(1, MaxTake)]
public int Take { get; set; } = 1024;
}

View File

@ -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<IEnumerable<TDto>> GetAsync(int idWell,
DateTime dateBegin = default, double intervalSec = 600d,
int approxPointsCount = 1024, CancellationToken token = default);
Task<IEnumerable<TDto>> GetAsync(int idWell, TelemetryDataRequest request, CancellationToken token);
/// <summary>
/// Получение статистики за период

View File

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

View File

@ -1,4 +1,5 @@
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Services;
using AsbCloudDb;
using AsbCloudDb.Model;
@ -137,10 +138,67 @@ 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;
}
/// <inheritdoc/>
public virtual async Task<IEnumerable<TDto>> GetAsync(int idWell, AsbCloudApp.Requests.TelemetryDataRequest request, CancellationToken token)
{
var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell);
if (telemetry is null)
return Enumerable.Empty<TDto>();
var timezone = telemetryService.GetTimezone(telemetry.Id);
var cache = telemetryDataCache.GetOrDefault(telemetry.Id, request);
if(cache is not null)
return cache;
var dbSet = db.Set<TEntity>();
var query = dbSet
.Where(d => d.IdTelemetry == telemetry.Id)
.AsNoTracking();
if (request.GeDate.HasValue)
{
var geDate = request.GeDate.Value.UtcDateTime;
query = query.Where(d => d.DateTime >= geDate);
}
if (request.LeDate.HasValue)
{
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);
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));

View File

@ -11,6 +11,7 @@ using Microsoft.Extensions.DependencyInjection;
using AsbCloudInfrastructure.Background;
using System.Threading;
using AsbCloudApp.Data;
using AsbCloudApp.Requests;
namespace AsbCloudInfrastructure.Services.SAUB
{
@ -21,6 +22,7 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
public TDto? FirstByDate { get; init; }
public CyclycArray<TDto> LastData { get; init; } = null!;
public double TimezoneHours { get; init; } = 5;
}
private IServiceProvider provider = null!;
@ -225,8 +227,62 @@ namespace AsbCloudInfrastructure.Services.SAUB
{
FirstByDate = first,
LastData = cacheItem,
TimezoneHours = hoursOffset,
};
return item;
}
public IEnumerable<TDto>? GetOrDefault(int idTelemetry, TelemetryDataRequest request)
{
if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem))
return null;
IEnumerable<TDto> data = cacheItem.LastData;
if (!data.Any())
return null;
if (request.GeDate.HasValue)
{
var geDate = request.GeDate.Value.ToRemoteDateTime(cacheItem.TimezoneHours);
if (data.First().DateTime > geDate)
return null;
data = data.Where(d => d.DateTime >= geDate);
}
else
{
if (request.Order == 0)
return null;
}
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);
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;
}
}
}

View File

@ -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<CompanyDto>(),
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<CompanyDto>(),
Email = u.Email,
Phone = u.Phone,
Position = u.Position,
IsContact = u.RelationContactsWells.Any(rel => rel.IdWell == wellId)
})
});
var entities = await query.AsNoTracking()

View File

@ -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<WellWithTimezoneDto>(),
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),
});

View File

@ -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);
}
/// <summary>
/// Новая версия. Возвращает данные САУБ по скважине.
/// По умолчанию за последние 10 минут.
/// </summary>
/// <param name="idWell">id скважины</param>
/// <param name="request"></param>
/// <param name="token">Токен завершения задачи</param>
/// <returns></returns>
[HttpGet("{idWell}/data")]
[Permission]
public virtual async Task<ActionResult<IEnumerable<TDto>>> 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);
}
/// <summary>
/// Возвращает диапазон дат за которые есть телеметрия за период времени
/// </summary>