- Gradle 실행 설정 추가 (clean, compileJava)

- API 편집기 닫기 전 변경사항 알림/확인 로직 추가
- 저장 성공/초기 로드 시점 기준 스냅샷 로직 및 UI 처리를 반영
This commit is contained in:
Rinjae(gf63)
2026-09-11 18:38:50 +09:00
parent 0b6f273132
commit 124df00f51
2 changed files with 195 additions and 1 deletions
+11 -1
View File
@@ -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();
@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="10 seconds">
<statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] \\(%F:%L\\) %-20M -%msg%n" />
<property name="PREFIX" value="${inst.Type:-ems}" />
<property name="LOG_HOME" value="/work/eactive/djb-eapim/workspace/eapim-admin/logs" />
<property name="BACKUP_HOME" value="${LOG_HOME}/backup/" />
<property name="LOG_LEVEL" value="${LOGBACK_LOG_LEVEL:-DEBUG}" />
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<charset>utf-8</charset>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_stdout.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/${PREFIX}_stdout.log-%d{yyyy-MM-dd}.%i
</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="ACCESS_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_access.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/${PREFIX}_access.log-%d{yyyy-MM-dd}.%i
</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="SMS_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/sms.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/sms.log-%d{yyyy-MM-dd}.%i
</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="QUERY_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_query.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/${PREFIX}_query.log-%d{yyyy-MM-dd}.%i
</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="DYNAMIC_APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_dynamic.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_HOME}/${PREFIX}_dynamic.log-%d{yyyy-MM-dd}.%i
</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="HIBERNATE_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_hibernate.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${PREFIX}_hibernate.log-%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<appender name="HOTSWAP_APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${PREFIX}_hotswap.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${PREFIX}_hotswap.log-%d{yyyy-MM-dd}.%i</fileNamePattern>
<maxFileSize>500MB</maxFileSize>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<charset>utf-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<logger name="com.eactive.eai.rms.onl.server" level="ERROR" />
<logger name="com.eactive.eai.rms.onl.dashboard" level="ERROR" />
<logger name="com.eactive.eai.rms.common.acl.user.BizDao" level="ERROR" />
<logger name="com.eactive.eai.rms.common.acl.user.BizDao" level="ERROR" />
<logger name="com.eactive.eai.rms.ext.djb.job" level="DEBUG" />
<logger name="com.eactive.eai.rms.ext.djb.apistatus" level="DEBUG" />
<logger name="org.springframework.orm.jpa.JpaTransactionManager" level="ERROR" additivity="false" />
<logger name="org.springframework" level="INFO" />
<logger name="net.sf.ehcache" level="INFO" />
<logger name="ACCESS_LOGGER" level="DEBUG" >
<appender-ref ref="ACCESS_APPENDER" />
</logger>
<logger name="SMS_LOGGER" level="DEBUG" >
<appender-ref ref="SMS_APPENDER" />
</logger>
<logger name="DYNAMIC_LOGGER" level="DEBUG" >
<appender-ref ref="DYNAMIC_APPENDER" />
</logger>
<!-- QUERY_APPENDER start -->
<!-- Hibernate SQL & 파라미터 바인딩 -->
<logger name="org.hibernate.SQL" level="DEBUG" additivity="false">
<appender-ref ref="QUERY_APPENDER" />
<appender-ref ref="HIBERNATE_APPENDER" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" additivity="false">
<appender-ref ref="QUERY_APPENDER" />
<appender-ref ref="HIBERNATE_APPENDER" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor" level="TRACE" additivity="false">
<appender-ref ref="QUERY_APPENDER" />
<appender-ref ref="HIBERNATE_APPENDER" />
</logger>
<!-- Hibernate 일반 로그 (DDL/init/connection 등) -->
<logger name="org.hibernate" level="INFO" additivity="false">
<appender-ref ref="HIBERNATE_APPENDER" />
<appender-ref ref="STDOUT" />
</logger>
<!-- iBATIS 2.3.4 (commons-logging 또는 log4j-over-slf4j 통해 SLF4J 도달) -->
<logger name="com.ibatis" level="DEBUG" additivity="false">
<appender-ref ref="QUERY_APPENDER" />
</logger>
<logger name="com.eactive.eai.rms.common.base.SchemaIdConfiguredSqlMapTemplate" level="DEBUG" additivity="false">
<appender-ref ref="QUERY_APPENDER" />
</logger>
<!-- QUERY_APPENDER end -->
<!-- HotswapAgent는 자체 logger를 사용하므로 logback에 안 잡힘. hotswap-agent.properties의 LOGFILE로 직접 파일 출력 -->
<root>
<level value="INFO" />
<appender-ref ref="STDOUT" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>