107 lines
4.5 KiB
Plaintext
107 lines
4.5 KiB
Plaintext
@{
|
|
ViewData["Title"] = "System Admin";
|
|
}
|
|
|
|
<div class="container mt-4">
|
|
<div class="card border-danger shadow">
|
|
<div class="card-header bg-danger text-white">
|
|
<h4 class="mb-0">🛠️ System Engineering - Discovery Mode</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<section class="mb-5">
|
|
<h5>1. 하니웰 Asset 모델 탐사 (Crawler)</h5>
|
|
<p class="text-muted">서버의 모든 노드를 훑어 <code>Honeywell_FullMap.csv</code> 파일을 생성합니다. <br>
|
|
<small class="text-danger">* 주의: 노드 수가 많을 경우 하니웰 서버와 네트워크에 부하가 발생할 수 있습니다.</small></p>
|
|
|
|
<button id="btnRunCrawler" class="btn btn-danger btn-lg" onclick="runCrawler()">
|
|
<span id="spinnerCrawler" class="spinner-border spinner-border-sm d-none" role="status" aria-hidden="true"></span>
|
|
🚀 탐사 및 CSV 생성 시작
|
|
</button>
|
|
</section>
|
|
|
|
<hr>
|
|
|
|
<section class="mt-4">
|
|
<h5>2. DB 동기화 (CSV to Database)</h5>
|
|
<p class="text-muted">생성된 CSV 파일을 읽어 PostgreSQL <code>raw_node_map</code> 테이블에 일괄 저장합니다.</p>
|
|
<button id="btnImportCsv" class="btn btn-warning btn-lg" onclick="importCsvToDb()">
|
|
<span id="spinnerImport" class="spinner-border spinner-border-sm d-none" role="status" aria-hidden="true"></span>
|
|
📥 CSV 데이터를 DB로 가져오기
|
|
</button>
|
|
</section>
|
|
</div>
|
|
<div class="card-footer bg-light">
|
|
<div id="statusMessage" class="fw-bold"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
async function runCrawler() {
|
|
const btn = document.getElementById('btnRunCrawler');
|
|
const spinner = document.getElementById('spinnerCrawler');
|
|
const status = document.getElementById('statusMessage');
|
|
|
|
if (!confirm("전체 노드 탐사를 시작하시겠습니까? (ns=1;s=$assetmodel 기준)")) return;
|
|
|
|
try {
|
|
// 버튼 비활성화 및 로딩 시작
|
|
btn.disabled = true;
|
|
spinner.classList.remove('d-none');
|
|
status.innerText = "⏳ 하니웰 서버 탐사 중... 잠시만 기다려 주세요.";
|
|
status.className = "text-primary fw-bold";
|
|
|
|
const response = await fetch('/Engineering/RunCrawler', { method: 'POST' });
|
|
const result = await response.json();
|
|
|
|
if (response.ok) {
|
|
alert("✅ 성공: " + result.message);
|
|
status.innerText = "✅ 탐사 완료: " + result.message;
|
|
status.className = "text-success fw-bold";
|
|
} else {
|
|
throw new Error(result.message || "탐사 실패");
|
|
}
|
|
} catch (error) {
|
|
alert("❌ 에러 발생: " + error.message);
|
|
status.innerText = "❌ 오류: " + error.message;
|
|
status.className = "text-danger fw-bold";
|
|
} finally {
|
|
btn.disabled = false;
|
|
spinner.classList.add('d-none');
|
|
}
|
|
}
|
|
|
|
async function importCsvToDb() {
|
|
const btn = document.getElementById('btnImportCsv');
|
|
const spinner = document.getElementById('spinnerImport');
|
|
const status = document.getElementById('statusMessage');
|
|
|
|
if (!confirm("CSV 데이터를 DB에 덮어씌우시겠습니까? (기존 데이터는 삭제됩니다.)")) return;
|
|
|
|
try {
|
|
btn.disabled = true;
|
|
spinner.classList.remove('d-none');
|
|
status.innerText = "⏳ DB 동기화 작업 중...";
|
|
|
|
const response = await fetch('/Engineering/ImportCsv', { method: 'POST' });
|
|
const result = await response.json();
|
|
|
|
if (response.ok) {
|
|
alert("✅ 성공: " + result.message);
|
|
status.innerText = "✅ DB 동기화 완료!";
|
|
status.className = "text-success fw-bold";
|
|
} else {
|
|
throw new Error(result.message || "동기화 실패");
|
|
}
|
|
} catch (error) {
|
|
alert("❌ 에러 발생: " + error.message);
|
|
status.innerText = "❌ 오류: " + error.message;
|
|
status.className = "text-danger fw-bold";
|
|
} finally {
|
|
btn.disabled = false;
|
|
spinner.classList.add('d-none');
|
|
}
|
|
}
|
|
</script>
|
|
} |