feat: 멀티테넌시 지원을 위한 레이어 관리 기능 추가
- 레이어 목록 조회, 특정 레이어 레이아웃 조회, 레이어 삭제 및 조건 설정 업데이트 기능을 추가했습니다. - 엔티티 참조 데이터 조회 및 공통 코드 데이터 조회에 멀티테넌시 필터를 적용하여 인증된 사용자의 회사 코드에 따라 데이터 접근을 제한했습니다. - 레이어 관리 패널에서 기본 레이어와 조건부 레이어의 컴포넌트를 통합하여 조건부 영역의 표시를 개선했습니다. - 레이아웃 저장 시 레이어 ID를 포함하여 레이어별로 저장할 수 있도록 변경했습니다.
This commit is contained in:
@@ -30,10 +30,13 @@ export class EntityReferenceController {
|
||||
try {
|
||||
const { tableName, columnName } = req.params;
|
||||
const { limit = 100, search } = req.query;
|
||||
// 멀티테넌시: 인증된 사용자의 회사 코드
|
||||
const companyCode = (req as any).user?.companyCode;
|
||||
|
||||
logger.info(`엔티티 참조 데이터 조회 요청: ${tableName}.${columnName}`, {
|
||||
limit,
|
||||
search,
|
||||
companyCode,
|
||||
});
|
||||
|
||||
// 컬럼 정보 조회 (table_type_columns에서)
|
||||
@@ -89,16 +92,34 @@ export class EntityReferenceController {
|
||||
});
|
||||
}
|
||||
|
||||
// 동적 쿼리로 참조 데이터 조회
|
||||
let sqlQuery = `SELECT ${referenceColumn}, ${displayColumn} as display_name FROM ${referenceTable}`;
|
||||
// 참조 테이블에 company_code 컬럼이 있는지 확인
|
||||
const hasCompanyCode = await queryOne<any>(
|
||||
`SELECT column_name FROM information_schema.columns
|
||||
WHERE table_name = $1 AND column_name = 'company_code' AND table_schema = 'public'`,
|
||||
[referenceTable]
|
||||
);
|
||||
|
||||
// 동적 쿼리로 참조 데이터 조회 (멀티테넌시 필터 적용)
|
||||
const whereConditions: string[] = [];
|
||||
const queryParams: any[] = [];
|
||||
|
||||
// 멀티테넌시: company_code 필터링 (참조 테이블에 company_code가 있는 경우)
|
||||
if (hasCompanyCode && companyCode && companyCode !== "*") {
|
||||
queryParams.push(companyCode);
|
||||
whereConditions.push(`company_code = $${queryParams.length}`);
|
||||
logger.info(`멀티테넌시 필터 적용: company_code = ${companyCode}`, { referenceTable });
|
||||
}
|
||||
|
||||
// 검색 조건 추가
|
||||
if (search) {
|
||||
sqlQuery += ` WHERE ${displayColumn} ILIKE $1`;
|
||||
queryParams.push(`%${search}%`);
|
||||
whereConditions.push(`${displayColumn} ILIKE $${queryParams.length}`);
|
||||
}
|
||||
|
||||
let sqlQuery = `SELECT ${referenceColumn}, ${displayColumn} as display_name FROM ${referenceTable}`;
|
||||
if (whereConditions.length > 0) {
|
||||
sqlQuery += ` WHERE ${whereConditions.join(" AND ")}`;
|
||||
}
|
||||
sqlQuery += ` ORDER BY ${displayColumn} LIMIT $${queryParams.length + 1}`;
|
||||
queryParams.push(Number(limit));
|
||||
|
||||
@@ -107,6 +128,7 @@ export class EntityReferenceController {
|
||||
referenceTable,
|
||||
referenceColumn,
|
||||
displayColumn,
|
||||
companyCode,
|
||||
});
|
||||
|
||||
const referenceData = await query<any>(sqlQuery, queryParams);
|
||||
@@ -119,7 +141,7 @@ export class EntityReferenceController {
|
||||
})
|
||||
);
|
||||
|
||||
logger.info(`엔티티 참조 데이터 조회 완료: ${options.length}개 항목`);
|
||||
logger.info(`엔티티 참조 데이터 조회 완료: ${options.length}개 항목`, { companyCode });
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
@@ -149,13 +171,16 @@ export class EntityReferenceController {
|
||||
try {
|
||||
const { codeCategory } = req.params;
|
||||
const { limit = 100, search } = req.query;
|
||||
// 멀티테넌시: 인증된 사용자의 회사 코드
|
||||
const companyCode = (req as any).user?.companyCode;
|
||||
|
||||
logger.info(`공통 코드 데이터 조회 요청: ${codeCategory}`, {
|
||||
limit,
|
||||
search,
|
||||
companyCode,
|
||||
});
|
||||
|
||||
// code_info 테이블에서 코드 데이터 조회
|
||||
// code_info 테이블에서 코드 데이터 조회 (멀티테넌시 필터 적용)
|
||||
const queryParams: any[] = [codeCategory, 'Y'];
|
||||
let sqlQuery = `
|
||||
SELECT code_value, code_name
|
||||
@@ -163,9 +188,16 @@ export class EntityReferenceController {
|
||||
WHERE code_category = $1 AND is_active = $2
|
||||
`;
|
||||
|
||||
// 멀티테넌시: company_code 필터링
|
||||
if (companyCode && companyCode !== "*") {
|
||||
queryParams.push(companyCode);
|
||||
sqlQuery += ` AND company_code = $${queryParams.length}`;
|
||||
logger.info(`공통 코드 멀티테넌시 필터 적용: company_code = ${companyCode}`);
|
||||
}
|
||||
|
||||
if (search) {
|
||||
sqlQuery += ` AND code_name ILIKE $3`;
|
||||
queryParams.push(`%${search}%`);
|
||||
sqlQuery += ` AND code_name ILIKE $${queryParams.length}`;
|
||||
}
|
||||
|
||||
sqlQuery += ` ORDER BY code_name ASC LIMIT $${queryParams.length + 1}`;
|
||||
@@ -174,12 +206,12 @@ export class EntityReferenceController {
|
||||
const codeData = await query<any>(sqlQuery, queryParams);
|
||||
|
||||
// 옵션 형태로 변환
|
||||
const options: EntityReferenceOption[] = codeData.map((code) => ({
|
||||
const options: EntityReferenceOption[] = codeData.map((code: any) => ({
|
||||
value: code.code_value,
|
||||
label: code.code_name,
|
||||
}));
|
||||
|
||||
logger.info(`공통 코드 데이터 조회 완료: ${options.length}개 항목`);
|
||||
logger.info(`공통 코드 데이터 조회 완료: ${options.length}개 항목`, { companyCode });
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user