결제, 구독 기능

This commit is contained in:
2025-05-11 17:27:39 +09:00
parent 2924a61a9d
commit 1db3a03ffd
18 changed files with 3276 additions and 180 deletions
+132
View File
@@ -0,0 +1,132 @@
<template>
<div class="payment-result fail">
<div class="result-container">
<div class="icon-container">
<i class="pi pi-times-circle"></i>
</div>
<h1>결제가 취소되었습니다</h1>
<p v-if="message">{{ message }}</p>
<div class="buttons">
<button class="primary-btn" @click="goToSubscription">구독 관리로 이동</button>
<button class="secondary-btn" @click="goToHome">홈으로 이동</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
const router = useRouter();
const route = useRoute();
const message = ref('');
onMounted(async () => {
// URL에서 메시지 가져오기
message.value = route.query.message || '결제가 취소되었습니다.';
// 부모 창에 결제 실패 메시지 전달
if (window.opener && window.opener.handlePaymentFail) {
window.opener.handlePaymentFail(message.value);
// 3초 후 창 닫기
setTimeout(() => {
window.close();
}, 3000);
}
});
const goToSubscription = () => {
if (window.opener) {
window.opener.location.href = '/club/subscription';
window.close();
} else {
router.push('/club/subscription');
}
};
const goToHome = () => {
if (window.opener) {
window.opener.location.href = '/';
window.close();
} else {
router.push('/');
}
};
</script>
<style scoped>
.payment-result {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f8f9fa;
}
.result-container {
background-color: white;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 40px;
text-align: center;
max-width: 500px;
width: 100%;
}
.icon-container {
margin-bottom: 20px;
}
.fail .icon-container i {
font-size: 80px;
color: #f44336;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
color: #333;
}
p {
color: #666;
margin-bottom: 30px;
}
.buttons {
display: flex;
justify-content: center;
gap: 15px;
}
.primary-btn, .secondary-btn {
padding: 10px 20px;
border-radius: 5px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.primary-btn {
background-color: #4caf50;
color: white;
border: none;
}
.primary-btn:hover {
background-color: #43a047;
transform: translateY(-2px);
}
.secondary-btn {
background-color: #f5f5f5;
color: #333;
border: 1px solid #ddd;
}
.secondary-btn:hover {
background-color: #e9e9e9;
transform: translateY(-2px);
}
</style>
@@ -0,0 +1,133 @@
<template>
<div class="payment-result success">
<div class="result-container">
<div class="icon-container">
<i class="pi pi-check-circle"></i>
</div>
<h1>결제가 완료되었습니다</h1>
<p>주문번호: {{ orderId }}</p>
<div class="buttons">
<button class="primary-btn" @click="goToSubscription">구독 관리로 이동</button>
<button class="secondary-btn" @click="goToHome">홈으로 이동</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import apiClient from '@/services/api';
const router = useRouter();
const route = useRoute();
const orderId = ref('');
onMounted(async () => {
// URL에서 주문 ID 가져오기
orderId.value = route.query.orderId || '';
// 부모 창에 결제 성공 메시지 전달
if (window.opener && window.opener.handlePaymentSuccess) {
window.opener.handlePaymentSuccess(orderId.value);
// 3초 후 창 닫기
setTimeout(() => {
window.close();
}, 3000);
}
});
const goToSubscription = () => {
if (window.opener) {
window.opener.location.href = '/club/subscription';
window.close();
} else {
router.push('/club/subscription');
}
};
const goToHome = () => {
if (window.opener) {
window.opener.location.href = '/';
window.close();
} else {
router.push('/');
}
};
</script>
<style scoped>
.payment-result {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #f8f9fa;
}
.result-container {
background-color: white;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
padding: 40px;
text-align: center;
max-width: 500px;
width: 100%;
}
.icon-container {
margin-bottom: 20px;
}
.success .icon-container i {
font-size: 80px;
color: #4caf50;
}
h1 {
font-size: 24px;
margin-bottom: 20px;
color: #333;
}
p {
color: #666;
margin-bottom: 30px;
}
.buttons {
display: flex;
justify-content: center;
gap: 15px;
}
.primary-btn, .secondary-btn {
padding: 10px 20px;
border-radius: 5px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
}
.primary-btn {
background-color: #4caf50;
color: white;
border: none;
}
.primary-btn:hover {
background-color: #43a047;
transform: translateY(-2px);
}
.secondary-btn {
background-color: #f5f5f5;
color: #333;
border: 1px solid #ddd;
}
.secondary-btn:hover {
background-color: #e9e9e9;
transform: translateY(-2px);
}
</style>