모던 대시보드 패치
- ApexCharts 기반 실시간 모니터링 대시보드 - 어댑터/배치/서버/소켓/트랜잭션 모니터링 컴포넌트 - 처리량 계산 및 데이터 매핑 서비스
This commit is contained in:
@@ -0,0 +1,267 @@
|
||||
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
|
||||
<div class="dashboard-sms-summary">
|
||||
<h2 class="section-title">장애통보(SMS)</h2>
|
||||
<div class="card shadow mb-0">
|
||||
<div class="sms-table-container">
|
||||
<table class="sms-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="18%">인스턴스</th>
|
||||
<th width="8%">유형</th>
|
||||
<th width="12%">시간</th>
|
||||
<th width="10%">건수</th>
|
||||
<th width="20%">오류대상</th>
|
||||
<th>메시지</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="smsTableBody">
|
||||
<!-- 데이터가 여기에 동적으로 로드됩니다 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* SMS 섹션 스타일 */
|
||||
.dashboard-sms-summary .section-title {
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.dashboard-sms-summary .card {
|
||||
border-radius: 0.35rem;
|
||||
box-shadow: 0 0.15rem 1.75rem 0 rgba(58, 59, 69, 0.15);
|
||||
}
|
||||
|
||||
.sms-table-container {
|
||||
max-height: 220px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.sms-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.sms-table th {
|
||||
background-color: #f8f9fc;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
padding: 0.5rem;
|
||||
border-bottom: 1px solid #e3e6f0;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.sms-table td {
|
||||
padding: 0.5rem;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.sms-table tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.sms-table tr:hover {
|
||||
background-color: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
|
||||
.error-type-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.error-type-icon.adapter {
|
||||
background-color: #4e73df;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error-type-icon.interface {
|
||||
background-color: #e74a3b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.error-type-icon i {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.error-target {
|
||||
font-family: monospace;
|
||||
padding: 0.2rem 0.4rem;
|
||||
background-color: #f8f9fc;
|
||||
border-radius: 0.2rem;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #e74a3b !important;
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: #6c757d;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.occurrence-count {
|
||||
display: inline-block;
|
||||
padding: 0.2rem 0.5rem;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0.25rem;
|
||||
font-weight: 600;
|
||||
color: #dc3545;
|
||||
min-width: 2.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// SMS 데이터 로드 함수
|
||||
function loadSmsData() {
|
||||
$.ajax({
|
||||
url: 'modern-dashboard-api.do',
|
||||
type: 'GET',
|
||||
data: {
|
||||
type: 'sms-notification'
|
||||
, serviceType: sessionStorage['serviceType']
|
||||
},
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
if (response.success) {
|
||||
renderSmsTable(response.data);
|
||||
} else {
|
||||
console.error('SMS 데이터 로드 실패:', response.message);
|
||||
showEmptySmsTable();
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('SMS 데이터 로드 중 오류 발생:', error);
|
||||
showEmptySmsTable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// SMS 테이블 렌더링 함수
|
||||
function renderSmsTable(data) {
|
||||
var $tableBody = $('#smsTableBody');
|
||||
$tableBody.empty();
|
||||
|
||||
if (data && data.length > 0) {
|
||||
// 최대 10개 항목만 표시
|
||||
var displayData = data.slice(0, 10);
|
||||
|
||||
$.each(displayData, function(index, item) {
|
||||
var errorTypeIcon = getErrorTypeIcon(item.errorType);
|
||||
var timeStr = formatTime(item.dateTime);
|
||||
|
||||
// 오류 대상 정보와 스타일 조건부 적용
|
||||
var errorTarget = '';
|
||||
if (item.errorType === 'ADAPTER') {
|
||||
// 어댑터 오류일 경우 - 클릭 불가능
|
||||
errorTarget = '<span class="adapter-id">' + (item.adapterId || '-') + '</span>';
|
||||
} else {
|
||||
// 인터페이스 오류일 경우 - 클릭 가능, data-service-type 속성 추가
|
||||
errorTarget = '<span class="error-target interface-id" data-service-type="' +
|
||||
(item.serviceType || '') + '" data-date-time="' +
|
||||
(item.dateTime || '') + '">' + (item.interfaceId || '-') + '</span>';
|
||||
}
|
||||
|
||||
var row = '<tr>' +
|
||||
'<td>' + (item.instanceName || '-') + '</td>' +
|
||||
'<td>' + errorTypeIcon + '</td>' +
|
||||
'<td class="text-nowrap">' + timeStr + '</td>' +
|
||||
'<td><span class="occurrence-count">' + (item.count || '0') + '</span></td>' +
|
||||
'<td>' + errorTarget + '</td>' +
|
||||
'<td class="text-danger">' + (item.errorContent || '-') + '</td>' +
|
||||
'</tr>';
|
||||
|
||||
$tableBody.append(row);
|
||||
});
|
||||
|
||||
// 인터페이스ID에만 클릭 이벤트 스타일 적용
|
||||
$('.interface-id').css({
|
||||
'cursor': 'pointer',
|
||||
'color': '#007bff',
|
||||
'text-decoration': 'underline'
|
||||
});
|
||||
|
||||
// 인터페이스ID 클릭 이벤트 처리 - 인터페이스 타입에만 적용
|
||||
$('.interface-id').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var row = $(this).closest('tr');
|
||||
var interfaceId = $(this).text().trim();
|
||||
var instanceName = row.find('td').eq(0).text().trim();
|
||||
var errorTime = $(this).data('date-time');
|
||||
var errorMessage = row.find('td').eq(5).text().trim();
|
||||
var serviceType = $(this).data('service-type');
|
||||
|
||||
// 인터페이스 로그 상세 모달 열기
|
||||
openInterfaceLogDetailModal(interfaceId, errorTime, instanceName, errorMessage, serviceType);
|
||||
});
|
||||
} else {
|
||||
showEmptySmsTable();
|
||||
}
|
||||
}
|
||||
|
||||
// 에러 타입 아이콘 생성
|
||||
function getErrorTypeIcon(errorType) {
|
||||
if (errorType === 'ADAPTER') {
|
||||
return '<div class="error-type-icon adapter" title="어댑터 오류"><i class="bi bi-plug"></i></div>';
|
||||
} else {
|
||||
return '<div class="error-type-icon interface" title="인터페이스 오류"><i class="bi bi-arrow-left-right"></i></div>';
|
||||
}
|
||||
}
|
||||
|
||||
// 오류 대상 정보 가져오기
|
||||
function getErrorTarget(item) {
|
||||
if (item.errorType === 'ADAPTER') {
|
||||
return item.adapterId || '-';
|
||||
} else {
|
||||
return item.interfaceId || '-';
|
||||
}
|
||||
}
|
||||
|
||||
// 시간 포맷팅 (HH:mm:ss)
|
||||
function formatTime(dateTimeStr) {
|
||||
if (!dateTimeStr) return '-';
|
||||
var parts = dateTimeStr.split(' ');
|
||||
if (parts.length >= 2) {
|
||||
var timePart = parts[1];
|
||||
return timePart.substring(0, 8); // HH:mm:ss 부분만 추출
|
||||
}
|
||||
return '-';
|
||||
}
|
||||
|
||||
// 빈 테이블 표시 함수
|
||||
function showEmptySmsTable() {
|
||||
var $tableBody = $('#smsTableBody');
|
||||
$tableBody.empty();
|
||||
$tableBody.append('<tr><td colspan="5" class="empty-message">장애 통보 내역이 없습니다</td></tr>');
|
||||
}
|
||||
|
||||
// 초기 데이터 로드
|
||||
loadSmsData();
|
||||
|
||||
// DashboardEventManager를 사용하여 새로고침 이벤트 구독
|
||||
if (window.DashboardEventManager) {
|
||||
window.DashboardEventManager.on('refresh', function() {
|
||||
console.log('SMS 데이터 갱신 시작');
|
||||
loadSmsData()
|
||||
});
|
||||
|
||||
// 초기화 완료 이벤트 로깅
|
||||
console.log('SMS 컴포넌트 초기화 완료');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user