diff --git a/AsbCloudApp/CyclycArray.cs b/AsbCloudApp/CyclicArray.cs similarity index 98% rename from AsbCloudApp/CyclycArray.cs rename to AsbCloudApp/CyclicArray.cs index b551d1c2..384b0fdd 100644 --- a/AsbCloudApp/CyclycArray.cs +++ b/AsbCloudApp/CyclicArray.cs @@ -6,7 +6,7 @@ namespace System.Collections.Generic /// Цикличный массив /// /// - public class CyclycArray : IEnumerable + public class CyclicArray : IEnumerable { readonly T[] array; int used, current = -1; @@ -15,7 +15,7 @@ namespace System.Collections.Generic /// constructor /// /// - public CyclycArray(int capacity) + public CyclicArray(int capacity) { array = new T[capacity]; } diff --git a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs index aba5593f..16a9749c 100644 --- a/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs +++ b/AsbCloudApp/Data/ProcessMaps/Report/ProcessMapReportWellDrillingDto.cs @@ -94,5 +94,5 @@ public class ProcessMapReportWellDrillingDto /// /// Механическая скорость, м/ч /// - public PlanFactDto Rop { get; set; } + public PlanFactDto Rop { get; set; } = new(); } \ No newline at end of file diff --git a/AsbCloudApp/Data/SectionByOperationsDto.cs b/AsbCloudApp/Data/SectionByOperationsDto.cs index 8123ad11..80b1fc3f 100644 --- a/AsbCloudApp/Data/SectionByOperationsDto.cs +++ b/AsbCloudApp/Data/SectionByOperationsDto.cs @@ -35,14 +35,18 @@ public class SectionByOperationsDto public DateTimeOffset DateStart { get; set; } /// - /// Глубина после завершения последней операции операции в секции, м + /// Глубина после завершения последней операции в секции, м /// [Range(0, 50_000)] public double DepthEnd { get; set; } /// - /// Дата после завершения последней операции операции в секции + /// Дата после завершения последней операции в секции /// public DateTimeOffset DateEnd { get; set; } - public string Caption { get; set; } + + /// + /// Название + /// + public string Caption { get; set; } = string.Empty; } diff --git a/AsbCloudApp/Repositories/ITelemetryDataCache.cs b/AsbCloudApp/Repositories/ITelemetryDataCache.cs index c31a0fbd..bce8d328 100644 --- a/AsbCloudApp/Repositories/ITelemetryDataCache.cs +++ b/AsbCloudApp/Repositories/ITelemetryDataCache.cs @@ -20,7 +20,7 @@ namespace AsbCloudApp.Repositories void AddRange(int idTelemetry, IEnumerable range); /// - /// вернуть последнюю записть + /// вернуть последнюю запись /// /// /// @@ -49,7 +49,7 @@ namespace AsbCloudApp.Repositories /// /// /// - DatesRangeDto? GetOrDefaultCachedaDateRange(int idTelemetry); + DatesRangeDto? GetOrDefaultCachedDateRange(int idTelemetry); /// /// Получить диапазон дат телеметрии. diff --git a/AsbCloudApp/Services/IWellFinalDocumentsService.cs b/AsbCloudApp/Services/IWellFinalDocumentsService.cs index 1d6196ca..8169b890 100644 --- a/AsbCloudApp/Services/IWellFinalDocumentsService.cs +++ b/AsbCloudApp/Services/IWellFinalDocumentsService.cs @@ -18,7 +18,7 @@ namespace AsbCloudApp.Services /// /// /// - Task UpdateRangeAsync(int idWell, IEnumerable? dtos, CancellationToken token); + Task UpdateRangeAsync(int idWell, IEnumerable dtos, CancellationToken token); /// /// Получение истории файлов diff --git a/AsbCloudDb/EFExtentions.cs b/AsbCloudDb/EFExtensions.cs similarity index 93% rename from AsbCloudDb/EFExtentions.cs rename to AsbCloudDb/EFExtensions.cs index 575480e3..9da4c626 100644 --- a/AsbCloudDb/EFExtentions.cs +++ b/AsbCloudDb/EFExtensions.cs @@ -12,14 +12,13 @@ using System.Threading.Tasks; namespace AsbCloudDb { - public static class EFExtentions + public static class EFExtensions { - private static readonly System.Text.Json.JsonSerializerOptions jsonSerializerOptions = new() + private static readonly JsonSerializerOptions jsonSerializerOptions = new() { AllowTrailingCommas = true, WriteIndented = true, - NumberHandling = System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString | - System.Text.Json.Serialization.JsonNumberHandling.AllowNamedFloatingPointLiterals, + NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.AllowNamedFloatingPointLiterals, }; public static Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder HasJsonConversion( @@ -28,11 +27,11 @@ namespace AsbCloudDb public static Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder HasJsonConversion( this Microsoft.EntityFrameworkCore.Metadata.Builders.PropertyBuilder builder, - System.Text.Json.JsonSerializerOptions jsonSerializerOptions) + JsonSerializerOptions jsonSerializerOptions) { builder.HasConversion( - s => System.Text.Json.JsonSerializer.Serialize(s, jsonSerializerOptions), - s => System.Text.Json.JsonSerializer.Deserialize(s, jsonSerializerOptions)!); + s => JsonSerializer.Serialize(s, jsonSerializerOptions), + s => JsonSerializer.Deserialize(s, jsonSerializerOptions)!); ValueComparer valueComparer = new ( (a,b) => @@ -102,7 +101,7 @@ namespace AsbCloudDb return factory.Columns; } - public static Microsoft.EntityFrameworkCore.ChangeTracking.EntityEntry Upsert(this DbSet dbSet, T value) + public static EntityEntry Upsert(this DbSet dbSet, T value) where T : class { return dbSet.Contains(value) diff --git a/AsbCloudDb/EFExtentionsInnitialization.cs b/AsbCloudDb/EFExtensionsInitialization.cs similarity index 92% rename from AsbCloudDb/EFExtentionsInnitialization.cs rename to AsbCloudDb/EFExtensionsInitialization.cs index 110a75ae..7c265b82 100644 --- a/AsbCloudDb/EFExtentionsInnitialization.cs +++ b/AsbCloudDb/EFExtensionsInitialization.cs @@ -5,9 +5,9 @@ using Microsoft.EntityFrameworkCore.Infrastructure; namespace AsbCloudDb { - public static class EFExtentionsInnitialization + public static class EFExtensionsInitialization { - public static void EnshureCreatedAndMigrated(this DatabaseFacade db) + public static void EnsureCreatedAndMigrated(this DatabaseFacade db) { db.SetCommandTimeout(TimeSpan.FromMinutes(5)); if (db.EnsureCreated()) diff --git a/AsbCloudDb/Model/AsbCloudDbContext.cs b/AsbCloudDb/Model/AsbCloudDbContext.cs index bd1e1690..43ede314 100644 --- a/AsbCloudDb/Model/AsbCloudDbContext.cs +++ b/AsbCloudDb/Model/AsbCloudDbContext.cs @@ -349,6 +349,10 @@ namespace AsbCloudDb.Model .HasJsonConversion(); }); + modelBuilder.Entity(entity => entity + .Property(p=>p.ExtraData) + .HasJsonConversion()); + modelBuilder.Entity(entity => { entity.HasNoKey() diff --git a/AsbCloudDb/Model/WellOperationCategory.cs b/AsbCloudDb/Model/WellOperationCategory.cs index 28acc79e..edba3581 100644 --- a/AsbCloudDb/Model/WellOperationCategory.cs +++ b/AsbCloudDb/Model/WellOperationCategory.cs @@ -42,7 +42,7 @@ namespace AsbCloudDb.Model /// /// КНБК /// - public const int IdKnbk = 4000; + public const int IdBha = 4000; /// /// Механическое. бурение @@ -246,7 +246,7 @@ namespace AsbCloudDb.Model /// Виды работ /// public static WellOperationCategory[] WorkTypes { get; } = new WellOperationCategory[]{ - new () {Id = IdKnbk, IdParent = 3000, Name = "КНБК", KeyValueName = "dT", KeyValueUnits = "мин" }, + new () {Id = IdBha, IdParent = 3000, Name = "КНБК", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdMechanicalDrilling, IdParent = 3000, Name = "Механическое. бурение", KeyValueName = "dT", KeyValueUnits = "м/ч" }, new () {Id = IdMeasurementStat, IdParent = 3000, Name = "Статический замер", KeyValueName = "dT", KeyValueUnits = "мин" }, new () {Id = IdNormalizedWellDiameter, IdParent = 3000, Name = "Нормализация диаметра скважины", KeyValueName = "dT", KeyValueUnits = "мин" }, diff --git a/AsbCloudInfrastructure/Background/BackgroundWorker.cs b/AsbCloudInfrastructure/Background/BackgroundWorker.cs index 1c641019..861c8a47 100644 --- a/AsbCloudInfrastructure/Background/BackgroundWorker.cs +++ b/AsbCloudInfrastructure/Background/BackgroundWorker.cs @@ -36,12 +36,12 @@ public class BackgroundWorker : BackgroundService /// /// последние 16 завершившиеся с ошибкой /// - public CyclycArray Felled { get; } = new(16); + public CyclicArray Felled { get; } = new(16); /// /// последние 16 успешно завершенных /// - public CyclycArray Done { get; } = new(16); + public CyclicArray Done { get; } = new(16); /// /// Ошибка в главном цикле, никогда не должна появляться diff --git a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkSubsystemOscillationOperationTimeCalc.cs b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkSubsystemOscillationOperationTimeCalc.cs index 1135385c..b2a6800f 100644 --- a/AsbCloudInfrastructure/Background/PeriodicWorks/WorkSubsystemOscillationOperationTimeCalc.cs +++ b/AsbCloudInfrastructure/Background/PeriodicWorks/WorkSubsystemOscillationOperationTimeCalc.cs @@ -167,7 +167,6 @@ public class WorkSubsystemOscillationOperationTimeCalc : WorkSubsystemOperationT .Where(d => d.IdTelemetry == idTelemetry) .Where(d => d.DateTime >= dateBegin) .Where(d => d.DateTime <= dateEnd) - .Where(d => d.WellDepth != null) .Where(d => d.WellDepth > 0) .GroupBy(d => Math.Ceiling(d.WellDepth * 10)) .Select(g => new diff --git a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs index 8c72be8e..9864ef4d 100644 --- a/AsbCloudInfrastructure/Repository/WellOperationRepository.cs +++ b/AsbCloudInfrastructure/Repository/WellOperationRepository.cs @@ -111,7 +111,8 @@ public class WellOperationRepository : IWellOperationRepository .ConfigureAwait(false); if (lastFactOperation is not null) - return DateTime.SpecifyKind(lastFactOperation.OperationPlan.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified); + return DateTime.SpecifyKind(lastFactOperation.OperationPlan!.DateStart.UtcDateTime + timeZoneOffset, DateTimeKind.Unspecified); + return null; } diff --git a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs index ae4aa1a9..92878495 100644 --- a/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs +++ b/AsbCloudInfrastructure/Services/DailyReport/DailyReportService.cs @@ -95,12 +95,10 @@ public class DailyReportService : IDailyReportService public async Task GetAsync(int idWell, DateTime dateDailyReport, CancellationToken cancellationToken) { - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); + var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) + ?? throw new ArgumentNullException(nameof(idWell), $"Скважина с Id: {idWell} не найдена"); - if (well is null) - throw new ArgumentNullException(nameof(idWell), $"Скважина с Id: {idWell} не найдена"); - - if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken)) + if (!await IsDateDailyReportInRangeAsync(idWell, dateDailyReport, cancellationToken)) throw new ArgumentInvalidException(nameof(dateDailyReport), "Невозможно получить суточный отчёт"); diff --git a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs index 3806e380..b9c7d201 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/Detectors/DetectorDrilling.cs @@ -61,10 +61,12 @@ public class DetectorDrilling : DetectorAbstract { var (avgRotorSpeed, dispersionOfNormalizedRotorSpeed) = CalcCriteries(telemetry, begin, end); var idCategory = GetIdOperation(avgRotorSpeed, dispersionOfNormalizedRotorSpeed); - var extraData = new Dictionary(); - extraData[ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed; - extraData[ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed; - extraData[ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold; + var extraData = new Dictionary + { + [ExtraDataKeyAvgRotorSpeed] = avgRotorSpeed, + [ExtraDataKeyDispersionOfNormalizedRotorSpeed] = dispersionOfNormalizedRotorSpeed, + [ExtraDataKeyHasOscillation] = dispersionOfNormalizedRotorSpeed > dispersionOfNormalizedRotorSpeedThreshold + }; return (idCategory, extraData); } diff --git a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs index 36b5cbf8..84e34f4c 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/WorkOperationDetection.cs @@ -118,6 +118,7 @@ public class WorkOperationDetection: Work { var data = await query .Where(d => d.DateTime > startDate) + .Take(take) .ToArrayAsync(token); if (data.Length < gap) diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index e4094c34..e1cd558a 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -13,203 +13,201 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace AsbCloudInfrastructure.Services +namespace AsbCloudInfrastructure.Services; + +public class ReportService : IReportService { + private readonly IAsbCloudDbContext db; + private readonly ITelemetryService telemetryService; + private readonly FileService fileService; + private readonly IWellService wellService; + private readonly BackgroundWorker backgroundWorkerService; - public class ReportService : IReportService + public int ReportCategoryId { get; private set; } + + public ReportService(IAsbCloudDbContext db, + ITelemetryService telemetryService, + IWellService wellService, + FileService fileService, + BackgroundWorker backgroundWorkerService) { - private readonly IAsbCloudDbContext db; - private readonly ITelemetryService telemetryService; - private readonly FileService fileService; - private readonly IWellService wellService; - private readonly BackgroundWorker backgroundWorkerService; - - public int ReportCategoryId { get; private set; } - - public ReportService(IAsbCloudDbContext db, - ITelemetryService telemetryService, - IWellService wellService, - FileService fileService, - BackgroundWorker backgroundWorkerService) - { - this.db = db; - this.wellService = wellService; - this.backgroundWorkerService = backgroundWorkerService; - this.telemetryService = telemetryService; - this.fileService = fileService; - ReportCategoryId = db.FileCategories - .AsNoTracking() - .First(c => c.Name.Equals("Рапорт")) - .Id; - } - - public string EnqueueCreateReportWork(int idWell, int idUser, int stepSeconds, int format, DateTime begin, - DateTime end, Action progressHandler) - { - var timezoneOffset = wellService.GetTimezone(idWell).Hours; - var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); - var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); - var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); - var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); - - var workId = $"create report by wellid:{idWell} for userid:{idUser} requested at {DateTime.Now}"; - - var workAction = async (string id, IServiceProvider serviceProvider, Action onProgress, CancellationToken token) => - { - using var context = serviceProvider.GetRequiredService(); - var fileService = serviceProvider.GetRequiredService(); - - var tempDir = Path.Combine(Path.GetTempPath(), "report"); - - var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, context); - var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName()); - var totalPages = generator.GetPagesCount(); - - generator.OnProgress += (s, e) => - { - var arg = e.Adapt(); - onProgress(arg.Operation?? string.Empty, arg.Progress); - progressHandler.Invoke(arg, id); - }; - generator.Make(reportFileName); - - var fileInfo = (await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token))!; - - progressHandler.Invoke(new - { - Operation = "done", - Progress = 100f, - TotalPages = totalPages, - CurrentPage = totalPages, - file = fileInfo, - }, id); - - var newReportProperties = new ReportProperty - { - IdWell = idWell, - IdFile = fileInfo.Id, - Begin = beginUtc, - End = endUtc, - Step = stepSeconds, - Format = format - }; - context.ReportProperties.Add(newReportProperties); - context.SaveChanges(); - }; - - var work = Work.CreateByDelegate(workId, workAction); - work.OnErrorAsync = (message, exception, token) => Task.Run(() => progressHandler.Invoke(new - { - Operation = "error", - Progress = 100f, - Message = string.IsNullOrEmpty(message) - ? exception.Message - : message, - Exception = exception, - }, workId) - , token); - - backgroundWorkerService.Enqueue(work); - - progressHandler.Invoke(new ReportProgressDto - { - Operation = "Ожидает начала в очереди.", - Progress = 0f, - }, workId); - return workId; - } - - public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) - { - var timezoneOffset = wellService.GetTimezone(idWell).Hours; - var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); - var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); - - var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, db); - var pagesCount = generator.GetPagesCount(); - return pagesCount; - } - - public DatesRangeDto? GetDatesRangeOrDefault(int idWell) - { - var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); - if (telemetry is null) - return null; - var range = telemetryService.GetDatesRange(telemetry.Id); - return range; - } - - public async Task> GetAllReportsByWellAsync(int idWell, CancellationToken token) - { - var timezoneOffset = wellService.GetTimezone(idWell).Hours; - var propertiesQuery = db.ReportProperties.Include(r => r.File) - .Where(p => p.IdWell == idWell) - .OrderBy(o => o.File.UploadDate) + this.db = db; + this.wellService = wellService; + this.backgroundWorkerService = backgroundWorkerService; + this.telemetryService = telemetryService; + this.fileService = fileService; + ReportCategoryId = db.FileCategories .AsNoTracking() - .Take(1024); - var entities = await propertiesQuery.ToListAsync(token); - var dtos = entities.Select(p => new ReportPropertiesDto - { - Id = p.Id, - Name = p.File.Name, - File = new FileInfoDto - { - Id = p.File.Id, - Author = null, - IdAuthor = p.File.IdAuthor ?? 0, - IdCategory = p.File.IdCategory, - IdWell = p.File.IdWell, - Name = p.File.Name, - Size = p.File.Size, - UploadDate = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), - }, - IdWell = p.IdWell, - Date = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), - Begin = p.Begin.ToRemoteDateTime(timezoneOffset), - End = p.End.ToRemoteDateTime(timezoneOffset), - Step = p.Step, - Format = p.Format == 0 ? ".pdf" : ".las" - }); - return dtos; - } + .First(c => c.Name.Equals("Рапорт")) + .Id; + } - private static IReportGenerator GetReportGenerator(int idWell, DateTime begin, - DateTime end, int stepSeconds, int format, IAsbCloudDbContext context) + public string EnqueueCreateReportWork(int idWell, int idUser, int stepSeconds, int format, DateTime begin, + DateTime end, Action progressHandler) + { + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); + var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); + + var workId = $"create report by wellid:{idWell} for userid:{idUser} requested at {DateTime.Now}"; + + var workAction = async (string id, IServiceProvider serviceProvider, Action onProgress, CancellationToken token) => { - var dataSource = new ReportDataSourcePgCloud(context, idWell); - IReportGenerator generator = format switch + using var context = serviceProvider.GetRequiredService(); + var fileService = serviceProvider.GetRequiredService(); + + var tempDir = Path.Combine(Path.GetTempPath(), "report"); + + var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, context); + var reportFileName = Path.Combine(tempDir, generator.GetReportDefaultFileName()); + var totalPages = generator.GetPagesCount(); + + generator.OnProgress += (s, e) => { - //LAS - 1 => new AsbSaubReportLas.ReprotGeneratorLas(dataSource), - //PDF - _ => new AsbSaubReportPdf.ReprotGeneratorPdf(dataSource), + var arg = e.Adapt(); + onProgress(arg.Operation?? string.Empty, arg.Progress); + progressHandler.Invoke(arg, id); }; + generator.Make(reportFileName); - if(begin == default || end == default) + var fileInfo = (await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token))!; + + progressHandler.Invoke(new { - var analyzeResult = dataSource.Analyze(); - begin = begin == default ? analyzeResult.MinDate : begin; - end = end == default ? begin.AddDays(1) : end; - } + Operation = "done", + Progress = 100f, + TotalPages = totalPages, + CurrentPage = totalPages, + file = fileInfo, + }, id); - generator.Begin = begin; - generator.End = end; - generator.Step = TimeSpan.FromSeconds(stepSeconds); - generator.WithCharts = true; - generator.WithEvents = true; + var newReportProperties = new ReportProperty + { + IdWell = idWell, + IdFile = fileInfo.Id, + Begin = beginUtc, + End = endUtc, + Step = stepSeconds, + Format = format + }; + context.ReportProperties.Add(newReportProperties); + context.SaveChanges(); + }; - return generator; - } + var work = Work.CreateByDelegate(workId, workAction); + work.OnErrorAsync = (message, exception, token) => Task.Run(() => progressHandler.Invoke(new + { + Operation = "error", + Progress = 100f, + Message = string.IsNullOrEmpty(message) + ? exception.Message + : message, + Exception = exception, + }, workId) + , token); - public async Task DeleteAllOldReportsAsync(TimeSpan lifetime, CancellationToken token) + backgroundWorkerService.Enqueue(work); + + progressHandler.Invoke(new ReportProgressDto { - var lifeTimeStartDate = DateTime.UtcNow.Date - lifetime; - var fileIds = await db.ReportProperties - .Where(r => r.File.UploadDate.Date < lifeTimeStartDate) - .Select(r => r.IdFile) - .ToArrayAsync(token); + Operation = "Ожидает начала в очереди.", + Progress = 0f, + }, workId); + return workId; + } - return await fileService.DeleteAsync(fileIds, token); + public int GetReportPagesCount(int idWell, DateTime begin, DateTime end, int stepSeconds, int format) + { + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var beginRemote = begin.ToTimeZoneOffsetHours(timezoneOffset); + var endRemote = end.ToTimeZoneOffsetHours(timezoneOffset); + + var generator = GetReportGenerator(idWell, beginRemote, endRemote, stepSeconds, format, db); + var pagesCount = generator.GetPagesCount(); + return pagesCount; + } + + public DatesRangeDto? GetDatesRangeOrDefault(int idWell) + { + var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(idWell); + if (telemetry is null) + return null; + var range = telemetryService.GetDatesRange(telemetry.Id); + return range; + } + + public async Task> GetAllReportsByWellAsync(int idWell, CancellationToken token) + { + var timezoneOffset = wellService.GetTimezone(idWell).Hours; + var propertiesQuery = db.ReportProperties.Include(r => r.File) + .Where(p => p.IdWell == idWell) + .OrderBy(o => o.File.UploadDate) + .AsNoTracking() + .Take(1024); + var entities = await propertiesQuery.ToListAsync(token); + var dtos = entities.Select(p => new ReportPropertiesDto + { + Id = p.Id, + Name = p.File.Name, + File = new FileInfoDto + { + Id = p.File.Id, + Author = null, + IdAuthor = p.File.IdAuthor ?? 0, + IdCategory = p.File.IdCategory, + IdWell = p.File.IdWell, + Name = p.File.Name, + Size = p.File.Size, + UploadDate = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), + }, + IdWell = p.IdWell, + Date = p.File.UploadDate.ToRemoteDateTime(timezoneOffset), + Begin = p.Begin.ToRemoteDateTime(timezoneOffset), + End = p.End.ToRemoteDateTime(timezoneOffset), + Step = p.Step, + Format = p.Format == 0 ? ".pdf" : ".las" + }); + return dtos; + } + + private static IReportGenerator GetReportGenerator(int idWell, DateTime begin, + DateTime end, int stepSeconds, int format, IAsbCloudDbContext context) + { + var dataSource = new ReportDataSourcePgCloud(context, idWell); + IReportGenerator generator = format switch + { + //LAS + 1 => new AsbSaubReportLas.ReprotGeneratorLas(dataSource), + //PDF + _ => new AsbSaubReportPdf.ReprotGeneratorPdf(dataSource), + }; + + if(begin == default || end == default) + { + var analyzeResult = dataSource.Analyze(); + begin = begin == default ? analyzeResult.MinDate : begin; + end = end == default ? begin.AddDays(1) : end; } + + generator.Begin = begin; + generator.End = end; + generator.Step = TimeSpan.FromSeconds(stepSeconds); + generator.WithCharts = true; + generator.WithEvents = true; + + return generator; + } + + public async Task DeleteAllOldReportsAsync(TimeSpan lifetime, CancellationToken token) + { + var lifeTimeStartDate = DateTime.UtcNow.Date - lifetime; + var fileIds = await db.ReportProperties + .Where(r => r.File.UploadDate.Date < lifeTimeStartDate) + .Select(r => r.IdFile) + .ToArrayAsync(token); + + return await fileService.DeleteAsync(fileIds, token); } } diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs index 44f730d3..e296692c 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataBaseService.cs @@ -213,7 +213,7 @@ namespace AsbCloudInfrastructure.Services.SAUB if ((DateTimeOffset.UtcNow - geDate) < TimeSpan.FromHours(12)) { // пробуем обойтись кешем - var cechedRange = telemetryDataCache.GetOrDefaultCachedaDateRange(telemetry.Id); + var cechedRange = telemetryDataCache.GetOrDefaultCachedDateRange(telemetry.Id); if (cechedRange?.From <= geDate) { var datesRange = new DatesRangeDto diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs index 4fefef5a..99983dd5 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataCache.cs @@ -20,7 +20,7 @@ namespace AsbCloudInfrastructure.Services.SAUB class TelemetryDataCacheItem { public TDto FirstByDate { get; init; } = default!; - public CyclycArray LastData { get; init; } = null!; + public CyclicArray LastData { get; init; } = null!; public double TimezoneHours { get; init; } = 5; } @@ -85,7 +85,7 @@ namespace AsbCloudInfrastructure.Services.SAUB cacheItem = caches.GetOrAdd(idTelemetry, _ => new TelemetryDataCacheItem() { FirstByDate = range.ElementAt(0), - LastData = new CyclycArray(activeWellCapacity) + LastData = new CyclicArray(activeWellCapacity) }); } @@ -159,7 +159,7 @@ namespace AsbCloudInfrastructure.Services.SAUB return new DatesRangeDto { From = from.Value, To = to }; } - public DatesRangeDto? GetOrDefaultCachedaDateRange(int idTelemetry) + public DatesRangeDto? GetOrDefaultCachedDateRange(int idTelemetry) { if (!caches.TryGetValue(idTelemetry, out TelemetryDataCacheItem? cacheItem)) return null; @@ -260,7 +260,7 @@ namespace AsbCloudInfrastructure.Services.SAUB return dto; }); - var cacheItem = new CyclycArray(capacity); + var cacheItem = new CyclicArray(capacity); cacheItem.AddRange(dtos); var item = new TelemetryDataCacheItem diff --git a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs index c990b4ce..2fbc78ad 100644 --- a/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/TelemetryDataSaubService.cs @@ -43,7 +43,6 @@ namespace AsbCloudInfrastructure.Services.SAUB .Where(t => t.IdTelemetry == idTelemetry) .Where(t => t.BlockPosition > 0.0001) .Where(t => t.WellDepth > 0.0001) - .Where(t => t.Mode != null) .Where(t => modes.Contains(t.Mode)) .Where(t => t.WellDepth - t.BitDepth < 0.01) .GroupBy(t => new { diff --git a/AsbCloudInfrastructure/Services/Trajectory/TrajectoryService.cs b/AsbCloudInfrastructure/Services/Trajectory/TrajectoryService.cs index 730d0445..6f16b193 100644 --- a/AsbCloudInfrastructure/Services/Trajectory/TrajectoryService.cs +++ b/AsbCloudInfrastructure/Services/Trajectory/TrajectoryService.cs @@ -13,7 +13,7 @@ abstract class TrajectoryBaseService where TGeo : TrajectoryGeoDto where TCartesian : TrajectoryCartesianDto, new() { - ITrajectoryRepository repository; + private readonly ITrajectoryRepository repository; public TrajectoryBaseService(ITrajectoryRepository repository) { @@ -31,16 +31,16 @@ abstract class TrajectoryBaseService public async Task?> GetAsync(int idWell, CancellationToken token) { var geoCoords = await repository.GetAsync(idWell, token); - var locs = GetTrajectoryVisualisation(geoCoords); + var locs = TrajectoryBaseService.GetTrajectoryVisualisation(geoCoords); var dtos = locs.Select(l => Convert(l)); return dtos; } - private IEnumerable GetTrajectoryVisualisation(IEnumerable geoCoordinates) + private static IEnumerable GetTrajectoryVisualisation(IEnumerable geoCoordinates) { var geoCoordinatesLength = geoCoordinates.Count(); if (geoCoordinatesLength < 2) - return new Location[0]; + return Enumerable.Empty(); var cartesianCoordinates = new Location[geoCoordinatesLength]; cartesianCoordinates[0] = new(); @@ -48,7 +48,7 @@ abstract class TrajectoryBaseService var geoCoordinatesArray = geoCoordinates.OrderBy(c => c.WellboreDepth).ToArray(); for (var i = 1; i < geoCoordinatesLength; i++) { - var coordinates = Calculate(cartesianCoordinates[i - 1], + var coordinates = TrajectoryBaseService.Calculate(cartesianCoordinates[i - 1], geoCoordinatesArray[i - 1], geoCoordinatesArray[i]); @@ -58,7 +58,7 @@ abstract class TrajectoryBaseService return cartesianCoordinates; } - protected Location Calculate(Location prevlocation, TrajectoryGeoDto prev, TrajectoryGeoDto current) + protected static Location Calculate(Location prevLocation, TrajectoryGeoDto prev, TrajectoryGeoDto current) { var intervalGeoParams = prev; var deltaWellLength = current.WellboreDepth - intervalGeoParams.WellboreDepth; @@ -70,9 +70,9 @@ abstract class TrajectoryBaseService return new() { - North = prevlocation.North + dNorth, - East = prevlocation.East + dEast, - Depth = prevlocation.Depth + dDepth, + North = prevLocation.North + dNorth, + East = prevLocation.East + dEast, + Depth = prevLocation.Depth + dDepth, Trajectory = current, }; } @@ -125,9 +125,9 @@ class TrajectoryNnbService : TrajectoryBaseService planRepository, @@ -147,11 +147,12 @@ public class TrajectoryService /// public async Task, IEnumerable>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token) { - var result = new TrajectoryPlanFactDto, IEnumerable>(); - - result.Plan = await trajectoryPlanService.GetAsync(idWell, token); - result.FactManual = await trajectoryFactService.GetAsync(idWell, token); - result.FactNnb = await trajectoryNnbService.GetAsync(idWell, token); + var result = new TrajectoryPlanFactDto, IEnumerable> + { + Plan = await trajectoryPlanService.GetAsync(idWell, token), + FactManual = await trajectoryFactService.GetAsync(idWell, token), + FactNnb = await trajectoryNnbService.GetAsync(idWell, token) + }; return result; } diff --git a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs index 591f28fc..8ac7c15c 100644 --- a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs +++ b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs @@ -28,8 +28,6 @@ namespace AsbCloudInfrastructure.Services private readonly IWellFinalDocumentsRepository wellFinalDocumentsRepository; private readonly NotificationService notificationService; - private const int FileServiceThrewException = -1; - public WellFinalDocumentsService(FileService fileService, IUserRepository userRepository, IWellService wellService, @@ -48,7 +46,7 @@ namespace AsbCloudInfrastructure.Services } /// - public async Task UpdateRangeAsync(int idWell, IEnumerable? dtos, CancellationToken token) + public async Task UpdateRangeAsync(int idWell, IEnumerable dtos, CancellationToken token) { var data = await wellFinalDocumentsRepository.UpdateRangeAsync(idWell, dtos, token); diff --git a/AsbCloudInfrastructure/Startup.cs b/AsbCloudInfrastructure/Startup.cs index 115c1f88..4913b392 100644 --- a/AsbCloudInfrastructure/Startup.cs +++ b/AsbCloudInfrastructure/Startup.cs @@ -22,7 +22,7 @@ namespace AsbCloudInfrastructure var provider = scope.ServiceProvider; var context = provider.GetRequiredService(); - context.Database.EnshureCreatedAndMigrated(); + context.Database.EnsureCreatedAndMigrated(); // TODO: Сделать инициализацию кеша телеметрии более явной. _ = provider.GetRequiredService>(); diff --git a/AsbCloudWebApi.Tests/Extensions/AspExtentions.cs b/AsbCloudWebApi.Tests/Extensions/AspExtensions.cs similarity index 93% rename from AsbCloudWebApi.Tests/Extensions/AspExtentions.cs rename to AsbCloudWebApi.Tests/Extensions/AspExtensions.cs index 62f0cbf7..59a5811d 100644 --- a/AsbCloudWebApi.Tests/Extensions/AspExtentions.cs +++ b/AsbCloudWebApi.Tests/Extensions/AspExtensions.cs @@ -3,7 +3,7 @@ using System.Linq; namespace AsbCloudWebApi.Tests { - public static class AspExtentions + public static class AspExtensions { public static IServiceCollection ReplaceService(this IServiceCollection services, T instance) where T : notnull diff --git a/AsbCloudWebApi/Controllers/ReportController.cs b/AsbCloudWebApi/Controllers/ReportController.cs index e9194ad6..ffcc8b9b 100644 --- a/AsbCloudWebApi/Controllers/ReportController.cs +++ b/AsbCloudWebApi/Controllers/ReportController.cs @@ -20,15 +20,16 @@ namespace AsbCloudWebApi.Controllers public class ReportController : ControllerBase { private readonly IReportService reportService; - private readonly FileService fileService; private readonly IWellService wellService; private readonly IHubContext reportsHubContext; - public ReportController(IReportService reportService, IWellService wellService, - FileService fileService, IHubContext reportsHubContext) + public ReportController( + IReportService reportService, + IWellService wellService, + IHubContext reportsHubContext) { this.reportService = reportService; - this.fileService = fileService; this.wellService = wellService; this.reportsHubContext = reportsHubContext; } diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryController.cs index 0b9b6421..789b9252 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryController.cs @@ -21,7 +21,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory public abstract class TrajectoryController : ControllerBase where TDto : TrajectoryGeoDto { - protected abstract string fileName { get; set; } + protected abstract string fileName { get; } private readonly IWellService wellService; private readonly TrajectoryExportService trajectoryExportService; diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs index 05764835..10ed41f3 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs @@ -19,19 +19,17 @@ namespace AsbCloudWebApi.Controllers.Trajectory /// [ApiController] [Authorize] - public abstract class TrajectoryEditableController : TrajectoryController - where Tdto : TrajectoryGeoDto + public abstract class TrajectoryEditableController : TrajectoryController + where TDto : TrajectoryGeoDto { - protected override string fileName { get; set; } - - private readonly TrajectoryParserService trajectoryImportService; - private readonly TrajectoryExportService trajectoryExportService; - private readonly ITrajectoryEditableRepository trajectoryRepository; + private readonly TrajectoryParserService trajectoryImportService; + private readonly TrajectoryExportService trajectoryExportService; + private readonly ITrajectoryEditableRepository trajectoryRepository; public TrajectoryEditableController(IWellService wellService, - TrajectoryParserService trajectoryImportService, - TrajectoryExportService trajectoryExportService, - ITrajectoryEditableRepository trajectoryRepository) + TrajectoryParserService trajectoryImportService, + TrajectoryExportService trajectoryExportService, + ITrajectoryEditableRepository trajectoryRepository) : base( wellService, trajectoryExportService, @@ -118,7 +116,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory /// количество успешно записанных строк в БД [HttpPost] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task AddAsync(int idWell, [FromBody] Tdto row, + public async Task AddAsync(int idWell, [FromBody] TDto row, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) @@ -141,7 +139,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory /// количество успешно записанных строк в БД [HttpPost("range")] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task AddRangeAsync(int idWell, [FromBody] IEnumerable rows, + public async Task AddRangeAsync(int idWell, [FromBody] IEnumerable rows, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) @@ -169,7 +167,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory [HttpPut("{idRow}")] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateAsync(int idWell, int idRow, - [FromBody] Tdto row, CancellationToken token) + [FromBody] TDto row, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs index f8823da5..e3020342 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs @@ -14,7 +14,7 @@ namespace AsbCloudWebApi.Controllers.Trajectory; [Route("api/well/{idWell}/[controller]")] public class TrajectoryFactManualController : TrajectoryEditableController { - protected override string fileName { get; set; } + protected override string fileName => "ЕЦП_шаблон_файла_фактическая_траектория.xlsx"; public TrajectoryFactManualController(IWellService wellService, TrajectoryFactManualParserService factTrajectoryImportService, TrajectoryFactManualExportService factTrajectoryExportService, @@ -24,7 +24,5 @@ public class TrajectoryFactManualController : TrajectoryEditableController { - protected override string fileName { get; set; } + protected override string fileName => "ЕЦП_шаблон_файла_фактическая_ннб_траектория.xlsx"; public TrajectoryFactNnbController( ITrajectoryNnbRepository trajectoryNnbRepository, TrajectoryFactNnbExportService trajectoryExportService, @@ -24,7 +24,5 @@ public class TrajectoryFactNnbController : TrajectoryController "ЕЦП_шаблон_файла_плановая_траектория.xlsx"; + public TrajectoryPlanController(IWellService wellService, TrajectoryPlanParserService trajectoryPlanImportService, TrajectoryPlanExportService trajectoryPlanExportService, @@ -32,7 +34,6 @@ namespace AsbCloudWebApi.Controllers.Trajectory trajectoryPlanExportService, trajectoryPlanRepository) { - fileName = "ЕЦП_шаблон_файла_плановая_траектория.xlsx"; this.trajectoryVisualizationService = trajectoryVisualizationService; } diff --git a/SignalRTestClient/Program.cs b/SignalRTestClient/Program.cs index 9ae72e04..aa61b859 100644 --- a/SignalRTestClient/Program.cs +++ b/SignalRTestClient/Program.cs @@ -6,7 +6,7 @@ namespace SignalRTestClient; internal class Program { - static void Main(string[] args) + static void Main() { var connectionBuilder = new HubConnectionBuilder(); var connection = connectionBuilder @@ -47,7 +47,7 @@ internal class Program builder.AddProvider(provider); } - private static Task AccessTokenProvider() + private static Task AccessTokenProvider() { return Task.FromResult("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJpZCI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZGV2IiwiaWRDb21wYW55IjoiMSIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6InJvb3QiLCJuYmYiOjE2NjI1NDgxNjIsImV4cCI6MTY5NDEwNTc2MiwiaXNzIjoiYSIsImF1ZCI6ImEifQ.OEAlNzxi7Jat6pzDBTAjTbChskc-tdJthJexyWwwUKE"); }