Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/main/webapp/WEB-INF/views/common/footer.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
<span id="emailText">solv.developers@gmail.com</span>
<i class="fa-regular fa-copy text-xs opacity-50"></i>
</button>
<button onclick="openPolicyModal()"
class="inline-flex items-center gap-2 px-3 py-1.5 rounded-full border border-slate-200 bg-white/70 text-slate-500
hover:text-[#2F93F7] hover:border-blue-200 transition-colors cursor-pointer">
<i class="fa-solid fa-scale-balanced text-sm"></i>
<span>가격정책</span>
</button>
</div>

<!-- Copyright -->
Expand All @@ -33,6 +39,23 @@
</div>
</footer>

<!-- Policy Modal -->
<div id="policyModal" class="policy-modal-overlay">
<div class="policy-modal-container">
<div class="policy-modal-header">
<h3 class="policy-modal-title">가격 정책 안내</h3>
<button onclick="closePolicyModal()" class="policy-modal-close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="policy-modal-body">
<jsp:include page="/WEB-INF/views/policy/policy.jsp" />
</div>
</div>
</div>

<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/policy/css/policy.css">

<script>
function copyEmail() {
const email = 'solv.developers@gmail.com';
Expand All @@ -45,4 +68,28 @@
}, 1500);
});
}

function openPolicyModal() {
document.getElementById('policyModal').classList.add('active');
document.body.style.overflow = 'hidden';
}

function closePolicyModal() {
document.getElementById('policyModal').classList.remove('active');
document.body.style.overflow = '';
}

// Close modal when clicking outside
document.getElementById('policyModal').addEventListener('click', function(e) {
if (e.target === this) {
closePolicyModal();
}
});

// Close modal on escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && document.getElementById('policyModal').classList.contains('active')) {
closePolicyModal();
}
});
</script>
1 change: 1 addition & 0 deletions src/main/webapp/WEB-INF/views/home.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/main/css/main.css?v=<%= System.currentTimeMillis() %>">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/main/css/promotion.css?v=<%= System.currentTimeMillis() %>">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/main/css/hero.css?v=<%= System.currentTimeMillis() %>">
<link rel="stylesheet" href="${pageContext.request.contextPath}/resources/policy/css/policy.css?v=<%= System.currentTimeMillis() %>">
<!-- Flatpickr -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/themes/material_blue.css">
Expand Down
210 changes: 210 additions & 0 deletions src/main/webapp/WEB-INF/views/policy/policy.jsp
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div class="policy-wrapper">
<h1>항공권 가격 정책 안내</h1>

<p>
flyway의 항공권 가격은 고정된 값이 아닙니다.<br>
출발 시점과 좌석 수요에 따라 <strong>합리적으로 조정되는 동적 가격 정책</strong>을 적용하고 있습니다.
</p>

<p>
이는 항공권의 실제 수요 흐름을 반영하면서도,<br>
고객이 이해할 수 있는 기준과 원칙에 따라 운영됩니다.
</p>

<hr>

<h2>✈️ flyway의 동적 가격 정책 원칙</h2>
<p>flyway는 다음 세 가지 원칙을 기준으로 가격을 산정합니다.</p>
<ul>
<li><strong>이해 가능한 기준</strong>: 가격이 왜 변하는지 설명할 수 있어야 합니다.</li>
<li><strong>과도한 변동 방지</strong>: 단기간 급등·급락은 제한합니다.</li>
<li><strong>공정한 가격 형성</strong>: 인기 노선과 시간대의 수요를 합리적으로 반영합니다.</li>
</ul>

<hr>

<h2>📐 가격 산정 구조</h2>
<p>항공권 가격은 다음과 같은 구조로 계산됩니다.</p>

<div class="note" style="text-align: center; font-weight: bold; font-size: 1.1em;">
목표 가격 = 기본 운임 × 시간 계수 × 좌석 점유율 계수
</div>

<p>
이후, 갑작스러운 가격 변동을 방지하기 위해<br>
이전 가격과의 차이를 단계적으로 반영합니다.
</p>

<div class="note" style="text-align: center; font-weight: bold; font-size: 1.1em;">
최종 가격 = 이전 가격 + 스무딩 계수 × (목표 가격 − 이전 가격)
</div>

<p>이 구조를 통해 수요 변화는 반영하되, 가격은 부드럽게 조정됩니다.</p>

<hr>

<h2>⏳ 출발 시점 반영 (시간 계수)</h2>
<p>
출발일이 가까워질수록 선택 가능한 좌석이 줄어들기 때문에<br>
이에 따른 <strong>시간 프리미엄</strong>이 적용됩니다.
</p>
<ul>
<li>출발까지 시간이 충분한 경우: 가격은 안정적으로 유지되거나 할인 혜택이 적용될 수 있습니다.</li>
<li>출발이 가까워질수록: 수요 집중을 반영해 가격이 점진적으로 상승합니다.</li>
<li>출발 직전: 막바지 예약 증가를 고려한 프리미엄이 적용될 수 있습니다.</li>
</ul>
<p>
시간 계수는 출발일까지 남은 <strong>일(Day) 단위</strong>,<br>
출발 임박 시에는 <strong>시간(Hour) 단위</strong>로 세분화되어 적용됩니다.
</p>

<h3>① Day 기준</h3>
<table>
<tr>
<th>출발까지</th>
<th>계수</th>
<th>의미</th>
</tr>
<tr><td>30일 이상</td><td>0.95</td><td>Early Bird 할인 (-5%)</td></tr>
<tr><td>21일 이상</td><td>1.00</td><td>기준가</td></tr>
<tr><td>14일 이상</td><td>1.10</td><td>+10%</td></tr>
<tr><td>7일 이상</td><td>1.25</td><td>+25%</td></tr>
<tr><td>7일 미만</td><td>1.50</td><td>+50%</td></tr>
</table>

<h3>② Hour 기준</h3>
<table>
<tr>
<th>출발까지</th>
<th>계수</th>
<th>의미</th>
</tr>
<tr><td>48시간 이내</td><td>1.50</td><td>+50%</td></tr>
<tr><td>24시간 이내</td><td>1.60</td><td>+60%</td></tr>
<tr><td>12시간 이내</td><td>1.70</td><td>+70%</td></tr>
<tr><td>6시간 이내</td><td>1.80</td><td>+80%</td></tr>
<tr><td>1시간 이내</td><td>1.90</td><td>출발 직전 프리미엄 (+90%)</td></tr>
</table>

<hr>

<h2>💺 수요 반영 (좌석 점유율 계수)</h2>
<p>좌석 점유율은 해당 항공편의 인기도와 수요를 나타내는 핵심 지표입니다.</p>
<ul>
<li>좌석이 여유로운 경우: 가격은 비교적 안정적으로 유지됩니다.</li>
<li>판매가 진행될수록: 가격은 점진적으로 상승합니다.</li>
<li>매진이 임박한 경우: 수요 집중을 반영한 프리미엄이 적용될 수 있습니다.</li>
</ul>
<p>
좌석 점유율에 따른 가격 변화는<br>
<strong>완만한 구간 → 상승 가속 구간 → 프리미엄 구간</strong>으로 단계적으로 설계되어 있습니다.
</p>

<table>
<tr>
<th>좌석 점유율</th>
<th>계수 변화</th>
<th>의미</th>
</tr>
<tr><td>0% ~ 40%</td><td>완만한 감소</td><td>수요가 낮아 할인 적용</td></tr>
<tr><td>40% ~ 60%</td><td>서서히 상승</td><td>보통 수준의 수요</td></tr>
<tr><td>60% ~ 80%</td><td>빠른 상승</td><td>인기 증가 반영</td></tr>
<tr><td>80% ~ 100%</td><td>급격한 상승</td><td>매진 임박 프리미엄</td></tr>
</table>

<hr>

<h2>🛡 가격 변동 완화 정책 (스무딩)</h2>
<p>
flyway는 가격이 단기간에 급격히 변하지 않도록<br>
<strong>가격 변동 완화 정책(스무딩)</strong>을 적용합니다.
</p>
<ul>
<li>출발까지 시간이 많이 남은 경우: 가격 변화 속도를 제한</li>
<li>출발이 임박한 경우: 시장 상황을 보다 빠르게 반영</li>
</ul>
<p>
또한, 과도한 가격 변동을 방지하기 위해<br>
짧은 시간 내 동일 항공편에 대한 반복적인 가격 재계산은 제한됩니다.
</p>

<h3>① Day 기준</h3>
<table>
<tr>
<th>출발까지</th>
<th>α 값</th>
<th>의미</th>
</tr>
<tr><td>30일 이상</td><td>0.15</td><td>목표가의 15% 반영</td></tr>
<tr><td>14일 이상</td><td>0.20</td><td>목표가의 20% 반영</td></tr>
<tr><td>7일 이상</td><td>0.30</td><td>목표가의 30% 반영</td></tr>
<tr><td>2일 이상</td><td>0.40</td><td>목표가의 40% 반영</td></tr>
</table>

<h3>② Hour 기준</h3>
<table>
<tr>
<th>출발까지</th>
<th>α 값</th>
<th>의미</th>
</tr>
<tr><td>48시간 이내</td><td>0.50</td><td>목표가의 50% 반영</td></tr>
<tr><td>24시간 이내</td><td>0.70</td><td>목표가의 70% 반영</td></tr>
<tr><td>6시간 이내</td><td>1.00</td><td>목표가 즉시 반영</td></tr>
</table>

<hr>

<h2>⏱ 가격 재산정 시점</h2>
<p>항공권 가격은 다음과 같은 경우에 재산정됩니다.</p>
<ul>
<li><strong>출발 30일 이내 항공편</strong>: 매일 자정 기준으로 가격 조정</li>
<li><strong>출발 48시간 이내 항공편</strong>: 1시간 단위로 가격 재산정</li>
<li><strong>결제 또는 환불 발생 시</strong>: 좌석 점유율 변경에 따른 즉시 반영<br>
(단, 10분 이내 중복 재계산은 제한)
</li>
</ul>

<hr>

<h2>ℹ️ 안내 사항</h2>
<ul>
<li>항공권 가격은 실시간으로 변동될 수 있으며, <strong>최종 결제 시점의 가격이 적용</strong>됩니다.</li>
<li>동일한 항공편이라도 예약 시점에 따라 가격이 다를 수 있습니다.</li>
<li>시간 계수, 좌석 점유율 계수, 스무딩 계수는 항공편 특성 및 시장 상황에 따라 유연하게 적용됩니다.</li>
<li>본 가격 정책은 운영 환경에 따라 변경될 수 있습니다.</li>
</ul>

<div class="note">
<h3>flyway의 약속</h3>
<p>
flyway는 가격을 숨기지 않습니다.<br>
대신, <strong>고객이 이해할 수 있는 기준으로 설명하고</strong>,<br>
<strong>공정한 가격 형성</strong>을 목표로 합니다.
</p>
</div>

<h2>특가 항공권 적용 방식 안내</h2>

<p>
특가 항공권은 메인 페이지에서 제공되는
<strong>프로모션 카드 클릭을 통해서만 적용되는 한정 혜택</strong>입니다.
</p>

<ul>
<li>메인 페이지 특가 카드 경유 시: 특가 요금 적용</li>
<li>검색을 통해 동일 항공편을 조회한 경우: 일반 요금 적용</li>
</ul>

<p>
이는 이벤트 목적의 한정 혜택으로,
검색 기반 가격 비교와는 분리하여 운영됩니다.
</p>

<ul>
<li>특가 적용 기간은 제한되어 있습니다.</li>
<li>특가 종료 시 일반 가격이 적용됩니다.</li>
<li>최종 결제 단계에서 적용 가격이 확정됩니다.</li>
</ul>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@
</div>

<div class="content-separator"></div>

<div class="policy-section">
<div class="policy-title">취소 및 변경</div>
<div class="policy-details">취소 수수료: 무료 (24시간 이내)<br>변경 수수료: ₩235,000 ~</div>
</div>
</div>
</div>
</div>
Loading