From 33cdc29e8028180c43e8713bb1c359fd855060ff Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 9 Jul 2026 09:02:29 +1000 Subject: [PATCH] =?UTF-8?q?feat(api):=20RobotHistory=20-=20=D1=84=D0=B8?= =?UTF-8?q?=D0=BB=D1=8C=D1=82=D1=80=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D0=B4=D0=B0=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../V1/Requests/Queries/RobotHistoryQuery.cs | 17 ++++++++--- .../Controllers/V1/RobotHistoryController.cs | 30 +++++++++++++++---- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/PARR.API/Contracts/V1/Requests/Queries/RobotHistoryQuery.cs b/PARR.API/Contracts/V1/Requests/Queries/RobotHistoryQuery.cs index d80113fd..36b21b21 100644 --- a/PARR.API/Contracts/V1/Requests/Queries/RobotHistoryQuery.cs +++ b/PARR.API/Contracts/V1/Requests/Queries/RobotHistoryQuery.cs @@ -2,22 +2,31 @@ namespace PARR.API.Contracts.V1.Requests.Queries { - public class RobotHistoryQuery + public record RobotHistoryQuery { /// /// Фильтр по ИД шаблона /// - public Guid? TemplateId { get; set; } + public Guid? TemplateId { get; init; } /// /// Фильтр по ИД робота /// - public RobotsEnum? RobotCode { get; set; } + public RobotsEnum? RobotCode { get; init; } /// /// Фильтр по уровню истории /// - public RobotHistoryLevelEnum? HistoryLevel { get; set; } + public RobotHistoryLevelEnum? HistoryLevel { get; init; } + /// + /// Дата начала + /// + public DateTimeOffset? DateFrom { get; init; } + + /// + /// Дата окончания + /// + public DateTimeOffset? DateTo { get; init; } } } diff --git a/PARR.API/Controllers/V1/RobotHistoryController.cs b/PARR.API/Controllers/V1/RobotHistoryController.cs index e47734e4..ce1a3090 100644 --- a/PARR.API/Controllers/V1/RobotHistoryController.cs +++ b/PARR.API/Controllers/V1/RobotHistoryController.cs @@ -62,6 +62,7 @@ namespace PARR.API.Controllers.V1 var paginationFilter = mapper.Map(paginationQuery); IQueryable query = robotHistoryService.Get() + .AsNoTracking() .Include(t => t.RobotConfiguration) .ThenInclude(t => t!.Template) .Include(t => t.RobotConfiguration) @@ -79,19 +80,38 @@ namespace PARR.API.Controllers.V1 if (request.HistoryLevel.HasValue) query = query.Where(t => t.HistoryLevel == (int)request.HistoryLevel); + if (request.DateFrom.HasValue) + { + var startDateUtc = request.DateFrom.Value.ToUniversalTime(); + query = query.Where(t => t.DateCreated >= startDateUtc); + } + + if (request.DateTo.HasValue) + { + var endDateUtc = request.DateTo.Value.ToUniversalTime(); + query = query.Where(t => t.DateCreated < endDateUtc); + } + var history = await robotHistoryService.GetPage(query, paginationFilter).ToListAsync(); - if (!history.Any()) + if (history.Count == 0) return NoContent(); var robotsIp = history.Where(t => !string.IsNullOrEmpty(t.RobotIp)).Select(t => t.RobotIp).Distinct().ToList(); - var users = await userService.Get().Where(t => robotsIp.Any(x => x == t.Ip)).Distinct().ToListAsync(); + var usersDictionary = await userService.Get() + .AsNoTracking() + .Where(t => robotsIp.Contains(t.Ip)) + .ToDictionaryAsync(t => t.Ip, t => t); var response = mapper.Map>(history); - response.ForEach(item => + foreach (var item in response) { - item.User = mapper.Map(users.FirstOrDefault(t => t.Ip == item.RobotIp)); - }); + if (!string.IsNullOrWhiteSpace(item.RobotIp) && usersDictionary.TryGetValue(item.RobotIp, out var user)) + { + item.User = mapper.Map(user); + } + } + var paginationResponse = new PagedResponse(response, true).GetPaginatedProps(paginationFilter, query); return Ok(paginationResponse);