fix(dal): ShortcodeService теперь возвращает значения мультиполей через запятую, NULL как "null". Добавлены отсутствующие навигационные данные
This commit is contained in:
@@ -218,23 +218,36 @@ namespace PARR.DAL.DomainServices.Implementations
|
|||||||
|
|
||||||
private async Task<string> ReplaceFieldValues(Guid unitId, string resultName, List<Match> shortcodesInMask)
|
private async Task<string> ReplaceFieldValues(Guid unitId, string resultName, List<Match> shortcodesInMask)
|
||||||
{
|
{
|
||||||
// 1. Извлекаем имена полей из шорткодов: %IP_АДРЕС% → "IP_АДРЕС"
|
// 1. Извлекаем имена полей из шорткодов
|
||||||
var requiredFieldNames = shortcodesInMask
|
var requiredFieldNames = shortcodesInMask
|
||||||
.Select(m => m.Value.Trim('%').ToUpper())
|
.Select(m => m.Value.Trim('%').ToUpperInvariant())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (requiredFieldNames.Count == 0)
|
if (requiredFieldNames.Count == 0)
|
||||||
return resultName;
|
return resultName;
|
||||||
|
|
||||||
// 2. Получаем только нужные значения
|
// 2. Получаем значения (может быть дубль)
|
||||||
var fieldValueMap = await unitInValueService.GetFieldValuesAsync(unitId, requiredFieldNames);
|
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)
|
foreach (var match in shortcodesInMask)
|
||||||
{
|
{
|
||||||
var fieldName = match.Value.Trim('%').ToUpper();
|
var fieldName = match.Value.Trim('%').ToUpperInvariant();
|
||||||
if (fieldValueMap.TryGetValue(fieldName, out var fieldValue))
|
|
||||||
resultName = resultName.Replace(match.Value, fieldValue);
|
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
|
else
|
||||||
{
|
{
|
||||||
logger.LogWarning("Поле '{FieldName}' не найдено для unitId={UnitId} при подстановке шорткода '{Shortcode}'",
|
logger.LogWarning("Поле '{FieldName}' не найдено для unitId={UnitId} при подстановке шорткода '{Shortcode}'",
|
||||||
|
|||||||
@@ -37,26 +37,27 @@ namespace PARR.DAL.Services.Implementations.Unit
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Dictionary<string, string>> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection<string> aihitNames)
|
public async Task<List<(string FieldName, string? Value)>> GetFieldValuesAsync(
|
||||||
|
Guid unitId,
|
||||||
|
IReadOnlyCollection<string> aihitNames)
|
||||||
{
|
{
|
||||||
if (aihitNames == null || aihitNames.Count == 0)
|
if (aihitNames == null || aihitNames.Count == 0)
|
||||||
return new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
return new List<(string, string?)>();
|
||||||
|
|
||||||
var result = await dataContext.UnitInValues
|
var keyValuePairs = await dataContext.UnitInValues
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
.AsSplitQuery()
|
.AsSplitQuery()
|
||||||
.Where(uiv => uiv.UnitId == unitId
|
.Where(uiv => uiv.UnitId == unitId
|
||||||
&& uiv.Field != null
|
&& uiv.Field != null
|
||||||
&& uiv.Value != null
|
&& uiv.Value != null
|
||||||
&& aihitNames.Contains(uiv.Field.AihitName.ToUpper()))
|
&& aihitNames.Contains(uiv.Field.AihitName.ToUpper()))
|
||||||
.ToDictionaryAsync(
|
.Select(uiv => new { Key = uiv.Field!.AihitName.ToUpper(), Value = uiv.Value!.Value })
|
||||||
uiv => uiv.Field!.AihitName.ToUpper(),
|
.ToListAsync();
|
||||||
uiv => uiv.Value!.Value ?? "",
|
|
||||||
StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
// Журналируем если не нашли поля
|
// Журналируем если не нашли поля
|
||||||
|
var foundFieldNames = keyValuePairs.Select(kvp => kvp.Key).ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||||
var missing = aihitNames
|
var missing = aihitNames
|
||||||
.Where(name => !result.ContainsKey(name.ToUpper()))
|
.Where(name => !foundFieldNames.Contains(name.ToUpper()))
|
||||||
.ToList();
|
.ToList();
|
||||||
if (missing.Any())
|
if (missing.Any())
|
||||||
{
|
{
|
||||||
@@ -64,7 +65,7 @@ namespace PARR.DAL.Services.Implementations.Unit
|
|||||||
unitId, string.Join(", ", missing));
|
unitId, string.Join(", ", missing));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return keyValuePairs.Select(kvp => (kvp.Key, kvp.Value)).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,6 @@ namespace PARR.DAL.Services.Interfaces.Unit
|
|||||||
{
|
{
|
||||||
Task<List<UnitInValue>> GetByUnitIdsAsync(IEnumerable<Guid> unitIds);
|
Task<List<UnitInValue>> GetByUnitIdsAsync(IEnumerable<Guid> unitIds);
|
||||||
Task<List<UnitInValue>> GetByUnitIdAsync(Guid unitId);
|
Task<List<UnitInValue>> GetByUnitIdAsync(Guid unitId);
|
||||||
Task<Dictionary<string, string>> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection<string> aihitNames);
|
Task<List<(string FieldName, string? Value)>> GetFieldValuesAsync(Guid unitId, IReadOnlyCollection<string> aihitNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user