diff --git a/PARR.DAL/DomainServices/UnitFilterService/UnitFilterService.cs b/PARR.DAL/DomainServices/UnitFilterService/UnitFilterService.cs index bab9577c..13f59b85 100644 --- a/PARR.DAL/DomainServices/UnitFilterService/UnitFilterService.cs +++ b/PARR.DAL/DomainServices/UnitFilterService/UnitFilterService.cs @@ -316,12 +316,12 @@ internal class UnitFilterService : IUnitFilterService } // Выполняем промежуточный запрос для логирования - var intermediateResult = await query.Select(u => u.Id).ToListAsync(cancellationToken); - logger.LogDebug(" После фильтра #{Index}: осталось {Count} юнитов", filterIndex, intermediateResult.Count); + //var intermediateResult = await query.Select(u => u.Id).ToListAsync(cancellationToken); + //logger.LogDebug(" После фильтра #{Index}: осталось {Count} юнитов", filterIndex, intermediateResult.Count); - // Обновляем query для следующей итерации - query = unitService.Get().AsNoTracking() - .Where(u => intermediateResult.Contains(u.Id)); + //// Обновляем query для следующей итерации + //query = unitService.Get().AsNoTracking() + // .Where(u => intermediateResult.Contains(u.Id)); } var result = await query.Select(u => u.Id).ToListAsync(cancellationToken); diff --git a/PARR.DAL/Services/Implementations/TemplateService.cs b/PARR.DAL/Services/Implementations/TemplateService.cs index 0a54e1ff..cc1b2c9b 100644 --- a/PARR.DAL/Services/Implementations/TemplateService.cs +++ b/PARR.DAL/Services/Implementations/TemplateService.cs @@ -111,24 +111,40 @@ namespace PARR.DAL.Services.Implementations public async Task ReserveUnusedTemplateAsync(Guid newUnitId, HistoryInitiator initiator) { - logger.LogDebug("Резервирую неиспользуемый шаблон для UnitId: {UnitId}", newUnitId); + logger.LogDebug("Резервирую неиспользуемый шаблон с проверкой конфигураций роботов для UnitId: {UnitId}", newUnitId); var sql = @" - UPDATE ""Templates"" - SET ""StatusTypeId"" = @NewStatus, - ""DateModified"" = @DateModified, - ""InitiatorIp"" = @InitiatorIp, - ""InitiatorParrComponentId"" = @InitiatorComponent, - ""InitiatorComment"" = @InitiatorComment - WHERE ""Id"" = ( - SELECT ""Id"" - FROM ""Templates"" - WHERE ""StatusTypeId"" = @OldStatus - AND ""UnitId"" != @NewUnitId - ORDER BY ""DateCreated"" ASC - LIMIT 1 - ) - RETURNING ""Id"";"; + UPDATE ""Templates"" + SET ""StatusTypeId"" = @NewStatus, + ""DateModified"" = @DateModified, + ""InitiatorIp"" = @InitiatorIp, + ""InitiatorParrComponentId"" = @InitiatorComponent, + ""InitiatorComment"" = @InitiatorComment + WHERE ""Id"" = ( + SELECT t.""Id"" + FROM ""Templates"" t + WHERE t.""StatusTypeId"" = @OldStatus + AND t.""UnitId"" != @NewUnitId + AND EXISTS ( + SELECT 1 + FROM ""RobotConfigurations"" rc + WHERE rc.""TemplateId"" = t.""Id"" + AND rc.""RobotCode"" = @RobotCode1 + AND rc.""TaskStatusCode"" = @TaskStatus + AND rc.""RobotStatusCode"" = @RobotStatus + ) + AND EXISTS ( + SELECT 1 + FROM ""RobotConfigurations"" rc + WHERE rc.""TemplateId"" = t.""Id"" + AND rc.""RobotCode"" = @RobotCode2 + AND rc.""TaskStatusCode"" = @TaskStatus + AND rc.""RobotStatusCode"" = @RobotStatus + ) + ORDER BY t.""DateCreated"" ASC + LIMIT 1 + ) + RETURNING ""Id"";"; var parameters = new[] { @@ -141,7 +157,12 @@ namespace PARR.DAL.Services.Implementations : DBNull.Value), new NpgsqlParameter("@InitiatorComment", initiator.InitiatorComment ?? (object)DBNull.Value), new NpgsqlParameter("@OldStatus", (int)TemplateStatusTypeEnum.Unused), - new NpgsqlParameter("@NewUnitId", newUnitId) + new NpgsqlParameter("@NewUnitId", newUnitId), + // Параметры для проверки конфигураций роботов + new NpgsqlParameter("@RobotCode1", 1), + new NpgsqlParameter("@RobotCode2", 2), + new NpgsqlParameter("@TaskStatus", 30), + new NpgsqlParameter("@RobotStatus", 44) }; try @@ -159,7 +180,7 @@ namespace PARR.DAL.Services.Implementations } else { - logger.LogDebug("Не удалось зарезервировать шаблон для UnitId: {UnitId}", newUnitId); + logger.LogDebug("Не удалось зарезервировать шаблон для UnitId: {UnitId} (не найдено подходящих конфигураций роботов)", newUnitId); } return reservedTemplateId; diff --git a/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs b/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs index a58a8397..5d789abb 100644 --- a/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs +++ b/PARR.TemplateMatcher/Services/Implemetaions/SimpleTemplateSynchronizer.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using PARR.BLL.Domain.Mq; using PARR.BLL.Services.Interfaces; using PARR.Common.Domain; @@ -29,9 +30,6 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer private const bool DefaultUsedTemplateState = false; private const bool DefaultUsedScheduleState = false; - // Маска для неиспользуемых шаблонов — хардкод, недоступна из GUI - private const string UnusedTemplateNameMask = "%П-1%_НЕАКТУАЛЬНЫЕ_%ЭК%_%ТИКТАК%"; - private readonly ILogger logger; private readonly IUnitFilterService unitFilterService; private readonly MqSettings mqSettings; @@ -45,6 +43,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer private readonly IMatchingStatusService matchingStatusService; private readonly SettingsFromDb settingsFromDb; private readonly INextRunService nextRunService; + private readonly IOptions templateSettings; public SimpleTemplateSynchronizer( ILogger logger, @@ -65,7 +64,8 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer ITemplateUpdaterMqSender templateUpdaterMqSender, IMatchingStatusService matchingStatusService, SettingsFromDb settingsFromDb, - INextRunService nextRunService + INextRunService nextRunService, + IOptions templateSettings ) { this.logger = logger; @@ -81,6 +81,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer this.matchingStatusService = matchingStatusService; this.settingsFromDb = settingsFromDb; this.nextRunService = nextRunService; + this.templateSettings = templateSettings; } public async Task SyncTemplatesForJobAsync(Guid jobId, HistoryInitiator initiator) @@ -552,7 +553,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer MinValueRelationships = unusedJob.MinValueRelationships, MaxValueRelationships = unusedJob.MaxValueRelationships, IsParentRelationships = unusedJob.IsParentRelationships, - TemplateNameMask = UnusedTemplateNameMask, + TemplateNameMask = templateSettings.Value.UnusedTemplateNameMask, WorkGroupMask = unusedJob.WorkGroupMask, ResponseAreaMask = unusedJob.ResponseAreaMask, TnkId = unusedJob.TnkId, diff --git a/PARR.TemplateMatcher/Services/Implemetaions/TemplateDeactivator.cs b/PARR.TemplateMatcher/Services/Implemetaions/TemplateDeactivator.cs index d6351a62..4a0d0fad 100644 --- a/PARR.TemplateMatcher/Services/Implemetaions/TemplateDeactivator.cs +++ b/PARR.TemplateMatcher/Services/Implemetaions/TemplateDeactivator.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; using PARR.BLL.Domain.Mq; using PARR.Common.Domain; using PARR.Constants; @@ -8,6 +9,7 @@ using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; using PARR.DAL.Services.Interfaces.Job; using PARR.TemplateMatcher.Services.Interfaces; +using PARR.TemplateMatcher.Settings; namespace PARR.TemplateMatcher.Services.Implementations; @@ -22,6 +24,7 @@ internal class TemplateDeactivator : ITemplateDeactivator private readonly ITemplateNameNormalizer namenormalizer; private readonly ITemplateUpdaterMqSender sender; private readonly SettingsFromDb settingsFromDb; + private readonly IOptions templateSettings; public TemplateDeactivator( ILogger logger, @@ -29,7 +32,8 @@ internal class TemplateDeactivator : ITemplateDeactivator IJobService jobService, ITemplateNameNormalizer namenormalizer, ITemplateUpdaterMqSender sender, - SettingsFromDb settingsFromDb + SettingsFromDb settingsFromDb, + IOptions templateSettings ) { this.logger = logger; @@ -38,6 +42,7 @@ internal class TemplateDeactivator : ITemplateDeactivator this.namenormalizer = namenormalizer; this.sender = sender; this.settingsFromDb = settingsFromDb; + this.templateSettings = templateSettings; } public async Task DeactivateTemplateAsync(Template template, HistoryInitiator initiator) @@ -70,12 +75,15 @@ internal class TemplateDeactivator : ITemplateDeactivator .ThenInclude(g => g!.GroupType) .FirstOrDefaultAsync(j => j.Id == settingsFromDb.JobIdForUnusedTemplates); + if (unusedJob == null) { logger.LogError("Job для деактивированных шаблонов не найден."); return false; } + unusedJob.TemplateNameMask = templateSettings.Value.UnusedTemplateNameMask; + // === Создаём временный Template для нормализации имени === var tempTemplateForName = new Template { @@ -96,7 +104,7 @@ internal class TemplateDeactivator : ITemplateDeactivator TemplateId = template.Id, JobId = unusedJob.Id, UnitId = template.UnitId, - Name = expectedName + "_" + DateTimeOffset.UtcNow.ToUnixTimeSeconds(), + Name = expectedName, IsActiveTemplate = DefaultUnusedTemplateState, IsActiveSchedule = DefaultUnusedScheduleState, LastRun = template.LastRun, diff --git a/PARR.TemplateMatcher/Settings/TemplateSettings.cs b/PARR.TemplateMatcher/Settings/TemplateSettings.cs new file mode 100644 index 00000000..154b1c7a --- /dev/null +++ b/PARR.TemplateMatcher/Settings/TemplateSettings.cs @@ -0,0 +1,7 @@ +namespace PARR.TemplateMatcher.Settings +{ + internal class TemplateSettings + { + public string UnusedTemplateNameMask { get; set; } = "%П-1%_НЕАКТУАЛЬНЫЕ_%ЭК%_%ТИКТАК%"; + } +} diff --git a/PARR.TemplateMatcher/TemplateMatcherInstaller.cs b/PARR.TemplateMatcher/TemplateMatcherInstaller.cs index 9a8aa55f..741844cd 100644 --- a/PARR.TemplateMatcher/TemplateMatcherInstaller.cs +++ b/PARR.TemplateMatcher/TemplateMatcherInstaller.cs @@ -20,6 +20,10 @@ namespace PARR.TemplateMatcher configuration.GetSection(nameof(MqSettings)).Bind(mqSettings); services.AddSingleton(mqSettings); + var templateSettings = new TemplateSettings(); + configuration.GetSection(nameof(TemplateSettings)).Bind(templateSettings); + services.AddSingleton(templateSettings); + services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/PARR.TemplateMatcherWorker/appsettings.json b/PARR.TemplateMatcherWorker/appsettings.json index 25ea572d..5132345f 100644 --- a/PARR.TemplateMatcherWorker/appsettings.json +++ b/PARR.TemplateMatcherWorker/appsettings.json @@ -44,5 +44,8 @@ }, "GroupedShortcodeCacheSettings": { "ValueTtl": "00:20:00" + }, + "TemplateSettings": { + "UnusedTemplateNameMask": "%П-1%_НЕАКТУАЛЬНЫЕ_%ЭК%_%ТИКТАК%" } }