diff --git a/AsbCloudApp/Requests/MessageRequest.cs b/AsbCloudApp/Requests/MessageRequest.cs new file mode 100644 index 00000000..83906bfc --- /dev/null +++ b/AsbCloudApp/Requests/MessageRequest.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AsbCloudApp.Requests +{ +#nullable enable + /// + /// параметры для запроса списка сообщений + /// + public class MessageRequestBase: RequestBase + { + /// + /// + /// + public IEnumerable? Categoryids { get; set; } + + + /// + /// + /// + public DateTime? Begin { get; set; } + + /// + /// + /// + public DateTime? End { get; set; } + + /// + /// + /// + public string? SearchString { get; set; } + + } + + /// + /// параметры для запроса списка сообщений (с id скважины) + /// + public class MessageRequest: MessageRequestBase { + + /// + /// id скважины + /// + public int IdWell { get; set; } + + /// + /// параметры для запроса списка сообщений (с id скважины) + /// + /// + /// + public MessageRequest(MessageRequestBase request, int idWell) + { + this.IdWell = idWell; + + this.Skip = request.Skip; + this.Take = request.Take; + this.SortFields = request.SortFields; + } + + } +} diff --git a/AsbCloudApp/Services/IMessageService.cs b/AsbCloudApp/Services/IMessageService.cs index 0b2261a4..b3abd842 100644 --- a/AsbCloudApp/Services/IMessageService.cs +++ b/AsbCloudApp/Services/IMessageService.cs @@ -1,5 +1,6 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Threading; @@ -15,20 +16,10 @@ namespace AsbCloudApp.Services /// /// Получить сообщения по параметрам /// - /// - /// - /// - /// - /// - /// - /// + /// /// /// - Task> GetMessagesAsync(int idWell, - IEnumerable categoryids = default, DateTime begin = default, - DateTime end = default, string searchString = default, - int skip = 0, int take = 32, - CancellationToken token = default); + Task> GetMessagesAsync(MessageRequest request, CancellationToken token); /// /// Метод для сохранения сообщения от панели diff --git a/AsbCloudInfrastructure/Services/SAUB/MessageService.cs b/AsbCloudInfrastructure/Services/SAUB/MessageService.cs index 1911029a..583eafaf 100644 --- a/AsbCloudInfrastructure/Services/SAUB/MessageService.cs +++ b/AsbCloudInfrastructure/Services/SAUB/MessageService.cs @@ -1,6 +1,8 @@ using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; +using AsbCloudApp.Requests; using AsbCloudApp.Services; +using AsbCloudDb; using AsbCloudDb.Model; using AsbCloudInfrastructure.EfCache; using Mapster; @@ -24,16 +26,17 @@ namespace AsbCloudInfrastructure.Services.SAUB this.telemetryService = telemetryService; } - public async Task> GetMessagesAsync( - int idWell, - IEnumerable categoryids = default, - DateTime begin = default, - DateTime end = default, - string searchString = default, - int skip = 0, - int take = 32, - CancellationToken token = default) + public async Task> GetMessagesAsync(MessageRequest request, CancellationToken token) { + var idWell = request.IdWell; + var categoryids = request.Categoryids; + var searchString = request.SearchString; + var begin = request.Begin; + var end = request.End; + var skip = request.Skip ?? 0; + var take = request.Take ?? 32; + var sortFields = request.SortFields; + var idTelemetry = telemetryService.GetOrDefaultIdTelemetryByIdWell(idWell); if (idTelemetry is null) return null; @@ -69,13 +72,13 @@ namespace AsbCloudInfrastructure.Services.SAUB if (begin != default) { - var beginUtc = begin.ToUtcDateTimeOffset(timezone.Hours); + var beginUtc = begin.Value.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.DateTime >= beginUtc); } if (end != default) { - var endUtc = end.ToUtcDateTimeOffset(timezone.Hours); + var endUtc = end.Value.ToUtcDateTimeOffset(timezone.Hours); query = query.Where(m => m.DateTime <= endUtc); } @@ -86,10 +89,27 @@ namespace AsbCloudInfrastructure.Services.SAUB Count = query.Count() }; - if (skip > 0) - query = query.Skip(skip); + var hasAllSortedFieldsInDBOType = false; - var messagesList = await query.Take(take).AsNoTracking() + if (sortFields?.Any() == true) + { + hasAllSortedFieldsInDBOType = hasAllFieldsInType(sortFields); + if (hasAllSortedFieldsInDBOType) + { + query = query + .SortBy(request.SortFields) + .Skip(skip) + .Take(take); + } + } + else + { + query = query + .Skip(skip) + .Take(take); + } + + var messagesList = await query.AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (messagesList.Count == 0) @@ -98,6 +118,9 @@ namespace AsbCloudInfrastructure.Services.SAUB var allUsers = await db.TelemetryUsers.FromCacheAsync(token); var users = allUsers.Where(u => u.IdTelemetry == idTelemetry); + var eventsDict = events.GroupBy(x => x.IdEvent).ToDictionary(x => x.Key, x => x.FirstOrDefault()); + var usersDict = users.GroupBy(x => x.IdUser).ToDictionary(x => x.Key, x => x.FirstOrDefault()); + foreach (var message in messagesList) { var messageDto = new MessageDto @@ -110,17 +133,15 @@ namespace AsbCloudInfrastructure.Services.SAUB if (message.IdTelemetryUser is not null) { - if (users.Any()) + if (usersDict.TryGetValue((int)message.IdTelemetryUser, out TelemetryUser user)) { - var user = users.FirstOrDefault(u => u.IdUser == message.IdTelemetryUser); messageDto.User = user.MakeDisplayName(); } else messageDto.User = message.IdTelemetryUser.ToString(); } - var e = events.FirstOrDefault(e => e.IdEvent == message.IdEvent); - if (e != null) + if (eventsDict.TryGetValue(message.IdEvent, out TelemetryEvent e)) { messageDto.CategoryId = e.IdCategory; messageDto.Message = e.MakeMessageText(message); @@ -129,6 +150,14 @@ namespace AsbCloudInfrastructure.Services.SAUB result.Items.Add(messageDto); } + if (sortFields?.Any() == true && !hasAllSortedFieldsInDBOType) + { + result.Items = result.Items.AsQueryable() + .SortBy(request.SortFields) + .Skip(skip) + .Take(take) + .ToList(); + } return result; } @@ -152,5 +181,14 @@ namespace AsbCloudInfrastructure.Services.SAUB return db.SaveChangesAsync(token); } + + private bool hasAllFieldsInType(IEnumerable sortFields) + { + var type = typeof(T); + var properyNames = type.GetProperties().Select(x => x.Name.ToLower()); + sortFields = sortFields.Select(x => x.ToLower().Split(' ')[0]); + var result = sortFields.All(field => properyNames.Contains(field)); + return result; + } } } diff --git a/AsbCloudWebApi/Controllers/SAUB/MessageController.cs b/AsbCloudWebApi/Controllers/SAUB/MessageController.cs index 00f6fd6e..89c40692 100644 --- a/AsbCloudWebApi/Controllers/SAUB/MessageController.cs +++ b/AsbCloudWebApi/Controllers/SAUB/MessageController.cs @@ -1,4 +1,5 @@ using AsbCloudApp.Data; +using AsbCloudApp.Requests; using AsbCloudApp.Services; using Microsoft.AspNetCore.Mvc; using System; @@ -28,29 +29,30 @@ namespace AsbCloudWebApi.Controllers.SAUB /// Выдает список сообщений по скважине /// /// id скважины - /// список категорий - /// дата начала - /// окончание - /// для пагинации кол-во записей пропустить - /// для пагинации кол-во записей - /// Строка поиска + /// Параметры запроса /// Токен для отмены задачи /// список сообщений по скважине [HttpGet] [Permission] [ProducesResponseType(typeof(PaginationContainer), (int)System.Net.HttpStatusCode.OK)] - public async Task GetMessagesAsync(int idWell, int skip = 0, int take = 32, - [FromQuery] IEnumerable categoryids = default, - DateTime begin = default, DateTime end = default, - string searchString = default, - CancellationToken token = default) + public async Task GetMessagesAsync( + [FromRoute] int idWell, + [FromQuery] MessageRequestBase request, + CancellationToken token = default) { - if (take > 1024) + + if (!await UserHasAccesToWellAsync(idWell, token)) + return Forbid(); + + if (request.Take > 1024) return BadRequest("limit mast be less then 1024"); - var result = await messageService.GetMessagesAsync(idWell, - categoryids, begin, end, searchString, - skip, take, token).ConfigureAwait(false); + var requestToService = new MessageRequest(request, idWell); + + var result = await messageService.GetMessagesAsync( + requestToService, + token) + .ConfigureAwait(false); if (result is null || result.Count == 0) return NoContent(); @@ -85,5 +87,15 @@ namespace AsbCloudWebApi.Controllers.SAUB return Ok(wellMessagesDatesRange); } + + protected async Task UserHasAccesToWellAsync(int idWell, CancellationToken token) + { + var idCompany = User.GetCompanyId(); + if (idCompany is not null && + await wellService.IsCompanyInvolvedInWellAsync((int)idCompany, idWell, token) + .ConfigureAwait(false)) + return true; + return false; + } } }