From ac613500878e78d6970567f30d3a39eba25692ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=B0=95=EC=84=B1=EC=98=81?= Date: Mon, 29 Sep 2025 09:55:38 +0900 Subject: [PATCH] =?UTF-8?q?=EB=8B=A8=EC=86=8D=20=ED=96=89=EC=9C=84?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=20-=20=EB=82=A8=EC=9D=80=20=EC=A1=B0?= =?UTF-8?q?=EC=B9=98=20=EB=A9=B4=EC=A0=81=20=EC=9E=90=EB=8F=99=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crdnActInfo/CrdnActInfoMapper_maria.xml | 11 +- src/main/webapp/resources/xit/xit-common.js | 103 +++++++++++++++++- 2 files changed, 100 insertions(+), 14 deletions(-) diff --git a/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/crdnActInfo/CrdnActInfoMapper_maria.xml b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/crdnActInfo/CrdnActInfoMapper_maria.xml index 5e72ab8..4bb29cd 100644 --- a/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/crdnActInfo/CrdnActInfoMapper_maria.xml +++ b/src/main/resources/mybatis/mapper/crdn/crndRegistAndView/crdnActInfo/CrdnActInfoMapper_maria.xml @@ -63,7 +63,7 @@ AND a.CRDN_YR = #{crdnYr} AND a.CRDN_NO = #{crdnNo} AND a.PSTN_INFO_ID = #{pstnInfoId} - ORDER BY a.REG_DT ASC, a.ACT_INFO_ID ASC + ORDER BY a.ACT_BGNG_YMD ASC, a.REG_DT ASC, a.ACT_INFO_ID ASC limit #{startIndex}, #{perPage} /* 서버사이드 페이징 처리 */ @@ -104,9 +104,6 @@ VRTC, AREA, RMRK, - ACTN_YMD, - ACTN_AREA, - ACTN_RMRK, REG_DT, RGTR, MDFCN_DT, @@ -134,9 +131,6 @@ #{vrtc}, #{area}, #{rmrk}, - replace(#{actnYmd},'-',''), - #{actnArea}, - #{actnRmrk}, NOW(), #{rgtr}, NOW(), @@ -219,9 +213,6 @@ VRTC = #{vrtc}, AREA = #{area}, RMRK = #{rmrk}, - ACTN_YMD = replace(#{actnYmd},'-',''), - ACTN_AREA = #{actnArea}, - ACTN_RMRK = #{actnRmrk}, MDFCN_DT = NOW(), MDFR = #{mdfr} WHERE ACT_INFO_ID = #{actInfoId} diff --git a/src/main/webapp/resources/xit/xit-common.js b/src/main/webapp/resources/xit/xit-common.js index 571927d..4cc6421 100644 --- a/src/main/webapp/resources/xit/xit-common.js +++ b/src/main/webapp/resources/xit/xit-common.js @@ -53,8 +53,11 @@ $(document).ajaxError( function( event, jqxhr, settings, exception ){ if( jqxhr.responseJSON ){ // 세션 만료인 경우 처리 if(jqxhr.responseJSON.errorCode === "SESSION_EXPIRED") { - // 새로운 공통 함수를 사용하여 세션 만료 처리 - handleSessionExpired(); + console.log('[Ajax Error] 세션 만료 감지, URL:', settings.url); + // 중요로직: 세션 만료 시 안전한 처리를 위해 약간의 지연 후 처리 + setTimeout(function() { + handleSessionExpired(); + }, 100); } else if(jqxhr.responseJSON.errorCode === "MessageException") { alert(jqxhr.responseJSON.message); } else if(jqxhr.responseJSON.errorCode === "MESSAGE") { @@ -63,7 +66,13 @@ $(document).ajaxError( function( event, jqxhr, settings, exception ){ console.error(jqxhr); alert("에러가 발생했습니다.\n\nERROR CODE : "+jqxhr.responseJSON.errorCode+"\nMESSAGE : "+jqxhr.responseJSON.message); } - } + } else if(jqxhr.status === 401) { + // HTTP 401 Unauthorized 응답도 세션 만료로 처리 + console.log('[Ajax Error] HTTP 401 감지, 세션 만료로 처리, URL:', settings.url); + setTimeout(function() { + handleSessionExpired(); + }, 100); + } }); /* Ajax Progress Block UI 설정 */ @@ -449,9 +458,95 @@ function logout() { /** * 세션 만료 처리 함수 - 모든 팝업을 닫고 로그인 페이지로 이동 + * 중요로직: 팝업 환경에서 세션 만료 시 현재 팝업이 아닌 최상위 창에서 로그인 페이지로 이동 */ function handleSessionExpired() { - redirectToLoginWithCloseAllPopups("세션이 종료되었습니다. 다시 로그인해주세요."); + try { + console.log('[세션 만료] 처리 시작'); + + // 중요로직: 현재 창이 팝업인지 확인 + var isPopup = !!(window.opener && !window.opener.closed); + console.log('[세션 만료] 현재 창 팝업 여부:', isPopup); + + if (isPopup) { + // 팝업인 경우: 최상위 부모창 찾기 + var topWindow = window; + var windowChain = []; + var currentWindow = window; + + // 최상위 창까지 탐색 + while (currentWindow && currentWindow.opener && !currentWindow.opener.closed) { + windowChain.push(currentWindow); + currentWindow = currentWindow.opener; + topWindow = currentWindow; + + // 무한루프 방지 (최대 10단계) + if (windowChain.length > 10) { + console.warn('[세션 만료] 너무 많은 팝업 체인, 탐색 중단'); + break; + } + } + + console.log('[세션 만료] 팝업 체인 길이:', windowChain.length); + console.log('[세션 만료] 최상위 창 찾음:', !!topWindow); + + // 메시지 표시 (현재 팝업에서) + alert("세션이 종료되었습니다. 다시 로그인해주세요."); + + // 최상위 창을 로그인 페이지로 이동 + if (topWindow && !topWindow.closed) { + try { + topWindow.location.href = (contextPath || '') + loginUrl; + console.log('[세션 만료] 최상위 창 리다이렉트 성공'); + } catch (redirectError) { + console.warn('[세션 만료] 최상위 창 리다이렉트 실패:', redirectError); + // 리다이렉트 실패 시 현재 창에서 이동 + location.href = (contextPath || '') + loginUrl; + } + } else { + // 최상위 창이 닫혀있는 경우 현재 창에서 이동 + location.href = (contextPath || '') + loginUrl; + console.log('[세션 만료] 현재 창에서 리다이렉트'); + } + + // 모든 팝업창 닫기 (약간의 지연 후) + setTimeout(function() { + try { + // 하위 팝업부터 상위 팝업 순서로 닫기 + for (var i = 0; i < windowChain.length; i++) { + try { + var popupWindow = windowChain[i]; + if (popupWindow && !popupWindow.closed) { + popupWindow.close(); + console.log('[세션 만료] 팝업창 닫기 성공:', i + 1); + } + } catch (closeError) { + console.warn('[세션 만료] 팝업창 닫기 실패:', closeError); + } + } + console.log('[세션 만료] 모든 팝업창 닫기 완료'); + } catch (e) { + console.warn('[세션 만료] 팝업창 일괄 닫기 실패:', e); + } + }, 300); // 리다이렉트 후 약간의 지연 + + } else { + // 일반 페이지인 경우 기존 로직 사용 + console.log('[세션 만료] 일반 페이지에서 처리'); + redirectToLoginWithCloseAllPopups("세션이 종료되었습니다. 다시 로그인해주세요."); + } + + } catch (e) { + console.error('[세션 만료] 전체 처리 중 오류:', e); + // 모든 처리가 실패한 경우 기본 처리 + try { + alert("세션이 종료되었습니다. 다시 로그인해주세요."); + location.href = (contextPath || '') + loginUrl; + } catch (finalError) { + console.error('[세션 만료] 최종 처리도 실패:', finalError); + location.reload(); + } + } } /**