Files
eapim-portal/src/main/resources/templates/views/apps/commission/commissionManage.html
T
Rinjae ba5b2e61a5 - logback 관련 XML 설정 파일 삭제
- KJBank 레이아웃, 프래그먼트 파일 DJBank로 변경
- HTML 레이아웃 파일 KJBank에서 DJBank로 업데이트
2026-05-24 22:21:57 +09:00

497 lines
21 KiB
HTML

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/djbank_title_layout}">
<head>
<title>수수료 관리</title>
</head>
<body>
<section layout:fragment="title">
<div class="page-title-banner">
<img th:src="@{/img/img_title_bg.png}" class="title-image">
<h1>기관 수수료 관리</h1>
</div>
</section>
<th:block layout:fragment="contentFragment">
<section class="org-register-container">
<div class="searchBox row-two">
<span class="form-inline form-inline--period">
<label for="forYear">조회기간</label>
<span class="period-selects">
<select id="forYear" class="form-control">
<option value="">- 선택 -</option>
</select> <span class="period-unit"></span>
<select id="forMonth" class="form-control">
<option value="">- 선택 -</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select> <span class="period-unit"></span>
</span>
</span>
<span class="btnBox">
<span id="searchedPeriod" class="searched-period" style="display:none; margin-right:10px; font-weight:bold; color:#28a745;"></span>
<button type="button" class="btn btn-primary" onclick="loadData()">
<span class="fa fa-search"></span><span>조회</span>
</button>
<button type="button" id="printBtn" class="btn btn-secondary" onclick="printCommission()">
<span>청구서 출력</span>
</button>
</span>
</div>
<div class="commission-container">
<div class="col-md-12">
<p class="commission-notice">
이용기관은 매월 1~5일 전월 수수료 조회 가능하며, 10일 확정금액으로 정산됩니다. <br/>
금액이상시 담당자 연락 및 조정요청 하시기 바랍니다. (매월 1~5일 수수료 조회, 6~9일 수수료 조정 및 확정, 10일 정산)
</p>
<!-- API 수수료 테이블 -->
<div class="table-responsive">
<table class="table table-bordered border-type">
<colgroup>
<col style="width:6%"/>
<col style="width:16%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col style="width:8%"/>
<col/>
</colgroup>
<thead>
<tr>
<th rowspan="2">구분</th>
<th rowspan="2">API 명</th>
<th colspan="4">조정 전</th>
<th colspan="4">조정 후</th>
<th rowspan="2">조정사유</th>
</tr>
<tr>
<th>처리<br/>건수</th>
<th>적용<br/>수수료(원)</th>
<th>최저<br/>수수료</th>
<th>출금<br/>예상금액</th>
<th>조정<br/>건수</th>
<th>조정<br/>수수료(원)</th>
<th>최저<br/>수수료</th>
<th>출금<br/>예상금액</th>
</tr>
</thead>
<tbody id="apiTableBody">
<!-- 동적 생성 -->
</tbody>
</table>
<!-- 판매 수수료 테이블 -->
<table class="table table-bordered border-type voffset3">
<colgroup>
<col style="width: 6%;">
<col style="width: 8%;">
<col style="width: 8%;">
<col style="width: 5%;">
<col style="width: 5%;">
<col style="width: 7%;">
<col style="width: 6%;">
<col style="width: 6%;">
<col style="width: 7%;">
<col style="width: 7%;">
<col style="width: 6%;">
<col style="width: 6%;">
<col style="width: 7%;">
<col style="width: 7%;">
<col>
</colgroup>
<thead>
<tr>
<th rowspan="2">구분</th>
<th rowspan="2">과금대상<br/>업무</th>
<th rowspan="2">수수료<br/>유형</th>
<th rowspan="2">과금<br/>기준</th>
<th rowspan="2">값구분</th>
<th rowspan="2">판매액</th>
<th colspan="4">조정 전</th>
<th colspan="4">조정 후</th>
<th rowspan="2">조정사유</th>
</tr>
<tr>
<th>적용<br/>수수료</th>
<th>처리<br/>건수</th>
<th>최저<br/>수수료</th>
<th>출금<br/>예상수수료</th>
<th>적용<br/>수수료</th>
<th>처리<br/>건수</th>
<th>최저<br/>수수료</th>
<th>출금<br/>예상수수료</th>
</tr>
</thead>
<tbody id="saleTableBody">
<!-- 동적 생성 -->
</tbody>
</table>
<!-- 합계 테이블 -->
<table class="table table-bordered border-type voffset3">
<colgroup>
<col/>
<col style="width: 13%"/>
<col style="width: 13%"/>
<col style="width: 13%"/>
<col style="width: 13%"/>
<col style="width: 13%"/>
<col style="width: 13%"/>
</colgroup>
<thead>
<tr>
<th rowspan="2">구분</th>
<th colspan="3">조정 전</th>
<th colspan="3">조정 후</th>
</tr>
<tr>
<th>판매액</th>
<th>처리건수(건)</th>
<th>출금예상금액</th>
<th>판매액</th>
<th>처리건수(건)</th>
<th>출금예상금액</th>
</tr>
</thead>
<tbody>
<tr class="summary-row">
<td class="text-center"><strong id="totalTitle">합계</strong></td>
<td class="text-right"><strong id="totalSalesAmount1">-</strong></td>
<td class="text-right"><strong id="totalCount1">-</strong></td>
<td class="text-right"><strong class="summary-amount" id="totalAmount1">-</strong></td>
<td class="text-right"><strong id="totalSalesAmount2">-</strong></td>
<td class="text-right"><strong id="totalCount2">-</strong></td>
<td class="text-right"><strong class="summary-amount" id="totalAmount2">-</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
</th:block>
<th:block layout:fragment="contentScript">
<script th:inline="javascript">
// 페이지 로드 시 초기화 및 자동 조회
document.addEventListener('DOMContentLoaded', function() {
var noOrgCode = /*[[${noOrgCode}]]*/ false;
if (noOrgCode) {
customPopups.showAlert('제휴기관코드가 등록되지 않았습니다.<br/>관리자에게 문의하세요.', function() {
history.back();
});
return;
}
initializeDateSelects();
// 페이지 로딩 후 자동 조회
loadData();
});
function initializeDateSelects() {
const now = new Date();
const currentYear = now.getFullYear();
const currentMonth = now.getMonth() + 1; // 0-indexed
// 전월 계산
let lastMonth = currentMonth - 1;
let lastMonthYear = currentYear;
if (lastMonth === 0) {
lastMonth = 12;
lastMonthYear = currentYear - 1;
}
// 연도 옵션 동적 생성 (최근 3년)
const yearSelect = document.getElementById('forYear');
for (let year = currentYear; year >= currentYear - 2; year--) {
const option = document.createElement('option');
option.value = year;
option.textContent = year;
if (year === lastMonthYear) {
option.selected = true;
}
yearSelect.appendChild(option);
}
// 월 기본값 설정 (전월)
const monthSelect = document.getElementById('forMonth');
monthSelect.value = lastMonth.toString();
}
function showSearchedPeriod(year, month) {
const searchedPeriodEl = document.getElementById('searchedPeriod');
searchedPeriodEl.textContent = year + '년 ' + month + '월 조회완료';
searchedPeriodEl.style.display = 'inline';
}
function hideSearchedPeriod() {
const searchedPeriodEl = document.getElementById('searchedPeriod');
searchedPeriodEl.style.display = 'none';
}
function formatNumber(num) {
return new Intl.NumberFormat('ko-KR').format(num);
}
function loadData() {
const year = document.getElementById('forYear').value;
const month = document.getElementById('forMonth').value;
if (!year || !month) {
customPopups.showAlert('조회 기간을 선택해주세요.');
return;
}
// 서버에서 데이터 조회 API 호출
fetch('/commission', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': /*[[${_csrf.token}]]*/ ''
},
body: JSON.stringify({
year: year,
month: month
})
})
.then(response => {
return response.json().then(data => {
if (!response.ok) {
// 서버에서 반환한 에러 메시지 추출
const errorMessage = data.description || data.message || '데이터 조회에 실패했습니다.';
throw new Error(errorMessage);
}
return data;
});
})
.then(data => renderCommissionData(data, year, month))
.catch(error => {
console.error('Error:', error);
hideSearchedPeriod();
customPopups.showAlert(error.message || '데이터 조회 중 오류가 발생했습니다.');
});
}
function renderCommissionData(data, year, month) {
// API 수수료 항목 필터링
const apiCommissions = data.list.filter(item => item.paymentTargetType === '01');
const saleCommissions = data.list.filter(item => item.paymentTargetType !== '01');
// API 수수료 테이블 렌더링
const apiTableBody = document.getElementById('apiTableBody');
apiTableBody.innerHTML = '';
let apiTotal1 = 0;
let apiTotal2 = 0;
let apiCount1 = 0;
let apiCount2 = 0;
apiCommissions.forEach((item, index) => {
if (index === 0) {
apiTableBody.innerHTML += `
<tr>
<td rowspan="${apiCommissions.length}" class="text-center">API<br/>수수료</td>
<td class="text-left">${item.paymentTargetName}</td>
<td class="text-right">${formatNumber(item.totalCount || 0)}</td>
<td class="text-right">${formatNumber(item.value || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right"><strong class="color_blue">${formatNumber(item.totalCount2 || 0)}</strong></td>
<td class="text-right">${formatNumber(item.value2 || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount2 || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
} else {
apiTableBody.innerHTML += `
<tr>
<td class="text-left">${item.paymentTargetName}</td>
<td class="text-right">${formatNumber(item.totalCount || 0)}</td>
<td class="text-right">${formatNumber(item.value || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right"><strong class="color_blue">${formatNumber(item.totalCount2 || 0)}</strong></td>
<td class="text-right">${formatNumber(item.value2 || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount2 || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
}
apiTotal1 += parseFloat(item.sum || 0);
apiTotal2 += parseFloat(item.sum2 || 0);
apiCount1 += parseInt(item.totalCount || 0);
apiCount2 += parseInt(item.totalCount2 || 0);
});
// API 소계
apiTableBody.innerHTML += `
<tr>
<td colspan="2" class="text-center">${year}${month}월 API 수수료 소계</td>
<td class="text-right">${formatNumber(apiCount1)}</td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"><strong class="color_blue">${formatNumber(apiTotal1)}</strong></td>
<td class="text-right">${formatNumber(apiCount2)}</td>
<td class="text-right"></td>
<td class="text-right"></td>
<td class="text-right"><strong class="color_blue">${formatNumber(apiTotal2)}</strong></td>
<td></td>
</tr>
`;
// 판매 수수료 테이블 렌더링
const saleTableBody = document.getElementById('saleTableBody');
saleTableBody.innerHTML = '';
let saleTotal1 = 0;
let saleTotal2 = 0;
let saleCount1 = 0;
let saleCount2 = 0;
let saleSalesAmount = 0;
saleCommissions.forEach((item, index) => {
const isPercentageFee = item.paymentBaseName === '금액';
if (index === 0) {
saleTableBody.innerHTML += `
<tr>
<td rowspan="${saleCommissions.length}" class="text-center">판매<br/>수수료</td>
<td class="text-left">${item.paymentTargetName}</td>
<td>${item.detailFeeTypeName || ''}</td>
<td>${item.paymentBaseName || ''}</td>
<td>${item.valueDivisionName || ''}</td>
<td class="text-right">${item.totalValue ? formatNumber(item.totalValue) : ''}</td>
<td class="text-right">${isPercentageFee ? (parseFloat(item.value || 0) * 100) + '%' : formatNumber(item.value || 0)}</td>
<td class="text-right">${formatNumber(item.totalCount || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right">${isPercentageFee ? (parseFloat(item.value2 || 0) * 100) + '%' : formatNumber(item.value2 || 0)}</td>
<td class="text-right">${formatNumber(item.totalCount2 || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount2 || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
} else {
saleTableBody.innerHTML += `
<tr>
<td class="text-left">${item.paymentTargetName}</td>
<td>${item.detailFeeTypeName || ''}</td>
<td>${item.paymentBaseName || ''}</td>
<td>${item.valueDivisionName || ''}</td>
<td class="text-right">${item.totalValue ? formatNumber(item.totalValue) : ''}</td>
<td class="text-right">${isPercentageFee ? (parseFloat(item.value || 0) * 100) + '%' : formatNumber(item.value || 0)}</td>
<td class="text-right">${formatNumber(item.totalCount || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right">${isPercentageFee ? (parseFloat(item.value2 || 0) * 100) + '%' : formatNumber(item.value2 || 0)}</td>
<td class="text-right">${formatNumber(item.totalCount2 || 0)}</td>
<td class="text-right">${formatNumber(item.minimumAmount2 || 0)}</td>
<td class="text-right"><span class="color_darkRed">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
}
saleTotal1 += parseFloat(item.sum || 0);
saleTotal2 += parseFloat(item.sum2 || 0);
saleCount1 += parseInt(item.totalCount || 0);
saleCount2 += parseInt(item.totalCount2 || 0);
saleSalesAmount += parseFloat(item.totalValue || 0);
});
// 판매 소계
saleTableBody.innerHTML += `
<tr>
<td colspan="5" class="text-center">${year}${month}월 판매 수수료 소계</td>
<td class="text-right">${formatNumber(saleSalesAmount)}</td>
<td class="text-right"></td>
<td class="text-right">${formatNumber(saleCount1)}</td>
<td></td>
<td class="text-right"><strong class="color_blue">${formatNumber(saleTotal1)}</strong></td>
<td class="text-right"></td>
<td class="text-right">${formatNumber(saleCount2)}</td>
<td></td>
<td class="text-right"><strong class="color_blue">${formatNumber(saleTotal2)}</strong></td>
<td></td>
</tr>
`;
// 합계 업데이트
document.getElementById('totalTitle').textContent = `${year}${month}월 합계`;
document.getElementById('totalSalesAmount1').textContent = formatNumber(saleSalesAmount);
document.getElementById('totalCount1').textContent = formatNumber(apiCount1 + saleCount1);
document.getElementById('totalAmount1').textContent = formatNumber(apiTotal1 + saleTotal1);
document.getElementById('totalSalesAmount2').textContent = formatNumber(saleSalesAmount);
document.getElementById('totalCount2').textContent = formatNumber(apiCount2 + saleCount2);
document.getElementById('totalAmount2').textContent = formatNumber(apiTotal2 + saleTotal2);
// 출력 버튼 표시
document.getElementById('printBtn').style.display = 'inline-block';
// 조회 기간 표시
showSearchedPeriod(year, month);
}
function printCommission() {
const year = document.getElementById('forYear').value;
const month = document.getElementById('forMonth').value;
if (!year || !month) {
customPopups.showAlert('조회 기간을 선택해주세요.');
return;
}
// 먼저 청구서 출력용 API로 데이터 조회하여 에러 여부 확인
fetch('/commission/print/check', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': /*[[${_csrf.token}]]*/ ''
},
body: JSON.stringify({
year: year,
month: month
})
})
.then(response => {
return response.json().then(data => {
if (!response.ok) {
const errorMessage = data.description || data.message || '데이터 조회에 실패했습니다.';
throw new Error(errorMessage);
}
return data;
});
})
.then(data => {
// 에러가 없으면 청구서 출력 페이지 열기
const printUrl = '/commission/print/' + year + '/' + month;
window.open(printUrl, '_blank', 'width=800,height=900,scrollbars=yes,resizable=yes');
})
.catch(error => {
console.error('Error:', error);
customPopups.showAlert(error.message || '청구서 조회 중 오류가 발생했습니다.');
});
}
</script>
</th:block>
</body>
</html>