회사별 메뉴 필터링 기능

This commit is contained in:
kjs
2025-10-27 16:58:43 +09:00
parent 29c49d7f07
commit 02df4355e2
4 changed files with 770 additions and 17 deletions

View File

@@ -17,19 +17,25 @@ export async function getAdminMenus(
res: Response
): Promise<void> {
try {
logger.info("=== 메뉴 목록 조회 시작 ===");
logger.info("=== 관리자 메뉴 목록 조회 시작 ===");
// 현재 로그인한 사용자의 회사 코드와 로케일 가져오기
// 현재 로그인한 사용자의 정보 가져오기
const userId = req.user?.userId;
const userCompanyCode = req.user?.companyCode || "ILSHIN";
const userType = req.user?.userType;
const userLang = (req.query.userLang as string) || "ko";
const menuType = req.query.menuType as string | undefined; // menuType 파라미터 추가
logger.info(`사용자 ID: ${userId}`);
logger.info(`사용자 회사 코드: ${userCompanyCode}`);
logger.info(`사용자 유형: ${userType}`);
logger.info(`사용자 로케일: ${userLang}`);
logger.info(`메뉴 타입: ${menuType || "전체"}`);
const paramMap = {
userId,
userCompanyCode,
userType,
userLang,
menuType, // menuType 추가
};
@@ -37,7 +43,7 @@ export async function getAdminMenus(
const menuList = await AdminService.getAdminMenuList(paramMap);
logger.info(
`메뉴 조회 결과: ${menuList.length}개 (타입: ${menuType || "전체"})`
`관리자 메뉴 조회 결과: ${menuList.length}개 (타입: ${menuType || "전체"}, 회사: ${userCompanyCode})`
);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
@@ -76,21 +82,29 @@ export async function getUserMenus(
try {
logger.info("=== 사용자 메뉴 목록 조회 시작 ===");
// 현재 로그인한 사용자의 회사 코드와 로케일 가져오기
// 현재 로그인한 사용자의 정보 가져오기
const userId = req.user?.userId;
const userCompanyCode = req.user?.companyCode || "ILSHIN";
const userType = req.user?.userType;
const userLang = (req.query.userLang as string) || "ko";
logger.info(`사용자 ID: ${userId}`);
logger.info(`사용자 회사 코드: ${userCompanyCode}`);
logger.info(`사용자 유형: ${userType}`);
logger.info(`사용자 로케일: ${userLang}`);
const paramMap = {
userId,
userCompanyCode,
userType,
userLang,
};
const menuList = await AdminService.getUserMenuList(paramMap);
logger.info(`사용자 메뉴 조회 결과: ${menuList.length}`);
logger.info(
`사용자 메뉴 조회 결과: ${menuList.length}개 (회사: ${userCompanyCode})`
);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
}

View File

@@ -3,18 +3,51 @@ import { query, queryOne } from "../database/db";
export class AdminService {
/**
* 관리자 메뉴 목록 조회
* 관리자 메뉴 목록 조회 (회사별 필터링 적용)
*/
static async getAdminMenuList(paramMap: any): Promise<any[]> {
try {
logger.info("AdminService.getAdminMenuList 시작 - 파라미터:", paramMap);
const { userLang = "ko", menuType } = paramMap;
const {
userId,
userCompanyCode,
userType,
userLang = "ko",
menuType,
} = paramMap;
// menuType에 따른 WHERE 조건 생성
const menuTypeCondition =
menuType !== undefined ? `MENU_TYPE = ${parseInt(menuType)}` : "1 = 1";
// 회사별 필터링 조건 생성
let companyFilter = "";
let queryParams: any[] = [userLang];
let paramIndex = 2;
if (userType === "SUPER_ADMIN" && userCompanyCode === "*") {
// SUPER_ADMIN: 모든 메뉴 표시
logger.info("✅ SUPER_ADMIN 모드: 모든 관리자 메뉴 표시");
companyFilter = "";
} else if (userType === "COMPANY_ADMIN") {
// COMPANY_ADMIN: 자기 회사 메뉴 + 공통 메뉴
companyFilter = `AND (MENU.COMPANY_CODE = $${paramIndex} OR MENU.COMPANY_CODE IS NULL)`;
queryParams.push(userCompanyCode);
paramIndex++;
logger.info(
`✅ COMPANY_ADMIN 모드: 회사 ${userCompanyCode} 관리자 메뉴 + 공통 메뉴 표시`
);
} else {
// 일반 사용자: 자기 회사 메뉴만
companyFilter = `AND (MENU.COMPANY_CODE = $${paramIndex} OR MENU.COMPANY_CODE IS NULL)`;
queryParams.push(userCompanyCode);
paramIndex++;
logger.info(
`✅ 일반 사용자 모드: 회사 ${userCompanyCode} 관리자 메뉴 + 공통 메뉴 표시`
);
}
// 기존 Java의 selectAdminMenuList 쿼리를 Raw Query로 포팅
// WITH RECURSIVE 쿼리 구현
const menuList = await query<any>(
@@ -96,6 +129,8 @@ export class AdminService {
)
FROM MENU_INFO MENU
WHERE ${menuTypeCondition}
AND STATUS = 'active'
${companyFilter}
AND NOT EXISTS (
SELECT 1 FROM MENU_INFO parent_menu
WHERE parent_menu.OBJID = MENU.PARENT_OBJ_ID
@@ -160,6 +195,7 @@ export class AdminService {
FROM MENU_INFO MENU_SUB
JOIN V_MENU ON MENU_SUB.PARENT_OBJ_ID = V_MENU.OBJID
WHERE MENU_SUB.OBJID != ANY(V_MENU.PATH)
AND MENU_SUB.STATUS = 'active'
)
SELECT
LEVEL AS LEV,
@@ -190,14 +226,18 @@ export class AdminService {
WHERE 1 = 1
ORDER BY PATH, SEQ
`,
[userLang]
queryParams
);
logger.info(
`메뉴 목록 조회 결과: ${menuList.length}개 (menuType: ${menuType || "전체"})`
`관리자 메뉴 목록 조회 결과: ${menuList.length}개 (menuType: ${menuType || "전체"}, userType: ${userType}, company: ${userCompanyCode})`
);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
logger.info("첫 번째 메뉴:", {
objid: menuList[0].objid,
name: menuList[0].menu_name_kor,
companyCode: menuList[0].company_code,
});
}
return menuList;
@@ -208,15 +248,44 @@ export class AdminService {
}
/**
* 사용자 메뉴 목록 조회
* 사용자 메뉴 목록 조회 (회사별 필터링 적용)
*/
static async getUserMenuList(paramMap: any): Promise<any[]> {
try {
logger.info("AdminService.getUserMenuList 시작 - 파라미터:", paramMap);
const { userLang = "ko" } = paramMap;
const { userId, userCompanyCode, userType, userLang = "ko" } = paramMap;
// 기존 Java의 selectUserMenuList 쿼리를 Raw Query로 포팅
// SUPER_ADMIN (company_code='*'): 모든 메뉴
// COMPANY_ADMIN: 자기 회사 메뉴 + 공통 메뉴 (company_code IS NULL)
// 일반 사용자: 권한이 있는 메뉴만
let companyFilter = "";
let queryParams: any[] = [userLang];
let paramIndex = 2;
if (userType === "SUPER_ADMIN" && userCompanyCode === "*") {
// SUPER_ADMIN: 모든 메뉴 표시
logger.info("✅ SUPER_ADMIN 모드: 모든 메뉴 표시");
companyFilter = "";
} else if (userType === "COMPANY_ADMIN") {
// COMPANY_ADMIN: 자기 회사 메뉴 + 공통 메뉴
companyFilter = `AND (MENU.COMPANY_CODE = $${paramIndex} OR MENU.COMPANY_CODE IS NULL)`;
queryParams.push(userCompanyCode);
paramIndex++;
logger.info(
`✅ COMPANY_ADMIN 모드: 회사 ${userCompanyCode} 메뉴 + 공통 메뉴 표시`
);
} else {
// 일반 사용자: 자기 회사 메뉴만
companyFilter = `AND (MENU.COMPANY_CODE = $${paramIndex} OR MENU.COMPANY_CODE IS NULL)`;
queryParams.push(userCompanyCode);
paramIndex++;
logger.info(
`✅ 일반 사용자 모드: 회사 ${userCompanyCode} 메뉴 + 공통 메뉴 표시`
);
}
// 기존 Java의 selectUserMenuList 쿼리를 Raw Query로 포팅 + 회사별 필터링
const menuList = await query<any>(
`
WITH RECURSIVE v_menu(
@@ -257,6 +326,8 @@ export class AdminService {
FROM MENU_INFO MENU
WHERE PARENT_OBJ_ID = 0
AND MENU_TYPE = 1
AND STATUS = 'active'
${companyFilter}
UNION ALL
@@ -279,7 +350,7 @@ export class AdminService {
MENU_SUB.OBJID = ANY(PATH)
FROM MENU_INFO MENU_SUB
JOIN V_MENU ON MENU_SUB.PARENT_OBJ_ID = V_MENU.OBJID
WHERE 1 = 1
WHERE MENU_SUB.STATUS = 'active'
)
SELECT
LEVEL AS LEV,
@@ -320,12 +391,18 @@ export class AdminService {
WHERE 1 = 1
ORDER BY PATH, SEQ
`,
[userLang]
queryParams
);
logger.info(`사용자 메뉴 목록 조회 결과: ${menuList.length}`);
logger.info(
`사용자 메뉴 목록 조회 결과: ${menuList.length}개 (userType: ${userType}, company: ${userCompanyCode})`
);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
logger.info("첫 번째 메뉴:", {
objid: menuList[0].objid,
name: menuList[0].menu_name_kor,
companyCode: menuList[0].company_code,
});
}
return menuList;