테이블 데이터 필터링 기능 및 textarea컴포넌트 자동 매핑 삭제
This commit is contained in:
154
backend-node/src/utils/dataFilterUtil.ts
Normal file
154
backend-node/src/utils/dataFilterUtil.ts
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* 데이터 필터 유틸리티
|
||||
* 프론트엔드의 DataFilterConfig를 SQL WHERE 절로 변환
|
||||
*/
|
||||
|
||||
export interface ColumnFilter {
|
||||
id: string;
|
||||
columnName: string;
|
||||
operator: "equals" | "not_equals" | "in" | "not_in" | "contains" | "starts_with" | "ends_with" | "is_null" | "is_not_null";
|
||||
value: string | string[];
|
||||
valueType: "static" | "category" | "code";
|
||||
}
|
||||
|
||||
export interface DataFilterConfig {
|
||||
enabled: boolean;
|
||||
filters: ColumnFilter[];
|
||||
matchType: "all" | "any"; // AND / OR
|
||||
}
|
||||
|
||||
/**
|
||||
* DataFilterConfig를 SQL WHERE 조건과 파라미터로 변환
|
||||
* @param dataFilter 필터 설정
|
||||
* @param tableAlias 테이블 별칭 (예: "r", "t1") - 조인 쿼리에서 사용
|
||||
* @param startParamIndex 시작 파라미터 인덱스 (예: 1이면 $1부터 시작)
|
||||
* @returns { whereClause: string, params: any[] }
|
||||
*/
|
||||
export function buildDataFilterWhereClause(
|
||||
dataFilter: DataFilterConfig | undefined,
|
||||
tableAlias?: string,
|
||||
startParamIndex: number = 1
|
||||
): { whereClause: string; params: any[] } {
|
||||
if (!dataFilter || !dataFilter.enabled || !dataFilter.filters || dataFilter.filters.length === 0) {
|
||||
return { whereClause: "", params: [] };
|
||||
}
|
||||
|
||||
const conditions: string[] = [];
|
||||
const params: any[] = [];
|
||||
let paramIndex = startParamIndex;
|
||||
|
||||
// 테이블 별칭이 있으면 "alias."를 붙이고, 없으면 그냥 컬럼명만
|
||||
const getColumnRef = (colName: string) => {
|
||||
return tableAlias ? `${tableAlias}."${colName}"` : `"${colName}"`;
|
||||
};
|
||||
|
||||
for (const filter of dataFilter.filters) {
|
||||
const { columnName, operator, value } = filter;
|
||||
|
||||
if (!columnName) {
|
||||
continue; // 컬럼명이 없으면 스킵
|
||||
}
|
||||
|
||||
const columnRef = getColumnRef(columnName);
|
||||
|
||||
switch (operator) {
|
||||
case "equals":
|
||||
conditions.push(`${columnRef} = $${paramIndex}`);
|
||||
params.push(value);
|
||||
paramIndex++;
|
||||
break;
|
||||
|
||||
case "not_equals":
|
||||
conditions.push(`${columnRef} != $${paramIndex}`);
|
||||
params.push(value);
|
||||
paramIndex++;
|
||||
break;
|
||||
|
||||
case "in":
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
const placeholders = value.map((_, idx) => `$${paramIndex + idx}`).join(", ");
|
||||
conditions.push(`${columnRef} IN (${placeholders})`);
|
||||
params.push(...value);
|
||||
paramIndex += value.length;
|
||||
}
|
||||
break;
|
||||
|
||||
case "not_in":
|
||||
if (Array.isArray(value) && value.length > 0) {
|
||||
const placeholders = value.map((_, idx) => `$${paramIndex + idx}`).join(", ");
|
||||
conditions.push(`${columnRef} NOT IN (${placeholders})`);
|
||||
params.push(...value);
|
||||
paramIndex += value.length;
|
||||
}
|
||||
break;
|
||||
|
||||
case "contains":
|
||||
conditions.push(`${columnRef} LIKE $${paramIndex}`);
|
||||
params.push(`%${value}%`);
|
||||
paramIndex++;
|
||||
break;
|
||||
|
||||
case "starts_with":
|
||||
conditions.push(`${columnRef} LIKE $${paramIndex}`);
|
||||
params.push(`${value}%`);
|
||||
paramIndex++;
|
||||
break;
|
||||
|
||||
case "ends_with":
|
||||
conditions.push(`${columnRef} LIKE $${paramIndex}`);
|
||||
params.push(`%${value}`);
|
||||
paramIndex++;
|
||||
break;
|
||||
|
||||
case "is_null":
|
||||
conditions.push(`${columnRef} IS NULL`);
|
||||
break;
|
||||
|
||||
case "is_not_null":
|
||||
conditions.push(`${columnRef} IS NOT NULL`);
|
||||
break;
|
||||
|
||||
default:
|
||||
// 알 수 없는 연산자는 무시
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (conditions.length === 0) {
|
||||
return { whereClause: "", params: [] };
|
||||
}
|
||||
|
||||
// matchType에 따라 AND / OR 조합
|
||||
const logicalOperator = dataFilter.matchType === "any" ? " OR " : " AND ";
|
||||
const whereClause = `(${conditions.join(logicalOperator)})`;
|
||||
|
||||
return { whereClause, params };
|
||||
}
|
||||
|
||||
/**
|
||||
* 기존 WHERE 절에 dataFilter 조건을 추가
|
||||
* @param existingWhere 기존 WHERE 절 (예: "company_code = $1")
|
||||
* @param existingParams 기존 파라미터 배열
|
||||
* @param dataFilter 필터 설정
|
||||
* @returns { whereClause: string, params: any[] }
|
||||
*/
|
||||
export function appendDataFilterToWhere(
|
||||
existingWhere: string,
|
||||
existingParams: any[],
|
||||
dataFilter: DataFilterConfig | undefined
|
||||
): { whereClause: string; params: any[] } {
|
||||
const { whereClause: filterWhere, params: filterParams } = buildDataFilterWhereClause(
|
||||
dataFilter,
|
||||
existingParams.length + 1
|
||||
);
|
||||
|
||||
if (!filterWhere) {
|
||||
return { whereClause: existingWhere, params: existingParams };
|
||||
}
|
||||
|
||||
const newWhere = existingWhere ? `${existingWhere} AND ${filterWhere}` : filterWhere;
|
||||
const newParams = [...existingParams, ...filterParams];
|
||||
|
||||
return { whereClause: newWhere, params: newParams };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user