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

@@ -5,7 +5,6 @@ using PARR.DAL.Contracts;
using PARR.DAL.Models.Job;
using PARR.DAL.Services.Interfaces.Job;
using PARR.TemplateMatcher.Services.Implementations;
using PARR.TemplateMatcher.Services.Implemetaions;
using PARR.TemplateMatcher.Services.Interfaces;
namespace PARR.TemplateMatcher
@@ -14,17 +13,19 @@ namespace PARR.TemplateMatcher
{
private readonly ILogger<TemplateMatcher> logger;
private readonly IJobService jobService;
private readonly IEnumerable<ITemplateSynchronizer> synchronizers; // Получаем все стратегии
private readonly IJobGroupService jobGroupService;
private readonly IEnumerable<ITemplateSynchronizer> synchronizers;
public TemplateMatcher(
ILogger<TemplateMatcher> logger,
IJobService jobService,
IJobGroupService jobGroupService,
IEnumerable<ITemplateSynchronizer> synchronizers
)
{
this.logger = logger;
this.jobService = jobService;
this.jobGroupService = jobGroupService;
this.synchronizers = synchronizers;
}
@@ -57,7 +58,7 @@ namespace PARR.TemplateMatcher
{
logger.LogError("GroupedTemplateSynchronizer не найден.");
}
return; // Завершаем выполнение для группового Job
return;
}
else
{
@@ -72,24 +73,106 @@ namespace PARR.TemplateMatcher
{
logger.LogError("SimpleTemplateSynchronizer не найден.");
}
return; // Завершаем выполнение для обычного Job
return;
}
}
public async Task SyncTemplatesForJobGroup(Guid jobGroupId, HistoryInitiator initiator)
{
logger.LogDebug("Начало синхронизации шаблонов для JobGroup {JobGroupId}", jobGroupId);
var synchronizer = synchronizers.FirstOrDefault(s => s is GroupedTemplateSynchronizer);
if (synchronizer != null)
var jobGroup = await jobGroupService.Get()
.AsNoTracking()
.Include(jg => jg.GroupType)
.FirstOrDefaultAsync(jg => jg.Id == jobGroupId);
if (jobGroup == null || jobGroup.GroupType == null)
{
await synchronizer.SyncTemplatesForJobGroupAsync(jobGroupId, initiator);
logger.LogWarning("JobGroup {JobGroupId} не найден или не содержит GroupType.", jobGroupId);
return;
}
else
// Определяем стратегию по типу группы
switch (jobGroup.GroupType.Code)
{
logger.LogError("GroupedTemplateSynchronizer не найден.");
case JobGroupTypesEnum.Group:
// Проверяем, есть ли GroupingUnitFieldId — это признак "настоящей" группировки
if (jobGroup.GroupingUnitFieldId.HasValue)
{
logger.LogInformation("JobGroup {JobGroupId} является Group с GroupingUnitFieldId. Передаём в GroupedTemplateSynchronizer.", jobGroupId);
var synchronizer = synchronizers.FirstOrDefault(s => s is GroupedTemplateSynchronizer);
if (synchronizer != null)
{
await synchronizer.SyncTemplatesForJobGroupAsync(jobGroupId, initiator);
}
else
{
logger.LogError("GroupedTemplateSynchronizer не найден для JobGroup {JobGroupId}.", jobGroupId);
}
}
else
{
logger.LogInformation("JobGroup {JobGroupId} является Group, но не имеет GroupingUnitFieldId. Обрабатываем как Collection.", jobGroupId);
//await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
}
break;
case JobGroupTypesEnum.Umbrella:
logger.LogInformation("JobGroup {JobGroupId} является Umbrella. Обрабатываем как Collection (каждый Job — независимо).", jobGroupId);
await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
break;
case JobGroupTypesEnum.Simple:
default:
logger.LogInformation("JobGroup {JobGroupId} имеет тип Simple. Обрабатываем как Collection.", jobGroupId);
await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
break;
}
}
public async Task UpdateTemplatesForJobGroup(Guid jobGroupId, HistoryInitiator initiator)
{
logger.LogDebug("Начало обновления шаблонов для JobGroup {JobGroupId}", jobGroupId);
var jobGroup = await jobGroupService.Get()
.AsNoTracking()
.Include(jg => jg.GroupType)
.FirstOrDefaultAsync(jg => jg.Id == jobGroupId);
if (jobGroup == null || jobGroup.GroupType == null)
{
logger.LogWarning("JobGroup {JobGroupId} не найден или не содержит GroupType.", jobGroupId);
return;
}
switch (jobGroup.GroupType.Code)
{
case JobGroupTypesEnum.Group:
if (jobGroup.GroupingUnitFieldId.HasValue)
{
logger.LogWarning("UpdateTemplatesForJobGroup не поддерживается для Group с GroupingUnitFieldId. Id: {JobGroupId}", jobGroupId);
}
else
{
logger.LogInformation("JobGroup {JobGroupId} — Group без GroupingUnitFieldId. Обновляем как Collection.", jobGroupId);
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
}
break;
case JobGroupTypesEnum.Umbrella:
logger.LogInformation("JobGroup {JobGroupId} — Umbrella. Обновляем как Collection.", jobGroupId);
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
break;
case JobGroupTypesEnum.Simple:
default:
logger.LogInformation("JobGroup {JobGroupId} — Simple. Обновляем как Collection.", jobGroupId);
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
break;
}
}
public async Task UpdateTemplatesForJob(Guid jobId, HistoryInitiator initiator)
{
logger.LogDebug("Начало обновления шаблонов для JobId {JobId}", jobId);
@@ -113,14 +196,12 @@ namespace PARR.TemplateMatcher
{
// Вызов UpdateTemplatesForJobAsync для GroupedTemplateSynchronizer (который делает предупреждение)
await synchronizer.UpdateTemplatesForJobAsync(jobId, initiator);
// Или, возможно, имеет смысл вызвать полную синхронизацию для группы:
// await synchronizer.SyncTemplatesForJobGroupAsync(job.GroupId, initiator);
}
else
{
logger.LogError("GroupedTemplateSynchronizer не найден.");
}
return; // Завершаем выполнение
return;
}
else
{
@@ -135,15 +216,77 @@ namespace PARR.TemplateMatcher
{
logger.LogError("SimpleTemplateSynchronizer не найден.");
}
return; // Завершаем выполнение
return;
}
}
// --- Вспомогательные методы ---
private async Task SyncJobGroupAsCollectionAsync(Guid jobGroupId, HistoryInitiator initiator)
{
logger.LogDebug("Синхронизация JobGroup {JobGroupId} как Collection (по каждому Job'у отдельно)", jobGroupId);
var jobIds = await jobService.Get()
.AsNoTracking()
.Where(j => j.GroupId == jobGroupId)
.Select(j => j.Id)
.ToListAsync();
if (!jobIds.Any())
{
logger.LogWarning("JobGroup {JobGroupId} не содержит Job'ов.", jobGroupId);
return;
}
logger.LogDebug("Найдено {Count} Job'ов в JobGroup {JobGroupId}", jobIds.Count, jobGroupId);
var simpleSynchronizer = synchronizers.FirstOrDefault(s => s is SimpleTemplateSynchronizer);
if (simpleSynchronizer == null)
{
logger.LogError("SimpleTemplateSynchronizer не найден для синхронизации Job'ов в JobGroup {JobGroupId}.", jobGroupId);
return;
}
foreach (var jobId in jobIds)
{
logger.LogDebug("Синхронизация Job {JobId} в рамках JobGroup {JobGroupId}", jobId, jobGroupId);
await simpleSynchronizer.SyncTemplatesForJobAsync(jobId, initiator);
}
logger.LogInformation("Синхронизация JobGroup {JobGroupId} как Collection завершена.", jobGroupId);
}
private async Task UpdateJobGroupAsCollectionAsync(Guid jobGroupId, HistoryInitiator initiator)
{
logger.LogDebug("Обновление JobGroup {JobGroupId} как Collection (по каждому Job'у)", jobGroupId);
var jobIds = await jobService.Get()
.AsNoTracking()
.Where(j => j.GroupId == jobGroupId)
.Select(j => j.Id)
.ToListAsync();
if (!jobIds.Any())
{
logger.LogWarning("JobGroup {JobGroupId} не содержит Job'ов.", jobGroupId);
return;
}
foreach (var jobId in jobIds)
{
logger.LogDebug("Обновление шаблонов для Job {JobId} в рамках JobGroup {JobGroupId}", jobId, jobGroupId);
await UpdateTemplatesForJob(jobId, initiator);
}
logger.LogInformation("Обновление JobGroup {JobGroupId} как Collection завершено.", jobGroupId);
}
private async Task<Job?> GetJobWithGroupAndAutoControlAsync(Guid jobId)
{
return await jobService.Get()
.AsNoTracking() // Добавлено
.AsNoTracking()
.Include(j => j.Group)
.ThenInclude(j => j!.GroupType)
.Include(j => j.AutoControl)