using AsbCloudApp.Data; using AsbCloudApp.Services; 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; namespace AsbCloudWebApi.Controllers { #nullable enable /// /// Плановая траектория (загрузка и хранение) /// [Route("api/well/{idWell}/plannedTrajectory")] [ApiController] [Authorize] public class PlannedTrajectoryController : ControllerBase { private readonly IWellService wellService; private readonly IPlannedTrajectoryImportService plannedTrajectoryImportService; private readonly IPlannedTrajectoryService plannedTrajectoryService; public PlannedTrajectoryController(IWellService wellService, IPlannedTrajectoryImportService plannedTrajectoryImportService, IPlannedTrajectoryService plannedTrajectoryService) { this.plannedTrajectoryImportService = plannedTrajectoryImportService; this.wellService = wellService; this.plannedTrajectoryService = plannedTrajectoryService; } /// /// Возвращает шаблон для заполнения строк плановой траектории /// /// Запрашиваемый файл [HttpGet] [Route("template")] [AllowAnonymous] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public IActionResult GetTemplate() { var stream = plannedTrajectoryImportService.GetTemplateFile(); var fileName = "ЕЦП_шаблон_файла_плановая_траектория.xlsx"; return File(stream, "application/octet-stream", fileName); } /// /// Формируем excel файл с текущими строками плановой траектории /// /// id скважины /// Токен отмены задачи /// Запрашиваемый файл [HttpGet] [Route("export")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public async Task ExportAsync([FromRoute] int idWell, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); var stream = await plannedTrajectoryImportService.ExportAsync(idWell, token); var fileName = plannedTrajectoryImportService.GetFileName(idWell, token); return File(stream, "application/octet-stream", fileName); } /// /// Импортирует координаты из excel (xlsx) файла /// /// id скважины /// Коллекция из одного файла xlsx /// Удалить операции перед импортом = 1, если фал валидный /// Токен отмены задачи /// [HttpPost] [Permission] [Route("import/{options}")] public async Task ImportAsync(int idWell, [FromForm] IFormFileCollection files, int options = 0, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); if (idCompany is null || idUser is null) return Forbid(); if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); if (files.Count < 1) return BadRequest("нет файла"); var file = files[0]; if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") return BadRequest("Требуется xlsx файл."); using Stream stream = file.OpenReadStream(); try { var result = plannedTrajectoryImportService.ImportAsync(idWell, idUser.Value, stream, token,(options & 1) > 0); return Ok(result); } catch (FileFormatException ex) { return BadRequest(ex.Message); } } /// /// Получаем список всех строк координат плановой траектории (для клиента) /// /// id скважины /// Токен отмены задачи /// Запрашиваемый файл [HttpGet] [Route("allRows")] [Permission] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetRows([FromRoute] int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var result = plannedTrajectoryService.GetOrDefaultAsync(idWell,token); return Ok(result); } /// /// Добавить одну новую строчку координат для плановой траектории /// /// /// /// /// [HttpPost] [Permission] [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] public async Task AddRowAsync(int idWell, [FromBody] PlannedTrajectoryDto row, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); var result = await plannedTrajectoryService.AddAsync(idWell, idUser.Value, row, token) .ConfigureAwait(false); return Ok(result); } /// /// Добавить массив строчек координат для плановой траектории /// /// /// /// /// [HttpPost] [Permission] [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] public async Task AddRowAsync(int idWell, [FromBody] IEnumerable rows, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); var result = await plannedTrajectoryService.AddRangeAsync(idWell, idUser.Value, rows, token) .ConfigureAwait(false); return Ok(result); } /// /// Изменить выбранную строку с координатами /// /// /// /// /// /// [HttpPut("{idRow}")] [Permission] [ProducesResponseType(typeof(PlannedTrajectoryDto), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateRowAsync(int idWell, int idRow, [FromBody] PlannedTrajectoryDto row, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); int? idUser = User.GetUserId(); if (!idUser.HasValue) return Forbid(); var result = await plannedTrajectoryService.UpdateAsync(idWell, idUser.Value, idRow, row, token) .ConfigureAwait(false); return Ok(result); } /// /// Удалить выбранную строку с координатами /// /// /// /// /// [HttpDelete("{idOperation}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task DeleteRowAsync(int idWell, int idRow, CancellationToken token = default) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); var result = await plannedTrajectoryService.DeleteRangeAsync(new int[] { idRow }, token) .ConfigureAwait(false); return Ok(result); } private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); } } }