merge dev to this

This commit is contained in:
Фролов 2021-12-03 09:58:48 +05:00
commit 00dd39b587
33 changed files with 6614 additions and 123 deletions

View File

@ -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; }

View File

@ -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; }

View 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; }
}
}

View 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; }
}
}

View File

@ -11,6 +11,8 @@ namespace AsbCloudApp.Data
public string WellType { get; set; }
public int IdWellType { get; set; }
public int? IdCluster { get; set; }
/// <summary>
/// 0 - незвестно,
/// 1 - в работе,

View File

@ -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);

View 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);
}
}

View File

@ -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);
}
}

File diff suppressed because it is too large Load Diff

View 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");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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" });
}
}
}

View File

@ -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")

View File

@ -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; }

View 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; }
}
}

View File

@ -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 скважины получателя")]

View File

@ -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

View File

@ -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)));
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View 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;
}
}

View File

@ -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);
}

View File

@ -78,8 +78,6 @@ namespace AsbCloudInfrastructure.Services
.ToListAsync()
.ConfigureAwait(false);
db.Dispose();
var oldReqs = dates.Select(t => new
{
Uid = cacheTelemetry.FirstOrDefault(c => c.Id == t.IdTelemetry)?.RemoteUid,
@ -94,6 +92,10 @@ namespace AsbCloudInfrastructure.Services
telemetryStat.TelemetryDateMax = oldReq.DateMax;
telemetryStat.LastTimeServer = oldReq.DateMax;
}
}).ContinueWith((t) =>
{
db.Dispose();
return t;
});
}

View File

@ -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,15 +30,34 @@ 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)
{
var allWellsByCompany = await wellService.GetWellsByCompanyAsync(idCompany, token).ConfigureAwait(false);
@ -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);

View File

@ -139,12 +139,27 @@ 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)
{
return new WellDto
{
Id = well.Id,
Caption = well.Caption,
IdCluster = well.IdCluster,
Cluster = well.Cluster?.Caption,
Deposit = well.Cluster?.Deposit?.Caption,
LastTelemetryDate = GetLastTelemetryDate(well.Id),

View File

@ -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);
}
}
}

View File

@ -10,22 +10,60 @@ 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>
/// Получает статстику по скважинам куста
/// </summary>

View File

@ -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)
{

View 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);
}
}
}

View File

@ -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("");
}
}
}

View File

@ -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"
]
}

View File

@ -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>