fix(dal): при формировании групповых шорткодов не хватало include GroupType, изменен ключ кэширования
This commit is contained in:
@@ -67,6 +67,7 @@ namespace PARR.API.Controllers.V1
|
|||||||
|
|
||||||
|
|
||||||
var query = robotConfigurationService.Get()
|
var query = robotConfigurationService.Get()
|
||||||
|
.AsSplitQuery()
|
||||||
.Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode);
|
.Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode);
|
||||||
|
|
||||||
switch (robotCode)
|
switch (robotCode)
|
||||||
@@ -85,6 +86,7 @@ namespace PARR.API.Controllers.V1
|
|||||||
.Include(t => t.Template)
|
.Include(t => t.Template)
|
||||||
.ThenInclude(a => a!.Job)
|
.ThenInclude(a => a!.Job)
|
||||||
.ThenInclude(t => t!.Group)
|
.ThenInclude(t => t!.Group)
|
||||||
|
.ThenInclude(g => g.GroupType)
|
||||||
.Include(t => t.Template)
|
.Include(t => t.Template)
|
||||||
.ThenInclude(w => w!.Job)
|
.ThenInclude(w => w!.Job)
|
||||||
.ThenInclude(t => t!.Tnk)
|
.ThenInclude(t => t!.Tnk)
|
||||||
@@ -93,7 +95,7 @@ namespace PARR.API.Controllers.V1
|
|||||||
|
|
||||||
query = query
|
query = query
|
||||||
.Include(t => t.Template)
|
.Include(t => t.Template)
|
||||||
.ThenInclude(t => t.UnitsInTemplate);
|
.ThenInclude(t => t!.UnitsInTemplate);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -108,6 +110,10 @@ namespace PARR.API.Controllers.V1
|
|||||||
.ThenInclude(t => t!.Unit)
|
.ThenInclude(t => t!.Unit)
|
||||||
.ThenInclude(t => t!.UnitValues)
|
.ThenInclude(t => t!.UnitValues)
|
||||||
.ThenInclude(t => t.Value)
|
.ThenInclude(t => t.Value)
|
||||||
|
.Include(t => t.Template)
|
||||||
|
.ThenInclude(a => a!.Job)
|
||||||
|
.ThenInclude(t => t!.Group)
|
||||||
|
.ThenInclude(g => g.GroupType)
|
||||||
.Include(t => t.Template)
|
.Include(t => t.Template)
|
||||||
.ThenInclude(a => a!.Job)
|
.ThenInclude(a => a!.Job)
|
||||||
.ThenInclude(t => t!.Group)
|
.ThenInclude(t => t!.Group)
|
||||||
@@ -129,6 +135,7 @@ namespace PARR.API.Controllers.V1
|
|||||||
}
|
}
|
||||||
|
|
||||||
// сортируем по NextRun, чтобы те у которых дата след срабатывания ближе к текущей, выполнились скорее
|
// сортируем по NextRun, чтобы те у которых дата след срабатывания ближе к текущей, выполнились скорее
|
||||||
|
//query = query.Where(t => t.Template.Job.GroupId == Guid.Parse("8a75030e-d2dc-4006-a773-002db36ebe27"));
|
||||||
query = query.OrderBy(t => t.Template!.NextRun);
|
query = query.OrderBy(t => t.Template!.NextRun);
|
||||||
|
|
||||||
RobotConfiguration? task = null;
|
RobotConfiguration? task = null;
|
||||||
@@ -203,7 +210,7 @@ namespace PARR.API.Controllers.V1
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.FullDescription))
|
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.FullDescription))
|
||||||
robotTaskTemplateResponse.FullDescription = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.FullDescription , templateForShortcodes);
|
robotTaskTemplateResponse.FullDescription = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.FullDescription, templateForShortcodes);
|
||||||
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.ShortDescription))
|
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.ShortDescription))
|
||||||
robotTaskTemplateResponse.ShortDescription = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.ShortDescription, templateForShortcodes);
|
robotTaskTemplateResponse.ShortDescription = await shortcodesService.ApplyShortcodesAsync(robotTaskTemplateResponse.ShortDescription, templateForShortcodes);
|
||||||
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.Solution))
|
if (shortcodesService.IsAnyShortcodes(robotTaskTemplateResponse.Solution))
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
using PARR.DAL.CacheServices;
|
using PARR.DAL.CacheServices;
|
||||||
using PARR.DAL.DomainServices.Interfaces;
|
using PARR.DAL.DomainServices.Interfaces;
|
||||||
using PARR.DAL.Settings;
|
using PARR.DAL.Settings;
|
||||||
using System.Text.RegularExpressions;
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace PARR.DAL.DomainServices.Implementations
|
namespace PARR.DAL.DomainServices.Implementations
|
||||||
{
|
{
|
||||||
@@ -23,6 +24,7 @@ namespace PARR.DAL.DomainServices.Implementations
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetAggregatedValueAsync(
|
public async Task<string> GetAggregatedValueAsync(
|
||||||
|
Guid jobGroupId,
|
||||||
Guid unitId,
|
Guid unitId,
|
||||||
string shortcode,
|
string shortcode,
|
||||||
Func<Task<string>> computeIfMissing)
|
Func<Task<string>> computeIfMissing)
|
||||||
@@ -30,7 +32,7 @@ namespace PARR.DAL.DomainServices.Implementations
|
|||||||
if (string.IsNullOrEmpty(shortcode))
|
if (string.IsNullOrEmpty(shortcode))
|
||||||
throw new ArgumentException("Ключ шорткода должен быть указан.", nameof(shortcode));
|
throw new ArgumentException("Ключ шорткода должен быть указан.", nameof(shortcode));
|
||||||
|
|
||||||
var cacheKey = GetCacheKey(unitId, shortcode);
|
var cacheKey = GetCacheKey(jobGroupId, unitId, shortcode);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -68,7 +70,7 @@ namespace PARR.DAL.DomainServices.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCacheKey(Guid unitId, string shortcodeKey)
|
private static string GetCacheKey(Guid jobGroupId, Guid unitId, string shortcodeKey)
|
||||||
{
|
{
|
||||||
var safeKey = shortcodeKey
|
var safeKey = shortcodeKey
|
||||||
.Trim()
|
.Trim()
|
||||||
@@ -81,9 +83,13 @@ namespace PARR.DAL.DomainServices.Implementations
|
|||||||
.Replace("/", "_")
|
.Replace("/", "_")
|
||||||
.Replace("\\", "_");
|
.Replace("\\", "_");
|
||||||
|
|
||||||
safeKey = Regex.Replace(safeKey, @"[^a-zA-Z0-9_-]", "_");
|
// ✅ SHA256 от safeKey
|
||||||
|
using var sha256 = SHA256.Create();
|
||||||
|
var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(safeKey));
|
||||||
|
var hashHex = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
|
||||||
|
|
||||||
return $"gr_shcd_{unitId:N}_{safeKey}"; // :N — без дефисов в Guid
|
// ✅ Новый формат ключа
|
||||||
|
return $"gr_shcd_{jobGroupId:N}{unitId:N}_{hashHex}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
public interface IGroupedShortcodesCacheService
|
public interface IGroupedShortcodesCacheService
|
||||||
{
|
{
|
||||||
Task<string> GetAggregatedValueAsync(
|
Task<string> GetAggregatedValueAsync(
|
||||||
|
Guid jobGroupId,
|
||||||
Guid unitId,
|
Guid unitId,
|
||||||
string shortcodeKey,
|
string shortcodeKey,
|
||||||
Func<Task<string>> computeIfMissing);
|
Func<Task<string>> computeIfMissing);
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
var maxShortcodes = Regex.Matches(resultName, maxShortcodePattern);
|
var maxShortcodes = Regex.Matches(resultName, maxShortcodePattern);
|
||||||
if (maxShortcodes.Count > 0)
|
if (maxShortcodes.Count > 0)
|
||||||
{
|
{
|
||||||
resultName = await ReplaceMaxShortcodesAsync(job.Group.Id, template.UnitId, resultName, maxShortcodes); // ✅ Исправлено: job.GroupId
|
var unitIds = template.UnitsInTemplate.Select(uit => uit.UnitId).ToList();
|
||||||
|
resultName = await ReplaceMaxShortcodesAsync(job.Group.Id, template.UnitId, unitIds, resultName, maxShortcodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,13 +161,14 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
{
|
{
|
||||||
var fieldValues = await unitInValueService.Get()
|
var fieldValues = await unitInValueService.Get()
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
|
//.AsSplitQuery()
|
||||||
.Include(uv => uv.Value)
|
.Include(uv => uv.Value)
|
||||||
.Where(uv =>
|
.Where(uv =>
|
||||||
uv.FieldId == groupingFieldId.Value &&
|
uv.FieldId == groupingFieldId.Value &&
|
||||||
unitIds.Contains(uv.UnitId) &&
|
unitIds.Contains(uv.UnitId) &&
|
||||||
uv.Value != null &&
|
uv.Value != null &&
|
||||||
!string.IsNullOrWhiteSpace(uv.Value.Value))
|
!string.IsNullOrWhiteSpace(uv.Value.Value))
|
||||||
.Select(uv => new { uv.UnitId, Value = uv.Value.Value })
|
.Select(uv => new { uv.UnitId, Value = uv.Value!.Value })
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
valuesByUnit = fieldValues
|
valuesByUnit = fieldValues
|
||||||
@@ -221,7 +223,9 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
|
|
||||||
public bool IsAnyShortcodes(string str)
|
public bool IsAnyShortcodes(string str)
|
||||||
{
|
{
|
||||||
return Regex.IsMatch(str, shortcodePattern);
|
return Regex.IsMatch(str, shortcodePattern) ||
|
||||||
|
Regex.IsMatch(str, maxShortcodePattern) ||
|
||||||
|
Regex.IsMatch(str, lettersShortcodePattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Match> GetShortCodes(string resultName)
|
private static List<Match> GetShortCodes(string resultName)
|
||||||
@@ -359,7 +363,7 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
return resultName;
|
return resultName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> ReplaceMaxShortcodesAsync(Guid jobGroupId, Guid unitId, string input, MatchCollection maxShortcodes)
|
private async Task<string> ReplaceMaxShortcodesAsync(Guid jobGroupId, Guid unitId, List<Guid> unitIds, string input, MatchCollection maxShortcodes)
|
||||||
{
|
{
|
||||||
var shortcodeToMatches = maxShortcodes
|
var shortcodeToMatches = maxShortcodes
|
||||||
.Cast<Match>()
|
.Cast<Match>()
|
||||||
@@ -370,18 +374,21 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
{
|
{
|
||||||
var fullShortcode = kvp.Key;
|
var fullShortcode = kvp.Key;
|
||||||
var matches = kvp.Value;
|
var matches = kvp.Value;
|
||||||
var fieldName = fullShortcode.Trim('%').Split(':', 2)[1].Trim(); // "РАБОЧАЯ_ГР_ОТВ_ЗА_ЭК"
|
var fieldName = fullShortcode.Trim('%').Split(':', 2)[1].Trim();
|
||||||
|
|
||||||
logger.LogDebug("Обработка {Shortcode} для JobGroup {JobGroupId}, Template.UnitId {UnitId}",
|
logger.LogDebug("Обработка {Shortcode} для JobGroup {JobGroupId}, Template.UnitId {UnitId}, fieldName {FieldName}",
|
||||||
fullShortcode, jobGroupId, unitId);
|
fullShortcode, jobGroupId, unitId, fieldName);
|
||||||
|
|
||||||
var mostFrequentValue = await groupedShortcodesCacheService.GetAggregatedValueAsync(
|
var mostFrequentValue = await groupedShortcodesCacheService.GetAggregatedValueAsync(
|
||||||
|
jobGroupId,
|
||||||
unitId,
|
unitId,
|
||||||
fullShortcode,
|
fullShortcode,
|
||||||
async () =>
|
async () =>
|
||||||
{
|
{
|
||||||
// Логика вычисления, если кэш пуст
|
logger.LogDebug("Кэш промахнут для {Shortcode}, начинаем вычисление.", fullShortcode);
|
||||||
var unitIds = await jobService.Get()
|
|
||||||
|
// ✅ Пытаемся загрузить UnitsInTemplate из БД
|
||||||
|
var dbUnitIds = await jobService.Get()
|
||||||
.Where(j => j.GroupId == jobGroupId)
|
.Where(j => j.GroupId == jobGroupId)
|
||||||
.Join(
|
.Join(
|
||||||
templateService.Get()
|
templateService.Get()
|
||||||
@@ -396,11 +403,23 @@ namespace PARR.DAL.DomainServices.Shortcodes
|
|||||||
.Distinct()
|
.Distinct()
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
logger.LogDebug("Загружено {Count} unitIds из БД для JobGroup {JobGroupId}", dbUnitIds.Count, jobGroupId);
|
||||||
|
|
||||||
|
// ✅ Если в БД нет UnitsInTemplate — используем переданные unitIds
|
||||||
|
var effectiveUnitIds = dbUnitIds.Any() ? dbUnitIds : unitIds;
|
||||||
|
|
||||||
|
logger.LogDebug("EffectiveUnitIds: [{Ids}], Count: {Count}", string.Join(", ", effectiveUnitIds), effectiveUnitIds.Count);
|
||||||
|
|
||||||
// Вызываем метод из сервиса
|
// Вызываем метод из сервиса
|
||||||
var result = await unitInValueService.GetMostFrequentValueForFieldAsync(unitIds, fieldName);
|
var result = await unitInValueService.GetMostFrequentValueForFieldAsync(effectiveUnitIds, fieldName);
|
||||||
|
|
||||||
|
logger.LogDebug("Результат GetMostFrequentValueForFieldAsync: {Result}, для поля {FieldName}, unitIds: [{Ids}]", result, fieldName, string.Join(", ", effectiveUnitIds));
|
||||||
|
|
||||||
return result ?? string.Empty;
|
return result ?? string.Empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
logger.LogDebug("Итоговое значение для {Shortcode}: {Value}", fullShortcode, mostFrequentValue);
|
||||||
|
|
||||||
foreach (var match in matches)
|
foreach (var match in matches)
|
||||||
{
|
{
|
||||||
input = input.Replace(match.Value, mostFrequentValue);
|
input = input.Replace(match.Value, mostFrequentValue);
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ internal class GroupedTemplateSynchronizer : ITemplateSynchronizer
|
|||||||
// 1. Получить JobGroup и связанные Job'ы
|
// 1. Получить JobGroup и связанные Job'ы
|
||||||
var jobGroup = await jobGroupService.Get()
|
var jobGroup = await jobGroupService.Get()
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
|
.Include(jg => jg.GroupType)
|
||||||
.Include(jg => jg.Jobs)
|
.Include(jg => jg.Jobs)
|
||||||
.ThenInclude(j => j.AutoControl)
|
.ThenInclude(j => j.AutoControl)
|
||||||
.Include(jg => jg.Jobs)
|
.Include(jg => jg.Jobs)
|
||||||
|
|||||||
@@ -1,22 +1,25 @@
|
|||||||
{
|
{
|
||||||
"Serilog": {
|
"ConnectionStrings": {
|
||||||
"MinimumLevel": {
|
"RedisConnection": "10.99.253.216:6379,password=ParrP@ssPtk202MMdevDvs"
|
||||||
"Default": "Debug",
|
},
|
||||||
"Override": {
|
"Serilog": {
|
||||||
"Microsoft": "Debug",
|
"MinimumLevel": {
|
||||||
"Microsoft.Hosting.Lifetime": "Debug"
|
"Default": "Debug",
|
||||||
}
|
"Override": {
|
||||||
|
"Microsoft": "Debug",
|
||||||
|
"Microsoft.Hosting.Lifetime": "Debug"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"WriteTo": [
|
||||||
|
{
|
||||||
|
"Name": "File",
|
||||||
|
"Args": {
|
||||||
|
"path": "log/log-.txt",
|
||||||
|
"rollingInterval": "Day"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"WriteTo": [
|
|
||||||
{
|
|
||||||
"Name": "File",
|
|
||||||
"Args": {
|
|
||||||
"path": "log/log-.txt",
|
|
||||||
"rollingInterval": "Day"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"MqSettings": {
|
"MqSettings": {
|
||||||
"TemplateMatcher": { "HostName": "10.99.253.216" },
|
"TemplateMatcher": { "HostName": "10.99.253.216" },
|
||||||
"TemplateGenerator": { "HostName": "10.99.253.216" },
|
"TemplateGenerator": { "HostName": "10.99.253.216" },
|
||||||
|
|||||||
Reference in New Issue
Block a user