엔티티 타입 다중 표시 컬럼 기능 구현

Frontend:
- EntityTypeConfig 인터페이스에 displayColumns 배열 추가
- EntityTypeConfigPanel에서 여러 표시 컬럼 선택 UI 구현
- 구분자 설정 기능 추가
- 하위 호환성을 위한 displayColumn 유지

Backend:
- EntityJoinConfig에 displayColumns 배열 지원
- 화면별 엔티티 설정을 전달받는 API 확장
- CONCAT을 사용한 다중 컬럼 표시 SQL 생성
- 기존 단일 컬럼과의 호환성 유지

이제 화면마다 다른 표시 컬럼 조합을 설정할 수 있음
예: 한 화면에서는 '이름'만, 다른 화면에서는 '이름 - 부서명' 표시
This commit is contained in:
kjs
2025-09-23 15:58:54 +09:00
parent 699efd25a2
commit 4aefb5be6a
6 changed files with 209 additions and 193 deletions

View File

@@ -16,8 +16,13 @@ const prisma = new PrismaClient();
export class EntityJoinService {
/**
* 테이블의 Entity 컬럼들을 감지하여 조인 설정 생성
* @param tableName 테이블명
* @param screenEntityConfigs 화면별 엔티티 설정 (선택사항)
*/
async detectEntityJoins(tableName: string): Promise<EntityJoinConfig[]> {
async detectEntityJoins(
tableName: string,
screenEntityConfigs?: Record<string, any>
): Promise<EntityJoinConfig[]> {
try {
logger.info(`Entity 컬럼 감지 시작: ${tableName}`);
@@ -48,8 +53,22 @@ export class EntityJoinService {
continue;
}
// display_column이 없으면 reference_column 사용
const displayColumn = column.display_column || column.reference_column;
// 화면별 엔티티 설정이 있으면 우선 사용, 없으면 기본값 사용
const screenConfig = screenEntityConfigs?.[column.column_name];
let displayColumns: string[] = [];
let separator = " - ";
if (screenConfig && screenConfig.displayColumns) {
// 화면에서 설정된 표시 컬럼들 사용
displayColumns = screenConfig.displayColumns;
separator = screenConfig.separator || " - ";
} else if (column.display_column) {
// 기존 설정된 단일 표시 컬럼 사용
displayColumns = [column.display_column];
} else {
// 기본값: reference_column 사용
displayColumns = [column.reference_column];
}
// 별칭 컬럼명 생성 (writer -> writer_name)
const aliasColumn = `${column.column_name}_name`;
@@ -59,8 +78,10 @@ export class EntityJoinService {
sourceColumn: column.column_name,
referenceTable: column.reference_table,
referenceColumn: column.reference_column,
displayColumn: displayColumn,
displayColumns: displayColumns,
displayColumn: displayColumns[0], // 하위 호환성
aliasColumn: aliasColumn,
separator: separator,
};
// 조인 설정 유효성 검증
@@ -130,10 +151,22 @@ export class EntityJoinService {
});
const joinColumns = joinConfigs
.map(
(config) =>
`COALESCE(${aliasMap.get(config.referenceTable)}.${config.displayColumn}, '') AS ${config.aliasColumn}`
)
.map((config) => {
const alias = aliasMap.get(config.referenceTable);
const displayColumns = config.displayColumns || [config.displayColumn];
const separator = config.separator || " - ";
if (displayColumns.length === 1) {
// 단일 컬럼인 경우
return `COALESCE(${alias}.${displayColumns[0]}, '') AS ${config.aliasColumn}`;
} else {
// 여러 컬럼인 경우 CONCAT으로 연결
const concatParts = displayColumns
.map(col => `COALESCE(${alias}.${col}, '')`)
.join(`, '${separator}', `);
return `CONCAT(${concatParts}) AS ${config.aliasColumn}`;
}
})
.join(", ");
// SELECT 절 구성