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; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// код операции
|
/// Идентификатор родительской категории
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Code { get; set; }
|
public int? IdParent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Название ключевого показателя операции
|
/// Название ключевого показателя операции
|
||||||
|
@ -46,6 +46,30 @@ namespace AsbCloudApp.Services
|
|||||||
int take = 32,
|
int take = 32,
|
||||||
CancellationToken token = default);
|
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>
|
/// <summary>
|
||||||
/// Получить операцию по id
|
/// Получить операцию по id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -89,39 +89,16 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
{
|
{
|
||||||
var timezone = wellService.GetTimezone(idWell);
|
var timezone = wellService.GetTimezone(idWell);
|
||||||
|
|
||||||
var query = db.WellOperations
|
var query = BuildQuery(
|
||||||
.Include(s => s.WellSectionType)
|
idWell,
|
||||||
.Include(s => s.OperationCategory)
|
operationType,
|
||||||
.Where(s => s.IdWell == idWell);
|
sectionTypeIds,
|
||||||
|
operationCategoryIds,
|
||||||
var dateStart = query.Min(o => o.DateStart);
|
begin,
|
||||||
|
end,
|
||||||
if (operationType != default)
|
minDepth,
|
||||||
query = query.Where(e => e.IdType == (int)operationType);
|
maxDepth,
|
||||||
|
token);
|
||||||
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 result = new PaginationContainer<WellOperationDto>
|
var result = new PaginationContainer<WellOperationDto>
|
||||||
{
|
{
|
||||||
@ -129,7 +106,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
Take = take,
|
Take = take,
|
||||||
Count = await query.CountAsync(token).ConfigureAwait(false),
|
Count = await query.CountAsync(token).ConfigureAwait(false),
|
||||||
};
|
};
|
||||||
|
var dateStart = query.Min(o => o.DateStart);
|
||||||
query = query
|
query = query
|
||||||
.OrderBy(e => e.DateStart)
|
.OrderBy(e => e.DateStart)
|
||||||
.ThenBy(e => e.DepthEnd)
|
.ThenBy(e => e.DepthEnd)
|
||||||
@ -162,6 +139,77 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
return result;
|
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,
|
public async Task<WellOperationDto> GetAsync(int id,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
@ -222,6 +270,61 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
|||||||
return await db.SaveChangesAsync(token)
|
return await db.SaveChangesAsync(token)
|
||||||
.ConfigureAwait(false);
|
.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
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,51 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return Ok(result);
|
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>
|
||||||
/// Возвращает нужную операцию на скважине
|
/// Возвращает нужную операцию на скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user