using AsbCloudApp.Data; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.IO; using System.Threading; using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers { /// /// Хранение файлов /// [Route("api/well/{idWell}/files")] [ApiController] [Authorize] public class FileController : ControllerBase { private readonly IFileService fileService; private readonly IWellService wellService; public FileController(IFileService fileService, IWellService wellService) { this.fileService = fileService; this.wellService = wellService; } /// /// Сохраняет переданные файлы и информацию о них /// /// id скважины /// id категории файла /// Коллекция файлов /// dependency /// Токен отмены задачи /// [HttpPost] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task SaveFilesAsync(int idWell, int idCategory, [FromForm] IFormFileCollection files, [FromServices] IUserService userService, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); int? idUser = User.GetUserId(); if (idCompany is null || idUser is null) return Forbid(); if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); if (!userService.HasPermission((int)idUser, $"File.edit{idCategory}")) return Forbid(); foreach (var file in files) { var fileStream = file.OpenReadStream(); await fileService.SaveAsync(idWell, idUser ?? 0, idCategory, file.FileName, fileStream, token).ConfigureAwait(false); } return Ok(); } /// /// Возвращает информацию о файлах для скважины в выбраной категории /// /// id скважины /// id категории файла /// id компаний для фильтрации возвращаемых файлов /// часть имени файла для поиска /// дата начала /// дата окончания /// для пагинации кол-во записей пропустить /// для пагинации кол-во записей взять /// Токен отмены задачи /// Список информации о файлах в этой категории [HttpGet] [Permission] [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetFilesInfoAsync( [FromRoute] int idWell, int idCategory = default, string companyName = default, string fileName = default, DateTime begin = default, DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var filesInfo = await fileService.GetInfosAsync(idWell, idCategory, companyName, fileName, begin, end, skip, take, token).ConfigureAwait(false); return Ok(filesInfo); } /// /// Возвращает файл с диска на сервере /// /// id скважины /// id запрашиваемого файла /// Токен отмены задачи /// Запрашиваемый файл [HttpGet] [Route("{fileId}")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public async Task GetFileAsync([FromRoute] int idWell, int fileId, 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(); try { var fileInfo = await fileService.GetInfoAsync(fileId, token); var relativePath = fileService.GetUrl(fileInfo); return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); } catch (FileNotFoundException ex) { return NotFound(ex.FileName); } } /// /// Помечает файл как удаленный /// /// id скважины /// id запрашиваемого файла /// dependency /// Токен отмены задачи /// [HttpDelete("{idFile}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task DeleteAsync(int idWell, int idFile, [FromServices] IUserService userService, CancellationToken token = default) { int? idUser = User.GetUserId(); int? idCompany = User.GetCompanyId(); if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var file = await fileService.GetInfoAsync((int)idFile, token); if (!userService.HasPermission((int)idUser, $"File.edit{file.IdCategory}")) return Forbid(); var result = await fileService.MarkAsDeletedAsync(idFile, token); return Ok(result); } /// /// Создает метку для файла /// /// id скважины /// метка файла /// Токен отмены задачи /// [HttpPost("fileMark")] [Permission] public async Task CreateFileMarkAsync(int idWell, FileMarkDto markDto, CancellationToken token = default) { var idCompany = User.GetCompanyId(); var idUser = User.GetUserId(); if (idCompany is null || idUser is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var result = await fileService.CreateFileMarkAsync(markDto, (int)idUser, token) .ConfigureAwait(false); return Ok(result); } /// /// Помечает метку у файла как удаленную /// /// id скважины /// id метки /// Токен отмены задачи /// [HttpDelete("fileMark")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task DeleteFileMarkAsync(int idWell, int idMark, CancellationToken token = default) { var idCompany = User.GetCompanyId(); if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var result = await fileService.MarkFileMarkAsDeletedAsync(idMark, token) .ConfigureAwait(false); return Ok(result); } } }