테스트 위젯 원본 승격 전 세이브
This commit is contained in:
109
frontend/lib/utils/columnMapping.ts
Normal file
109
frontend/lib/utils/columnMapping.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 컬럼 매핑 유틸리티
|
||||
* 다중 데이터 소스 통합 시 컬럼명을 통일하기 위한 함수
|
||||
*/
|
||||
|
||||
/**
|
||||
* 데이터에 컬럼 매핑 적용
|
||||
* @param data 원본 데이터 배열
|
||||
* @param columnMapping 컬럼 매핑 객체 { 원본컬럼: 표시이름 }
|
||||
* @returns 매핑이 적용된 데이터 배열
|
||||
*
|
||||
* @example
|
||||
* const data = [{ name: "상품A", amount: 1000 }];
|
||||
* const mapping = { name: "product", amount: "value" };
|
||||
* const result = applyColumnMapping(data, mapping);
|
||||
* // result: [{ product: "상품A", value: 1000 }]
|
||||
*/
|
||||
export function applyColumnMapping(
|
||||
data: any[],
|
||||
columnMapping?: Record<string, string>
|
||||
): any[] {
|
||||
// 매핑이 없거나 빈 객체면 원본 그대로 반환
|
||||
if (!columnMapping || Object.keys(columnMapping).length === 0) {
|
||||
return data;
|
||||
}
|
||||
|
||||
console.log("🔄 컬럼 매핑 적용 중...", {
|
||||
rowCount: data.length,
|
||||
mappingCount: Object.keys(columnMapping).length,
|
||||
mapping: columnMapping,
|
||||
});
|
||||
|
||||
// 각 행에 매핑 적용
|
||||
const mappedData = data.map((row) => {
|
||||
const mappedRow: any = {};
|
||||
|
||||
// 모든 컬럼 순회
|
||||
Object.keys(row).forEach((originalCol) => {
|
||||
// 매핑이 있으면 매핑된 이름 사용, 없으면 원본 이름 사용
|
||||
const mappedCol = columnMapping[originalCol] || originalCol;
|
||||
mappedRow[mappedCol] = row[originalCol];
|
||||
});
|
||||
|
||||
return mappedRow;
|
||||
});
|
||||
|
||||
console.log("✅ 컬럼 매핑 완료", {
|
||||
originalColumns: Object.keys(data[0] || {}),
|
||||
mappedColumns: Object.keys(mappedData[0] || {}),
|
||||
});
|
||||
|
||||
return mappedData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 여러 데이터 소스의 데이터를 병합
|
||||
* 각 데이터 소스의 컬럼 매핑을 적용한 후 병합
|
||||
*
|
||||
* @param dataSets 데이터셋 배열 [{ data, columnMapping, source }]
|
||||
* @returns 병합된 데이터 배열
|
||||
*
|
||||
* @example
|
||||
* const dataSets = [
|
||||
* {
|
||||
* data: [{ name: "A", amount: 100 }],
|
||||
* columnMapping: { name: "product", amount: "value" },
|
||||
* source: "DB1"
|
||||
* },
|
||||
* {
|
||||
* data: [{ product_name: "B", total: 200 }],
|
||||
* columnMapping: { product_name: "product", total: "value" },
|
||||
* source: "DB2"
|
||||
* }
|
||||
* ];
|
||||
* const result = mergeDataSources(dataSets);
|
||||
* // result: [
|
||||
* // { product: "A", value: 100, _source: "DB1" },
|
||||
* // { product: "B", value: 200, _source: "DB2" }
|
||||
* // ]
|
||||
*/
|
||||
export function mergeDataSources(
|
||||
dataSets: Array<{
|
||||
data: any[];
|
||||
columnMapping?: Record<string, string>;
|
||||
source?: string;
|
||||
}>
|
||||
): any[] {
|
||||
console.log(`🔗 ${dataSets.length}개의 데이터 소스 병합 중...`);
|
||||
|
||||
const mergedData: any[] = [];
|
||||
|
||||
dataSets.forEach(({ data, columnMapping, source }) => {
|
||||
// 각 데이터셋에 컬럼 매핑 적용
|
||||
const mappedData = applyColumnMapping(data, columnMapping);
|
||||
|
||||
// 소스 정보 추가
|
||||
const dataWithSource = mappedData.map((row) => ({
|
||||
...row,
|
||||
_source: source || "unknown", // 어느 데이터 소스에서 왔는지 표시
|
||||
}));
|
||||
|
||||
mergedData.push(...dataWithSource);
|
||||
});
|
||||
|
||||
console.log(`✅ 데이터 병합 완료: 총 ${mergedData.length}개 행`);
|
||||
|
||||
return mergedData;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user