using AsbCloudApp.Data; using AsbCloudApp.Data.SAUB; 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; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.SAUB { public class MessageService : IMessageService { private readonly IAsbCloudDbContext db; private readonly IMemoryCache memoryCache; private readonly ITelemetryService telemetryService; public MessageService(IAsbCloudDbContext db, IMemoryCache memoryCache, ITelemetryService telemetryService) { this.db = db; this.memoryCache = memoryCache; this.telemetryService = telemetryService; } public async Task> GetMessagesAsync(MessageRequest request, CancellationToken token) { var result = new PaginationContainer { Skip = request.Skip ?? 0, Take = request.Take ?? 32, }; var telemetry = telemetryService.GetOrDefaultTelemetryByIdWell(request.IdWell); if (telemetry is null) return result; var allEvents = await memoryCache.GetOrCreateBasicAsync(db.Set(), token); var events = allEvents.Where(e => e.IdTelemetry == telemetry.Id); if (!events.Any()) return result; var query = db.TelemetryMessages.Where(m => m.IdTelemetry == telemetry.Id) .OrderBy(m => m.DateTime).AsNoTracking(); if (request.Categoryids?.Any() == true || !string.IsNullOrEmpty(request.SearchString)) { if (!string.IsNullOrEmpty(request.SearchString)) events = events.Where(e => e.MessageTemplate.Contains(request.SearchString, StringComparison.OrdinalIgnoreCase)); if (request.Categoryids?.Any() == true) events = events.Where(e => request.Categoryids.ToList().Contains(e.IdCategory)); var eventIds = events.Select(e => e.IdEvent); if (!eventIds.Any()) return result; query = query.Where(m => eventIds.Contains(m.IdEvent)); } query = query.OrderByDescending(m => m.DateTime); var timezone = telemetryService.GetTimezone(telemetry.Id); if (request.Begin is not null) { var beginUtc = request.Begin.Value.ToUniversalTime(); query = query.Where(m => m.DateTime >= beginUtc); } if (request.End is not null) { var endUtc = request.End.Value.ToUniversalTime(); query = query.Where(m => m.DateTime <= endUtc); } result.Count = query.Count(); if (request.SortFields?.Any() == true) { query = query.SortBy(request.SortFields); } var messagesList = await query.Skip(result.Skip) .Take(result.Take).AsNoTracking() .ToListAsync(token).ConfigureAwait(false); if (messagesList.Count == 0) return result; var allUsers = await memoryCache.GetOrCreateBasicAsync(db.Set(), token); var users = allUsers.Where(u => u.IdTelemetry == telemetry.Id); var eventsDict = events.ToDictionary(x=>x.IdEvent, x => x); var usersDict = users.ToDictionary(x => x.IdUser, x => x); var messagesDtoList = new List(); foreach (var message in messagesList) { var messageDto = new MessageDto { Id = message.Id, WellDepth = message.WellDepth }; messageDto.DateTime = message.DateTime.ToOffset(TimeSpan.FromHours(timezone.Hours)); if (message.IdTelemetryUser is not null) { if (usersDict.TryGetValue((int)message.IdTelemetryUser, out TelemetryUser? user)) { messageDto.User = user.MakeDisplayName(); } else messageDto.User = message.IdTelemetryUser.ToString(); } if (eventsDict.TryGetValue(message.IdEvent, out TelemetryEvent? e)) { messageDto.CategoryId = e.IdCategory; messageDto.Message = e.MakeMessageText(message); } messagesDtoList.Add(messageDto); } result.Items = result.Items.Concat(messagesDtoList); return result; } public Task InsertAsync(string uid, IEnumerable dtos, CancellationToken token = default) { if (!dtos.Any()) return Task.CompletedTask; var telemetry = telemetryService.GetOrCreateTelemetryByUid(uid); var timezone = telemetryService.GetTimezone(telemetry.Id); foreach (var dto in dtos) { var entity = dto.Adapt(); entity.Id = 0; entity.IdTelemetry = telemetry.Id; entity.DateTime = dto.Date.ToOffset(TimeSpan.FromHours(timezone.Hours)); db.TelemetryMessages.Add(entity); } return db.SaveChangesAsync(token); } } }