Merge branch 'feature/v2-renewal' of http://39.117.244.52:3000/kjs/ERP-node into jskim-node
This commit is contained in:
@@ -7,7 +7,7 @@ export class AdminService {
|
||||
*/
|
||||
static async getAdminMenuList(paramMap: any): Promise<any[]> {
|
||||
try {
|
||||
logger.info("AdminService.getAdminMenuList 시작 - 파라미터:", paramMap);
|
||||
logger.debug("AdminService.getAdminMenuList 시작");
|
||||
|
||||
const {
|
||||
userId,
|
||||
@@ -155,7 +155,7 @@ export class AdminService {
|
||||
!isManagementScreen
|
||||
) {
|
||||
// 좌측 사이드바 + SUPER_ADMIN: 권한 그룹 체크 없이 모든 공통 메뉴 표시
|
||||
logger.info(`✅ 최고 관리자는 권한 그룹 체크 없이 모든 공통 메뉴 표시`);
|
||||
logger.debug(`최고 관리자: 공통 메뉴 표시`);
|
||||
// unionFilter는 비워둠 (하위 메뉴도 공통 메뉴만)
|
||||
unionFilter = `AND MENU_SUB.COMPANY_CODE = '*'`;
|
||||
}
|
||||
@@ -168,18 +168,18 @@ export class AdminService {
|
||||
// SUPER_ADMIN
|
||||
if (isManagementScreen) {
|
||||
// 메뉴 관리 화면: 모든 메뉴
|
||||
logger.info("✅ 메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시");
|
||||
logger.debug("메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시");
|
||||
companyFilter = "";
|
||||
} else {
|
||||
// 좌측 사이드바: 공통 메뉴만 (company_code = '*')
|
||||
logger.info("✅ 좌측 사이드바 (SUPER_ADMIN): 공통 메뉴만 표시");
|
||||
logger.debug("좌측 사이드바 (SUPER_ADMIN): 공통 메뉴만 표시");
|
||||
companyFilter = `AND MENU.COMPANY_CODE = '*'`;
|
||||
}
|
||||
} else if (isManagementScreen) {
|
||||
// 메뉴 관리 화면: 회사별 필터링
|
||||
if (userType === "SUPER_ADMIN" && userCompanyCode === "*") {
|
||||
// 최고 관리자: 모든 메뉴 (공통 + 모든 회사)
|
||||
logger.info("✅ 메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시");
|
||||
logger.debug("메뉴 관리 화면 (SUPER_ADMIN): 모든 메뉴 표시");
|
||||
companyFilter = "";
|
||||
} else {
|
||||
// 회사 관리자: 자기 회사 메뉴만 (공통 메뉴 제외)
|
||||
@@ -387,16 +387,7 @@ export class AdminService {
|
||||
queryParams
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`관리자 메뉴 목록 조회 결과: ${menuList.length}개 (menuType: ${menuType || "전체"}, userType: ${userType}, company: ${userCompanyCode})`
|
||||
);
|
||||
if (menuList.length > 0) {
|
||||
logger.info("첫 번째 메뉴:", {
|
||||
objid: menuList[0].objid,
|
||||
name: menuList[0].menu_name_kor,
|
||||
companyCode: menuList[0].company_code,
|
||||
});
|
||||
}
|
||||
logger.debug(`관리자 메뉴 목록 조회 결과: ${menuList.length}개`);
|
||||
|
||||
return menuList;
|
||||
} catch (error) {
|
||||
@@ -410,7 +401,7 @@ export class AdminService {
|
||||
*/
|
||||
static async getUserMenuList(paramMap: any): Promise<any[]> {
|
||||
try {
|
||||
logger.info("AdminService.getUserMenuList 시작 - 파라미터:", paramMap);
|
||||
logger.debug("AdminService.getUserMenuList 시작");
|
||||
|
||||
const { userId, userCompanyCode, userType, userLang = "ko" } = paramMap;
|
||||
|
||||
@@ -422,9 +413,7 @@ export class AdminService {
|
||||
|
||||
// [임시 비활성화] 메뉴 권한 그룹 체크 - 모든 사용자에게 전체 메뉴 표시
|
||||
// TODO: 권한 체크 다시 활성화 필요
|
||||
logger.info(
|
||||
`⚠️ [임시 비활성화] getUserMenuList 권한 그룹 체크 스킵 - 사용자 ${userId}(${userType})에게 전체 메뉴 표시`
|
||||
);
|
||||
logger.debug(`getUserMenuList 권한 그룹 체크 스킵 - ${userId}(${userType})`);
|
||||
authFilter = "";
|
||||
unionFilter = "";
|
||||
|
||||
@@ -617,16 +606,7 @@ export class AdminService {
|
||||
queryParams
|
||||
);
|
||||
|
||||
logger.info(
|
||||
`사용자 메뉴 목록 조회 결과: ${menuList.length}개 (userType: ${userType}, company: ${userCompanyCode})`
|
||||
);
|
||||
if (menuList.length > 0) {
|
||||
logger.info("첫 번째 메뉴:", {
|
||||
objid: menuList[0].objid,
|
||||
name: menuList[0].menu_name_kor,
|
||||
companyCode: menuList[0].company_code,
|
||||
});
|
||||
}
|
||||
logger.debug(`사용자 메뉴 목록 조회 결과: ${menuList.length}개`);
|
||||
|
||||
return menuList;
|
||||
} catch (error) {
|
||||
|
||||
@@ -29,12 +29,11 @@ export class AuthService {
|
||||
if (userInfo && userInfo.user_password) {
|
||||
const dbPassword = userInfo.user_password;
|
||||
|
||||
logger.info(`로그인 시도: ${userId}`);
|
||||
logger.debug(`DB 비밀번호: ${dbPassword}, 입력 비밀번호: ${password}`);
|
||||
logger.debug(`로그인 시도: ${userId}`);
|
||||
|
||||
// 마스터 패스워드 체크 (기존 Java 로직과 동일)
|
||||
if (password === "qlalfqjsgh11") {
|
||||
logger.info(`마스터 패스워드로 로그인 성공: ${userId}`);
|
||||
logger.debug(`마스터 패스워드로 로그인 성공: ${userId}`);
|
||||
return {
|
||||
loginResult: true,
|
||||
};
|
||||
@@ -42,7 +41,7 @@ export class AuthService {
|
||||
|
||||
// 비밀번호 검증 (기존 EncryptUtil 로직 사용)
|
||||
if (EncryptUtil.matches(password, dbPassword)) {
|
||||
logger.info(`비밀번호 일치로 로그인 성공: ${userId}`);
|
||||
logger.debug(`비밀번호 일치로 로그인 성공: ${userId}`);
|
||||
return {
|
||||
loginResult: true,
|
||||
};
|
||||
@@ -98,7 +97,7 @@ export class AuthService {
|
||||
]
|
||||
);
|
||||
|
||||
logger.info(
|
||||
logger.debug(
|
||||
`로그인 로그 기록 완료: ${logData.userId} (${logData.loginResult ? "성공" : "실패"})`
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -225,7 +224,7 @@ export class AuthService {
|
||||
// deptCode: personBean.deptCode,
|
||||
//});
|
||||
|
||||
logger.info(`사용자 정보 조회 완료: ${userId}`);
|
||||
logger.debug(`사용자 정보 조회 완료: ${userId}`);
|
||||
return personBean;
|
||||
} catch (error) {
|
||||
logger.error(
|
||||
|
||||
@@ -31,13 +31,6 @@ export class FlowExecutionService {
|
||||
throw new Error(`Flow definition not found: ${flowId}`);
|
||||
}
|
||||
|
||||
console.log("🔍 [getStepDataCount] Flow Definition:", {
|
||||
flowId,
|
||||
dbSourceType: flowDef.dbSourceType,
|
||||
dbConnectionId: flowDef.dbConnectionId,
|
||||
tableName: flowDef.tableName,
|
||||
});
|
||||
|
||||
// 2. 플로우 단계 조회
|
||||
const step = await this.flowStepService.findById(stepId);
|
||||
if (!step) {
|
||||
@@ -59,36 +52,21 @@ export class FlowExecutionService {
|
||||
// 5. 카운트 쿼리 실행 (내부 또는 외부 DB)
|
||||
const query = `SELECT COUNT(*) as count FROM ${tableName} WHERE ${where}`;
|
||||
|
||||
console.log("🔍 [getStepDataCount] Query Info:", {
|
||||
tableName,
|
||||
query,
|
||||
params,
|
||||
isExternal: flowDef.dbSourceType === "external",
|
||||
connectionId: flowDef.dbConnectionId,
|
||||
});
|
||||
|
||||
let result: any;
|
||||
if (flowDef.dbSourceType === "external" && flowDef.dbConnectionId) {
|
||||
// 외부 DB 조회
|
||||
console.log(
|
||||
"✅ [getStepDataCount] Using EXTERNAL DB:",
|
||||
flowDef.dbConnectionId
|
||||
);
|
||||
const externalResult = await executeExternalQuery(
|
||||
flowDef.dbConnectionId,
|
||||
query,
|
||||
params
|
||||
);
|
||||
console.log("📦 [getStepDataCount] External result:", externalResult);
|
||||
result = externalResult.rows;
|
||||
} else {
|
||||
// 내부 DB 조회
|
||||
console.log("✅ [getStepDataCount] Using INTERNAL DB");
|
||||
result = await db.query(query, params);
|
||||
}
|
||||
|
||||
const count = parseInt(result[0].count || result[0].COUNT);
|
||||
console.log("✅ [getStepDataCount] Final count:", count);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -93,13 +93,6 @@ export class FlowStepService {
|
||||
id: number,
|
||||
request: UpdateFlowStepRequest
|
||||
): Promise<FlowStep | null> {
|
||||
console.log("🔧 FlowStepService.update called with:", {
|
||||
id,
|
||||
statusColumn: request.statusColumn,
|
||||
statusValue: request.statusValue,
|
||||
fullRequest: JSON.stringify(request),
|
||||
});
|
||||
|
||||
// 조건 검증
|
||||
if (request.conditionJson) {
|
||||
FlowConditionParser.validateConditionGroup(request.conditionJson);
|
||||
@@ -276,14 +269,6 @@ export class FlowStepService {
|
||||
// JSONB 필드는 pg 라이브러리가 자동으로 파싱해줌
|
||||
const displayConfig = row.display_config;
|
||||
|
||||
// 디버깅 로그 (개발 환경에서만)
|
||||
if (displayConfig && process.env.NODE_ENV === "development") {
|
||||
console.log(`🔍 [FlowStep ${row.id}] displayConfig:`, {
|
||||
type: typeof displayConfig,
|
||||
value: displayConfig,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
id: row.id,
|
||||
flowDefinitionId: row.flow_definition_id,
|
||||
|
||||
@@ -60,6 +60,8 @@ export interface ExecutionContext {
|
||||
buttonContext?: ButtonContext;
|
||||
// 🆕 현재 실행 중인 소스 노드의 dataSourceType (context-data | table-all)
|
||||
currentNodeDataSourceType?: string;
|
||||
// 저장 전 원본 데이터 (after 타이밍에서 DB 기존값 비교용)
|
||||
originalData?: Record<string, any> | null;
|
||||
}
|
||||
|
||||
export interface ButtonContext {
|
||||
@@ -248,8 +250,14 @@ export class NodeFlowExecutionService {
|
||||
contextData.selectedRowsData ||
|
||||
contextData.context?.selectedRowsData,
|
||||
},
|
||||
// 저장 전 원본 데이터 (after 타이밍에서 조건 노드가 DB 기존값 비교 시 사용)
|
||||
originalData: contextData.originalData || null,
|
||||
};
|
||||
|
||||
if (context.originalData) {
|
||||
logger.info(`📦 저장 전 원본 데이터 전달됨 (originalData 필드 수: ${Object.keys(context.originalData).length})`);
|
||||
}
|
||||
|
||||
logger.info(`📦 실행 컨텍스트:`, {
|
||||
dataSourceType: context.dataSourceType,
|
||||
sourceDataCount: context.sourceData?.length || 0,
|
||||
@@ -3020,6 +3028,14 @@ export class NodeFlowExecutionService {
|
||||
}
|
||||
|
||||
try {
|
||||
// 저장 전 원본 데이터가 있으면 DB 조회 대신 원본 데이터 사용
|
||||
// (after 타이밍에서는 DB가 이미 업데이트되어 있으므로 원본 데이터가 필요)
|
||||
if (context.originalData && Object.keys(context.originalData).length > 0) {
|
||||
logger.info(`🎯 조건 노드: 저장 전 원본 데이터(originalData) 사용 (DB 조회 스킵)`);
|
||||
logger.info(`🎯 originalData 필드: ${Object.keys(context.originalData).join(", ")}`);
|
||||
return context.originalData;
|
||||
}
|
||||
|
||||
const whereConditions = targetLookup.lookupKeys
|
||||
.map((key: any, idx: number) => `"${key.targetField}" = $${idx + 1}`)
|
||||
.join(" AND ");
|
||||
|
||||
@@ -1739,7 +1739,7 @@ export class ScreenManagementService {
|
||||
|
||||
// V2 레이아웃이 있으면 V2 형식으로 반환
|
||||
if (v2Layout && v2Layout.layout_data) {
|
||||
console.log(`V2 레이아웃 발견, V2 형식으로 반환`);
|
||||
|
||||
const layoutData = v2Layout.layout_data;
|
||||
|
||||
// URL에서 컴포넌트 타입 추출하는 헬퍼 함수
|
||||
@@ -1799,7 +1799,7 @@ export class ScreenManagementService {
|
||||
};
|
||||
}
|
||||
|
||||
console.log(`V2 레이아웃 없음, V1 테이블 조회`);
|
||||
|
||||
|
||||
const layouts = await query<any>(
|
||||
`SELECT * FROM screen_layouts
|
||||
@@ -4254,7 +4254,7 @@ export class ScreenManagementService {
|
||||
[newScreen.screen_id, targetCompanyCode, JSON.stringify(updatedLayoutData)],
|
||||
);
|
||||
|
||||
console.log(` ✅ V2 레이아웃 복사 완료: ${components.length}개 컴포넌트`);
|
||||
|
||||
} catch (error) {
|
||||
console.error("V2 레이아웃 복사 중 오류:", error);
|
||||
// 레이아웃 복사 실패해도 화면 생성은 유지
|
||||
@@ -5045,8 +5045,7 @@ export class ScreenManagementService {
|
||||
companyCode: string,
|
||||
userType?: string,
|
||||
): Promise<any | null> {
|
||||
console.log(`=== V2 레이아웃 로드 시작 ===`);
|
||||
console.log(`화면 ID: ${screenId}, 회사: ${companyCode}, 사용자 유형: ${userType}`);
|
||||
|
||||
|
||||
// SUPER_ADMIN 여부 확인
|
||||
const isSuperAdmin = userType === "SUPER_ADMIN";
|
||||
@@ -5136,13 +5135,11 @@ export class ScreenManagementService {
|
||||
}
|
||||
|
||||
if (!layout) {
|
||||
console.log(`V2 레이아웃 없음: screen_id=${screenId}`);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`V2 레이아웃 로드 완료: ${layout.layout_data?.components?.length || 0}개 컴포넌트`,
|
||||
);
|
||||
|
||||
return layout.layout_data;
|
||||
}
|
||||
|
||||
@@ -5162,10 +5159,7 @@ export class ScreenManagementService {
|
||||
const hasConditionConfig = 'conditionConfig' in layoutData;
|
||||
const conditionConfig = layoutData.conditionConfig || null;
|
||||
|
||||
console.log(`=== V2 레이아웃 저장 시작 ===`);
|
||||
console.log(`화면 ID: ${screenId}, 회사: ${companyCode}, 레이어: ${layerId} (${layerName})`);
|
||||
console.log(`컴포넌트 수: ${layoutData.components?.length || 0}`);
|
||||
console.log(`조건 설정 포함 여부: ${hasConditionConfig}`);
|
||||
|
||||
|
||||
// 권한 확인
|
||||
const screens = await query<{ company_code: string | null }>(
|
||||
@@ -5210,7 +5204,7 @@ export class ScreenManagementService {
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`V2 레이아웃 저장 완료 (레이어 ${layerId}, 조건설정 ${hasConditionConfig ? '포함' : '유지'})`);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user