Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into common/feat/dashboard-map
This commit is contained in:
@@ -1094,4 +1094,150 @@ export class ExternalRestApiConnectionService {
|
||||
throw new Error("올바르지 않은 인증 타입입니다.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 다중 REST API 데이터 조회 및 병합
|
||||
* 여러 REST API의 응답을 병합하여 하나의 데이터셋으로 반환
|
||||
*/
|
||||
static async fetchMultipleData(
|
||||
configs: Array<{
|
||||
connectionId: number;
|
||||
endpoint: string;
|
||||
jsonPath: string;
|
||||
alias: string;
|
||||
}>,
|
||||
userCompanyCode?: string
|
||||
): Promise<ApiResponse<{
|
||||
rows: any[];
|
||||
columns: Array<{ columnName: string; columnLabel: string; dataType: string; sourceApi: string }>;
|
||||
total: number;
|
||||
sources: Array<{ connectionId: number; connectionName: string; rowCount: number }>;
|
||||
}>> {
|
||||
try {
|
||||
logger.info(`다중 REST API 데이터 조회 시작: ${configs.length}개 API`);
|
||||
|
||||
// 각 API에서 데이터 조회
|
||||
const results = await Promise.all(
|
||||
configs.map(async (config) => {
|
||||
try {
|
||||
const result = await this.fetchData(
|
||||
config.connectionId,
|
||||
config.endpoint,
|
||||
config.jsonPath,
|
||||
userCompanyCode
|
||||
);
|
||||
|
||||
if (result.success && result.data) {
|
||||
return {
|
||||
success: true,
|
||||
connectionId: config.connectionId,
|
||||
connectionName: result.data.connectionInfo.connectionName,
|
||||
alias: config.alias,
|
||||
rows: result.data.rows,
|
||||
columns: result.data.columns,
|
||||
};
|
||||
} else {
|
||||
logger.warn(`API ${config.connectionId} 조회 실패:`, result.message);
|
||||
return {
|
||||
success: false,
|
||||
connectionId: config.connectionId,
|
||||
connectionName: "",
|
||||
alias: config.alias,
|
||||
rows: [],
|
||||
columns: [],
|
||||
error: result.message,
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`API ${config.connectionId} 조회 오류:`, error);
|
||||
return {
|
||||
success: false,
|
||||
connectionId: config.connectionId,
|
||||
connectionName: "",
|
||||
alias: config.alias,
|
||||
rows: [],
|
||||
columns: [],
|
||||
error: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// 성공한 결과만 필터링
|
||||
const successfulResults = results.filter(r => r.success);
|
||||
|
||||
if (successfulResults.length === 0) {
|
||||
return {
|
||||
success: false,
|
||||
message: "모든 REST API 조회에 실패했습니다.",
|
||||
error: {
|
||||
code: "ALL_APIS_FAILED",
|
||||
details: results.map(r => ({ connectionId: r.connectionId, error: r.error })),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 컬럼 병합 (별칭 적용)
|
||||
const mergedColumns: Array<{ columnName: string; columnLabel: string; dataType: string; sourceApi: string }> = [];
|
||||
|
||||
for (const result of successfulResults) {
|
||||
for (const col of result.columns) {
|
||||
const prefixedColumnName = result.alias ? `${result.alias}${col.columnName}` : col.columnName;
|
||||
mergedColumns.push({
|
||||
columnName: prefixedColumnName,
|
||||
columnLabel: `${col.columnLabel} (${result.connectionName})`,
|
||||
dataType: col.dataType,
|
||||
sourceApi: result.connectionName,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 데이터 병합 (가로 병합: 각 API의 첫 번째 행끼리 병합)
|
||||
// 참고: 실제 사용 시에는 조인 키가 필요할 수 있음
|
||||
const maxRows = Math.max(...successfulResults.map(r => r.rows.length));
|
||||
const mergedRows: any[] = [];
|
||||
|
||||
for (let i = 0; i < maxRows; i++) {
|
||||
const mergedRow: any = {};
|
||||
|
||||
for (const result of successfulResults) {
|
||||
const row = result.rows[i] || {};
|
||||
|
||||
for (const [key, value] of Object.entries(row)) {
|
||||
const prefixedKey = result.alias ? `${result.alias}${key}` : key;
|
||||
mergedRow[prefixedKey] = value;
|
||||
}
|
||||
}
|
||||
|
||||
mergedRows.push(mergedRow);
|
||||
}
|
||||
|
||||
logger.info(`다중 REST API 데이터 병합 완료: ${mergedRows.length}개 행, ${mergedColumns.length}개 컬럼`);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
rows: mergedRows,
|
||||
columns: mergedColumns,
|
||||
total: mergedRows.length,
|
||||
sources: successfulResults.map(r => ({
|
||||
connectionId: r.connectionId,
|
||||
connectionName: r.connectionName,
|
||||
rowCount: r.rows.length,
|
||||
})),
|
||||
},
|
||||
message: `${successfulResults.length}개 API에서 총 ${mergedRows.length}개 데이터를 조회했습니다.`,
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error("다중 REST API 데이터 조회 오류:", error);
|
||||
return {
|
||||
success: false,
|
||||
message: "다중 REST API 데이터 조회에 실패했습니다.",
|
||||
error: {
|
||||
code: "MULTI_FETCH_ERROR",
|
||||
details: error instanceof Error ? error.message : "알 수 없는 오류",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user