과금 페이지 수정

This commit is contained in:
현성필
2025-11-17 11:14:22 +09:00
parent 5af11f8d55
commit ac59d4109c
9 changed files with 428 additions and 547 deletions
@@ -119,7 +119,7 @@ public class CommissionController {
@PostMapping()
public ResponseEntity<?> list(@RequestBody CommissionSearch search) {
CommissionDTO commissionDTO = null;
search.setProvider(providerCode);
search.setPartnerCode(SecurityUtil.getUserOrg().getOrgCode());
if (!StringUtils.isEmpty(search.getPartnerCode())) {
@@ -157,50 +157,6 @@ public class CommissionController {
return ErrorUtil.create("fail.commission.needPartnerCode");
}
@GetMapping("/print1/{year}/{month}")
public ResponseEntity<?> print(
@PathVariable("year") String year,
@PathVariable("month") String month) {
CommissionDTO commissionDTO = null;
CommissionSearch search = new CommissionSearch();
search.setOrganization(SecurityUtil.getPortalAuthenticatedUser().getPortalOrg());
search.setProvider(providerCode);
search.setYear(year);
search.setMonth(month);
search.setPartnerCode(SecurityUtil.getUserOrg().getOrgCode());
if (!StringUtils.isEmpty(search.getPartnerCode())) {
try {
String url = obmUrl + Constants.COMMISSION_PRINT_URL;
String result = externalService.getResponseHttpPost(url, toJson(search));
HashMap<String, Object> returnObj = new ObjectMapper().readValue(result, HashMap.class);
if (StringUtils.pathEquals(search.getPartnerCode(), "000002-01")) {
log.debug("Found Together : " + search.getPartnerCode());
search.setPartnerCode("000002-02");
String togetherResult = externalService.getResponseHttpPost(url, toJson(search));
HashMap<String, Object> togetherLendingReturnObj = new ObjectMapper().readValue(togetherResult, HashMap.class);
log.debug("togetherLendingReturnObj : " + togetherLendingReturnObj.toString());
if (!StringUtils.isEmpty(togetherLendingReturnObj.get("error"))) {
HashMap<String, Object> error = (HashMap) togetherLendingReturnObj.get("error");
return ErrorUtil.create("fail.commission.serverError", error.get("message").toString());
}
HashMap<String, Object> mergeMap = mergeCommissionData(returnObj, togetherLendingReturnObj);
result = new ObjectMapper().writeValueAsString(mergeMap);
}
commissionDTO = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).readValue(result, CommissionDTO.class);
} catch (Exception e) {
log.warn(e.getMessage(), e);
return ErrorUtil.create("fail.commission.list", "수수료 조회에 실패하였습니다.");
}
return ResponseEntity.ok().body(commissionDTO);
}
return ErrorUtil.create("fail.commission.needPartnerCode");
}
private String toJson(CommissionSearch search) {
try {
Map<String, String> jsonMap = new HashMap<>();
+32 -11
View File
@@ -11947,6 +11947,7 @@ select.form-control {
border: 1px solid #E2E8F0;
border-radius: 6px;
font-size: 14px;
min-width: 100px;
}
.form-inline {
@@ -12132,35 +12133,55 @@ select.form-control {
-webkit-overflow-scrolling: touch;
}
}
.commission-print-page {
body.commission-print-page {
font-size: 12px;
}
.commission-print-page body {
width: 600px;
margin: 90px;
font-family: "Noto Sans KR", -apple-system, sans-serif;
}
.commission-print-page table {
body.commission-print-page div {
position: relative;
}
body.commission-print-page table {
border-collapse: collapse;
}
.commission-print-page table th,
.commission-print-page table td {
body.commission-print-page table th,
body.commission-print-page table td {
padding: 5px 10px;
}
.commission-print-page table tr {
body.commission-print-page table tr {
font-size: 12px;
}
.commission-print-page h1 {
body.commission-print-page h1 {
text-align: center;
}
.commission-print-page h1 img {
body.commission-print-page h1 img {
width: 300px;
}
.commission-print-page h2 {
body.commission-print-page h2 {
margin-top: 40px;
float: left;
}
.commission-print-page p {
body.commission-print-page p {
line-height: 1.6;
}
body.commission-print-page p[style*="float: right"] {
margin-top: 25px;
}
body.commission-print-page .btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
body.commission-print-page .btn-primary {
background: #667eea;
color: white;
}
body.commission-print-page .btn-primary:hover {
background: #5a67d8;
}
.container {
max-width: 1280px;
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -45,6 +45,7 @@
border: 1px solid $border-gray;
border-radius: $border-radius-sm;
font-size: $font-size-sm;
min-width: 100px;
}
}
@@ -258,12 +259,15 @@
}
// Commission Print Page Specific
.commission-print-page {
// Note: commissionPrint.html uses body class for scoping
body.commission-print-page {
font-size: 12px;
width: 600px;
margin: 90px;
font-family: 'Noto Sans KR', -apple-system, sans-serif;
body {
width: 600px;
margin: 90px;
div {
position: relative;
}
table {
@@ -289,9 +293,32 @@
h2 {
margin-top: $spacing-2xl;
float: left;
}
p {
line-height: 1.6;
&[style*="float: right"] {
margin-top: 25px;
}
}
// Print buttons
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.btn-primary {
background: #667eea;
color: white;
&:hover {
background: #5a67d8;
}
}
}
@@ -3,22 +3,15 @@
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/kjbank_base_layout}">
<head>
<title>수수료 관리</title>
<title>수수료 관리</title>
</head>
<body>
<section layout:fragment="contentFragment" class="content">
<div class="row wrap" style="max-width: 1400px; margin: 0 auto; padding: 20px;">
<div class="col-md-12">
<h2><strong>기관 수수료 관리</strong></h2>
<p class="searchInfo">
<button class="btn btn-default" onclick="downloadExcel()" style="display:none;">다운로드</button>
</p>
<p class="searchInfo">
<button id="printBtn" class="btn btn-default" style="margin-left: 5px; display:none;" onclick="printCommission()">
<span>청구서 출력</span>
</button>
</p>
<div class="searchBox row-two" style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; display: flex; align-items: center; gap: 20px; flex-wrap: wrap;">
<div class="row wrap" style="max-width: 1400px; margin: 0 auto; padding: 20px;">
<div class="col-md-12">
<h2><strong>기관 수수료 관리</strong></h2>
<div class="searchBox row-two" style="background: #f8f9fa; padding: 20px; border-radius: 8px; margin-bottom: 20px; display: flex; align-items: center; gap: 20px; flex-wrap: wrap;">
<span class="form-inline" style="display: flex; align-items: center; gap: 10px;">
<label for="providers" style="font-weight: 500; min-width: 80px;">제공기관</label>
<select id="providers" class="form-control">
@@ -27,19 +20,20 @@
<option value="2">한국은행</option>
</select>
</span>
<span class="form-inline" style="display: flex; align-items: center; gap: 10px;">
<span class="form-inline" style="display: flex; align-items: center; gap: 10px;">
<label for="organizations" style="font-weight: 500; min-width: 80px;">이용기관</label>
<select id="organizations" class="form-control">
<option value="">- 선택 -</option>
<option value="1" selected th:text="${organization?.orgName ?: 'ABC 핀테크'}"></option>
</select>
</span>
<span class="form-inline" style="display: flex; align-items: center; gap: 10px;">
<span class="form-inline" style="display: flex; align-items: center; gap: 10px;">
<label for="forYear" style="font-weight: 500; min-width: 80px;">조회기간</label>
<select id="forYear" class="form-control">
<option value="">- 선택 -</option>
<option value="2023">2023</option>
<option value="2024" selected>2024</option>
<option value="2024">2024</option>
<option value="2025" selected>2025</option>
</select> <span></span>&nbsp;&nbsp;
<select id="forMonth" class="form-control">
<option value="">- 선택 -</option>
@@ -57,274 +51,246 @@
<option value="12">12</option>
</select> <span></span>
</span>
<span class="btnBox" style="margin-left: auto;">
<span class="btnBox" style="margin-left: auto;">
<button type="button" class="btn btn-primary" onclick="loadData()">
<span class="glyphicon glyphicon-search"></span>&nbsp;<span>조회</span>
</button>
<button type="button" id="printBtn" class="btn btn-secondary" style="margin-left: 5px; display:none;" onclick="printCommission()">
<span>청구서 출력</span>
</button>
</span>
</div>
<p class="voffset3" style="color: #dc3545; margin-top: 30px;">
이용기관은 매월 1~5일 전월 수수료 조회 가능하며, 10일 확정금액으로 정산됩니다. <br/>
금액이상시 담당자 연락 및 조정요청 하시기 바랍니다. (매월 1~5일 수수료 조회, 6~9일 수수료 조정 및 확정, 10일 정산)
</p>
</div>
<p class="voffset3" style="color: #dc3545; margin-top: 30px;">
이용기관은 매월 1~5일 전월 수수료 조회 가능하며, 10일 확정금액으로 정산됩니다. <br/>
금액이상시 담당자 연락 및 조정요청 하시기 바랍니다. (매월 1~5일 수수료 조회, 6~9일 수수료 조정 및 확정, 10일 정산)
</p>
<!-- API 수수료 테이블 -->
<div class="table-responsive voffset3" style="overflow-x: auto; margin-top: 30px;">
<table class="table table-bordered border-type" style="border: 2px solid #dee2e6;">
<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>
<!-- API 수수료 테이블 -->
<div class="table-responsive voffset3" style="overflow-x: auto; margin-top: 30px;">
<table class="table table-bordered border-type" style="border: 2px solid #dee2e6;">
<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" style="border: 2px solid #dee2e6; margin-top: 30px;">
<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" style="border: 2px solid #dee2e6; margin-top: 30px;">
<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" style="border: 2px solid #dee2e6; margin-top: 30px;">
<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="bg-warning" style="background-color: #fff3cd !important;">
<td class="text-center"><strong id="totalTitle">2024년 3월 합계</strong></td>
<td class="text-right"><strong id="totalSalesAmount1">0</strong></td>
<td class="text-right"><strong id="totalCount1">0</strong></td>
<td class="text-right"><strong class="color_blue" style="font-size:16px; color: #007bff;" id="totalAmount1">0</strong></td>
<td class="text-right"><strong id="totalSalesAmount2">0</strong></td>
<td class="text-right"><strong id="totalCount2">0</strong></td>
<td class="text-right"><strong class="color_blue" style="font-size:16px; color: #007bff;" id="totalAmount2">0</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 합계 테이블 -->
<table class="table table-bordered border-type voffset3" style="border: 2px solid #dee2e6; margin-top: 30px;">
<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="bg-warning" style="background-color: #fff3cd !important;">
<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="color_blue" style="font-size:16px; color: #007bff;" 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="color_blue" style="font-size:16px; color: #007bff;" id="totalAmount2">-</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</section>
<th:block layout:fragment="contentScript">
<script th:inline="javascript">
// 샘플 데이터
const sampleData = {
apiCommissions: [
{
name: '계좌잔액조회',
count1: 20543, fee1: 50, min1: 500000, amount1: 1027150,
count2: 20543, fee2: 50, min2: 500000, amount2: 1027150,
reason: ''
},
{
name: '거래내역조회',
count1: 11876, fee1: 80, min1: 500000, amount1: 950080,
count2: 11876, fee2: 80, min2: 500000, amount2: 950080,
reason: ''
},
{
name: '송금 API',
count1: 4892, fee1: 200, min1: 500000, amount1: 978400,
count2: 4892, fee2: 200, min2: 500000, amount2: 978400,
reason: ''
},
{
name: '본인인증 API',
count1: 2341, fee1: 150, min1: 300000, amount1: 351150,
count2: 2100, fee2: 150, min2: 300000, amount2: 315000,
reason: '오류건 제외'
}
],
saleCommissions: [
{
name: '개인대출 상품 A',
type: '정률',
base: '금액',
division: '원',
salesAmount: 1050000000,
fee1: 0.025, count1: 55, min1: 100000, amount1: 275000,
fee2: 0.025, count2: 55, min2: 100000, amount2: 275000,
reason: ''
},
{
name: '기업대출 상품 B',
type: '정액',
base: '건',
division: '건',
salesAmount: 0,
fee1: 8000, count1: 21, min1: 100000, amount1: 168000,
fee2: 8000, count2: 21, min2: 100000, amount2: 168000,
reason: ''
},
{
name: '소상공인 대출 C',
type: '정액',
base: '건',
division: '건',
salesAmount: 0,
fee1: 3000, count1: 30, min1: 50000, amount1: 90000,
fee2: 3000, count2: 28, min2: 50000, amount2: 84000,
reason: '취소건 제외'
}
]
};
<script th:inline="javascript">
function formatNumber(num) {
return new Intl.NumberFormat('ko-KR').format(num);
}
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-CSRF-TOKEN': /*[[${_csrf.token}]]*/ ''
},
body: JSON.stringify({
year: year,
month: month
})
})
.then(response => {
if (!response.ok) {
throw new Error('데이터 조회에 실패했습니다.');
}
return response.json();
})
.then(data => renderCommissionData(data, year, month))
.catch(error => {
console.error('Error:', error);
customPopups.showAlert('데이터 조회 중 오류가 발생했습니다.');
});
}
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 style="color: #8b0000;">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right"><strong style="color: #007bff;">${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 style="color: #8b0000;">${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 style="color: #8b0000;">${formatNumber(item.sum || 0)}</span></td>
<td class="text-right"><strong style="color: #007bff;">${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 style="color: #8b0000;">${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);
});
function loadData() {
const year = document.getElementById('forYear').value;
const month = document.getElementById('forMonth').value;
if (!year || !month) {
customPopups.showAlert('조회 기간을 선택해주세요.');
return;
}
// API 수수료 테이블 렌더링
const apiTableBody = document.getElementById('apiTableBody');
apiTableBody.innerHTML = '';
let apiTotal1 = 0;
let apiTotal2 = 0;
let apiCount1 = 0;
let apiCount2 = 0;
sampleData.apiCommissions.forEach((item, index) => {
if (index === 0) {
apiTableBody.innerHTML += `
<tr>
<td rowspan="${sampleData.apiCommissions.length}" class="text-center">API<br/>수수료</td>
<td class="text-left">${item.name}</td>
<td class="text-right">${formatNumber(item.count1)}</td>
<td class="text-right">${formatNumber(item.fee1)}</td>
<td class="text-right">${formatNumber(item.min1)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount1)}</span></td>
<td class="text-right"><strong style="color: #007bff;">${formatNumber(item.count2)}</strong></td>
<td class="text-right">${formatNumber(item.fee2)}</td>
<td class="text-right">${formatNumber(item.min2)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount2)}</span></td>
<td>${item.reason}</td>
</tr>
`;
} else {
apiTableBody.innerHTML += `
<tr>
<td class="text-left">${item.name}</td>
<td class="text-right">${formatNumber(item.count1)}</td>
<td class="text-right">${formatNumber(item.fee1)}</td>
<td class="text-right">${formatNumber(item.min1)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount1)}</span></td>
<td class="text-right"><strong style="color: #007bff;">${formatNumber(item.count2)}</strong></td>
<td class="text-right">${formatNumber(item.fee2)}</td>
<td class="text-right">${formatNumber(item.min2)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount2)}</span></td>
<td>${item.reason}</td>
</tr>
`;
}
apiTotal1 += item.amount1;
apiTotal2 += item.amount2;
apiCount1 += item.count1;
apiCount2 += item.count2;
});
// API 소계
apiTableBody.innerHTML += `
// API 소계
apiTableBody.innerHTML += `
<tr>
<td colspan="2" class="text-center">${year}년 ${month}월 API 수수료 소계</td>
<td class="text-right">${formatNumber(apiCount1)}</td>
@@ -339,66 +305,67 @@
</tr>
`;
// 판매 수수료 테이블 렌더링
const saleTableBody = document.getElementById('saleTableBody');
saleTableBody.innerHTML = '';
// 판매 수수료 테이블 렌더링
const saleTableBody = document.getElementById('saleTableBody');
saleTableBody.innerHTML = '';
let saleTotal1 = 0;
let saleTotal2 = 0;
let saleCount1 = 0;
let saleCount2 = 0;
let saleSalesAmount = 0;
let saleTotal1 = 0;
let saleTotal2 = 0;
let saleCount1 = 0;
let saleCount2 = 0;
let saleSalesAmount = 0;
sampleData.saleCommissions.forEach((item, index) => {
if (index === 0) {
saleTableBody.innerHTML += `
saleCommissions.forEach((item, index) => {
const isPercentageFee = item.paymentBaseName === '금액';
if (index === 0) {
saleTableBody.innerHTML += `
<tr>
<td rowspan="${sampleData.saleCommissions.length}" class="text-center">판매<br/>수수료</td>
<td class="text-left">${item.name}</td>
<td>${item.type}</td>
<td>${item.base}</td>
<td>${item.division}</td>
<td class="text-right">${item.salesAmount > 0 ? formatNumber(item.salesAmount) : ''}</td>
<td class="text-right">${item.base === '금액' ? (item.fee1 * 100) + '%' : formatNumber(item.fee1)}</td>
<td class="text-right">${formatNumber(item.count1)}</td>
<td class="text-right">${formatNumber(item.min1)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount1)}</span></td>
<td class="text-right">${item.base === '금액' ? (item.fee2 * 100) + '%' : formatNumber(item.fee2)}</td>
<td class="text-right">${formatNumber(item.count2)}</td>
<td class="text-right">${formatNumber(item.min2)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount2)}</span></td>
<td>${item.reason}</td>
<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 style="color: #8b0000;">${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 style="color: #8b0000;">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
} else {
saleTableBody.innerHTML += `
} else {
saleTableBody.innerHTML += `
<tr>
<td class="text-left">${item.name}</td>
<td>${item.type}</td>
<td>${item.base}</td>
<td>${item.division}</td>
<td class="text-right">${item.salesAmount > 0 ? formatNumber(item.salesAmount) : ''}</td>
<td class="text-right">${item.base === '금액' ? (item.fee1 * 100) + '%' : formatNumber(item.fee1)}</td>
<td class="text-right">${formatNumber(item.count1)}</td>
<td class="text-right">${formatNumber(item.min1)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount1)}</span></td>
<td class="text-right">${item.base === '금액' ? (item.fee2 * 100) + '%' : formatNumber(item.fee2)}</td>
<td class="text-right">${formatNumber(item.count2)}</td>
<td class="text-right">${formatNumber(item.min2)}</td>
<td class="text-right"><span style="color: #8b0000;">${formatNumber(item.amount2)}</span></td>
<td>${item.reason}</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 style="color: #8b0000;">${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 style="color: #8b0000;">${formatNumber(item.sum2 || 0)}</span></td>
<td>${item.changeReason2 || ''}</td>
</tr>
`;
}
saleTotal1 += item.amount1;
saleTotal2 += item.amount2;
saleCount1 += item.count1;
saleCount2 += item.count2;
saleSalesAmount += item.salesAmount;
});
}
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 += `
// 판매 소계
saleTableBody.innerHTML += `
<tr>
<td colspan="5" class="text-center">${year}년 ${month}월 판매 수수료 소계</td>
<td class="text-right">${formatNumber(saleSalesAmount)}</td>
@@ -414,54 +381,33 @@
</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('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';
}
// 출력 버튼 표시
document.getElementById('printBtn').style.display = 'inline-block';
}
function printCommission() {
const year = document.getElementById('forYear').value;
const month = document.getElementById('forMonth').value;
function printCommission() {
const year = document.getElementById('forYear').value;
const month = document.getElementById('forMonth').value;
if (!year || !month) {
customPopups.showAlert('조회 기간을 선택해주세요.');
return;
}
if (!year || !month) {
customPopups.showAlert('조회 기간을 선택해주세요.');
return;
}
// 별도 창으로 청구서 출력 페이지 열기
const printUrl = '/commission/print/' + year + '/' + month;
window.open(printUrl, '_blank', 'width=800,height=900,scrollbars=yes,resizable=yes');
}
function downloadExcel() {
customPopups.showAlert('엑셀 다운로드 기능 (구현 예정)');
}
// 페이지 로드 시 초기 데이터 로드
window.onload = function() {
loadData();
};
</script>
<style>
.glyphicon-search::before {
content: "🔍";
}
@media print {
.searchBox,
.searchInfo {
display: none !important;
}
}
</style>
// 별도 창으로 청구서 출력 페이지 열기
const printUrl = '/commission/print/' + year + '/' + month;
window.open(printUrl, '_blank', 'width=800,height=900,scrollbars=yes,resizable=yes');
}
</script>
</th:block>
</body>
</html>
@@ -3,62 +3,63 @@
<head>
<meta charset="utf-8">
<title>수수료 청구서</title>
<link rel="stylesheet" th:href="@{/content/css/vendor.css}">
<style>
html,body{font-size:12px;}
body{width:600px; margin:90px; font-family: 'Noto Sans KR', -apple-system, sans-serif;}
table{border-collapse: collapse;}
table th, td{padding:5px 10px;}
table tr{font-size:12px;}
.info-table{ border-top: 10px solid gray; width: 100%; border-bottom: 2px solid #333;}
.info-table th{text-align:left;}
.commission-table{width:100%;}
.commission-table th,.commission-table td{border:1px solid #999 !important}
.commission-table td{text-align:right}
.bg_ygreen{background-color:aquamarine; text-align:center}
.bg_skyBlue{background-color:skyblue; text-align:center}
.bg_yellow{background-color:yellow; text-align:center}
<!-- <link rel="stylesheet" th:href="@{/content/css/vendor.css}">-->
<!-- <link rel="stylesheet" th:href="@{/css/main.css}">-->
<style>
html,body{font-size:12px;}
body{width:600px; margin:90px}
table{border-collapse: collapse;}
table th, td{padding:5px 10px;}
table tr{font-size:12px;}
.info-table{ border-top: 10px solid gray; width: 100%; border-bottom: 2px solid #333;}
.info-table th{text-align:left;}
.commission-table{width:100%;}
.commission-table th,.commission-table td{border:1px solid #999 !important}
.commission-table td{text-align:right}
.bg_ygreen{background-color:aquamarine; text-align:center}
.bg_skyBlue{background-color:skyblue; text-align:center}
.bg_yellow{background-color:yellow; text-align:center}
DIV { position: relative; }
DIV { position: relative; }
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary {
background: #667eea;
color: white;
}
.btn-primary:hover {
background: #5a67d8;
}
.btn-primary:hover {
background: #5a67d8;
}
@media print {
@page {
size: auto;
margin: 0 -0cm;
}
html {
margin:0 0cm;
}
#printButton, #backButton {
display: none !important;
}
}
</style>
@media print {
@page {
size: auto;
margin: 0 -0cm;
}
html {
margin: 0 0cm;
}
.control {
display: none !important;
}
}
</style>
</head>
<body>
<button id="backButton" class="btn btn-primary" style="margin-right: 10px;" onclick="history.back()">뒤로가기</button>
<input id="printButton" type="button" class="btn btn-primary" value="청구서 인쇄" onclick="window.print()"/>
<body class="commission-print-page">
<div class="control">
<input id="printButton" type="button" class="btn btn-primary" value="청구서 인쇄" onclick="window.print()"/>
</div>
<div id="PrintDIV">
<h1 style="text-align:center">
<img style="width:300px;" th:src="@{/img/portal/logo.jpg}" alt="광주은행 오픈뱅킹" />
<img style="height:30px;" th:src="@{/img/logo/logo.png}" alt="광주은행 오픈뱅킹" />
</h1>
<p style="text-align:center">우61470 광주광역시 동구 제봉로 225 전화 (062)239-6722 FAX (062)239-6719 오픈뱅크 플랫폼 담당자</p>
@@ -160,71 +161,6 @@
</tr>
</th:block>
</th:block>
<!-- 샘플 데이터 (commission이 null인 경우) -->
<th:block th:if="${commission == null}">
<tr>
<td style="text-align:left">계좌잔액조회</td>
<td></td>
<td>20,543</td>
<td>₩50</td>
<td>₩1,027,150</td>
</tr>
<tr>
<td style="text-align:left">거래내역조회</td>
<td></td>
<td>11,876</td>
<td>₩80</td>
<td>₩950,080</td>
</tr>
<tr>
<td style="text-align:left">송금 API</td>
<td></td>
<td>4,892</td>
<td>₩200</td>
<td>₩978,400</td>
</tr>
<tr>
<td style="text-align:left">본인인증 API</td>
<td></td>
<td>2,341</td>
<td>₩150</td>
<td>₩351,150</td>
</tr>
<tr>
<th class="bg_skyBlue" colspan="4">소계</th>
<td class="bg_skyBlue">₩3,306,780</td>
</tr>
<tr>
<td style="text-align:left">개인대출 상품 A</td>
<td>₩1,050,000,000</td>
<td>55</td>
<td>₩5,000</td>
<td>₩275,000</td>
</tr>
<tr>
<td style="text-align:left">기업대출 상품 B</td>
<td>₩1,680,000,000</td>
<td>21</td>
<td>₩8,000</td>
<td>₩168,000</td>
</tr>
<tr>
<td style="text-align:left">소상공인 대출 C</td>
<td>₩450,000,000</td>
<td>30</td>
<td>₩3,000</td>
<td>₩90,000</td>
</tr>
<tr>
<th class="bg_skyBlue" colspan="4">소계</th>
<td class="bg_skyBlue">₩533,000</td>
</tr>
<tr>
<th class="bg_yellow" colspan="4">합계</th>
<td class="bg_yellow">₩3,839,780</td>
</tr>
</th:block>
</tbody>
</table>
@@ -62,7 +62,7 @@
</li>
<li sec:authorize="hasRole('ROLE_APP')">
<a th:href="@{/myapikey}"><i class="fas fa-key"></i>인증 키 관리</a>
<a th:href="@{/commission/manage}"><i class="fas fa-key"></i>과금 관리</a>
<a th:href="@{/commission/manage}"><i class="fas fa-money-bill"></i>과금 관리</a>
</li>
<li><a th:href="@{/mypage}"><i class="fas fa-user-circle"></i>내 정보 관리</a></li>
<li><a th:href="@{/change_password}"><i class="fas fa-lock"></i>비밀번호 변경</a></li>
@@ -148,11 +148,6 @@
<i class="fas fa-key"></i> 인증 키 관리
</a>
</li>
<!-- <li sec:authorize="hasRole('ROLE_API_KEY_REQUEST_VIEW')">-->
<!-- <a th:href="@{/myapikey/api_key_request/history}" class="drawer-link">-->
<!-- <i class="fas fa-list"></i> 인증키 신청 목록-->
<!-- </a>-->
<!-- </li>-->
<li sec:authorize="isAuthenticated()">
<a th:href="@{/mypage}" class="drawer-link">
<i class="fas fa-user-circle"></i> 내 정보 관리