diff --git a/AsbCloudApp/AsbCloudApp.csproj b/AsbCloudApp/AsbCloudApp.csproj index 8ca1bbfe..11ffe050 100644 --- a/AsbCloudApp/AsbCloudApp.csproj +++ b/AsbCloudApp/AsbCloudApp.csproj @@ -18,7 +18,4 @@ - - - diff --git a/AsbCloudApp/Data/RequestLogDto.cs b/AsbCloudApp/Data/RequestLogDto.cs index 28b3ff79..eb3231c0 100644 --- a/AsbCloudApp/Data/RequestLogDto.cs +++ b/AsbCloudApp/Data/RequestLogDto.cs @@ -2,6 +2,7 @@ namespace AsbCloudApp.Data { +#nullable enable /// /// DTO журнала запросов /// @@ -10,7 +11,7 @@ namespace AsbCloudApp.Data /// /// логин пользователя /// - public string UserLogin { get; set; } + public string UserLogin { get; set; } = string.Empty; /// /// Id пользователя @@ -20,22 +21,22 @@ namespace AsbCloudApp.Data /// /// IP адрес пользователя /// - public string UserIp { get; set; } + public string? UserIp { get; set; } /// /// метод запроса (GET, POST,..) /// - public string RequestMethod { get; set; } + public string RequestMethod { get; set; } = null!; /// /// url /// - public string RequestPath { get; set; } + public string? RequestPath { get; set; } /// /// Referer /// - public string Referer { get; set; } + public string Referer { get; set; } = string.Empty; /// /// продолжительность выполнения @@ -47,19 +48,20 @@ namespace AsbCloudApp.Data /// public int Status { get; set; } - /// - /// сообщение об ошибке, если она произошла - /// - public string ExceptionMessage { get; set; } - /// /// метка времени запроса /// public DateTime Date { get; set; } + /// + /// сообщение об ошибке, если она произошла + /// + public string? ExceptionMessage { get; set; } = null!; + /// /// стек вызовов /// - public string ExceptionStack { get; set; } + public string? ExceptionStack { get; set; } = null!; } +#nullable disable } \ No newline at end of file diff --git a/AsbCloudApp/Data/RequestLogUserDto.cs b/AsbCloudApp/Data/RequestLogUserDto.cs index 1aed73d0..bd39eaef 100644 --- a/AsbCloudApp/Data/RequestLogUserDto.cs +++ b/AsbCloudApp/Data/RequestLogUserDto.cs @@ -2,6 +2,7 @@ namespace AsbCloudApp.Data { +#nullable enable /// /// DTO статистики запросов по пользователю /// @@ -15,12 +16,12 @@ namespace AsbCloudApp.Data /// /// логин /// - public string Login { get; set; } + public string Login { get; set; } = string.Empty; /// /// IP адрес пользователя /// - public string Ip { get; set; } + public string? Ip { get; set; } /// /// время выполнения запроса @@ -45,6 +46,7 @@ namespace AsbCloudApp.Data /// /// DTO пользователя /// - public UserDto User { get; set; } + public UserDto User { get; set; } = null!; } +#nullable disable } diff --git a/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs b/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs index ee2504e6..37d80116 100644 --- a/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs +++ b/AsbCloudApp/Data/SAUB/TelemetryUserDto.cs @@ -1,6 +1,4 @@ -using AsbCloudDb.Model; - -namespace AsbCloudApp.Data.SAUB +namespace AsbCloudApp.Data.SAUB { /// /// Пользователь панели оператора diff --git a/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs b/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs index 0173170a..3d16d518 100644 --- a/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs +++ b/AsbCloudApp/Data/Subsystems/SubsystemActiveWellStatDto.cs @@ -10,7 +10,7 @@ namespace AsbCloudApp.Data.Subsystems /// /// Активная скважина /// - public WellDto Well { get; set; } = null!; //TODO: заменить на WellInfo + public WellInfoDto Well { get; set; } = null!; /// /// Наработки подсистемы АКБ /// diff --git a/AsbCloudApp/Repositories/IDepositRepository.cs b/AsbCloudApp/Repositories/IDepositRepository.cs new file mode 100644 index 00000000..44c5fe1d --- /dev/null +++ b/AsbCloudApp/Repositories/IDepositRepository.cs @@ -0,0 +1,44 @@ +using AsbCloudApp.Data; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace AsbCloudApp.Repositories +{ +#nullable enable + /// + /// Сервис информации о кустах + /// + public interface IDepositRepository + { + /// + /// список месторождений, доступных для пользователя + /// + /// + /// + /// + Task> GetAsync(int idCompany, + CancellationToken token); + + /// + /// Список месторождений/кустов/скважин у которых заполненны параметры бурения + /// + /// + /// + /// + Task> GetAllWithDrillParamsAsync(int idCompany, + CancellationToken token = default); + + /// + /// Список кустов месторождения доступных компании + /// + /// + /// + /// + /// + Task> GetClustersAsync(int idCompany, + int depositId, CancellationToken token); + + } +#nullable disable +} diff --git a/AsbCloudApp/Requests/RequestBase.cs b/AsbCloudApp/Requests/RequestBase.cs index 67cb6eaa..368dfe4f 100644 --- a/AsbCloudApp/Requests/RequestBase.cs +++ b/AsbCloudApp/Requests/RequestBase.cs @@ -2,6 +2,7 @@ namespace AsbCloudApp.Requests { +#nullable enable /// /// Базовые параметры запроса /// @@ -22,6 +23,7 @@ namespace AsbCloudApp.Requests /// Содержат список названий полей сортировки /// Указать направление сортировки можно через пробел "asc" или "desc" /// - public IEnumerable SortFields { get; set; } + public IEnumerable? SortFields { get; set; } } +#nullable disable } diff --git a/AsbCloudApp/Requests/WellOperationRequest.cs b/AsbCloudApp/Requests/WellOperationRequest.cs new file mode 100644 index 00000000..16c355d1 --- /dev/null +++ b/AsbCloudApp/Requests/WellOperationRequest.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; + +namespace AsbCloudApp.Requests +{ +#nullable enable + /// + /// параметры для запроса списка операций + /// + public class WellOperationRequestBase: RequestBase + { + /// + /// фильтр по дате начала операции + /// + public DateTime? GeDate { get; set; } + + /// + /// фильтр по дате окончания операции + /// + public DateTime? LeDate { get; set; } + + /// + /// фильтр по максимальной глубине скважины + /// + public double? LeDepth { get; set; } + + /// + /// фильтр по минимальной глубине скважины + /// + public double? GeDepth { get; set; } + + /// + /// фильтр по списку id категорий операции + /// + public IEnumerable? OperationCategoryIds { get; set; } + + /// + /// фильтр по план = 0, факт = 1 + /// + public int? OperationType { get; set; } + + /// + /// фильтр по списку id конструкций секции + /// + public IEnumerable? SectionTypeIds { get; set; } + } + + /// + /// Параметры для запроса списка операций (с id скважины) + /// + public class WellOperationRequest: WellOperationRequestBase + { + /// + /// id скважины + /// + public int IdWell { get; set; } + + /// + /// ctor + /// + public WellOperationRequest(){} + + /// + /// копирующий конструктор + /// + /// + /// + public WellOperationRequest(WellOperationRequestBase request, int idWell) + { + this.IdWell = idWell; + + this.GeDepth = request.GeDepth; + this.LeDepth = request.LeDepth; + this.GeDate = request.GeDate; + this.LeDate = request.LeDate; + + this.OperationCategoryIds = request.OperationCategoryIds; + this.OperationType = request.OperationType; + this.SectionTypeIds = request.SectionTypeIds; + + this.Skip= request.Skip; + this.Take= request.Take; + this.SortFields = request.SortFields; + } + } +#nullable disable +} diff --git a/AsbCloudApp/Services/IClusterService.cs b/AsbCloudApp/Services/IClusterService.cs deleted file mode 100644 index 5a77d46d..00000000 --- a/AsbCloudApp/Services/IClusterService.cs +++ /dev/null @@ -1,62 +0,0 @@ -using AsbCloudApp.Data; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudApp.Services -{ - //TODO: remove unused methods - - /// - /// Сервис информации о кустах - /// - public interface IClusterService - { - /// - /// список месторождений - /// - /// - /// - /// - Task> GetDepositsAsync(int idCompany, - CancellationToken token); - - /// - /// Список кустов с заполненными параметрами бурения - /// - /// - /// - /// - Task> GetDepositsDrillParamsAsync(int idCompany, - CancellationToken token = default); - - /// - /// Список кустов месторождения доступных компании - /// - /// - /// - /// - /// - Task> GetClustersAsync(int idCompany, - int depositId, CancellationToken token); - - /// - /// Список кустов доступных компании - /// - /// - /// - /// - Task> GetClustersAsync(int idCompany, - CancellationToken token); - - /// - /// Список скважин доступных компании - /// - /// - /// - /// - /// - Task> GetWellsAsync(int idCompany, - int clusterId, CancellationToken token); - } -} diff --git a/AsbCloudApp/Services/IRequestTracker.cs b/AsbCloudApp/Services/IRequestTracker.cs index 48e09afd..3a4c0fe3 100644 --- a/AsbCloudApp/Services/IRequestTracker.cs +++ b/AsbCloudApp/Services/IRequestTracker.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace AsbCloudApp.Services { - // TODO: make this nullable +#nullable enable /// /// Отслеживание и сбор статистики по запросам @@ -29,34 +29,35 @@ namespace AsbCloudApp.Services /// /// /// - IEnumerable GetAll(int take = -1); + IEnumerable GetAll(int? take); /// /// запросы которые выполнялись быстро /// /// /// - IEnumerable GetFast(int take = -1); + IEnumerable GetFast(int? take); /// /// запросы, которые выполнялись медленно /// /// /// - IEnumerable GetSlow(int take = -1); + IEnumerable GetSlow(int? take); /// /// запросы, которые завершились ошибкой /// /// /// - IEnumerable GetError(int take = -1); + IEnumerable GetError(int? take); /// /// Статистика посещений пользователей /// /// /// - IEnumerable GetUsersStat(int take = -1); + IEnumerable GetUsersStat(int? take); } +#nullable disable } diff --git a/AsbCloudApp/Services/IWellOperationService.cs b/AsbCloudApp/Services/IWellOperationService.cs index ea1aa9b0..61b9b4b0 100644 --- a/AsbCloudApp/Services/IWellOperationService.cs +++ b/AsbCloudApp/Services/IWellOperationService.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Threading; @@ -6,6 +7,7 @@ using System.Threading.Tasks; namespace AsbCloudApp.Services { +#nullable enable /// /// сервис операций по скважине /// @@ -21,54 +23,22 @@ namespace AsbCloudApp.Services /// /// Получить список операций /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// + /// /// /// Task> GetOperationsAsync( - int idWell, - int? operationType = null, - IEnumerable sectionTypeIds = null, - IEnumerable operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - int skip = 0, - int take = 32, - CancellationToken token = default); + WellOperationRequest request, + CancellationToken token); /// /// Получить статистику операции по скважине с группировкой по категориям /// - /// - /// - /// - /// - /// - /// - /// - /// + /// /// /// Task> GetGroupOperationsStatAsync( - int idWell, - int? operationType = null, - IEnumerable sectionTypeIds = null, - IEnumerable operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - CancellationToken token = default); + WellOperationRequest request, + CancellationToken token); /// /// Получить операцию по id @@ -76,29 +46,24 @@ namespace AsbCloudApp.Services /// /// /// - Task GetOrDefaultAsync(int id, CancellationToken token); + Task GetOrDefaultAsync(int id, CancellationToken token); - //todo: idWell Не нужен /// /// Добавить несколько операций за один раз /// - /// /// /// /// - Task InsertRangeAsync(int idWell, + Task InsertRangeAsync( IEnumerable wellOperationDtos, CancellationToken token); - //todo: id Не нужны /// /// Обновить существующую операцию /// - /// - /// /// /// /// - Task UpdateAsync(int idWell, int idOperation, WellOperationDto item, + Task UpdateAsync(WellOperationDto item, CancellationToken token); /// @@ -122,4 +87,5 @@ namespace AsbCloudApp.Services /// DateTimeOffset? FirstOperationDate(int idWell); } +#nullable disable } diff --git a/AsbCloudInfrastructure/DependencyInjection.cs b/AsbCloudInfrastructure/DependencyInjection.cs index 08c6ff4c..d1ab6bfb 100644 --- a/AsbCloudInfrastructure/DependencyInjection.cs +++ b/AsbCloudInfrastructure/DependencyInjection.cs @@ -109,7 +109,7 @@ namespace AsbCloudInfrastructure services.AddSingleton(provider => ReduceSamplingService.GetInstance(configuration)); services.AddTransient(); - services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/AsbCloudInfrastructure/Services/ClusterService.cs b/AsbCloudInfrastructure/Repository/DepositRepository.cs similarity index 65% rename from AsbCloudInfrastructure/Services/ClusterService.cs rename to AsbCloudInfrastructure/Repository/DepositRepository.cs index 93fe292c..e937c271 100644 --- a/AsbCloudInfrastructure/Services/ClusterService.cs +++ b/AsbCloudInfrastructure/Repository/DepositRepository.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudDb.Model; using Mapster; @@ -8,20 +9,22 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace AsbCloudInfrastructure.Services +namespace AsbCloudInfrastructure.Repository { - public class ClusterService : IClusterService +#nullable enable + public class DepositRepository : IDepositRepository { private readonly IAsbCloudDbContext db; private readonly IWellService wellService; - public ClusterService(IAsbCloudDbContext db, IWellService wellService) + public DepositRepository(IAsbCloudDbContext db, IWellService wellService) { this.db = db; this.wellService = wellService; } - public async Task> GetDepositsAsync(int idCompany, + /// + public async Task> GetAsync(int idCompany, CancellationToken token = default) { var wellEntities = await (from well in db.Wells @@ -40,7 +43,8 @@ namespace AsbCloudInfrastructure.Services return dtos; } - public async Task> GetDepositsDrillParamsAsync(int idCompany, + /// + public async Task> GetAllWithDrillParamsAsync(int idCompany, CancellationToken token = default) { var wellEntities = await (from well in db.Wells @@ -59,21 +63,7 @@ namespace AsbCloudInfrastructure.Services return dtos; } - public async Task> GetClustersAsync(int idCompany, - CancellationToken token = default) - { - var entities = await GetWellsForCompany(idCompany) - .Select(e => e.Cluster) - .Distinct() - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Adapt>(); - - return dtos; - } - + /// public async Task> GetClustersAsync(int idCompany, int depositId, CancellationToken token = default) { @@ -90,48 +80,22 @@ namespace AsbCloudInfrastructure.Services return dtos; } - public async Task> GetWellsAsync(int idCompany, - int idCluster, CancellationToken token = default) - { - var entities = await GetWellsForCompany(idCompany) - .Where(e => e.IdCluster == idCluster) - .AsNoTracking() - .ToListAsync(token) - .ConfigureAwait(false); - - var dtos = entities.Select(e => new WellDto - { - Id = e.Id, - Caption = e.Caption, - Latitude = e.Latitude, - Longitude = e.Longitude, - Cluster = e.Cluster.Caption, - Deposit = e.Cluster.Deposit.Caption, - }); - - return dtos; - } - private static IEnumerable>> GroupWells(IEnumerable wellEntities) - { - return wellEntities + => wellEntities .GroupBy(w => w.Cluster) .GroupBy(c => c.Key.Deposit); - } private IQueryable GetWellsForCompany(int idCompany) - { - return db.Wells - .Include(w => w.RelationCompaniesWells) - .ThenInclude(r => r.Company) - .Include(w => w.Cluster) - .ThenInclude(c => c.Deposit) - .Where(w => w.RelationCompaniesWells.Any(c => c.IdCompany == idCompany)); - } + => db.Wells + .Include(w => w.RelationCompaniesWells) + .ThenInclude(r => r.Company) + .Include(w => w.Cluster) + .ThenInclude(c => c.Deposit) + .Where(w => w.RelationCompaniesWells.Any(c => c.IdCompany == idCompany)); private IEnumerable CreateDepositDto(IEnumerable>> gDepositEntities) { - return gDepositEntities.Select(gDeposit => new DepositDto + var dtos = gDepositEntities.Select(gDeposit => new DepositDto { Id = gDeposit.Key.Id, Caption = gDeposit.Key.Caption, @@ -154,6 +118,8 @@ namespace AsbCloudInfrastructure.Services }), }), }); + return dtos; } } +#nullable disable } diff --git a/AsbCloudInfrastructure/Services/RequestTrackerService.cs b/AsbCloudInfrastructure/Services/RequestTrackerService.cs index 454cea5e..1c37304e 100644 --- a/AsbCloudInfrastructure/Services/RequestTrackerService.cs +++ b/AsbCloudInfrastructure/Services/RequestTrackerService.cs @@ -7,6 +7,7 @@ using System.Linq; namespace AsbCloudInfrastructure.Services { +#nullable enable public class RequestTrackerService : IRequerstTrackerService { const int fastRequestsCount = 1000; @@ -16,28 +17,28 @@ namespace AsbCloudInfrastructure.Services const int fastLimitMs = 500; static readonly char[] stackTraceSeparators = "\r\n".ToCharArray(); - private readonly ConcurrentQueue fastRequests = new ConcurrentQueue(); - private readonly ConcurrentQueue slowRequests = new ConcurrentQueue(); - private readonly ConcurrentQueue errorRequests = new ConcurrentQueue(); + private readonly ConcurrentQueue fastRequests = new (); + private readonly ConcurrentQueue slowRequests = new (); + private readonly ConcurrentQueue errorRequests = new (); private readonly ConcurrentDictionary users = new ConcurrentDictionary(); - private static IEnumerable Get(IEnumerable list, int take = -1) + private static IEnumerable Get(IEnumerable list, int? take) { IEnumerable orderedlist = list.OrderByDescending(r => r.Date); if (take > 0) - orderedlist = orderedlist.Take(take); + orderedlist = orderedlist.Take(take.Value); return orderedlist; } - public IEnumerable GetUsersStat(int take = -1) + public IEnumerable GetUsersStat(int? take) { IEnumerable result = users.Values.OrderByDescending(u => u.LastDate); if (take > 0) - result = result.Take(take); + result = result.Take(take.Value); return result; } - public IEnumerable GetAll(int take = -1) + public IEnumerable GetAll(int? take) { var result = fastRequests .Union(slowRequests) @@ -46,13 +47,13 @@ namespace AsbCloudInfrastructure.Services return Get(result, take); } - public IEnumerable GetFast(int take = -1) + public IEnumerable GetFast(int? take) => Get(fastRequests, take); - public IEnumerable GetSlow(int take = -1) + public IEnumerable GetSlow(int? take) => Get(slowRequests, take); - public IEnumerable GetError(int take = -1) + public IEnumerable GetError(int? take) => Get(errorRequests, take); public void RegisterRequest(RequestLogDto requestLog) @@ -103,14 +104,13 @@ namespace AsbCloudInfrastructure.Services { if (!string.IsNullOrEmpty(requestLog.UserLogin)) { - var key = $"{requestLog?.UserId}>{requestLog?.UserIp}"; + var key = $"{requestLog.UserId}>{requestLog.UserIp}"; if (!users.ContainsKey(key)) users[key] = new RequestLogUserDto { UserId = requestLog.UserId, Ip = requestLog.UserIp, Login = requestLog.UserLogin, - //User = userService.Get(requestLog.UserId), }; users[key].ElapsedMs += requestLog.ElapsedMilliseconds; users[key].LastDate = requestLog.Date; @@ -128,4 +128,5 @@ namespace AsbCloudInfrastructure.Services } } } +#nullable disable } diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs new file mode 100644 index 00000000..6251bae9 --- /dev/null +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationRepository.cs @@ -0,0 +1,242 @@ +using AsbCloudApp.Data; +using AsbCloudApp.Requests; +using AsbCloudApp.Services; +using AsbCloudDb; +using AsbCloudDb.Model; +using Mapster; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Threading; +using System.Collections; + +namespace AsbCloudInfrastructure.Services.WellOperationService +{ +#nullable enable + + + /* + var opsQuery = db.WellOperations + .Where( o => o.IdWell == idWell ) + .Where( o => o.IdType == idType ) + .Select( o => new { + o.Id, + o.IdType, + o.IdWell, + o.IdWellSectionType, + o.IdCategory, + + o.Well, + o.WellSectionType, + o.OperationCategory, + + o.DateStart, + o.DepthStart, + o.DepthEnd, + o.DurationHours, + o.CategoryInfo, + o.Comment, + + nptHours = db.WellOperations + .Where(subOp => subOp.IdWell == idWell) + .Where(subOp => subOp.IdType == idType) + .Where(subOp => nptCats.Contains( subOp.IdCategory )) + .Where(subOp => subOp.DateStart <= o.DateStart) + .Select(subOp => subOp.DurationHours) + .Sum(), + Day = o.DateStart - db.WellOperations + .Where(subOp => subOp.IdWell == idWell) + .Where(subOp => subOp.IdType == idType) + .Where(subOp => subOp.DateStart <= o.DateStart) + .Min(subOp => subOp.DateStart), + }) + .OrderBy(o => o.DateStart); + */ + public class WellOperationRepository + { + private readonly IAsbCloudDbContext db; + private readonly IMemoryCache memoryCache; + private readonly IWellService wellService; + private static Dictionary? firstOperationsCache = null; + + public const int idOperationTypePlan = 0; + public const int idOperationTypeFact = 1; + + public WellOperationRepository(IAsbCloudDbContext db, IMemoryCache memoryCache, IWellService wellService) + { + this.db = db; + this.memoryCache = memoryCache; + this.wellService = wellService; + } + + public IDictionary GetSectionTypes() + => memoryCache + .GetOrCreateBasic(db) + .ToDictionary(s => s.Id, s => s.Caption); + + public IEnumerable GetCategories() + { + var allCategories = memoryCache + .GetOrCreateBasic(db); + + var parentIds = allCategories + .Select(o => o.IdParent) + .Distinct(); + + var operationCategories = allCategories + .Where(o => !parentIds.Contains(o.Id)) + .OrderBy(o => o.IdParent) + .ThenBy(o => o.Name); + + var result = operationCategories.Adapt>(); + return result; + } + + public DateTimeOffset? FirstOperationDate(int idWell) + { + if (firstOperationsCache is null) + { + var query = db.WellOperations + .GroupBy(o => o.IdWell) + .Select(g => new Tuple + ( + g.Key, + g.Where(o => o.IdType == idOperationTypePlan).Min(o => o.DateStart), + g.Where(o => o.IdType == idOperationTypeFact).Min(o => o.DateStart) + )); + + firstOperationsCache = query + .ToDictionary(f => f.Item1, f => f.Item3 ?? f.Item2); + } + + return firstOperationsCache?.GetValueOrDefault(idWell); + } + + public async Task GetOrDefaultAsync(int id, + CancellationToken token) + { + var entity = await db.WellOperations + .Include(s => s.WellSectionType) + .Include(s => s.OperationCategory) + .FirstOrDefaultAsync(e => e.Id == id, token) + .ConfigureAwait(false); + + if (entity is null) + return null; + + var timezone = wellService.GetTimezone(entity.IdWell); + + var dto = entity.Adapt(); + dto.WellSectionTypeName = entity.WellSectionType.Caption; + dto.DateStart = entity.DateStart.ToRemoteDateTime(timezone.Hours); + dto.CategoryName = entity.OperationCategory.Name; + return dto; + } + + public Task> GetAsync(WellOperationRequest request, + CancellationToken token) + { + return Task.FromResult(Enumerable.Empty()); + } + + public async Task InsertRangeAsync( + IEnumerable wellOperationDtos, + CancellationToken token) + { + var firstOperation = wellOperationDtos + .FirstOrDefault(); + if (firstOperation is null) + return 0; + + var idWell = firstOperation.IdWell; + + var timezone = wellService.GetTimezone(idWell); + foreach (var dto in wellOperationDtos) + { + var entity = dto.Adapt(); + entity.Id = default; + entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); + entity.IdWell = idWell; + db.WellOperations.Add(entity); + } + + return await db.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + public async Task UpdateAsync( + WellOperationDto dto, CancellationToken token) + { + var timezone = wellService.GetTimezone(dto.IdWell); + var entity = dto.Adapt(); + entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); + db.WellOperations.Update(entity); + return await db.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + public async Task DeleteAsync(IEnumerable ids, + CancellationToken token) + { + var query = db.WellOperations.Where(e => ids.Contains(e.Id)); + db.WellOperations.RemoveRange(query); + return await db.SaveChangesAsync(token) + .ConfigureAwait(false); + } + + private IQueryable BuildQuery(WellOperationRequest request) + { + var timezone = wellService.GetTimezone(request.IdWell); + + var query = db.WellOperations + .Include(s => s.WellSectionType) + .Include(s => s.OperationCategory) + .Where(s => s.IdWell == request.IdWell); + + if (request.OperationType.HasValue) + query = query.Where(e => e.IdType == request.OperationType.Value); + + if (request.SectionTypeIds?.Any() == true) + query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType)); + + if (request.OperationCategoryIds?.Any() == true) + query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory)); + + if (request.GeDepth.HasValue) + query = query.Where(e => e.DepthEnd >= request.GeDepth.Value); + + if (request.LeDepth.HasValue) + query = query.Where(e => e.DepthEnd <= request.LeDepth.Value); + + if (request.GeDate.HasValue) + { + var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart >= geDateOffset); + } + + if (request.LeDate.HasValue) + { + var leDateOffset = request.LeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart <= leDateOffset); + } + + if (request.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + { + query = query + .OrderBy(e => e.DateStart) + .ThenBy(e => e.DepthEnd) + .ThenBy(e => e.Id); + } + + return query; + } + } +#nullable disable +} diff --git a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs index 3c386136..54e559ba 100644 --- a/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs +++ b/AsbCloudInfrastructure/Services/WellOperationService/WellOperationService.cs @@ -1,5 +1,7 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; +using AsbCloudDb; using AsbCloudDb.Model; using Mapster; using Microsoft.EntityFrameworkCore; @@ -75,47 +77,24 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task> GetOperationsAsync( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = null, - IEnumerable? operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - int skip = 0, - int take = 32, - CancellationToken token = default) + WellOperationRequest request, + CancellationToken token) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(request.IdWell); - var query = BuildQuery( - idWell, - operationType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - token); + var query = BuildQuery(request); var result = new PaginationContainer { - Skip = skip, - Take = take, + Skip = request.Skip ?? 0, + Take = request.Take ?? 32, Count = await query.CountAsync(token).ConfigureAwait(false), }; - - query = query - .OrderBy(e => e.DateStart) - .ThenBy(e => e.DepthEnd) - .ThenBy(e => e.Id); - if (skip > 0) - query = query.Skip(skip); + if (result.Skip > 0) + query = query.Skip(result.Skip!); - var entities = await query.Take(take).AsNoTracking() + var entities = await query.Take(result.Take).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (!entities.Any()) @@ -144,26 +123,10 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task> GetGroupOperationsStatAsync( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = default, - IEnumerable? operationCategoryIds = default, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - CancellationToken token = default) + WellOperationRequest request, + CancellationToken token) { - var query = BuildQuery( - idWell, - operationType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - token); + var query = BuildQuery(request); var entities = await query .Select(o => new { o.IdCategory, @@ -172,11 +135,12 @@ namespace AsbCloudInfrastructure.Services.WellOperationService }) .ToListAsync(token); var parentRelationDictionary = GetCategories() - .ToDictionary(c => c.Id, cc => new + .ToDictionary(c => c.Id, c => new { - Name = cc.Name, - IdParent = cc.IdParent + c.Name, + c.IdParent }); + var dtos = entities .GroupBy(o => o.IdCategory) .Select(g => new WellGroupOpertionDto @@ -206,16 +170,14 @@ namespace AsbCloudInfrastructure.Services.WellOperationService TotalMinutes = g.Sum(o => o.TotalMinutes), Items = g.ToList(), IdParent = g.Key.HasValue ? parentRelationDictionary[g.Key.Value].IdParent : defaultId, - }); } return dtos; } public async Task GetOrDefaultAsync(int id, - CancellationToken token = default) + CancellationToken token) { - var entity = await db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) @@ -234,10 +196,17 @@ namespace AsbCloudInfrastructure.Services.WellOperationService return dto; } - public async Task InsertRangeAsync(int idWell, + public async Task InsertRangeAsync( IEnumerable wellOperationDtos, - CancellationToken token = default) + CancellationToken token) { + var firstOperation = wellOperationDtos + .FirstOrDefault(); + if (firstOperation is null) + return 0; + + var idWell = firstOperation.IdWell; + var timezone = wellService.GetTimezone(idWell); foreach (var dto in wellOperationDtos) { @@ -252,12 +221,11 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } - public async Task UpdateAsync(int idWell, int idOperation, - WellOperationDto dto, CancellationToken token = default) + public async Task UpdateAsync( + WellOperationDto dto, CancellationToken token) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(dto.IdWell); var entity = dto.Adapt(); - entity.Id = idOperation; entity.DateStart = dto.DateStart.ToUtcDateTimeOffset(timezone.Hours); db.WellOperations.Update(entity); return await db.SaveChangesAsync(token) @@ -265,7 +233,7 @@ namespace AsbCloudInfrastructure.Services.WellOperationService } public async Task DeleteAsync(IEnumerable ids, - CancellationToken token = default) + CancellationToken token) { var query = db.WellOperations.Where(e => ids.Contains(e.Id)); db.WellOperations.RemoveRange(query); @@ -273,57 +241,55 @@ namespace AsbCloudInfrastructure.Services.WellOperationService .ConfigureAwait(false); } - private IQueryable BuildQuery( - int idWell, - int? operationType = default, - IEnumerable? sectionTypeIds = null, - IEnumerable? operationCategoryIds = null, - DateTime begin = default, - DateTime end = default, - double minDepth = double.MinValue, - double maxDepth = double.MaxValue, - CancellationToken token = default) + private IQueryable BuildQuery(WellOperationRequest request) { - var timezone = wellService.GetTimezone(idWell); + var timezone = wellService.GetTimezone(request.IdWell); var query = db.WellOperations .Include(s => s.WellSectionType) .Include(s => s.OperationCategory) - .Where(s => s.IdWell == idWell); + .Where(s => s.IdWell == request.IdWell); - if (operationType.HasValue) - query = query.Where(e => e.IdType == operationType.Value); + if (request.OperationType.HasValue) + query = query.Where(e => e.IdType == request.OperationType.Value); - if (sectionTypeIds != default && sectionTypeIds.Any()) - query = query.Where(e => sectionTypeIds.Contains(e.IdWellSectionType)); + if (request.SectionTypeIds?.Any() == true) + query = query.Where(e => request.SectionTypeIds.Contains(e.IdWellSectionType)); - if (operationCategoryIds != default && operationCategoryIds.Any()) - query = query.Where(e => operationCategoryIds.Contains(e.IdCategory)); + if (request.OperationCategoryIds?.Any() == true) + query = query.Where(e => request.OperationCategoryIds.Contains(e.IdCategory)); - if (minDepth != double.MinValue) - query = query.Where(e => e.DepthEnd >= minDepth); + if (request.GeDepth.HasValue) + query = query.Where(e => e.DepthEnd >= request.GeDepth.Value); - if (maxDepth != double.MaxValue) - query = query.Where(e => e.DepthEnd <= maxDepth); + if (request.LeDepth.HasValue) + query = query.Where(e => e.DepthEnd <= request.LeDepth.Value); - if (begin != default) + if (request.GeDate.HasValue) { - var beginOffset = begin.ToUtcDateTimeOffset(timezone.Hours); - query = query.Where(e => e.DateStart >= beginOffset); + var geDateOffset = request.GeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart >= geDateOffset); } - if (end != default) + if (request.LeDate.HasValue) { - var endOffset = end.ToUtcDateTimeOffset(timezone.Hours); - query = query.Where(e => e.DateStart <= endOffset); + var leDateOffset = request.LeDate.Value.ToUtcDateTimeOffset(timezone.Hours); + query = query.Where(e => e.DateStart <= leDateOffset); + } + + if (request.SortFields?.Any() == true) + { + query = query.SortBy(request.SortFields); + } + else + { + query = query + .OrderBy(e => e.DateStart) + .ThenBy(e => e.DepthEnd) + .ThenBy(e => e.Id); } - query = query - .OrderBy(e => e.DateStart) - .ThenBy(e => e.DepthEnd) - .ThenBy(e => e.Id); return query; - } } #nullable disable diff --git a/AsbCloudWebApi.Tests/ServicesTests/ClusterServiceTest.cs b/AsbCloudWebApi.Tests/ServicesTests/ClusterServiceTest.cs deleted file mode 100644 index 3c1ff649..00000000 --- a/AsbCloudWebApi.Tests/ServicesTests/ClusterServiceTest.cs +++ /dev/null @@ -1,170 +0,0 @@ -using AsbCloudApp.Services; -using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services; -using Moq; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Xunit; - -namespace AsbCloudWebApi.Tests.ServicesTests; - -public class ClusterServiceTest -{ - private readonly AsbCloudDbContext context; - private readonly Mock wellService; - - private readonly List deposits = new() - { - new Deposit { Id = 1, Caption = "Test deposit 1" }, - new Deposit { Id = 2, Caption = "Test deposit 2" }, - new Deposit { Id = 3, Caption = "Test deposit 3" }, - new Deposit { Id = 4, Caption = "Test deposit 4" } - }; - - private readonly List clusters = new() - { - new Cluster { Id = 1, Caption = "Test cluster 1", IdDeposit = 1, Timezone = new SimpleTimezone()}, - new Cluster { Id = 2, Caption = "Test cluster 2", IdDeposit = 1, Timezone = new SimpleTimezone() }, - new Cluster { Id = 3, Caption = "Test cluster 3", IdDeposit = 2, Timezone = new SimpleTimezone() }, - new Cluster { Id = 4, Caption = "Test cluster 4", IdDeposit = 2, Timezone = new SimpleTimezone() } - }; - - private readonly List wells = new() - { - new Well { Id = 1, Caption = "Test well 1", IdCluster = 1 }, - new Well { Id = 2, Caption = "Test well 2", IdCluster = 2 }, - new Well { Id = 3, Caption = "Test well 3", IdCluster = 1 }, - new Well { Id = 4, Caption = "Test well 4", IdCluster = 2 } - }; - - private readonly List companiesTypes = new() - { - new CompanyType { Id = 1, Caption = "test company type"} - }; - - private readonly List companies = new() - { - new Company { Id = 1, Caption = "Test company 1", IdCompanyType = 1}, - new Company { Id = 2, Caption = "Test company 2", IdCompanyType = 1} - }; - - private readonly List relations = new() - { - new RelationCompanyWell { IdCompany = 1, IdWell = 1 }, - new RelationCompanyWell { IdCompany = 1, IdWell = 2 }, - new RelationCompanyWell { IdCompany = 2, IdWell = 2 } - }; - - private readonly List wellSectionTypes = new() - { - new WellSectionType { Id = 1, Caption = "Test well section type 1" } - }; - - public ClusterServiceTest() - { - context = TestHelpter.MakeRealTestContext(); - wellService = new Mock(); - context.Deposits.RemoveRange(context.Deposits); - context.Clusters.RemoveRange(context.Clusters); - context.Wells.RemoveRange(context.Wells); - context.CompaniesTypes.RemoveRange(context.CompaniesTypes); - context.Companies.RemoveRange(context.Companies); - context.RelationCompaniesWells.RemoveRange(context.RelationCompaniesWells); - context.WellSectionTypes.RemoveRange(context.WellSectionTypes); - if (context.ChangeTracker.HasChanges()) - context.SaveChanges(); - context.Deposits.AddRange(deposits); - context.Clusters.AddRange(clusters); - context.Wells.AddRange(wells); - context.CompaniesTypes.AddRange(companiesTypes); - context.Companies.AddRange(companies); - context.RelationCompaniesWells.AddRange(relations); - context.WellSectionTypes.AddRange(wellSectionTypes); - context.SaveChanges(); - } - - ~ClusterServiceTest() - { - context.Deposits.RemoveRange(context.Deposits); - context.Clusters.RemoveRange(context.Clusters); - context.Wells.RemoveRange(context.Wells); - context.CompaniesTypes.RemoveRange(context.CompaniesTypes); - context.Companies.RemoveRange(context.Companies); - context.RelationCompaniesWells.RemoveRange(context.RelationCompaniesWells); - context.SaveChanges(); - } - - [Fact] - public async Task GetDepositsAsync_returns_one_deposit() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetDepositsAsync(1); - - Assert.Single(dtos); - } - - [Fact] - public async Task GetDepositsAsync_returns_one_deposit_with_two_clusters() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetDepositsAsync(1); - - Assert.Equal(2, dtos.FirstOrDefault()?.Clusters.Count()); - } - [Fact] - public async Task GetDrillParamsAsync_returns_depositDtos() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetDepositsDrillParamsAsync(1); - - Assert.True(dtos.Any()); - } - - [Fact] - public async Task GetDrillParamsAsync_returns_one_deposit() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetDepositsDrillParamsAsync(1); - - Assert.Single(dtos); - } - - [Fact] - public async Task GetDrillParamsAsync_returns_one_deposit_with_two_clusters() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetDepositsDrillParamsAsync(1); - - Assert.Equal(2, dtos.FirstOrDefault()?.Clusters.Count()); - } - - [Fact] - public async Task GetClustersAsync_returns_two_dtos() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetClustersAsync(1); - - Assert.Equal(2, dtos.Count()); - } - - [Fact] - public async Task GetClustersAsync_with_deposit_returns_two_clusters() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetClustersAsync(1, 1); - - Assert.Equal(2, dtos.Count()); - } - - [Fact] - public async Task GetWellsAsync_returns_one_well_by_cluster_and_company() - { - var service = new ClusterService(context, wellService.Object); - var dtos = await service.GetWellsAsync(1, 1); - - Assert.Single(dtos); - } - - -} \ No newline at end of file diff --git a/AsbCloudWebApi/Controllers/ClusterController.cs b/AsbCloudWebApi/Controllers/ClusterController.cs deleted file mode 100644 index 981dd5b6..00000000 --- a/AsbCloudWebApi/Controllers/ClusterController.cs +++ /dev/null @@ -1,67 +0,0 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Services; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; - -namespace AsbCloudWebApi.Controllers -{ - /// - /// Инфо о кустах - /// - [Route("api/cluster")] - [ApiController] - [Authorize] - public class ClusterController : ControllerBase - { - private readonly IClusterService clusterService; - - public ClusterController(IClusterService clusterService) - { - this.clusterService = clusterService; - } - - /// - /// Получает список доступных пользователю кустов - /// - /// Токен отмены задачи - /// - [HttpGet()] - [Permission] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetClustersAsync(CancellationToken token = default) - { - int? idCompany = User.GetCompanyId(); - - if (idCompany is null) - return Forbid(); - - var result = await clusterService.GetClustersAsync((int)idCompany, - token).ConfigureAwait(false); - return Ok(result); - } - - /// - /// Получение доступных пользователю скважин - /// - /// - /// Токен отмены задачи - /// - [HttpGet("{idCluster}")] - [Permission] - [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] - public async Task GetWellsAsync(int idCluster, CancellationToken token = default) - { - int? idCompany = User.GetCompanyId(); - - if (idCompany is null) - return Forbid(); - - var result = await clusterService.GetWellsAsync((int)idCompany, - idCluster, token).ConfigureAwait(false); - return Ok(result); - } - } -} diff --git a/AsbCloudWebApi/Controllers/DepositController.cs b/AsbCloudWebApi/Controllers/DepositController.cs index 9fd4d03f..f1f89506 100644 --- a/AsbCloudWebApi/Controllers/DepositController.cs +++ b/AsbCloudWebApi/Controllers/DepositController.cs @@ -1,5 +1,5 @@ using AsbCloudApp.Data; -using AsbCloudApp.Services; +using AsbCloudApp.Repositories; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; @@ -16,11 +16,11 @@ namespace AsbCloudWebApi.Controllers [Authorize] public class DepositController : ControllerBase { - private readonly IClusterService clusterService; + private readonly IDepositRepository depositService; - public DepositController(IClusterService clusterService) + public DepositController(IDepositRepository depositService) { - this.clusterService = clusterService; + this.depositService = depositService; } /// @@ -38,7 +38,7 @@ namespace AsbCloudWebApi.Controllers if (idCompany is null) return Forbid(); - var result = await clusterService.GetDepositsAsync((int)idCompany, + var result = await depositService.GetAsync((int)idCompany, token).ConfigureAwait(false); return Ok(result); } @@ -58,7 +58,7 @@ namespace AsbCloudWebApi.Controllers if (idCompany is null) return Forbid(); - var result = await clusterService.GetDepositsDrillParamsAsync((int)idCompany, + var result = await depositService.GetAllWithDrillParamsAsync((int)idCompany, token).ConfigureAwait(false); return Ok(result); } @@ -80,7 +80,7 @@ namespace AsbCloudWebApi.Controllers if (idCompany is null) return Forbid(); - var result = await clusterService.GetClustersAsync((int)idCompany, + var result = await depositService.GetClustersAsync((int)idCompany, depositId, token).ConfigureAwait(false); return Ok(result); } diff --git a/AsbCloudWebApi/Controllers/RequestTrackerController.cs b/AsbCloudWebApi/Controllers/RequestTrackerController.cs index 33bfb0c7..a645b257 100644 --- a/AsbCloudWebApi/Controllers/RequestTrackerController.cs +++ b/AsbCloudWebApi/Controllers/RequestTrackerController.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; namespace AsbCloudWebApi.Controllers { +#nullable enable /// /// Мониторинг запросов, ошибок, пользователей /// @@ -87,4 +88,5 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } } +#nullable disable } diff --git a/AsbCloudWebApi/Controllers/WellOperationController.cs b/AsbCloudWebApi/Controllers/WellOperationController.cs index c65ad48a..2fc8a757 100644 --- a/AsbCloudWebApi/Controllers/WellOperationController.cs +++ b/AsbCloudWebApi/Controllers/WellOperationController.cs @@ -1,9 +1,9 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; 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.Threading; @@ -11,6 +11,7 @@ using System.Threading.Tasks; namespace AsbCloudWebApi.Controllers { +#nullable enable /// /// Буровые операции (вводимые вручную) /// @@ -44,7 +45,6 @@ namespace AsbCloudWebApi.Controllers return Ok(result); } - /// /// Возвращает список имен типов операций на скважине /// @@ -63,15 +63,7 @@ namespace AsbCloudWebApi.Controllers /// Отфильтрованный список операций на скважине. Если не применять фильтр, то вернется весь список. Сортированный по глубине затем по дате /// /// id скважины - /// фильтр по план = 0, факт = 1 - /// фильтр по списку id конструкций секции - /// фильтр по списку id категорий операции - /// фильтр по началу операции - /// фильтр по окончанию операции - /// фильтр по минимальной глубине скважины - /// фильтр по максимальной глубине скважины - /// - /// + /// /// /// Список операций на скважине в контейнере для постраничного просмотра [HttpGet] @@ -79,31 +71,15 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] public async Task GetOperationsAsync( [FromRoute] int idWell, - [FromQuery] int? opertaionType = default, - [FromQuery] IEnumerable sectionTypeIds = default, - [FromQuery] IEnumerable operationCategoryIds = default, - [FromQuery] DateTime begin = default, - [FromQuery] DateTime end = default, - [FromQuery] double minDepth = double.MinValue, - [FromQuery] double maxDepth = double.MaxValue, - [FromQuery] int skip = 0, - [FromQuery] int take = 32, - CancellationToken token = default) + [FromQuery] WellOperationRequestBase request, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); + var requestToService = new WellOperationRequest(request, idWell); var result = await operationService.GetOperationsAsync( - idWell, - opertaionType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, - skip, - take, + requestToService, token) .ConfigureAwait(false); return Ok(result); @@ -113,13 +89,7 @@ namespace AsbCloudWebApi.Controllers /// Статистика операций по скважине, группированая по категориям /// /// id скважины - /// - /// - /// - /// - /// - /// - /// + /// /// /// [HttpGet] @@ -128,27 +98,15 @@ namespace AsbCloudWebApi.Controllers [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task GetGroupOperationsAsync( [FromRoute] int idWell, - [FromQuery] int? opertaionType = default, - [FromQuery] IEnumerable sectionTypeIds = default, - [FromQuery] IEnumerable operationCategoryIds = default, - [FromQuery] DateTime begin = default, - [FromQuery] DateTime end = default, - [FromQuery] double minDepth = double.MinValue, - [FromQuery] double maxDepth = double.MaxValue, - CancellationToken token = default) + [FromQuery] WellOperationRequestBase request, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); + var requestToService = new WellOperationRequest(request, idWell); var result = await operationService.GetGroupOperationsStatAsync( - idWell, - opertaionType, - sectionTypeIds, - operationCategoryIds, - begin, - end, - minDepth, - maxDepth, + requestToService, token) .ConfigureAwait(false); return Ok(result); @@ -165,8 +123,8 @@ namespace AsbCloudWebApi.Controllers [Route("{idOperation}")] [Permission] [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] - public async Task GetAsync(int idWell, int idOperation, - CancellationToken token = default) + public async Task GetOrDefaultAsync(int idWell, int idOperation, + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); @@ -186,13 +144,17 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(IEnumerable), (int)System.Net.HttpStatusCode.OK)] public async Task InsertRangeAsync(int idWell, [FromBody] IEnumerable values, - CancellationToken token = default) + CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.InsertRangeAsync(idWell, values, token) + foreach(var value in values) + value.IdWell= idWell; + + var result = await operationService.InsertRangeAsync(values, token) .ConfigureAwait(false); + return Ok(result); } @@ -208,12 +170,15 @@ namespace AsbCloudWebApi.Controllers [Permission] [ProducesResponseType(typeof(WellOperationDto), (int)System.Net.HttpStatusCode.OK)] public async Task UpdateAsync(int idWell, int idOperation, - [FromBody] WellOperationDto value, CancellationToken token = default) + [FromBody] WellOperationDto value, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) return Forbid(); - var result = await operationService.UpdateAsync(idWell, idOperation, value, token) + value.IdWell= idWell; + value.Id = idOperation; + + var result = await operationService.UpdateAsync(value, token) .ConfigureAwait(false); return Ok(result); } @@ -228,7 +193,7 @@ namespace AsbCloudWebApi.Controllers [HttpDelete("{idOperation}")] [Permission] [ProducesResponseType(typeof(int), (int)System.Net.HttpStatusCode.OK)] - public async Task DeleteAsync(int idWell, int idOperation, CancellationToken token = default) + public async Task DeleteAsync(int idWell, int idOperation, CancellationToken token) { if (!await CanUserAccessToWellAsync(idWell, token).ConfigureAwait(false)) @@ -254,8 +219,8 @@ namespace AsbCloudWebApi.Controllers [Route("import/{options}")] public async Task ImportAsync(int idWell, [FromForm] IFormFileCollection files, - int options = 0, - CancellationToken token = default) + int options, + CancellationToken token) { int? idCompany = User.GetCompanyId(); int? idUser = User.GetUserId(); @@ -297,7 +262,7 @@ namespace AsbCloudWebApi.Controllers [Route("export")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task ExportAsync([FromRoute] int idWell, CancellationToken token = default) + public async Task ExportAsync([FromRoute] int idWell, CancellationToken token) { int? idCompany = User.GetCompanyId(); @@ -324,7 +289,7 @@ namespace AsbCloudWebApi.Controllers [Route("scheduleReport")] [Permission] [ProducesResponseType(typeof(PhysicalFileResult), (int)System.Net.HttpStatusCode.OK)] - public async Task ScheduleReportAsync([FromRoute] int idWell, [FromServices] IScheduleReportService scheduleReportService, CancellationToken token = default) + public async Task ScheduleReportAsync([FromRoute] int idWell, [FromServices] IScheduleReportService scheduleReportService, CancellationToken token) { int? idCompany = User.GetCompanyId(); @@ -355,11 +320,12 @@ namespace AsbCloudWebApi.Controllers return File(stream, "application/octet-stream", fileName); } - private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token = default) + private async Task CanUserAccessToWellAsync(int idWell, CancellationToken token) { int? idCompany = User.GetCompanyId(); return idCompany is not null && await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token).ConfigureAwait(false); } } +#nullable disable } diff --git a/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs b/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs index 551b4d03..7b337f46 100644 --- a/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs +++ b/AsbCloudWebApi/Middlewares/RequerstTrackerMiddleware.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; namespace AsbCloudWebApi.Middlewares { +#nullable enable public class RequerstTrackerMiddleware { private readonly RequestDelegate next; @@ -18,8 +19,8 @@ namespace AsbCloudWebApi.Middlewares var service = context.RequestServices.GetRequiredService(); var requestLog = new AsbCloudApp.Data.RequestLogDto { - UserLogin = context.User?.Identity.Name, - UserIp = context.Connection.RemoteIpAddress.ToString(), + UserLogin = context.User.Identity?.Name ?? string.Empty, + UserIp = context.Connection?.RemoteIpAddress?.ToString(), RequestMethod = context.Request.Method, RequestPath = context.Request.Path.Value, Referer = context.Request.Headers["Referer"].ToString(), @@ -32,7 +33,7 @@ namespace AsbCloudWebApi.Middlewares var sw = System.Diagnostics.Stopwatch.StartNew(); try { - await next?.Invoke(context); + await next.Invoke(context); sw.Stop(); requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds; requestLog.Status = context.Response.StatusCode; @@ -43,10 +44,10 @@ namespace AsbCloudWebApi.Middlewares sw.Stop(); requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds; requestLog.Status = context.Response.StatusCode; - // TODO: Add request params and body size. service.RegisterRequestError(requestLog, ex); throw; } } } +#nullable disable }