forked from ddrilling/AsbCloudServer
all changes but database and but migrations
This commit is contained in:
parent
2963d74f43
commit
64e51915c8
62
AsbCloudApp/Data/WellGroupOpertionDto.cs
Normal file
62
AsbCloudApp/Data/WellGroupOpertionDto.cs
Normal file
@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace AsbCloudApp.Data;
|
||||
#nullable enable
|
||||
/// <summary>
|
||||
/// Модель группированных операций по скважине
|
||||
/// </summary>
|
||||
public class WellGroupOpertionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id категории
|
||||
/// </summary>
|
||||
public int IdCategory { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название категории
|
||||
/// </summary>
|
||||
public string Category { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор родителя
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public int? IdParent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Количество операций
|
||||
/// </summary>
|
||||
public int Count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Суммарное время операций, мин
|
||||
/// </summary>
|
||||
public double TotalMinutes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Мин продолжительность операции, мин
|
||||
/// </summary>
|
||||
public double? MinutesMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Макс продолжительность операции, мин
|
||||
/// </summary>
|
||||
public double? MinutesMax { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Средняя продолжительность операции, мин
|
||||
/// </summary>
|
||||
public double? MinutesAverage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Общая глубина забоя
|
||||
/// </summary>
|
||||
public double DeltaDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// дочерние операции
|
||||
/// </summary>
|
||||
public IEnumerable<WellGroupOpertionDto>? Items { get; set; }
|
||||
}
|
||||
#nullable disable
|
@ -16,9 +16,9 @@ namespace AsbCloudApp.Data
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// код операции
|
||||
/// Идентификатор родительской категории
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
public int? IdParent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Название ключевого показателя операции
|
||||
|
@ -46,6 +46,30 @@ namespace AsbCloudApp.Services
|
||||
int take = 32,
|
||||
CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получить статистику операции по скважине с группировкой по категориям
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="operationType"></param>
|
||||
/// <param name="sectionTypeIds"></param>
|
||||
/// <param name="operationCategoryIds"></param>
|
||||
/// <param name="begin"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="minDepth"></param>
|
||||
/// <param name="maxDepth"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<WellGroupOpertionDto>> GetGroupOperationsStatAsync(
|
||||
int idWell,
|
||||
int? operationType = null,
|
||||
IEnumerable<int> sectionTypeIds = null,
|
||||
IEnumerable<int> operationCategoryIds = null,
|
||||
DateTime begin = default,
|
||||
DateTime end = default,
|
||||
double minDepth = double.MinValue,
|
||||
double maxDepth = double.MaxValue,
|
||||
CancellationToken token = default);
|
||||
|
||||
/// <summary>
|
||||
/// Получить операцию по id
|
||||
/// </summary>
|
||||
|
@ -89,39 +89,16 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
{
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
|
||||
var query = db.WellOperations
|
||||
.Include(s => s.WellSectionType)
|
||||
.Include(s => s.OperationCategory)
|
||||
.Where(s => s.IdWell == idWell);
|
||||
|
||||
var dateStart = query.Min(o => o.DateStart);
|
||||
|
||||
if (operationType != default)
|
||||
query = query.Where(e => e.IdType == (int)operationType);
|
||||
|
||||
if (sectionTypeIds != default && sectionTypeIds.Any())
|
||||
query = query.Where(e => sectionTypeIds.Contains(e.IdWellSectionType));
|
||||
|
||||
if (operationCategoryIds != default && operationCategoryIds.Any())
|
||||
query = query.Where(e => operationCategoryIds.Contains(e.IdCategory));
|
||||
|
||||
if (minDepth != double.MinValue)
|
||||
query = query.Where(e => e.DepthEnd >= minDepth);
|
||||
|
||||
if (maxDepth != double.MaxValue)
|
||||
query = query.Where(e => e.DepthEnd <= maxDepth);
|
||||
|
||||
if (begin != default)
|
||||
{
|
||||
var beginOffset = begin.ToUtcDateTimeOffset(timezone.Hours);
|
||||
query = query.Where(e => e.DateStart >= beginOffset);
|
||||
}
|
||||
|
||||
if (end != default)
|
||||
{
|
||||
var endOffset = end.ToUtcDateTimeOffset(timezone.Hours);
|
||||
query = query.Where(e => e.DateStart <= endOffset);
|
||||
}
|
||||
var query = BuildQuery(
|
||||
idWell,
|
||||
operationType,
|
||||
sectionTypeIds,
|
||||
operationCategoryIds,
|
||||
begin,
|
||||
end,
|
||||
minDepth,
|
||||
maxDepth,
|
||||
token);
|
||||
|
||||
var result = new PaginationContainer<WellOperationDto>
|
||||
{
|
||||
@ -129,7 +106,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
Take = take,
|
||||
Count = await query.CountAsync(token).ConfigureAwait(false),
|
||||
};
|
||||
|
||||
var dateStart = query.Min(o => o.DateStart);
|
||||
query = query
|
||||
.OrderBy(e => e.DateStart)
|
||||
.ThenBy(e => e.DepthEnd)
|
||||
@ -162,6 +139,77 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<WellGroupOpertionDto>?> GetGroupOperationsStatAsync(
|
||||
int idWell,
|
||||
int? operationType = default,
|
||||
IEnumerable<int>? sectionTypeIds = default,
|
||||
IEnumerable<int>? operationCategoryIds = default,
|
||||
DateTime begin = default,
|
||||
DateTime end = default,
|
||||
double minDepth = double.MinValue,
|
||||
double maxDepth = double.MaxValue,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var query = BuildQuery(
|
||||
idWell,
|
||||
operationType,
|
||||
sectionTypeIds,
|
||||
operationCategoryIds,
|
||||
begin,
|
||||
end,
|
||||
minDepth,
|
||||
maxDepth,
|
||||
token);
|
||||
if (query is null)
|
||||
return null;
|
||||
var entities = await query
|
||||
.Select(o => new {
|
||||
o.IdCategory,
|
||||
DurationMinutes = o.DurationHours * 60,
|
||||
DurationDepth = o.DepthEnd - o.DepthStart
|
||||
})
|
||||
.ToListAsync(token);
|
||||
var parentRelationDictionary = GetCategories()
|
||||
.ToDictionary(c => c.Id, cc => new
|
||||
{
|
||||
Name = cc.Name,
|
||||
IdParent = cc.IdParent
|
||||
});
|
||||
var dtos = entities
|
||||
.GroupBy(o => o.IdCategory)
|
||||
.Select(g => new WellGroupOpertionDto
|
||||
{
|
||||
IdCategory = g.Key,
|
||||
Category = parentRelationDictionary[g.Key].Name,
|
||||
Count = g.Count(),
|
||||
MinutesAverage = g.Average(o => o.DurationMinutes),
|
||||
MinutesMin = g.Min(o => o.DurationMinutes),
|
||||
MinutesMax = g.Max(o => o.DurationMinutes),
|
||||
TotalMinutes = g.Sum(o => o.DurationMinutes),
|
||||
DeltaDepth = g.Sum(o => o.DurationDepth),
|
||||
IdParent = parentRelationDictionary[g.Key].IdParent
|
||||
});
|
||||
var defaultId = 0;
|
||||
while (dtos.Any(x => x.IdParent != null))
|
||||
{
|
||||
defaultId--;
|
||||
dtos = dtos
|
||||
.GroupBy(o => o.IdParent)
|
||||
.Select(g => new WellGroupOpertionDto
|
||||
{
|
||||
IdCategory = g.Key.HasValue ? g.Key.Value : defaultId,
|
||||
Category = g.Key.HasValue ? parentRelationDictionary[g.Key.Value].Name : "unknown",
|
||||
Count = g.Sum(o => o.Count),
|
||||
DeltaDepth = g.Sum(o => o.DeltaDepth),
|
||||
TotalMinutes = g.Sum(o => o.TotalMinutes),
|
||||
Items = g.ToList(),
|
||||
IdParent = g.Key.HasValue ? parentRelationDictionary[g.Key.Value].IdParent : defaultId,
|
||||
|
||||
});
|
||||
}
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<WellOperationDto> GetAsync(int id,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
@ -222,6 +270,61 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
return await db.SaveChangesAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private IQueryable<WellOperation> BuildQuery(
|
||||
int idWell,
|
||||
int? operationType = default,
|
||||
IEnumerable<int> sectionTypeIds = default,
|
||||
IEnumerable<int> operationCategoryIds = default,
|
||||
DateTime begin = default,
|
||||
DateTime end = default,
|
||||
double minDepth = double.MinValue,
|
||||
double maxDepth = double.MaxValue,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var timezone = wellService.GetTimezone(idWell);
|
||||
|
||||
var query = db.WellOperations
|
||||
.Include(s => s.WellSectionType)
|
||||
.Include(s => s.OperationCategory)
|
||||
.Where(s => s.IdWell == idWell);
|
||||
|
||||
var dateStart = query.Min(o => o.DateStart);
|
||||
|
||||
if (operationType.HasValue)
|
||||
query = query.Where(e => e.IdType == operationType.Value);
|
||||
|
||||
if (sectionTypeIds != default && sectionTypeIds.Any())
|
||||
query = query.Where(e => sectionTypeIds.Contains(e.IdWellSectionType));
|
||||
|
||||
if (operationCategoryIds != default && operationCategoryIds.Any())
|
||||
query = query.Where(e => operationCategoryIds.Contains(e.IdCategory));
|
||||
|
||||
if (minDepth != double.MinValue)
|
||||
query = query.Where(e => e.DepthEnd >= minDepth);
|
||||
|
||||
if (maxDepth != double.MaxValue)
|
||||
query = query.Where(e => e.DepthEnd <= maxDepth);
|
||||
|
||||
if (begin != default)
|
||||
{
|
||||
var beginOffset = begin.ToUtcDateTimeOffset(timezone.Hours);
|
||||
query = query.Where(e => e.DateStart >= beginOffset);
|
||||
}
|
||||
|
||||
if (end != default)
|
||||
{
|
||||
var endOffset = end.ToUtcDateTimeOffset(timezone.Hours);
|
||||
query = query.Where(e => e.DateStart <= endOffset);
|
||||
}
|
||||
|
||||
query = query
|
||||
.OrderBy(e => e.DateStart)
|
||||
.ThenBy(e => e.DepthEnd)
|
||||
.ThenBy(e => e.Id);
|
||||
return query;
|
||||
|
||||
}
|
||||
}
|
||||
#nullable disable
|
||||
}
|
||||
|
@ -109,6 +109,51 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Статистика операций по скважине, группированая по категориям
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины</param>
|
||||
/// <param name="opertaionType"></param>
|
||||
/// <param name="sectionTypeIds"></param>
|
||||
/// <param name="operationCategoryIds"></param>
|
||||
/// <param name="begin"></param>
|
||||
/// <param name="end"></param>
|
||||
/// <param name="minDepth"></param>
|
||||
/// <param name="maxDepth"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Route("groupStat")]
|
||||
[Permission]
|
||||
[ProducesResponseType(typeof(IEnumerable<WellGroupOpertionDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetGroupOperationsAsync(
|
||||
[FromRoute] int idWell,
|
||||
[FromQuery] int? opertaionType = default,
|
||||
[FromQuery] IEnumerable<int> sectionTypeIds = default,
|
||||
[FromQuery] IEnumerable<int> operationCategoryIds = default,
|
||||
[FromQuery] DateTime begin = default,
|
||||
[FromQuery] DateTime end = default,
|
||||
[FromQuery] double minDepth = double.MinValue,
|
||||
[FromQuery] double maxDepth = double.MaxValue,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await operationService.GetGroupOperationsStatAsync(
|
||||
idWell,
|
||||
opertaionType,
|
||||
sectionTypeIds,
|
||||
operationCategoryIds,
|
||||
begin,
|
||||
end,
|
||||
minDepth,
|
||||
maxDepth,
|
||||
token)
|
||||
.ConfigureAwait(false);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Возвращает нужную операцию на скважине
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user