262 lines
9.7 KiB
Plaintext
262 lines
9.7 KiB
Plaintext
<%@ page language="java" contentType="text/html; charset=utf-8"%>
|
|
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
|
|
|
<link href="<c:url value="/addon/bootstrap-5.3.2/css/bootstrap.min.css"/>" rel="stylesheet" />
|
|
<script src="<c:url value="/addon/bootstrap-5.3.2/js/bootstrap.bundle.min.js"/>"></script>
|
|
<link href="<c:url value="/addon/select2-4.1.0/css/select2.min.css"/>" rel="stylesheet" />
|
|
<link href="<c:url value="/addon/select2-4.1.0/css/select2-bootstrap.min.css"/>" rel="stylesheet" />
|
|
<script src="<c:url value="/addon/select2-4.1.0/js/select2.min.js"/>"></script>
|
|
<link href="<c:url value="/addon/gridjs/theme/mermaid.min.css"/>" rel="stylesheet" />
|
|
<script src="<c:url value="/addon/gridjs/gridjs.production.min.js"/>"></script>
|
|
<link href="<c:url value="/addon/bootstrap-icons-1.11.3/bootstrap-icons.min.css"/>" rel="stylesheet" />
|
|
<link href="<c:url value="/addon/bootstrap-datepicker/css/bootstrap-datepicker.min.css"/>" rel="stylesheet" />
|
|
<script src="<c:url value="/addon/bootstrap-datepicker/js/bootstrap-datepicker.min.js"/>"></script>
|
|
<script src="<c:url value="/addon/bootstrap-datepicker/locales/bootstrap-datepicker.ko.min.js"/>"></script>
|
|
|
|
<style>
|
|
.card {
|
|
border: none;
|
|
border-radius: 10px;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
transition: all 0.3s ease;
|
|
}
|
|
.card:hover {
|
|
transform: translateY(-5px);
|
|
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);
|
|
}
|
|
.card-icon {
|
|
font-size: 2.5rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.card-title {
|
|
font-size: 1.25rem;
|
|
font-weight: 600;
|
|
}
|
|
.card-text {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
}
|
|
.search-panel {
|
|
background-color: #f8f9fa;
|
|
border-radius: 10px;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
|
}
|
|
.gridjs-wrapper {
|
|
border-radius: 10px;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
border: none !important;
|
|
font-size: 14px;
|
|
}
|
|
.gridjs-table {
|
|
border: none !important;
|
|
}
|
|
.gridjs-thead {
|
|
background-color: #f8f9fa;
|
|
}
|
|
.gridjs-th {
|
|
background-color: #f8f9fa !important;
|
|
color: #495057 !important;
|
|
border-top: none !important;
|
|
text-align: center !important;
|
|
padding: 15px !important;
|
|
font-size: 16px !important;
|
|
}
|
|
.gridjs-td {
|
|
border: none !important;
|
|
padding: 15px !important;
|
|
font-size: 14px !important;
|
|
}
|
|
.gridjs-tr:nth-child(even) {
|
|
background-color: #f8f9fa;
|
|
}
|
|
.gridjs-tr:hover {
|
|
background-color: #e9ecef;
|
|
}
|
|
.gridjs-search {
|
|
margin-bottom: 5px;
|
|
}
|
|
.gridjs-search-input {
|
|
border-radius: 5px;
|
|
border: 1px solid #ced4da;
|
|
padding: 10px 15px;
|
|
width: 100%;
|
|
}
|
|
/* Datepicker 스타일 추가 */
|
|
.datepicker {
|
|
border-radius: 0.375rem;
|
|
border: 1px solid #ced4da;
|
|
}
|
|
.datepicker-dropdown {
|
|
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.btn-date-range.active {
|
|
background-color: #6c757d;
|
|
color: white;
|
|
}
|
|
.required-mark {
|
|
color: red;
|
|
margin-left: 2px;
|
|
font-weight: bold;
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
// 현재 페이지 타입을 결정하는 함수
|
|
function getPageType() {
|
|
if (window.location.href.includes('portalStatisticsApiTableMan')) {
|
|
return 'API';
|
|
} else if (window.location.href.includes('portalStatisticsAppTableMan')) {
|
|
return 'APP';
|
|
} else if (window.location.href.includes('portalStatisticsOrgTableMan')) {
|
|
return 'ORG';
|
|
} else if (window.location.href.includes('portalStatisticsDailyApiTableMan')) {
|
|
return 'DAILY_API';
|
|
} else if (window.location.href.includes('portalStatisticsDailyAppTableMan')) {
|
|
return 'DAILY_APP';
|
|
} else if (window.location.href.includes('portalStatisticsDailyOrgTableMan')) {
|
|
return 'DAILY_ORG';
|
|
}
|
|
return 'UNKNOWN'; // 기본값
|
|
}
|
|
|
|
// 선택된 날짜 범위를 가져오는 함수
|
|
function getDateRange() {
|
|
var startDate = document.querySelector('input[name=startDate]').value;
|
|
var endDate = document.querySelector('input[name=endDate]').value;
|
|
return { startDate: startDate, endDate: endDate };
|
|
}
|
|
|
|
// CSV 내보내기 함수
|
|
function exportToCSV(grid) {
|
|
if (!grid) {
|
|
alert('데이터를 먼저 조회해주세요.');
|
|
return;
|
|
}
|
|
|
|
var pageType = getPageType();
|
|
var dateRange = getDateRange();
|
|
|
|
// 날짜 형식을 YYYYMMDD로 변경
|
|
var formattedStartDate = dateRange.startDate.replace(/-/g, '');
|
|
var formattedEndDate = dateRange.endDate.replace(/-/g, '');
|
|
|
|
var fileName = pageType + '_' + formattedStartDate + '_' + formattedEndDate + '.csv';
|
|
|
|
var csvContent = "data:text/csv;charset=utf-8,\uFEFF"; // BOM 추가로 한글 깨짐 방지
|
|
|
|
// 헤더 추가
|
|
var headers = grid.config.columns.map(function(col) { return col.name; });
|
|
csvContent += headers.join(",") + "\r\n";
|
|
|
|
// 데이터 추가
|
|
grid.config.data.forEach(function(row) {
|
|
var dataRow = headers.map(function(header) {
|
|
var column = grid.config.columns.find(function(col) { return col.name === header; });
|
|
var cellValue = row[column.id];
|
|
// 큰따옴표로 감싸고 콤마를 이스케이프
|
|
return '"' + (cellValue ? cellValue.toString().replace(/"/g, '""') : '') + '"';
|
|
});
|
|
csvContent += dataRow.join(",") + "\r\n";
|
|
});
|
|
|
|
var encodedUri = encodeURI(csvContent);
|
|
var link = document.createElement("a");
|
|
link.setAttribute("href", encodedUri);
|
|
link.setAttribute("download", fileName);
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
// addExportButton 함수 수정
|
|
function addExportButton(grid) {
|
|
var gridContainer = grid.config.container;
|
|
var gridHead = gridContainer.querySelector('.gridjs-head');
|
|
|
|
if (gridHead) {
|
|
var headerContainer = document.createElement('div');
|
|
headerContainer.style.display = 'flex';
|
|
headerContainer.style.justifyContent = 'space-between';
|
|
headerContainer.style.alignItems = 'center';
|
|
headerContainer.style.marginBottom = '10px';
|
|
|
|
var searchInput = gridHead.querySelector('.gridjs-search');
|
|
if (searchInput) {
|
|
headerContainer.appendChild(searchInput);
|
|
}
|
|
|
|
var exportButton = document.createElement('button');
|
|
exportButton.className = 'btn btn-sm btn-success gridjs-export-btn';
|
|
exportButton.innerHTML = '<i class="bi bi-download"></i> CSV 내보내기';
|
|
|
|
// 명시적인 스타일 적용
|
|
exportButton.style.backgroundColor = '#198754';
|
|
exportButton.style.color = '#ffffff';
|
|
exportButton.style.border = '1px solid #198754';
|
|
exportButton.style.borderRadius = '4px';
|
|
exportButton.style.padding = '5px 10px';
|
|
exportButton.style.fontSize = '14px';
|
|
exportButton.style.cursor = 'pointer';
|
|
exportButton.style.marginLeft = '10px';
|
|
exportButton.style.outline = 'none';
|
|
exportButton.style.boxShadow = 'none';
|
|
|
|
exportButton.onmouseover = function() {
|
|
this.style.backgroundColor = '#157347';
|
|
this.style.borderColor = '#146c43';
|
|
};
|
|
exportButton.onmouseout = function() {
|
|
this.style.backgroundColor = '#198754';
|
|
this.style.borderColor = '#198754';
|
|
};
|
|
|
|
exportButton.onclick = function() { exportToCSV(grid); };
|
|
|
|
headerContainer.appendChild(exportButton);
|
|
gridHead.insertBefore(headerContainer, gridHead.firstChild);
|
|
|
|
// 스타일 태그 추가
|
|
var style = document.createElement('style');
|
|
style.textContent = '.gridjs-export-btn { display: inline-block !important; visibility: visible !important; opacity: 1 !important; }';
|
|
document.head.appendChild(style);
|
|
}
|
|
}
|
|
function getRequiredLabel(label) {
|
|
return label + ' <span class="required-mark">*</span>';
|
|
}
|
|
// 사업자등록번호 포맷팅
|
|
function formatCompanyRegNo(value) {
|
|
return value.replace(/(\d{3})(\d{2})(\d{5})/, "$1-$2-$3");
|
|
}
|
|
// 법인등록번호 포맷팅
|
|
function formatCorpRegNo(value) {
|
|
return value.replace(/(\d{6})(\d{7})/, "$1-$2");
|
|
}
|
|
function removeHyphen(text) {
|
|
return text.replace(/-/g, '');
|
|
}
|
|
// 전화번호 포맷팅 (일반전화, 휴대폰, 대표번호 등)
|
|
function formatPhoneNumber(phoneNumber) {
|
|
if (!phoneNumber) return '';
|
|
|
|
phoneNumber = phoneNumber.replace(/[^0-9]/g, ''); // 숫자만 추출
|
|
|
|
if (phoneNumber.length <= 4) {
|
|
return phoneNumber;
|
|
} else if (phoneNumber.length <= 7) {
|
|
return phoneNumber.replace(/(\d{4})(\d{1,3})/, '$1-$2');
|
|
} else if (phoneNumber.startsWith('02')) { // 서울 지역번호
|
|
return phoneNumber.replace(/(\d{2})(\d{3,4})(\d{4})/, '$1-$2-$3');
|
|
} else if (phoneNumber.startsWith('1')) { // 1588, 1566 등
|
|
if (phoneNumber.length <= 8) {
|
|
return phoneNumber.replace(/(\d{4})(\d{4})/, '$1-$2');
|
|
} else {
|
|
return phoneNumber.replace(/(\d{4})(\d{3,4})(\d{4})/, '$1-$2-$3');
|
|
}
|
|
} else { // 그 외 지역번호 또는 휴대전화
|
|
return phoneNumber.replace(/(\d{3})(\d{3,4})(\d{4})/, '$1-$2-$3');
|
|
}
|
|
}
|
|
</script> |