From ae79426973cb22abf098b81b6a119414d2d19898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D1=82=D0=B5=D0=BF=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=94?= =?UTF-8?q?=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 25 Jul 2024 16:53:48 +0300 Subject: [PATCH] =?UTF-8?q?=D0=AD=D0=BA=D1=81=D0=BF=D0=BE=D1=80=D1=82=20?= =?UTF-8?q?=D0=B0=D0=B2=D1=82=D0=BE=D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D1=91=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BE=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DetectedOperationExportService.cs | 333 +++++++++--------- .../SAUB/DetectedOperationController.cs | 6 +- 2 files changed, 174 insertions(+), 165 deletions(-) diff --git a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs index bc8869b4..98a9f298 100644 --- a/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs +++ b/AsbCloudInfrastructure/Services/DetectOperations/DetectedOperationExportService.cs @@ -14,210 +14,219 @@ using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudApp.Data; using AsbCloudApp.Data.WellOperation; +using AsbCloudApp.Requests; using AsbCloudInfrastructure.Services.DetectOperations.Detectors; namespace AsbCloudInfrastructure.Services.DetectOperations; public class DetectedOperationExportService { - private readonly IWellService wellService; - private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; - private readonly IDetectedOperationService detectedOperationService; - private const int headerRowsCount = 1; + private readonly IWellService wellService; + private readonly IWellOperationCategoryRepository wellOperationCategoryRepository; + private readonly IDetectedOperationRepository detectedOperationRepository; + private const int headerRowsCount = 1; - private const string cellDepositName = "B1"; - private const string cellClusterName = "B2"; - private const string cellWellName = "B3"; - private const string cellDeltaDate = "H2"; + private const string cellDepositName = "B1"; + private const string cellClusterName = "B2"; + private const string cellWellName = "B3"; + private const string cellDeltaDate = "H2"; - private const int columnOperationName = 1; - private const int columnDateStart = 2; - private const int columnDateEnd = 3; - private const int columnDuration = 4; - private const int columnDepthStart = 5; - private const int columnDepthEnd = 6; - private const int columnDeltaDepth = 7; - private const int columnDepth = 8; - private const int columnIdReasonOfEnd = 9; - private const int columnComment = 10; + private const int columnOperationName = 1; + private const int columnDateStart = 2; + private const int columnDateEnd = 3; + private const int columnDuration = 4; + private const int columnDepthStart = 5; + private const int columnDepthEnd = 6; + private const int columnDeltaDepth = 7; + private const int columnDepth = 8; + private const int columnIdReasonOfEnd = 9; + private const int columnComment = 10; - public DetectedOperationExportService(IWellService wellService, - IWellOperationCategoryRepository wellOperationCategoryRepository, - IDetectedOperationService detectedOperationService) - { - this.wellService = wellService; - this.wellOperationCategoryRepository = wellOperationCategoryRepository; - this.detectedOperationService = detectedOperationService; - } + public DetectedOperationExportService(IWellService wellService, + IWellOperationCategoryRepository wellOperationCategoryRepository, + IDetectedOperationRepository detectedOperationRepository) + { + this.wellService = wellService; + this.wellOperationCategoryRepository = wellOperationCategoryRepository; + this.detectedOperationRepository = detectedOperationRepository; + } - /// - /// Экспорт excel файла с операциями по скважине - /// - /// ключ скважины - /// хост - /// - /// - /// - public async Task ExportAsync(int idWell, string host, CancellationToken token) - { - var well = await wellService.GetOrDefaultAsync(idWell, token); + /// + /// Экспорт excel файла с операциями по скважине + /// + /// ключ скважины + /// хост + /// + /// + /// + public async Task ExportAsync(int idWell, string host, CancellationToken token) + { + var well = await wellService.GetOrDefaultAsync(idWell, token); - if (well is null) - throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} does not exist"); + if (well is null) + throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} does not exist"); - if (!well.IdTelemetry.HasValue) - throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} has no telemetry"); + if (!well.IdTelemetry.HasValue) + throw new ArgumentInvalidException(nameof(idWell), $"Well {idWell} has no telemetry"); - var operations = await detectedOperationService.DetectOperationsAsync(well.IdTelemetry.Value, DateTime.UnixEpoch, token); + var request = new DetectedOperationByTelemetryRequest + { + IdTelemetry = well.IdTelemetry.Value + }; - return await GenerateExcelFileStreamAsync(well, host, operations, token); - } + var operations = await detectedOperationRepository.Get(request, token); - private async Task GenerateExcelFileStreamAsync(WellDto well, string host, IEnumerable operationDetectorResults, - CancellationToken cancellationToken) - { - using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken); + return await GenerateExcelFileStreamAsync(well, host, operations, token); + } - using var workbook = new XLWorkbook(excelTemplateStream); + private async Task GenerateExcelFileStreamAsync(WellDto well, + string host, + IEnumerable operationDetectorResults, + CancellationToken cancellationToken) + { + using var excelTemplateStream = await GetExcelTemplateStreamAsync(cancellationToken); - AddToWorkbook(workbook, well, host, operationDetectorResults); + using var workbook = new XLWorkbook(excelTemplateStream); - MemoryStream memoryStream = new MemoryStream(); - workbook.SaveAs(memoryStream, new SaveOptions { }); - memoryStream.Seek(0, SeekOrigin.Begin); - return memoryStream; - } + AddToWorkbook(workbook, well, host, operationDetectorResults); - private void AddToWorkbook(XLWorkbook workbook, WellDto well, string host, IEnumerable operations) - { - const string sheetName = "Операции"; + MemoryStream memoryStream = new MemoryStream(); + workbook.SaveAs(memoryStream, new SaveOptions { }); + memoryStream.Seek(0, SeekOrigin.Begin); + return memoryStream; + } - if (!operations.Any()) - return; + private void AddToWorkbook(XLWorkbook workbook, WellDto well, string host, IEnumerable operations) + { + const string sheetName = "Операции"; - var sheet = workbook.GetWorksheet(sheetName); + if (!operations.Any()) + return; - var orderedOperations = operations - .OrderBy(x => x.DateStart) - .ThenBy(x => x.DepthStart).ToArray(); + var sheet = workbook.GetWorksheet(sheetName); - AddToSheet(sheet, well, host, orderedOperations); - } + var orderedOperations = operations + .OrderBy(x => x.DateStart) + .ThenBy(x => x.DepthStart).ToArray(); - private void AddToSheet(IXLWorksheet sheet, WellDto well, string host, IList operations) - { - var wellOperationCategories = wellOperationCategoryRepository.Get(true); + AddToSheet(sheet, well, host, orderedOperations); + } - sheet.Cell(cellDepositName).SetCellValue(well.Deposit); - sheet.Cell(cellClusterName).SetCellValue(well.Cluster); - sheet.Cell(cellWellName).SetCellValue(well.Caption); + private void AddToSheet(IXLWorksheet sheet, WellDto well, string host, IList operations) + { + var wellOperationCategories = wellOperationCategoryRepository.Get(true); - var deltaDate = operations.Max(o => o.DateEnd - o.DateStart); - - sheet.Cell(cellDeltaDate).SetCellValue(deltaDate); + sheet.Cell(cellDepositName).SetCellValue(well.Deposit); + sheet.Cell(cellClusterName).SetCellValue(well.Cluster); + sheet.Cell(cellWellName).SetCellValue(well.Caption); - for (int i = 0; i < operations.Count; i++) - { - var current = operations[i]; - var dateStart = current.DateStart.DateTime; - var dateEnd = current.DateEnd.DateTime; + var deltaDate = operations.Max(o => o.DateEnd - o.DateStart); - var row = sheet.Row(5 + i + headerRowsCount); + sheet.Cell(cellDeltaDate).SetCellValue(deltaDate); - var categoryName = GetCategoryName(wellOperationCategories, current); - - row.Cell(columnDateStart).SetCellValue(dateStart); - row.Cell(columnOperationName).SetCellValue(categoryName); - row.Cell(columnDateEnd).SetCellValue(dateEnd); - row.Cell(columnDuration).SetCellValue((dateEnd - dateStart).TotalMinutes); - row.Cell(columnDepthStart).SetCellValue(current.DepthStart); - row.Cell(columnDepthEnd).SetCellValue(current.DepthEnd); - row.Cell(columnDepth).SetCellValue(current.DepthEnd - current.DepthStart); + for (int i = 0; i < operations.Count; i++) + { + var current = operations[i]; + var dateStart = current.DateStart.DateTime; + var dateEnd = current.DateEnd.DateTime; - if (current.ExtraData.TryGetValue("IdReasonOfEnd", out object? idReasonOfEndObject) - && idReasonOfEndObject is int idReasonOfEnd) - { - var reasonOfEnd = GetIdReasonOfEnd(idReasonOfEnd); - row.Cell(columnIdReasonOfEnd).SetCellValue(reasonOfEnd); - } + var row = sheet.Row(5 + i + headerRowsCount); - var query = new QueryBuilder(); - query.Add("end", dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff")); - query.Add("range", "1800"); + var categoryName = GetCategoryName(wellOperationCategories, current); - var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}"; - row.Cell(columnDateStart).SetHyperlink(link); - - var deltaDepth = i > 0 && i + 1 < operations.Count - ? current.DepthStart - operations[i - 1].DepthEnd - : 0; + row.Cell(columnDateStart).SetCellValue(dateStart); + row.Cell(columnOperationName).SetCellValue(categoryName); + row.Cell(columnDateEnd).SetCellValue(dateEnd); + row.Cell(columnDuration).SetCellValue((dateEnd - dateStart).TotalMinutes); + row.Cell(columnDepthStart).SetCellValue(current.DepthStart); + row.Cell(columnDepthEnd).SetCellValue(current.DepthEnd); + row.Cell(columnDepth).SetCellValue(current.DepthEnd - current.DepthStart); - row.Cell(columnDeltaDepth).SetCellValue(deltaDepth); + if (current.ExtraData.TryGetValue("IdReasonOfEnd", out object? idReasonOfEndObject) + && idReasonOfEndObject is int idReasonOfEnd) + { + var reasonOfEnd = GetIdReasonOfEnd(idReasonOfEnd); + row.Cell(columnIdReasonOfEnd).SetCellValue(reasonOfEnd); + } - var comment = CreateComment(operations[i]); - row.Cell(columnComment).SetCellValue(comment); - } - } + var query = new QueryBuilder(); + query.Add("end", dateStart.AddSeconds(1800 * 0.9).ToString("yyyy-MM-ddTHH:mm:ss.fff")); + query.Add("range", "1800"); - private static string GetCategoryName(IEnumerable wellOperationCategories, DetectedOperationDto current) - { - var idCategory = current.IdCategory; - if (idCategory == WellOperationCategory.IdSlide && current.EnabledSubsystems.IsAutoOscillation) - return "Бурение в слайде с осцилляцией"; + var link = $"{host}/well/{well.Id}/telemetry/monitoring{query}"; + row.Cell(columnDateStart).SetHyperlink(link); - var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory); - - if(category is not null) - return category.Name; + var deltaDepth = i > 0 && i + 1 < operations.Count + ? current.DepthStart - operations[i - 1].DepthEnd + : 0; - return $"Операция №{idCategory}"; - } + row.Cell(columnDeltaDepth).SetCellValue(deltaDepth); - private static string GetIdReasonOfEnd(int idReasonOfEnd) - => idReasonOfEnd switch { - 0 => "Не определена", - 1 => "Не определено начало операции", - 101 => "Разница глубин забоя и положением долота", - 300 => "Низкое давление", - 301 => "Высокое давление", - 700 => "Изменение глубины долота и осевая нагрузка < веса на крюке", - _ => idReasonOfEnd.ToString($"Причина № {idReasonOfEnd}"), + var comment = CreateComment(operations[i]); + row.Cell(columnComment).SetCellValue(comment); + } + } - }; + private static string GetCategoryName(IEnumerable wellOperationCategories, DetectedOperationDto current) + { + var idCategory = current.IdCategory; + if (idCategory == WellOperationCategory.IdSlide && current.EnabledSubsystems.IsAutoOscillation) + return "Бурение в слайде с осцилляцией"; - private async Task GetExcelTemplateStreamAsync(CancellationToken cancellationToken) - { - string resourceName = Assembly.GetExecutingAssembly() - .GetManifestResourceNames() - .FirstOrDefault(n => n.EndsWith("DetectOperations.xlsx"))!; + var category = wellOperationCategories.FirstOrDefault(o => o.Id == current.IdCategory); - using var stream = Assembly.GetExecutingAssembly() - .GetManifestResourceStream(resourceName)!; + if (category is not null) + return category.Name; - var memoryStream = new MemoryStream(); - await stream.CopyToAsync(memoryStream, cancellationToken); - memoryStream.Position = 0; + return $"Операция №{idCategory}"; + } - return memoryStream; - } - - private static string CreateComment(DetectedOperationDto operation) - { - switch (operation.IdCategory) - { - case WellOperationCategory.IdRotor: - case WellOperationCategory.IdSlide: - var comment = ""; - if (operation.ExtraData.TryGetValue(DetectorDrilling.ExtraDataKeyAvgRotorSpeed, out object? oAvgRotorSpeed)) - comment += $"Средняя скорость оборотов ротора: {oAvgRotorSpeed}\r\n"; + private static string GetIdReasonOfEnd(int idReasonOfEnd) + => idReasonOfEnd switch + { + 0 => "Не определена", + 1 => "Не определено начало операции", + 101 => "Разница глубин забоя и положением долота", + 300 => "Низкое давление", + 301 => "Высокое давление", + 700 => "Изменение глубины долота и осевая нагрузка < веса на крюке", + _ => idReasonOfEnd.ToString($"Причина № {idReasonOfEnd}"), + }; - if (operation.ExtraData.TryGetValue(DetectorDrilling.ExtraDataKeyDispersionOfNormalizedRotorSpeed, out object? oDispersionOfNormalizedRotorSpeed)) - comment += $"Дисперсия нормированных оборотов ротора: {oDispersionOfNormalizedRotorSpeed}"; - - return comment; - - default: - return string.Empty; - } - } + private async Task GetExcelTemplateStreamAsync(CancellationToken cancellationToken) + { + string resourceName = Assembly.GetExecutingAssembly() + .GetManifestResourceNames() + .FirstOrDefault(n => n.EndsWith("DetectOperations.xlsx"))!; + + using var stream = Assembly.GetExecutingAssembly() + .GetManifestResourceStream(resourceName)!; + + var memoryStream = new MemoryStream(); + await stream.CopyToAsync(memoryStream, cancellationToken); + memoryStream.Position = 0; + + return memoryStream; + } + + private static string CreateComment(DetectedOperationDto operation) + { + switch (operation.IdCategory) + { + case WellOperationCategory.IdRotor: + case WellOperationCategory.IdSlide: + var comment = ""; + if (operation.ExtraData.TryGetValue(DetectorDrilling.ExtraDataKeyAvgRotorSpeed, out object? oAvgRotorSpeed)) + comment += $"Средняя скорость оборотов ротора: {oAvgRotorSpeed}\r\n"; + + if (operation.ExtraData.TryGetValue(DetectorDrilling.ExtraDataKeyDispersionOfNormalizedRotorSpeed, + out object? oDispersionOfNormalizedRotorSpeed)) + comment += $"Дисперсия нормированных оборотов ротора: {oDispersionOfNormalizedRotorSpeed}"; + + return comment; + + default: + return string.Empty; + } + } } \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs b/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs index c593c4d6..5011c8d3 100644 --- a/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/DetectedOperationController.cs @@ -167,13 +167,13 @@ namespace AsbCloudWebApi.Controllers.SAUB public async Task ExportAsync(int idWell, CancellationToken token) { var idCompany = User.GetCompanyId(); - + if (idCompany is null) return Forbid(); - + var host = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}"; var stream = await detectedOperationExportService.ExportAsync(idWell, host, token); - + return File(stream, "application/octet-stream", "operations.xlsx"); }