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 ProcessMapWellDrillingController : ProcessMapBaseController { private readonly IHubContext telemetryHubContext; private readonly IProcessMapReportWellDrillingService wellDrillingProcessMapReportService; private readonly IProcessMapReportExportService wellDrillingProcessMapReportExportService; private readonly IProcessMapImportService wellDrillingProcessMapImportService; public ProcessMapWellDrillingController(IWellService wellService, IProcessMapPlanRepository repository, IUserRepository userRepository, IHubContext telemetryHubContext, IProcessMapReportExportService wellDrillingProcessMapReportExportService, IProcessMapImportService wellDrillingProcessMapImportService, IProcessMapReportWellDrillingService wellDrillingProcessMapReportService, ICrudRepository wellSectionRepository) : base(wellService, repository, userRepository, wellSectionRepository) { this.telemetryHubContext = telemetryHubContext; this.wellDrillingProcessMapReportExportService = wellDrillingProcessMapReportExportService; this.wellDrillingProcessMapImportService = wellDrillingProcessMapImportService; this.wellDrillingProcessMapReportService = wellDrillingProcessMapReportService; } /// /// Создание РТК /// /// Тело запроса /// Id скважины /// /// public override async Task InsertAsync(ProcessMapPlanWellDrillingDto processMap, int idWell, CancellationToken cancellationToken) { var result = await base.InsertAsync(processMap, idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken); return result; } /// /// Обновление РТК /// /// Тело запроса /// Id скважины /// /// public override async Task UpdateAsync(ProcessMapPlanWellDrillingDto processMap, int idWell, CancellationToken cancellationToken) { var result = await base.UpdateAsync(processMap, idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken); return result; } /// /// Удаление РТК /// /// Id удаляемой РТК /// Id скважины /// /// public override async Task DeleteAsync(int id, int idWell, CancellationToken cancellationToken) { var result = await base.DeleteAsync(id, idWell, cancellationToken); await NotifyUsersBySignalR(idWell, cancellationToken); return result; } /// /// Получение отчета РТК бурение /// /// Id /// /// [HttpGet("report")] [ProducesResponseType(typeof(ProcessMapPlanWellDrillingDto), 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); await NotifyUsersBySignalR(idWell, 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 NotifyUsersBySignalR(int idWell, CancellationToken cancellationToken) { var wellDrillingProcessMaps = await repository.GetByIdWellAsync(idWell, cancellationToken); await telemetryHubContext.Clients .Group($"well_{idWell}") .SendAsync("UpdateProcessMap", wellDrillingProcessMaps, cancellationToken); } }