DD.WellWorkover.Cloud/AsbCloudWebApi/Controllers/ProcessMapController.cs
Степанов Дмитрий 67113878a3 Рефакторинг
1. Добавил проверку при удалении РТК
2. Сделал небольшой рефакторинг контроллеров
2023-10-05 09:33:38 +05:00

284 lines
13 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 AsbCloudApp.Exceptions;
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>
public override async Task<ActionResult<int>> InsertAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
{
value.IdUser = User.GetUserId()
?? throw new ForbidException("Неизвестный пользователь");
await AssertUserHasAccessToProcessMapAsync(value.IdWell, token);
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>
public override async Task<ActionResult<int>> UpdateAsync([FromBody] ProcessMapPlanDto value, CancellationToken token)
{
value.IdUser = User.GetUserId()
?? throw new ForbidException("Неизвестный пользователь");
await AssertUserHasAccessToProcessMapAsync(value.IdWell, token);
var result = await base.UpdateAsync(value, token);
await NotifyUsersBySignalR(value.IdWell, token);
return result;
}
public override async Task<ActionResult<int>> DeleteAsync(int id, CancellationToken token)
{
await AssertUserHasAccessToProcessMapAsync(id, token);
return await base.DeleteAsync(id, token);
}
/// <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)
{
var idUser = User.GetUserId();
if (!idUser.HasValue)
throw new ForbidException("Неизвестный пользователь");
await AssertUserHasAccessToProcessMapAsync(idWell, cancellationToken);
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)
{
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 AssertUserHasAccessToProcessMapAsync(int idWell, CancellationToken cancellationToken)
{
var idUser = User.GetUserId();
var idCompany = User.GetCompanyId();
if (!idCompany.HasValue || !idUser.HasValue)
throw new ForbidException("Неизвестный пользователь");
var well = await wellService.GetOrDefaultAsync(idWell, cancellationToken)
?? throw new ForbidException($"Скважины с {idWell} не существует");
if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, idWell, cancellationToken))
throw new ForbidException("Нет доступа к скважине");
if (well.IdState == 2 && !userRepository.HasPermission(idUser.Value, "ProcessMap.editCompletedWell"))
throw new ForbidException("Недостаточно прав для редактирования РТК завершённой скважины");
}
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);
}
}
}