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;
|
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>
|
||||||
/// Запрос для получения РТК план по скважине
|
/// Запрос для получения РТК план по скважине
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -59,4 +72,14 @@ public class ProcessMapPlanBaseRequestWithWell : ProcessMapPlanBaseRequest
|
|||||||
/// Id скважины
|
/// Id скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int IdWell { get; set; }
|
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>
|
||||||
/// класс с фильтрами для запроса
|
/// класс с фильтрами для запроса
|
||||||
/// </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>
|
||||||
/// идентификатор скважины
|
/// идентификатор скважины
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -20,52 +18,5 @@ public class SubsystemRequest: RequestBase, IValidatableObject
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Идентификатор бурильщика
|
/// Идентификатор бурильщика
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int? IdDriller { get; set; }
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,4 +37,12 @@ public interface ISubsystemService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
|
Task<IEnumerable<DrillerDetectedOperationStatDto>> GetByWellsAsync(GetStatRequest request,
|
||||||
CancellationToken token);
|
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>
|
||||||
/// Получение телеметрии для РТК статистики
|
/// Получение телеметрии для РТК статистики
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="idTelemetry"></param>
|
/// <param name="idsTelemetries"></param>
|
||||||
/// <param name="isBitOnBottom"></param>
|
/// <param name="isBitOnBottom"></param>
|
||||||
/// <param name="geDate"></param>
|
/// <param name="geDate"></param>
|
||||||
/// <param name="leDate"></param>
|
/// <param name="leDate"></param>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <param name="token"></param>
|
/// <param name="token"></param>
|
||||||
/// <returns></returns>
|
/// <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>
|
/// <summary>
|
||||||
/// усредненная статистика по 1м за весь период
|
/// усредненная статистика по 1м за весь период
|
||||||
|
@ -33,6 +33,13 @@ public interface ITelemetryService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
TelemetryDto GetOrCreateTelemetryByUid(string uid);
|
TelemetryDto GetOrCreateTelemetryByUid(string uid);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// получить список телеметрии по ключам скважин
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="idsWells">ключи скважин</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить временную зону скважины по idTelemetry
|
/// получить временную зону скважины по idTelemetry
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -47,12 +54,6 @@ public interface ITelemetryService
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
TelemetryBaseDto? GetOrDefaultTelemetryByIdWell(int idWell);
|
TelemetryBaseDto? GetOrDefaultTelemetryByIdWell(int idWell);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// получить список телеметрии по ключам скважин
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="idsWells">ключи скважин</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
IEnumerable<TelemetryDto> GetOrDefaultTelemetriesByIdsWells(IEnumerable<int> idsWells);
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// получить диапазон дат за которые есть данные
|
/// получить диапазон дат за которые есть данные
|
||||||
/// </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,
|
Id = 533,
|
||||||
Description = "Разрешение просматривать критические сообщения",
|
Description = "Разрешение просматривать критические сообщения",
|
||||||
Name = "CriticalMessage.get"
|
Name = "CriticalMessage.get"
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
Id = 534,
|
||||||
|
Description = "Разрешение просматривать статистику по плановым и фактическим подсистемам на скважинах",
|
||||||
|
Name = "SubsystemStatPlanFact.get"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -6388,6 +6394,11 @@ namespace AsbCloudDb.Migrations
|
|||||||
{
|
{
|
||||||
IdUserRole = 1,
|
IdUserRole = 1,
|
||||||
IdPermission = 533
|
IdPermission = 533
|
||||||
|
},
|
||||||
|
new
|
||||||
|
{
|
||||||
|
IdUserRole = 1,
|
||||||
|
IdPermission = 534
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -166,7 +166,8 @@ namespace AsbCloudDb.Model.DefaultData
|
|||||||
new() { Id = 531, Name = "WellSectionPlan.delete", Description = "Разрешение на удаление плановой конструкции скважины"},
|
new() { Id = 531, Name = "WellSectionPlan.delete", Description = "Разрешение на удаление плановой конструкции скважины"},
|
||||||
|
|
||||||
new() { Id = 532, Name = "Version.get", 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
|
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);
|
.Returns(telemetryDataSaubDtos);
|
||||||
|
|
||||||
dataSaubStatService = new DataSaubStatService(
|
dataSaubStatService = new DataSaubStatService(
|
||||||
|
@ -309,7 +309,6 @@ public static class DependencyInjection
|
|||||||
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
services.AddTransient<IWellOperationRepository, WellOperationRepository>();
|
||||||
services.AddTransient<IDailyReportService, DailyReportService>();
|
services.AddTransient<IDailyReportService, DailyReportService>();
|
||||||
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
|
||||||
services.AddTransient<ISubsystemService, SubsystemService>();
|
|
||||||
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
services.AddTransient<IScheduleRepository, ScheduleRepository>();
|
||||||
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
|
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedRepositoryBase<OperationValueDto, OperationValue>>();
|
||||||
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
|
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
|
||||||
@ -488,6 +487,9 @@ public static class DependencyInjection
|
|||||||
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
|
services.AddTransient<ITelemetryDataSaubService, TelemetryDataSaubService>();
|
||||||
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
|
services.AddTransient<ITelemetryDataService<TelemetryDataSpinDto>, TelemetryDataSpinService>();
|
||||||
|
|
||||||
|
// Subsystem service
|
||||||
|
services.AddTransient<ISubsystemService, SubsystemService>();
|
||||||
|
|
||||||
// Wits
|
// Wits
|
||||||
services.AddTransient<IWitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto>, WitsRecordRepository<AsbCloudApp.Data.WITS.Record1Dto, AsbCloudDb.Model.WITS.Record1>>();
|
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>>();
|
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);
|
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;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ public class DataSaubStatService : IDataSaubStatService
|
|||||||
var geDate = detectedOperations.First().DateStart;
|
var geDate = detectedOperations.First().DateStart;
|
||||||
var leDate = detectedOperations.OrderByDescending(d => d.DateEnd).First().DateEnd;
|
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())
|
if (!dataSaub.Any())
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -37,14 +37,19 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
|||||||
this.telemetryUserService = telemetryUserService;
|
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 geDateUtc = geDate.ToUniversalTime();
|
||||||
var leDateUtc = leDate.ToUniversalTime();
|
var leDateUtc = leDate.ToUniversalTime();
|
||||||
|
|
||||||
var query = db.Set<TelemetryDataSaub>()
|
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 >= geDateUtc)
|
||||||
.Where(t => t.DateTime <= leDateUtc);
|
.Where(t => t.DateTime <= leDateUtc);
|
||||||
|
|
||||||
@ -56,7 +61,7 @@ public class TelemetryDataSaubService : TelemetryDataBaseService<TelemetryDataSa
|
|||||||
.Take(take);
|
.Take(take);
|
||||||
|
|
||||||
var entities = await query.ToArrayAsync(token);
|
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;
|
return dtos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ public class TelemetryService : ITelemetryService
|
|||||||
private IEnumerable<Telemetry> GetTelemetryCache()
|
private IEnumerable<Telemetry> GetTelemetryCache()
|
||||||
=> memoryCache.GetOrCreateBasic(
|
=> memoryCache.GetOrCreateBasic(
|
||||||
db.Set<Telemetry>()
|
db.Set<Telemetry>()
|
||||||
.Include(t => t.Well));
|
.Include(t => t.Well));
|
||||||
|
|
||||||
private void DropTelemetryCache()
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
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;
|
namespace AsbCloudInfrastructure.Services.Subsystems;
|
||||||
|
|
||||||
internal class SubsystemService : ISubsystemService
|
public class SubsystemService : ISubsystemService
|
||||||
{
|
{
|
||||||
private const int IdSubsystemAPD = 1;
|
private const int IdSubsystemAPD = 1;
|
||||||
private const int IdSubsystemAPDRotor = 11;
|
private const int IdSubsystemAPDRotor = 11;
|
||||||
@ -26,18 +28,27 @@ internal class SubsystemService : ISubsystemService
|
|||||||
private readonly IWellService wellService;
|
private readonly IWellService wellService;
|
||||||
private readonly IDetectedOperationService detectedOperationService;
|
private readonly IDetectedOperationService detectedOperationService;
|
||||||
private readonly IScheduleRepository scheduleRepository;
|
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>();
|
private IDictionary<int, SubsystemDto> subsystems = new Dictionary<int, SubsystemDto>();
|
||||||
|
|
||||||
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
public SubsystemService(ICrudRepository<SubsystemDto> subsystemRepository,
|
||||||
IWellService wellService,
|
IWellService wellService,
|
||||||
IDetectedOperationService detectedOperationService,
|
IDetectedOperationService detectedOperationService,
|
||||||
IScheduleRepository scheduleRepository)
|
IScheduleRepository scheduleRepository,
|
||||||
|
ITelemetryService telemetryService,
|
||||||
|
ITelemetryDataSaubService telemetryDataSaubService,
|
||||||
|
IChangeLogRepository<ProcessMapPlanSubsystemsDto, ProcessMapPlanBaseRequestWithWell> processMapPlanRepository)
|
||||||
{
|
{
|
||||||
this.wellService = wellService;
|
this.wellService = wellService;
|
||||||
this.subsystemRepository = subsystemRepository;
|
this.subsystemRepository = subsystemRepository;
|
||||||
this.detectedOperationService = detectedOperationService;
|
this.detectedOperationService = detectedOperationService;
|
||||||
this.scheduleRepository = scheduleRepository;
|
this.scheduleRepository = scheduleRepository;
|
||||||
|
this.telemetryService = telemetryService;
|
||||||
|
this.telemetryDataSaubService = telemetryDataSaubService;
|
||||||
|
this.processMapPlanRepository = processMapPlanRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
// получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод
|
// получить расписания бурильщиков по скважинам // ScheduleRepository добавить новый метод
|
||||||
@ -57,11 +68,11 @@ internal class SubsystemService : ISubsystemService
|
|||||||
var result = new List<DrillerDetectedOperationStatDto>();
|
var result = new List<DrillerDetectedOperationStatDto>();
|
||||||
var schedulePage = await scheduleRepository.GetPageAsync(request, token);
|
var schedulePage = await scheduleRepository.GetPageAsync(request, token);
|
||||||
var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token);
|
var wells = await wellService.GetAsync(new WellRequest { Ids = request.IdsWells }, token);
|
||||||
|
|
||||||
foreach (var schedule in schedulePage)
|
foreach (var schedule in schedulePage)
|
||||||
{
|
{
|
||||||
var idWell = schedule.IdWell;
|
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());
|
var byWellRequest = new DetectedOperationByWellRequest(idWell, new DetectedOperationRequest());
|
||||||
|
|
||||||
@ -124,6 +135,70 @@ internal class SubsystemService : ISubsystemService
|
|||||||
return result;
|
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(
|
private async Task<IEnumerable<SubsystemStatDto>> CalcStatAsync(
|
||||||
IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
|
IEnumerable<DetectedOperationWithDrillerDto> operations, CancellationToken token)
|
||||||
{
|
{
|
||||||
@ -157,7 +232,7 @@ internal class SubsystemService : ISubsystemService
|
|||||||
SumDepthInterval = sumDepthInterval,
|
SumDepthInterval = sumDepthInterval,
|
||||||
OperationCount = operationCount,
|
OperationCount = operationCount,
|
||||||
};
|
};
|
||||||
if(oscillationStat.SumOperationDepthInterval != 0d)
|
if (oscillationStat.SumOperationDepthInterval != 0d)
|
||||||
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
|
oscillationStat.KUsage = oscillationStat.SumDepthInterval / oscillationStat.SumOperationDepthInterval;
|
||||||
|
|
||||||
return oscillationStat;
|
return oscillationStat;
|
||||||
|
@ -80,6 +80,24 @@ public class SubsystemController : ControllerBase
|
|||||||
return Ok(result);
|
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)
|
private async Task<bool> UserHasAccessToWellAsync(int idWell, CancellationToken token)
|
||||||
{
|
{
|
||||||
var idCompany = User.GetCompanyId();
|
var idCompany = User.GetCompanyId();
|
||||||
|
Loading…
Reference in New Issue
Block a user