47 lines
1.8 KiB
C#
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());
|
|
}
|