Merge branch 'main' of http://39.117.244.52:3000/kjs/ERP-node into feat/rest-api
This commit is contained in:
commit
2c30d40623
|
|
@ -1,554 +0,0 @@
|
||||||
import { query } from "../database/db";
|
|
||||||
import { logger } from "../utils/logger";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 인터페이스
|
|
||||||
*/
|
|
||||||
export interface RoleGroup {
|
|
||||||
objid: number;
|
|
||||||
authName: string;
|
|
||||||
authCode: string;
|
|
||||||
companyCode: string;
|
|
||||||
status: string;
|
|
||||||
writer: string;
|
|
||||||
regdate: Date;
|
|
||||||
memberCount?: number;
|
|
||||||
menuCount?: number;
|
|
||||||
memberNames?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 멤버 인터페이스
|
|
||||||
*/
|
|
||||||
export interface RoleMember {
|
|
||||||
objid: number;
|
|
||||||
masterObjid: number;
|
|
||||||
userId: string;
|
|
||||||
userName?: string;
|
|
||||||
deptName?: string;
|
|
||||||
positionName?: string;
|
|
||||||
writer: string;
|
|
||||||
regdate: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 메뉴 권한 인터페이스
|
|
||||||
*/
|
|
||||||
export interface MenuPermission {
|
|
||||||
objid: number;
|
|
||||||
menuObjid: number;
|
|
||||||
authObjid: number;
|
|
||||||
menuName?: string;
|
|
||||||
createYn: string;
|
|
||||||
readYn: string;
|
|
||||||
updateYn: string;
|
|
||||||
deleteYn: string;
|
|
||||||
writer: string;
|
|
||||||
regdate: Date;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 서비스
|
|
||||||
*/
|
|
||||||
export class RoleService {
|
|
||||||
/**
|
|
||||||
* 회사별 권한 그룹 목록 조회
|
|
||||||
* @param companyCode - 회사 코드 (undefined 시 전체 조회)
|
|
||||||
* @param search - 검색어
|
|
||||||
*/
|
|
||||||
static async getRoleGroups(
|
|
||||||
companyCode?: string,
|
|
||||||
search?: string
|
|
||||||
): Promise<RoleGroup[]> {
|
|
||||||
try {
|
|
||||||
let sql = `
|
|
||||||
SELECT
|
|
||||||
objid,
|
|
||||||
auth_name AS "authName",
|
|
||||||
auth_code AS "authCode",
|
|
||||||
company_code AS "companyCode",
|
|
||||||
status,
|
|
||||||
writer,
|
|
||||||
regdate,
|
|
||||||
(SELECT COUNT(*) FROM authority_sub_user asu WHERE asu.master_objid = am.objid) AS "memberCount",
|
|
||||||
(SELECT COUNT(*) FROM rel_menu_auth rma WHERE rma.auth_objid = am.objid) AS "menuCount",
|
|
||||||
(SELECT STRING_AGG(ui.user_name, ', ' ORDER BY ui.user_name)
|
|
||||||
FROM authority_sub_user asu
|
|
||||||
JOIN user_info ui ON asu.user_id = ui.user_id
|
|
||||||
WHERE asu.master_objid = am.objid) AS "memberNames"
|
|
||||||
FROM authority_master am
|
|
||||||
WHERE 1=1
|
|
||||||
`;
|
|
||||||
|
|
||||||
const params: any[] = [];
|
|
||||||
let paramIndex = 1;
|
|
||||||
|
|
||||||
// 회사 코드 필터 (companyCode가 undefined면 전체 조회)
|
|
||||||
if (companyCode) {
|
|
||||||
sql += ` AND company_code = $${paramIndex}`;
|
|
||||||
params.push(companyCode);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 검색어 필터
|
|
||||||
if (search && search.trim()) {
|
|
||||||
sql += ` AND (auth_name ILIKE $${paramIndex} OR auth_code ILIKE $${paramIndex})`;
|
|
||||||
params.push(`%${search.trim()}%`);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
sql += ` ORDER BY regdate DESC`;
|
|
||||||
|
|
||||||
logger.info("권한 그룹 조회 SQL", { sql, params });
|
|
||||||
const result = await query<RoleGroup>(sql, params);
|
|
||||||
logger.info("권한 그룹 조회 결과", { count: result.length });
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 목록 조회 실패", { error, companyCode, search });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 상세 조회
|
|
||||||
*/
|
|
||||||
static async getRoleGroupById(objid: number): Promise<RoleGroup | null> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
SELECT
|
|
||||||
objid,
|
|
||||||
auth_name AS "authName",
|
|
||||||
auth_code AS "authCode",
|
|
||||||
company_code AS "companyCode",
|
|
||||||
status,
|
|
||||||
writer,
|
|
||||||
regdate
|
|
||||||
FROM authority_master
|
|
||||||
WHERE objid = $1
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<RoleGroup>(sql, [objid]);
|
|
||||||
return result.length > 0 ? result[0] : null;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 상세 조회 실패", { error, objid });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 생성
|
|
||||||
*/
|
|
||||||
static async createRoleGroup(data: {
|
|
||||||
authName: string;
|
|
||||||
authCode: string;
|
|
||||||
companyCode: string;
|
|
||||||
writer: string;
|
|
||||||
}): Promise<RoleGroup> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
INSERT INTO authority_master (objid, auth_name, auth_code, company_code, status, writer, regdate)
|
|
||||||
VALUES (nextval('seq_authority_master'), $1, $2, $3, 'active', $4, NOW())
|
|
||||||
RETURNING objid, auth_name AS "authName", auth_code AS "authCode",
|
|
||||||
company_code AS "companyCode", status, writer, regdate
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<RoleGroup>(sql, [
|
|
||||||
data.authName,
|
|
||||||
data.authCode,
|
|
||||||
data.companyCode,
|
|
||||||
data.writer,
|
|
||||||
]);
|
|
||||||
|
|
||||||
logger.info("권한 그룹 생성 성공", {
|
|
||||||
objid: result[0].objid,
|
|
||||||
authName: data.authName,
|
|
||||||
});
|
|
||||||
return result[0];
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 생성 실패", { error, data });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 수정
|
|
||||||
*/
|
|
||||||
static async updateRoleGroup(
|
|
||||||
objid: number,
|
|
||||||
data: {
|
|
||||||
authName?: string;
|
|
||||||
authCode?: string;
|
|
||||||
status?: string;
|
|
||||||
}
|
|
||||||
): Promise<RoleGroup> {
|
|
||||||
try {
|
|
||||||
const updates: string[] = [];
|
|
||||||
const params: any[] = [];
|
|
||||||
let paramIndex = 1;
|
|
||||||
|
|
||||||
if (data.authName !== undefined) {
|
|
||||||
updates.push(`auth_name = $${paramIndex}`);
|
|
||||||
params.push(data.authName);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.authCode !== undefined) {
|
|
||||||
updates.push(`auth_code = $${paramIndex}`);
|
|
||||||
params.push(data.authCode);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.status !== undefined) {
|
|
||||||
updates.push(`status = $${paramIndex}`);
|
|
||||||
params.push(data.status);
|
|
||||||
paramIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (updates.length === 0) {
|
|
||||||
throw new Error("수정할 데이터가 없습니다");
|
|
||||||
}
|
|
||||||
|
|
||||||
params.push(objid);
|
|
||||||
|
|
||||||
const sql = `
|
|
||||||
UPDATE authority_master
|
|
||||||
SET ${updates.join(", ")}
|
|
||||||
WHERE objid = $${paramIndex}
|
|
||||||
RETURNING objid, auth_name AS "authName", auth_code AS "authCode",
|
|
||||||
company_code AS "companyCode", status, writer, regdate
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<RoleGroup>(sql, params);
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("권한 그룹을 찾을 수 없습니다");
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("권한 그룹 수정 성공", { objid, updates });
|
|
||||||
return result[0];
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 수정 실패", { error, objid, data });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 삭제
|
|
||||||
*/
|
|
||||||
static async deleteRoleGroup(objid: number): Promise<void> {
|
|
||||||
try {
|
|
||||||
// CASCADE로 연결된 데이터도 함께 삭제됨 (authority_sub_user, rel_menu_auth)
|
|
||||||
await query("DELETE FROM authority_master WHERE objid = $1", [objid]);
|
|
||||||
logger.info("권한 그룹 삭제 성공", { objid });
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 삭제 실패", { error, objid });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 멤버 목록 조회
|
|
||||||
*/
|
|
||||||
static async getRoleMembers(masterObjid: number): Promise<RoleMember[]> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
SELECT
|
|
||||||
asu.objid,
|
|
||||||
asu.master_objid AS "masterObjid",
|
|
||||||
asu.user_id AS "userId",
|
|
||||||
ui.user_name AS "userName",
|
|
||||||
ui.dept_name AS "deptName",
|
|
||||||
ui.position_name AS "positionName",
|
|
||||||
asu.writer,
|
|
||||||
asu.regdate
|
|
||||||
FROM authority_sub_user asu
|
|
||||||
JOIN user_info ui ON asu.user_id = ui.user_id
|
|
||||||
WHERE asu.master_objid = $1
|
|
||||||
ORDER BY ui.user_name
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<RoleMember>(sql, [masterObjid]);
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 멤버 조회 실패", { error, masterObjid });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 멤버 추가 (여러 명)
|
|
||||||
*/
|
|
||||||
static async addRoleMembers(
|
|
||||||
masterObjid: number,
|
|
||||||
userIds: string[],
|
|
||||||
writer: string
|
|
||||||
): Promise<void> {
|
|
||||||
try {
|
|
||||||
// 이미 존재하는 멤버 제외
|
|
||||||
const existingSql = `
|
|
||||||
SELECT user_id
|
|
||||||
FROM authority_sub_user
|
|
||||||
WHERE master_objid = $1 AND user_id = ANY($2)
|
|
||||||
`;
|
|
||||||
const existing = await query<{ user_id: string }>(existingSql, [
|
|
||||||
masterObjid,
|
|
||||||
userIds,
|
|
||||||
]);
|
|
||||||
const existingIds = new Set(
|
|
||||||
existing.map((row: { user_id: string }) => row.user_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
const newUserIds = userIds.filter((userId) => !existingIds.has(userId));
|
|
||||||
|
|
||||||
if (newUserIds.length === 0) {
|
|
||||||
logger.info("추가할 신규 멤버가 없습니다", { masterObjid, userIds });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 배치 삽입
|
|
||||||
const values = newUserIds
|
|
||||||
.map(
|
|
||||||
(_, index) =>
|
|
||||||
`(nextval('seq_authority_sub_user'), $1, $${index + 2}, $${newUserIds.length + 2}, NOW())`
|
|
||||||
)
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
const sql = `
|
|
||||||
INSERT INTO authority_sub_user (objid, master_objid, user_id, writer, regdate)
|
|
||||||
VALUES ${values}
|
|
||||||
`;
|
|
||||||
|
|
||||||
await query(sql, [masterObjid, ...newUserIds, writer]);
|
|
||||||
|
|
||||||
// 히스토리 기록
|
|
||||||
for (const userId of newUserIds) {
|
|
||||||
await this.insertAuthorityHistory(masterObjid, userId, "ADD", writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("권한 그룹 멤버 추가 성공", {
|
|
||||||
masterObjid,
|
|
||||||
count: newUserIds.length,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 멤버 추가 실패", { error, masterObjid, userIds });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 그룹 멤버 제거 (여러 명)
|
|
||||||
*/
|
|
||||||
static async removeRoleMembers(
|
|
||||||
masterObjid: number,
|
|
||||||
userIds: string[],
|
|
||||||
writer: string
|
|
||||||
): Promise<void> {
|
|
||||||
try {
|
|
||||||
await query(
|
|
||||||
"DELETE FROM authority_sub_user WHERE master_objid = $1 AND user_id = ANY($2)",
|
|
||||||
[masterObjid, userIds]
|
|
||||||
);
|
|
||||||
|
|
||||||
// 히스토리 기록
|
|
||||||
for (const userId of userIds) {
|
|
||||||
await this.insertAuthorityHistory(
|
|
||||||
masterObjid,
|
|
||||||
userId,
|
|
||||||
"REMOVE",
|
|
||||||
writer
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("권한 그룹 멤버 제거 성공", {
|
|
||||||
masterObjid,
|
|
||||||
count: userIds.length,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 그룹 멤버 제거 실패", { error, masterObjid, userIds });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 권한 히스토리 기록
|
|
||||||
*/
|
|
||||||
private static async insertAuthorityHistory(
|
|
||||||
masterObjid: number,
|
|
||||||
userId: string,
|
|
||||||
historyType: "ADD" | "REMOVE",
|
|
||||||
writer: string
|
|
||||||
): Promise<void> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
INSERT INTO authority_master_history
|
|
||||||
(objid, parent_objid, parent_name, parent_code, user_id, active, history_type, writer, reg_date)
|
|
||||||
SELECT
|
|
||||||
nextval('seq_authority_master'),
|
|
||||||
$1,
|
|
||||||
am.auth_name,
|
|
||||||
am.auth_code,
|
|
||||||
$2,
|
|
||||||
am.status,
|
|
||||||
$3,
|
|
||||||
$4,
|
|
||||||
NOW()
|
|
||||||
FROM authority_master am
|
|
||||||
WHERE am.objid = $1
|
|
||||||
`;
|
|
||||||
|
|
||||||
await query(sql, [masterObjid, userId, historyType, writer]);
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("권한 히스토리 기록 실패", {
|
|
||||||
error,
|
|
||||||
masterObjid,
|
|
||||||
userId,
|
|
||||||
historyType,
|
|
||||||
});
|
|
||||||
// 히스토리 기록 실패는 메인 작업을 중단하지 않음
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 메뉴 권한 목록 조회
|
|
||||||
*/
|
|
||||||
static async getMenuPermissions(
|
|
||||||
authObjid: number
|
|
||||||
): Promise<MenuPermission[]> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
SELECT
|
|
||||||
rma.objid,
|
|
||||||
rma.menu_objid AS "menuObjid",
|
|
||||||
rma.auth_objid AS "authObjid",
|
|
||||||
mi.menu_name_kor AS "menuName",
|
|
||||||
mi.menu_code AS "menuCode",
|
|
||||||
mi.menu_url AS "menuUrl",
|
|
||||||
rma.create_yn AS "createYn",
|
|
||||||
rma.read_yn AS "readYn",
|
|
||||||
rma.update_yn AS "updateYn",
|
|
||||||
rma.delete_yn AS "deleteYn",
|
|
||||||
rma.execute_yn AS "executeYn",
|
|
||||||
rma.export_yn AS "exportYn",
|
|
||||||
rma.writer,
|
|
||||||
rma.regdate
|
|
||||||
FROM rel_menu_auth rma
|
|
||||||
LEFT JOIN menu_info mi ON rma.menu_objid = mi.objid
|
|
||||||
WHERE rma.auth_objid = $1
|
|
||||||
ORDER BY mi.menu_name_kor
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<MenuPermission>(sql, [authObjid]);
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("메뉴 권한 조회 실패", { error, authObjid });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 메뉴 권한 설정 (여러 메뉴)
|
|
||||||
*/
|
|
||||||
static async setMenuPermissions(
|
|
||||||
authObjid: number,
|
|
||||||
permissions: Array<{
|
|
||||||
menuObjid: number;
|
|
||||||
createYn: string;
|
|
||||||
readYn: string;
|
|
||||||
updateYn: string;
|
|
||||||
deleteYn: string;
|
|
||||||
}>,
|
|
||||||
writer: string
|
|
||||||
): Promise<void> {
|
|
||||||
try {
|
|
||||||
// 기존 권한 삭제
|
|
||||||
await query("DELETE FROM rel_menu_auth WHERE auth_objid = $1", [
|
|
||||||
authObjid,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 새로운 권한 삽입
|
|
||||||
if (permissions.length > 0) {
|
|
||||||
const values = permissions
|
|
||||||
.map(
|
|
||||||
(_, index) =>
|
|
||||||
`(nextval('seq_rel_menu_auth'), $${index * 5 + 2}, $1, $${index * 5 + 3}, $${index * 5 + 4}, $${index * 5 + 5}, $${index * 5 + 6}, $${permissions.length * 5 + 2}, NOW())`
|
|
||||||
)
|
|
||||||
.join(", ");
|
|
||||||
|
|
||||||
const params = permissions.flatMap((p) => [
|
|
||||||
p.menuObjid,
|
|
||||||
p.createYn,
|
|
||||||
p.readYn,
|
|
||||||
p.updateYn,
|
|
||||||
p.deleteYn,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const sql = `
|
|
||||||
INSERT INTO rel_menu_auth (objid, menu_objid, auth_objid, create_yn, read_yn, update_yn, delete_yn, writer, regdate)
|
|
||||||
VALUES ${values}
|
|
||||||
`;
|
|
||||||
|
|
||||||
await query(sql, [authObjid, ...params, writer]);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.info("메뉴 권한 설정 성공", {
|
|
||||||
authObjid,
|
|
||||||
count: permissions.length,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("메뉴 권한 설정 실패", { error, authObjid, permissions });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 사용자가 속한 권한 그룹 목록 조회
|
|
||||||
*/
|
|
||||||
static async getUserRoleGroups(
|
|
||||||
userId: string,
|
|
||||||
companyCode: string
|
|
||||||
): Promise<RoleGroup[]> {
|
|
||||||
try {
|
|
||||||
const sql = `
|
|
||||||
SELECT
|
|
||||||
am.objid,
|
|
||||||
am.auth_name AS "authName",
|
|
||||||
am.auth_code AS "authCode",
|
|
||||||
am.company_code AS "companyCode",
|
|
||||||
am.status,
|
|
||||||
am.writer,
|
|
||||||
am.regdate
|
|
||||||
FROM authority_master am
|
|
||||||
JOIN authority_sub_user asu ON am.objid = asu.master_objid
|
|
||||||
WHERE asu.user_id = $1
|
|
||||||
AND am.company_code = $2
|
|
||||||
AND am.status = 'active'
|
|
||||||
ORDER BY am.auth_name
|
|
||||||
`;
|
|
||||||
|
|
||||||
const result = await query<RoleGroup>(sql, [userId, companyCode]);
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("사용자 권한 그룹 조회 실패", {
|
|
||||||
error,
|
|
||||||
userId,
|
|
||||||
companyCode,
|
|
||||||
});
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 전체 메뉴 목록 조회 (권한 설정용)
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* 전체 메뉴 목록 조회 (권한 설정용)
|
|
||||||
*/
|
|
||||||
static async getAllMenus(companyCode?: string): Promise<any[]> {
|
|
||||||
try {
|
|
||||||
logger.info("🔍 전체 메뉴 목록 조회 시작", { companyCode });
|
|
||||||
|
|
||||||
let whereConditions: string[] = ["status = 'active'"];
|
|
||||||
const params: any[] = [];
|
|
||||||
let paramIndex = 1;
|
|
||||||
|
|
||||||
// 회사 코드 필터 (선택적)
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/**
|
|
||||||
* 전체 메뉴 목록 조회 (권한 설정용)
|
|
||||||
*/
|
|
||||||
static async getAllMenus(companyCode?: string): Promise<any[]> {
|
|
||||||
try {
|
|
||||||
logger.info("🔍 전체 메뉴 목록 조회 시작", { companyCode });
|
|
||||||
|
|
||||||
let whereConditions: string[] = ["status = 'active'"];
|
|
||||||
const params: any[] = [];
|
|
||||||
let paramIndex = 1;
|
|
||||||
|
|
||||||
// 회사 코드 필터 (선택적)
|
|
||||||
// 공통 메뉴(*)와 특정 회사 메뉴를 모두 조회
|
|
||||||
if (companyCode) {
|
|
||||||
whereConditions.push(`(company_code = \$${paramIndex} OR company_code = '*')`);
|
|
||||||
params.push(companyCode);
|
|
||||||
paramIndex++;
|
|
||||||
logger.info("📋 회사 코드 필터 적용", { companyCode });
|
|
||||||
} else {
|
|
||||||
logger.info("📋 회사 코드 필터 없음 (전체 조회)");
|
|
||||||
}
|
|
||||||
|
|
||||||
const whereClause = whereConditions.join(" AND ");
|
|
||||||
|
|
||||||
const sql = `
|
|
||||||
SELECT
|
|
||||||
objid,
|
|
||||||
menu_name_kor AS "menuName",
|
|
||||||
menu_name_eng AS "menuNameEng",
|
|
||||||
menu_code AS "menuCode",
|
|
||||||
menu_url AS "menuUrl",
|
|
||||||
menu_type AS "menuType",
|
|
||||||
parent_obj_id AS "parentObjid",
|
|
||||||
seq AS "sortOrder",
|
|
||||||
company_code AS "companyCode"
|
|
||||||
FROM menu_info
|
|
||||||
WHERE ${whereClause}
|
|
||||||
ORDER BY seq, menu_name_kor
|
|
||||||
`;
|
|
||||||
|
|
||||||
logger.info("🔍 SQL 쿼리 실행", {
|
|
||||||
whereClause,
|
|
||||||
params,
|
|
||||||
sql: sql.substring(0, 200) + "...",
|
|
||||||
});
|
|
||||||
|
|
||||||
const result = await query<any>(sql, params);
|
|
||||||
|
|
||||||
logger.info("✅ 메뉴 목록 조회 성공", {
|
|
||||||
count: result.length,
|
|
||||||
companyCode,
|
|
||||||
menus: result.map((m) => ({
|
|
||||||
objid: m.objid,
|
|
||||||
name: m.menuName,
|
|
||||||
code: m.menuCode,
|
|
||||||
companyCode: m.companyCode,
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("❌ 메뉴 목록 조회 실패", { error, companyCode });
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue