using AsbCloudApp.Data; using AsbCloudApp.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.IO; using System.Linq; 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; } /// <summary> /// Сохраняет переданные файлы и информацию о них /// </summary> /// <param name="idWell">id скважины</param> /// <param name="idCategory">id категории файла</param> /// <param name="files">Коллекция файлов</param> /// <param name="token"> Токен отмены задачи </param> /// <returns></returns> [HttpPost] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task<IActionResult> SaveFilesAsync(int idWell, int idCategory, [FromForm] IFormFileCollection files, 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(); var fileInfoCollection = files.Select(f => new FileInfoDto { Name = f.FileName, IdCategory = idCategory, UploadDate = DateTime.Now }); foreach (var file in files) { var fileStream = file.OpenReadStream(); await fileService.SaveAsync(idWell, idUser??0, idCategory, file.FileName, fileStream); } return Ok(); } /// <summary> /// Возвращает информацию о файлах для скважины в выбраной категории /// </summary> /// <param name="idWell">id скважины</param> /// <param name="idCategory">id категории файла</param> /// <param name="token"> Токен отмены задачи </param> /// <returns>Список информации о файлах в этой категории</returns> [HttpGet] [Route("category/{idCategory}")] [ProducesResponseType(typeof(IEnumerable<FileInfoDto>), (int)System.Net.HttpStatusCode.OK)] public async Task<IActionResult> GetInfosByCategoryAsync([FromRoute] int idWell, int idCategory, 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.GetInfosByCategoryAsync(idWell, idCategory, token) .ConfigureAwait(false); return Ok(filesInfo); } /// <summary> /// Возвращает информацию о файлах для скважины в выбраной категории /// </summary> /// <param name="idWell">id скважины</param> /// <param name="idCategory">id категории файла</param> /// <param name="companyName">id компаний для фильтрации возвращаемых файлов</param> /// <param name="fileName">часть имени файла для поиска</param> /// <param name="begin">дата начала</param> /// <param name="end">дата окончания</param> /// <param name="skip">для пагинации кол-во записей пропустить</param> /// <param name="take">для пагинации кол-во записей взять </param> /// <param name="token"> Токен отмены задачи </param> /// <returns>Список информации о файлах в этой категории</returns> [HttpGet] [ProducesResponseType(typeof(PaginationContainer<FileInfoDto>), (int)System.Net.HttpStatusCode.OK)] public async Task<IActionResult> 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); } /// <summary> /// Возвращает файл с диска на сервере /// </summary> /// <param name="idWell">id скважины</param> /// <param name="fileId">id запрашиваемого файла</param> /// <param name="token"> Токен отмены задачи </param> /// <returns>Запрашиваемый файл</returns> [HttpGet] [Route("{fileId}")] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public async Task<IActionResult> GetFileAsync([FromRoute] int idWell, int fileId, CancellationToken token = default) { try { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var fileInfo = await fileService.GetInfoAsync(fileId, token); if (fileInfo is null) throw new FileNotFoundException(); var relativePath = fileService.GetUrl(fileInfo); return PhysicalFile(Path.GetFullPath(relativePath), "application/octet-stream", fileInfo.Name); } catch (FileNotFoundException ex) { return NotFound($"Файл не найден. Текст ошибки: {ex.Message}"); } } /// <summary> /// Помечает файл как удаленный /// </summary> /// <param name="idWell">id скважины</param> /// <param name="idFile">id запрашиваемого файла</param> /// <param name="token"> Токен отмены задачи </param> /// <returns></returns> [HttpDelete("{idFile}")] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] public async Task<IActionResult> DeleteAsync(int idWell, int idFile, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); var result = await fileService.MarkAsDeletedAsync(idFile, token); return Ok(result); } } }