diff --git a/WebContent/js/djb/apispec/app.js b/WebContent/js/djb/apispec/app.js index cdc4a13..6ef3052 100644 --- a/WebContent/js/djb/apispec/app.js +++ b/WebContent/js/djb/apispec/app.js @@ -29,6 +29,14 @@ // (enricher 는 oauth·api_key 를 모두 apiKey-in-header 로 모델링하므로 scheme.type 만으로 구분 불가) var djbAuthType = ''; + // 마지막 저장(또는 최초 로드) 시점의 state.data 스냅샷 — 닫기 전 미저장 변경 여부 판별용. + var savedSnapshot = null; + function isDirty() { return savedSnapshot !== null && JSON.stringify(state.data) !== savedSnapshot; } + function closeEditor() { + if (isDirty() && !window.confirm('저장하지 않은 변경사항이 있습니다. 저장하지 않고 닫으시겠습니까?')) return; + window.close(); + } + // ============================================================ // 2. 유틸 // ============================================================ @@ -1703,7 +1711,7 @@ var bSave = $('#btn-save'); if (bSave) bSave.addEventListener('click', () => saveSpec(false)); var bRegen = $('#btn-regen'); if (bRegen) bRegen.addEventListener('click', regenerate); - var bClose = $('#btn-close'); if (bClose) bClose.addEventListener('click', () => window.close()); + var bClose = $('#btn-close'); if (bClose) bClose.addEventListener('click', closeEditor); // Cmd/Ctrl + S → 저장 (브라우저 기본 저장 대화상자 차단) document.addEventListener('keydown', function (e) { @@ -2066,6 +2074,7 @@ .then(function (res) { if (res && res.status === 'success') { toast(temp ? '임시저장되었습니다' : '저장되었습니다'); + savedSnapshot = JSON.stringify(state.data); // 저장 성공 시점을 새 저장 기준선으로 갱신 var badge = $('#hdr-source'); if (badge) { badge.textContent = '저장본'; badge.className = 'ml-1 px-2 py-0.5 text-[11px] rounded-full bg-emerald-50 text-emerald-700 border border-emerald-200'; badge.classList.remove('hidden'); } } else toast('저장 실패: ' + (res && res.errorMsg || ''), 'error'); }) @@ -2102,6 +2111,7 @@ // ============================================================ function init() { loadInitialData().then(function () { + savedSnapshot = JSON.stringify(state.data); // 초기 로드(자동생성 포함) 완료 시점을 저장 기준선으로 설정 renderStepper(); renderForm(); bindGlobalEvents(); diff --git a/src/main/resources/logback-rinjae_gf63_linux.xml b/src/main/resources/logback-rinjae_gf63_linux.xml new file mode 100644 index 0000000..8f24e17 --- /dev/null +++ b/src/main/resources/logback-rinjae_gf63_linux.xml @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + utf-8 + %d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n + + + + + ${LOG_HOME}/${PREFIX}_stdout.log + + + ${LOG_HOME}/${PREFIX}_stdout.log-%d{yyyy-MM-dd}.%i + + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + + ${LOG_HOME}/${PREFIX}_access.log + + + ${LOG_HOME}/${PREFIX}_access.log-%d{yyyy-MM-dd}.%i + + 500MB + + + utf-8 + ${LOG_PATTERN} + + + + ${LOG_HOME}/sms.log + + + ${LOG_HOME}/sms.log-%d{yyyy-MM-dd}.%i + + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + ${LOG_HOME}/${PREFIX}_query.log + + + ${LOG_HOME}/${PREFIX}_query.log-%d{yyyy-MM-dd}.%i + + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + ${LOG_HOME}/${PREFIX}_dynamic.log + + + ${LOG_HOME}/${PREFIX}_dynamic.log-%d{yyyy-MM-dd}.%i + + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + ${LOG_HOME}/${PREFIX}_hibernate.log + + ${LOG_HOME}/${PREFIX}_hibernate.log-%d{yyyy-MM-dd}.%i + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + ${LOG_HOME}/${PREFIX}_hotswap.log + + ${LOG_HOME}/${PREFIX}_hotswap.log-%d{yyyy-MM-dd}.%i + 500MB + 10 + + + utf-8 + ${LOG_PATTERN} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file