update
This commit is contained in:
@@ -116,11 +116,10 @@
|
||||
class="btn btn-success">
|
||||
GUID to Excel
|
||||
</button>
|
||||
<button type="submit" formaction="{{ url_for('utils.update_gpu_list') }}"
|
||||
<button type="submit" formaction="{{ url_for('utils.update_gpu_list') }}"
|
||||
class="btn btn-success">
|
||||
GPU to Excel
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -148,79 +147,78 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# 파일 관리 도구 #}
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-light border-0 py-2">
|
||||
<h6 class="mb-0">
|
||||
<i class="bi bi-tools me-2"></i>
|
||||
파일 관리 도구
|
||||
</h6>
|
||||
</div>
|
||||
{# 파일 관리 도구 #}
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-light border-0 py-2">
|
||||
<h6 class="mb-0">
|
||||
<i class="bi bi-tools me-2"></i>
|
||||
파일 관리 도구
|
||||
</h6>
|
||||
</div>
|
||||
|
||||
<div class="card-body p-4 file-tools">
|
||||
<div class="card-body p-4 file-tools">
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xxl-5 g-3 align-items-end">
|
||||
|
||||
<!-- 한 줄로 정렬: 화면이 넓을 때 5등분 / 좁아지면 자동 줄바꿈 -->
|
||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xxl-5 g-3 align-items-end">
|
||||
<!-- ZIP 다운로드 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">ZIP 다운로드</label>
|
||||
<form method="post" action="{{ url_for('main.download_zip') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="zip_filename" placeholder="파일명" required>
|
||||
<button class="btn btn-primary" type="submit">다운로드</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 파일 백업 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">파일 백업</label>
|
||||
<form method="post" action="{{ url_for('main.backup_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="backup_prefix" placeholder="PO로 시작">
|
||||
<button class="btn btn-success" type="submit">백업</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- MAC 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">MAC 파일 이동</label>
|
||||
<form id="macMoveForm" method="post" action="{{ url_for('utils.move_mac_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-warning w-100" type="submit">MAC Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- GUID 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">GUID 파일 이동</label>
|
||||
<form id="guidMoveForm" method="post" action="{{ url_for('utils.move_guid_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-info w-100" type="submit">GUID Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- GPU 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">GPU 파일 이동</label>
|
||||
<form id="gpuMoveForm" method="post" action="{{ url_for('utils.move_gpu_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-info w-100" type="submit">GPU Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- ZIP 다운로드 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">ZIP 다운로드</label>
|
||||
<form method="post" action="{{ url_for('main.download_zip') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="zip_filename" placeholder="파일명" required>
|
||||
<button class="btn btn-primary" type="submit">다운로드</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- 파일 백업 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">파일 백업</label>
|
||||
<form method="post" action="{{ url_for('main.backup_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="backup_prefix" placeholder="PO로 시작">
|
||||
<button class="btn btn-success" type="submit">백업</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- MAC 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">MAC 파일 이동</label>
|
||||
<form id="macMoveForm" method="post" action="{{ url_for('utils.move_mac_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-warning w-100" type="submit">MAC Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- GUID 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">GUID 파일 이동</label>
|
||||
<form id="guidMoveForm" method="post" action="{{ url_for('utils.move_guid_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-info w-100" type="submit">GUID Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- GPU 파일 이동 -->
|
||||
<div class="col">
|
||||
<label class="form-label text-nowrap">GPU 파일 이동</label>
|
||||
<form id="gpuMoveForm" method="post" action="{{ url_for('utils.move_gpu_files') }}">
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||
<button class="btn btn-info w-100" type="submit">GPU Move</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{# 처리된 파일 목록 - 목록별 버튼 스타일 분리 (processed-list) #}
|
||||
|
||||
{# 처리된 파일 목록 #}
|
||||
<div class="row mb-4 processed-list">
|
||||
<div class="col">
|
||||
<div class="card border shadow-sm">
|
||||
@@ -272,7 +270,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# 백업된 파일 목록 - 목록별 버튼 스타일 분리 (backup-list) #}
|
||||
{# 백업된 파일 목록 #}
|
||||
<div class="row backup-list">
|
||||
<div class="col">
|
||||
<div class="card border shadow-sm">
|
||||
@@ -305,8 +303,8 @@
|
||||
{% for file in info.files %}
|
||||
<div class="col-auto">
|
||||
<div class="file-card-compact border rounded p-2 text-center">
|
||||
<a href="{{ url_for('main.download_backup_file', date=date, filename=file) }}
|
||||
" class="text-decoration-none text-dark fw-semibold d-block mb-2 text-nowrap px-2"
|
||||
<a href="{{ url_for('main.download_backup_file', date=date, filename=file) }}"
|
||||
class="text-decoration-none text-dark fw-semibold d-block mb-2 text-nowrap px-2"
|
||||
download title="{{ file }}">
|
||||
{{ file.rsplit('.', 1)[0] }}
|
||||
</a>
|
||||
@@ -473,7 +471,10 @@
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 스크립트 선택 시 XML 드롭다운 토글
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
const TARGET_SCRIPT = "02-set_config.py";
|
||||
const scriptSelect = document.getElementById('script');
|
||||
const xmlGroup = document.getElementById('xmlFileGroup');
|
||||
@@ -493,7 +494,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
scriptSelect.addEventListener('change', toggleXml);
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 파일 보기 모달
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
const modalEl = document.getElementById('fileViewModal');
|
||||
const titleEl = document.getElementById('fileViewModalLabel');
|
||||
const contentEl = document.getElementById('fileViewContent');
|
||||
@@ -525,7 +529,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 진행바 업데이트
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
window.updateProgress = function (val) {
|
||||
const bar = document.getElementById('progressBar');
|
||||
if (!bar) return;
|
||||
@@ -535,10 +542,16 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
bar.innerHTML = `<span class="fw-semibold">${v}%</span>`;
|
||||
};
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// CSRF 토큰
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
const csrfToken = document.querySelector('input[name="csrf_token"]')?.value || '';
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 공통 POST 함수
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
async function postFormAndHandle(url) {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
@@ -562,7 +575,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
return { success: true, html: true };
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// MAC 파일 이동
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
const macForm = document.getElementById('macMoveForm');
|
||||
if (macForm) {
|
||||
macForm.addEventListener('submit', async (e) => {
|
||||
@@ -582,7 +598,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// GUID 파일 이동
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
const guidForm = document.getElementById('guidMoveForm');
|
||||
if (guidForm) {
|
||||
guidForm.addEventListener('submit', async (e) => {
|
||||
@@ -602,83 +621,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
// IP 폼 제출
|
||||
const ipForm = document.getElementById("ipForm");
|
||||
if (ipForm) {
|
||||
ipForm.addEventListener("submit", async (ev) => {
|
||||
ev.preventDefault();
|
||||
const formData = new FormData(ipForm);
|
||||
const btn = ipForm.querySelector('button[type="submit"]');
|
||||
const originalHtml = btn.innerHTML;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>처리 중...';
|
||||
|
||||
try {
|
||||
const res = await fetch(ipForm.action, {
|
||||
method: "POST",
|
||||
body: formData
|
||||
});
|
||||
if (!res.ok) throw new Error("HTTP " + res.status);
|
||||
|
||||
const data = await res.json();
|
||||
console.log("[DEBUG] process_ips 응답:", data);
|
||||
|
||||
if (data.job_id) {
|
||||
pollProgress(data.job_id);
|
||||
} else {
|
||||
// job_id가 없으면 완료로 간주
|
||||
window.updateProgress(100);
|
||||
setTimeout(() => location.reload(), 1000);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("처리 중 오류:", err);
|
||||
alert("처리 중 오류 발생: " + err.message);
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = originalHtml;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 진행률 폴링 함수
|
||||
function pollProgress(jobId) {
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
const res = await fetch(`/progress_status/${jobId}`);
|
||||
if (!res.ok) {
|
||||
clearInterval(interval);
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.progress !== undefined) {
|
||||
window.updateProgress(data.progress);
|
||||
}
|
||||
|
||||
// 완료 시 (100%)
|
||||
if (data.progress >= 100) {
|
||||
clearInterval(interval);
|
||||
window.updateProgress(100);
|
||||
|
||||
// 페이지 새로고침
|
||||
setTimeout(() => location.reload(), 1500);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('진행률 확인 중 오류:', err);
|
||||
clearInterval(interval);
|
||||
}
|
||||
}, 500); // 0.5초마다 확인
|
||||
}
|
||||
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// 알림 자동 닫기
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
setTimeout(() => {
|
||||
document.querySelectorAll('.alert').forEach(alert => {
|
||||
const bsAlert = new bootstrap.Alert(alert);
|
||||
bsAlert.close();
|
||||
});
|
||||
}, 5000);
|
||||
|
||||
});
|
||||
</script>
|
||||
<!-- 외부 script.js 파일만 로드 -->
|
||||
|
||||
<!-- 외부 script.js 파일 (IP 폼 처리 로직 포함) -->
|
||||
<script src="{{ url_for('static', filename='script.js') }}"></script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user