DD.WellWorkover.Cloud/AsbCloudWebApi/Controllers/ProcessMapController.cs
2023-09-28 17:42:30 +05:00

283 lines
12 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
{
/// <summary>
/// РТК
/// </summary>
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ProcessMapController : CrudWellRelatedController<ProcessMapPlanDto, IProcessMapPlanRepository>
{
private readonly ITelemetryService telemetryService;
private readonly IHubContext<TelemetryHub> 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<TelemetryHub> 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;
}
/// <summary>
/// Возвращает все значения для коридоров бурения по uid панели
/// </summary>
/// <param name="uid"> uid панели </param>
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
/// <param name="token"> Токен отмены задачи </param>
/// <returns> Список параметров для коридоров бурения </returns>
[HttpGet("/api/telemetry/{uid}/drillFlowChart")]
[Obsolete("use GetByUidAsync(..) instead")]
[AllowAnonymous]
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanDto>), (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<ProcessMapPlanDto>());
}
/// <summary>
/// Возвращает РТК по uid телеметрии
/// </summary>
/// <param name="uid"> uid телеметрии </param>
/// <param name="updateFrom"> Дата, с которой следует искать новые параметры </param>
/// <param name="token"> Токен отмены задачи </param>
/// <returns> Список параметров для коридоров бурения </returns>
[HttpGet("/api/telemetry/{uid}/processMap")]
[AllowAnonymous]
[ProducesResponseType(typeof(IEnumerable<ProcessMapPlanDto>), (int)System.Net.HttpStatusCode.OK)]
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
public async Task<IActionResult> 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);
}
/// <summary>
/// Выгрузка расширенной РТК
/// </summary>
/// <param name="wellId"></param>
/// /// <param name="token"></param>
/// <returns></returns>
[HttpGet("report/{wellId}")]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> 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();
}
/// <summary>
/// Выгрузка режимной карты по бурению скважины
/// </summary>
/// <param name="wellId"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("report/{wellId}/data")]
[ProducesResponseType(typeof(IEnumerable<ProcessMapReportDto>), (int)System.Net.HttpStatusCode.OK)]
public async Task<IActionResult> GetDrillProcessMap(int wellId, CancellationToken token)
{
var data = await processMapService.GetProcessMapReportAsync(wellId, token);
return Ok(data);
}
/// <summary>
/// Добавить запись плановой РТК
/// </summary>
/// <param name="value"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpPost]
public override async Task<ActionResult<int>> 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;
}
/// <summary>
/// Редактировать запись по id плановой РТК
/// </summary>
/// <param name="value">запись</param>
/// <param name="token"></param>
/// <returns>1 - успешно отредактировано, 0 - нет</returns>
[HttpPut]
public override async Task<ActionResult<int>> 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;
}
/// <summary>
/// Возвращает шаблон файла импорта плановой РТК
/// </summary>
/// <returns>Запрашиваемый файл</returns>
[HttpGet("template")]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
public async Task<IActionResult> GetTemplateAsync(CancellationToken cancellationToken)
{
var stream = await processMapPlanImportService.GetExcelTemplateStreamAsync(cancellationToken);
var fileName = "ЕЦП_шаблон_файла_РТК.xlsx";
return File(stream, "application/octet-stream", fileName);
}
/// <summary>
/// Импортирует плановой РТК из excel (xlsx) файла
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="options">Удалить РТК перед импортом = 1, если файл валидный</param>
/// <param name="file">Загружаемый файл</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpPost("import/{idWell}/{options}")]
[ProducesResponseType(typeof(ValidationProblemDetails), (int)System.Net.HttpStatusCode.BadRequest)]
public async Task<IActionResult> 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();
}
/// <summary>
/// Экспорт плановой РТК в excel
/// </summary>
/// <param name="idWell">Id скважины</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
[HttpGet("export/{idWell}")]
[ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK, "application/octet-stream")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<IActionResult> 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<bool> 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);
}
}
}