Files
KArtSell.Aegis/docs/Design/kbx-foundation-v36/backend/Shared/Excel/ImportMappingEngine.cs
T

47 lines
1.8 KiB
C#

namespace Shared.Excel;
public sealed class ImportMappingEngine
{
public IReadOnlyList<ImportMapping> Map(
IReadOnlyList<string> sourceColumns,
ImportDefinition definition,
IReadOnlyList<ImportMapping>? saved = null)
{
var savedBySource = (saved ?? [])
.Where(x => x.TargetField is not null)
.ToDictionary(x => Normalize(x.SourceColumn), StringComparer.OrdinalIgnoreCase);
var result = new List<ImportMapping>(sourceColumns.Count);
foreach (var source in sourceColumns)
{
var normalized = Normalize(source);
if (savedBySource.TryGetValue(normalized, out var savedMapping) &&
definition.Fields.Any(x => x.Key.Equals(savedMapping.TargetField, StringComparison.OrdinalIgnoreCase)))
{
result.Add(savedMapping with { SourceColumn = source, Source = "saved", Confidence = 1m, Reason = "저장된 매핑" });
continue;
}
var exact = definition.Fields.FirstOrDefault(x => Normalize(x.Label) == normalized || Normalize(x.Key) == normalized);
if (exact is not null)
{
result.Add(new(source, exact.Key, "exact", 1m, "필드명 일치"));
continue;
}
var alias = definition.Fields.FirstOrDefault(x => x.Aliases.Any(a => Normalize(a) == normalized));
if (alias is not null)
{
result.Add(new(source, alias.Key, "alias", 1m, $"별칭 '{source}' 일치"));
continue;
}
result.Add(new(source, null, "manual", null, null));
}
return result;
}
private static string Normalize(string value) =>
new(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray());
}