forked from ddrilling/AsbCloudServer
merge dev to this
This commit is contained in:
commit
00dd39b587
@ -6,7 +6,6 @@ namespace AsbCloudApp.Data
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Caption { get; set; }
|
||||
public string Description { get; set; }
|
||||
public double? Latitude { get; set; }
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
|
@ -6,7 +6,6 @@ namespace AsbCloudApp.Data
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Caption { get; set; }
|
||||
public string Description { get; set; }
|
||||
public double? Latitude { get; set; }
|
||||
public double? Longitude { get; set; }
|
||||
|
||||
|
12
AsbCloudApp/Data/SetpointInfoDto.cs
Normal file
12
AsbCloudApp/Data/SetpointInfoDto.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class SetpointInfoDto
|
||||
{
|
||||
public string DisplayName { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Units { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public double Max { get; set; }
|
||||
public double Min { get; set; }
|
||||
}
|
||||
}
|
30
AsbCloudApp/Data/SetpointsRequestDto.cs
Normal file
30
AsbCloudApp/Data/SetpointsRequestDto.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Data
|
||||
{
|
||||
public class SetpointsRequestDto : IId
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public int IdWell { get; set; }
|
||||
|
||||
public int IdAuthor { get; set; }
|
||||
|
||||
public int IdState { get; set; }
|
||||
|
||||
public DateTime UploadDate { get; set; }
|
||||
|
||||
public int ObsolescenceSec { get; set; }
|
||||
|
||||
public Dictionary<string, double> Setpoints { get; set; }
|
||||
public string Comment { get; set; }
|
||||
|
||||
public WellDto Well { get; set; }
|
||||
|
||||
public UserDto Author { get; set; }
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ namespace AsbCloudApp.Data
|
||||
public double? Longitude { get; set; }
|
||||
public string WellType { get; set; }
|
||||
public int IdWellType { get; set; }
|
||||
|
||||
public int? IdCluster { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0 - незвестно,
|
||||
|
@ -5,8 +5,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface IWellOperationsStatService
|
||||
public interface IOperationsStatService
|
||||
{
|
||||
Task<ClusterRopStatDto> GetRopStatByIdWellAsync(int idWell, CancellationToken token);
|
||||
Task<ClusterRopStatDto> GetRopStatByUidAsync(string uid, CancellationToken token);
|
||||
Task<StatClusterDto> GetStatClusterAsync(int idCluster, int idCompany, CancellationToken token = default);
|
||||
Task<StatWellDto> GetStatWellAsync(int idWell, CancellationToken token = default);
|
||||
Task<IEnumerable<PlanFactPredictBase<WellOperationDto>>> GetTvdAsync(int idWell, CancellationToken token);
|
20
AsbCloudApp/Services/ISetpointsService.cs
Normal file
20
AsbCloudApp/Services/ISetpointsService.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using AsbCloudApp.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudApp.Services
|
||||
{
|
||||
public interface ISetpointsService
|
||||
{
|
||||
Task<int> InsertAsync(SetpointsRequestDto setpoints, CancellationToken token);
|
||||
Task<IEnumerable<SetpointsRequestDto>> GetAsync(int idWell, CancellationToken token);
|
||||
Task<IEnumerable<SetpointsRequestDto>> GetForPanelAsync(string uid, CancellationToken token);
|
||||
Task<int> TryDelete(int idWell, int id, CancellationToken token);
|
||||
Task<int> UpdateStateAsync(string uid, int id, SetpointsRequestDto setpointsRequestDto, CancellationToken token);
|
||||
IEnumerable<SetpointInfoDto> GetSetpointsNames(int idWell);
|
||||
}
|
||||
}
|
@ -18,5 +18,6 @@ namespace AsbCloudApp.Services
|
||||
bool IsCompanyInvolvedInWell(int idCompany, int idWell);
|
||||
string GetStateText(int state);
|
||||
DateTime GetLastTelemetryDate(int idWell);
|
||||
Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token);
|
||||
}
|
||||
}
|
||||
|
2841
AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs
generated
Normal file
2841
AsbCloudDb/Migrations/20211124111523_AddSetpoints.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
61
AsbCloudDb/Migrations/20211124111523_AddSetpoints.cs
Normal file
61
AsbCloudDb/Migrations/20211124111523_AddSetpoints.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class AddSetpoints : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "t_setpoints_rquest",
|
||||
columns: table => new
|
||||
{
|
||||
id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
id_well = table.Column<int>(type: "integer", nullable: false, comment: "id скважины"),
|
||||
id_author = table.Column<int>(type: "integer", nullable: false, comment: "Id пользователя, загрузившего файл"),
|
||||
id_state = table.Column<int>(type: "integer", nullable: false, comment: "0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело"),
|
||||
date = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
obsolescence = table.Column<int>(type: "integer", nullable: false, comment: "сек. до устаревания"),
|
||||
setpoint_set = table.Column<Dictionary<string, double>>(type: "jsonb", nullable: true, comment: "Набор уставок"),
|
||||
comment = table.Column<string>(type: "text", nullable: true, comment: "комментарий для оператора")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_t_setpoints_rquest", x => x.id);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_setpoints_rquest_t_user_id_author",
|
||||
column: x => x.id_author,
|
||||
principalTable: "t_user",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_t_setpoints_rquest_t_well_id_well",
|
||||
column: x => x.id_well,
|
||||
principalTable: "t_well",
|
||||
principalColumn: "id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
},
|
||||
comment: "Запросы на изменение уставок панели оператора");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_setpoints_rquest_id_author",
|
||||
table: "t_setpoints_rquest",
|
||||
column: "id_author");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_t_setpoints_rquest_id_well",
|
||||
table: "t_setpoints_rquest",
|
||||
column: "id_well");
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "t_setpoints_rquest");
|
||||
}
|
||||
}
|
||||
}
|
2841
AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs
generated
Normal file
2841
AsbCloudDb/Migrations/20211202064227_RenameTable_WellComposite.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
namespace AsbCloudDb.Migrations
|
||||
{
|
||||
public partial class RenameTable_WellComposite : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_well_сomposite",
|
||||
table: "t_well_сomposite");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_well_сomposite",
|
||||
newName: "t_well_composite");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_well_сomposite_id_well_src",
|
||||
table: "t_well_composite",
|
||||
newName: "IX_t_well_composite_id_well_src");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_well_сomposite_id_well_section_type",
|
||||
table: "t_well_composite",
|
||||
newName: "IX_t_well_composite_id_well_section_type");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_well_composite",
|
||||
table: "t_well_composite",
|
||||
columns: new[] { "id_well", "id_well_src", "id_well_section_type" });
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropPrimaryKey(
|
||||
name: "PK_t_well_composite",
|
||||
table: "t_well_composite");
|
||||
|
||||
migrationBuilder.RenameTable(
|
||||
name: "t_well_composite",
|
||||
newName: "t_well_сomposite");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_well_composite_id_well_src",
|
||||
table: "t_well_сomposite",
|
||||
newName: "IX_t_well_сomposite_id_well_src");
|
||||
|
||||
migrationBuilder.RenameIndex(
|
||||
name: "IX_t_well_composite_id_well_section_type",
|
||||
table: "t_well_сomposite",
|
||||
newName: "IX_t_well_сomposite_id_well_section_type");
|
||||
|
||||
migrationBuilder.AddPrimaryKey(
|
||||
name: "PK_t_well_сomposite",
|
||||
table: "t_well_сomposite",
|
||||
columns: new[] { "id_well", "id_well_src", "id_well_section_type" });
|
||||
}
|
||||
}
|
||||
}
|
@ -834,6 +834,60 @@ namespace AsbCloudDb.Migrations
|
||||
.HasComment("Отчеты с данными по буровым");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id")
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("comment")
|
||||
.HasComment("комментарий для оператора");
|
||||
|
||||
b.Property<int>("IdAuthor")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_author")
|
||||
.HasComment("Id пользователя, загрузившего файл");
|
||||
|
||||
b.Property<int>("IdState")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_state")
|
||||
.HasComment("0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело");
|
||||
|
||||
b.Property<int>("IdWell")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("id_well")
|
||||
.HasComment("id скважины");
|
||||
|
||||
b.Property<int>("ObsolescenceSec")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("obsolescence")
|
||||
.HasComment("сек. до устаревания");
|
||||
|
||||
b.Property<Dictionary<string, double>>("Setpoints")
|
||||
.HasColumnType("jsonb")
|
||||
.HasColumnName("setpoint_set")
|
||||
.HasComment("Набор уставок");
|
||||
|
||||
b.Property<DateTime>("UploadDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdAuthor");
|
||||
|
||||
b.HasIndex("IdWell");
|
||||
|
||||
b.ToTable("t_setpoints_rquest");
|
||||
|
||||
b
|
||||
.HasComment("Запросы на изменение уставок панели оператора");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.Telemetry", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
@ -1824,7 +1878,7 @@ namespace AsbCloudDb.Migrations
|
||||
|
||||
b.HasIndex("IdWellSrc");
|
||||
|
||||
b.ToTable("t_well_сomposite");
|
||||
b.ToTable("t_well_composite");
|
||||
|
||||
b
|
||||
.HasComment("Композитная скважина");
|
||||
@ -2613,6 +2667,25 @@ namespace AsbCloudDb.Migrations
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.SetpointsRequest", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.User", "Author")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdAuthor")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AsbCloudDb.Model.Well", "Well")
|
||||
.WithMany()
|
||||
.HasForeignKey("IdWell")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Author");
|
||||
|
||||
b.Navigation("Well");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AsbCloudDb.Model.TelemetryAnalysis", b =>
|
||||
{
|
||||
b.HasOne("AsbCloudDb.Model.WellOperationCategory", "Operation")
|
||||
|
@ -21,6 +21,7 @@ namespace AsbCloudDb.Model
|
||||
public virtual DbSet<Measure> Measures { get; set; }
|
||||
public virtual DbSet<MeasureCategory> MeasureCategories { get; set; }
|
||||
public virtual DbSet<ReportProperty> ReportProperties { get; set; }
|
||||
public virtual DbSet<SetpointsRequest> SetpointsRequests { get; set; }
|
||||
public virtual DbSet<Telemetry> Telemetries { get; set; }
|
||||
public virtual DbSet<TelemetryDataSaub> TelemetryDataSaub { get; set; }
|
||||
public virtual DbSet<TelemetryDataSpin> TelemetryDataSpin { get; set; }
|
||||
|
43
AsbCloudDb/Model/SetpointsRequest.cs
Normal file
43
AsbCloudDb/Model/SetpointsRequest.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_setpoints_rquest"), Comment("Запросы на изменение уставок панели оператора")]
|
||||
public class SetpointsRequest : IId, IIdWell
|
||||
{
|
||||
[Key]
|
||||
[Column("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("id_well"), Comment("id скважины")]
|
||||
public int IdWell { get; set; }
|
||||
|
||||
[Column("id_author"), Comment("Id пользователя, загрузившего файл")]
|
||||
public int IdAuthor { get; set; }
|
||||
|
||||
[Column("id_state"), Comment("0: неизвестно, 1:ожидает отправки, 2: отправлено, 3: принято оператором, 4: отклонено оператором, 5: устарело")]
|
||||
public int IdState { get; set; }
|
||||
|
||||
[Column("date", TypeName = "timestamp with time zone")]
|
||||
public DateTime UploadDate { get; set; }
|
||||
|
||||
[Column("obsolescence"), Comment("сек. до устаревания")]
|
||||
public int ObsolescenceSec { get; set; }
|
||||
|
||||
[Column("setpoint_set", TypeName = "jsonb"), Comment("Набор уставок")]
|
||||
public Dictionary<string, double> Setpoints { get; set; }
|
||||
|
||||
[Column("comment"), Comment("комментарий для оператора")]
|
||||
public string Comment { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdWell))]
|
||||
public virtual Well Well { get; set; }
|
||||
|
||||
[ForeignKey(nameof(IdAuthor))]
|
||||
public virtual User Author { get; set; }
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||
#nullable disable
|
||||
namespace AsbCloudDb.Model
|
||||
{
|
||||
[Table("t_well_сomposite"), Comment("Композитная скважина")]
|
||||
[Table("t_well_composite"), Comment("Композитная скважина")]
|
||||
public class WellComposite : IIdWell
|
||||
{
|
||||
[Column("id_well"), Comment("Id скважины получателя")]
|
||||
|
@ -17,7 +17,7 @@ dotnet ef migrations remvoe <MigrationName> --project AsbCloudDb
|
||||
#backup
|
||||
```
|
||||
sudo -u postgres pg_dump -Fc -U postgres postgres -W | gzip > 2021-09-27_dump.sql.gz
|
||||
sudo -u postgres pg_dump -Fc -U postgres postgres -W > 2021-11-13_dump.sql.gz
|
||||
sudo -u postgres pg_dump -Fc -U postgres postgres -W > 2021-11-26_dump.sql
|
||||
```
|
||||
|
||||
#restore
|
||||
|
@ -8,11 +8,21 @@ using AsbCloudInfrastructure.Services.WellOperationService;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
|
||||
namespace AsbCloudInfrastructure
|
||||
{
|
||||
public static class DependencyInjection
|
||||
{
|
||||
public static IAsbCloudDbContext MakeContext(string connectionString)
|
||||
{
|
||||
var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
|
||||
.UseNpgsql(connectionString)
|
||||
.Options;
|
||||
var context = new AsbCloudDbContext(options);
|
||||
return context;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddDbContext<AsbCloudDbContext>(options =>
|
||||
@ -47,8 +57,15 @@ namespace AsbCloudInfrastructure
|
||||
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellOperationService, WellOperationService>();
|
||||
services.AddTransient<IWellOperationsStatService, WellOperationsStatService>();
|
||||
services.AddTransient<IWellService, WellService>();
|
||||
services.AddTransient<IOperationsStatService, OperationsStatService>();
|
||||
services.AddTransient<IWellOperationImportService, WellOperationImportService>();
|
||||
services.AddTransient<IWellCompositeService, WellCompositeService>();
|
||||
services.AddTransient<IMeasureService, MeasureService>();
|
||||
services.AddTransient<IDrillingProgramService, DrillingProgramService>();
|
||||
services.AddTransient<IDrillParamsService, DrillParamsService>();
|
||||
services.AddTransient<IDrillFlowChartService, DrillFlowChartService>();
|
||||
services.AddTransient<ITimeZoneService, TimeZoneService>();
|
||||
services.AddTransient<ISetpointsService, SetpointsService>();
|
||||
|
||||
// admin crud services:
|
||||
services.AddTransient<ICrudService<ClusterDto>, CrudServiceBase<ClusterDto, Cluster>>();
|
||||
@ -67,5 +84,18 @@ namespace AsbCloudInfrastructure
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>()
|
||||
.AddTransient(provider => new Lazy<TService>(provider.GetService<TService>));
|
||||
|
||||
public static IServiceCollection AddTransientLazy<TService, TImplementation>(this IServiceCollection services, Func<IServiceProvider, TImplementation> implementationFactory)
|
||||
where TService : class
|
||||
where TImplementation : class, TService
|
||||
=> services.AddTransient<TService, TImplementation>(implementationFactory)
|
||||
.AddTransient(provider => new Lazy<TService>(() => implementationFactory(provider)));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@ -10,7 +11,7 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
private readonly ConcurrentDictionary<string, CacheTableDataStore> cache =
|
||||
new ConcurrentDictionary<string, CacheTableDataStore>();
|
||||
|
||||
public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context)
|
||||
public CacheTable<TEntity> GetCachedTable<TEntity>(DbContext context, IEnumerable<string> includes = null)
|
||||
where TEntity : class
|
||||
{
|
||||
var nameOfTEntity = typeof(TEntity).FullName;
|
||||
@ -18,7 +19,7 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
NameOfTEntity = nameOfTEntity,
|
||||
Entities = new List<TEntity>(),
|
||||
});
|
||||
var tableCache = new CacheTable<TEntity>(context, cacheItem);
|
||||
var tableCache = new CacheTable<TEntity>(context, cacheItem, includes);
|
||||
return tableCache;
|
||||
}
|
||||
|
||||
|
@ -18,17 +18,42 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
private static readonly string nameOfTEntity = typeof(TEntity).Name;
|
||||
|
||||
private readonly CacheTableDataStore data;
|
||||
private readonly Func<DbSet<TEntity>, IQueryable<TEntity>> configureDbSet;
|
||||
private readonly List<TEntity> cached;
|
||||
private readonly DbContext context;
|
||||
private readonly DbSet<TEntity> dbSet;
|
||||
|
||||
internal CacheTable(DbContext context, CacheTableDataStore data)
|
||||
internal CacheTable(DbContext context, CacheTableDataStore data, IEnumerable<string> includes = null)
|
||||
{
|
||||
this.context = context;
|
||||
this.data = data;
|
||||
dbSet = context.Set<TEntity>();
|
||||
|
||||
if (includes?.Any() == true)
|
||||
configureDbSet = (DbSet<TEntity> dbSet) =>
|
||||
{
|
||||
IQueryable<TEntity> result = dbSet;
|
||||
foreach (var include in includes)
|
||||
result = result.Include(include);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
cached = (List<TEntity>)data.Entities;
|
||||
if ((cached.Count == 0)||data.IsObsolete)
|
||||
if ((cached.Count == 0) || data.IsObsolete)
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
internal CacheTable(DbContext context, CacheTableDataStore data, Func<DbSet<TEntity>, IQueryable<TEntity>> configureDbSet = null)
|
||||
{
|
||||
this.context = context;
|
||||
this.data = data;
|
||||
this.configureDbSet = configureDbSet;
|
||||
|
||||
dbSet = context.Set<TEntity>();
|
||||
|
||||
cached = (List<TEntity>)data.Entities;
|
||||
if ((cached.Count == 0) || data.IsObsolete)
|
||||
Refresh(false);
|
||||
}
|
||||
|
||||
@ -97,7 +122,8 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
||||
{
|
||||
cached.Clear();
|
||||
var entities = dbSet.AsNoTracking().ToList();
|
||||
IQueryable<TEntity> query = configureDbSet is null ? dbSet : configureDbSet(dbSet);
|
||||
var entities = query.AsNoTracking().ToList();
|
||||
//Trace.WriteLine($"CacheTable<{nameOfTEntity}> refresh");
|
||||
cached.AddRange(entities);
|
||||
data.LastResreshDate = DateTime.Now;
|
||||
@ -109,7 +135,8 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
if (force || data.LastResreshDate + minPeriodRefresh < DateTime.Now)
|
||||
{
|
||||
cached.Clear();
|
||||
var entities = await context.Set<TEntity>().AsNoTracking()
|
||||
IQueryable<TEntity> query = configureDbSet is null ? dbSet : configureDbSet(dbSet);
|
||||
var entities = await query.AsNoTracking()
|
||||
.ToListAsync(token).ConfigureAwait(false);
|
||||
//Trace.WriteLine($"CacheTable<{nameOfTEntity}> refreshAsync");
|
||||
cached.AddRange(entities);
|
||||
@ -246,8 +273,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
dbSet.Update(entity);
|
||||
else
|
||||
dbSet.Add(entity);
|
||||
context.SaveChanges();
|
||||
InternalRefresh(true);
|
||||
var affected = context.SaveChanges();
|
||||
if (affected > 0)
|
||||
InternalRefresh(true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -257,8 +285,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
dbSet.Update(entity);
|
||||
else
|
||||
dbSet.Add(entity);
|
||||
await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
if(affected > 0)
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
}, token);
|
||||
|
||||
public void Upsert(IEnumerable<TEntity> entities)
|
||||
@ -275,8 +304,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
else
|
||||
dbSet.Add(entity);
|
||||
}
|
||||
context.SaveChanges();
|
||||
InternalRefresh(true);
|
||||
var affected = context.SaveChanges();
|
||||
if (affected > 0)
|
||||
InternalRefresh(true);
|
||||
});
|
||||
}
|
||||
|
||||
@ -294,8 +324,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
else
|
||||
dbSet.Add(entity);
|
||||
}
|
||||
await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
if (affected > 0)
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
}, token);
|
||||
}
|
||||
|
||||
@ -303,15 +334,17 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
=> Sync(_ =>
|
||||
{
|
||||
dbSet.RemoveRange(dbSet.Where(predicate));
|
||||
context.SaveChanges();
|
||||
InternalRefresh(true);
|
||||
var affected = context.SaveChanges();
|
||||
if (affected > 0)
|
||||
InternalRefresh(true);
|
||||
});
|
||||
|
||||
public Task RemoveAsync(Func<TEntity, bool> predicate, CancellationToken token = default)
|
||||
=> SyncAsync(async (wasFree, token) => {
|
||||
dbSet.RemoveRange(dbSet.Where(predicate));
|
||||
await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
if (affected > 0)
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
}, token);
|
||||
|
||||
public TEntity Insert(TEntity entity)
|
||||
@ -320,8 +353,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
Sync(_ =>
|
||||
{
|
||||
var entry = dbSet.Add(entity);
|
||||
context.SaveChanges();
|
||||
InternalRefresh(true);
|
||||
var affected = context.SaveChanges();
|
||||
if (affected > 0)
|
||||
InternalRefresh(true);
|
||||
result = entry.Entity;
|
||||
});
|
||||
return result;
|
||||
@ -333,8 +367,9 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
await SyncAsync(async (wasFree, token) =>
|
||||
{
|
||||
var entry = dbSet.Add(entity);
|
||||
await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
var affected = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
if (affected > 0)
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
result = entry.Entity;
|
||||
}, token);
|
||||
return result;
|
||||
@ -346,7 +381,8 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
Sync(_ => {
|
||||
dbSet.AddRange(newEntities);
|
||||
result = context.SaveChanges();
|
||||
InternalRefresh(true);
|
||||
if (result > 0)
|
||||
InternalRefresh(true);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@ -357,7 +393,8 @@ namespace AsbCloudInfrastructure.Services.Cache
|
||||
await SyncAsync(async (wasFree, token) => {
|
||||
dbSet.AddRange(newEntities);
|
||||
result = await context.SaveChangesAsync(token).ConfigureAwait(false);
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
if (result > 0)
|
||||
await InternalRefreshAsync(true, token).ConfigureAwait(false);
|
||||
}, token);
|
||||
return result;
|
||||
}
|
||||
|
@ -129,14 +129,12 @@ namespace AsbCloudInfrastructure.Services
|
||||
Caption = gDeposit.Key.Caption,
|
||||
Latitude = gDeposit.Key.Latitude,
|
||||
Longitude = gDeposit.Key.Longitude,
|
||||
Description = "",
|
||||
Clusters = gDeposit.Select(gCluster => new ClusterDto
|
||||
{
|
||||
Id = gCluster.Key.Id,
|
||||
Caption = gCluster.Key.Caption,
|
||||
Latitude = gCluster.Key.Latitude,
|
||||
Longitude = gCluster.Key.Longitude,
|
||||
Description = "",
|
||||
Wells = gCluster.Select(well => {
|
||||
var dto = well.Adapt<WellDto>();
|
||||
dto.WellType = well.WellType?.Caption;
|
||||
|
144
AsbCloudInfrastructure/Services/SetpointsService.cs
Normal file
144
AsbCloudInfrastructure/Services/SetpointsService.cs
Normal file
@ -0,0 +1,144 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudInfrastructure.Services.Cache;
|
||||
using Mapster;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
public class SetpointsService : ISetpointsService, IConverter<SetpointsRequestDto, SetpointsRequest>
|
||||
{
|
||||
// ## Инфо от АПГ от 26.11.2021, дополнения ШОВ от 26.11.2021
|
||||
private static readonly Dictionary<string, SetpointInfoDto> SetpointInfos = new ()
|
||||
{
|
||||
{ "bitLoad", new SetpointInfoDto { Name = "bitLoad", DisplayName = "Осевая нагрузка" } },
|
||||
{ "dPressureMaxRotorSP", new SetpointInfoDto { Name = "dPressureMaxRotorSP", DisplayName = "Дифференциальное рабочее давление в роторе" } },
|
||||
{ "dPressureMaxSlideSP", new SetpointInfoDto { Name = "dPressureMaxSlideSP", DisplayName = "Дифференциальное рабочее давление в слайде" } },
|
||||
{ "torque", new SetpointInfoDto { Name = "torque", DisplayName = "Крутящий момент" } },
|
||||
{ "speedRotorSp", new SetpointInfoDto { Name = "speedRotorSp", DisplayName = "Скорость бурения в роторе" } },
|
||||
{ "speedSlideSp", new SetpointInfoDto { Name = "speedSlideSp", DisplayName = "Скорость бурения в слайде" } },
|
||||
{ "speedDevelopSp", new SetpointInfoDto { Name = "speedDevelopSp", DisplayName = "Скорость проработки" } },
|
||||
//{ "", new SetpointInfoDto { Name = "", DisplayName = "Скорость обратной проработки" } }, // Такая же что и прямой
|
||||
//{ "", new SetpointInfoDto { Name = "", DisplayName = "Обороты ВСП" } }, // Оно в ПЛК спинмастера, пока сделать нельзя, позднее можно.
|
||||
//{ "", new SetpointInfoDto { Name = "", DisplayName = "Расход промывочной жидкости" } }, // Нет в контроллере
|
||||
};
|
||||
|
||||
private readonly CacheTable<SetpointsRequest> cacheSetpoints;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
|
||||
public SetpointsService(IAsbCloudDbContext db, CacheDb cacheDb, ITelemetryService telemetryService)
|
||||
{
|
||||
cacheSetpoints = cacheDb.GetCachedTable<SetpointsRequest>(
|
||||
(AsbCloudDbContext)db,
|
||||
new List<string> {
|
||||
nameof(SetpointsRequest.Author),
|
||||
nameof(SetpointsRequest.Well),
|
||||
});
|
||||
this.telemetryService = telemetryService;
|
||||
}
|
||||
|
||||
public async Task<int> InsertAsync(SetpointsRequestDto setpoints, CancellationToken token)
|
||||
{
|
||||
setpoints.IdState = 1;
|
||||
setpoints.UploadDate = DateTime.Now;
|
||||
var inserted = await cacheSetpoints.InsertAsync(Convert(setpoints), token)
|
||||
.ConfigureAwait(false);
|
||||
return inserted?.Id ?? 0;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointsRequestDto>> GetAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var entities = await cacheSetpoints.WhereAsync(s => s.IdWell == idWell, token)
|
||||
.ConfigureAwait(false);
|
||||
var dtos = entities.Select(s => Convert(s));
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<SetpointsRequestDto>> GetForPanelAsync(string uid, CancellationToken token)
|
||||
{
|
||||
var idWell = telemetryService.GetidWellByTelemetryUid(uid) ?? -1;
|
||||
|
||||
if (idWell < 0)
|
||||
return null;
|
||||
|
||||
var entities = (await cacheSetpoints.WhereAsync(s =>
|
||||
s.IdWell == idWell && s.IdState == 1 && s.UploadDate.AddSeconds(s.ObsolescenceSec) > DateTime.Now,
|
||||
token)
|
||||
.ConfigureAwait(false))
|
||||
.ToList();// без .ToList() работает не правильно.
|
||||
|
||||
if (!entities.Any())
|
||||
return null;
|
||||
|
||||
foreach (var entity in entities)
|
||||
entity.IdState = 2;
|
||||
|
||||
await cacheSetpoints.UpsertAsync(entities, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var dtos = entities.Select(Convert);
|
||||
|
||||
return dtos;
|
||||
}
|
||||
|
||||
public async Task<int> UpdateStateAsync(string uid, int id, SetpointsRequestDto setpointsRequestDto, CancellationToken token)
|
||||
{
|
||||
if (setpointsRequestDto.IdState != 3 && setpointsRequestDto.IdState != 4)
|
||||
throw new ArgumentOutOfRangeException(nameof(setpointsRequestDto), $"{nameof(setpointsRequestDto.IdState)} = {setpointsRequestDto.IdState}. Mast be 3 or 4.");
|
||||
|
||||
var idWell = telemetryService.GetidWellByTelemetryUid(uid) ?? -1;
|
||||
|
||||
if (idWell < 0)
|
||||
return 0;
|
||||
|
||||
bool Predicate(SetpointsRequest s) => s.Id == id && s.IdWell == idWell && s.IdState == 2;
|
||||
|
||||
var entity = await cacheSetpoints.FirstOrDefaultAsync(Predicate, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (entity is null)
|
||||
return 0;
|
||||
|
||||
entity.IdState = setpointsRequestDto.IdState;
|
||||
await cacheSetpoints.UpsertAsync(entity, token)
|
||||
.ConfigureAwait(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
public async Task<int> TryDelete(int idWell, int id, CancellationToken token)
|
||||
{
|
||||
bool Predicate(SetpointsRequest s) => s.Id == id && s.IdWell == idWell && s.IdState == 1;
|
||||
var isExist = await cacheSetpoints.ContainsAsync(Predicate, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!isExist)
|
||||
return 0;
|
||||
|
||||
await cacheSetpoints.RemoveAsync(Predicate, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
public SetpointsRequest Convert(SetpointsRequestDto src)
|
||||
{
|
||||
var entity = src.Adapt<SetpointsRequest>();
|
||||
return entity;
|
||||
}
|
||||
|
||||
public SetpointsRequestDto Convert(SetpointsRequest src)
|
||||
{
|
||||
var dto = src.Adapt<SetpointsRequestDto>();
|
||||
return dto;
|
||||
}
|
||||
|
||||
public IEnumerable<SetpointInfoDto> GetSetpointsNames(int idWell)
|
||||
=> SetpointInfos.Values;
|
||||
}
|
||||
}
|
@ -125,6 +125,25 @@ namespace AsbCloudInfrastructure.Services
|
||||
if (fullDataCount > 1.75 * approxPointsCount)
|
||||
{
|
||||
var m = (int)Math.Round(1d * fullDataCount / approxPointsCount);
|
||||
|
||||
switch (m)
|
||||
{
|
||||
//case var i when i <= 1: // тут для полноты, но никогда не сработает из-за условия выше
|
||||
// break;
|
||||
case var i when i < 10:
|
||||
query = query.Where((d) => d.Date.Second % m == 0);
|
||||
break;
|
||||
case var i when i < 30:
|
||||
query = query.Where((d) => (d.Date.Minute * 60 + d.Date.Second) % m == 0);
|
||||
break;
|
||||
case var i when i < 600:
|
||||
query = query.Where((d) => ((d.Date.Hour * 60 + d.Date.Minute) * 60 + d.Date.Second) % m == 0);
|
||||
break;
|
||||
default:
|
||||
query = query.Where((d) => (((d.Date.DayOfYear * 24 + d.Date.Hour) * 60 + d.Date.Minute) * 60 + d.Date.Second) % m == 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (m > 1)
|
||||
query = query.Where((d) => (((d.Date.DayOfYear*24 + d.Date.Hour)*60 + d.Date.Minute)*60 + d.Date.Second) % m == 0);
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ namespace AsbCloudInfrastructure.Services
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
db.Database.SetCommandTimeout(2 * 60);
|
||||
db.Database.SetCommandTimeout(2 * 60);
|
||||
var dates = await db.TelemetryDataSaub
|
||||
.GroupBy(d => d.IdTelemetry)
|
||||
.Select(g => new
|
||||
@ -77,9 +77,7 @@ namespace AsbCloudInfrastructure.Services
|
||||
.AsNoTracking()
|
||||
.ToListAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
db.Dispose();
|
||||
|
||||
|
||||
var oldReqs = dates.Select(t => new
|
||||
{
|
||||
Uid = cacheTelemetry.FirstOrDefault(c => c.Id == t.IdTelemetry)?.RemoteUid,
|
||||
@ -91,9 +89,13 @@ namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
var telemetryStat = telemetriesStats.GetOrAdd(oldReq.Uid, (uid) => new TrackerStat { RemoteUid = uid });
|
||||
telemetryStat.TelemetryDateMin = oldReq.DateMin;
|
||||
telemetryStat.TelemetryDateMax = oldReq.DateMax;
|
||||
telemetryStat.TelemetryDateMax = oldReq.DateMax;
|
||||
telemetryStat.LastTimeServer = oldReq.DateMax;
|
||||
}
|
||||
}).ContinueWith((t) =>
|
||||
{
|
||||
db.Dispose();
|
||||
return t;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,11 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
{
|
||||
public class WellOperationsStatService : IWellOperationsStatService
|
||||
public class OperationsStatService : IOperationsStatService
|
||||
{
|
||||
private readonly IAsbCloudDbContext db;
|
||||
private readonly IWellService wellService;
|
||||
private readonly ITelemetryService telemetryService;
|
||||
private readonly CacheTable<WellSectionType> cacheSectionsTypes;
|
||||
private readonly CacheTable<WellType> cacheWellType;
|
||||
private readonly CacheTable<Cluster> cacheCluster;
|
||||
@ -29,14 +30,33 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
private const int idOperationTypePlan = 0;
|
||||
private const int idOperationTypeFact = 1;
|
||||
|
||||
public WellOperationsStatService(IAsbCloudDbContext db, CacheDb cache, IWellService wellService)
|
||||
public OperationsStatService(IAsbCloudDbContext db, CacheDb cache, IWellService wellService,
|
||||
ITelemetryService telemetryService)
|
||||
{
|
||||
this.db = db;
|
||||
this.wellService = wellService;
|
||||
this.telemetryService = telemetryService;
|
||||
cacheSectionsTypes = cache.GetCachedTable<WellSectionType>((DbContext)db);
|
||||
cacheWellType = cache.GetCachedTable<WellType>((DbContext)db);
|
||||
cacheCluster = cache.GetCachedTable<Cluster>((DbContext)db);
|
||||
}
|
||||
|
||||
public async Task<ClusterRopStatDto> GetRopStatByIdWellAsync(int idWell,
|
||||
CancellationToken token)
|
||||
{
|
||||
return await GetRopStatAsync(idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<ClusterRopStatDto> GetRopStatByUidAsync(string uid,
|
||||
CancellationToken token)
|
||||
{
|
||||
var idWell = telemetryService.GetidWellByTelemetryUid(uid);
|
||||
|
||||
if (idWell is null)
|
||||
return null;
|
||||
|
||||
return await GetRopStatAsync((int)idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<StatClusterDto> GetStatClusterAsync(int idCluster, int idCompany, CancellationToken token = default)
|
||||
{
|
||||
@ -93,6 +113,52 @@ namespace AsbCloudInfrastructure.Services.WellOperationService
|
||||
return statWellDto;
|
||||
}
|
||||
|
||||
private async Task<ClusterRopStatDto> GetRopStatAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var clusterWellsIds = await wellService.GetClusterWellsIdsAsync(idWell, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (clusterWellsIds is null)
|
||||
return null;
|
||||
|
||||
var idLastSectionType = await (from o in db.WellOperations
|
||||
where o.IdWell == idWell &&
|
||||
o.IdType == 1
|
||||
orderby o.DepthStart
|
||||
select o.IdWellSectionType)
|
||||
.LastOrDefaultAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (idLastSectionType == default)
|
||||
return null;
|
||||
|
||||
var operations = await (from o in db.WellOperations
|
||||
where clusterWellsIds.Contains(o.IdWell) &&
|
||||
o.IdType == 1 &&
|
||||
o.IdWellSectionType == idLastSectionType
|
||||
select o)
|
||||
.ToListAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var statsList = clusterWellsIds.Select(clusterWellId =>
|
||||
{
|
||||
var currentWellOps = operations.Where(o => o.IdWell == clusterWellId);
|
||||
var stat = CalcStat(currentWellOps);
|
||||
return stat;
|
||||
}).Where(c => c is not null);
|
||||
|
||||
if (!statsList.Any())
|
||||
return null;
|
||||
|
||||
var clusterRops = new ClusterRopStatDto()
|
||||
{
|
||||
RopMax = statsList.Max(s => s.Rop),
|
||||
RopAverage = statsList.Average(s => s.Rop)
|
||||
};
|
||||
|
||||
return clusterRops;
|
||||
}
|
||||
|
||||
private async Task<StatWellDto> CalcStatWellAsync(Well well, CancellationToken token = default)
|
||||
{
|
||||
var wellType = await cacheWellType.FirstOrDefaultAsync(t => t.Id == well.IdWellType, token);
|
@ -138,6 +138,20 @@ namespace AsbCloudInfrastructure.Services
|
||||
_ => "Незвестно",
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<int>> GetClusterWellsIdsAsync(int idWell, CancellationToken token)
|
||||
{
|
||||
var well = await cacheWells.FirstOrDefaultAsync(w => w.Id == idWell)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (well is null)
|
||||
return null;
|
||||
|
||||
var clusterWells = await cacheWells.WhereAsync(w => w.IdCluster == well.IdCluster)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return clusterWells.Select(w => w.Id);
|
||||
}
|
||||
|
||||
private WellDto Convert(Well well)
|
||||
{
|
||||
@ -145,6 +159,7 @@ namespace AsbCloudInfrastructure.Services
|
||||
{
|
||||
Id = well.Id,
|
||||
Caption = well.Caption,
|
||||
IdCluster = well.IdCluster,
|
||||
Cluster = well.Cluster?.Caption,
|
||||
Deposit = well.Cluster?.Deposit?.Caption,
|
||||
LastTelemetryDate = GetLastTelemetryDate(well.Id),
|
||||
|
@ -1,67 +0,0 @@
|
||||
using AsbCloudApp.Data;
|
||||
using AsbCloudApp.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Контроллер статистики вручную внесенных операций на кусту
|
||||
/// </summary>
|
||||
[Route("api/cluster")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class ClusterOperationStatController : ControllerBase
|
||||
{
|
||||
private readonly IWellOperationService operationService;
|
||||
private readonly IWellService wellService;
|
||||
private readonly IWellOperationImportService wellOperationImportService;
|
||||
|
||||
public ClusterOperationStatController(IWellOperationService operationService,
|
||||
IWellService wellService, IWellOperationImportService wellOperationImportService)
|
||||
{
|
||||
this.operationService = operationService;
|
||||
this.wellService = wellService;
|
||||
this.wellOperationImportService = wellOperationImportService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формирует данные по среднему и максимальному МСП на кусту
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины с данного куста (через нее будут полуены данные)</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Возвращает данные по среднему и максимальному МСП на кусту</returns>
|
||||
[HttpGet("{idWell}/ropStat")]
|
||||
[ProducesResponseType(typeof(ClusterRopStatDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetClusterRopStatAsync([FromRoute] int idWell,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
// var result = await operationService.GetOperationsAsync(
|
||||
// idWell, token).ConfigureAwait(false);
|
||||
|
||||
var result = new ClusterRopStatDto()
|
||||
{
|
||||
RopMax = 3.2,
|
||||
RopAverage = 1.1
|
||||
};
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
private async Task<bool> CanUserAccessToWellAsync(int idWell, CancellationToken token = default)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,21 +10,59 @@ using System.Threading.Tasks;
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Контроллер секций скважины
|
||||
/// Контроллер статистики по операциям на скважине
|
||||
/// </summary>
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
[Route("api")]
|
||||
public class WellOperationStatController : ControllerBase
|
||||
public class OperationStatController : ControllerBase
|
||||
{
|
||||
private readonly IWellOperationsStatService operationsStatService;
|
||||
private readonly IOperationsStatService operationsStatService;
|
||||
private readonly IWellService wellService;
|
||||
|
||||
public WellOperationStatController(IWellOperationsStatService sectionsService, IWellService wellService)
|
||||
public OperationStatController(IOperationsStatService sectionsService, IWellService wellService)
|
||||
{
|
||||
this.operationsStatService = sectionsService;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формирует данные по среднему и максимальному МСП на кусту по id скважины
|
||||
/// </summary>
|
||||
/// <param name="idWell">id скважины с данного куста (через нее будут полуены данные)</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Возвращает данные по среднему и максимальному МСП на кусту</returns>
|
||||
[HttpGet("well/{idWell}/ropStat")]
|
||||
[ProducesResponseType(typeof(ClusterRopStatDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetClusterRopStatByIdWellAsync([FromRoute] int idWell,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
var result = await operationsStatService.GetRopStatByIdWellAsync(
|
||||
idWell, token).ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Формирует данные по среднему и максимальному МСП на кусту по uid панели
|
||||
/// </summary>
|
||||
/// <param name="uid">id передающей данные панели</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>Возвращает данные по среднему и максимальному МСП на кусту</returns>
|
||||
[HttpGet("telemetry/{uid}/ropStat")]
|
||||
[ProducesResponseType(typeof(ClusterRopStatDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetClusterRopStatByUidAsync([FromRoute] string uid,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var result = await operationsStatService.GetRopStatByUidAsync(
|
||||
uid, token).ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает статстику по скважинам куста
|
@ -16,6 +16,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последние `take` запросов к серверу
|
||||
/// </summary>
|
||||
/// <param name="take">от 1 до 1000</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IActionResult GetAll(int take = 512)
|
||||
{
|
||||
@ -23,6 +28,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последние `take` быстрых запросов к серверу
|
||||
/// </summary>
|
||||
/// <param name="take">от 1 до 1000</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("fast")]
|
||||
public IActionResult GetFast(int take = 512)
|
||||
{
|
||||
@ -30,6 +40,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последние `take` медленных запросов к серверу
|
||||
/// </summary>
|
||||
/// <param name="take">от 1 до 1000</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("slow")]
|
||||
public IActionResult GetSlow(int take = 512)
|
||||
{
|
||||
@ -37,6 +52,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последние `take` ошибок при выполнении запросов
|
||||
/// </summary>
|
||||
/// <param name="take">от 1 до 1000</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("error")]
|
||||
public IActionResult GetError(int take = 512)
|
||||
{
|
||||
@ -44,6 +64,11 @@ namespace AsbCloudWebApi.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получить последних пользователей обращавшихся к серверу. Уникальность пользователя проверяется по логину и Ip.
|
||||
/// </summary>
|
||||
/// <param name="take">от 1 до 1000</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("users")]
|
||||
public IActionResult GetUsersStat(int take = 512)
|
||||
{
|
||||
|
164
AsbCloudWebApi/Controllers/SetpointsController.cs
Normal file
164
AsbCloudWebApi/Controllers/SetpointsController.cs
Normal file
@ -0,0 +1,164 @@
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudApp.Data;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace AsbCloudWebApi.Controllers
|
||||
{
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class SetpointsController : ControllerBase
|
||||
{
|
||||
private readonly ISetpointsService setpointsService;
|
||||
private readonly IWellService wellService;
|
||||
private const int ObsolescenceSecMin = 30;
|
||||
private const int ObsolescenceSecMax = 6 * 60 * 60;
|
||||
|
||||
public SetpointsController(ISetpointsService setpointsService, IWellService wellService)
|
||||
{
|
||||
this.setpointsService = setpointsService;
|
||||
this.wellService = wellService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает список запросов на изменение уставок.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("api/well/{idWell}/setpointsNames")]
|
||||
[ProducesResponseType(typeof(IEnumerable<SetpointInfoDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[AllowAnonymous]
|
||||
public IActionResult GetSetpointsNamesByIdWellAsync([FromRoute] int idWell)
|
||||
{
|
||||
var result = setpointsService.GetSetpointsNames(idWell);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавляет запрос на изменение заданий панели оператора.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="setpoints"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("api/well/{idWell}/setpoints")]
|
||||
[ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> InsertAsync(int idWell, SetpointsRequestDto setpoints, CancellationToken token = default)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
int? idUser = User.GetUserId();
|
||||
|
||||
if (idCompany is null || idUser is null)
|
||||
return Forbid();
|
||||
|
||||
if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany,
|
||||
idWell, token).ConfigureAwait(false))
|
||||
return Forbid();
|
||||
|
||||
setpoints.IdAuthor = idUser ?? -1;
|
||||
setpoints.IdWell = idWell;
|
||||
setpoints.IdState = 1;
|
||||
|
||||
if (setpoints is null
|
||||
|| setpoints.ObsolescenceSec > ObsolescenceSecMax
|
||||
|| setpoints.ObsolescenceSec < ObsolescenceSecMin)
|
||||
return BadRequest("Wrong ObsolescenceSec");
|
||||
|
||||
if (!setpoints.Setpoints.Any())
|
||||
return BadRequest("Wrong Setpoints count");
|
||||
|
||||
var result = await setpointsService.InsertAsync(setpoints, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает список запросов на изменение уставок.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("api/well/{idWell}/setpoints")]
|
||||
[ProducesResponseType(typeof(IEnumerable<SetpointsRequestDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> GetByIdWellAsync([FromRoute] int idWell, CancellationToken token = default)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
int? idUser = User.GetUserId();
|
||||
|
||||
if (idCompany is null || idUser is null)
|
||||
return Forbid();
|
||||
|
||||
var result = await setpointsService.GetAsync(idWell, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Отчет о принятии, или отклонении уставок оператором.
|
||||
/// После уставка будет не изменяемой.
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="setpointsRequestDto">можно передать только новый state eg.: {state:3} - принято</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("api/telemetry/{uid}/setpoints/{id}")]
|
||||
[ProducesResponseType(typeof(SetpointsRequestDto), (int)System.Net.HttpStatusCode.OK)]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> UpdateByTelemetryUidAsync([FromRoute] string uid, int id, SetpointsRequestDto setpointsRequestDto, CancellationToken token = default)
|
||||
{
|
||||
var result = await setpointsService.UpdateStateAsync(uid, id, setpointsRequestDto, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает запросы на изменение уставок панели.
|
||||
/// !!SIDE EFFECT: изменяет состояние запросов уставок на отправлено, это не позволит удалить эти уставки после отправки на панель.
|
||||
/// </summary>
|
||||
/// <param name="uid"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("api/telemetry/{uid}/setpoints")]
|
||||
[ProducesResponseType(typeof(IEnumerable<SetpointsRequestDto>), (int)System.Net.HttpStatusCode.OK)]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> GetByTelemetryUidAsync([FromRoute] string uid, CancellationToken token = default)
|
||||
{
|
||||
var result = await setpointsService.GetForPanelAsync(uid, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Пробует удалить запрос на изменение уставок. Это будет выполнено, если запрос еще не был отправлен на панель.
|
||||
/// </summary>
|
||||
/// <param name="idWell"></param>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns>1 - удалено, 0 и меньше - не удалено</returns>
|
||||
[HttpDelete("api/well/{idWell}/setpoints/{id}")]
|
||||
public async Task<IActionResult> TryDeleteByIdWellAsync(int idWell, int id, CancellationToken token = default)
|
||||
{
|
||||
int? idCompany = User.GetCompanyId();
|
||||
int? idUser = User.GetUserId();
|
||||
|
||||
if (idCompany is null || idUser is null)
|
||||
return Forbid();
|
||||
|
||||
var result = await setpointsService.TryDelete(idWell, id, token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace AsbCloudWebApi
|
||||
{
|
||||
@ -8,6 +11,24 @@ namespace AsbCloudWebApi
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
//new TraceListenerView(); // to trace mysterious errors
|
||||
if(args?.Length > 0 )
|
||||
{
|
||||
if (args.Contains("db_init")) {
|
||||
var connectionStringName = "DefaultConnection";
|
||||
|
||||
IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
|
||||
.AddJsonFile("appsettings.json")
|
||||
.Build();
|
||||
|
||||
AsbCloudInfrastructure.DependencyInjection.MakeContext(configuration.GetConnectionString(connectionStringName));
|
||||
Console.WriteLine("Óñïåøíî âûïîëíåíî.");
|
||||
return;
|
||||
}
|
||||
WriteHelp();
|
||||
return;
|
||||
}
|
||||
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
@ -17,5 +38,17 @@ namespace AsbCloudWebApi
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
|
||||
private static void WriteHelp()
|
||||
{
|
||||
Console.WriteLine("Ïðè çàïóñêå áåç êëþ÷åé ïðîãðàììà ïðîñòî ñòàðòóåò â îáû÷íîì ðåæèìå.");
|
||||
Console.WriteLine("Êëþ÷è äëÿ çàïóñêà:");
|
||||
Console.WriteLine("db_init - ñîçäàòü êîíòåêñò ÁÄ è âûéòè.");
|
||||
Console.WriteLine("Êîíòåêñò ñîçäàñòñÿ äëÿ ñòðîêè ïîäêëþ÷åíèÿ \"DefaultConnection\"");
|
||||
Console.WriteLine("Ñîçäàíèå êîíòåêñòà ïðèâåäåò ê ñîçäàíèþ ÁÄ, åñëè åé íåò");
|
||||
Console.WriteLine("è ïðèìåíåíèþ âñåõ ìèãðàöèé, åñëè ÁÄ óæå åñòü.");
|
||||
Console.WriteLine("Äëÿ ñîçäàíèÿ êîíòåêñòà â ÁÄ äîëæíà áûòü ñîçäàíà ñõåìà public");
|
||||
Console.WriteLine("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,24 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.2e1e40de.chunk.css",
|
||||
"main.js": "/static/js/main.71c1bcb4.chunk.js",
|
||||
"main.js.map": "/static/js/main.71c1bcb4.chunk.js.map",
|
||||
"main.css": "/static/css/main.fb3df553.chunk.css",
|
||||
"main.js": "/static/js/main.47b40915.chunk.js",
|
||||
"main.js.map": "/static/js/main.47b40915.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.6870c5e2.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.6870c5e2.js.map",
|
||||
"static/js/2.6a982f4d.chunk.js": "/static/js/2.6a982f4d.chunk.js",
|
||||
"static/js/2.6a982f4d.chunk.js.map": "/static/js/2.6a982f4d.chunk.js.map",
|
||||
"static/js/2.8306ac4d.chunk.js": "/static/js/2.8306ac4d.chunk.js",
|
||||
"static/js/2.8306ac4d.chunk.js.map": "/static/js/2.8306ac4d.chunk.js.map",
|
||||
"static/js/3.c22d92b4.chunk.js": "/static/js/3.c22d92b4.chunk.js",
|
||||
"static/js/3.c22d92b4.chunk.js.map": "/static/js/3.c22d92b4.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/main.2e1e40de.chunk.css.map": "/static/css/main.2e1e40de.chunk.css.map",
|
||||
"static/js/2.6a982f4d.chunk.js.LICENSE.txt": "/static/js/2.6a982f4d.chunk.js.LICENSE.txt"
|
||||
"static/css/main.fb3df553.chunk.css.map": "/static/css/main.fb3df553.chunk.css.map",
|
||||
"static/js/2.8306ac4d.chunk.js.LICENSE.txt": "/static/js/2.8306ac4d.chunk.js.LICENSE.txt",
|
||||
"static/media/ClusterIcon.a395f860.svg": "/static/media/ClusterIcon.a395f860.svg",
|
||||
"static/media/DepositIcon.6de7c7ae.svg": "/static/media/DepositIcon.6de7c7ae.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.6870c5e2.js",
|
||||
"static/js/2.6a982f4d.chunk.js",
|
||||
"static/css/main.2e1e40de.chunk.css",
|
||||
"static/js/main.71c1bcb4.chunk.js"
|
||||
"static/js/2.8306ac4d.chunk.js",
|
||||
"static/css/main.fb3df553.chunk.css",
|
||||
"static/js/main.47b40915.chunk.js"
|
||||
]
|
||||
}
|
@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="manifest" href="/manifest.json"/><title>АСБ Vision</title><link href="/static/css/main.2e1e40de.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=r[2],s=0,p=[];s<i.length;s++)a=i[s],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&p.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);p.length;)p.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var c=t[i];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{3:"c22d92b4"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/",a.oe=function(e){throw console.error(e),e};var i=this.webpackJsonpasb_cloud_front_react=this.webpackJsonpasb_cloud_front_react||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var l=0;l<i.length;l++)r(i[l]);var f=c;t()}([])</script><script src="/static/js/2.6a982f4d.chunk.js"></script><script src="/static/js/main.71c1bcb4.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="manifest" href="/manifest.json"/><title>АСБ Vision</title><link href="/static/css/main.fb3df553.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=r[2],s=0,p=[];s<i.length;s++)a=i[s],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&p.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);p.length;)p.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var c=t[i];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{3:"c22d92b4"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/",a.oe=function(e){throw console.error(e),e};var i=this.webpackJsonpasb_cloud_front_react=this.webpackJsonpasb_cloud_front_react||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var l=0;l<i.length;l++)r(i[l]);var f=c;t()}([])</script><script src="/static/js/2.8306ac4d.chunk.js"></script><script src="/static/js/main.47b40915.chunk.js"></script></body></html>
|
Loading…
Reference in New Issue
Block a user