feat(dal,templateMatcher): уточнена логика UnitFilterService, в TemplateMatcher добавлены методы синхронизации и обновлению существующих шаблонов по группе

This commit is contained in:
Mikhail Kuznetsov
2025-12-30 14:27:59 +10:00
parent 0cb8387349
commit ec53638c58
8 changed files with 427 additions and 148 deletions

View File

@@ -4,6 +4,7 @@ using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using PARR.Common.Domain;
using PARR.Constants;
using PARR.DAL.Contracts;
using PARR.DAL.DomainServices.Interfaces;
using PARR.DAL.Models;
using PARR.DAL.Models.Job;
@@ -14,6 +15,7 @@ using PARR.DAL.Services.Interfaces.Unit;
using PARR.DAL.TransformServices;
using PARR.TemplateMatcher.Services.Interfaces;
using PARR.TemplateMatcher.Settings;
using System.Configuration;
using System.Text.Json;
namespace PARR.TemplateMatcher.Services.Implementations;
@@ -60,7 +62,8 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
IUnitFieldService unitFieldService,
ITemplateDeactivator templateDeactivator,
ITemplateNameNormalizer templateNameNormalizer,
ITemplateUpdaterMqSender templateUpdaterMqSender
ITemplateUpdaterMqSender templateUpdaterMqSender,
SettingsFromDb settingsFromDb
)
{
this.logger = logger;
@@ -155,7 +158,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
}
#if DEBUG
// Отладка: проверить, есть ли юнит в expectedUnitIds
// Отладка: проверить, есть ли юнит в expectedUnitIds
if (expectedUnitIds.Contains(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в expectedUnitIds.", targetUnitId);
@@ -191,7 +194,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
.ToHashSet();
#if DEBUG
// Отладка: проверить, есть ли юнит в unitIdsWithValidGroupingFieldSet
// Отладка: проверить, есть ли юнит в unitIdsWithValidGroupingFieldSet
if (unitIdsWithValidGroupingFieldSet.Contains(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в unitIdsWithValidGroupingFieldSet.", targetUnitId);
@@ -223,7 +226,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
.ToHashSet(); // И снова в HashSet
#if DEBUG
// Отладка: проверить, есть ли юнит в unitIdsWithValidWorkGroupFieldSet
// Отладка: проверить, есть ли юнит в unitIdsWithValidWorkGroupFieldSet
if (unitIdsWithValidWorkGroupFieldSet.Contains(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в unitIdsWithValidWorkGroupFieldSet.", targetUnitId);
@@ -257,7 +260,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
.ToListAsync();
#if DEBUG
// Отладка: проверить, юнит участвует в potentialUnitInUnitLinks
// Отладка: проверить, юнит участвует в potentialUnitInUnitLinks
var potentialLinksContainingTarget = potentialUnitInUnitLinks.Where(l => l.ParentUnitId == targetUnitId || l.ChildUnitId == targetUnitId).ToList();
if (potentialLinksContainingTarget.Any())
{
@@ -334,7 +337,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
}
#if DEBUG
// Отладка: проверить, юнит участвует в filteredUnitInUnitLinks
// Отладка: проверить, юнит участвует в filteredUnitInUnitLinks
var filteredLinksContainingTarget = filteredUnitInUnitLinks.Where(l => l.ParentUnitId == targetUnitId || l.ChildUnitId == targetUnitId).ToList();
if (filteredLinksContainingTarget.Any())
{
@@ -377,7 +380,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
logger.LogDebug("Сформировано {Count} групп по связанным юнитам до разрешения конфликтов.", groupedRelationships.Count);
#if DEBUG
// Отладка: проверить, юнит есть в groupedRelationships.Values
// Отладка: проверить, юнит есть в groupedRelationships.Values
var allUnitsInGroups = groupedRelationships.Values.SelectMany(x => x).ToList();
if (allUnitsInGroups.Contains(targetUnitId))
{
@@ -410,7 +413,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
}
#if DEBUG
// Отладка: проверить, юнит есть в unitToKeys до поиска конфликтов
// Отладка: проверить, юнит есть в unitToKeys до поиска конфликтов
if (unitToKeys.ContainsKey(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в unitToKeys до поиска конфликтов, находится в {Count} группах: [{Groups}]", targetUnitId, unitToKeys[targetUnitId].Count, string.Join(", ", unitToKeys[targetUnitId]));
@@ -425,7 +428,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
var conflictedUnits = unitToKeys.Where(kvp => kvp.Value.Count > 1).ToList();
#if DEBUG
// Отладка: проверить, юнит в conflictedUnits
// Отладка: проверить, юнит в conflictedUnits
var targetConflictedEntry = conflictedUnits.FirstOrDefault(c => c.Key == targetUnitId);
if (targetConflictedEntry.Key != default)
{
@@ -468,7 +471,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
}
#if DEBUG
// Отладка: проверить, юнит есть в groupedRelationships.Values после разрешения конфликтов
// Отладка: проверить, юнит есть в groupedRelationships.Values после разрешения конфликтов
var allUnitsInGroupsAfterConflictResolution = groupedRelationships.Values.SelectMany(x => x).ToList();
if (allUnitsInGroupsAfterConflictResolution.Contains(targetUnitId))
{
@@ -503,7 +506,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
if (childUnitIds.Count == 0)
continue;
#if DEBUG
// Отладка: проверить, есть ли ВРТ-AOS-05-ДВС в childUnitIds
// Отладка: проверить, есть ли ВРТ-AOS-05-ДВС в childUnitIds
var childUnitNames = childUnitIds.Select(id => unitService.Get().AsNoTracking().Where(u => u.Id == id).Select(u => u.Name).FirstOrDefaultAsync().GetAwaiter().GetResult() ?? id.ToString()).ToList();
if (childUnitNames.Contains("ВРТ-AOS-05-ДВС"))
{

View File

@@ -95,11 +95,26 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
if (unitIds == null || !unitIds.Any())
{
logger.LogInformation("Для Job {JobId} фильтры не дали Unit'ов.", jobId);
// Деактивировать все существующие шаблоны для этого Job
var existingTemplatesForDeactivation = await templateService.Get()
.AsNoTracking()
.Include(t => t.UnitsInTemplate)
.Where(t => t.JobId == jobId && t.StatusTypeId == TemplateStatusTypeEnum.Used)
.ToListAsync();
foreach (var unusedTemplate in existingTemplatesForDeactivation)
{
logger.LogInformation("Деактивация лишнего шаблона {TemplateId} (Job {JobId}, UnitId {UnitId}).", unusedTemplate.Id, jobId, unusedTemplate.UnitId);
await templateDeactivator.DeactivateTemplateAsync(unusedTemplate, initiator);
}
logger.LogInformation("Синхронизация шаблонов завершена для Job {JobId}.", jobId);
return;
}
#if DEBUG
// Отладка: проверить, есть ли юнит в unitIds
// Отладка: проверить, есть ли юнит в unitIds
if (unitIds.Contains(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в unitIds.", targetUnitId);
@@ -107,12 +122,10 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
else
{
logger.LogDebug("Юнит {TargetUnitId} НЕ найден в unitIds.", targetUnitId);
return; // ❌ юнит отсеялся на этом этапе
}
#endif
var existingTemplates = await templateService.Get()
.AsNoTracking()
.Include(t => t.UnitsInTemplate)
.Where(t => t.JobId == jobId)
.ToListAsync();
@@ -203,7 +216,7 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
}
#if DEBUG
// Отладка: проверить, есть ли юнит в unitIds
// Отладка: проверить, есть ли юнит в unitIds
if (unitIds.Contains(targetUnitId))
{
logger.LogDebug("Юнит {TargetUnitId} найден в unitIds.", targetUnitId);
@@ -211,7 +224,6 @@ internal class SimpleTemplateSynchronizer : ITemplateSynchronizer
else
{
logger.LogDebug("Юнит {TargetUnitId} НЕ найден в unitIds.", targetUnitId);
return; // ❌ юнит отсеялся на этом этапе
}
#endif

View File

@@ -1,16 +1,13 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using PARR.Common.Domain;
using PARR.Constants;
using PARR.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Models.Job;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.Job;
using PARR.TemplateMatcher.Services.Interfaces;
using PARR.TemplateMatcher.Settings;
using System.Text.Json;
namespace PARR.TemplateMatcher.Services.Implementations;
@@ -24,20 +21,23 @@ internal class TemplateDeactivator : ITemplateDeactivator
private readonly IJobService jobService;
private readonly ITemplateNameNormalizer namenormalizer;
private readonly ITemplateUpdaterMqSender sender;
private readonly Guid unusedJobId = Guid.Parse("8f85a91c-a223-4686-bb69-1f0ee73624f2");
private readonly SettingsFromDb settingsFromDb;
public TemplateDeactivator(
ILogger<TemplateDeactivator> logger,
ITemplateService templateService,
IJobService jobService,
ITemplateNameNormalizer namenormalizer,
ITemplateUpdaterMqSender sender)
ITemplateUpdaterMqSender sender,
SettingsFromDb settingsFromDb
)
{
this.logger = logger;
this.templateService = templateService;
this.jobService = jobService;
this.namenormalizer = namenormalizer;
this.sender = sender;
this.settingsFromDb = settingsFromDb;
}
public async Task<bool> DeactivateTemplateAsync(Template template, HistoryInitiator initiator)
@@ -68,7 +68,7 @@ internal class TemplateDeactivator : ITemplateDeactivator
.Include(j => j.Tnk)
.Include(j => j.Group)
.ThenInclude(g => g!.GroupType)
.FirstOrDefaultAsync(j => j.Id == unusedJobId);
.FirstOrDefaultAsync(j => j.Id == settingsFromDb.JobIdForUnusedTemplates);
if (unusedJob == null)
{
@@ -84,7 +84,7 @@ internal class TemplateDeactivator : ITemplateDeactivator
TemplateId = template.Id,
JobId = unusedJob.Id,
UnitId = template.UnitId,
Name = expectedName,
Name = expectedName + "_" + DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
IsActiveTemplate = DefaultUnusedTemplateState,
IsActiveSchedule = DefaultUnusedScheduleState,
LastRun = template.LastRun,