diff --git a/AsbCloudApp/Data/FileInfoDto.cs b/AsbCloudApp/Data/FileInfoDto.cs index 63abba8f..badcd5a4 100644 --- a/AsbCloudApp/Data/FileInfoDto.cs +++ b/AsbCloudApp/Data/FileInfoDto.cs @@ -39,6 +39,11 @@ namespace AsbCloudApp.Data /// public long Size { get; set; } + /// + /// Помечен как удаленный + /// + public bool IsDeleted { get; set; } + /// /// DTO автора /// diff --git a/AsbCloudApp/Repositories/IFileRepository.cs b/AsbCloudApp/Repositories/IFileRepository.cs index 4363c204..a05cf909 100644 --- a/AsbCloudApp/Repositories/IFileRepository.cs +++ b/AsbCloudApp/Repositories/IFileRepository.cs @@ -14,13 +14,12 @@ namespace AsbCloudApp.Repositories public interface IFileRepository : ICrudService { /// - /// Получить файлы определенной категории + /// Получение файлов по скважине /// - /// - /// + /// /// /// - Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token); + Task> GetInfosAsync(FileRequest request, CancellationToken token); /// /// Получить список файлов в контейнере @@ -28,7 +27,7 @@ namespace AsbCloudApp.Repositories /// /// /// - Task> GetInfosAsync(FileServiceRequest request, CancellationToken token = default); + Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token = default); /// /// Пометить файл как удаленный @@ -79,13 +78,6 @@ namespace AsbCloudApp.Repositories /// Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token); - /// - /// Получение файлов по скважине - /// - /// - /// - /// - Task> GetInfosByWellIdAsync(FileServiceRequest request, CancellationToken token); } #nullable disable } diff --git a/AsbCloudApp/Requests/FileServiceRequest.cs b/AsbCloudApp/Requests/FileRequest.cs similarity index 71% rename from AsbCloudApp/Requests/FileServiceRequest.cs rename to AsbCloudApp/Requests/FileRequest.cs index bc561bdd..14a799e0 100644 --- a/AsbCloudApp/Requests/FileServiceRequest.cs +++ b/AsbCloudApp/Requests/FileRequest.cs @@ -7,13 +7,13 @@ namespace AsbCloudApp.Requests /// /// Параметры запроса для файлового сервиса /// - public class FileServiceRequest : RequestBase + public class FileRequest : RequestBase { /// /// Идентификатор скважины /// [Required] - public int? IdWell { get; set; } + public int IdWell { get; set; } /// /// Идентификатор категории файла @@ -24,12 +24,12 @@ namespace AsbCloudApp.Requests /// /// Наименование компании /// - public string? CompanyName { get; set; } + public string? CompanyNamePart { get; set; } /// /// Имя файла /// - public string? FileName { get; set; } + public string? FileNamePart { get; set; } /// /// Дата начала периода @@ -41,16 +41,6 @@ namespace AsbCloudApp.Requests /// public DateTime? End { get; set; } - /// - /// Идентификатор файла - /// - public int? IdFile { get; set; } - - /// - /// Идентификатор отметки - /// - public int? IdMark { get; set; } - /// /// Признак удаления /// diff --git a/AsbCloudApp/Services/FileService.cs b/AsbCloudApp/Services/FileService.cs index 04b2c65d..3ba250aa 100644 --- a/AsbCloudApp/Services/FileService.cs +++ b/AsbCloudApp/Services/FileService.cs @@ -6,8 +6,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using static Npgsql.PostgresTypes.PostgresCompositeType; -using static System.Net.WebRequestMethods; namespace AsbCloudApp.Services { @@ -41,7 +39,7 @@ namespace AsbCloudApp.Services /// /// /// - public async Task MoveAsync(int idWell, int? idUser, int idCategory, + public async Task MoveAsync(int idWell, int? idUser, int idCategory, string destinationFileName, string srcFilePath, CancellationToken token = default) { destinationFileName = Path.GetFileName(destinationFileName); @@ -61,8 +59,8 @@ namespace AsbCloudApp.Services string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, destinationFileName, fileId); fileStorageRepository.MoveFile(srcFilePath, filePath); - - return await GetInfoAsync(fileId, token); + + return await GetOrDefaultAsync(fileId, token); } /// @@ -75,7 +73,7 @@ namespace AsbCloudApp.Services /// /// /// - public async Task SaveAsync(int idWell, int? idUser, int idCategory, + public async Task SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token) { //save info to db @@ -85,7 +83,7 @@ namespace AsbCloudApp.Services IdAuthor = idUser, IdCategory = idCategory, Name = Path.GetFileName(fileFullName), - Size = fileStream?.Length ?? 0 + Size = fileStream.Length }; var fileId = await fileRepository.InsertAsync(dto, token) @@ -95,26 +93,7 @@ namespace AsbCloudApp.Services string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, fileFullName, fileId); await fileStorageRepository.SaveFileAsync(filePath, fileStream, token); - return await GetInfoAsync(fileId, token); - } - - /// - /// Инфо о файле - /// - /// - /// - /// - public async Task GetInfoAsync(int idFile, - CancellationToken token) - { - var dto = await fileRepository.GetOrDefaultAsync(idFile, token).ConfigureAwait(false); - - var ext = Path.GetExtension(dto.Name); - - var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext); - var fullPath = Path.GetFullPath(relativePath); - - return dto; + return await GetOrDefaultAsync(fileId, token); } /// @@ -198,15 +177,23 @@ namespace AsbCloudApp.Services return result; } + /// + /// Получить файлы определенной категории + /// + /// + /// + /// + public Task> GetInfosAsync(FileRequest request, CancellationToken token) + => fileRepository.GetInfosAsync(request, token); + /// /// Получить список файлов в контейнере /// /// /// /// - public async Task> GetInfosAsync(FileServiceRequest request, CancellationToken token) - => await fileRepository.GetInfosAsync(request, token) - .ConfigureAwait(false); + public Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token) + => fileRepository.GetInfosPaginatedAsync(request, token); /// /// Пометить файл как удаленный @@ -214,9 +201,8 @@ namespace AsbCloudApp.Services /// /// /// - public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) - => await fileRepository.MarkAsDeletedAsync(idFile, token) - .ConfigureAwait(false); + public Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) + => fileRepository.MarkAsDeletedAsync(idFile, token); /// /// добавить метку на файл @@ -225,9 +211,8 @@ namespace AsbCloudApp.Services /// /// /// - public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) - => await fileRepository.CreateFileMarkAsync(fileMarkDto, idUser, token) - .ConfigureAwait(false); + public Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) + => fileRepository.CreateFileMarkAsync(fileMarkDto, idUser, token); /// /// Получить запись по id @@ -235,9 +220,8 @@ namespace AsbCloudApp.Services /// /// /// - public async Task GetOrDefaultAsync(int id, CancellationToken token) - => await fileRepository.GetOrDefaultAsync(id, token) - .ConfigureAwait(false); + public Task GetOrDefaultAsync(int id, CancellationToken token) + => fileRepository.GetOrDefaultAsync(id, token); /// /// получить инфо о файле по метке @@ -245,9 +229,8 @@ namespace AsbCloudApp.Services /// /// /// - public async Task GetByMarkId(int idMark, CancellationToken token) - => await fileRepository.GetByMarkId(idMark, token) - .ConfigureAwait(false); + public Task GetByMarkId(int idMark, CancellationToken token) + => fileRepository.GetByMarkId(idMark, token); /// /// получить инфо о файле по метке @@ -255,30 +238,8 @@ namespace AsbCloudApp.Services /// /// /// - public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) - => await fileRepository.MarkFileMarkAsDeletedAsync(idsMarks, token) - .ConfigureAwait(false); - - /// - /// Получение файлов по скважине - /// - /// - /// - /// - public async Task> GetInfosByWellIdAsync(int idWell, CancellationToken token) - => await fileRepository.GetInfosByWellIdAsync(new FileServiceRequest { IdWell = idWell, IsDeleted = false }, token) - .ConfigureAwait(false); - - /// - /// Получить файлы определенной категории - /// - /// - /// - /// - /// - public async Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token) - => await fileRepository.GetInfosByCategoryAsync(idWell, idCategory, token) - .ConfigureAwait(false); + public Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) + => fileRepository.MarkFileMarkAsDeletedAsync(idsMarks, token); /// /// Удаление всех файлов по скважине помеченных как удаленные @@ -288,8 +249,8 @@ namespace AsbCloudApp.Services /// public async Task DeleteFilesFromDbMarkedDeletionByIdWell(int idWell, CancellationToken token) { - var files = await fileRepository.GetInfosByWellIdAsync( - new FileServiceRequest + var files = await fileRepository.GetInfosAsync( + new FileRequest { IdWell = idWell, IsDeleted = true @@ -306,8 +267,8 @@ namespace AsbCloudApp.Services /// public async Task DeleteFilesNotExistStorage(int idWell, CancellationToken token) { - var files = await fileRepository.GetInfosByWellIdAsync( - new FileServiceRequest + var files = await fileRepository.GetInfosAsync( + new FileRequest { IdWell = idWell }, @@ -324,8 +285,8 @@ namespace AsbCloudApp.Services /// public async Task> GetListFilesNotDisc(int idWell, CancellationToken token) { - var files = await fileRepository.GetInfosByWellIdAsync( - new FileServiceRequest + var files = await fileRepository.GetInfosAsync( + new FileRequest { IdWell = idWell }, @@ -338,9 +299,8 @@ namespace AsbCloudApp.Services /// Получить файловый поток по идентификатору файла /// /// - /// /// - public FileStream GetFileStream(FileInfoDto fileInfo) + public Stream GetFileStream(FileInfoDto fileInfo) { var relativePath = GetUrl(fileInfo); var fileStream = new FileStream(Path.GetFullPath(relativePath), FileMode.Open); diff --git a/AsbCloudDb/EFExtentions.cs b/AsbCloudDb/EFExtentions.cs index f0523294..3cbf3509 100644 --- a/AsbCloudDb/EFExtentions.cs +++ b/AsbCloudDb/EFExtentions.cs @@ -117,6 +117,17 @@ namespace AsbCloudDb } return stat; } + + public static IQueryable SkipTake(this IQueryable query, int? skip, int? take) + { + if (skip > 0) + query = query.Skip((int)skip); + + if (take > 0) + query = query.Take((int)take); + + return query; + } } interface IQueryStringFactory { } diff --git a/AsbCloudInfrastructure/Repository/FileRepository.cs b/AsbCloudInfrastructure/Repository/FileRepository.cs index 6eacf56b..deb43445 100644 --- a/AsbCloudInfrastructure/Repository/FileRepository.cs +++ b/AsbCloudInfrastructure/Repository/FileRepository.cs @@ -1,12 +1,17 @@ using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Services; +using DocumentFormat.OpenXml.Drawing.Charts; +using DocumentFormat.OpenXml.Wordprocessing; using Mapster; using Microsoft.EntityFrameworkCore; +using Org.BouncyCastle.Asn1.Ocsp; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -16,7 +21,7 @@ namespace AsbCloudInfrastructure.Repository #nullable enable public class FileRepository : IFileRepository { - private readonly IQueryable dbSetConfigured; + private readonly IQueryable dbSetConfigured; private readonly IAsbCloudDbContext db; public FileRepository(IAsbCloudDbContext db) @@ -31,10 +36,55 @@ namespace AsbCloudInfrastructure.Repository .Include(f => f.Well); } - public async Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token) + private IQueryable BuildQuery(FileRequest request) { - var entities = await dbSetConfigured - .Where(e => e.IdWell == idWell && e.IdCategory == idCategory && e.IsDeleted == false) + var query = dbSetConfigured + .Where(e => e.IdWell == request.IdWell); + + double timezoneOffsetHours = query.FirstOrDefault() + ?.Well.Timezone.Hours ?? 5d; + + if (request.IdCategory is not null) + query = query.Where(x => x.IdCategory == request.IdCategory); + + if (request.IsDeleted is not null) + query = query.Where(x => x.IsDeleted == request.IsDeleted); + + if (request.CompanyNamePart is not null) + query = query.Where(e => e.Author.Company.Caption.ToLower().Contains(request.CompanyNamePart.ToLower())); + + if (request.FileNamePart is not null) + query = query.Where(e => e.Name.ToLower().Contains(request.FileNamePart.ToLower())); + + if (request.Begin is not null) + { + var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezoneOffsetHours); + query = query.Where(e => e.UploadDate >= beginUtc); + } + + if (request.End is not null) + { + var endUtc = request.End.Value.ToUtcDateTimeOffset(timezoneOffsetHours); + query = query.Where(e => e.UploadDate <= endUtc); + } + + if (request?.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + query = query + .OrderBy(o => o.UploadDate); + + return query; + } + + public async Task> GetInfosAsync(FileRequest request, CancellationToken token) + { + var query = BuildQuery(request); + + var entities = await query + .SkipTake(request.Skip, request.Take) .AsNoTracking() .ToListAsync(token) .ConfigureAwait(false); @@ -43,51 +93,37 @@ namespace AsbCloudInfrastructure.Repository return dtos; } - public async Task> GetInfosAsync(FileServiceRequest request, CancellationToken token = default) + public async Task> GetInfosPaginatedAsync(FileRequest request, CancellationToken token = default) { - var query = GetQuery(request, token); - var firstFile = query.FirstOrDefault(); var skip = request.Skip ?? 0; var take = request.Take ?? 32; - if (firstFile is null) - return new PaginationContainer() - { - Skip = skip, - Take = take, - Count = 0, - }; + var query = BuildQuery(request); - var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; - var count = await query.CountAsync(token).ConfigureAwait(false); - var result = new PaginationContainer(count) + var result = new PaginationContainer() { Skip = skip, Take = take, - Count = count, + Count = await query.CountAsync(token), }; - if (count <= skip) + if (result.Count == 0) return result; - query = query.OrderBy(e => e.UploadDate); - - if (skip > 0) - query = query.Skip(skip); - query = query.Take(take); - var entities = await query - .Take(take).AsNoTracking().ToListAsync(token) + .SkipTake(skip, take) + .AsNoTracking() + .ToListAsync(token) .ConfigureAwait(false); - var dtos = entities.Select(e => Convert(e, timezoneOffset)); - result.Items.AddRange(dtos); + result.Items = entities.Select(e => Convert(e)).ToList(); + return result; } public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) { - var result = new List(); + var result = Enumerable.Empty(); var entities = await dbSetConfigured .AsNoTracking() @@ -95,14 +131,8 @@ namespace AsbCloudInfrastructure.Repository .ToListAsync(token) .ConfigureAwait(false); - foreach (var entity in entities) - { - if (entity is null) - { - throw new FileNotFoundException($"fileId:{entity.Id} not found"); - } - result.Add(Convert(entity)); - } + if (entities is not null) + result = entities.Select(entity => Convert(entity)); return result; } @@ -140,7 +170,7 @@ namespace AsbCloudInfrastructure.Repository .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) .ConfigureAwait(false); - FileInfoDto dto = Convert(entity); + FileInfoDto dto = Convert(entity!); return dto; } @@ -178,26 +208,13 @@ namespace AsbCloudInfrastructure.Repository return await db.SaveChangesAsync(token); } - public async Task> GetInfosByWellIdAsync(FileServiceRequest request, CancellationToken token) - { - var query = GetQuery(request, token); - - var entities = await query - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e)); - return dtos; - } - public async Task> GetAllAsync(CancellationToken token) => await dbSetConfigured.AsNoTracking() .Select(x => Convert(x)) .ToListAsync(token) .ConfigureAwait(false); - public async Task GetOrDefaultAsync(int id, CancellationToken token) + public async Task GetOrDefaultAsync(int id, CancellationToken token) { var entity = await dbSetConfigured .AsNoTracking() @@ -205,24 +222,20 @@ namespace AsbCloudInfrastructure.Repository .ConfigureAwait(false); if (entity is null) - { - throw new FileNotFoundException($"fileId:{id} not found"); - } + return null; var dto = Convert(entity); return dto; } - public FileInfoDto GetOrDefault(int id) + public FileInfoDto? GetOrDefault(int id) { var entity = dbSetConfigured .AsNoTracking() .FirstOrDefault(f => f.Id == id); if (entity is null) - { - throw new FileNotFoundException($"fileId:{id} not found"); - } + return null; var dto = Convert(entity); return dto; @@ -230,7 +243,7 @@ namespace AsbCloudInfrastructure.Repository public async Task InsertAsync(FileInfoDto newItem, CancellationToken token) { - var fileInfo = new AsbCloudDb.Model.FileInfo() + var fileInfo = new FileInfo() { IdWell = newItem.IdWell, IdAuthor = newItem.IdAuthor, @@ -261,50 +274,13 @@ namespace AsbCloudInfrastructure.Repository throw new NotImplementedException(); } - private IQueryable GetQuery(FileServiceRequest request, CancellationToken token = default) - { - var query = dbSetConfigured - .Where(e => e.IdWell == request.IdWell && - e.IdCategory == request.IdCategory); - - if (request.IsDeleted is not null) - query = query.Where(x => x.IsDeleted == request.IsDeleted); - - if (request.CompanyName is not null) - query = query.Where(e => (e.Author == null) || - (e.Author.Company == null) || - e.Author.Company.Caption.Contains(request.CompanyName)); - - if (request.FileName is not null) - query = query.Where(e => e.Name.ToLower().Contains(request.FileName.ToLower())); - - var firstFile = query.FirstOrDefault(); - if (firstFile is null) - return Enumerable.Empty().AsQueryable(); - - var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; - if (request.Begin is not null) - { - var beginUtc = request.Begin.Value.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate >= beginUtc); - } - - if (request.End is not null) - { - var endUtc = request.End.Value.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate <= endUtc); - } - - return query; - } - - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity) + private static FileInfoDto Convert(FileInfo entity) { var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; return Convert(entity, timezoneOffset); } - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity, double timezoneOffset) + private static FileInfoDto Convert(FileInfo entity, double timezoneOffset) { var dto = entity.Adapt(); dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); diff --git a/AsbCloudInfrastructure/Repository/FileStorageRepository.cs b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs index 0d7a2cf8..8bd61e2f 100644 --- a/AsbCloudInfrastructure/Repository/FileStorageRepository.cs +++ b/AsbCloudInfrastructure/Repository/FileStorageRepository.cs @@ -1,13 +1,10 @@ using AsbCloudApp.Data; -using AsbCloudApp.Exceptions; using AsbCloudApp.Repositories; -using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -using FileInfo = System.IO.FileInfo; namespace AsbCloudInfrastructure.Repository { @@ -102,10 +99,8 @@ namespace AsbCloudInfrastructure.Repository var allFilesPath = GetFilesPath(idWell); foreach (var filePath in allFilesPath) - { - int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile); - result.Add(idFile); - } + if(int.TryParse(Path.GetFileNameWithoutExtension(filePath), out int idFile)) + result.Add(idFile); return result; } @@ -118,7 +113,8 @@ namespace AsbCloudInfrastructure.Repository private static void CreateDirectory(string filePath) { - Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + var directoryName = Path.GetDirectoryName(filePath)!; + Directory.CreateDirectory(directoryName); } } #nullable disable diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index ca0827b0..e926a886 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -282,7 +282,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram fileMarkDto.IdMarkType != idMarkTypeReject) throw new ArgumentInvalidException($"В этом методе допустимы только отметки о принятии или отклонении.", nameof(fileMarkDto)); - var fileInfo = await fileService.GetInfoAsync(fileMarkDto.IdFile, token) + var fileInfo = await fileService.GetOrDefaultAsync(fileMarkDto.IdFile, token) .ConfigureAwait(false); if (fileInfo is null) @@ -357,7 +357,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private async Task NotifyPublisherOnFullAccepAsync(FileMarkDto fileMark, CancellationToken token) { - var file = await fileService.GetInfoAsync(fileMark.IdFile, token); + var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var user = file.Author; var factory = new DrillingMailBodyFactory(configuration); @@ -369,7 +369,7 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram private async Task NotifyPublisherOnRejectAsync(FileMarkDto fileMark, CancellationToken token) { - var file = await fileService.GetInfoAsync(fileMark.IdFile, token); + var file = await fileService.GetOrDefaultAsync(fileMark.IdFile, token); var well = await wellService.GetOrDefaultAsync(file.IdWell, token); var user = file.Author; var factory = new DrillingMailBodyFactory(configuration); @@ -473,7 +473,6 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram var well = await wellService.GetOrDefaultAsync(idWell, token); var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx"; var tempResultFilePath = Path.Combine(Path.GetTempPath(), "drillingProgram", resultFileName); - var mailService = new EmailService(backgroundWorker, configuration); async Task funcProgramMake(string id, CancellationToken token) { var contextOptions = new DbContextOptionsBuilder() diff --git a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs index 62d82522..4d44f38c 100644 --- a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs +++ b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Exceptions; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Repository; @@ -96,7 +97,7 @@ namespace AsbCloudInfrastructure.Services .Select(g => g.Key); var files = (await fileService - .GetInfosByWellIdAsync(idWell, token) + .GetInfosAsync(new FileRequest { IdWell = idWell}, token) .ConfigureAwait(false)) .Where(f => categoriesIds.Contains(f.IdCategory)) .ToArray(); @@ -162,7 +163,12 @@ namespace AsbCloudInfrastructure.Services public async Task GetFilesHistoryByIdCategory(int idWell, int idCategory, CancellationToken token) { - var files = await fileService.GetInfosByCategoryAsync(idWell, idCategory, token).ConfigureAwait(false); + var request = new FileRequest + { + IdWell = idWell, + IdCategory = idCategory, + }; + var files = await fileService.GetInfosAsync(request, token).ConfigureAwait(false); return new WellFinalDocumentsHistoryDto { IdWell = idWell, diff --git a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs index fa72df35..a1e275b9 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs @@ -220,7 +220,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests { ConfigureNotApproved(); fileServiceMock - .Setup(s => s.GetInfoAsync(It.IsAny(), It.IsAny())) + .Setup(s => s.GetOrDefaultAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(file1002.Adapt())); fileServiceMock @@ -251,7 +251,7 @@ namespace AsbCloudWebApi.Tests.ServicesTests { ConfigureNotApproved(); fileServiceMock - .Setup(s => s.GetInfoAsync(It.IsAny(), It.IsAny())) + .Setup(s => s.GetOrDefaultAsync(It.IsAny(), It.IsAny())) .Returns(Task.FromResult(file1002.Adapt())); fileServiceMock diff --git a/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs index 4f83e996..698f83cd 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/FileServiceTest.cs @@ -109,18 +109,12 @@ namespace AsbCloudWebApi.Tests.ServicesTests return Task.FromResult(result); }); - repositoryMock.Setup(x => x.GetInfosByWellIdAsync(It.IsAny(), It.IsAny())) - .Returns((FileServiceRequest request, CancellationToken token) => { + repositoryMock.Setup(x => x.GetInfosAsync(It.IsAny(), It.IsAny())) + .Returns((FileRequest request, CancellationToken token) => { var data = Files.Where(x => x.IdWell == request.IdWell); return Task.FromResult(data); }); - repositoryMock.Setup(x => x.GetInfosByCategoryAsync(It.IsAny(), It.IsAny(), It.IsAny())) - .Returns((int idWell, int idCategory, CancellationToken token) => { - var data = Files.Where(x => x.IdWell == idWell && x.IdCategory == idCategory); - return Task.FromResult(data); - }); - repositoryMock.Setup(x => x.CreateFileMarkAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Returns((FileMarkDto dto, int idUser, CancellationToken token) => { dto.Id = FileMarks.Max(x => x.Id) + 1; @@ -149,9 +143,9 @@ namespace AsbCloudWebApi.Tests.ServicesTests } [Fact] - public async Task GetInfoAsync_returns_FileInfo() + public async Task GetOrDefaultAsync_returns_FileInfo() { - var data = await fileService.GetInfoAsync(1742, CancellationToken.None); + var data = await fileService.GetOrDefaultAsync(1742, CancellationToken.None); Assert.NotNull(data); } @@ -191,20 +185,6 @@ namespace AsbCloudWebApi.Tests.ServicesTests Assert.True(result > 0); } - [Fact] - public async Task GetInfosByWellIdAsync_returns_FileInfo() - { - var data = await fileService.GetInfosByWellIdAsync(90, CancellationToken.None); - Assert.NotNull(data); - } - - [Fact] - public async Task GetInfosByCategoryAsync_returns_FileInfo() - { - var data = await fileService.GetInfosByCategoryAsync(90, 10040, CancellationToken.None); - Assert.NotNull(data); - } - [Fact] public async Task CreateFileMarkAsync() { diff --git a/AsbCloudWebApi/Controllers/FileController.cs b/AsbCloudWebApi/Controllers/FileController.cs index 7d4e395b..d4dfad33 100644 --- a/AsbCloudWebApi/Controllers/FileController.cs +++ b/AsbCloudWebApi/Controllers/FileController.cs @@ -7,8 +7,7 @@ using Microsoft.AspNetCore.Mvc; using System.IO; using System.Threading; using System.Threading.Tasks; -using System.Text; -using static System.Net.WebRequestMethods; +using AsbCloudDb.Model; namespace AsbCloudWebApi.Controllers { @@ -79,19 +78,19 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetFilesInfoAsync( - [FromQuery] FileServiceRequest request, + [FromQuery] FileRequest request, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); - if (request.IdWell is null || request.IdCategory is null || idCompany is null) + if (request.IdCategory is null || idCompany is null) return Forbid(); if (!await wellService.IsCompanyInvolvedInWellAsync(idCompany.Value, - request.IdWell.Value, token).ConfigureAwait(false)) + request.IdWell, token).ConfigureAwait(false)) return Forbid(); - var filesInfo = await fileService.GetInfosAsync(request, token).ConfigureAwait(false); + var filesInfo = await fileService.GetInfosPaginatedAsync(request, token).ConfigureAwait(false); return Ok(filesInfo); } @@ -100,36 +99,33 @@ namespace AsbCloudWebApi.Controllers /// Возвращает файл с диска на сервере /// /// id скважины - /// id запрашиваемого файла + /// id запрашиваемого файла /// Токен отмены задачи /// Запрашиваемый файл [HttpGet] - [Route("{fileId}")] + [Route("{idFile}")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] public async Task GetFileAsync([FromRoute] int idWell, - int fileId, CancellationToken token = default) + int idFile, CancellationToken token = default) { int? idCompany = User.GetCompanyId(); if (idCompany is null) return Forbid(); + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token); + + if (fileInfo is null) + return NotFound(idFile); + if (!await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, - idWell, token).ConfigureAwait(false)) + fileInfo.IdWell, token).ConfigureAwait(false)) return Forbid(); - try - { - var fileInfo = await fileService.GetInfoAsync(fileId, token); - var fileStream = fileService.GetFileStream(fileInfo); + var fileStream = fileService.GetFileStream(fileInfo); - return File(fileStream, "application/octet-stream", fileInfo.Name); - } - catch (FileNotFoundException ex) - { - return NotFound(ex.FileName); - } + return File(fileStream, "application/octet-stream", fileInfo.Name); } /// @@ -151,13 +147,16 @@ namespace AsbCloudWebApi.Controllers int? idCompany = User.GetCompanyId(); - if (idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, + if (idUser is null || idCompany is null || !await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false)) return Forbid(); - var file = await fileService.GetInfoAsync((int)idFile, token); + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token); - if (!userService.HasPermission((int)idUser, $"File.edit{file.IdCategory}")) + if (fileInfo is null) + return NotFound(idFile); + + if (!userService.HasPermission((int)idUser, $"File.edit{fileInfo?.IdCategory}")) return Forbid(); var result = await fileService.MarkAsDeletedAsync(idFile, token);