결제, 구독 기능
This commit is contained in:
@@ -83,6 +83,7 @@
|
||||
:getStatusSeverity="getStatusSeverity"
|
||||
:formatDate="formatDate"
|
||||
:availableMembers="clubMembers"
|
||||
:hasTeamFeature="hasTeamFeature"
|
||||
@edit="editFromDetails"
|
||||
@hide="hideDialog"
|
||||
@participant-updated="fetchEvents"
|
||||
@@ -105,11 +106,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useClubStore } from '@/stores/clubStore';
|
||||
import eventService from '@/services/eventService';
|
||||
import apiClient from '@/services/api';
|
||||
import dayjs from 'dayjs';
|
||||
import clubService from '@/services/clubService';
|
||||
import ScoreManagement from '@/components/event/ScoreManagement.vue';
|
||||
@@ -142,6 +144,9 @@ const filters = ref({
|
||||
startDate: { value: null, matchMode: 'equals' }
|
||||
});
|
||||
|
||||
// 팀 기능 사용 권한 여부
|
||||
const hasTeamFeature = computed(() => clubStore.hasFeature('team_create'));
|
||||
|
||||
// 이벤트 유형 옵션
|
||||
const eventTypeOptions = [
|
||||
{ name: '정기전', value: '정기전' },
|
||||
@@ -156,17 +161,22 @@ const clubMembers = ref([]);
|
||||
|
||||
// 이벤트 목록 가져오기
|
||||
const fetchEvents = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const response = await eventService.getEvents(clubId.value);
|
||||
events.value = response;
|
||||
loading.value = true;
|
||||
const data = await eventService.getEvents(clubId.value);
|
||||
events.value = data;
|
||||
} catch (error) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: '오류',
|
||||
detail: '이벤트 목록을 가져오는데 실패했습니다.',
|
||||
life: 3000
|
||||
});
|
||||
console.error('이벤트 목록 로드 실패:', error);
|
||||
|
||||
// 403 오류는 중앙에서 처리하민로 여기서는 기타 오류만 처리
|
||||
if (!error.response) {
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: '오류',
|
||||
detail: '이벤트 목록을 불러오는 데 실패했습니다.',
|
||||
life: 3000
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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>
|
||||
Reference in New Issue
Block a user