This commit is contained in:
@@ -66,6 +66,8 @@ $routes->group('', ['namespace' => 'App\Controllers\Article'], static function (
|
||||
$routes->get('getResultList', 'Receipt::getResultList');
|
||||
$routes->get('excel', 'Receipt::excel');
|
||||
|
||||
$routes->post('saveTel', 'Receipt::saveTel'); // 연락가능전화 저장
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -623,6 +625,12 @@ $routes->group('manage', ['namespace' => 'App\Controllers\Manage'], function ($r
|
||||
$routes->get('loginlog/excel', 'LoginLog::excel');
|
||||
});
|
||||
|
||||
/**
|
||||
* 금리비교
|
||||
*/
|
||||
$routes->group('interest_rates', ['namespace' => 'App\Controllers\Interest'], function ($routes) {
|
||||
$routes->get('interest/lists', 'Rates::lists');
|
||||
});
|
||||
|
||||
/**
|
||||
* 로그인 API
|
||||
|
||||
@@ -173,4 +173,28 @@ class Receipt extends BaseController
|
||||
|
||||
return view("pages/article/receipt/detail", $this->data);
|
||||
}
|
||||
|
||||
|
||||
// 연락처 저장
|
||||
public function saveTel()
|
||||
{
|
||||
try {
|
||||
|
||||
$tel = $this->request->getPost('agent_tel');
|
||||
|
||||
$this->model->saveTel($tel);
|
||||
|
||||
|
||||
return $this->response->setJSON([
|
||||
'code' => '0',
|
||||
'msg' => 'success'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return $this->response->setJSON([
|
||||
'code' => '9',
|
||||
'msg' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
40
app/Controllers/Interest/Rates.php
Normal file
40
app/Controllers/Interest/Rates.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
namespace App\Controllers\Interest;
|
||||
|
||||
use App\Controllers\BaseController;
|
||||
use App\Models\common\CodeModel;
|
||||
use App\Models\interest\RatesModel;
|
||||
|
||||
class Rates extends BaseController
|
||||
{
|
||||
private $model, $codeModel;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->model = new RatesModel();
|
||||
$this->codeModel = new CodeModel();
|
||||
}
|
||||
|
||||
public function lists(): string
|
||||
{
|
||||
|
||||
$codes = $this->codeModel->getCodeLists(['BANK', 'INSURANCE', 'LOAN_PLACE']); // 코드조회
|
||||
|
||||
$placeArr = [];
|
||||
foreach ($codes as $c) {
|
||||
if ($c['category'] == "LOAN_PLACE") {
|
||||
array_push($placeArr, $c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$data = $this->model->getLists();
|
||||
|
||||
|
||||
$this->data['place'] = $placeArr;
|
||||
$this->data['data'] = $data;
|
||||
|
||||
return view("pages/interest/list", $this->data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1253,4 +1253,54 @@ class ReceiptModel extends Model
|
||||
|
||||
return $query2->getResultArray();
|
||||
}
|
||||
|
||||
// 연락처 저장
|
||||
public function saveTel($rcpt_sq, $tel)
|
||||
{
|
||||
$this->db->transStart();
|
||||
$usr_id = session('usr_id');
|
||||
|
||||
$sql = "SELECT rcpt_stat, agent_tel FROM receipt WHERE rcpt_sq = ?";
|
||||
$data = [$rcpt_sq];
|
||||
$query = $this->db->query($sql, $data);
|
||||
$row = $query->getRowArray();
|
||||
|
||||
$sql = "UPDATE receipt" .
|
||||
" SET agent_tel = ?" .
|
||||
" WHERE rcpt_sq = ?";
|
||||
$data = [$tel, $rcpt_sq];
|
||||
|
||||
|
||||
if ($query = $this->db->query($sql, $data) === false) {
|
||||
return [
|
||||
'success' => false,
|
||||
'msg' => '저장실패',
|
||||
];
|
||||
}
|
||||
|
||||
$this->saveChangedHistory($rcpt_sq, $row['rcpt_stat'], 'C20', $usr_id, $row['agent_tel']);
|
||||
|
||||
$this->db->transComplete();
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function saveChangedHistory($rcpt_sq, $rcpt_stat, $changed_type, $usr_id, $remark)
|
||||
{
|
||||
$sql = "INSERT INTO changed_history" .
|
||||
" (rcpt_sq, rcpt_stat, changed_type, changed_id, changed_tm, remark)" .
|
||||
" VALUES" .
|
||||
" (?, ?, ?, ?, now(), ?)";
|
||||
$data = [
|
||||
$rcpt_sq,
|
||||
$rcpt_stat,
|
||||
$changed_type,
|
||||
$usr_id,
|
||||
$remark
|
||||
];
|
||||
$res = $this->db->query($sql, $data);
|
||||
}
|
||||
}
|
||||
44
app/Models/interest/RatesModel.php
Normal file
44
app/Models/interest/RatesModel.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
namespace App\Models\interest;
|
||||
|
||||
use CodeIgniter\Model;
|
||||
|
||||
class RatesModel extends Model
|
||||
{
|
||||
|
||||
public function getLists()
|
||||
{
|
||||
|
||||
$builder = $this->db->table("tb_lender AS a");
|
||||
|
||||
$builder->select("a.seq
|
||||
, IFNULL(CASE
|
||||
WHEN a.bank_type = 'B' THEN (SELECT cd_nm FROM codes WHERE cd = a.bank AND category = 'BANK')
|
||||
WHEN a.bank_type = 'I' THEN (SELECT cd_nm FROM codes WHERE cd = a.bank AND category = 'INSURANCE') END, a.bank_nm) AS bank
|
||||
, a.bank_type
|
||||
, a.product
|
||||
, a.tel
|
||||
, a.min_rate
|
||||
, a.avg_rate
|
||||
, a.max_rate
|
||||
, a.chg_yn
|
||||
, a.split_yn
|
||||
, b.extra_fee
|
||||
, b.late_rate
|
||||
, b.join_method
|
||||
, b.prepay_fee
|
||||
, b.loan_limit
|
||||
, IFNULL(DATE_FORMAT(b.prov_date, '%Y-%m-%d'), '') AS prov_date");
|
||||
|
||||
$builder->join("tbl_lender_dtl AS b", "b.seq = a.seq", "LEFT");
|
||||
|
||||
|
||||
$builder->where("a.use_yn", "Y");
|
||||
|
||||
|
||||
// $builder->orderBy('a.seq', 'DESC');
|
||||
|
||||
return $builder->get()->getResultArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,7 +98,7 @@ $usr_level = session('usr_level');
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<input type="text" id="agent_tel" name="agent_tel" class="form-control form-control-sm" maxlength="16"
|
||||
value="<?= esc($agent_tel) ?>" style="max-width: 220px;" />
|
||||
<button type="button" class="btn btn-sm btn-outline-light">저장</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-light" onclick="fn_save_tel();">저장</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -109,6 +109,8 @@ $usr_level = session('usr_level');
|
||||
</div>
|
||||
|
||||
<!-- 매물정보 -->
|
||||
<form id="rcptFrm" onsubmit="return false;">
|
||||
<input type="hidden" name="rcpt_product" id="rcpt_product" value="<?= $data['rcpt_product'] ?>" />
|
||||
<div class="main-card mb-3 card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">매물 정보</h5>
|
||||
@@ -151,7 +153,7 @@ $usr_level = session('usr_level');
|
||||
<td><?= $data['rcpt_product_nm'] ?></td>
|
||||
<th>거래구분</th>
|
||||
<td>
|
||||
<select class="form-select" id="trade_type" disabled>
|
||||
<select class="form-select" id="trade_type" onchange="trade_type_onchange();" disabled>
|
||||
<option value="">거래구분</option>
|
||||
<?php foreach ($codes as $c): ?>
|
||||
<?php if ($c['category'] === "TRADE_TYPE"): ?>
|
||||
@@ -229,8 +231,6 @@ $usr_level = session('usr_level');
|
||||
$chk_array = ['B01', 'B02', 'B03'];
|
||||
$show_sale_premium = (in_array(($data['rcpt_product'] ?? ''), $chk_array) || ($data['trade_type'] ?? '') === 'A1');
|
||||
|
||||
// 월세 영역 노출(서버에서 1차 결정: 값이 있으면 보여주기 / 없으면 숨김)
|
||||
$show_monthly = (!empty($v3));
|
||||
?>
|
||||
|
||||
<!-- 보증금/금액 -->
|
||||
@@ -242,7 +242,7 @@ $usr_level = session('usr_level');
|
||||
</div>
|
||||
|
||||
<!-- 월세(월) -->
|
||||
<div id="div_trade_type_price_monthly" class="<?= $show_monthly ? '' : 'd-none' ?>">
|
||||
<div id="div_trade_type_price_monthly">
|
||||
<div class="d-flex align-items-center gap-1 flex-wrap">
|
||||
<input type="text" class="form-control form-control-sm" name="rcpt_product_info3"
|
||||
id="rcpt_product_info3" value="<?= esc($v3) ?>" style="width: 110px;" disabled />
|
||||
@@ -268,9 +268,11 @@ $usr_level = session('usr_level');
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- 버튼 -->
|
||||
<div class="d-flex align-items-center gap-1 mt-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-light btn-edit">수정</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-success btn-save">가격수정</button>
|
||||
<div class="d-flex align-items-center justify-content-end gap-1 mt-2">
|
||||
<button type="button" class="btn btn-sm btn-outline-light btn-edit"
|
||||
onclick="editPriceInfo();">수정</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-success btn-save"
|
||||
onclick="modifyPriceInfo();">가격수정</button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -299,12 +301,25 @@ $usr_level = session('usr_level');
|
||||
?>
|
||||
<td class="d-flex gap-1">
|
||||
<input type="text" class="form-control" name="rcpt_floor" id="rcpt_floor"
|
||||
value="<?= $data['rcpt_floor'] ?>" size="8" maxlength="3" disabled="disabled" style="width: 100px;" />
|
||||
value="<?= $data['rcpt_floor'] ?>" size="8" maxlength="3" disabled="disabled"
|
||||
style="width: 100px;" />
|
||||
<input type="text" class="form-control" name="rcpt_floor2" id="rcpt_floor2"
|
||||
value="<?= $data['rcpt_floor2'] ?>" size="8" maxlength="3" disabled="disabled"
|
||||
style="width: 100px;" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="spc">
|
||||
<th></th>
|
||||
<td></td>
|
||||
<th>면적확인파일1</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr class="spc">
|
||||
<th>방</th>
|
||||
<td></td>
|
||||
<th>면적확인파일2</th>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>지도좌표</th>
|
||||
<td class="d-flex text-nowrap gap-1">
|
||||
@@ -1061,7 +1076,8 @@ $usr_level = session('usr_level');
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div class="fw-semibold">분양권 (최대 5장)</div>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="viewFilePop('I8', '0')">파일</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="viewFilePop('I8', '0')">파일</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
@@ -1080,7 +1096,8 @@ $usr_level = session('usr_level');
|
||||
<div class="fw-semibold">매물사진 (최대 15장)</div>
|
||||
|
||||
<div class="d-flex gap-1 flex-wrap">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="viewFilePop('I4', '')">파일</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="viewFilePop('I4', '')">파일</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="saveImgOrder('I4', 'M201')">저장</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger"
|
||||
@@ -1249,6 +1266,7 @@ $usr_level = session('usr_level');
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- 정보변경 이력 -->
|
||||
<div class="main-card mb-3 card">
|
||||
@@ -1302,6 +1320,8 @@ $usr_level = session('usr_level');
|
||||
|
||||
$(function () {
|
||||
|
||||
trade_type_onchange();
|
||||
|
||||
map = new naver.maps.Map('mapArea', {
|
||||
center: new naver.maps.LatLng(lat, lng),
|
||||
useStyleMap: true,
|
||||
@@ -1323,8 +1343,128 @@ $usr_level = session('usr_level');
|
||||
map: map
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
function trade_type_onchange() {
|
||||
var trade_type = $('#trade_type').val();
|
||||
if (trade_type == 'B2' || trade_type == 'B3') {
|
||||
// 월세...
|
||||
$('#div_trade_type_price_monthly').show();
|
||||
} else {
|
||||
$('#div_trade_type_price_monthly').hide();
|
||||
}
|
||||
}
|
||||
|
||||
// 가격수정 btn
|
||||
function editPriceInfo() {
|
||||
var rcpt_product = $('#rcpt_product').val();
|
||||
var trade_type = $('#trade_type').val();
|
||||
|
||||
$("#trade_type").prop("disabled", false);
|
||||
|
||||
$("#rcpt_product_info2").prop("disabled", false);
|
||||
$("#rcpt_product_info3").prop("disabled", false);
|
||||
|
||||
if (trade_type == "A1") {
|
||||
if (rcpt_product == 'A01' || rcpt_product == 'A02' || rcpt_product == 'A03' || rcpt_product == 'B01' || rcpt_product == 'B02' || rcpt_product == 'B03') {
|
||||
$("#rcpt_product_info4").prop("disabled", false);
|
||||
$("#rcpt_product_info5").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 가격수정 저장
|
||||
function modifyPriceInfo() {
|
||||
swal.fire({
|
||||
text: "저장 하시겠습니까?",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "예",
|
||||
cancelButtonText: "아니오",
|
||||
closeOnConfirm: false,
|
||||
closeOnCancel: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
var params = {
|
||||
'rcpt_sq': '<?= $data['rcpt_sq'] ?>',
|
||||
'agent_tel': $("#agent_tel").val(),
|
||||
};
|
||||
|
||||
callAjax("/article/apt/modifyPriceInfo", params, fn_result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 연락가능전화 저장
|
||||
function fn_save_tel() {
|
||||
swal.fire({
|
||||
text: "저장 하시겠습니까?",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "예",
|
||||
cancelButtonText: "아니오",
|
||||
closeOnConfirm: false,
|
||||
closeOnCancel: true,
|
||||
confirmButtonColor: "#3085d6",
|
||||
cancelButtonColor: "#d33",
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
var params = {
|
||||
'rcpt_sq': '<?= $data['rcpt_sq'] ?>',
|
||||
'agent_tel': $("#agent_tel").val(),
|
||||
};
|
||||
|
||||
callAjax("/article/apt/saveAptMemo", params, fn_result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function callAjax(target, params, callback) {
|
||||
$.ajax({
|
||||
url: target,
|
||||
method: "POST",
|
||||
dataType: "json",
|
||||
data: params,
|
||||
beforeSend: function () {
|
||||
blockUI.blockPage({
|
||||
message: tpl
|
||||
})
|
||||
},
|
||||
complete: function () {
|
||||
blockUI.unblockPage()
|
||||
},
|
||||
success: function (result) {
|
||||
callback(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function fn_result(result) {
|
||||
if (result.code == '0') {
|
||||
Swal.fire({
|
||||
title: "정상 처리되었습니다.",
|
||||
icon: "success",
|
||||
draggable: true
|
||||
})
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1000);
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: result.msg,
|
||||
icon: "error",
|
||||
draggable: true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -669,7 +669,7 @@ $usr_nm = session('usr_nm');
|
||||
if (!rowData) return;
|
||||
|
||||
const rcpt_atclno = rowData.rcpt_atclno;
|
||||
location.href = "<?= site_url('article/dept/detail') ?>/" + rcpt_atclno;
|
||||
location.href = "<?= site_url('article/receipt/detail') ?>/" + rcpt_atclno;
|
||||
});
|
||||
|
||||
|
||||
|
||||
998
app/Views/pages/interest/list.php
Normal file
998
app/Views/pages/interest/list.php
Normal file
@@ -0,0 +1,998 @@
|
||||
<?= $this->extend('layouts/main') ?>
|
||||
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<?php
|
||||
/**
|
||||
* 문자열/JSON/배열 모두 받아서 "항목 리스트"로 정규화
|
||||
* - JSON 배열 문자열: '["a","b"]'
|
||||
* - 개행 문자열: "a\nb"
|
||||
* - 배열: ["a","b"]
|
||||
*/
|
||||
function normalize_lines($v): array
|
||||
{
|
||||
if ($v === null)
|
||||
return [];
|
||||
|
||||
// 이미 배열이면 그대로
|
||||
if (is_array($v)) {
|
||||
return array_values(array_filter(array_map('trim', $v), fn($x) => $x !== ''));
|
||||
}
|
||||
|
||||
$s = trim((string) $v);
|
||||
if ($s === '')
|
||||
return [];
|
||||
|
||||
// JSON 배열 문자열이면 decode
|
||||
if ($s[0] === '[') {
|
||||
$decoded = json_decode($s, true);
|
||||
if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
|
||||
return array_values(array_filter(array_map('trim', $decoded), fn($x) => $x !== ''));
|
||||
}
|
||||
}
|
||||
|
||||
// 개행 기반 분리
|
||||
$lines = preg_split("/\r\n|\r|\n/", $s);
|
||||
return array_values(array_filter(array_map('trim', $lines), fn($x) => $x !== ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* 상세 섹션 렌더
|
||||
*/
|
||||
function render_detail_section(string $title, $value): string
|
||||
{
|
||||
$lines = normalize_lines($value);
|
||||
if (empty($lines))
|
||||
return '';
|
||||
|
||||
$html = '<div class="detail-row">';
|
||||
$html .= '<div class="detail-title">' . esc($title) . '</div>';
|
||||
$html .= '<ul class="detail-list">';
|
||||
foreach ($lines as $line) {
|
||||
$html .= '<li>' . esc($line) . '</li>';
|
||||
}
|
||||
$html .= '</ul></div>';
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* 원리금균등상환
|
||||
* @param float $principal
|
||||
* @param float $annualRate
|
||||
* @param int $years
|
||||
* @return float|int
|
||||
*/
|
||||
function calcEqualPaymentMonthly(float $principal, float $annualRate, int $years): float
|
||||
{
|
||||
$n = $years * 12;
|
||||
$r = ($annualRate / 100.0) / 12.0;
|
||||
|
||||
if ($n <= 0)
|
||||
return 0.0;
|
||||
if (abs($r) < 1e-12)
|
||||
return $principal / $n;
|
||||
|
||||
$pow = pow(1.0 + $r, $n);
|
||||
return ($principal * $r * $pow) / ($pow - 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 원금균등상환
|
||||
* @param float $principal
|
||||
* @param float $annualRate
|
||||
* @param int $years
|
||||
* @return float|int
|
||||
*/
|
||||
function calcEqualPrincipalAvgMonthly(float $principal, float $annualRate, int $years): float
|
||||
{
|
||||
$n = $years * 12;
|
||||
$r = ($annualRate / 100.0) / 12.0;
|
||||
|
||||
if ($n <= 0)
|
||||
return 0.0;
|
||||
|
||||
// 이자합(원금균등): P*r*(n+1)/2 (매달 원금이 선형 감소)
|
||||
$totalInterest = $principal * $r * ($n + 1) / 2.0;
|
||||
|
||||
$totalPayment = $principal + $totalInterest;
|
||||
return $totalPayment / $n;
|
||||
}
|
||||
|
||||
function won(float $v): string
|
||||
{
|
||||
return number_format((int) round($v));
|
||||
}
|
||||
?>
|
||||
|
||||
<style>
|
||||
.product_list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.product-card {
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 12px;
|
||||
padding: 14px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.title-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bank_name {
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
color: #00f;
|
||||
}
|
||||
|
||||
.product_name {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.badges {
|
||||
/*margin-left: auto;*/
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.label_icon {
|
||||
display: inline-block;
|
||||
color: #555;
|
||||
margin: 4px 0 0 5px;
|
||||
border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
font-size: 11px;
|
||||
line-height: 13px;
|
||||
border: 1px solid #555;
|
||||
padding: 2px 6px;
|
||||
vertical-align: top;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.rate_detail {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
|
||||
.rate_detail .rate {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.rate_detail dt {
|
||||
color: #6c757d;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.rate_detail dd {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.rate_text {
|
||||
font-size: 16px;
|
||||
color: #F58027;
|
||||
}
|
||||
|
||||
.text_red {
|
||||
font-size: 14px;
|
||||
color: #F58027;
|
||||
}
|
||||
|
||||
.product-actions {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.collapse-box {
|
||||
margin-top: 12px;
|
||||
border-top: 1px dashed #e9ecef;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
.detail-grid {
|
||||
display: grid;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.detail-row {
|
||||
border: 1px solid #f1f3f5;
|
||||
border-radius: 10px;
|
||||
padding: 12px;
|
||||
background: #fcfcfd;
|
||||
}
|
||||
|
||||
.detail-title {
|
||||
font-weight: 800;
|
||||
font-size: 13px;
|
||||
color: #343a40;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.detail-list {
|
||||
margin: 0;
|
||||
padding-left: 18px;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
.detail-list li {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.detail-foot {
|
||||
margin-top: 10px;
|
||||
font-size: 12px;
|
||||
color: #868e96;
|
||||
}
|
||||
|
||||
table {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.rate-cell {
|
||||
vertical-align: middle !important;
|
||||
/* fallback */
|
||||
padding: 12px 10px;
|
||||
}
|
||||
|
||||
.rate-cell {
|
||||
display: grid;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
/* 세로 가운데 */
|
||||
align-items: flex-start;
|
||||
/* 왼쪽 정렬 */
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.rate-cell span {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.rate-cell p {
|
||||
margin: 2px 0 0;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* ===== Owl wrapper ===== */
|
||||
.owl-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* Owl 내부 overflow/폭 안정화 */
|
||||
.owl-wrap .owl-stage-outer {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Owl 기본 nav/dots는 우리가 커스텀 컨트롤을 쓰므로 숨김 */
|
||||
.product-carousel .owl-nav,
|
||||
.product-carousel .owl-dots {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* ===== 컨트롤 바 ===== */
|
||||
.owl-controls-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-top: 14px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
/* 화살표 버튼 */
|
||||
.owl-controls-bar .owl-btn {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid #dee2e6;
|
||||
background: #fff;
|
||||
color: #212529;
|
||||
font-size: 28px;
|
||||
/* 아이콘 크기 */
|
||||
line-height: 1;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.owl-controls-bar .owl-btn:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.owl-controls-bar .owl-btn:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
/* 비활성(맨 처음/맨 끝) */
|
||||
.owl-controls-bar .owl-btn.is-disabled {
|
||||
opacity: 0.45;
|
||||
cursor: default;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* 1/N 카운터 */
|
||||
.owl-controls-bar .owl-counter {
|
||||
min-width: 74px;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* 모바일 터치 영역 살짝 키우기 */
|
||||
@media (max-width: 576px) {
|
||||
.owl-controls-bar .owl-btn {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.owl-controls-bar .owl-counter {
|
||||
min-width: 84px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="d-grid">
|
||||
<div class="mb-3 card">
|
||||
<div class="tabs-lg-alternate card-header">
|
||||
<ul class="nav nav-justified">
|
||||
<li class="nav-item">
|
||||
<a data-bs-toggle="tab" href="#tab-eg9-0" class="active nav-link" data-cd="all">
|
||||
<div class="widget-number">전체</div>
|
||||
</a>
|
||||
</li>
|
||||
<?php foreach ($place as $p): ?>
|
||||
<li class="nav-item">
|
||||
<a data-bs-toggle="tab" href="#tab-eg9-0" class="nav-link" data-cd="<?= $p['cd'] ?>">
|
||||
<div class="widget-number"><?= $p['cd_nm'] ?></div>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="tab-eg9-0" role="tabpanel">
|
||||
<div class="card-body">
|
||||
<?php
|
||||
// $data: 상품 리스트 배열이라고 가정
|
||||
$chunks = array_chunk($data, 5); // 5개씩 슬라이드 1장
|
||||
?>
|
||||
|
||||
<div class="owl-wrap">
|
||||
<div class="owl-carousel product-carousel">
|
||||
<?php foreach ($chunks as $pageIdx => $items): ?>
|
||||
<div class="item">
|
||||
<ul class="product_list">
|
||||
<?php foreach ($items as $d): ?>
|
||||
<li class="product-card">
|
||||
<div class="product-head">
|
||||
<div class="title-row">
|
||||
<a href="<?= esc($d['bank_url'] ?? '#') ?>" class="bank_name" target="_blank" rel="noopener">
|
||||
<?= esc($d['bank'] ?? '') ?>
|
||||
</a>
|
||||
<span class="product_name"><?= esc($d['product'] ?? '') ?></span>
|
||||
|
||||
<div class="badges">
|
||||
<?php if ($d['chg_yn'] == "Y"): ?>
|
||||
<span class="label_icon">변동금리</span>
|
||||
<?php endif; ?>
|
||||
<?php if ($d['split_yn'] == "Y"): ?>
|
||||
<span class="label_icon">분할상환</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<dl class="rate_detail">
|
||||
<div class="rate">
|
||||
<dt>최저</dt>
|
||||
<dd><strong class="rate_text"><?= esc($d['min_rate'] ?? '-') ?>%</strong></dd>
|
||||
</div>
|
||||
<div class="rate">
|
||||
<dt>최고</dt>
|
||||
<dd><strong class="rate_text"><?= esc($d['max_rate'] ?? '-') ?>%</strong></dd>
|
||||
</div>
|
||||
<div class="rate">
|
||||
<dt>평균</dt>
|
||||
<dd><strong class="rate_text"><?= esc($d['avg_rate'] ?? '-') ?>%</strong></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!-- 액션 버튼 -->
|
||||
<div class="product-actions">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary js-toggle"
|
||||
data-target="#detail-<?= $d['seq'] ?>">
|
||||
상세보기
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary js-toggle"
|
||||
data-target="#pay-<?= $d['seq'] ?>">
|
||||
월평균상환액
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 상세 (접기/펼치기) -->
|
||||
<div class="collapse-box" id="detail-<?= $d['seq'] ?>" hidden>
|
||||
<div class="detail-grid">
|
||||
<?= render_detail_section('대출부대비용', $d['extra_fee'] ?? null) ?>
|
||||
<?= render_detail_section('연체이자율', $d['late_rate'] ?? null) ?>
|
||||
<?= render_detail_section('가입방식', $d['join_method'] ?? null) ?>
|
||||
<?= render_detail_section('중도상환수수료', $d['prepay_fee'] ?? null) ?>
|
||||
<?= render_detail_section('대출한도', $d['loan_limit'] ?? null) ?>
|
||||
<div class="detail-row">
|
||||
<div class="detail-title">상품문의</div>
|
||||
<ul class="detail-list">
|
||||
<li>
|
||||
<?= $d['bank'] ?> <?= $d['tel'] ?? '' ?>
|
||||
</li>
|
||||
<li><a href="https://m.map.naver.com/search2/search.nhn?query=<?= $d['bank'] ?>"
|
||||
target="_blank">지점찾기</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($d['prov_date'])): ?>
|
||||
<div class="detail-foot">금융회사 최종 제공일
|
||||
<?= esc($d['prov_date']) ?>.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 월평균상환액 -->
|
||||
<div class="collapse-box" id="pay-<?= $d['seq'] ?>" hidden>
|
||||
<?php
|
||||
$basis = $d['pay_basis'] ?? '1억원 대출, 10년 분할 상환시';
|
||||
?>
|
||||
<div class="pay-box">
|
||||
<div class="detail-row" style="margin-bottom: 15px;">
|
||||
<ul class="detail-list">
|
||||
<li>
|
||||
<?= esc($basis) ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2" style="width: 30%;">금리</th>
|
||||
<th colspan="2">월평균 상환액</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width: 35%;">원리금 균등상환</th>
|
||||
<th style="width: 35%;">원금 균등상환</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">당월최저</span>
|
||||
<p><strong class="text_red"><?= $d['min_rate'] ?>%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong><?= won(calcEqualPaymentMonthly(100000000, $d['min_rate'], 10)) ?></strong>원
|
||||
</td>
|
||||
<td><strong>
|
||||
<?= won(calcEqualPrincipalAvgMonthly(100000000, $d['min_rate'], 10)) ?>
|
||||
</strong>원
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">당월최고</span>
|
||||
<p><strong class="text_red"><?= $d['max_rate'] ?>%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong><?= won(calcEqualPaymentMonthly(100000000, $d['max_rate'], 10)) ?></strong>원
|
||||
</td>
|
||||
<td><strong>
|
||||
<?= won(calcEqualPrincipalAvgMonthly(100000000, $d['max_rate'], 10)) ?>
|
||||
</strong>원
|
||||
</td>
|
||||
</tr>
|
||||
<?php if (!empty($d['avg_rate'])): ?>
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">전월평균</span>
|
||||
<p><strong class="text_red"><?= $d['avg_rate'] ?>%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong><?= won(calcEqualPaymentMonthly(100000000, $d['avg_rate'], 10)) ?></strong>원
|
||||
</td>
|
||||
<td><strong>
|
||||
<?= won(calcEqualPrincipalAvgMonthly(100000000, $d['avg_rate'], 10)) ?>
|
||||
</strong>원
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="detail-foot">
|
||||
<?php if (!empty($d['prov_date'])): ?>
|
||||
<span>금융회사 최종 제공일
|
||||
<?= esc($d['prov_date']) ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="owl-controls-bar">
|
||||
<button type="button" class="owl-btn owl-prev" aria-label="이전">‹</button>
|
||||
<div class="owl-counter" aria-live="polite">1 / 1</div>
|
||||
<button type="button" class="owl-btn owl-next" aria-label="다음">›</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.carousel.min.css">
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/assets/owl.theme.default.min.css">
|
||||
<script type="text/javascript"
|
||||
src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.3.4/owl.carousel.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
const datas = <?= json_encode($data, JSON_UNESCAPED_UNICODE); ?>;
|
||||
|
||||
let owlInited = false;
|
||||
|
||||
const esc = (s) => String(s ?? '').replace(/[&<>"']/g, m => ({
|
||||
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
|
||||
}[m]));
|
||||
|
||||
$(function () {
|
||||
|
||||
$('.nav-link').on('click', function () {
|
||||
const cd = $(this).data('cd');
|
||||
|
||||
var arr = new Array();
|
||||
|
||||
rebuildByCd(cd);
|
||||
|
||||
// switch (cd) {
|
||||
// // 전체
|
||||
// case "all":
|
||||
// arr = datas;
|
||||
// break;
|
||||
// // 은행
|
||||
// case "B":
|
||||
// $.each(datas, function (idx, v) {
|
||||
// if (v.bank_type == "B") {
|
||||
// arr.push(v);
|
||||
// }
|
||||
// });
|
||||
// break;
|
||||
// // 저축은행
|
||||
// case "SB":
|
||||
// $.each(datas, function (idx, v) {
|
||||
// if (v.bank_type == "SB") {
|
||||
// arr.push(v);
|
||||
// }
|
||||
// });
|
||||
// break;
|
||||
// // 보험
|
||||
// case "I":
|
||||
// $.each(datas, function (idx, v) {
|
||||
// if (v.bank_type == "I") {
|
||||
// arr.push(v);
|
||||
// }
|
||||
// });
|
||||
// break;
|
||||
// }
|
||||
|
||||
// 다시 렌더링
|
||||
|
||||
});
|
||||
|
||||
|
||||
const $owl = $('.product-carousel');
|
||||
initOwlOnce();
|
||||
|
||||
// ✅ Owl 드래그가 버튼 클릭을 먹어버리는 문제 방지
|
||||
$(document).on('mousedown touchstart pointerdown', '.product-carousel .js-toggle, .product-carousel a', function (e) {
|
||||
e.stopPropagation();
|
||||
});
|
||||
|
||||
// ✅ 클릭도 가끔 막히는 케이스 방지
|
||||
$(document).on('click', '.product-carousel .js-toggle', function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const sel = $(this).data('target');
|
||||
const $target = $(sel);
|
||||
if ($target.length) {
|
||||
$target.prop('hidden', !$target.prop('hidden'));
|
||||
|
||||
// 내용 펼치면 높이 변하니까 autoHeight 갱신
|
||||
setTimeout(() => $('.product-carousel').trigger('refresh.owl.carousel'), 0);
|
||||
}
|
||||
});
|
||||
|
||||
// Bootstrap 탭 전환 완료 후 폭 재계산
|
||||
$(document).on('shown.bs.tab', 'a[data-bs-toggle="tab"]', function () {
|
||||
const $owl = $('.product-carousel');
|
||||
if ($owl.length) {
|
||||
// 숨김->보임 전환 직후엔 약간 텀 주는 게 안정적
|
||||
setTimeout(() => $owl.trigger('refresh.owl.carousel'), 0);
|
||||
}
|
||||
});
|
||||
|
||||
// ===== 외부 버튼 컨트롤 =====
|
||||
$('.owl-controls-bar .owl-prev').on('click', function () {
|
||||
$owl.trigger('prev.owl.carousel');
|
||||
});
|
||||
|
||||
$('.owl-controls-bar .owl-next').on('click', function () {
|
||||
$owl.trigger('next.owl.carousel');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
function initOwlOnce() {
|
||||
if (owlInited) return;
|
||||
owlInited = true;
|
||||
|
||||
$('.product-carousel').owlCarousel({
|
||||
items: 1,
|
||||
loop: false,
|
||||
margin: 16,
|
||||
autoHeight: true,
|
||||
smartSpeed: 250,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
pullDrag: false,
|
||||
onInitialized: updateOwlUI,
|
||||
onTranslated: updateOwlUI,
|
||||
onResized: updateOwlUI
|
||||
});
|
||||
}
|
||||
|
||||
// ===== 카운터 + 버튼 활성/비활성 =====
|
||||
function updateOwlUI(event) {
|
||||
// event가 없는 경우(수동 호출) 대비
|
||||
const e = event || $owl.data('owl.carousel');
|
||||
const carousel = event ? event.relatedTarget : e;
|
||||
|
||||
if (!carousel) return;
|
||||
|
||||
const total = carousel.items().length; // 총 슬라이드 수(= 5개 묶음 페이지 수)
|
||||
const current = carousel.relative(carousel.current()) + 1;
|
||||
|
||||
$('.owl-counter').text(`${current} / ${total}`);
|
||||
|
||||
// 버튼 disable 처리
|
||||
const $prev = $('.owl-controls-bar .owl-prev');
|
||||
const $next = $('.owl-controls-bar .owl-next');
|
||||
|
||||
$prev.toggleClass('is-disabled', current <= 1);
|
||||
$next.toggleClass('is-disabled', current >= total);
|
||||
}
|
||||
|
||||
|
||||
function chunk(arr, size) {
|
||||
const out = [];
|
||||
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
|
||||
return out;
|
||||
}
|
||||
|
||||
// ✅ 카드 HTML 생성 함수 (여기서 너의 카드 마크업을 그대로 문자열로 만들어야 함)
|
||||
function renderCard(d) {
|
||||
// 중요: XSS 방지 필요하면 escape 처리(최소한 텍스트는 escape)
|
||||
|
||||
const badges = `
|
||||
${d.chg_yn === 'Y' ? `<span class="label_icon">변동금리</span>` : ``}
|
||||
${d.split_yn === 'Y' ? `<span class="label_icon">분할상환</span>` : ``}
|
||||
`;
|
||||
|
||||
// detail/pay 영역은 지금 너가 PHP 함수(render_detail_section, won...)를 쓰고 있어서
|
||||
// 프론트에서 완전 동일하게 만들려면 "서버에서 HTML을 내려받는" 방식이 더 좋음.
|
||||
// 일단은 카드 상단(요약)만 재렌더하고 상세는 필요 시 Ajax로 가져오는 패턴 추천.
|
||||
return `
|
||||
<li class="product-card">
|
||||
<div class="product-head">
|
||||
<div class="title-row">
|
||||
<a href="${esc(d.bank_url || '#')}" class="bank_name" target="_blank" rel="noopener">${esc(d.bank)}</a>
|
||||
<span class="product_name">${esc(d.product)}</span>
|
||||
<div class="badges">${badges}</div>
|
||||
</div>
|
||||
<dl class="rate_detail">
|
||||
<div class="rate"><dt>최저</dt><dd><strong class="rate_text">${esc(d.min_rate)}%</strong></dd></div>
|
||||
<div class="rate"><dt>최고</dt><dd><strong class="rate_text">${esc(d.max_rate)}%</strong></dd></div>
|
||||
<div class="rate"><dt>평균</dt><dd><strong class="rate_text">${esc(d.avg_rate)}%</strong></dd></div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="product-actions">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary js-toggle" data-target="#detail-${esc(d.seq)}">상세보기</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary js-toggle" data-target="#pay-${esc(d.seq)}">월평균상환액</button>
|
||||
</div>
|
||||
|
||||
<div class="collapse-box" id="detail-${esc(d.seq)}" hidden>
|
||||
<div class="detail-grid">
|
||||
${render_detail_section('대출부대비용', esc(d.extra_fee))}
|
||||
${render_detail_section('연체이자율', esc(d.late_rate))}
|
||||
${render_detail_section('가입방식', esc(d.join_method))}
|
||||
${render_detail_section('중도상환수수료', esc(d.prepay_fee))}
|
||||
${render_detail_section('대출한도', esc(d.loan_limit))}
|
||||
|
||||
<div class="detail-row">
|
||||
<div class="detail-title">상품문의</div>
|
||||
<ul class="detail-list">
|
||||
<li>${esc(d.bank)}</li>
|
||||
<li>
|
||||
<a href="https://m.map.naver.com/search2/search.nhn?query=<?= $d['bank'] ?>" target="_blank">${esc(d.tel)}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-foot">
|
||||
금융회사 최종 제공일 ${esc(d.prov_date)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="collapse-box" id="pay-${esc(d.seq)}" hidden>
|
||||
${render_rates_section(d)}
|
||||
</div>
|
||||
</li>
|
||||
`;
|
||||
|
||||
|
||||
}
|
||||
|
||||
function renderSlides(list) {
|
||||
const pages = chunk(list, 5);
|
||||
if (!pages.length) {
|
||||
return `<div class="item"><div class="text-center text-muted py-5">데이터가 없습니다.</div></div>`;
|
||||
}
|
||||
|
||||
return pages.map(page => `
|
||||
<div class="item">
|
||||
<ul class="product_list">
|
||||
${page.map(renderCard).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function destroyOwl($owl) {
|
||||
if ($owl.hasClass('owl-loaded')) {
|
||||
$owl.trigger('destroy.owl.carousel');
|
||||
|
||||
// owl이 감싼 wrapper 제거
|
||||
$owl.find('.owl-stage-outer').children().unwrap();
|
||||
$owl.removeClass('owl-center owl-loaded owl-text-select-on');
|
||||
$owl.find('.owl-stage').children().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
function rebuildByCd(cd) {
|
||||
const filtered = (cd === 'all')
|
||||
? datas
|
||||
: datas.filter(x => String(x.bank_type) === String(cd));
|
||||
|
||||
const $owl = $('.product-carousel');
|
||||
destroyOwl($owl);
|
||||
$owl.html(renderSlides(filtered));
|
||||
initOwl($owl);
|
||||
}
|
||||
|
||||
function initOwl($owl) {
|
||||
$owl.owlCarousel({
|
||||
items: 1,
|
||||
loop: false,
|
||||
margin: 16,
|
||||
autoHeight: true,
|
||||
smartSpeed: 250,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
pullDrag: false,
|
||||
onInitialized: updateOwlUI,
|
||||
onTranslated: updateOwlUI,
|
||||
onResized: updateOwlUI
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function render_detail_section(title, value) {
|
||||
|
||||
|
||||
const lines = normalize_lines(value);
|
||||
if (!lines.length) return '';
|
||||
|
||||
str = `
|
||||
<div class="detail-row">
|
||||
<div class="detail-title">${title}</div>
|
||||
<ul class="detail-list">`;
|
||||
|
||||
for (const line of lines) {
|
||||
const text = Array.isArray(line) ? line.join(' ') : String(line ?? '').trim();
|
||||
if (!text) continue;
|
||||
str += `<li>${esc(text)}</li>`;
|
||||
}
|
||||
|
||||
|
||||
str += `
|
||||
</ul>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function render_rates_section(d) {
|
||||
|
||||
var basis = '1억원 대출, 10년 분할 상환시';
|
||||
|
||||
var str = `
|
||||
<div class="pay-box">
|
||||
<div class="detail-row" style="margin-bottom: 15px;">
|
||||
<ul class="detail-list">
|
||||
<li>
|
||||
<?= esc($basis) ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th rowspan="2" style="width: 30%;">금리</th>
|
||||
<th colspan="2">월평균 상환액</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="width: 35%;">원리금 균등상환</th>
|
||||
<th style="width: 35%;">원금 균등상환</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">당월최저</span>
|
||||
<p><strong class="text_red">${esc(d.min_rate)}%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPaymentMonthly(100000000, d.min_rate, 10))}</strong>원
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPaymentMonthly(100000000, d.min_rate, 10))}</strong>원
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">당월최고</span>
|
||||
<p><strong class="text_red">${esc(d.max_rate)}%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPaymentMonthly(100000000, d.max_rate, 10))}/strong>원
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPrincipalAvgMonthly(100000000, d.max_rate, 10))}</strong>원
|
||||
</td>
|
||||
</tr>`;
|
||||
|
||||
if (d.avg_rate != null) {
|
||||
str += `
|
||||
<tr>
|
||||
<td class="rate-cell">
|
||||
<span class="text_black">전월평균</span>
|
||||
<p><strong class="text_red">${esc(d.avg_rate)}%</strong></p>
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPaymentMonthly(100000000, d.avg_rate, 10))} ?></strong>원
|
||||
</td>
|
||||
<td>
|
||||
<strong>${won(calcEqualPrincipalAvgMonthly(100000000, d.avg_rate, 10))}</strong>원
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
str += `
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="detail-foot">
|
||||
<span>금융회사 최종 제공일 ${esc(d.prov_date)}</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function normalize_lines(v) {
|
||||
if (v === null || v === undefined) return [];
|
||||
|
||||
// 이미 배열이면
|
||||
if (Array.isArray(v)) {
|
||||
return v.map(x => String(x).trim()).filter(x => x !== '');
|
||||
}
|
||||
|
||||
let s = String(v).trim();
|
||||
if (!s) return [];
|
||||
|
||||
// JSON 배열 문자열이면
|
||||
if (s.startsWith('[')) {
|
||||
try {
|
||||
const decoded = JSON.parse(s);
|
||||
if (Array.isArray(decoded)) {
|
||||
return decoded.map(x => String(x).trim()).filter(x => x !== '');
|
||||
}
|
||||
} catch (e) { }
|
||||
}
|
||||
|
||||
// 개행 기준 분리
|
||||
return s
|
||||
.split(/\r\n|\r|\n/)
|
||||
.map(x => x.trim())
|
||||
.filter(x => x !== '');
|
||||
}
|
||||
|
||||
// 원리금균등상환
|
||||
function calcEqualPaymentMonthly(principal, annualRate, years) {
|
||||
const n = years * 12;
|
||||
const r = (annualRate / 100.0) / 12.0;
|
||||
|
||||
if (n <= 0) return 0.0;
|
||||
if (Math.abs(r) < 1e-12) return principal / n;
|
||||
|
||||
const pow = Math.pow(1.0 + r, n);
|
||||
return (principal * r * pow) / (pow - 1.0);
|
||||
}
|
||||
|
||||
// 원금균등상환
|
||||
function calcEqualPrincipalAvgMonthly(principal, annualRate, years) {
|
||||
const n = years * 12;
|
||||
const r = (annualRate / 100.0) / 12.0;
|
||||
|
||||
if (n <= 0) return 0.0;
|
||||
|
||||
// 이자합(원금균등): P * r * (n + 1) / 2
|
||||
const totalInterest = principal * r * (n + 1) / 2.0;
|
||||
|
||||
const totalPayment = principal + totalInterest;
|
||||
return totalPayment / n;
|
||||
}
|
||||
|
||||
function won(v) {
|
||||
return Math.round(v).toLocaleString('ko-KR');
|
||||
}
|
||||
</script>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
292
public/plugin/css/loan_rate.css
Normal file
292
public/plugin/css/loan_rate.css
Normal file
@@ -0,0 +1,292 @@
|
||||
@charset "utf-8";
|
||||
|
||||
/* reset */
|
||||
/* body {font-size:1rem;color:#333;line-height:1.5;letter-spacing:0.5px;padding:0;margin:0;overflow-x:hidden;-webkit-text-size-adjust:none;
|
||||
font-family: -apple-system,BlinkMacSystemFont,'Malgun Gothic','맑은 고딕',helvetica,'Apple SD Gothic Neo',helvetica,'나눔바른고딕 옛한글','NanumBarunGothic YetHangul',sans-serif;}
|
||||
*/
|
||||
ul, li,dl,dt,dd {list-style:none;margin:0;padding:0;}
|
||||
a {color:#333;text-decoration:none;}
|
||||
p,h1,h2,h3,h4,h5,h6 {margin:0;}
|
||||
table {width:100%;border-collapse:collapse;border-spacing:0;font-size:inherit;}
|
||||
table th {font-weight:normal;}
|
||||
caption {height:0;width:0;overflow:hidden;font-size:0;line-height:0;text-indent:-99999em;}
|
||||
u {font-style:oblique;text-decoration:none;}
|
||||
html body * {box-sizing:border-box;}
|
||||
|
||||
/* tab */
|
||||
.tab_type01 {height:50px;border-bottom:1px solid #ddd;}
|
||||
.tab_type01 ul:after {content:'';display:block;clear:both;}
|
||||
.tab_type01 ul {border-left:1px solid #ddd;}
|
||||
.tab_type01 ul li {float:left;}
|
||||
.tab_type01 ul li a {display:block;height:49px;padding:0 5px;text-align:center;font-size:13px;color:#666;line-height:49px;border:1px solid #ddd;
|
||||
border-left:none;border-bottom:none;background-color:#f1f1f1;}
|
||||
.tab_type01 ul li a.active {position:relative;height:50px;line-height:48px;color:#333;background-color:#fff;}
|
||||
.tab_type01 ul li a.active:before {content:'';position:absolute;top:-1px;left:-1px;right:-1px;height:2px;background-color:#222;}
|
||||
.tab_type01.col_2 ul li {width:25%;}
|
||||
.tab_view_box {display:none;margin-top:35px;}
|
||||
.tab_view_box.block {display:block;}
|
||||
|
||||
.loan_rate {padding:20px;}
|
||||
.inner {position:relative;}
|
||||
|
||||
.owl_page {text-align:center;padding:0 0 20px 0;}
|
||||
.owl_page > span {display:inline-block;text-align:center;padding:0 10px;}
|
||||
.owl_page .owl_prev_btn,
|
||||
.owl_page .owl_next_btn {cursor:pointer;}
|
||||
.owl_page .owl_counter b {color:#00f;}
|
||||
|
||||
/* 담보대출정보 */
|
||||
.loan_rate .product_list .item {
|
||||
border-top: 1px solid #ddd;
|
||||
padding: 14px 18px 18px 18px;
|
||||
}
|
||||
.loan_rate .product_list .product_title {
|
||||
font-size: 15px;
|
||||
margin-bottom: 1px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
}
|
||||
.loan_rate .product_list .product_title .bank_name {
|
||||
color: #00f;
|
||||
}
|
||||
.loan_rate .product_list .product_title .label_icon {
|
||||
display: inline-block;
|
||||
color:#555;
|
||||
margin: 4px 0 0 5px;
|
||||
border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
font-size: 11px;
|
||||
line-height: 13px;
|
||||
border: 1px solid #555;
|
||||
padding: 2px 6px;
|
||||
vertical-align: top;
|
||||
font-weight: bold;
|
||||
}
|
||||
.loan_rate .product_list .product_title .label_icon + .label_icon {
|
||||
margin-left: 0;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail {
|
||||
overflow: hidden;
|
||||
padding: 0 0 2px;
|
||||
font-size: 13px;
|
||||
line-height: 22px;
|
||||
letter-spacing: -0.5px;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dt {
|
||||
float: left;
|
||||
margin: 3px 12px 0 0;
|
||||
clear: both;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dd {
|
||||
overflow: hidden;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dd.line_align {
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dd.line_align + dt {
|
||||
clear: inherit;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dd strong.rate_text {
|
||||
color: #f7901e;
|
||||
}
|
||||
.loan_rate .product_list .rate_detail dd.line_align:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 0;
|
||||
width: 1px;
|
||||
height: 13px;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 10px 0 0;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail li {
|
||||
display: block;
|
||||
text-align: center;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail li ~ li .option_btn {border-left:none;}
|
||||
.loan_rate .info_detail .list_detail li._foldingWrapper.active .layer_box {display:block;}
|
||||
.loan_rate .info_detail .list_detail li._foldingWrapper.active .option_btn {background-color:#fff;border-bottom:0;}
|
||||
|
||||
.loan_rate .info_detail .list_detail .option_btn {
|
||||
display: block;
|
||||
font-size:12px;
|
||||
padding: 8px 0 0 0;
|
||||
height: 36px;
|
||||
vertical-align: middle;
|
||||
color: #333;
|
||||
background-color: #f2f2f2;
|
||||
border: 1px solid #ddd;
|
||||
border-right: 1px solid #ddd;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .option_btn::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 5px;
|
||||
background: url(../images/ico_arrow_down_gray.png) no-repeat;
|
||||
margin: 5px 0 0 5px;
|
||||
vertical-align: top;
|
||||
background-size:8px auto;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail ._foldingWrapper.active .option_btn::after {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box {
|
||||
display: none;
|
||||
padding: 15px 0 0 15px;
|
||||
border: 1px solid #e4e5e7;
|
||||
border-width: 0px 1px 1px;
|
||||
width: 200%;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail li + li .layer_box {
|
||||
margin-left: -100%;
|
||||
padding:15px 10px 0 15px;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .info_box {
|
||||
margin: -1px 0 0;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info {
|
||||
overflow: hidden;
|
||||
padding-right: 15px;
|
||||
font-size: 13px;
|
||||
line-height: 23px;
|
||||
text-align: left;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info dt {
|
||||
float: left;
|
||||
color: #222;
|
||||
margin: 6px 10px 0 0;
|
||||
font-weight:600;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info dt.none_float {
|
||||
float: none;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info dd {
|
||||
overflow: hidden;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info dt + dd {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .detial_info .none_float + dd {
|
||||
margin-top: 1px;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .layer_box .notice_text {
|
||||
text-align: left;
|
||||
margin: 7px 0 0 0;
|
||||
font-size: 13px;
|
||||
color:#222;
|
||||
line-height: 21px;
|
||||
font-weight:600;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .layer_box .bottom_area {
|
||||
margin: 10px 15px 0 0;
|
||||
border-top: 1px solid #eee;
|
||||
}
|
||||
.loan_rate .info_detail .list_detail .layer_box .bottom_area .btn_close {
|
||||
display: block;
|
||||
font-size:12px;
|
||||
height: 36px;
|
||||
padding: 8px 0 0;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
text-align: center;
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
|
||||
.loan_rate .info_detail .list_detail .table_box table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .table_box thead tr th {
|
||||
color: #222;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
background-color: #f2f2f2;
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px 5px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
.loan_rate .info_detail .list_detail .table_box tbody tr td {
|
||||
font-size: 13px;
|
||||
min-height: 42px;
|
||||
color: #222;
|
||||
vertical-align: middle;
|
||||
border: 1px solid #ddd;
|
||||
padding: 10px 7px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .table_box tbody tr td > span {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .desp_info {
|
||||
padding: 0 15px 10px 0;
|
||||
font-size: 13px;
|
||||
line-height: 23px;
|
||||
color: #222;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .table_box tbody tr td .text_red {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
color: #f7901e;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .sub_info dl {
|
||||
overflow: hidden;
|
||||
font-size: 13px;
|
||||
line-height: 23px;
|
||||
color: #222;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .notice_text + dl {
|
||||
margin: 7px 0 0 0;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .sub_info dl dt {
|
||||
float: left;
|
||||
margin: 3px 10px 0 0;
|
||||
font-size:13px;
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .sub_info dl dd {
|
||||
overflow: hidden;
|
||||
margin-top: 3px;
|
||||
font-weight:400;
|
||||
}
|
||||
|
||||
.loan_rate .info_detail .list_detail .layer_box .sub_info a,
|
||||
.info_detail .list_detail .detial_info dd a {
|
||||
color:#00f;
|
||||
}
|
||||
|
||||
6
public/plugin/css/owl.carousel.min.css
vendored
Normal file
6
public/plugin/css/owl.carousel.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Owl Carousel v2.3.4
|
||||
* Copyright 2013-2018 David Deutsch
|
||||
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
|
||||
*/
|
||||
.owl-carousel,.owl-carousel .owl-item{-webkit-tap-highlight-color:transparent;position:relative}.owl-carousel{display:none;width:100%;z-index:1}.owl-carousel .owl-stage{position:relative;-ms-touch-action:pan-Y;touch-action:manipulation;-moz-backface-visibility:hidden}.owl-carousel .owl-stage:after{content:".";display:block;clear:both;visibility:hidden;line-height:0;height:0}.owl-carousel .owl-stage-outer{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0)}.owl-carousel .owl-item,.owl-carousel .owl-wrapper{-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0)}.owl-carousel .owl-item{min-height:1px;float:left;-webkit-backface-visibility:hidden;-webkit-touch-callout:none}.owl-carousel .owl-item img{display:block;width:100%}.owl-carousel .owl-dots.disabled,.owl-carousel .owl-nav.disabled{display:none}.no-js .owl-carousel,.owl-carousel.owl-loaded{display:block}.owl-carousel .owl-dot,.owl-carousel .owl-nav .owl-next,.owl-carousel .owl-nav .owl-prev{cursor:pointer;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel .owl-nav button.owl-next,.owl-carousel .owl-nav button.owl-prev,.owl-carousel button.owl-dot{background:0 0;color:inherit;border:none;padding:0!important;font:inherit}.owl-carousel.owl-loading{opacity:0;display:block}.owl-carousel.owl-hidden{opacity:0}.owl-carousel.owl-refresh .owl-item{visibility:hidden}.owl-carousel.owl-drag .owl-item{-ms-touch-action:pan-y;touch-action:pan-y;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.owl-carousel.owl-grab{cursor:move;cursor:grab}.owl-carousel.owl-rtl{direction:rtl}.owl-carousel.owl-rtl .owl-item{float:right}.owl-carousel .animated{animation-duration:1s;animation-fill-mode:both}.owl-carousel .owl-animated-in{z-index:0}.owl-carousel .owl-animated-out{z-index:1}.owl-carousel .fadeOut{animation-name:fadeOut}@keyframes fadeOut{0%{opacity:1}100%{opacity:0}}.owl-height{transition:height .5s ease-in-out}.owl-carousel .owl-item .owl-lazy{opacity:0;transition:opacity .4s ease}.owl-carousel .owl-item .owl-lazy:not([src]),.owl-carousel .owl-item .owl-lazy[src^=""]{max-height:0}.owl-carousel .owl-item img.owl-lazy{transform-style:preserve-3d}.owl-carousel .owl-video-wrapper{position:relative;height:100%;background:#000}.owl-carousel .owl-video-play-icon{position:absolute;height:80px;width:80px;left:50%;top:50%;margin-left:-40px;margin-top:-40px;background:url(owl.video.play.png) no-repeat;cursor:pointer;z-index:1;-webkit-backface-visibility:hidden;transition:transform .1s ease}.owl-carousel .owl-video-play-icon:hover{-ms-transform:scale(1.3,1.3);transform:scale(1.3,1.3)}.owl-carousel .owl-video-playing .owl-video-play-icon,.owl-carousel .owl-video-playing .owl-video-tn{display:none}.owl-carousel .owl-video-tn{opacity:0;height:100%;background-position:center center;background-repeat:no-repeat;background-size:contain;transition:opacity .4s ease}.owl-carousel .owl-video-frame{position:relative;z-index:1;height:100%;width:100%}
|
||||
6
public/plugin/css/owl.theme.default.min.css
vendored
Normal file
6
public/plugin/css/owl.theme.default.min.css
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Owl Carousel v2.3.4
|
||||
* Copyright 2013-2018 David Deutsch
|
||||
* Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
|
||||
*/
|
||||
.owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#869791;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#869791}
|
||||
105
public/plugin/js/loan_rate.js
Normal file
105
public/plugin/js/loan_rate.js
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
$(document).ready(function(){
|
||||
// tab
|
||||
$('.tab_type01 a').click(function (e) {
|
||||
var contentid = $(this).attr('title');
|
||||
e.preventDefault();
|
||||
|
||||
$('.tab_type01 .active').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
$('.tab_view_box').removeClass('block');
|
||||
$('#' + contentid).addClass('block');
|
||||
|
||||
$('.owl-carousel.loan_rate_sgroup').trigger('to.owl.carousel', 0);
|
||||
$('.loan_rate ._foldingWrapper').removeClass('active');
|
||||
});
|
||||
|
||||
// content slide.
|
||||
var loanTotalOwl = $('.owl-carousel.type_total');
|
||||
var loanBankOwl = $('.owl-carousel.type_bank');
|
||||
var loanSavingsbankOwl = $('.owl-carousel.type_savingsbank');
|
||||
var loanInsuranceOwl = $('.owl-carousel.type_insurance');
|
||||
|
||||
loanTotalOwl.owlCarousel({
|
||||
items:1,
|
||||
loop: false,
|
||||
nav: false,
|
||||
dots: false,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
onInitialized : counter,
|
||||
onTranslated : counter
|
||||
});
|
||||
|
||||
loanBankOwl.owlCarousel({
|
||||
items:1,
|
||||
loop: false,
|
||||
nav: false,
|
||||
dots: false,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
onInitialized : counter,
|
||||
onTranslated : counter
|
||||
});
|
||||
|
||||
loanSavingsbankOwl.owlCarousel({
|
||||
items:1,
|
||||
loop: false,
|
||||
nav: false,
|
||||
dots: false,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
onInitialized : counter,
|
||||
onTranslated : counter
|
||||
});
|
||||
|
||||
loanInsuranceOwl.owlCarousel({
|
||||
items:1,
|
||||
loop: false,
|
||||
nav: false,
|
||||
dots: false,
|
||||
mouseDrag: false,
|
||||
touchDrag: false,
|
||||
onInitialized : counter,
|
||||
onTranslated : counter
|
||||
});
|
||||
|
||||
$('.loan_rate .owl_prev_btn').click(function() {
|
||||
$(this).closest('.tab_view_box').find('.owl-carousel.loan_rate_sgroup').trigger('prev.owl.carousel');
|
||||
});
|
||||
|
||||
$('.loan_rate .owl_next_btn').click(function() {
|
||||
$(this).closest('.tab_view_box').find('.owl-carousel.loan_rate_sgroup').trigger('next.owl.carousel');
|
||||
})
|
||||
|
||||
function counter(event) {
|
||||
var element = event.target;
|
||||
var items = event.item.count;
|
||||
var item = event.item.index + 1;
|
||||
|
||||
if(item > items) {
|
||||
item = item - items
|
||||
}
|
||||
|
||||
$(element).closest('.tab_view_box').find('.owl_counter').html("<b>" + item + "</b> / " + items);
|
||||
}
|
||||
|
||||
// 상세보기 & 월평균상환액 tab.
|
||||
$('.loan_rate ul.list_detail .option_btn').click(function () {
|
||||
var isActive = $(this).parent('li._foldingWrapper').hasClass('active');
|
||||
|
||||
$(this).closest('ul.list_detail').find('li._foldingWrapper').removeClass('active');
|
||||
|
||||
if(!isActive) {
|
||||
$(this).parent('li._foldingWrapper').addClass('active');
|
||||
} else {
|
||||
$(this).parent('li._foldingWrapper').removeClass('active');
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$('.loan_rate .info_detail .bottom_area .btn_close').click(function () {
|
||||
$(this).closest('ul.list_detail').find('li._foldingWrapper').removeClass('active');
|
||||
});
|
||||
|
||||
});
|
||||
7
public/plugin/js/owl.carousel.min.js
vendored
Normal file
7
public/plugin/js/owl.carousel.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user