From 362da02233f6c5eb065c7ad1854668232f73c345 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Tue, 9 Dec 2025 12:20:27 +1000 Subject: [PATCH] =?UTF-8?q?feat(api):=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20?= =?UTF-8?q?=D1=81=D0=B1=D1=80=D0=BE=D1=81=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1?= =?UTF-8?q?=D0=BE=D0=BA=20=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE=D0=BD=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D0=B8=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.API/Contracts/V1/ApiRoutes.cs | 12 ++- .../Controllers/V1/RobotTaskController.cs | 2 +- .../V1/RobotTaskRobotStatusController.cs | 2 +- PARR.API/Controllers/V1/TemplateController.cs | 87 +------------------ .../V1/TemplateSyncStateController.cs | 87 +++++++++++++++++++ .../RobotConfigurationService.cs | 12 +-- .../Interfaces/IRobotConfigurationService.cs | 2 +- 7 files changed, 111 insertions(+), 93 deletions(-) create mode 100644 PARR.API/Controllers/V1/TemplateSyncStateController.cs diff --git a/PARR.API/Contracts/V1/ApiRoutes.cs b/PARR.API/Contracts/V1/ApiRoutes.cs index 419a5000..bb0747a4 100644 --- a/PARR.API/Contracts/V1/ApiRoutes.cs +++ b/PARR.API/Contracts/V1/ApiRoutes.cs @@ -1,4 +1,6 @@ -namespace PARR.API.Contracts.V1 +using RabbitMQ.Client.Exceptions; + +namespace PARR.API.Contracts.V1 { // https://tproger.ru/translations/luchshie-praktiki-razrabotki-rest-api-20-sovetov/ @@ -68,6 +70,7 @@ public const string GetAll = Base + "/templates/"; public const string Get = Base + "/templates/" + getParam; public const string ChangeState = Base + "/templates/" + getParam + "/change-state"; + //public const string SetOkStatus = Base + "/templates/" + getParam + "/status/ok"; //public const string GetByStatusCode = Base + "/templates/status/{statusCode}"; @@ -75,6 +78,13 @@ public const string getParam = "{id}"; } + public static class TemplateSyncState + { + public const string ResetSyncErrors = Base + "/templates/" + getParam + "/reset-sync-errors"; + + public const string getParam = "{id}"; + } + public static class TemplateStatusType { public const string GetAll = Base + "/template-status-types/"; diff --git a/PARR.API/Controllers/V1/RobotTaskController.cs b/PARR.API/Controllers/V1/RobotTaskController.cs index 1533a48c..148e5926 100644 --- a/PARR.API/Controllers/V1/RobotTaskController.cs +++ b/PARR.API/Controllers/V1/RobotTaskController.cs @@ -265,7 +265,7 @@ namespace PARR.API.Controllers.V1 var config = await robotConfigurationService.GetAsync(taskId); //изменение статуса робота - robotConfigurationService.ChangeRobotStatus(RobotStatusEnum.InProgress, ref config!); + robotConfigurationService.ChangeRobotStatus(RobotStatusEnum.InProgress, config!); if (!await robotConfigurationService.CommitAsync()) return false; diff --git a/PARR.API/Controllers/V1/RobotTaskRobotStatusController.cs b/PARR.API/Controllers/V1/RobotTaskRobotStatusController.cs index 7b4a7114..3fbb3ded 100644 --- a/PARR.API/Controllers/V1/RobotTaskRobotStatusController.cs +++ b/PARR.API/Controllers/V1/RobotTaskRobotStatusController.cs @@ -52,7 +52,7 @@ namespace PARR.API.Controllers.V1 return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найдено задание с id: {taskId}" } })); //изменение статуса робота - robotConfigurationService.ChangeRobotStatus(request.RobotStatusCode, ref config); + robotConfigurationService.ChangeRobotStatus(request.RobotStatusCode, config); //если успех, изменяем статус задания на успех if (request.RobotStatusCode == RobotStatusEnum.Complete) diff --git a/PARR.API/Controllers/V1/TemplateController.cs b/PARR.API/Controllers/V1/TemplateController.cs index c0c9faa7..99bd201f 100644 --- a/PARR.API/Controllers/V1/TemplateController.cs +++ b/PARR.API/Controllers/V1/TemplateController.cs @@ -30,18 +30,21 @@ namespace PARR.API.Controllers.V1 private readonly ITemplateService templateService; private readonly IRobotConfigurationService robotConfigurationService; private readonly IClientService clientService; + private readonly ILogger logger; public TemplateController( IMapper mapper, ITemplateService templateService, IRobotConfigurationService robotConfigurationService, - IClientService clientService + IClientService clientService, + ILogger logger ) { this.mapper = mapper; this.templateService = templateService; this.robotConfigurationService = robotConfigurationService; this.clientService = clientService; + this.logger = logger; } @@ -175,87 +178,5 @@ namespace PARR.API.Controllers.V1 return Ok(new Response(response, true)); } - /// - /// Получить один шаблон по заданному статусу - /// - /// - /// - //[HttpGet(ApiRoutes.Template.GetByStatusCode)] - //public async Task GetByStatus([FromRoute] int statusCode, [FromQuery] RobinQuery query) - //{ - // Template? template = null; - - // //1.Ищем `RobotStatusCode` = 22 и `RobotLastStatusUpdated` истекло и `RobotAttemptsNumber` >= допустимого значения из настроек, - // //ставим всем этим записям `RobotStatusCode`= 33 - // //2.Поиск шаблонов со `StatusCode` 10 или 20 и `RobotStatusCode` = 11.Находим, **выбрали эту запись, конец**. - // //3.Поиск шаблонов со `StatusCode` 10 или 20 и `RobotStatusCode` = 22. - // //Далее проверяется `RobotLastStatusUpdated`, что время последнего смены статуса не превышает допустимого(берется из настроек, поле `RobotWaitTime`) - // //и что текущая попытка не больше разрешенной(берется из настроек, поле `RobotAttemptsNumber`) - если это так, берется эта запись. - - // //1. - // await templateService.CheckAndSetErrorRobotStatusAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime); - - - // //2. - // template = await templateService.GetWithIncludes() - // .AsSplitQuery() - // .FirstOrDefaultAsync(t => t.StatusCode == statusCode && t.RobotStatusCode == (int)RobotStatusEnum.Wait); - - // //3. - // if (template == null) - // { - // var endDate = DateTimeOffset.UtcNow.Add(-settingsFromDb.RobotWaitTime); - // template = await templateService.GetWithIncludes() - // .AsSplitQuery() - // .FirstOrDefaultAsync(t => - // t.StatusCode == statusCode - // && t.RobotStatusCode == (int)RobotStatusEnum.InProgress - // && t.RobotAttemptsNumber < settingsFromDb.RobotAttemptsNumber - // && t.RobotLastStatusUpdated < endDate - // ); - // } - - - // if (template == null) - // return NotFound(); - - // var response = mapper.Map(template); - - // if (query.Robin == true) - // { - // var stringResponse = mapper.Map(response); - // return Ok(stringResponse); - // } - - // return Ok(new Response(response, true)); - //} - - - /// - /// Установить статус ОК для шаблона с id - /// - /// - /// - //[HttpPut(ApiRoutes.Template.SetOkStatus)] - //public async Task SetOkStatus([FromRoute] Guid id) - //{ - // var template = await templateService.GetWithIncludes() - // .AsSplitQuery() - // .FirstOrDefaultAsync(t => t.Id == id); - - // if (template == null) - // return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден шаблон с id: {id}" } })); - - // template.StatusCode = (int)TaskStatusEnum.Ok; - - // if (!await templateService.CommitAsync()) - // return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при изменении статуса у шаблона с id: {id}" } })); - - // var response = mapper.Map(template); - - // return Ok(new Response(response, true)); - //} - - } } diff --git a/PARR.API/Controllers/V1/TemplateSyncStateController.cs b/PARR.API/Controllers/V1/TemplateSyncStateController.cs new file mode 100644 index 00000000..46a6dd38 --- /dev/null +++ b/PARR.API/Controllers/V1/TemplateSyncStateController.cs @@ -0,0 +1,87 @@ +using AutoMapper; +using InfluxDB.Client.Api.Domain; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +using PARR.API.Contracts.V1; +using PARR.API.Contracts.V1.Responses; +using PARR.API.Contracts.V1.Responses.Base; +using PARR.API.Controllers.V1.Base; +using PARR.Constants; +using PARR.DAL.Contracts; +using PARR.DAL.Services.Interfaces; + +namespace PARR.API.Controllers.V1 +{ + /// + /// Управление состоянием синхронизации шаблонов + /// + [Authorize(Roles = ParrRoles.Administrator.Role)] + public class TemplateSyncStateController : BaseApiController + { + private readonly IMapper mapper; + private readonly ITemplateService templateService; + private readonly IRobotConfigurationService robotConfigurationService; + private readonly ILogger logger; + + public TemplateSyncStateController( + IMapper mapper, + ITemplateService templateService, + IRobotConfigurationService robotConfigurationService, + ILogger logger + ) + { + this.mapper = mapper; + this.templateService = templateService; + this.robotConfigurationService = robotConfigurationService; + this.logger = logger; + } + + + /// + /// Сбросить ошибки синхронизации шаблона по ИД + /// + /// + /// + [HttpPost(ApiRoutes.TemplateSyncState.ResetSyncErrors)] + public async Task ResetSyncErrors([FromRoute] Guid id) + { + var template = await templateService.Get() + .Include(t => t.RobotConfigurations).ThenInclude(t => t.Robot) + .Include(t => t.RobotConfigurations).ThenInclude(t => t.TaskStatus) + .Include(t => t.RobotConfigurations).ThenInclude(t => t.RobotStatus) + .FirstOrDefaultAsync(t => t.Id == id); + + if (template == null) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Не найден шаблона с id: {id}" } })); + + var isChanged = false; + + // смотрим RobotStatusCode, если есть завершенный с ошибкой, то сбросим ошибку и кол-во попыток + foreach (var config in template.RobotConfigurations) + { + if (config.RobotStatusCode == (int)RobotStatusEnum.Error) + { + robotConfigurationService.ChangeRobotStatus(RobotStatusEnum.Wait, config); + isChanged = true; + logger.LogDebug($"Для шаблона {id} изменен статус ОШИБКА для робота robotCode: {config.RobotCode}, новый статус: {RobotStatusEnum.Wait.ToString()}"); + } + } + + if (!isChanged) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Для данного шаблона нет ошибочных статусов." } })); + + if (!await templateService.CommitAsync()) + { + logger.LogError($"Ошибка при сбросе статуса ошибки синхрнизации для шаблона {id}"); + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при сбросе ошибок синхронизации." } })); + } + + var response = mapper.Map>(template.RobotConfigurations); + + + return Ok(new Response>(response, true)); + } + + } +} diff --git a/PARR.DAL/Services/Implementations/RobotConfigurationService.cs b/PARR.DAL/Services/Implementations/RobotConfigurationService.cs index 6188d32b..c5630245 100644 --- a/PARR.DAL/Services/Implementations/RobotConfigurationService.cs +++ b/PARR.DAL/Services/Implementations/RobotConfigurationService.cs @@ -25,20 +25,20 @@ namespace PARR.DAL.Services.Implementations protected override DataContext EntitiContext => dataContext; - public void ChangeTaskStatus(TaskStatusEnum taskStatus, RobotConfiguration configuration) + public void ChangeTaskStatus(TaskStatusEnum taskStatus, RobotConfiguration configuration) { configuration.TaskStatusCode = (int)taskStatus; switch (taskStatus) { case TaskStatusEnum.Creating: - ChangeRobotStatus(RobotStatusEnum.Wait, ref configuration); + ChangeRobotStatus(RobotStatusEnum.Wait, configuration); break; case TaskStatusEnum.Updating: - ChangeRobotStatus(RobotStatusEnum.Wait, ref configuration); + ChangeRobotStatus(RobotStatusEnum.Wait, configuration); break; case TaskStatusEnum.Ok: - ChangeRobotStatus(RobotStatusEnum.Complete, ref configuration); + ChangeRobotStatus(RobotStatusEnum.Complete, configuration); break; default: break; @@ -46,7 +46,7 @@ namespace PARR.DAL.Services.Implementations } - public void ChangeRobotStatus(RobotStatusEnum robotStatus, ref RobotConfiguration configuration) + public void ChangeRobotStatus(RobotStatusEnum robotStatus, RobotConfiguration configuration) { configuration.RobotStatusCode = (int)robotStatus; @@ -103,7 +103,7 @@ namespace PARR.DAL.Services.Implementations configObjs.ForEach(item => { - ChangeRobotStatus(RobotStatusEnum.Error, ref item); + ChangeRobotStatus(RobotStatusEnum.Error, item); logger.LogInformation($"Устанавливаю RobotStatus: {RobotStatusEnum.Error} для RobotConfigurationId {item.Id}"); }); diff --git a/PARR.DAL/Services/Interfaces/IRobotConfigurationService.cs b/PARR.DAL/Services/Interfaces/IRobotConfigurationService.cs index 627b9138..f4b9045e 100644 --- a/PARR.DAL/Services/Interfaces/IRobotConfigurationService.cs +++ b/PARR.DAL/Services/Interfaces/IRobotConfigurationService.cs @@ -12,7 +12,7 @@ namespace PARR.DAL.Services.Interfaces /// /// /// - void ChangeRobotStatus(RobotStatusEnum robotStatus, ref RobotConfiguration configuration); + void ChangeRobotStatus(RobotStatusEnum robotStatus, RobotConfiguration configuration); /// /// Обновить статус задания (автоматически обновляется статус робота при необходимости)