fix: 분할패널 연결 필터에 operator equals 누락으로 인한 조회 실패 수정 : 우측 패널에 연관 데이터(부서인원)가 조회되지 않던 문제 수정

- 재고이력에서 품번으로 출력안되는 문제 해결 : 엔티티 조인 쿼리 생성 시 동일한 컬럼 별칭이 중복 생성되어 SQL 에러 발생하던 문제 방지
This commit is contained in:
SeongHyun Kim 2026-01-20 16:08:38 +09:00
parent 585febfb52
commit c31b0540aa
2 changed files with 45 additions and 10 deletions

View File

@ -334,6 +334,10 @@ export class EntityJoinService {
);
});
// 🔧 _label 별칭 중복 방지를 위한 Set
// 같은 sourceColumn에서 여러 조인 설정이 있을 때 _label은 첫 번째만 생성
const generatedLabelAliases = new Set<string>();
const joinColumns = joinConfigs
.map((config) => {
const aliasKey = `${config.referenceTable}:${config.sourceColumn}`;
@ -368,16 +372,26 @@ export class EntityJoinService {
// _label 필드도 함께 SELECT (프론트엔드 getColumnUniqueValues용)
// sourceColumn_label 형식으로 추가
resultColumns.push(
`COALESCE(${alias}.${col}::TEXT, '') AS ${config.sourceColumn}_label`
);
// 🔧 중복 방지: 같은 sourceColumn에서 _label은 첫 번째만 생성
const labelAlias = `${config.sourceColumn}_label`;
if (!generatedLabelAliases.has(labelAlias)) {
resultColumns.push(
`COALESCE(${alias}.${col}::TEXT, '') AS ${labelAlias}`
);
generatedLabelAliases.add(labelAlias);
}
// 🆕 referenceColumn (PK)도 항상 SELECT (parentDataMapping용)
// 예: customer_code, item_number 등
// col과 동일해도 별도의 alias로 추가 (customer_code as customer_code)
resultColumns.push(
`COALESCE(${alias}.${config.referenceColumn}::TEXT, '') AS ${config.referenceColumn}`
);
// 🔧 중복 방지: referenceColumn도 한 번만 추가
const refColAlias = config.referenceColumn;
if (!generatedLabelAliases.has(refColAlias)) {
resultColumns.push(
`COALESCE(${alias}.${config.referenceColumn}::TEXT, '') AS ${refColAlias}`
);
generatedLabelAliases.add(refColAlias);
}
} else {
resultColumns.push(
`COALESCE(main.${col}::TEXT, '') AS ${config.aliasColumn}`
@ -392,6 +406,11 @@ export class EntityJoinService {
const individualAlias = `${config.sourceColumn}_${col}`;
// 🔧 중복 방지: 같은 alias가 이미 생성되었으면 스킵
if (generatedLabelAliases.has(individualAlias)) {
return;
}
if (isJoinTableColumn) {
// 조인 테이블 컬럼은 조인 별칭 사용
resultColumns.push(
@ -403,6 +422,7 @@ export class EntityJoinService {
`COALESCE(main.${col}::TEXT, '') AS ${individualAlias}`
);
}
generatedLabelAliases.add(individualAlias);
});
// 🆕 referenceColumn (PK)도 함께 SELECT (parentDataMapping용)
@ -410,11 +430,13 @@ export class EntityJoinService {
config.referenceTable && config.referenceTable !== tableName;
if (
isJoinTableColumn &&
!displayColumns.includes(config.referenceColumn)
!displayColumns.includes(config.referenceColumn) &&
!generatedLabelAliases.has(config.referenceColumn) // 🔧 중복 방지
) {
resultColumns.push(
`COALESCE(${alias}.${config.referenceColumn}::TEXT, '') AS ${config.referenceColumn}`
);
generatedLabelAliases.add(config.referenceColumn);
}
}

View File

@ -924,10 +924,15 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
const { entityJoinApi } = await import("@/lib/api/entityJoin");
// 복합키 조건 생성
// 🔧 entity 타입 컬럼은 코드 값으로 정확히 매칭해야 하므로 operator: 'equals' 사용
const searchConditions: Record<string, any> = {};
keys.forEach((key) => {
if (key.leftColumn && key.rightColumn && leftItem[key.leftColumn] !== undefined) {
searchConditions[key.rightColumn] = leftItem[key.leftColumn];
// 연결 필터는 정확한 값 매칭이 필요하므로 equals 연산자 사용
searchConditions[key.rightColumn] = {
value: leftItem[key.leftColumn],
operator: "equals",
};
}
});
@ -1033,16 +1038,24 @@ export const SplitPanelLayoutComponent: React.FC<SplitPanelLayoutComponentProps>
if (keys && keys.length > 0) {
// 복합키
// 🔧 entity 타입 컬럼은 코드 값으로 정확히 매칭해야 하므로 operator: 'equals' 사용
keys.forEach((key) => {
if (key.leftColumn && key.rightColumn && leftItem[key.leftColumn] !== undefined) {
searchConditions[key.rightColumn] = leftItem[key.leftColumn];
searchConditions[key.rightColumn] = {
value: leftItem[key.leftColumn],
operator: "equals",
};
}
});
} else {
// 단일키
// 🔧 entity 타입 컬럼은 코드 값으로 정확히 매칭해야 하므로 operator: 'equals' 사용
const leftValue = leftItem[leftColumn];
if (leftValue !== undefined) {
searchConditions[rightColumn] = leftValue;
searchConditions[rightColumn] = {
value: leftValue,
operator: "equals",
};
}
}