ERP-node/backend-node/src/services/adminService.ts

378 lines
12 KiB
TypeScript
Raw Normal View History

2025-08-21 09:41:46 +09:00
import { logger } from "../utils/logger";
import { query, queryOne } from "../database/db";
2025-08-21 09:41:46 +09:00
export class AdminService {
/**
*
*/
static async getAdminMenuList(paramMap: any): Promise<any[]> {
try {
logger.info("AdminService.getAdminMenuList 시작 - 파라미터:", paramMap);
2025-09-09 16:14:21 +09:00
const { userLang = "ko" } = paramMap;
2025-08-21 09:41:46 +09:00
// 기존 Java의 selectAdminMenuList 쿼리를 Raw Query로 포팅
// WITH RECURSIVE 쿼리 구현
const menuList = await query<any>(
`
2025-08-21 09:41:46 +09:00
WITH RECURSIVE v_menu(
LEVEL,
MENU_TYPE,
OBJID,
PARENT_OBJ_ID,
MENU_NAME_KOR,
MENU_URL,
MENU_DESC,
SEQ,
WRITER,
REGDATE,
STATUS,
SYSTEM_NAME,
COMPANY_CODE,
LANG_KEY,
LANG_KEY_DESC,
PATH,
CYCLE,
TRANSLATED_NAME,
TRANSLATED_DESC
) AS (
SELECT
1 AS LEVEL,
MENU.MENU_TYPE,
MENU.OBJID::numeric,
MENU.PARENT_OBJ_ID,
MENU.MENU_NAME_KOR,
MENU.MENU_URL,
MENU.MENU_DESC,
MENU.SEQ,
MENU.WRITER,
MENU.REGDATE,
MENU.STATUS,
MENU.SYSTEM_NAME,
MENU.COMPANY_CODE,
MENU.LANG_KEY,
MENU.LANG_KEY_DESC,
ARRAY [MENU.OBJID],
FALSE,
-- (우선순위: 회사별 > > )
COALESCE(
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU.LANG_KEY
AND (MLKM.company_code = MENU.COMPANY_CODE OR (MENU.COMPANY_CODE IS NULL AND MLKM.company_code = '*'))
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU.LANG_KEY
AND MLKM.company_code = '*'
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
MENU.MENU_NAME_KOR
),
-- (우선순위: 회사별 > > )
COALESCE(
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU.LANG_KEY_DESC
AND (MLKM.company_code = MENU.COMPANY_CODE OR (MENU.COMPANY_CODE IS NULL AND MLKM.company_code = '*'))
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU.LANG_KEY_DESC
AND MLKM.company_code = '*'
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
MENU.MENU_DESC
)
FROM MENU_INFO MENU
2025-09-09 16:14:21 +09:00
WHERE MENU_TYPE = 0
AND NOT EXISTS (
SELECT 1 FROM MENU_INFO parent_menu
WHERE parent_menu.OBJID = MENU.PARENT_OBJ_ID
)
2025-08-21 09:41:46 +09:00
UNION ALL
SELECT
V_MENU.LEVEL + 1,
MENU_SUB.MENU_TYPE,
MENU_SUB.OBJID,
MENU_SUB.PARENT_OBJ_ID,
MENU_SUB.MENU_NAME_KOR,
MENU_SUB.MENU_URL,
MENU_SUB.MENU_DESC,
MENU_SUB.SEQ,
MENU_SUB.WRITER,
MENU_SUB.REGDATE,
MENU_SUB.STATUS,
MENU_SUB.SYSTEM_NAME,
MENU_SUB.COMPANY_CODE,
MENU_SUB.LANG_KEY,
MENU_SUB.LANG_KEY_DESC,
PATH || MENU_SUB.SEQ::numeric,
MENU_SUB.OBJID = ANY(PATH),
-- (우선순위: 회사별 > > )
COALESCE(
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU_SUB.LANG_KEY
AND (MLKM.company_code = MENU_SUB.COMPANY_CODE OR (MENU_SUB.COMPANY_CODE IS NULL AND MLKM.company_code = '*'))
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU_SUB.LANG_KEY
AND MLKM.company_code = '*'
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
MENU_SUB.MENU_NAME_KOR
),
-- (우선순위: 회사별 > > )
COALESCE(
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU_SUB.LANG_KEY_DESC
AND (MLKM.company_code = MENU_SUB.COMPANY_CODE OR (MENU_SUB.COMPANY_CODE IS NULL AND MLKM.company_code = '*'))
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
(SELECT MLT.lang_text
FROM MULTI_LANG_KEY_MASTER MLKM
JOIN MULTI_LANG_TEXT MLT ON MLKM.key_id = MLT.key_id
WHERE MLKM.lang_key = MENU_SUB.LANG_KEY_DESC
AND MLKM.company_code = '*'
AND MLT.lang_code = $1
2025-08-21 09:41:46 +09:00
LIMIT 1),
MENU_SUB.MENU_DESC
)
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)
)
SELECT
LEVEL AS LEV,
CASE MENU_TYPE
WHEN '0' THEN 'admin'
WHEN '1' THEN 'user'
ELSE ''
END AS MENU_TYPE,
A.OBJID,
A.PARENT_OBJ_ID,
A.MENU_NAME_KOR,
LPAD(' ', 3 * (LEVEL - 1)) || A.MENU_NAME_KOR AS LPAD_MENU_NAME_KOR,
A.MENU_URL,
A.MENU_DESC,
A.SEQ,
A.WRITER,
TO_CHAR(A.REGDATE, 'YYYY-MM-DD') AS REGDATE,
A.STATUS,
A.COMPANY_CODE,
A.LANG_KEY,
A.LANG_KEY_DESC,
COALESCE(CM.COMPANY_NAME, '미지정') AS COMPANY_NAME,
A.TRANSLATED_NAME,
A.TRANSLATED_DESC,
CASE UPPER(A.STATUS)
WHEN 'ACTIVE' THEN '활성화'
WHEN 'INACTIVE' THEN '비활성화'
ELSE ''
END AS STATUS_TITLE
FROM v_menu A
LEFT JOIN COMPANY_MNG CM ON A.COMPANY_CODE = CM.COMPANY_CODE
WHERE 1 = 1
ORDER BY PATH, SEQ
`,
[userLang]
);
2025-08-21 09:41:46 +09:00
logger.info(`관리자 메뉴 목록 조회 결과: ${menuList.length}`);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
}
return menuList;
} catch (error) {
logger.error("AdminService.getAdminMenuList 오류:", error);
throw error;
}
}
/**
*
*/
static async getUserMenuList(paramMap: any): Promise<any[]> {
try {
logger.info("AdminService.getUserMenuList 시작 - 파라미터:", paramMap);
2025-09-09 16:14:21 +09:00
const { userLang = "ko" } = paramMap;
2025-08-21 09:41:46 +09:00
// 기존 Java의 selectUserMenuList 쿼리를 Raw Query로 포팅
const menuList = await query<any>(
`
2025-08-21 09:41:46 +09:00
WITH RECURSIVE v_menu(
LEVEL,
MENU_TYPE,
OBJID,
PARENT_OBJ_ID,
MENU_NAME_KOR,
MENU_URL,
MENU_DESC,
SEQ,
WRITER,
REGDATE,
STATUS,
COMPANY_CODE,
LANG_KEY,
LANG_KEY_DESC,
PATH,
CYCLE
) AS (
SELECT
1 AS LEVEL,
MENU_TYPE,
OBJID::numeric,
PARENT_OBJ_ID,
MENU_NAME_KOR,
MENU_URL,
MENU_DESC,
SEQ,
WRITER,
REGDATE,
STATUS,
COMPANY_CODE,
LANG_KEY,
LANG_KEY_DESC,
ARRAY [MENU.OBJID],
FALSE
FROM MENU_INFO MENU
WHERE PARENT_OBJ_ID = 0
AND MENU_TYPE = 1
UNION ALL
SELECT
V_MENU.LEVEL + 1,
MENU_SUB.MENU_TYPE,
MENU_SUB.OBJID,
MENU_SUB.PARENT_OBJ_ID,
MENU_SUB.MENU_NAME_KOR,
MENU_SUB.MENU_URL,
MENU_SUB.MENU_DESC,
MENU_SUB.SEQ,
MENU_SUB.WRITER,
MENU_SUB.REGDATE,
MENU_SUB.STATUS,
MENU_SUB.COMPANY_CODE,
MENU_SUB.LANG_KEY,
MENU_SUB.LANG_KEY_DESC,
PATH || MENU_SUB.SEQ::numeric,
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
)
SELECT
LEVEL AS LEV,
CASE MENU_TYPE
WHEN '0' THEN 'admin'
WHEN '1' THEN 'user'
ELSE ''
END AS MENU_TYPE,
A.OBJID,
A.PARENT_OBJ_ID,
A.MENU_NAME_KOR,
LPAD(' ', 3 * (LEVEL - 1)) || A.MENU_NAME_KOR AS LPAD_MENU_NAME_KOR,
A.MENU_URL,
A.MENU_DESC,
A.SEQ,
A.WRITER,
TO_CHAR(A.REGDATE, 'YYYY-MM-DD') AS REGDATE,
A.STATUS,
A.COMPANY_CODE,
A.LANG_KEY,
A.LANG_KEY_DESC,
COALESCE(CM.COMPANY_NAME, '미지정') AS COMPANY_NAME,
-- (우선순위: 번역 > )
COALESCE(MLT_NAME.lang_text, A.MENU_NAME_KOR) AS TRANSLATED_NAME,
-- (우선순위: 번역 > )
COALESCE(MLT_DESC.lang_text, A.MENU_DESC) AS TRANSLATED_DESC,
CASE UPPER(A.STATUS)
WHEN 'ACTIVE' THEN '활성화'
WHEN 'INACTIVE' THEN '비활성화'
ELSE ''
END AS STATUS_TITLE
FROM v_menu A
LEFT JOIN COMPANY_MNG CM ON A.COMPANY_CODE = CM.COMPANY_CODE
LEFT JOIN MULTI_LANG_KEY_MASTER MLKM_NAME ON A.LANG_KEY = MLKM_NAME.lang_key
LEFT JOIN MULTI_LANG_TEXT MLT_NAME ON MLKM_NAME.key_id = MLT_NAME.key_id AND MLT_NAME.lang_code = $1
2025-08-21 09:41:46 +09:00
LEFT JOIN MULTI_LANG_KEY_MASTER MLKM_DESC ON A.LANG_KEY_DESC = MLKM_DESC.lang_key
LEFT JOIN MULTI_LANG_TEXT MLT_DESC ON MLKM_DESC.key_id = MLT_DESC.key_id AND MLT_DESC.lang_code = $1
2025-08-21 09:41:46 +09:00
WHERE 1 = 1
ORDER BY PATH, SEQ
`,
[userLang]
);
2025-08-21 09:41:46 +09:00
logger.info(`사용자 메뉴 목록 조회 결과: ${menuList.length}`);
if (menuList.length > 0) {
logger.info("첫 번째 메뉴:", menuList[0]);
}
return menuList;
} catch (error) {
logger.error("AdminService.getUserMenuList 오류:", error);
throw error;
}
}
/**
*
*/
static async getMenuInfo(menuId: string): Promise<any> {
try {
logger.info(`AdminService.getMenuInfo 시작 - menuId: ${menuId}`);
// Raw Query를 사용한 메뉴 정보 조회 (회사 정보 포함)
const menuResult = await query<any>(
`SELECT
m.*,
c.company_name
FROM menu_info m
LEFT JOIN company_mng c ON m.company_code = c.company_code
WHERE m.objid = $1::numeric`,
[menuId]
);
2025-08-21 09:41:46 +09:00
if (!menuResult || menuResult.length === 0) {
2025-08-21 09:41:46 +09:00
return null;
}
const menuInfo = menuResult[0];
// 응답 형식 조정 (기존 형식과 호환성 유지)
const result = {
...menuInfo,
objid: menuInfo.objid?.toString(),
menu_type: menuInfo.menu_type?.toString(),
parent_obj_id: menuInfo.parent_obj_id?.toString(),
seq: menuInfo.seq?.toString(),
company_name: menuInfo.company_name || "미지정",
};
logger.info("메뉴 정보 조회 결과:", result);
return result;
2025-08-21 09:41:46 +09:00
} catch (error) {
logger.error("AdminService.getMenuInfo 오류:", error);
throw error;
}
}
}