카테고리 설정 구현

This commit is contained in:
kjs
2025-12-18 14:12:48 +09:00
parent 75e5326b3e
commit f03b247db2
11 changed files with 2927 additions and 138 deletions

View File

@@ -662,6 +662,10 @@ export const getParentOptions = async (
/**
* 연쇄 관계로 자식 옵션 조회
* 실제 연쇄 드롭다운에서 사용하는 API
*
* 다중 부모값 지원:
* - parentValue: 단일 값 (예: "공정검사")
* - parentValues: 다중 값 (예: "공정검사,출하검사" 또는 배열)
*/
export const getCascadingOptions = async (
req: AuthenticatedRequest,
@@ -669,10 +673,26 @@ export const getCascadingOptions = async (
) => {
try {
const { code } = req.params;
const { parentValue } = req.query;
const { parentValue, parentValues } = req.query;
const companyCode = req.user?.companyCode || "*";
if (!parentValue) {
// 다중 부모값 파싱
let parentValueArray: string[] = [];
if (parentValues) {
// parentValues가 있으면 우선 사용 (다중 선택)
if (Array.isArray(parentValues)) {
parentValueArray = parentValues.map(v => String(v));
} else {
// 콤마로 구분된 문자열
parentValueArray = String(parentValues).split(',').map(v => v.trim()).filter(v => v);
}
} else if (parentValue) {
// 기존 단일 값 호환
parentValueArray = [String(parentValue)];
}
if (parentValueArray.length === 0) {
return res.json({
success: true,
data: [],
@@ -714,13 +734,17 @@ export const getCascadingOptions = async (
const relation = relationResult.rows[0];
// 자식 옵션 조회
// 자식 옵션 조회 - 다중 부모값에 대해 IN 절 사용
// SQL Injection 방지를 위해 파라미터화된 쿼리 사용
const placeholders = parentValueArray.map((_, idx) => `$${idx + 1}`).join(', ');
let optionsQuery = `
SELECT
SELECT DISTINCT
${relation.child_value_column} as value,
${relation.child_label_column} as label
${relation.child_label_column} as label,
${relation.child_filter_column} as parent_value
FROM ${relation.child_table}
WHERE ${relation.child_filter_column} = $1
WHERE ${relation.child_filter_column} IN (${placeholders})
`;
// 멀티테넌시 적용 (테이블에 company_code가 있는 경우)
@@ -730,7 +754,8 @@ export const getCascadingOptions = async (
[relation.child_table]
);
const optionsParams: any[] = [parentValue];
const optionsParams: any[] = [...parentValueArray];
let paramIndex = parentValueArray.length + 1;
// company_code = "*"는 최고 관리자 전용이므로 일반 회사는 자기 회사 데이터만
if (
@@ -738,8 +763,9 @@ export const getCascadingOptions = async (
tableInfoResult.rowCount > 0 &&
companyCode !== "*"
) {
optionsQuery += ` AND company_code = $2`;
optionsQuery += ` AND company_code = $${paramIndex}`;
optionsParams.push(companyCode);
paramIndex++;
}
// 정렬
@@ -751,9 +777,9 @@ export const getCascadingOptions = async (
const optionsResult = await pool.query(optionsQuery, optionsParams);
logger.info("연쇄 옵션 조회", {
logger.info("연쇄 옵션 조회 (다중 부모값 지원)", {
relationCode: code,
parentValue,
parentValues: parentValueArray,
optionsCount: optionsResult.rowCount,
});