From 4874a9288ba6a168574be28fdfdb92e3dae65685 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: Mon, 29 Jan 2024 15:39:39 +0500 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D0=BB=D0=B5=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Добавлен метод расширения для парсинга Excel файлов 2. Рефакторинг контроллеров траекторий --- .../TrajectoryEditableController.cs | 156 ++++++++---------- .../TrajectoryFactManualController.cs | 30 ++-- .../Trajectory/TrajectoryPlanController.cs | 90 +++++----- AsbCloudWebApi/Extentions.cs | 35 +++- 4 files changed, 170 insertions(+), 141 deletions(-) diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs index 10ed41f3..acd7a7d2 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryEditableController.cs @@ -2,14 +2,15 @@ using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudInfrastructure.Services.Trajectory.Export; -using AsbCloudInfrastructure.Services.Trajectory.Import; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; -using System.IO; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Requests.Import; +using AsbCloudInfrastructure.Services; namespace AsbCloudWebApi.Controllers.Trajectory { @@ -21,26 +22,27 @@ namespace AsbCloudWebApi.Controllers.Trajectory [Authorize] public abstract class TrajectoryEditableController : TrajectoryController where TDto : TrajectoryGeoDto - { - private readonly TrajectoryParserService trajectoryImportService; - private readonly TrajectoryExportService trajectoryExportService; + { + private readonly ParserServiceFactory parserServiceFactory; + private readonly TrajectoryExportService trajectoryExportService; private readonly ITrajectoryEditableRepository trajectoryRepository; - public TrajectoryEditableController(IWellService wellService, - TrajectoryParserService trajectoryImportService, - TrajectoryExportService trajectoryExportService, + protected TrajectoryEditableController(IWellService wellService, + ParserServiceFactory parserServiceFactory, + TrajectoryExportService trajectoryExportService, ITrajectoryEditableRepository trajectoryRepository) : base( wellService, trajectoryExportService, trajectoryRepository) { - this.trajectoryImportService = trajectoryImportService; - this.trajectoryExportService = trajectoryExportService; + this.trajectoryExportService = trajectoryExportService; this.trajectoryRepository = trajectoryRepository; + this.parserServiceFactory = parserServiceFactory; + } - } - + protected abstract TrajectoryParserRequest ParserOptions { get; } + /// /// Возвращает excel шаблон для заполнения строк траектории /// @@ -55,56 +57,32 @@ namespace AsbCloudWebApi.Controllers.Trajectory return File(stream, "application/octet-stream", fileName); } - /// - /// Импортирует координаты из excel (xlsx) файла - /// - /// id скважины - /// Коллекция из одного файла xlsx - /// Удалить операции перед импортом, если фал валидный - /// Токен отмены задачи - /// количество успешно записанных строк в БД - [HttpPost("import/{deleteBeforeImport}")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] - public async Task ImportAsync(int idWell, - [FromForm] IFormFileCollection files, - bool deleteBeforeImport, - CancellationToken token) - { - int? idUser = User.GetUserId(); - if (!idUser.HasValue) - return Forbid(); - if (!await CanUserAccessToWellAsync(idWell, - token).ConfigureAwait(false)) - return Forbid(); - if (files.Count < 1) - return this.ValidationBadRequest(nameof(files), "нет файла"); - var file = files[0]; - if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") - return this.ValidationBadRequest(nameof(files), "Требуется xlsx файл."); - using Stream stream = file.OpenReadStream(); + /// + /// Импортирует координаты из excel (xlsx) файла + /// + /// id скважины + /// Коллекция из одного файла xlsx + /// Токен отмены задачи + /// количество успешно записанных строк в БД + [HttpPost("parse")] + [ProducesResponseType((int)System.Net.HttpStatusCode.OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] + public async Task>> Parse(int idWell, + [FromForm] IFormFileCollection files, + CancellationToken token) + { + var idUser = User.GetUserId(); - try - { - var trajectoryRows = trajectoryImportService.Import(stream); - foreach (var row in trajectoryRows) - { - row.IdWell = idWell; - row.IdUser = idUser.Value; - } + if (!idUser.HasValue) + return Forbid(); - if (deleteBeforeImport) - await trajectoryRepository.DeleteByIdWellAsync(idWell, token); + if (!await CanUserAccessToWellAsync(idWell, token)) + return Forbid(); - var rowsCount = await trajectoryRepository.AddRangeAsync(trajectoryRows, token); + var parserService = parserServiceFactory.Create(ParserOptions.IdParserService); - return Ok(rowsCount); - } - catch (FileFormatException ex) - { - return this.ValidationBadRequest(nameof(files), ex.Message); - } - } + return this.ParseExcelFile(files, ParserOptions, parserService); + } /// @@ -130,31 +108,41 @@ namespace AsbCloudWebApi.Controllers.Trajectory return Ok(result); } - /// - /// Добавить массив строчек координат для плановой траектории - /// - /// - /// - /// - /// количество успешно записанных строк в БД - [HttpPost("range")] - [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task AddRangeAsync(int idWell, [FromBody] IEnumerable rows, - CancellationToken token) - { - if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) - return Forbid(); - int? idUser = User.GetUserId(); - if (!idUser.HasValue) - return Forbid(); - foreach (var item in rows) - { - item.IdUser = idUser.Value; - item.IdWell = idWell; - } - var result = await trajectoryRepository.AddRangeAsync(rows, token); - return Ok(result); - } + /// + /// Добавить массив строчек координат для плановой траектории + /// + /// + /// + /// + /// + /// количество успешно записанных строк в БД + [HttpPost("range/{deleteBeforeInsert:bool}")] + [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] + public async Task AddRangeAsync(int idWell, + [FromBody] IEnumerable dtos, + bool deleteBeforeInsert, + CancellationToken token) + { + if (!await CanUserAccessToWellAsync(idWell, token)) + return Forbid(); + + var idUser = User.GetUserId(); + + if (!idUser.HasValue) + return Forbid(); + + foreach (var dto in dtos) + { + dto.IdUser = idUser.Value; + dto.IdWell = idWell; + } + + if (deleteBeforeInsert) + await trajectoryRepository.DeleteByIdWellAsync(idWell, token); + + var result = await trajectoryRepository.AddRangeAsync(dtos, token); + return Ok(result); + } /// /// Изменить выбранную строку с координатами @@ -201,4 +189,4 @@ namespace AsbCloudWebApi.Controllers.Trajectory return Ok(result); } } -} +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs index e3020342..65ee4b9e 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryFactManualController.cs @@ -1,8 +1,9 @@ using AsbCloudApp.Data.Trajectory; using AsbCloudApp.Repositories; +using AsbCloudApp.Requests.Import; using AsbCloudApp.Services; +using AsbCloudInfrastructure.Services; using AsbCloudInfrastructure.Services.Trajectory.Export; -using AsbCloudInfrastructure.Services.Trajectory.Import; using Microsoft.AspNetCore.Mvc; namespace AsbCloudWebApi.Controllers.Trajectory; @@ -14,15 +15,20 @@ namespace AsbCloudWebApi.Controllers.Trajectory; [Route("api/well/{idWell}/[controller]")] public class TrajectoryFactManualController : TrajectoryEditableController { - protected override string fileName => "ЕЦП_шаблон_файла_фактическая_траектория.xlsx"; - public TrajectoryFactManualController(IWellService wellService, - TrajectoryFactManualParserService factTrajectoryImportService, - TrajectoryFactManualExportService factTrajectoryExportService, - ITrajectoryEditableRepository trajectoryFactRepository) - : base( - wellService, - factTrajectoryImportService, - factTrajectoryExportService, - trajectoryFactRepository) - { } + protected override string fileName => "ЕЦП_шаблон_файла_фактическая_траектория.xlsx"; + + public TrajectoryFactManualController(IWellService wellService, + TrajectoryFactManualExportService trajectoryExportService, + ParserServiceFactory parserServiceFactory, + ITrajectoryEditableRepository trajectoryRepository) + : base(wellService, parserServiceFactory, trajectoryExportService, trajectoryRepository) + { + } + + protected override TrajectoryParserRequest ParserOptions => new() + { + IdParserService = ParserServiceFactory.IdTrajectoryFactManualParserService, + SheetName = "Фактическая траектория", + HeaderRowsCount = 2 + }; } \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryPlanController.cs b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryPlanController.cs index 122352ad..87c4ac20 100644 --- a/AsbCloudWebApi/Controllers/Trajectory/TrajectoryPlanController.cs +++ b/AsbCloudWebApi/Controllers/Trajectory/TrajectoryPlanController.cs @@ -2,58 +2,62 @@ using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudInfrastructure.Services.Trajectory; -using AsbCloudInfrastructure.Services.Trajectory.Import; using AsbCloudInfrastructure.Services.Trajectory.Export; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Requests.Import; +using AsbCloudInfrastructure.Services; namespace AsbCloudWebApi.Controllers.Trajectory { + /// + /// Плановая траектория (загрузка и хранение) + /// + [Route("api/well/{idWell}/[controller]")] + [ApiController] + public class TrajectoryPlanController : TrajectoryEditableController + { + private readonly TrajectoryService trajectoryVisualizationService; - /// - /// Плановая траектория (загрузка и хранение) - /// - [Route("api/well/{idWell}/[controller]")] - [ApiController] - public class TrajectoryPlanController : TrajectoryEditableController - { - private readonly TrajectoryService trajectoryVisualizationService; + protected override string fileName => "ЕЦП_шаблон_файла_плановая_траектория.xlsx"; - protected override string fileName => "ЕЦП_шаблон_файла_плановая_траектория.xlsx"; + public TrajectoryPlanController(IWellService wellService, + TrajectoryPlanExportService trajectoryExportService, + ParserServiceFactory parserServiceFactory, + ITrajectoryEditableRepository trajectoryRepository, + TrajectoryService trajectoryVisualizationService) + : base(wellService, parserServiceFactory, trajectoryExportService, trajectoryRepository) + { + this.trajectoryVisualizationService = trajectoryVisualizationService; + } + + protected override TrajectoryParserRequest ParserOptions => new() + { + IdParserService = ParserServiceFactory.IdTrajectoryPlanParserService, + SheetName = "Плановая траектория", + HeaderRowsCount = 2 + }; - public TrajectoryPlanController(IWellService wellService, - TrajectoryPlanParserService trajectoryPlanImportService, - TrajectoryPlanExportService trajectoryPlanExportService, - ITrajectoryEditableRepository trajectoryPlanRepository, - TrajectoryService trajectoryVisualizationService) - : base( - wellService, - trajectoryPlanImportService, - trajectoryPlanExportService, - trajectoryPlanRepository) - { - this.trajectoryVisualizationService = trajectoryVisualizationService; - } + /// + /// Получение координат для визуализации траектории (плановой и фактической) + /// + /// + /// + /// + [HttpGet("trajectoryCartesianPlanFact")] + [ProducesResponseType( + typeof(TrajectoryPlanFactDto, IEnumerable>), + (int)System.Net.HttpStatusCode.OK)] + public async Task GetTrajectoryCartesianPlanFactAsync(int idWell, CancellationToken token) + { + if (!await CanUserAccessToWellAsync(idWell, + token).ConfigureAwait(false)) + return Forbid(); - /// - /// Получение координат для визуализации траектории (плановой и фактической) - /// - /// - /// - /// - [HttpGet("trajectoryCartesianPlanFact")] - [ProducesResponseType(typeof(TrajectoryPlanFactDto, IEnumerable>), (int)System.Net.HttpStatusCode.OK)] - public async Task GetTrajectoryCartesianPlanFactAsync(int idWell, CancellationToken token) - { - if (!await CanUserAccessToWellAsync(idWell, - token).ConfigureAwait(false)) - return Forbid(); - - var result = await trajectoryVisualizationService.GetTrajectoryCartesianAsync(idWell, token); - return Ok(result); - } - } - -} + var result = await trajectoryVisualizationService.GetTrajectoryCartesianAsync(idWell, token); + return Ok(result); + } + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Extentions.cs b/AsbCloudWebApi/Extentions.cs index ba87612f..4e643a74 100644 --- a/AsbCloudWebApi/Extentions.cs +++ b/AsbCloudWebApi/Extentions.cs @@ -3,7 +3,12 @@ using AsbCloudWebApi.Converters; using System; using System.Collections.Generic; using System.ComponentModel; +using System.IO; using System.Security.Claims; +using AsbCloudApp.Data; +using AsbCloudApp.Requests.Import; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Http; namespace Microsoft.AspNetCore.Mvc { @@ -59,6 +64,32 @@ namespace Microsoft.AspNetCore.Mvc return options; } - } -} + public static ActionResult> ParseExcelFile(this ControllerBase controller, + IFormFileCollection files, + TOptions options, + IParserService parserService) + where TDto : class, IId + where TOptions : ParserOptionsRequestBase + { + if (files.Count < 1) + return controller.ValidationBadRequest(nameof(files), "Нет файла"); + var file = files[0]; + if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") + return controller.ValidationBadRequest(nameof(files), "Требуется .xlsx файл."); + + using var stream = file.OpenReadStream(); + + try + { + var items = parserService.Parse(stream, options); + + return controller.Ok(items); + } + catch (FileFormatException ex) + { + return controller.ValidationBadRequest(nameof(files), ex.Message); + } + } + } +} \ No newline at end of file