우측 패널 일괄삭제 기능

This commit is contained in:
kjs
2025-11-20 11:58:43 +09:00
parent c3f58feef7
commit e3b78309fa
7 changed files with 587 additions and 105 deletions

View File

@@ -200,6 +200,25 @@ export class EntityJoinService {
}
}
/**
* 날짜 컬럼을 YYYY-MM-DD 형식으로 변환하는 SQL 표현식
*/
private formatDateColumn(
tableAlias: string,
columnName: string,
dataType?: string
): string {
// date, timestamp 타입이면 TO_CHAR로 변환
if (
dataType &&
(dataType.includes("date") || dataType.includes("timestamp"))
) {
return `TO_CHAR(${tableAlias}.${columnName}, 'YYYY-MM-DD')`;
}
// 기본은 TEXT 캐스팅
return `${tableAlias}.${columnName}::TEXT`;
}
/**
* Entity 조인이 포함된 SQL 쿼리 생성
*/
@@ -210,19 +229,30 @@ export class EntityJoinService {
whereClause: string = "",
orderBy: string = "",
limit?: number,
offset?: number
offset?: number,
columnTypes?: Map<string, string> // 컬럼명 → 데이터 타입 매핑
): { query: string; aliasMap: Map<string, string> } {
try {
// 기본 SELECT 컬럼들 (TEXT 캐스팅하여 record 타입 오류 방지)
// "*"는 특별 처리: AS 없이 그냥 main.*만
const baseColumns = selectColumns
.map((col) => {
if (col === "*") {
return "main.*";
}
return `main.${col}::TEXT AS ${col}`;
})
.join(", ");
// 기본 SELECT 컬럼들 (날짜는 YYYY-MM-DD 형식, 나머지는 TEXT 캐스팅)
// 🔧 "*"는 전체 조회하되, 날짜 타입 타임존 문제를 피하기 위해
// jsonb_build_object를 사용하여 명시적으로 변환
let baseColumns: string;
if (selectColumns.length === 1 && selectColumns[0] === "*") {
// main.* 사용 시 날짜 타입 필드만 TO_CHAR로 변환
// PostgreSQL의 날짜 → 타임스탬프 자동 변환으로 인한 타임존 문제 방지
baseColumns = `main.*`;
logger.info(
`⚠️ [buildJoinQuery] main.* 사용 - 날짜 타임존 변환 주의 필요`
);
} else {
baseColumns = selectColumns
.map((col) => {
const dataType = columnTypes?.get(col);
const formattedCol = this.formatDateColumn("main", col, dataType);
return `${formattedCol} AS ${col}`;
})
.join(", ");
}
// Entity 조인 컬럼들 (COALESCE로 NULL을 빈 문자열로 처리)
// 별칭 매핑 생성 (JOIN 절과 동일한 로직)
@@ -303,6 +333,13 @@ export class EntityJoinService {
resultColumns.push(
`COALESCE(${alias}.${col}::TEXT, '') AS ${config.sourceColumn}_label`
);
// 🆕 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}`
);
} else {
resultColumns.push(
`COALESCE(main.${col}::TEXT, '') AS ${config.aliasColumn}`
@@ -328,6 +365,18 @@ export class EntityJoinService {
.join(` || '${separator}' || `);
resultColumns.push(`(${concatParts}) AS ${config.aliasColumn}`);
// 🆕 referenceColumn (PK)도 함께 SELECT (parentDataMapping용)
const isJoinTableColumn =
config.referenceTable && config.referenceTable !== tableName;
if (
isJoinTableColumn &&
!displayColumns.includes(config.referenceColumn)
) {
resultColumns.push(
`COALESCE(${alias}.${config.referenceColumn}::TEXT, '') AS ${config.referenceColumn}`
);
}
}
// 모든 resultColumns를 반환