Merge branch 'feature/well_case' of http://46.146.209.148:8080/DDrilling/AsbCloudServer into feature/well_case

This commit is contained in:
ai.astrakhantsev 2022-09-13 15:46:31 +05:00
commit 13ed715e5b
34 changed files with 14053 additions and 180 deletions

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>

View File

@ -0,0 +1,21 @@
namespace AsbCloudApp.Data.Subsystems
{
/// <summary>
/// Описание параметров подсистемы
/// </summary>
public class SubsystemDto : IId
{
/// <summary>
/// Идентификатор подсистемы
/// </summary>
public int Id { get; set; }
/// <summary>
/// Наименование подсистемы
/// </summary>
public string Name { get; set; }
/// <summary>
/// Детальное описание подсистемы
/// </summary>
public string Description { get; set; }
}
}

View File

@ -0,0 +1,38 @@
using System;
namespace AsbCloudApp.Data.Subsystems
{
/// <summary>
/// Модель информации о работе подсистемы
/// </summary>
public class SubsystemOperationTimeDto:IId
{
/// <summary>
/// Идентификатор
/// </summary>
public int Id { get; set; }
/// <summary>
/// идентификатор подсистемы
/// </summary>
public int IdSubsystem { get; set; }
/// <summary>
/// Название подсистемы
/// </summary>
public string SubsystemName { get; set; }
/// <summary>
/// дата/время включения подсистемы
/// </summary>
public DateTime DateStart { get; set; }
/// <summary>
/// дата/время выключения подсистемы
/// </summary>
public DateTime DateEnd { get; set; }
/// <summary>
/// глубина забоя на момент включения подсистемы
/// </summary>
public double DepthStart { get; set; }
/// <summary>
/// глубина забоя на момент выключения подсистемы
/// </summary>
public double DepthEnd { get; set; }
}
}

View File

@ -0,0 +1,30 @@
using System;
namespace AsbCloudApp.Data.Subsystems
{
/// <summary>
/// Статистика подсистемы
/// </summary>
public class SubsystemStatDto
{
/// <summary>
/// Идентификатор подсистемы
/// </summary>
public int IdSubsystem { get; set; }
/// <summary>
/// Название подсистемы
/// </summary>
public string SubsystemName { get; set; }
/// <summary>
/// наработка подсистемы
/// </summary>
public double UsedTimeHours { get; set; }
/// <summary>
/// коэффициент использования
/// </summary>
public double KUsage { get; set; }
/// <summary>
/// коэффициент применения
/// </summary>
public double K2 { get; set; }
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AsbCloudApp.Requests
{
#nullable enable
/// <summary>
/// класс с фильтрами для запроса
/// </summary>
public class SubsystemOperationTimeRequest: RequestBase
{
/// <summary>
/// идентификатор скважины, может не указыватся пользователем
/// </summary>
[Required]
public int IdWell { get; set; }
/// <summary>
/// идентификатор подсистемы
/// </summary>
public IEnumerable<int>? IdsSubsystems { get; set; }
/// <summary>
/// Больше или равно дате
/// </summary>
public DateTime? GtDate { get; set; }
/// <summary>
/// Меньше или равно дате
/// </summary>
public DateTime? LtDate { get; set; }
/// <summary>
/// Больше или равно глубины забоя
/// </summary>
public double? GtDepth { get; set; }
/// <summary>
/// Меньше или равно глубины забоя
/// </summary>
public double? LtDepth { get; set; }
/// <summary>
/// информация попадает в выборку, если интервал выборки частично или полностью пересекается с запрашиваемым интервалом
/// </summary>
public const int SelectModeOuter = 0;
/// <summary>
/// информация попадает в выборку, если интервал выборки строго полностью пересекается с запрашиваемым интервалом.
/// </summary>
public const int SelectModeInner = 1;
/// <summary>
/// аналогично outer, но интервалы в частично пересекающиеся укорачиваются по границам интервала выборки.
/// </summary>
public const int SelectModeTrim = 2;
/// <summary>
/// Режим выборки элементов
/// </summary>
public int SelectMode { get; set; } = SelectModeOuter;
}
#nullable disable
}

View File

@ -33,6 +33,7 @@ namespace AsbCloudApp.Services
/// <returns>null if not found</returns>
Task<TDto?> GetOrDefaultAsync(int id, CancellationToken token);
/// <summary>
/// Получить запись по id
/// </summary>

View File

@ -0,0 +1,42 @@
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Requests;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services.Subsystems
{
#nullable enable
/// <summary>
/// Получение инфо о наработке подсистем
/// </summary>
public interface ISubsystemOperationTimeService
{
/// <summary>
/// Статистика о наработке подсистем
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token);
/// <summary>
/// Удаление наработки по подсистемам.
/// Если удаляется конец, то фоновый сервис подсчета наработки восстановит эти данные.
/// Может потребоваться для запуска повторного расчета по новому алгоритму.
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token);
/// <summary>
/// Интервалы работы подсистем
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token);
}
#nullable disable
}

View File

@ -0,0 +1,14 @@
using AsbCloudApp.Data.Subsystems;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudApp.Services.Subsystems
{
#nullable enable
public interface ISubsystemService
{
Task<IEnumerable<SubsystemDto>?> GetSubsystemAsync(int? idWell, CancellationToken token);
}
#nullable disable
}

View File

@ -6,11 +6,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1">
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.6">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.6" />
</ItemGroup>
<ItemGroup>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class Add_Table_Subsystem_and_SubsystemOperationTime : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "t_subsystem",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
name = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true),
description = table.Column<string>(type: "character varying(255)", maxLength: 255, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_t_subsystem", x => x.id);
},
comment: "Описание подсистем");
migrationBuilder.CreateTable(
name: "t_subsystem_operation_time",
columns: table => new
{
id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
id_telemetry = table.Column<int>(type: "integer", nullable: false, comment: "ИД телеметрии по которой выдается информация"),
id_subsystem = table.Column<int>(type: "integer", nullable: false),
date_start = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "дата/время включения подсистемы"),
date_end = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "дата/время выключения подсистемы"),
depth_start = table.Column<float>(type: "real", nullable: true, comment: "глубина забоя на момент включения подсистемы"),
depth_end = table.Column<float>(type: "real", nullable: true, comment: "глубина забоя на момент выключения подсистемы")
},
constraints: table =>
{
table.PrimaryKey("PK_t_subsystem_operation_time", x => x.id);
table.ForeignKey(
name: "FK_t_subsystem_operation_time_t_subsystem_id_subsystem",
column: x => x.id_subsystem,
principalTable: "t_subsystem",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_t_subsystem_operation_time_t_telemetry_id_telemetry",
column: x => x.id_telemetry,
principalTable: "t_telemetry",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
},
comment: "наработки подсистем");
migrationBuilder.InsertData(
table: "t_permission",
columns: new[] { "id", "description", "name" },
values: new object[,]
{
{ 127, "Разрешение удалять админ. Подсистемы", "AdminSubsytem.delete" },
{ 128, "Разрешение редактировать админ. Подсистемы", "AdminSubsytem.edit" },
{ 129, "Разрешение просматривать админ. Подсистемы", "AdminSubsytem.get" }
});
migrationBuilder.CreateIndex(
name: "IX_t_subsystem_operation_time_id_subsystem",
table: "t_subsystem_operation_time",
column: "id_subsystem");
migrationBuilder.CreateIndex(
name: "IX_t_subsystem_operation_time_id_telemetry",
table: "t_subsystem_operation_time",
column: "id_telemetry");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "t_subsystem_operation_time");
migrationBuilder.DropTable(
name: "t_subsystem");
migrationBuilder.DeleteData(
table: "t_permission",
keyColumn: "id",
keyValue: 127);
migrationBuilder.DeleteData(
table: "t_permission",
keyColumn: "id",
keyValue: 128);
migrationBuilder.DeleteData(
table: "t_permission",
keyColumn: "id",
keyValue: 129);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,104 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace AsbCloudDb.Migrations
{
public partial class AddDataDefault_SubsystemFiller : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_subsystem",
type: "character varying(255)",
maxLength: 255,
nullable: false,
defaultValue: "",
oldClrType: typeof(string),
oldType: "character varying(255)",
oldMaxLength: 255,
oldNullable: true);
migrationBuilder.InsertData(
table: "t_subsystem",
columns: new[] { "id", "description", "name" },
values: new object[,]
{
{ 1, "Ручной", "Ручной" },
{ 2, "Бурение в роторе", "Бурение в роторе" },
{ 3, "Проработка", "Проработка" },
{ 4, "Бурение в слайде", "Бурение в слайде" },
{ 5, "Спуск СПО", "Спуск СПО" },
{ 6, "Подъем СПО", "Подъем СПО" },
{ 7, "Подъем с проработкой", "Подъем с проработкой" },
{ 11, "Блокировка", "Блокировка" },
{ 65536, "Spin master", "Spin master" },
{ 65537, "Torque master", "Torque master" }
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 1);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 2);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 3);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 4);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 5);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 6);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 7);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 11);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 65536);
migrationBuilder.DeleteData(
table: "t_subsystem",
keyColumn: "id",
keyValue: 65537);
migrationBuilder.AlterColumn<string>(
name: "name",
table: "t_subsystem",
type: "character varying(255)",
maxLength: 255,
nullable: true,
oldClrType: typeof(string),
oldType: "character varying(255)",
oldMaxLength: 255);
}
}
}

View File

@ -1335,6 +1335,24 @@ namespace AsbCloudDb.Migrations
Name = "AdminWell.get"
},
new
{
Id = 127,
Description = "Разрешение удалять админ. Подсистемы",
Name = "AdminSubsytem.delete"
},
new
{
Id = 128,
Description = "Разрешение редактировать админ. Подсистемы",
Name = "AdminSubsytem.edit"
},
new
{
Id = 129,
Description = "Разрешение просматривать админ. Подсистемы",
Name = "AdminSubsytem.get"
},
new
{
Id = 200,
Description = "Разрешение редактировать 0",
@ -3039,6 +3057,144 @@ namespace AsbCloudDb.Migrations
b.HasComment("Запросы на изменение уставок панели оператора");
});
modelBuilder.Entity("AsbCloudDb.Model.Subsystems.Subsystem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Description")
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("description");
b.Property<string>("Name")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("character varying(255)")
.HasColumnName("name");
b.HasKey("Id");
b.ToTable("t_subsystem");
b.HasComment("Описание подсистем");
b.HasData(
new
{
Id = 1,
Description = "Ручной",
Name = "Ручной"
},
new
{
Id = 2,
Description = "Бурение в роторе",
Name = "Бурение в роторе"
},
new
{
Id = 3,
Description = "Проработка",
Name = "Проработка"
},
new
{
Id = 4,
Description = "Бурение в слайде",
Name = "Бурение в слайде"
},
new
{
Id = 5,
Description = "Спуск СПО",
Name = "Спуск СПО"
},
new
{
Id = 6,
Description = "Подъем СПО",
Name = "Подъем СПО"
},
new
{
Id = 7,
Description = "Подъем с проработкой",
Name = "Подъем с проработкой"
},
new
{
Id = 11,
Description = "Блокировка",
Name = "Блокировка"
},
new
{
Id = 65536,
Description = "Spin master",
Name = "Spin master"
},
new
{
Id = 65537,
Description = "Torque master",
Name = "Torque master"
});
});
modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasColumnName("id");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<DateTimeOffset>("DateEnd")
.HasColumnType("timestamp with time zone")
.HasColumnName("date_end")
.HasComment("дата/время выключения подсистемы");
b.Property<DateTimeOffset>("DateStart")
.HasColumnType("timestamp with time zone")
.HasColumnName("date_start")
.HasComment("дата/время включения подсистемы");
b.Property<float?>("DepthEnd")
.HasColumnType("real")
.HasColumnName("depth_end")
.HasComment("глубина забоя на момент выключения подсистемы");
b.Property<float?>("DepthStart")
.HasColumnType("real")
.HasColumnName("depth_start")
.HasComment("глубина забоя на момент включения подсистемы");
b.Property<int>("IdSubsystem")
.HasColumnType("integer")
.HasColumnName("id_subsystem");
b.Property<int>("IdTelemetry")
.HasColumnType("integer")
.HasColumnName("id_telemetry")
.HasComment("ИД телеметрии по которой выдается информация");
b.HasKey("Id");
b.HasIndex("IdSubsystem");
b.HasIndex("IdTelemetry");
b.ToTable("t_subsystem_operation_time");
b.HasComment("наработки подсистем");
});
modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b =>
{
b.Property<int>("Id")
@ -6254,6 +6410,25 @@ namespace AsbCloudDb.Migrations
b.Navigation("Well");
});
modelBuilder.Entity("AsbCloudDb.Model.Subsystems.SubsystemOperationTime", b =>
{
b.HasOne("AsbCloudDb.Model.Subsystems.Subsystem", "Subsystem")
.WithMany()
.HasForeignKey("IdSubsystem")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")
.WithMany()
.HasForeignKey("IdTelemetry")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Subsystem");
b.Navigation("Telemetry");
});
modelBuilder.Entity("AsbCloudDb.Model.TelemetryDataSaub", b =>
{
b.HasOne("AsbCloudDb.Model.Telemetry", "Telemetry")

View File

@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using AsbCloudDb.Model.Subsystems;
using Microsoft.EntityFrameworkCore;
using System.Threading;
using System.Threading.Tasks;
@ -28,6 +29,8 @@ namespace AsbCloudDb.Model
public virtual DbSet<RelationUserUserRole> RelationUserUserRoles => Set<RelationUserUserRole>();
public virtual DbSet<ReportProperty> ReportProperties => Set<ReportProperty>();
public virtual DbSet<SetpointsRequest> SetpointsRequests => Set<SetpointsRequest>();
public virtual DbSet<Subsystem> Subsystems => Set<Subsystem>();
public virtual DbSet<SubsystemOperationTime> SubsystemOperationTimes => Set<SubsystemOperationTime>();
public virtual DbSet<Telemetry> Telemetries => Set<Telemetry>();
public virtual DbSet<TelemetryDataSaub> TelemetryDataSaub => Set<TelemetryDataSaub>();
public virtual DbSet<TelemetryDataSaubStat> TelemetryDataSaubStats => Set<TelemetryDataSaubStat>();

View File

@ -22,6 +22,7 @@ namespace AsbCloudDb.Model.DefaultData
new EntityFillerWellType(),
new EntityFillerMeasureCategory(),
new EntityFillerCompanyType(),
new EntityFillerSubsystem(),
};
foreach (var filler in fillers)

View File

@ -30,6 +30,11 @@
new (){ Id = 124, Name="AdminWell.delete", Description="Разрешение удалять админ. Скважины"},
new (){ Id = 125, Name="AdminWell.edit", Description="Разрешение редактировать админ. Скважины"},
new (){ Id = 126, Name="AdminWell.get", Description="Разрешение просматривать админ. Скважины"},
new (){ Id = 127, Name="AdminSubsytem.delete", Description="Разрешение удалять админ. Подсистемы"},
new (){ Id = 128, Name="AdminSubsytem.edit", Description="Разрешение редактировать админ. Подсистемы"},
new (){ Id = 129, Name="AdminSubsytem.get", Description="Разрешение просматривать админ. Подсистемы"},
new (){ Id = 200, Name="Auth.edit", Description="Разрешение редактировать 0"},
new (){ Id = 201, Name="Auth.get", Description="Разрешение просматривать 0"},
new (){ Id = 202, Name="Cluster.get", Description="Разрешение просматривать Кусты"},

View File

@ -0,0 +1,24 @@
using AsbCloudDb.Model.Subsystems;
namespace AsbCloudDb.Model.DefaultData
{
internal class EntityFillerSubsystem : EntityFiller<Subsystem>
{
protected override Subsystem[] GetData() => new Subsystem[]{
// САУБ - ид подсистем с 1 до 65_535
new () {Id = 1, Name = "Ручной", Description = "Ручной"},
new () {Id = 2, Name = "Бурение в роторе", Description = "Бурение в роторе"},
new () {Id = 3, Name = "Проработка", Description = "Проработка"},
new () {Id = 4, Name = "Бурение в слайде", Description = "Бурение в слайде"},
new () {Id = 5, Name = "Спуск СПО", Description = "Спуск СПО"},
new () {Id = 6, Name = "Подъем СПО", Description = "Подъем СПО"},
new () {Id = 7, Name = "Подъем с проработкой", Description = "Подъем с проработкой"},
new () {Id = 11, Name = "Блокировка", Description = "Блокировка"},
//Spin master - id подсистем с 65_536 до 131_071
new () {Id = 65536, Name = "Spin master", Description = "Spin master"},
new () {Id = 65537, Name = "Torque master", Description = "Torque master"}
};
}
}

View File

@ -1,4 +1,5 @@
using AsbCloudDb.Model.WITS;
using AsbCloudDb.Model.Subsystems;
using AsbCloudDb.Model.WITS;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
@ -28,6 +29,8 @@ namespace AsbCloudDb.Model
DbSet<RelationUserRolePermission> RelationUserRolePermissions { get; }
DbSet<RelationUserUserRole> RelationUserUserRoles { get; }
DbSet<ReportProperty> ReportProperties { get; }
DbSet<Subsystem> Subsystems { get; }
DbSet<SubsystemOperationTime> SubsystemOperationTimes { get; }
DbSet<Telemetry> Telemetries { get; }
DbSet<TelemetryDataSaub> TelemetryDataSaub { get; }
DbSet<TelemetryDataSaubStat> TelemetryDataSaubStats { get; }

View File

@ -0,0 +1,22 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;
namespace AsbCloudDb.Model.Subsystems
{
[Table("t_subsystem"), Comment("Описание подсистем")]
public class Subsystem : IId
{
[Column("id"), Key]
public int Id { get; set; }
[Column("name")]
[StringLength(255)]
public string Name { get; set; } = null!;
[Column("description")]
[StringLength(255)]
public string? Description { get; set; }
}
}

View File

@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
namespace AsbCloudDb.Model.Subsystems
{
[Table("t_subsystem_operation_time"), Comment("наработки подсистем")]
public partial class SubsystemOperationTime : IId
{
[Column("id"), Key]
public int Id { get; set; }
[Column("id_telemetry"), Comment("ИД телеметрии по которой выдается информация")]
public int IdTelemetry { get; set; }
[Column("id_subsystem")]
public int IdSubsystem { get; set; }
[Column("date_start"), Comment("дата/время включения подсистемы")]
public DateTimeOffset DateStart { get; set; }
[Column("date_end"), Comment("дата/время выключения подсистемы")]
public DateTimeOffset DateEnd { get; set; }
[Column("depth_start"), Comment("глубина забоя на момент включения подсистемы")]
public float? DepthStart { get; set; }
[Column("depth_end"), Comment("глубина забоя на момент выключения подсистемы")]
public float? DepthEnd { get; set; }
[JsonIgnore]
[ForeignKey(nameof(IdSubsystem))]
public virtual Subsystem Subsystem { get; set; } = null!;
[JsonIgnore]
[ForeignKey(nameof(IdTelemetry))]
public virtual Telemetry Telemetry { get; set; } = null!;
}
}

View File

@ -28,14 +28,13 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ClosedXML" Version="0.95.4" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.0.2" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.57.0.2684" />
<PackageReference Include="itext7" Version="7.2.2" />
<PackageReference Include="ClosedXML" Version="0.96.0" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="itext7" Version="7.2.3" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.18.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.18.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.23.1" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.23.1" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,10 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.SAUB;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
using AsbCloudInfrastructure.Repository;
using AsbCloudInfrastructure.Services;
using AsbCloudInfrastructure.Services.Cache;
@ -9,6 +12,7 @@ using AsbCloudInfrastructure.Services.DailyReport;
using AsbCloudInfrastructure.Services.DetectOperations;
using AsbCloudInfrastructure.Services.DrillingProgram;
using AsbCloudInfrastructure.Services.SAUB;
using AsbCloudInfrastructure.Services.Subsystems;
using AsbCloudInfrastructure.Services.WellOperationService;
using AsbCloudInfrastructure.Validators;
using FluentValidation.AspNetCore;
@ -87,7 +91,7 @@ namespace AsbCloudInfrastructure
services.AddScoped<IEmailService, EmailService>();
services.AddHostedService<OperationDetectionBackgroundService>();
services.AddHostedService<SubsystemOperationTimeBackgroundService>();
services.AddSingleton(new WitsInfoService());
services.AddSingleton(new CacheDb());
services.AddSingleton(new InstantDataRepository());
@ -120,6 +124,8 @@ namespace AsbCloudInfrastructure
services.AddTransient<IDailyReportService, DailyReportService>();
services.AddTransient<IDetectedOperationService, DetectedOperationService>();
services.AddTransient<IDrillerService, DrillerService>();
services.AddTransient<ISubsystemOperationTimeService, SubsystemOperationTimeService>();
services.AddTransient<IScheduleRepository, ScheduleRepository>();
services.AddTransient<IRepositoryWellRelated<OperationValueDto>, CrudWellRelatedServiceBase<OperationValueDto, OperationValue>>();
services.AddTransient<IUserSettingsRepository, UserSettingsRepository>();
@ -140,6 +146,7 @@ namespace AsbCloudInfrastructure
new CrudCacheServiceBase<CompanyDto, Company>(
s.GetService<IAsbCloudDbContext>(),
dbSet => dbSet.Include(c => c.CompanyType)));
services.AddTransient<ICrudService<CompanyTypeDto>, CrudCacheServiceBase<CompanyTypeDto, CompanyType>>();
services.AddTransient<ICrudService<ClusterDto>, CrudCacheServiceBase<ClusterDto, Cluster>>(s =>
new CrudCacheServiceBase<ClusterDto, Cluster>(
@ -147,7 +154,9 @@ namespace AsbCloudInfrastructure
dbSet => dbSet
.Include(c => c.Wells)
.Include(c => c.Deposit))); // может быть включен в сервис ClusterService
services.AddTransient<ICrudService<FileCategoryDto>, CrudCacheServiceBase<FileCategoryDto, FileCategory>>();
// Subsystem service
services.AddTransient<ICrudService<SubsystemDto>, CrudCacheServiceBase<SubsystemDto, Subsystem>>();
services.AddTransient<ISubsystemService, SubsystemService>();
services.AddTransient<ICrudService<PermissionDto>, CrudCacheServiceBase<PermissionDto, Permission>>();

View File

@ -0,0 +1,261 @@
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Subsystems
{
#nullable enable
internal class SubsystemOperationTimeBackgroundService : BackgroundService
{
private readonly string connectionString;
private readonly TimeSpan period = TimeSpan.FromHours(1);
private const int idSubsytemTorqueMaster = 65537;
private const int idSubsytemSpinMaster = 65536;
public SubsystemOperationTimeBackgroundService(IConfiguration configuration)
{
connectionString = configuration.GetConnectionString("DefaultConnection");
}
protected override async Task ExecuteAsync(CancellationToken token)
{
var timeToStart = DateTime.Now;
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
.UseNpgsql(connectionString)
.Options;
while (!token.IsCancellationRequested)
{
if (DateTime.Now > timeToStart)
{
timeToStart = DateTime.Now + period;
try
{
using var context = new AsbCloudDbContext(options);
var added = await OperationTimeAllTelemetriesAsync(context, token);
Trace.TraceInformation($"Total subsystem operation time complete. Added {added} operations time.");
}
catch (Exception ex)
{
Trace.TraceError(ex.Message);
}
GC.Collect();
}
var ms = (int)(timeToStart - DateTime.Now).TotalMilliseconds;
ms = ms > 100 ? ms : 100;
await Task.Delay(ms, token).ConfigureAwait(false);
}
}
public override async Task StopAsync(CancellationToken token)
{
await base.StopAsync(token).ConfigureAwait(false);
}
private static async Task<int> OperationTimeAllTelemetriesAsync(IAsbCloudDbContext db, CancellationToken token)
{
var lastDetectedDates = await db.SubsystemOperationTimes
.GroupBy(o => o.IdTelemetry)
.Select(g => new
{
IdTelemetry = g.Key,
LastDate = g.Max(o => o.DateEnd)
})
.ToListAsync(token);
var telemetryIds = await db.Telemetries
.Where(t => t.Info != null && t.TimeZone != null)
.Select(t => t.Id)
.ToListAsync(token);
var telemetryLastDetectedDates = telemetryIds
.GroupJoin(lastDetectedDates,
t => t,
o => o.IdTelemetry,
(outer, inner) => new
{
IdTelemetry = outer,
inner.SingleOrDefault()?.LastDate,
});
var affected = 0;
foreach (var item in telemetryLastDetectedDates)
{
var newOperationsSaub = await OperationTimeSaubAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSaub?.Any() == true)
{
db.SubsystemOperationTimes.AddRange(newOperationsSaub);
affected += await db.SaveChangesAsync(token);
}
var newOperationsSpin = await OperationTimeSpinAsync(item.IdTelemetry, item.LastDate ?? DateTimeOffset.MinValue, db, token);
if (newOperationsSpin?.Any() == true)
{
db.SubsystemOperationTimes.AddRange(newOperationsSpin);
affected += await db.SaveChangesAsync(token);
}
}
return affected;
}
private static async Task<IEnumerable<SubsystemOperationTime>> OperationTimeSaubAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{
static int? GetSubsytemId(short mode)
{
return mode +1;
}
var query =
$"select tt.date, tt.mode, tt.well_depth " +
$"from ( " +
$" select " +
$" date, " +
$" mode, " +
$" well_depth, " +
$" lag(mode,1) over (order by date) as mode_prev " +
$" from t_telemetry_data_saub " +
$" where id_telemetry = @idTelemetry " +
$" order by date ) as tt " +
$"where (tt.mode_prev is null or tt.mode != tt.mode_prev) and tt.date >= @begin " +
$"order by tt.date;";
var idTelemetryParam = new NpgsqlParameter("@idTelemetry", idTelemetry);
var beginParam = new NpgsqlParameter("@begin", begin);
await db.Database.OpenConnectionAsync(token);
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = query;
command.Parameters.Add(idTelemetryParam);
command.Parameters.Add(beginParam);
using var result = await command.ExecuteReaderAsync(token);
var subsystemOperationTime = new List<SubsystemOperationTime>(32);
if (result.Read())
{
var mode = result.GetFieldValue<short>(1);
var idSubsystem = GetSubsytemId(mode);
var dateStart = result.GetFieldValue<DateTimeOffset>(0);
var depthStart = result.GetFieldValue<float>(2);
while (result.Read())
{
var dateEnd = result.GetFieldValue<DateTimeOffset>(0);
var depthEnd = result.GetFieldValue<float>(2);
if (idSubsystem.HasValue)
{
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
IdSubsystem = idSubsystem.Value,
DateStart = dateStart,
DateEnd = dateEnd,
DepthStart = depthStart,
DepthEnd = depthEnd
};
subsystemOperationTime.Add(operationTimeItem);
}
mode = result.GetFieldValue<short>(1);
idSubsystem = GetSubsytemId(mode);
dateStart = dateEnd;
depthStart = depthEnd;
}
}
return subsystemOperationTime;
}
private static async Task<IEnumerable<SubsystemOperationTime>?> OperationTimeSpinAsync(int idTelemetry, DateTimeOffset begin, IAsbCloudDbContext db, CancellationToken token)
{
static int? GetSubsytemId(short mode, int state)
{
if (state == 7 && (mode & 2) > 0)
return idSubsytemTorqueMaster;
if (state != 0 & state != 6 & state != 7)
return idSubsytemSpinMaster;
return null;
}
var query =
$"select " +
$" tspin.date, " +
$" tspin.mode, " +
$" tspin.state, " +
$" tsaub.well_depth " +
$"from ( " +
$" select " +
$" date, " +
$" mode, " +
$" lag(mode, 1) over (order by date) as mode_pre, " +
$" state, " +
$" lag(state, 1) over (order by date) as state_pre " +
$" from t_telemetry_data_spin " +
$" where id_telemetry = @idTelemetry and date >= @begin" +
$" order by date ) as tspin " +
$"left outer join ( " +
$" select " +
$" date, " +
$" well_depth " +
$" from t_telemetry_data_saub " +
$" where id_telemetry = @idTelemetry and date >= @begin) as tsaub " +
$"on EXTRACT(EPOCH from tspin.date) = EXTRACT(EPOCH from tsaub.date) " +
$"where mode_pre is null or state_pre is null or mode != mode_pre or state != state_pre " +
$"order by date;";
var idTelemetryParam = new NpgsqlParameter("@idTelemetry", idTelemetry);
var beginParam = new NpgsqlParameter("@begin", begin);
await db.Database.OpenConnectionAsync(token);
using var command = db.Database.GetDbConnection().CreateCommand();
command.CommandText = query;
command.Parameters.Add(idTelemetryParam);
command.Parameters.Add(beginParam);
using var result = await command.ExecuteReaderAsync(token);
var subsystemOperationTime = new List<SubsystemOperationTime>(32);
if (result.Read())
{
var mode = result.GetFieldValue<short>(1);
var state = result.GetFieldValue<int>(2);
var idSubsystem = GetSubsytemId(mode, state);
var dateStart = result.GetFieldValue<DateTimeOffset>(0);
var depthStart = result.GetFieldValue<float?>(3);
while (result.Read())
{
var dateEnd = result.GetFieldValue<DateTimeOffset>(0);
var depthEnd = result.GetFieldValue<float?>(3);
if (idSubsystem.HasValue)
{
var operationTimeItem = new SubsystemOperationTime()
{
IdTelemetry = idTelemetry,
IdSubsystem = idSubsystem.Value,
DateStart = dateStart,
DateEnd = dateEnd,
DepthStart = depthStart,
DepthEnd = depthEnd
};
subsystemOperationTime.Add(operationTimeItem);
}
mode = result.GetFieldValue<short>(1);
state = result.GetFieldValue<int>(2);
idSubsystem = GetSubsytemId(mode, state);
dateStart = dateEnd;
depthStart = depthEnd;
}
}
return subsystemOperationTime;
}
}
#nullable disable
}

View File

@ -0,0 +1,208 @@
using AsbCloudApp.Data;
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudDb;
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Subsystems
{
#nullable enable
internal class SubsystemOperationTimeService : ISubsystemOperationTimeService
{
private readonly IAsbCloudDbContext db;
private readonly IWellService wellService;
private readonly ICrudService<SubsystemDto> subsystemService;
public SubsystemOperationTimeService(IAsbCloudDbContext db, IWellService wellService, ICrudService<SubsystemDto> subsystemService)
{
this.db = db;
this.wellService = wellService;
this.subsystemService = subsystemService;
}
/// <inheritdoc/>
public async Task<int> DeleteAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return 0;
var query = BuildQuery(request);
if (query is null)
return 0;
db.SubsystemOperationTimes.RemoveRange(query);
return await db.SaveChangesAsync(token);
}
/// <inheritdoc/>
public async Task<IEnumerable<SubsystemOperationTimeDto>?> GetOperationTimeAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(request.IdWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var query = BuildQuery(request);
if (query is null)
return null;
IEnumerable<SubsystemOperationTime> data = await query.ToListAsync(token);
if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeInner)
{
if (request.GtDate is not null)
data = data.Where(o => o.DateStart >= request.GtDate.Value);
if (request.LtDate is not null)
data = data.Where(o => o.DateEnd <= request.LtDate.Value);
}
else if (request.SelectMode == SubsystemOperationTimeRequest.SelectModeTrim)
{
var begin = request.GtDate?.ToUtcDateTimeOffset(well.Timezone.Hours);
var end = request.LtDate?.ToUtcDateTimeOffset(well.Timezone.Hours);
data = Trim(data, begin, end);
}
var dtos = data.Select(o => Convert(o, well));
return dtos;
}
/// <inheritdoc/>
public async Task<IEnumerable<SubsystemStatDto>?> GetStatAsync(SubsystemOperationTimeRequest request, CancellationToken token)
{
request.SelectMode = SubsystemOperationTimeRequest.SelectModeTrim;
var data = await GetOperationTimeAsync(request, token);
if (data is null)
return null;
var statList = CalcStat(data, request);
return statList;
}
private static IEnumerable<SubsystemOperationTime> Trim(IEnumerable<SubsystemOperationTime> data, DateTimeOffset? gtDate, DateTimeOffset? ltDate)
{
var items = data.Select((item) =>
{
if (gtDate.HasValue && item.DateStart < gtDate.Value)
{
item.DateStart = gtDate.Value;
item.DepthStart = null;
}
if (ltDate.HasValue && item.DateEnd > ltDate.Value)
{
item.DateEnd = ltDate.Value;
item.DepthEnd = null;
}
return item;
});
return items;
}
private IEnumerable<SubsystemStatDto> CalcStat(IEnumerable<SubsystemOperationTimeDto> dtos, SubsystemOperationTimeRequest request)
{
var groupedDataSubsystems = dtos
.GroupBy(o => o.IdSubsystem);
var periodGroupTotal = dtos.Sum(o => (o.DateEnd - o.DateStart).TotalHours);
var gtDate = request.GtDate ?? dtos.Min(o => o.DateStart);
var ltDate = request.LtDate ?? dtos.Max(o => o.DateEnd);
var periodRequest = (ltDate - gtDate).TotalHours;
var result = groupedDataSubsystems.Select(item =>
{
var periodGroup = item.Sum(o => (o.DateEnd - o.DateStart).TotalHours);
var subsystemStat = new SubsystemStatDto()
{
IdSubsystem = item.Key,
SubsystemName = subsystemService.GetOrDefault(item.Key)?.Name ?? "unknown",
UsedTimeHours = periodGroup,
KUsage = 1d * periodGroup / periodRequest,
K2 = 1d * periodGroup / periodGroupTotal,
};
return subsystemStat;
});
return result;
}
private IQueryable<SubsystemOperationTime>? BuildQuery(SubsystemOperationTimeRequest request)
{
if (request.SelectMode > 0 && request.GtDate is null && request.LtDate is null)
return null;
var well = wellService.GetOrDefault(request.IdWell);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var query = db.SubsystemOperationTimes
.Include(o => o.Subsystem)
.Where(o => o.IdTelemetry == well.IdTelemetry)
.AsNoTracking();
if (request.IdsSubsystems?.Any() == true)
query = query.Where(o => request.IdsSubsystems.Contains(o.IdSubsystem));
// # Dates range condition
// [GtDate LtDate]
// [DateStart DateEnd] [DateStart DateEnd]
if (request.GtDate.HasValue)
{
DateTimeOffset gtDate = request.GtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateEnd >= gtDate);
}
if (request.LtDate.HasValue)
{
DateTimeOffset ltDate = request.LtDate.Value.ToUtcDateTimeOffset(well.Timezone.Hours);
query = query.Where(o => o.DateStart <= ltDate);
}
if (request.GtDepth.HasValue)
query = query.Where(o => o.DepthEnd >= request.GtDepth.Value);
if (request.LtDepth.HasValue)
query = query.Where(o => o.DepthStart <= request.LtDepth.Value);
if (request?.SortFields?.Any() == true)
{
query = query.SortBy(request.SortFields);
}
else
{
query = query
.OrderBy(o => o.DateStart)
.ThenBy(o => o.DepthStart);
}
if (request?.Skip > 0)
query = query.Skip((int)request.Skip);
if (request?.Take > 0)
query = query.Take((int)request.Take);
else
query = query.Take(3000);
return query;
}
private static SubsystemOperationTimeDto Convert(SubsystemOperationTime operationTime, WellDto well)
{
var dto = operationTime.Adapt<SubsystemOperationTimeDto>();
dto.DateStart = operationTime.DateStart.ToRemoteDateTime(well.Timezone.Hours);
dto.DateEnd = operationTime.DateEnd.ToRemoteDateTime(well.Timezone.Hours);
return dto;
}
}
#nullable disable
}

View File

@ -0,0 +1,53 @@
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using AsbCloudDb.Model;
using AsbCloudDb.Model.Subsystems;
using AsbCloudInfrastructure.Repository;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Subsystems
{
#nullable enable
internal class SubsystemService : CrudCacheServiceBase<SubsystemDto, Subsystem>, ISubsystemService
{
private readonly IWellService wellService;
public SubsystemService(IAsbCloudDbContext dbContext, IWellService wellService) : base(dbContext)
{
this.wellService = wellService;
}
private async Task<IEnumerable<SubsystemDto>?> GetSubsystemByIdWellAsync(int idWell, CancellationToken token)
{
var well = await wellService.GetOrDefaultAsync(idWell, token);
if (well?.IdTelemetry is null || well.Timezone is null)
return null;
var entities = await dbContext.SubsystemOperationTimes
.Include(e => e.Subsystem)
.AsNoTracking()
.Where(o => o.IdTelemetry == well.IdTelemetry)
.Select(o => o.Subsystem)
.Distinct()
.ToArrayAsync(token);
var dtos = entities.Select(e => e.Adapt<SubsystemDto>());
return dtos;
}
public async Task<IEnumerable<SubsystemDto>?> GetSubsystemAsync(int? idWell, CancellationToken token)
{
if (idWell.HasValue)
{
var subsystemWell = await GetSubsystemByIdWellAsync(idWell.Value, token);
return subsystemWell;
}
var subsystem = await GetAllAsync(token);
return subsystem;
}
}
#nullable disable
}

View File

@ -7,12 +7,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
<PackageReference Include="Moq" Version="4.18.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="6.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="6.0.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
<PackageReference Include="Moq" Version="4.18.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>

View File

@ -9,12 +9,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.6" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.6" />
<PackageReference Include="protobuf-net" Version="3.1.4" />
<PackageReference Include="protobuf-net.AspNetCore" Version="3.0.101" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.3.1" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.8" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="6.0.8" />
<PackageReference Include="protobuf-net" Version="3.1.17" />
<PackageReference Include="protobuf-net.AspNetCore" Version="3.1.17" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.4.0" />
</ItemGroup>
<ItemGroup>

View File

@ -78,6 +78,7 @@ namespace AsbCloudWebApi.Controllers
public override async Task<ActionResult<T>> GetAsync(int id, CancellationToken token)
{
var actionResult = await base.GetAsync(id, token);
// TODO: this can be nullref
var result = actionResult.Value;
if (!await UserHasAccesToWellAsync(result.IdWell, token))
return Forbid();

View File

@ -0,0 +1,23 @@
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace AsbCloudWebApi.Controllers.Subsystems
{
/// <summary>
/// Редактор подсистем для админки
/// </summary>
[Route("api/admin/subsystem")]
[ApiController]
[Authorize]
public class AdminSubsystemController : CrudController<SubsystemDto, ICrudService<SubsystemDto>>
{
public AdminSubsystemController(ICrudService<SubsystemDto> service)
: base(service)
{
}
}
}

View File

@ -0,0 +1,103 @@
using AsbCloudApp.Data.Subsystems;
using AsbCloudApp.Requests;
using AsbCloudApp.Services;
using AsbCloudApp.Services.Subsystems;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudWebApi.Controllers.Subsystems
{
/// <summary>
/// Наработка подсистем
/// </summary>
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class SubsystemOperationTimeController : ControllerBase
{
private readonly ISubsystemOperationTimeService subsystemOperationTimeService;
private readonly IWellService wellService;
private readonly ISubsystemService subsystemService;
public SubsystemOperationTimeController(ISubsystemOperationTimeService subsystemOperationTimeService, IWellService wellService, ISubsystemService subsystemService)
{
this.subsystemOperationTimeService = subsystemOperationTimeService;
this.wellService = wellService;
this.subsystemService = subsystemService;
}
/// <summary>
/// получить статистику
/// </summary>
[HttpGet("stat")]
[ProducesResponseType(typeof(IEnumerable<SubsystemStatDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetStatAsync([FromQuery] SubsystemOperationTimeRequest request, CancellationToken token = default)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
return Forbid();
var subsystemResult = await subsystemOperationTimeService.GetStatAsync(request, token);
return Ok(subsystemResult);
}
/// <summary>
/// получить список подсистем общий.
/// </summary>
[HttpGet("subsystem")]
[ProducesResponseType(typeof(IEnumerable<SubsystemDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetSubsystemAsync([FromQuery] int? idWell, CancellationToken token = default)
{
if (idWell.HasValue)
if (!await UserHasAccesToWellAsync(idWell.Value, token))
return Forbid();
var result = await subsystemService.GetSubsystemAsync(idWell, token);
return Ok(result);
}
/// <summary>
/// получить список наработок подсистем
/// </summary>
[HttpGet("operationTime")]
[ProducesResponseType(typeof(IEnumerable<SubsystemOperationTimeDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetOperationTimeAsync(
[FromQuery] SubsystemOperationTimeRequest request,
CancellationToken token = default)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
return Forbid();
var result = await subsystemOperationTimeService.GetOperationTimeAsync(request, token);
return Ok(result);
}
/// <summary>
/// Удалить наработки.
/// </summary>
/// <param name="request"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpDelete]
[Permission]
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> DeleteAsync(
[FromQuery] SubsystemOperationTimeRequest request,
CancellationToken token)
{
if (!await UserHasAccesToWellAsync(request.IdWell, token))
return Forbid();
var result = await subsystemOperationTimeService.DeleteAsync(request, token);
return Ok(result);
}
protected async Task<bool> UserHasAccesToWellAsync(int idWell, CancellationToken token)
{
var idCompany = User.GetCompanyId();
if (idCompany is not null &&
await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token)
.ConfigureAwait(false))
return true;
return false;
}
}
}

View File

@ -8,13 +8,15 @@
<ItemGroup>
<Compile Remove="Connected Services\**" />
<Compile Remove="Properties\**" />
<EmbeddedResource Remove="Connected Services\**" />
<EmbeddedResource Remove="Properties\**" />
<None Remove="Connected Services\**" />
<None Remove="Properties\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.57.0.2684" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
@ -32,9 +34,4 @@
<ProjectReference Include="..\AsbCloudInfrastructure\AsbCloudInfrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
</Project>

View File

@ -1,145 +0,0 @@
using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using System.IO;
using System.Linq;
// usage example at the very bottom
namespace ConsoleApp1
{
public class GoogleDriveService
{
private readonly DriveService service;
public GoogleDriveService()
{ // ключи для почты asbautodrilling@gmail.com.
var tokenResponse = new TokenResponse
{
AccessToken = "ya29.a0ARrdaM-lM7q0TIC_DXixR4oW63QUftjSPHl-8nIdvZwtqA8Z1bXtlYpDrQXj9UFTjW8FW8uqPMrdamUSp4kO4a9JX7FddkBWxaJ_omSJpqzDfnHTHA_7-zGMUohaAsmPLsQtFz_GUmB5ZoVLmA8xWdbJxVxU",
RefreshToken = "1//04FeDguc19IfgCgYIARAAGAQSNwF-L9Ir8U7wX2seanUzsxXXGgFzOYQqjbtN9O27ZZybbOobZjVAo_4_eFNLMX1ElPKOFVWsrJQ"
};
var applicationName = "Files"; // Use the name of the project in Google Cloud
var username = "asbautodrilling@gmail.com"; // Use your email
var apiCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = new ClientSecrets
{
ClientId = "1020584579240-f7amqg35qg7j94ta1ntgitajq27cgh49.apps.googleusercontent.com",
ClientSecret = "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"
},
Scopes = new[] { DriveService.Scope.Drive },
DataStore = new FileDataStore(applicationName)
});
var credential = new UserCredential(apiCodeFlow, username, tokenResponse);
var newService = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = applicationName
});
this.service = newService;
}
// public IEnumerable<Google.Apis.Drive.v3.Data.File> GetAllFiles() // get file names
// {
// var fileList = service.Files.List();
// fileList.Fields = "files(id, webViewLink, size)";
// //fileList.Q =$"mimeType!='application/vnd.google-apps.folder' and '{folder}' in parents";
// //fileList.Fields = "nextPageToken, files(id, name, size, mimeType)";
//
// var result = new List<Google.Apis.Drive.v3.Data.File>();
// string pageToken = null;
// do
// {
// fileList.PageToken = pageToken;
// var filesResult = fileList.Execute();
// var files = filesResult.Files;
// pageToken = filesResult.NextPageToken;
// result.AddRange(files);
// } while (pageToken != null);
//
// return result;
// }
public string GetFileWebLink(string idFile)
{
var fileList = service.Files.List();
fileList.Fields = "files(id, webViewLink, size)";
var filesResult = fileList.Execute();
var file = filesResult.Files.FirstOrDefault(f => f.Id == idFile);
return file?.WebViewLink ?? string.Empty;
}
// У Гугла почему-то folder это и папка, и файл.
public string CreateFolder(string folderName)
{
var driveFolder = new Google.Apis.Drive.v3.Data.File();
driveFolder.Name = folderName;
driveFolder.MimeType = "application/vnd.google-apps.folder";
//driveFolder.Parents = new string[] { parent };
var command = service.Files.Create(driveFolder);
var file = command.Execute();
return file.Id;
}
public void CreatePublicPermissionForFile(string idFile)
{
var permission = new Permission() { Type = "anyone", Role = "reader" };
var addPermissionRequest = service.Permissions.Create(permission, idFile);
addPermissionRequest.Execute();
}
public string UploadFile(Stream file, string fileName, string fileMime, string fileDescription)
{
var driveFile = new Google.Apis.Drive.v3.Data.File();
driveFile.Name = fileName;
driveFile.Description = fileDescription;
driveFile.MimeType = fileMime;
//driveFile.Parents = new [] {folder};
var request = service.Files.Create(driveFile, file, fileMime);
request.Fields = "id";
var response = request.Upload();
if (response.Status != Google.Apis.Upload.UploadStatus.Completed)
throw response.Exception;
return request.ResponseBody.Id;
}
public void DeleteFile(string fileId)
{
var command = service.Files.Delete(fileId);
var result = command.Execute();
}
}
}
// usage example:
// var service = new GoogleDriveService();
//
// //var files = serviceWrapper.GetAllFiles();
//
// // foreach (var file in files)
// // {
// // var permission = new Permission() { Type = "anyone", Role = "reader"};
// // var createRequest = service.Permissions.Create(permission, file.Id);
// // createRequest.Execute();
// // Console.WriteLine(file.WebViewLink);
// // }
//
// var path = "/home/cult/First.xlsx";
// var fileInfo = new FileInfo(path);
// var fileStream = System.IO.File.Open(path, FileMode.Open);
// var uploadedFileId = service.UploadFileAsync(fileStream, fileInfo.Name, "", "uploaded");
// service.CreatePublicPermissionForFileAsync(uploadedFileId);
// var webLink = service.GetFileWebLinkAsync(uploadedFileId);
// Console.WriteLine(webLink);