From e763cc4ff2dcd5b76aae21c8e07dc70073d6c3ea 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, 9 Oct 2023 17:16:02 +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 --- .../Controllers/ProcessMapController.cs | 283 ------------------ ...ProcessMapWellboreDevelopmentController.cs | 96 ------ .../ProcessMaps/ProcessMapBaseController.cs | 146 +++++++++ .../WellDrillingProcessMapController.cs | 214 +++++++++++++ .../WellReamProcessMapController.cs | 15 + .../SAUB/TelemetryProcessMapController.cs | 90 ++++++ .../Controllers/WellCompositeController.cs | 4 +- 7 files changed, 467 insertions(+), 381 deletions(-) delete mode 100644 AsbCloudWebApi/Controllers/ProcessMapController.cs delete mode 100644 AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs create mode 100644 AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs create mode 100644 AsbCloudWebApi/Controllers/ProcessMaps/WellDrillingProcessMapController.cs create mode 100644 AsbCloudWebApi/Controllers/ProcessMaps/WellReamProcessMapController.cs create mode 100644 AsbCloudWebApi/Controllers/SAUB/TelemetryProcessMapController.cs diff --git a/AsbCloudWebApi/Controllers/ProcessMapController.cs b/AsbCloudWebApi/Controllers/ProcessMapController.cs deleted file mode 100644 index 9b749340..00000000 --- a/AsbCloudWebApi/Controllers/ProcessMapController.cs +++ /dev/null @@ -1,283 +0,0 @@ -using AsbCloudApp.Data.ProcessMap; -using AsbCloudApp.Repositories; -using AsbCloudApp.Services; -using AsbCloudWebApi.SignalR; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.SignalR; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; - -namespace AsbCloudWebApi.Controllers -{ - /// - /// РТК - /// - [ApiController] - [Route("api/[controller]")] - [Authorize] - public class ProcessMapController : CrudWellRelatedController - { - private readonly ITelemetryService telemetryService; - private readonly IHubContext telemetryHubContext; - private readonly IProcessMapReportMakerService processMapReportService; - private readonly IProcessMapService processMapService; - private readonly IProcessMapPlanImportService processMapPlanImportService; - private readonly IUserRepository userRepository; - - private const string SirnalRMethodGetDataName = "UpdateProcessMap"; - - public ProcessMapController( - IWellService wellService, - IProcessMapPlanRepository repository, - IProcessMapReportMakerService processMapReportService, - IProcessMapService processMapService, - ITelemetryService telemetryService, - IHubContext telemetryHubContext, - IProcessMapPlanImportService processMapPlanImportService, - IUserRepository userRepository) - : base(wellService, repository) - { - this.telemetryService = telemetryService; - this.telemetryHubContext = telemetryHubContext; - this.processMapReportService = processMapReportService; - this.processMapService = processMapService; - this.processMapPlanImportService = processMapPlanImportService; - this.userRepository = userRepository; - - } - - /// - /// Возвращает все значения для коридоров бурения по uid панели - /// - /// uid панели - /// Дата, с которой следует искать новые параметры - /// Токен отмены задачи - /// Список параметров для коридоров бурения - [HttpGet("/api/telemetry/{uid}/drillFlowChart")] - [Obsolete("use GetByUidAsync(..) instead")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] - public IActionResult GetByTelemetry(string uid, DateTime updateFrom, CancellationToken token) - { - var idWell = telemetryService.GetIdWellByTelemetryUid(uid); - if (idWell is null) - return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}"); - return Ok(Enumerable.Empty()); - } - - /// - /// Возвращает РТК по uid телеметрии - /// - /// uid телеметрии - /// Дата, с которой следует искать новые параметры - /// Токен отмены задачи - /// Список параметров для коридоров бурения - [HttpGet("/api/telemetry/{uid}/processMap")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] - public async Task GetByUidAsync(string uid, DateTime updateFrom, CancellationToken token) - { - var idWell = telemetryService.GetIdWellByTelemetryUid(uid); - if (idWell is null) - return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}"); - - var dto = await service.GetAllAsync((int)idWell, - updateFrom, token); - - return Ok(dto); - } - - /// - /// Выгрузка расширенной РТК - /// - /// - /// /// - /// - [HttpGet("report/{wellId}")] - [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task GetReportFileAsync(int wellId, CancellationToken token) - { - var stream = await processMapReportService.MakeReportAsync(wellId, token); - if (stream != null) - { - var well = await wellService.GetOrDefaultAsync(wellId, token); - if (well is null) - return NoContent(); - - var fileName = $"РТК по скважине {well.Caption} куст {well.Cluster}.xlsx"; - return File(stream, "application/octet-stream", fileName); - } - - return NoContent(); - } - - /// - /// Выгрузка режимной карты по бурению скважины - /// - /// - /// - /// - [HttpGet("report/{wellId}/data")] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetDrillProcessMap(int wellId, CancellationToken token) - { - var data = await processMapService.GetProcessMapReportAsync(wellId, token); - return Ok(data); - } - - /// - /// Добавить запись плановой РТК - /// - /// - /// - /// - [HttpPost] - public override async Task> InsertAsync([FromBody] ProcessMapPlanDto value, CancellationToken token) - { - if (!await CanUserEditProcessMapAsync(value.IdWell, token)) - return Forbid(); - - value.IdUser = User.GetUserId() ?? -1; - var result = await base.InsertAsync(value, token); - await NotifyUsersBySignalR(value.IdWell, token); - return result; - } - - /// - /// Редактировать запись по id плановой РТК - /// - /// запись - /// - /// 1 - успешно отредактировано, 0 - нет - [HttpPut] - public override async Task> UpdateAsync([FromBody] ProcessMapPlanDto value, CancellationToken token) - { - if (!await CanUserEditProcessMapAsync(value.IdWell, token)) - return Forbid(); - - value.IdUser = User.GetUserId() ?? -1; - var result = await base.UpdateAsync(value, token); - await NotifyUsersBySignalR(value.IdWell, token); - return result; - } - - /// - /// Возвращает шаблон файла импорта плановой РТК - /// - /// Запрашиваемый файл - [HttpGet("template")] - [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")] - public async Task GetTemplateAsync(CancellationToken cancellationToken) - { - var stream = await processMapPlanImportService.GetExcelTemplateStreamAsync(cancellationToken); - var fileName = "ЕЦП_шаблон_файла_РТК.xlsx"; - return File(stream, "application/octet-stream", fileName); - } - - /// - /// Импортирует плановой РТК из excel (xlsx) файла - /// - /// Id скважины - /// Удалить РТК перед импортом = 1, если файл валидный - /// Загружаемый файл - /// - /// - [HttpPost("import/{idWell}/{options}")] - [ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)] - public async Task ImportAsync(int idWell, - int options, - [Required] IFormFile file, - CancellationToken cancellationToken) - { - int? idUser = User.GetUserId(); - - if (idUser is null) - return Forbid(); - - if (!await CanUserEditProcessMapAsync(idWell, cancellationToken)) - return Forbid(); - - if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") - return this.ValidationBadRequest(nameof(file), "Требуется xlsx файл."); - - using Stream stream = file.OpenReadStream(); - - try - { - await processMapPlanImportService.ImportAsync(idWell, - idUser.Value, - (options & 1) > 0, - stream, - cancellationToken); - } - catch (FileFormatException ex) - { - return this.ValidationBadRequest(nameof(file), ex.Message); - } - - return Ok(); - } - - /// - /// Экспорт плановой РТК в excel - /// - /// Id скважины - /// - /// - [HttpGet("export/{idWell}")] - [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")] - [ProducesResponseType(StatusCodes.Status204NoContent)] - public async Task ExportAsync(int idWell, CancellationToken cancellationToken) - { - int? idUser = User.GetUserId(); - - if (idUser is null) - return Forbid(); - - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken); - - if (well is null) - return NoContent(); - - var stream = await processMapPlanImportService.ExportAsync(idWell, cancellationToken); - var fileName = $"РТК-план по скважине {well.Caption} куст {well.Cluster}.xlsx"; - return File(stream, "application/octet-stream", fileName); - } - - private async Task CanUserEditProcessMapAsync(int idWell, CancellationToken token) - { - var idUser = User.GetUserId(); - - if (!idUser.HasValue) - return false; - - var idCompany = User.GetCompanyId(); - if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, token)) - return false; - - var well = await wellService.GetOrDefaultAsync(idWell, token); - - if (well is null) - return false; - - return well.IdState != 2 || userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell"); - } - - private async Task NotifyUsersBySignalR(int idWell, CancellationToken token) - { - var dtos = await service.GetAllAsync(idWell, null, token); - _ = Task.Run(() => telemetryHubContext.Clients.Group($"well_{idWell}") - .SendAsync(SirnalRMethodGetDataName, dtos), CancellationToken.None); - } - } -} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs b/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs deleted file mode 100644 index 07df4cbe..00000000 --- a/AsbCloudWebApi/Controllers/ProcessMapWellboreDevelopmentController.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using AsbCloudApp.Data.ProcessMap; -using AsbCloudApp.Exceptions; -using AsbCloudApp.Repositories; -using AsbCloudApp.Services; -using Microsoft.AspNetCore.Mvc; -using System; -using Microsoft.AspNetCore.Authorization; - -namespace AsbCloudWebApi.Controllers; - -/// -/// Проработка скважины -/// -public class ProcessMapWellboreDevelopmentController : CrudWellRelatedController -{ - private readonly IUserRepository userRepository; - private readonly IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService; - - public ProcessMapWellboreDevelopmentController(IWellService wellService, - IProcessMapWellboreDevelopmentRepository processMapWellboreDevelopmentRepository, - IUserRepository userRepository, - IProcessMapWellboreDevelopmentService processMapWellboreDevelopmentService) - : base(wellService, processMapWellboreDevelopmentRepository) - { - this.userRepository = userRepository; - this.processMapWellboreDevelopmentService = processMapWellboreDevelopmentService; - } - - /// - /// Добавить запись проработки - /// - /// - /// - /// - /// - public override async Task> InsertAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token) - { - value.IdUser = User.GetUserId() - ?? throw new ForbidException("Неизвестный пользователь"); - - await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, value.IdUser, token); - - return await processMapWellboreDevelopmentService.InsertAsync(value, token); - } - - /// - /// Обновить запись проработки - /// - /// - /// - /// - public override async Task> UpdateAsync(ProcessMapWellboreDevelopmentDto value, CancellationToken token) - { - value.IdUser = User.GetUserId() - ?? throw new ForbidException("Неизвестный пользователь"); - - await AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(value.IdWell, value.IdUser, token); - - return await processMapWellboreDevelopmentService.UpdateAsync(value, token); - } - - /// - /// Возвращает проработки по uid телеметрии - /// - /// Уникальный ключ телеметрии - /// Необязательный параметр. Начальная дата - /// - /// - [HttpGet("telemetry/{uid}")] - [AllowAnonymous] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetByUidAsync(string uid, DateTime updateFrom, CancellationToken cancellationToken) - { - var dto = await processMapWellboreDevelopmentService.GetByTelemetryAsync(uid, updateFrom, - cancellationToken); - - return Ok(dto); - } - - private async Task AssertUserHasAccessToProcessMapWellboreDevelopmentAsync(int idUser, int idWell, CancellationToken cancellationToken) - { - var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) - ?? throw new ForbidException($"Скважины с {idWell} не существует"); - - var idCompany = User.GetCompanyId(); - if (!idCompany.HasValue || !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) - throw new ForbidException("Нет доступа к скважине"); - - if (well.IdState == 2 && !userRepository.HasPermission(idUser, "ProcessMap.editCompletedWell")) - throw new ForbidException("Недостаточно прав для редактирования РТК завершённой скважины"); - } -} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs new file mode 100644 index 00000000..3a72930f --- /dev/null +++ b/AsbCloudWebApi/Controllers/ProcessMaps/ProcessMapBaseController.cs @@ -0,0 +1,146 @@ +using System; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace AsbCloudWebApi.Controllers.ProcessMaps; + +/// +/// РТК +/// +[ApiController] +[Route("api/well/{idWell}/[controller]")] +[Authorize] +public abstract class ProcessMapBaseController : ControllerBase + where TProcessMap : ProcessMapBaseDto +{ + protected int IdUser + { + get + { + var idUser = User.GetUserId(); + + if (!idUser.HasValue) + throw new ForbidException("Неизвестный пользователь"); + + return idUser.Value; + } + } + + protected readonly IWellService wellService; + protected readonly IRepositoryWellRelated repository; + protected readonly IUserRepository userRepository; + + protected ProcessMapBaseController(IWellService wellService, + IRepositoryWellRelated repository, + IUserRepository userRepository) + { + this.wellService = wellService; + this.repository = repository; + this.userRepository = userRepository; + } + + /// + /// Создание РТК + /// + /// Тело запроса + /// Id скважины + /// + /// + [HttpPost] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public virtual async Task InsertAsync(TProcessMap processMap, int idWell, CancellationToken cancellationToken) + { + processMap.IdWell = idWell; + processMap.IdUser = IdUser; + processMap.LastUpdate = DateTime.UtcNow; + + await AssertUserHasAccessToEditProcessMapAsync(processMap.IdWell, cancellationToken); + + var result = await repository.InsertAsync(processMap, cancellationToken); + + return Ok(result); + } + + /// + /// Обновление РТК + /// + /// Тело запроса + /// Id скважины + /// + /// + [HttpPut] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public virtual async Task UpdateAsync(TProcessMap processMap, int idWell, CancellationToken cancellationToken) + { + processMap.IdWell = idWell; + processMap.IdUser = IdUser; + processMap.LastUpdate = DateTime.UtcNow; + + await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); + + var result = await repository.UpdateAsync(processMap, cancellationToken); + + if (result == ICrudRepository.ErrorIdNotFound) + return this.ValidationBadRequest(nameof(processMap.Id), $"РТК с Id: {processMap.Id} не существует"); + + return Ok(result); + } + + /// + /// Удаление РТК + /// + /// Id скважины + /// + /// + [HttpDelete] + [ProducesResponseType(typeof(int), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public virtual async Task DeleteAsync(int idWell, CancellationToken cancellationToken) + { + await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); + + var result = await repository.DeleteAsync(idWell, cancellationToken); + + return Ok(result); + } + + /// + /// Получение РТК по Id скважины + /// + /// Id скважины + /// + /// + [HttpGet] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task GetAsync(int idWell, CancellationToken cancellationToken) + { + var processMaps = await repository.GetByIdWellAsync(idWell, cancellationToken); + + return Ok(processMaps); + } + + protected virtual async Task AssertUserHasAccessToEditProcessMapAsync(int idWell, + CancellationToken cancellationToken) + { + var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken) + ?? throw new ArgumentInvalidException(nameof(idWell),$"Скважины с {idWell} не существует"); + + var idCompany = User.GetCompanyId(); + + if (!idCompany.HasValue || + !await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken)) + throw new ForbidException("Нет доступа к скважине"); + + if (well.IdState == 2 && !userRepository.HasPermission(IdUser, "WellDrillingProcessMap.editCompletedWell")) + throw new ForbidException("Недостаточно прав для редактирования РТК завершенной скважины"); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/WellDrillingProcessMapController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/WellDrillingProcessMapController.cs new file mode 100644 index 00000000..533ed9ca --- /dev/null +++ b/AsbCloudWebApi/Controllers/ProcessMaps/WellDrillingProcessMapController.cs @@ -0,0 +1,214 @@ +using System.ComponentModel.DataAnnotations; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using AsbCloudApp.Data; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Exceptions; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; +using AsbCloudApp.Services.ProcessMaps; +using AsbCloudApp.Services.ProcessMaps.WellDrillingProcessMap; +using AsbCloudWebApi.SignalR; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.SignalR; + +namespace AsbCloudWebApi.Controllers.ProcessMaps; + +public class WellDrillingProcessMapController : ProcessMapBaseController +{ + private readonly IHubContext telemetryHubContext; + + private readonly IWellDrillingProcessMapReportService wellDrillingProcessMapReportService; + private readonly IProcessMapReportExportService wellDrillingProcessMapReportExportService; + private readonly IProcessMapImportService wellDrillingProcessMapImportService; + private readonly ICrudRepository wellSectionRepository; + + public WellDrillingProcessMapController(IWellService wellService, + IWellDrillingProcessMapRepository repository, + IUserRepository userRepository, + IHubContext telemetryHubContext, + IProcessMapReportExportService wellDrillingProcessMapReportExportService, + IProcessMapImportService wellDrillingProcessMapImportService, + IWellDrillingProcessMapReportService wellDrillingProcessMapReportService, + ICrudRepository wellSectionRepository) + : base(wellService, repository, userRepository) + { + this.telemetryHubContext = telemetryHubContext; + this.wellDrillingProcessMapReportExportService = wellDrillingProcessMapReportExportService; + this.wellDrillingProcessMapImportService = wellDrillingProcessMapImportService; + this.wellDrillingProcessMapReportService = wellDrillingProcessMapReportService; + this.wellSectionRepository = wellSectionRepository; + } + + /// + /// Создание РТК + /// + /// Тело запроса + /// Id скважины + /// + /// + public override async Task InsertAsync(WellDrillingProcessMapDto processMap, int idWell, + CancellationToken cancellationToken) + { + await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken); + + var result = await base.InsertAsync(processMap, idWell, cancellationToken); + + await NotifyUsersBySignalR(idWell, cancellationToken); + + return result; + } + + /// + /// Обновление РТК + /// + /// Тело запроса + /// Id скважины + /// + /// + public override async Task UpdateAsync(WellDrillingProcessMapDto processMap, int idWell, + CancellationToken cancellationToken) + { + await CheckIsExistsWellSectionTypeAsync(processMap.IdWellSectionType, cancellationToken); + + var result = await base.UpdateAsync(processMap, idWell, cancellationToken); + + await NotifyUsersBySignalR(idWell, cancellationToken); + + return result; + } + + /// + /// Удаление РТК + /// + /// Id скважины + /// + /// + public override async Task DeleteAsync(int idWell, CancellationToken cancellationToken) + { + var result = await base.DeleteAsync(idWell, cancellationToken); + + await NotifyUsersBySignalR(idWell, cancellationToken); + + return result; + } + + /// + /// Получение отчета РТК бурение + /// + /// Id + /// + /// + [HttpGet("report")] + [ProducesResponseType(typeof(WellDrillingProcessMapDto), StatusCodes.Status200OK)] + public async Task GetReportAsync(int idWell, CancellationToken cancellationToken) + { + var report = await wellDrillingProcessMapReportService.GetAsync(idWell, cancellationToken); + + return Ok(report); + } + + /// + /// Экспорт отчета РТК бурение + /// + /// Id скважины + /// + /// + [HttpGet("report/export")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task ExportReportAsync(int idWell, CancellationToken cancellationToken) + { + var report = await wellDrillingProcessMapReportExportService.ExportAsync(idWell, cancellationToken); + + if (report is null) + return NoContent(); + + return File(report.Value.File, "application/octet-stream", report.Value.Name); + } + + /// + /// Импорт РТК бурение + /// + /// Id скважины + /// + /// + /// + /// + [HttpPost("import/{options}")] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task ImportAsync(int idWell, + int options, + [Required] IFormFile file, + CancellationToken cancellationToken) + { + await AssertUserHasAccessToEditProcessMapAsync(idWell, cancellationToken); + + if (Path.GetExtension(file.FileName).ToLower() != ".xlsx") + return this.ValidationBadRequest(nameof(file), "Требуется xlsx файл."); + + using Stream stream = file.OpenReadStream(); + + try + { + await wellDrillingProcessMapImportService.ImportAsync(idWell, + IdUser, + (options & 1) > 0, + stream, + cancellationToken); + } + catch (FileFormatException ex) + { + return this.ValidationBadRequest(nameof(file), ex.Message); + } + + return Ok(); + } + + /// + /// Экспорт РТК бурение + /// + /// Id скважины + /// + /// + [HttpGet("export")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task ExportAsync(int idWell, CancellationToken cancellationToken) + { + var processMapsFile = await wellDrillingProcessMapImportService.ExportAsync(idWell, cancellationToken); + + return File(processMapsFile.File, "application/octet-stream", processMapsFile.Name); + } + + /// + /// Возвращает шаблон файла для импорта + /// + /// Запрашиваемый файл + [HttpGet("template")] + [ProducesResponseType(typeof(PhysicalFileResult), StatusCodes.Status200OK, "application/octet-stream")] + public async Task GetTemplateAsync(CancellationToken cancellationToken) + { + var template = await wellDrillingProcessMapImportService.GetExcelTemplateStreamAsync(cancellationToken); + return File(template.File, "application/octet-stream", template.Name); + } + + private async Task CheckIsExistsWellSectionTypeAsync(int idWellSectionType, CancellationToken cancellationToken) + { + var wellSection = await wellSectionRepository.GetOrDefaultAsync(idWellSectionType, cancellationToken); + + if (wellSection is null) + throw new ArgumentInvalidException(nameof(WellDrillingProcessMapDto.IdWellSectionType), $"Тип секции с Id: {idWellSectionType} не найден"); + } + + private async Task NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken) + { + var wellDrillingProcessMaps = await repository.GetByIdWellAsync(idWell, cancellationToken); + + await telemetryHubContext.Clients + .Group($"well_{idWell}") + .SendAsync("UpdateProcessMap", wellDrillingProcessMaps, cancellationToken); + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ProcessMaps/WellReamProcessMapController.cs b/AsbCloudWebApi/Controllers/ProcessMaps/WellReamProcessMapController.cs new file mode 100644 index 00000000..43f9c26c --- /dev/null +++ b/AsbCloudWebApi/Controllers/ProcessMaps/WellReamProcessMapController.cs @@ -0,0 +1,15 @@ +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Repositories; +using AsbCloudApp.Services; + +namespace AsbCloudWebApi.Controllers.ProcessMaps; + +public class WellReamProcessMapController : ProcessMapBaseController +{ + public WellReamProcessMapController(IWellService wellService, + IWellReamProcessMapRepository repository, + IUserRepository userRepository) + : base(wellService, repository, userRepository) + { + } +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/SAUB/TelemetryProcessMapController.cs b/AsbCloudWebApi/Controllers/SAUB/TelemetryProcessMapController.cs new file mode 100644 index 00000000..d5217c21 --- /dev/null +++ b/AsbCloudWebApi/Controllers/SAUB/TelemetryProcessMapController.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using System.Threading; +using AsbCloudApp.Data.ProcessMaps; +using AsbCloudApp.Repositories; +using AsbCloudApp.Requests; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Http; +using AsbCloudApp.Services; + +namespace AsbCloudWebApi.Controllers.SAUB; + +/// +/// Данные РТК для SAUB +/// +[ApiController] +[Route("api/[controller]")] +public class TelemetryProcessMapController : ControllerBase +{ + private readonly IWellService wellService; + private readonly ITelemetryService telemetryService; + private readonly IWellDrillingProcessMapRepository wellDrillingProcessMapRepository; + private readonly IWellReamProcessMapRepository wellReamProcessMapRepository; + + public TelemetryProcessMapController(IWellService wellService, + ITelemetryService telemetryService, + IWellDrillingProcessMapRepository wellDrillingProcessMapRepository, + IWellReamProcessMapRepository wellReamProcessMapRepository) + { + this.wellService = wellService; + this.telemetryService = telemetryService; + this.wellDrillingProcessMapRepository = wellDrillingProcessMapRepository; + this.wellReamProcessMapRepository = wellReamProcessMapRepository; + } + + /// + /// Получение РТК бурение по Uid телеметрии + /// + /// Уникальный Id телеметрии + /// Дата с которой требуется получить РТК + /// + /// + [HttpGet("wellDrillingProcessMap")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task GetWellDrillingProcessMapByUidAsync(string uid, DateTime updateFrom, CancellationToken cancellationToken) + { + var idWell = telemetryService.GetIdWellByTelemetryUid(uid); + + if (!idWell.HasValue) + return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}"); + + var wellDrillingProcessMaps = await wellDrillingProcessMapRepository.GetAsync(new WellDrillingProcessMapRequest + { + IdWell = idWell.Value, + UpdateFrom = updateFrom + }, cancellationToken); + + return Ok(wellDrillingProcessMaps); + } + + /// + /// Получение РТК проработки по Uid телеметрии + /// + /// Уникальный Id телеметрии + /// Дата с которой требуется получить РТК + /// + /// + [HttpGet("wellReamProcessMap")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)] + public async Task GetWellReamProcessMapByUidAsync(string uid, DateTime updateFrom, + CancellationToken cancellationToken) + { + var idWell = telemetryService.GetIdWellByTelemetryUid(uid); + + if (!idWell.HasValue) + return this.ValidationBadRequest(nameof(uid), $"Wrong uid {uid}"); + + var wellReamProcessMaps = await wellReamProcessMapRepository.GetAsync(new WellReamProcessMapRequest + { + IdWell = idWell.Value, + UpdateFrom = updateFrom + }, cancellationToken); + + return Ok(wellReamProcessMaps); + } + +} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/WellCompositeController.cs b/AsbCloudWebApi/Controllers/WellCompositeController.cs index d977128d..f9488ac6 100644 --- a/AsbCloudWebApi/Controllers/WellCompositeController.cs +++ b/AsbCloudWebApi/Controllers/WellCompositeController.cs @@ -1,5 +1,4 @@ using AsbCloudApp.Data; -using AsbCloudApp.Data.ProcessMap; using AsbCloudApp.Repositories; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; @@ -7,6 +6,7 @@ using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using AsbCloudApp.Data.ProcessMaps; namespace AsbCloudWebApi.Controllers { @@ -73,7 +73,7 @@ namespace AsbCloudWebApi.Controllers /// [HttpGet("compositeProcessMap")] [Permission] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] + [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetCompositeProcessMap(int idWell, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false))