diff --git a/AsbCloudApp/Services/IFileRepository.cs b/AsbCloudApp/Services/IFileRepository.cs new file mode 100644 index 00000000..e01891cc --- /dev/null +++ b/AsbCloudApp/Services/IFileRepository.cs @@ -0,0 +1,97 @@ +using AsbCloudApp.Data; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Services +{ + /// + /// Сервис доступа к файлам + /// + public interface IFileRepository : ICrudService + { + /// + /// Получить файлы определенной категории + /// + /// + /// + /// + /// + Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token); + + /// + /// Получить список файлов в контейнере + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + Task> GetInfosAsync(int idWell, + int idCategory, string companyName = default, string fileName = default, DateTime begin = default, + DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default); + + /// + /// Пометить файл как удаленный + /// + /// + /// + /// + Task MarkAsDeletedAsync(int idFile, CancellationToken token = default); + + /// + /// удалить файлы + /// + /// + /// + /// + Task> DeleteAsync(IEnumerable ids, CancellationToken token); + + /// + /// получить инфо о файле по метке + /// + /// + /// + /// + Task GetByMarkId(int idMark, CancellationToken token); + + /// + /// добавить метку на файл + /// + /// + /// + /// + /// + Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token); + + /// + /// Инфо о файлах + /// + /// + /// + /// + Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token); + + /// + /// пометить метки файлов как удаленные + /// + /// + /// + /// + Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token); + + /// + /// Получение файлов по скважине + /// + /// + /// + /// + Task> GetInfosByWellIdAsync(int idWell, CancellationToken token); + } +} diff --git a/AsbCloudApp/Services/IFileService.cs b/AsbCloudApp/Services/IFileService.cs index 18d0829d..a83d6d5c 100644 --- a/AsbCloudApp/Services/IFileService.cs +++ b/AsbCloudApp/Services/IFileService.cs @@ -31,23 +31,6 @@ namespace AsbCloudApp.Services /// Task SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token = default); - /// - /// Получить список файлов в контейнере - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - Task> GetInfosAsync(int idWell, - int idCategory, string companyName = default, string fileName = default, DateTime begin = default, DateTime end = default, - int skip = 0, int take = 32, CancellationToken token = default); - /// /// Инфо о файле /// @@ -57,24 +40,6 @@ namespace AsbCloudApp.Services Task GetInfoAsync(int idFile, CancellationToken token); - /// - /// Пометить файл как удаленный - /// - /// - /// - /// - Task MarkAsDeletedAsync(int idFile, - CancellationToken token = default); - - /// - /// Получить файлы определенной категории - /// - /// - /// - /// - /// - Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token = default); - /// /// удалить файл /// @@ -103,7 +68,7 @@ namespace AsbCloudApp.Services /// /// /// - string GetUrl(int idFile); + Task GetUrl(int idFile); /// /// получить путь для скачивания @@ -115,15 +80,6 @@ namespace AsbCloudApp.Services /// string GetUrl(int idWell, int idCategory, int idFile, string dotExtention); - /// - /// добавить метку на файл - /// - /// - /// - /// - /// - Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token); - /// /// пометить метку файла как удаленную /// @@ -143,7 +99,57 @@ namespace AsbCloudApp.Services /// /// Task MoveAsync(int idWell, int? idUser, int idCategory, string destinationFileName, string srcFileFullName, CancellationToken token = default); - + + /// + /// Инфо о файле + /// + /// + /// + /// + Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token); + + /// + /// Получить список файлов в контейнере + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + Task> GetInfosAsync(int idWell, + int idCategory, string companyName = default, string fileName = default, DateTime begin = default, + DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default); + + /// + /// Пометить файл как удаленный + /// + /// + /// + /// + Task MarkAsDeletedAsync(int idFile, CancellationToken token = default); + + /// + /// добавить метку на файл + /// + /// + /// + /// + /// + Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token); + + /// + /// Получить запись по id + /// + /// + /// + /// + Task GetOrDefaultAsync(int id, CancellationToken token); + /// /// получить инфо о файле по метке /// @@ -160,14 +166,6 @@ namespace AsbCloudApp.Services /// Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token); - /// - /// Инфо о файле - /// - /// - /// - /// - Task> GetInfoByIdsAsync(List idsFile, CancellationToken token); - /// /// Получение файлов по скважине /// @@ -175,5 +173,14 @@ namespace AsbCloudApp.Services /// /// Task> GetInfosByWellIdAsync(int idWell, CancellationToken token); + + /// + /// Получить файлы определенной категории + /// + /// + /// + /// + /// + Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token); } } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 35f5f3e2..1c69736d 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -158,6 +158,7 @@ namespace AsbCloudInfrastructure dbSet => dbSet .Include(c => c.Wells) .Include(c => c.Deposit))); // может быть включен в сервис ClusterService + services.AddTransient(); // Subsystem service services.AddTransient, CrudCacheServiceBase>(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/Repository/FileRepository.cs b/AsbCloudInfrastructure/Repository/FileRepository.cs new file mode 100644 index 00000000..2726c2b7 --- /dev/null +++ b/AsbCloudInfrastructure/Repository/FileRepository.cs @@ -0,0 +1,305 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Services; +using AsbCloudDb.Model; +using Mapster; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Repository +{ + public class FileRepository : IFileRepository + { + private readonly IQueryable dbSetConfigured; + private readonly IAsbCloudDbContext db; + + public FileRepository(IAsbCloudDbContext db) + { + this.db = db; + this.dbSetConfigured = db.Files + .Include(f => f.Author) + .ThenInclude(u => u.Company) + .ThenInclude(c => c.CompanyType) + .Include(f => f.FileMarks) + .ThenInclude(m => m.User) + .Include(f => f.Well); + } + + public async Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token) + { + var entities = await dbSetConfigured + .Where(e => e.IdWell == idWell && e.IdCategory == idCategory && e.IsDeleted == false) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + + var dtos = entities.Select(e => Convert(e)); + return dtos; + } + + public async Task> GetInfosAsync(int idWell, + int idCategory, string companyName = default, string fileName = default, DateTime begin = default, + DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) + { + var query = dbSetConfigured + .Where(e => e.IdWell == idWell && + e.IdCategory == idCategory && + !e.IsDeleted); + + if (!string.IsNullOrEmpty(companyName)) + query = query.Where(e => (e.Author == null) || + (e.Author.Company == null) || + e.Author.Company.Caption.Contains(companyName)); + + if (!string.IsNullOrEmpty(fileName)) + query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower())); + + var firstFile = await query.FirstOrDefaultAsync(token); + if (firstFile is null) + return new PaginationContainer() + { + Skip = skip, + Take = take, + Count = 0, + }; + + var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; + + if (begin != default) + { + var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); + query = query.Where(e => e.UploadDate >= beginUtc); + } + + if (end != default) + { + var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); + query = query.Where(e => e.UploadDate <= endUtc); + } + + var count = await query.CountAsync(token).ConfigureAwait(false); + + var result = new PaginationContainer(count) + { + Skip = skip, + Take = take, + Count = count, + }; + + if (count <= skip) + 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) + .ConfigureAwait(false); + + var dtos = entities.Select(e => Convert(e, timezoneOffset)); + result.Items.AddRange(dtos); + return result; + } + + public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) + { + var result = new List(); + + var entities = await dbSetConfigured + .AsNoTracking() + .Where(f => idsFile.Contains(f.Id)) + .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)); + } + + return result; + } + + public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) + { + var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false); + + if (fileInfo is null) + return 0; + + fileInfo.IsDeleted = true; + + return await db.SaveChangesAsync(token).ConfigureAwait(false); + } + + public async Task> DeleteAsync(IEnumerable ids, CancellationToken token) + { + var query = dbSetConfigured + .Where(f => ids.Contains(f.Id) && f.IsDeleted); + + var files = await query.ToListAsync(token); + + var filesDtos = files.Select(x => Convert(x)); + + db.Files.RemoveRange(query); + await db.SaveChangesAsync(token).ConfigureAwait(false); + + return filesDtos; + } + + public async Task GetByMarkId(int idMark, CancellationToken token) + { + var entity = await dbSetConfigured + .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) + .ConfigureAwait(false); + + FileInfoDto dto = Convert(entity); + return dto; + } + + public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) + { + var fileMark = await db.FileMarks + .FirstOrDefaultAsync(m => m.IdFile == fileMarkDto.IdFile && + m.IdMarkType == fileMarkDto.IdMarkType && + m.IdUser == idUser && + m.IsDeleted == false, + token) + .ConfigureAwait(false); + + if (fileMark is not null) + return 0; + + var newFileMark = fileMarkDto.Adapt(); + newFileMark.Id = default; + newFileMark.DateCreated = DateTime.UtcNow; + newFileMark.IdUser = idUser; + newFileMark.User = null; + + db.FileMarks.Add(newFileMark); + return await db.SaveChangesAsync(token); + } + + public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) + { + var fileMarkQuery = db.FileMarks + .Where(m => idsMarks.Contains(m.Id)); + + foreach (var fileMark in fileMarkQuery) + fileMark.IsDeleted = true; + + return await db.SaveChangesAsync(token); + } + + public async Task> GetInfosByWellIdAsync(int idWell, CancellationToken token) + { + var entities = await dbSetConfigured + .Where(e => e.IdWell == idWell && e.IsDeleted == false) + .AsNoTracking() + .ToListAsync(token) + .ConfigureAwait(false); + + var dtos = entities.Select(e => Convert(e)); + return dtos; + } + + private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity) + { + var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; + return Convert(entity, timezoneOffset); + } + + private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity, double timezoneOffset) + { + var dto = entity.Adapt(); + dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); + dto.FileMarks = entity.FileMarks.Select(m => + { + var mark = m.Adapt(); + mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset); + return mark; + }); + return dto; + } + + 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) + { + var entity = await dbSetConfigured + .AsNoTracking() + .FirstOrDefaultAsync(f => f.Id == id, token) + .ConfigureAwait(false); + + if (entity is null) + { + throw new FileNotFoundException($"fileId:{id} not found"); + } + + var dto = Convert(entity); + return dto; + } + + 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"); + } + + var dto = Convert(entity); + return dto; + } + + public async Task InsertAsync(FileInfoDto newItem, CancellationToken token) + { + var fileInfo = new AsbCloudDb.Model.FileInfo() + { + IdWell = newItem.IdWell, + IdAuthor = newItem.IdAuthor, + IdCategory = newItem.IdCategory, + Name = newItem.Name, + UploadDate = DateTime.UtcNow, + IsDeleted = false, + Size = newItem.Size, + }; + + var entry = db.Files.Add(fileInfo); + await db.SaveChangesAsync(token).ConfigureAwait(false); + return entry.Entity.Id; + } + + public Task InsertRangeAsync(IEnumerable newItems, CancellationToken token) + { + throw new NotImplementedException(); + } + + public Task UpdateAsync(FileInfoDto item, CancellationToken token) + { + throw new NotImplementedException(); + } + + public Task DeleteAsync(int id, CancellationToken token) + { + throw new NotImplementedException(); + } + } +} diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index 5fbc7301..0e840524 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -2,6 +2,7 @@ using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -479,7 +480,8 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram .UseNpgsql(connectionString) .Options; using var context = new AsbCloudDbContext(contextOptions); - var fileService = new FileService(context); + var fileRepository = new FileRepository(context); + var fileService = new FileService(fileRepository); var files = state.Parts.Select(p => fileService.GetUrl(p.File)); DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath, state.Parts, well); await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token); diff --git a/AsbCloudInfrastructure/Services/FileService.cs b/AsbCloudInfrastructure/Services/FileService.cs index 947fd853..cdfed260 100644 --- a/AsbCloudInfrastructure/Services/FileService.cs +++ b/AsbCloudInfrastructure/Services/FileService.cs @@ -2,6 +2,7 @@ using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using System; @@ -16,21 +17,12 @@ namespace AsbCloudInfrastructure.Services public class FileService : IFileService { public string RootPath { get; private set; } + private readonly IFileRepository fileRepository; - private readonly IQueryable dbSetConfigured; - private readonly IAsbCloudDbContext db; - - public FileService(IAsbCloudDbContext db) + public FileService(IFileRepository fileRepository) { RootPath = "files"; - this.db = db; - dbSetConfigured = db.Files - .Include(f => f.Author) - .ThenInclude(u => u.Company) - .ThenInclude(c => c.CompanyType) - .Include(f => f.FileMarks) - .ThenInclude(m => m.User) - .Include(f => f.Well); + this.fileRepository = fileRepository; } public async Task MoveAsync(int idWell, int? idUser, int idCategory, @@ -44,45 +36,39 @@ namespace AsbCloudInfrastructure.Services var sysFileInfo = new System.IO.FileInfo(srcFilePath); //save info to db - var fileInfo = new AsbCloudDb.Model.FileInfo() - { + var dto = new FileInfoDto { IdWell = idWell, IdAuthor = idUser, IdCategory = idCategory, Name = destinationFileName, - UploadDate = DateTime.UtcNow, - IsDeleted = false, - Size = sysFileInfo.Length, + Size = sysFileInfo.Length }; - - var entry = db.Files.Add(fileInfo); - await db.SaveChangesAsync(token).ConfigureAwait(false); - var fileId = entry.Entity.Id; + var fileId = await fileRepository.InsertAsync(dto, token) + .ConfigureAwait(false); + string filePath = MakeFilePath(idWell, idCategory, destinationFileName, fileId); Directory.CreateDirectory(Path.GetDirectoryName(filePath)); File.Move(srcFilePath, filePath); - return await GetInfoAsync(entry.Entity.Id, token); + return await GetInfoAsync(fileId, token); } public async Task SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token) { //save info to db - var fileInfo = new AsbCloudDb.Model.FileInfo() + var dto = new FileInfoDto { IdWell = idWell, IdAuthor = idUser, IdCategory = idCategory, Name = Path.GetFileName(fileFullName), - UploadDate = DateTime.UtcNow, - IsDeleted = false, Size = fileStream?.Length ?? 0 }; - var entry = db.Files.Add(fileInfo); - await db.SaveChangesAsync(token).ConfigureAwait(false); - var fileId = entry.Entity.Id; + var fileId = await fileRepository.InsertAsync(dto, token) + .ConfigureAwait(false); + //save stream to disk string filePath = MakeFilePath(idWell, idCategory, fileFullName, fileId); @@ -91,7 +77,7 @@ namespace AsbCloudInfrastructure.Services using var newfileStream = new FileStream(filePath, FileMode.Create); await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false); - return await GetInfoAsync(entry.Entity.Id, token); + return await GetInfoAsync(fileId, token); } private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId) @@ -100,137 +86,32 @@ namespace AsbCloudInfrastructure.Services $"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}"); } - public async Task> GetInfosByCategoryAsync(int idWell, - int idCategory, CancellationToken token) - { - var entities = await dbSetConfigured - .Where(e => e.IdWell == idWell && e.IdCategory == idCategory && e.IsDeleted == false) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e)); - return dtos; - } - - public async Task> GetInfosAsync(int idWell, - int idCategory, string companyName = default, string fileName = default, DateTime begin = default, - DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) - { - var query = dbSetConfigured - .Where(e => e.IdWell == idWell && - e.IdCategory == idCategory && - !e.IsDeleted); - - if (!string.IsNullOrEmpty(companyName)) - query = query.Where(e => (e.Author == null) || - (e.Author.Company == null) || - e.Author.Company.Caption.Contains(companyName)); - - if (!string.IsNullOrEmpty(fileName)) - query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower())); - - var firstFile = await query.FirstOrDefaultAsync(token); - if (firstFile is null) - return new PaginationContainer() - { - Skip = skip, - Take = take, - Count = 0, - }; - - var timezoneOffset = firstFile.Well.Timezone?.Hours ?? 5; - - if (begin != default) - { - var beginUtc = begin.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate >= beginUtc); - } - - if (end != default) - { - var endUtc = end.ToUtcDateTimeOffset(timezoneOffset); - query = query.Where(e => e.UploadDate <= endUtc); - } - - var count = await query.CountAsync(token).ConfigureAwait(false); - - var result = new PaginationContainer(count) - { - Skip = skip, - Take = take, - Count = count, - }; - - if (count <= skip) - 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) - .ConfigureAwait(false); - - var dtos = entities.Select(e => Convert(e, timezoneOffset)); - result.Items.AddRange(dtos); - return result; - } - public async Task GetInfoAsync(int idFile, CancellationToken token) { - var entity = await dbSetConfigured - .AsNoTracking() - .FirstOrDefaultAsync(f => f.Id == idFile, token) - .ConfigureAwait(false); + var dto = await fileRepository.GetOrDefaultAsync(idFile, token).ConfigureAwait(false); - if (entity is null) - { - throw new FileNotFoundException($"fileId:{idFile} not found"); - } + var ext = Path.GetExtension(dto.Name); - var ext = Path.GetExtension(entity.Name); - - var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); + var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext); var fullPath = Path.GetFullPath(relativePath); if (!File.Exists(fullPath)) { throw new FileNotFoundException("not found", relativePath); } - var dto = Convert(entity); return dto; } - public async Task MarkAsDeletedAsync(int idFile, - CancellationToken token = default) - { - var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false); - - if (fileInfo is null) - return 0; - - fileInfo.IsDeleted = true; - - return await db.SaveChangesAsync(token).ConfigureAwait(false); - } - public Task DeleteAsync(int idFile, CancellationToken token) - => DeleteAsync(new int[] { idFile }, token); + => DeleteAsync(new int[] { idFile }, token); public async Task DeleteAsync(IEnumerable ids, CancellationToken token) { if (ids is null || !ids.Any()) return 0; - var filesQuery = db.Files - .Where(f => ids.Contains(f.Id)); - - var files = await filesQuery.ToListAsync(token); + var files = await fileRepository.DeleteAsync(ids, token).ConfigureAwait(false); if (files is null || !files.Any()) return 0; @@ -242,18 +123,12 @@ namespace AsbCloudInfrastructure.Services File.Delete(fileName); } - db.Files.RemoveRange(filesQuery); - - return await db.SaveChangesAsync(token).ConfigureAwait(false); + return files.Any() ? 1 : 0; } - public string GetUrl(int idFile) + public async Task GetUrl(int idFile) { - var fileInfo = db.Files - .FirstOrDefault(f => f.Id == idFile); - - if (fileInfo is null) - return null; + var fileInfo = await fileRepository.GetOrDefaultAsync(idFile, CancellationToken.None).ConfigureAwait(false); return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); } @@ -264,116 +139,61 @@ namespace AsbCloudInfrastructure.Services public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); - public async Task GetByMarkId(int idMark, - CancellationToken token) - { - var entity = await dbSetConfigured - .FirstOrDefaultAsync(f => f.FileMarks.Any(m => m.Id == idMark), token) - .ConfigureAwait(false); - - FileInfoDto dto = Convert(entity); - return dto; - } - - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity) - { - var timezoneOffset = entity.Well.Timezone?.Hours ?? 5; - return Convert(entity, timezoneOffset); - } - - private static FileInfoDto Convert(AsbCloudDb.Model.FileInfo entity, double timezoneOffset) - { - var dto = entity.Adapt(); - dto.UploadDate = entity.UploadDate.ToRemoteDateTime(timezoneOffset); - dto.FileMarks = entity.FileMarks.Select(m => - { - var mark = m.Adapt(); - mark.DateCreated = m.DateCreated.ToRemoteDateTime(timezoneOffset); - return mark; - }); - return dto; - } - public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) - { - var fileMark = await db.FileMarks - .FirstOrDefaultAsync(m => m.IdFile == fileMarkDto.IdFile && - m.IdMarkType == fileMarkDto.IdMarkType && - m.IdUser == idUser && - m.IsDeleted == false, - token) - .ConfigureAwait(false); - - if (fileMark is not null) - return 0; - - var newFileMark = fileMarkDto.Adapt(); - newFileMark.Id = default; - newFileMark.DateCreated = DateTime.UtcNow; - newFileMark.IdUser = idUser; - newFileMark.User = null; - - db.FileMarks.Add(newFileMark); - return await db.SaveChangesAsync(token); - } - public Task MarkFileMarkAsDeletedAsync(int idMark, CancellationToken token) - => MarkFileMarkAsDeletedAsync(new int[] { idMark }, token); + => fileRepository.MarkFileMarkAsDeletedAsync(new int[] { idMark }, token); - public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, - CancellationToken token) + public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) { - var fileMarkQuery = db.FileMarks - .Where(m => idsMarks.Contains(m.Id)); + var result = await fileRepository.GetInfoByIdsAsync(idsFile, token).ConfigureAwait(false); - foreach (var fileMark in fileMarkQuery) - fileMark.IsDeleted = true; - - return await db.SaveChangesAsync(token); - } - - public async Task> GetInfoByIdsAsync(List idsFile, CancellationToken token) - { - var result = new List(); - - var entities = await dbSetConfigured - .AsNoTracking() - .Where(f => idsFile.Contains(f.Id)) - .ToListAsync(token) - .ConfigureAwait(false); - - foreach (var entity in entities) + foreach (var entity in result) { - if (entity is null) - { - throw new FileNotFoundException($"fileId:{entity.Id} not found"); - } - + var ext = Path.GetExtension(entity.Name); - var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); var fullPath = Path.GetFullPath(relativePath); if (!File.Exists(fullPath)) { throw new FileNotFoundException("not found", relativePath); } - - result.Add(Convert(entity)); } return result; } - public async Task> GetInfosByWellIdAsync(int idWell, CancellationToken token) - { - var entities = await dbSetConfigured - .Where(e => e.IdWell == idWell && e.IsDeleted == false) - .AsNoTracking() - .ToListAsync(token) + public async Task> GetInfosAsync(int idWell, + int idCategory, string companyName = default, string fileName = default, DateTime begin = default, + DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default) + => await fileRepository.GetInfosAsync(idWell, idCategory, companyName, fileName, begin, end, skip, take, token) .ConfigureAwait(false); - var dtos = entities.Select(e => Convert(e)); - return dtos; - } + public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) + => await fileRepository.MarkAsDeletedAsync(idFile, token) + .ConfigureAwait(false); + + public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) + => await fileRepository.CreateFileMarkAsync(fileMarkDto, idUser, token) + .ConfigureAwait(false); + + public async Task GetOrDefaultAsync(int id, CancellationToken token) + => await fileRepository.GetOrDefaultAsync(id, token) + .ConfigureAwait(false); + + public async Task GetByMarkId(int idMark, CancellationToken token) + => await fileRepository.GetByMarkId(idMark, token) + .ConfigureAwait(false); + + 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(idWell, token) + .ConfigureAwait(false); + + public async Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token) + => await fileRepository.GetInfosByCategoryAsync(idWell, idCategory, token) + .ConfigureAwait(false); } } diff --git a/AsbCloudInfrastructure/Services/ReportService.cs b/AsbCloudInfrastructure/Services/ReportService.cs index 3c70915b..53d8653a 100644 --- a/AsbCloudInfrastructure/Services/ReportService.cs +++ b/AsbCloudInfrastructure/Services/ReportService.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using AsbSaubReport; using Mapster; using Microsoft.EntityFrameworkCore; @@ -65,7 +66,8 @@ namespace AsbCloudInfrastructure.Services }; generator.Make(reportFileName); - var fileService = new FileService(context); + var fileRepository = new FileRepository(context); + var fileService = new FileService(fileRepository); var fileInfo = await fileService.MoveAsync(idWell, idUser, ReportCategoryId, reportFileName, reportFileName, token); progressHandler.Invoke(new diff --git a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs index 3885d0e3..4d5f6427 100644 --- a/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs +++ b/AsbCloudInfrastructure/Services/WellFinalDocumentsService.cs @@ -2,6 +2,7 @@ using AsbCloudApp.Exceptions; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs index 7cea8d32..949c8c46 100644 --- a/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs +++ b/AsbCloudWebApi.Tests/ServicesTests/DrillingProgramServiceTest.cs @@ -1,6 +1,7 @@ using AsbCloudApp.Data; using AsbCloudApp.Services; using AsbCloudDb.Model; +using AsbCloudInfrastructure.Repository; using AsbCloudInfrastructure.Services.DrillingProgram; using Mapster; using Microsoft.Extensions.Configuration; diff --git a/AsbCloudWebApi/Controllers/FileController.cs b/AsbCloudWebApi/Controllers/FileController.cs index 46f9d589..a7711247 100644 --- a/AsbCloudWebApi/Controllers/FileController.cs +++ b/AsbCloudWebApi/Controllers/FileController.cs @@ -4,6 +4,8 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; +using System.Collections; +using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -223,5 +225,33 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } + + /// + /// Возвращает информацию о файле + /// + /// id запрашиваемого файла + /// Токен отмены задачи + /// Запрашиваемый файл + [HttpGet] + [Route("/api/files/{idFile}")] + [Permission] + [ProducesResponseType(typeof(FileInfoDto), (int)System.Net.HttpStatusCode.OK)] + public async Task GetFileInfoAsync([FromRoute] int idFile, CancellationToken token = default) + { + int? idCompany = User.GetCompanyId(); + + if (idCompany is null) + return Forbid(); + + try + { + var fileInfo = await fileService.GetOrDefaultAsync(idFile, token).ConfigureAwait(false); + return Ok(fileInfo); + } + catch (FileNotFoundException ex) + { + return NotFound(ex.FileName); + } + } } }