forked from ddrilling/AsbCloudServer
Merge pull request 'Наработка подсистем' (#327) from feature/#37115045-subsystems-operation-time into dev
Reviewed-on: https://test.digitaldrilling.ru:8443/DDrilling/AsbCloudServer/pulls/327 Reviewed-by: Степанов Дмитрий Александрович <da.stepanov@digitaldrilling.ru>
This commit is contained in:
commit
b92fbf690f
60
AsbCloudApp/Data/Subsystems/SubsystemStatPlanFactDto.cs
Normal file
60
AsbCloudApp/Data/Subsystems/SubsystemStatPlanFactDto.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Data.Subsystems;
|
||||
|
||||
/// <summary>
|
||||
/// Статистика плановых и фактических подсистем
|
||||
/// </summary>
|
||||
public class SubsystemPlanFactStatDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Тип секции
|
||||
/// </summary>
|
||||
public int IdWellSectionType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу от, м
|
||||
/// </summary>
|
||||
public double DepthStart { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Глубина по стволу до, м
|
||||
/// </summary>
|
||||
public double DepthEnd { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование ротора (план)
|
||||
/// </summary>
|
||||
public double AutoRotorPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование слайда (план)
|
||||
/// </summary>
|
||||
public double AutoSlidePlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование слайда с осцилляцией (план)
|
||||
/// </summary>
|
||||
public double AutoOscillationPlan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование ротора (факт)
|
||||
/// </summary>
|
||||
public double? AutoRotorFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование слайда (факт)
|
||||
/// </summary>
|
||||
public double? AutoSlideFact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Использование слайда (факт)
|
||||
/// </summary>
|
||||
public double? AutoOscillationFact { get; set; }
|
||||
}
|
@ -44,6 +44,19 @@ public class ProcessMapPlanBaseRequestWithWell : ProcessMapPlanBaseRequest
|
||||
IdWell = idWell;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <inheritdoc/>
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="gtDepth"></param>
|
||||
/// <param name="ltDepth"></param>
|
||||
public ProcessMapPlanBaseRequestWithWell(int idWell, double? gtDepth, double? ltDepth)
|
||||
{
|
||||
IdWell = idWell;
|
||||
GtDepth = gtDepth;
|
||||
LtDepth = ltDepth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Запрос для получения РТК план по скважине
|
||||
/// </summary>
|
||||
@ -59,4 +72,14 @@ public class ProcessMapPlanBaseRequestWithWell : ProcessMapPlanBaseRequest
|
||||
/// Id скважины
|
||||
/// </summary>
|
||||
public int IdWell { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Меньше глубины забоя
|
||||
/// </summary>
|
||||
public double? LtDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Больше глубине забоя
|
||||
/// </summary>
|
||||
public double? GtDepth { get; set; }
|
||||
}
|
||||
|
60
AsbCloudApp/Requests/SubsystemBaseRequest.cs
Normal file
60
AsbCloudApp/Requests/SubsystemBaseRequest.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// класс с фильтрами для запроса
|
||||
/// </summary>
|
||||
public class SubsystemBaseRequest: RequestBase, IValidatableObject
|
||||
{
|
||||
private static readonly DateTimeOffset validationMinDate = new DateTimeOffset(2020,01,01,0,0,0, TimeSpan.Zero);
|
||||
|
||||
/// <summary>
|
||||
/// Больше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset? GeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Меньше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset? LeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Больше или равно глубины забоя
|
||||
/// </summary>
|
||||
public double? GeDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Меньше или равно глубины забоя
|
||||
/// </summary>
|
||||
public double? LeDepth { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (GeDate.HasValue && GeDate < validationMinDate)
|
||||
yield return new ValidationResult(
|
||||
$"Должно быть больше {validationMinDate:O})",
|
||||
new[] { nameof(GeDate) });
|
||||
|
||||
if (LeDate.HasValue && GeDate.HasValue)
|
||||
{
|
||||
if (LeDate < GeDate)
|
||||
yield return new ValidationResult(
|
||||
$"{nameof(LeDate)} должно быть больше {nameof(GeDate)}. ({LeDate:O} < {GeDate:O})",
|
||||
new[] { nameof(LeDate), nameof(GeDate) });
|
||||
}
|
||||
|
||||
if (LeDepth.HasValue && GeDepth.HasValue)
|
||||
{
|
||||
if (LeDepth < GeDepth)
|
||||
yield return new ValidationResult(
|
||||
$"{nameof(LeDepth)} должно быть больше {nameof(GeDepth)}. ({LeDepth} < {GeDepth})",
|
||||
new[] { nameof(LeDepth), nameof(GeDepth) });
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
}
|
17
AsbCloudApp/Requests/SubsystemPlanFactRequest.cs
Normal file
17
AsbCloudApp/Requests/SubsystemPlanFactRequest.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
|
||||
namespace AsbCloudApp.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// класс с фильтрами для запроса
|
||||
/// </summary>
|
||||
public class SubsystemPlanFactRequest: SubsystemBaseRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// идентификаторы скважин
|
||||
/// </summary>
|
||||
public IEnumerable<int> IdsWell { get; set; } = Enumerable.Empty<int>();
|
||||
}
|
@ -7,10 +7,8 @@ namespace AsbCloudApp.Requests;
|
||||
/// <summary>
|
||||
/// класс с фильтрами для запроса
|
||||
/// </summary>
|
||||
public class SubsystemRequest: RequestBase, IValidatableObject
|
||||
public class SubsystemRequest: SubsystemBaseRequest
|
||||
{
|
||||
private static readonly DateTimeOffset validationMinDate = new DateTimeOffset(2020,01,01,0,0,0, TimeSpan.Zero);
|
||||
|
||||
/// <summary>
|
||||
/// идентификатор скважины
|
||||
/// </summary>
|
||||
@ -20,52 +18,5 @@ public class SubsystemRequest: RequestBase, IValidatableObject
|
||||
/// <summary>
|
||||
/// Идентификатор бурильщика
|
||||
/// </summary>
|
||||
public int? IdDriller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Больше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset? GeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Меньше или равно дате
|
||||
/// </summary>
|
||||
public DateTimeOffset? LeDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Больше или равно глубины забоя
|
||||
/// </summary>
|
||||
public double? GeDepth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Меньше или равно глубины забоя
|
||||
/// </summary>
|
||||
public double? LeDepth { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
|
||||
{
|
||||
if (GeDate.HasValue && GeDate < validationMinDate)
|
||||
yield return new ValidationResult(
|
||||
$"Должно быть больше {validationMinDate:O})",
|
||||
new[] { nameof(GeDate) });
|
||||
|
||||
if (LeDate.HasValue && GeDate.HasValue)
|
||||
{
|
||||
if (LeDate < GeDate)
|
||||
yield return new ValidationResult(
|
||||
$"{nameof(LeDate)} должно быть больше {nameof(GeDate)}. ({LeDate:O} < {GeDate:O})",
|
||||
new[] { nameof(LeDate), nameof(GeDate) });
|
||||
}
|
||||
|
||||
if (LeDepth.HasValue && GeDepth.HasValue)
|
||||
{
|
||||
if (LeDepth < GeDepth)
|
||||
yield return new ValidationResult(
|
||||
$"{nameof(LeDepth)} должно быть больше {nameof(GeDepth)}. ({LeDepth} < {GeDepth})",
|
||||
new[] { nameof(LeDepth), nameof(GeDepth) });
|
||||
}
|
||||
|
||||
yield break;
|
||||
}
|
||||
public int? IdDriller { get; set; }
|
||||
}
|
||||
|
@ -37,4 +37,12 @@ public interface ISubsystemService
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
|
||||
CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение статистики по плановым и фактическим подсистемам на скважинах
|
||||
/// </summary>
|
||||
/// <param name="request">параметры запроса</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SubsystemPlanFactStatDto>> GetStatPlanFactByWellsAsync(SubsystemPlanFactRequest request, CancellationToken token);
|
||||
}
|
@ -15,14 +15,14 @@ public interface ITelemetryDataSaubService : ITelemetryDataService<TelemetryData
|
||||
/// <summary>
|
||||
/// Получение телеметрии для РТК статистики
|
||||
/// </summary>
|
||||
/// <param name="idTelemetry"></param>
|
||||
/// <param name="idsTelemetries"></param>
|
||||
/// <param name="isBitOnBottom"></param>
|
||||
/// <param name="geDate"></param>
|
||||
/// <param name="leDate"></param>
|
||||
/// <param name="take"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<TelemetryDataSaubDto>> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token);
|
||||
Task<IEnumerable<TelemetryDataSaubDto>> Get(IEnumerable<int> idsTelemetries, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// усредненная статистика по 1м за весь период
|
||||
|
@ -33,6 +33,13 @@ public interface ITelemetryService
|
||||
/// <returns></returns>
|
||||
TelemetryDto GetOrCreateTelemetryByUid(string uid);
|
||||
|
||||
/// <summary>
|
||||
/// получить список телеметрии по ключам скважин
|
||||
/// </summary>
|
||||
/// <param name="idsWells">ключи скважин</param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells);
|
||||
|
||||
/// <summary>
|
||||
/// получить временную зону скважины по idTelemetry
|
||||
/// </summary>
|
||||
@ -47,12 +54,6 @@ public interface ITelemetryService
|
||||
/// <returns></returns>
|
||||
TelemetryBaseDto? GetOrDefaultTelemetryByIdWell(int idWell);
|
||||
|
||||
/// <summary>
|
||||
/// получить список телеметрии по ключам скважин
|
||||
/// </summary>
|
||||
/// <param name="idsWells">ключи скважин</param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells);
|
||||
/// <summary>
|
||||
/// получить диапазон дат за которые есть данные
|
||||
/// </summary>
|
||||
|
12399
AsbCloudDb/Migrations/20240918081814_Add_Permission_SubsystemStatPlanFact_get.Designer.cs
generated
Normal file
12399
AsbCloudDb/Migrations/20240918081814_Add_Permission_SubsystemStatPlanFact_get.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class Add_Permission_SubsystemStatPlanFact_get : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_permission",
|
||||
columns: new[] { "id", "description", "name" },
|
||||
values: new object[] { 534, "Разрешение просматривать статистику по плановым и фактическим подсистемам на скважинах", "SubsystemStatPlanFact.get" });
|
||||
|
||||
migrationBuilder.InsertData(
|
||||
table: "t_relation_user_role_permission",
|
||||
columns: new[] { "id_permission", "id_user_role" },
|
||||
values: new object[] { 534, 1 });
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_relation_user_role_permission",
|
||||
keyColumns: new[] { "id_permission", "id_user_role" },
|
||||
keyValues: new object[] { 534, 1 });
|
||||
|
||||
migrationBuilder.DeleteData(
|
||||
table: "t_permission",
|
||||
keyColumn: "id",
|
||||
keyValue: 534);
|
||||
}
|
||||
}
|
||||
}
|
@ -2638,6 +2638,12 @@ namespace AsbCloudDb.Migrations
|
||||
Id = 533,
|
||||
Description = "Разрешение просматривать критические сообщения",
|
||||
Name = "CriticalMessage.get"
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 534,
|
||||
Description = "Разрешение просматривать статистику по плановым и фактическим подсистемам на скважинах",
|
||||
Name = "SubsystemStatPlanFact.get"
|
||||
});
|
||||
});
|
||||
|
||||
@ -6388,6 +6394,11 @@ namespace AsbCloudDb.Migrations
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 533
|
||||
},
|
||||
new
|
||||
{
|
||||
IdUserRole = 1,
|
||||
IdPermission = 534
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -166,7 +166,8 @@ namespace AsbCloudDb.Model.DefaultData
|
||||
new() { Id = 531, Name = "WellSectionPlan.delete", Description = "Разрешение на удаление плановой конструкции скважины"},
|
||||
|
||||
new() { Id = 532, Name = "Version.get", Description = "Разрешение просматривать информацию о телеметрии"},
|
||||
new() { Id = 533, Name = "CriticalMessage.get", Description = "Разрешение просматривать критические сообщения"}
|
||||
new() { Id = 533, Name = "CriticalMessage.get", Description = "Разрешение просматривать критические сообщения"},
|
||||
new() { Id = 534, Name = "SubsystemStatPlanFact.get", Description = "Разрешение просматривать статистику по плановым и фактическим подсистемам на скважинах"},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ public class DataSaubStatServiceTest
|
||||
}
|
||||
|
||||
dataSaubServiceMock
|
||||
.Get(Arg.Any<int>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Get(Arg.Any<IEnumerable<int>>(), Arg.Any<bool>(), Arg.Any<DateTimeOffset>(), Arg.Any<DateTimeOffset>(), Arg.Any<int>(), Arg.Any<CancellationToken>())
|
||||
.Returns(telemetryDataSaubDtos);
|
||||
|
||||
dataSaubStatService = new DataSaubStatService(
|
||||
|
@ -309,7 +309,6 @@ public static class DependencyInjection
|
||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||
services.AddTransient<ISubsystemService, SubsystemService>();
|
||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
|
||||
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
|
||||
@ -488,6 +487,9 @@ public static class DependencyInjection
|
||||
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
|
||||
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
|
||||
|
||||
// Subsystem service
|
||||
services.AddTransient<ISubsystemService, SubsystemService>();
|
||||
|
||||
// Wits
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
|
||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record7Dto, AsbCloudDb.Model.WITS.Record7>>();
|
||||
|
@ -34,6 +34,16 @@ public class ProcessMapPlanBaseRepository<TEntity, TDto> : ChangeLogRepositoryAb
|
||||
query = query.Where(e => e.Creation >= from || e.Obsolete >= from);
|
||||
}
|
||||
|
||||
if (request.GtDepth.HasValue)
|
||||
{
|
||||
query = query.Where(e => e.DepthEnd > request.GtDepth);
|
||||
}
|
||||
|
||||
if (request.LtDepth.HasValue)
|
||||
{
|
||||
query = query.Where(e => e.DepthStart < request.LtDepth);
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class DataSaubStatService : IDataSaubStatService
|
||||
var geDate = detectedOperations.First().DateStart;
|
||||
var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd;
|
||||
|
||||
var dataSaub = await dataSaubService.Get(idTelemetry, true, geDate, leDate, 100_000, token);
|
||||
var dataSaub = await dataSaubService.Get([idTelemetry], true, geDate, leDate, 100_000, token);
|
||||
|
||||
if (!dataSaub.Any())
|
||||
return 0;
|
||||
|
@ -37,14 +37,19 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
||||
this.telemetryUserService = telemetryUserService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<TelemetryDataSaubDto>> Get(int idTelemetry, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token)
|
||||
public async Task<IEnumerable<TelemetryDataSaubDto>> Get(IEnumerable<int> idsTelemetries, bool isBitOnBottom, DateTimeOffset geDate, DateTimeOffset leDate, int take, CancellationToken token)
|
||||
{
|
||||
var offset = telemetryService.GetTimezone(idTelemetry).Offset;
|
||||
var offsetDict = new Dictionary<int, TimeSpan>();
|
||||
foreach (var idTelemetry in idsTelemetries)
|
||||
{
|
||||
offsetDict.Add(idTelemetry, telemetryService.GetTimezone(idTelemetry).Offset);
|
||||
}
|
||||
|
||||
var geDateUtc = geDate.ToUniversalTime();
|
||||
var leDateUtc = leDate.ToUniversalTime();
|
||||
|
||||
var query = db.Set<TelemetryDataSaub>()
|
||||
.Where(t => t.IdTelemetry == idTelemetry)
|
||||
.Where(t => idsTelemetries.Contains(t.IdTelemetry))
|
||||
.Where(t => t.DateTime >= geDateUtc)
|
||||
.Where(t => t.DateTime <= leDateUtc);
|
||||
|
||||
@ -56,7 +61,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
||||
.Take(take);
|
||||
|
||||
var entities = await query.ToArrayAsync(token);
|
||||
var dtos = entities.Select(e => Convert(e, offset.TotalHours));
|
||||
var dtos = entities.Select(e => Convert(e, offsetDict.GetValueOrDefault(e.IdTelemetry).TotalHours));
|
||||
return dtos;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ public class TelemetryService : ITelemetryService
|
||||
private IEnumerable<Telemetry> GetTelemetryCache()
|
||||
=> memoryCache.GetOrCreateBasic(
|
||||
db.Set<Telemetry>()
|
||||
.Include(t => t.Well));
|
||||
.Include(t => t.Well));
|
||||
|
||||
private void DropTelemetryCache()
|
||||
{
|
||||
|
@ -1,20 +1,22 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.ProcessMaps;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Repositories;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Data.DetectedOperation;
|
||||
using AsbCloudApp.Data.Subsystems;
|
||||
using AsbCloudApp.Exceptions;
|
||||
using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.DetectOperations;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.Subsystems;
|
||||
|
||||
internal class SubsystemService : ISubsystemService
|
||||
public class SubsystemService : ISubsystemService
|
||||
{
|
||||
private const int IdSubsystemAPD = 1;
|
||||
private const int IdSubsystemAPDRotor = 11;
|
||||
@ -26,18 +28,27 @@ internal class SubsystemService : ISubsystemService
|
||||
private readonly IWellService wellService;
|
||||
private readonly IDetectedOperationService detectedOperationService;
|
||||
private readonly IScheduleRepository scheduleRepository;
|
||||
private readonly ITelemetryDataSaubService telemetryDataSaubService;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly IChangeLogRepository<ProcessMapPlanSubsystemsDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepository;
|
||||
|
||||
private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>();
|
||||
|
||||
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
||||
IWellService wellService,
|
||||
IDetectedOperationService detectedOperationService,
|
||||
IScheduleRepository scheduleRepository)
|
||||
IScheduleRepository scheduleRepository,
|
||||
ITelemetryService telemetryService,
|
||||
ITelemetryDataSaubService telemetryDataSaubService,
|
||||
IChangeLogRepository<ProcessMapPlanSubsystemsDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepository)
|
||||
{
|
||||
this.wellService = wellService;
|
||||
this.subsystemRepository = subsystemRepository;
|
||||
this.detectedOperationService = detectedOperationService;
|
||||
this.scheduleRepository = scheduleRepository;
|
||||
this.telemetryService = telemetryService;
|
||||
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||
this.processMapPlanRepository = processMapPlanRepository;
|
||||
}
|
||||
|
||||
// получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод
|
||||
@ -57,11 +68,11 @@ internal class SubsystemService : ISubsystemService
|
||||
var result = new List<DrillerDetectedOperationStatDto>();
|
||||
var schedulePage = await scheduleRepository.GetPageAsync(request, token);
|
||||
var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token);
|
||||
|
||||
|
||||
foreach (var schedule in schedulePage)
|
||||
{
|
||||
var idWell = schedule.IdWell;
|
||||
var well = wells.FirstOrDefault(w=> w.Id == idWell)!;
|
||||
var well = wells.FirstOrDefault(w => w.Id == idWell)!;
|
||||
|
||||
var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest());
|
||||
|
||||
@ -124,6 +135,70 @@ internal class SubsystemService : ISubsystemService
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SubsystemPlanFactStatDto>> GetStatPlanFactByWellsAsync(SubsystemPlanFactRequest request, CancellationToken token)
|
||||
{
|
||||
var telemetriesDict = telemetryService
|
||||
.GetOrDefaultTelemetriesByIdsWells(request.IdsWell)
|
||||
.ToDictionary(t => t.Id, t => t.IdWell);
|
||||
|
||||
var dtNow = DateTimeOffset.UtcNow;
|
||||
var geDate = request.GeDate ?? new DateTimeOffset(dtNow.Date);
|
||||
var leDate = request.LeDate ?? geDate.AddDays(1).AddMinutes(-1);
|
||||
var telemetryDataSaub = await telemetryDataSaubService.Get(telemetriesDict.Keys, false, geDate, leDate, 100_000, token);
|
||||
|
||||
var groupedTelemetryDataSaub = telemetryDataSaub
|
||||
.GroupBy(t => t.IdTelemetry)
|
||||
.ToDictionary(t => t.Key, t => new
|
||||
{
|
||||
IdWell = telemetriesDict.GetValueOrDefault(t.Key)!,
|
||||
MinDepth = t.MinBy(x => x.WellDepth)!.WellDepth,
|
||||
MaxDepth = t.MaxBy(x => x.WellDepth)!.WellDepth
|
||||
});
|
||||
|
||||
var result = new List<SubsystemPlanFactStatDto>();
|
||||
|
||||
foreach (var telemetryDataSaubItem in groupedTelemetryDataSaub)
|
||||
{
|
||||
var telemetryDataSaubInfo = telemetryDataSaubItem.Value;
|
||||
var requestProcessMapPlan = new ProcessMapPlanBaseRequestWithWell(telemetryDataSaubInfo.IdWell!.Value, telemetryDataSaubInfo.MinDepth, telemetryDataSaubInfo.MaxDepth);
|
||||
var processMapPlanSubsystems = await processMapPlanRepository.GetCurrent(requestProcessMapPlan, token);
|
||||
|
||||
foreach (var processMapPlanSubsystem in processMapPlanSubsystems)
|
||||
{
|
||||
var stat = new SubsystemPlanFactStatDto();
|
||||
stat.IdWell = processMapPlanSubsystem.IdWell;
|
||||
stat.IdWellSectionType = processMapPlanSubsystem.IdWellSectionType;
|
||||
stat.DepthStart = processMapPlanSubsystem.DepthStart < telemetryDataSaubInfo.MinDepth
|
||||
? telemetryDataSaubInfo.MinDepth
|
||||
: processMapPlanSubsystem.DepthStart;
|
||||
stat.DepthEnd = processMapPlanSubsystem.DepthEnd > telemetryDataSaubInfo.MaxDepth
|
||||
? telemetryDataSaubInfo.MaxDepth
|
||||
: processMapPlanSubsystem.DepthEnd;
|
||||
stat.AutoRotorPlan = processMapPlanSubsystem.AutoRotor;
|
||||
stat.AutoSlidePlan = processMapPlanSubsystem.AutoSlide;
|
||||
stat.AutoOscillationPlan = processMapPlanSubsystem.AutoOscillation;
|
||||
|
||||
var subsystemRequest = new SubsystemRequest()
|
||||
{
|
||||
IdWell = telemetriesDict.GetValueOrDefault(telemetryDataSaubItem.Key)!.Value,
|
||||
GeDepth = stat.DepthStart,
|
||||
LeDepth = stat.DepthEnd
|
||||
};
|
||||
var subsystemStatFact = await GetStatAsync(subsystemRequest, token);
|
||||
var subsystemStatFactDict = subsystemStatFact.ToDictionary(s => s.IdSubsystem);
|
||||
|
||||
stat.AutoRotorFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemAPDRotor)?.KUsage;
|
||||
stat.AutoSlideFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemAPDSlide)?.KUsage;
|
||||
stat.AutoOscillationFact = subsystemStatFactDict.GetValueOrDefault(IdSubsystemOscillation)?.KUsage;
|
||||
|
||||
result.Add(stat);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(
|
||||
IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
|
||||
{
|
||||
@ -157,7 +232,7 @@ internal class SubsystemService : ISubsystemService
|
||||
SumDepthInterval = sumDepthInterval,
|
||||
OperationCount = operationCount,
|
||||
};
|
||||
if(oscillationStat.SumOperationDepthInterval != 0d)
|
||||
if (oscillationStat.SumOperationDepthInterval != 0d)
|
||||
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
|
||||
|
||||
return oscillationStat;
|
||||
|
@ -80,6 +80,24 @@ public class SubsystemController : ControllerBase
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// получить статистику по плановым и фактическим подсистемам на скважинах
|
||||
/// </summary>
|
||||
[HttpGet("/api/serviceWork/subsystemWells")]
|
||||
[Permission("SubsystemStatPlanFact.get")]
|
||||
[ProducesResponseType(typeof(IEnumerable<SubsystemPlanFactStatDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetStatPlanFactAsync([FromQuery] SubsystemPlanFactRequest request, CancellationToken token)
|
||||
{
|
||||
foreach (var idWell in request.IdsWell)
|
||||
{
|
||||
if (!await UserHasAccessToWellAsync(idWell, token))
|
||||
return Forbid();
|
||||
}
|
||||
var subsystemStat = await subsystemService.GetStatPlanFactByWellsAsync(request, token);
|
||||
|
||||
return Ok(subsystemStat);
|
||||
}
|
||||
|
||||
private async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var idCompany = User.GetCompanyId();
|
||||
|
Loading…
Reference in New Issue
Block a user