diff --git a/PARR.DAL/DomainServices/Implementations/ShortcodesService.cs b/PARR.DAL/DomainServices/Implementations/ShortcodesService.cs index 27b5dd23..99b33c1c 100644 --- a/PARR.DAL/DomainServices/Implementations/ShortcodesService.cs +++ b/PARR.DAL/DomainServices/Implementations/ShortcodesService.cs @@ -218,23 +218,36 @@ namespace PARR.DAL.DomainServices.Implementations private async Task ReplaceFieldValues(Guid unitId, string resultName, List shortcodesInMask) { - // 1. Извлекаем имена полей из шорткодов: %IP_АДРЕС% → "IP_АДРЕС" + // 1. Извлекаем имена полей из шорткодов var requiredFieldNames = shortcodesInMask - .Select(m => m.Value.Trim('%').ToUpper()) + .Select(m => m.Value.Trim('%').ToUpperInvariant()) .ToList(); if (requiredFieldNames.Count == 0) return resultName; - // 2. Получаем только нужные значения - var fieldValueMap = await unitInValueService.GetFieldValuesAsync(unitId, requiredFieldNames); + // 2. Получаем значения (может быть дубль) + var fieldValues = await unitInValueService.GetFieldValuesAsync(unitId, requiredFieldNames); - // 3. Подставляем значения + // 3. Группируем по FieldName → список значений + var fieldValuesMap = fieldValues + .GroupBy(x => x.FieldName, StringComparer.OrdinalIgnoreCase) + .ToDictionary( + g => g.Key, + g => g.Select(x => x.Value).ToList(), // список значений (может быть null) + StringComparer.OrdinalIgnoreCase); + + // 4. Объединяем значения через запятую (null → "null") и подставляем foreach (var match in shortcodesInMask) { - var fieldName = match.Value.Trim('%').ToUpper(); - if (fieldValueMap.TryGetValue(fieldName, out var fieldValue)) - resultName = resultName.Replace(match.Value, fieldValue); + var fieldName = match.Value.Trim('%').ToUpperInvariant(); + + if (fieldValuesMap.TryGetValue(fieldName, out var values)) + { + // Объединяем все значения через запятую, null заменяем на строку "null" + var combinedValue = string.Join(", ", values.Select(v => v ?? "null")); + resultName = resultName.Replace(match.Value, combinedValue); + } else { logger.LogWarning("Поле '{FieldName}' не найдено для unitId={UnitId} при подстановке шорткода '{Shortcode}'", diff --git a/PARR.DAL/Services/Implementations/Unit/UnitInValueService.cs b/PARR.DAL/Services/Implementations/Unit/UnitInValueService.cs index aa818669..fb167c7f 100644 --- a/PARR.DAL/Services/Implementations/Unit/UnitInValueService.cs +++ b/PARR.DAL/Services/Implementations/Unit/UnitInValueService.cs @@ -37,26 +37,27 @@ namespace PARR.DAL.Services.Implementations.Unit } - public async Task> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection aihitNames) + public async Task> GetFieldValuesAsync( + Guid unitId, + IReadOnlyCollection aihitNames) { if (aihitNames == null || aihitNames.Count == 0) - return new Dictionary(StringComparer.OrdinalIgnoreCase); + return new List<(string, string?)>(); - var result = await dataContext.UnitInValues + var keyValuePairs = await dataContext.UnitInValues .AsNoTracking() .AsSplitQuery() .Where(uiv => uiv.UnitId == unitId && uiv.Field != null && uiv.Value != null && aihitNames.Contains(uiv.Field.AihitName.ToUpper())) - .ToDictionaryAsync( - uiv => uiv.Field!.AihitName.ToUpper(), - uiv => uiv.Value!.Value ?? "", - StringComparer.OrdinalIgnoreCase); + .Select(uiv => new { Key = uiv.Field!.AihitName.ToUpper(), Value = uiv.Value!.Value }) + .ToListAsync(); // Журналируем если не нашли поля + var foundFieldNames = keyValuePairs.Select(kvp => kvp.Key).ToHashSet(StringComparer.OrdinalIgnoreCase); var missing = aihitNames - .Where(name => !result.ContainsKey(name.ToUpper())) + .Where(name => !foundFieldNames.Contains(name.ToUpper())) .ToList(); if (missing.Any()) { @@ -64,7 +65,7 @@ namespace PARR.DAL.Services.Implementations.Unit unitId, string.Join(", ", missing)); } - return result; + return keyValuePairs.Select(kvp => (kvp.Key, kvp.Value)).ToList(); } } } diff --git a/PARR.DAL/Services/Interfaces/Unit/IUnitInValueService.cs b/PARR.DAL/Services/Interfaces/Unit/IUnitInValueService.cs index ff33d3ee..038308cf 100644 --- a/PARR.DAL/Services/Interfaces/Unit/IUnitInValueService.cs +++ b/PARR.DAL/Services/Interfaces/Unit/IUnitInValueService.cs @@ -6,6 +6,6 @@ namespace PARR.DAL.Services.Interfaces.Unit { Task> GetByUnitIdsAsync(IEnumerable unitIds); Task> GetByUnitIdAsync(Guid unitId); - Task> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection aihitNames); + Task> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection aihitNames); } }