결제, 구독 기능
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
const { Feature, ClubFeature, Club } = require('../models');
|
||||
const { Feature, ClubFeature, Club, ClubSubscription, SubscriptionPlan, SubscriptionPlanFeature } = require('../models');
|
||||
const { Op } = require('sequelize');
|
||||
|
||||
// 전체 기능 목록 조회
|
||||
@@ -20,7 +20,7 @@ exports.getFeatures = async (req, res) => {
|
||||
// 사용 가능한 기능 목록 조회
|
||||
exports.getAvailableFeatures = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.query;
|
||||
const { clubId } = req.body;
|
||||
|
||||
if (!clubId) {
|
||||
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
|
||||
@@ -47,10 +47,40 @@ exports.getAvailableFeatures = async (req, res) => {
|
||||
|
||||
const activeFeatureIds = activeFeatures.map(af => af.featureId);
|
||||
|
||||
// 기능 목록에 활성화 상태 추가
|
||||
// 현재 구독 중인 플랜에 포함된 기능 조회
|
||||
const { ClubSubscription, SubscriptionPlan, SubscriptionPlanFeature } = require('../models');
|
||||
|
||||
// 현재 활성화된 구독 조회
|
||||
const activeSubscription = await ClubSubscription.findOne({
|
||||
where: {
|
||||
clubId,
|
||||
status: 'active',
|
||||
endDate: {
|
||||
[Op.gt]: new Date()
|
||||
}
|
||||
},
|
||||
attributes: ['planId']
|
||||
});
|
||||
|
||||
let planFeatureIds = [];
|
||||
|
||||
// 현재 구독 플랜이 있는 경우, 해당 플랜에 포함된 기능 ID 목록 조회
|
||||
if (activeSubscription) {
|
||||
const planFeatures = await SubscriptionPlanFeature.findAll({
|
||||
where: {
|
||||
planId: activeSubscription.planId
|
||||
},
|
||||
attributes: ['featureId']
|
||||
});
|
||||
|
||||
planFeatureIds = planFeatures.map(pf => pf.featureId);
|
||||
}
|
||||
|
||||
// 기능 목록에 활성화 상태 및 플랜 포함 여부 추가
|
||||
const formattedFeatures = features.map(feature => ({
|
||||
...feature.toJSON(),
|
||||
isActive: activeFeatureIds.includes(feature.id)
|
||||
isActive: activeFeatureIds.includes(feature.id),
|
||||
isIncludedInPlan: planFeatureIds.includes(feature.id)
|
||||
}));
|
||||
|
||||
res.json(formattedFeatures);
|
||||
@@ -63,7 +93,7 @@ exports.getAvailableFeatures = async (req, res) => {
|
||||
// 활성화된 기능 목록 조회
|
||||
exports.getActiveFeatures = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.query;
|
||||
const { clubId } = req.body;
|
||||
|
||||
if (!clubId) {
|
||||
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
|
||||
@@ -80,10 +110,19 @@ exports.getActiveFeatures = async (req, res) => {
|
||||
model: Feature,
|
||||
attributes: ['name', 'description']
|
||||
}],
|
||||
attributes: ['id', 'featureId', 'purchaseDate', 'expiryDate']
|
||||
attributes: ['id', 'featureId', 'createdAt', 'expiryDate']
|
||||
});
|
||||
|
||||
res.json(activeFeatures);
|
||||
// createdAt을 purchaseDate로 매핑
|
||||
const formattedFeatures = activeFeatures.map(feature => ({
|
||||
id: feature.id,
|
||||
featureId: feature.featureId,
|
||||
purchaseDate: feature.createdAt,
|
||||
expiryDate: feature.expiryDate,
|
||||
Feature: feature.Feature
|
||||
}));
|
||||
|
||||
res.json(formattedFeatures);
|
||||
} catch (error) {
|
||||
console.error('활성화된 기능 목록 조회 오류:', error);
|
||||
res.status(500).json({ message: '활성화된 기능 목록을 가져오는 중 오류가 발생했습니다.' });
|
||||
@@ -93,7 +132,7 @@ exports.getActiveFeatures = async (req, res) => {
|
||||
// 기능 구매 내역 조회
|
||||
exports.getFeaturePayments = async (req, res) => {
|
||||
try {
|
||||
const { clubId } = req.query;
|
||||
const { clubId } = req.body;
|
||||
|
||||
if (!clubId) {
|
||||
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
|
||||
@@ -105,29 +144,41 @@ exports.getFeaturePayments = async (req, res) => {
|
||||
},
|
||||
include: [{
|
||||
model: Feature,
|
||||
attributes: ['name']
|
||||
attributes: ['name', 'price']
|
||||
}],
|
||||
attributes: [
|
||||
'id',
|
||||
'featureId',
|
||||
'purchaseDate',
|
||||
'createdAt',
|
||||
'expiryDate',
|
||||
'amount',
|
||||
'duration',
|
||||
'status'
|
||||
'enabled'
|
||||
],
|
||||
order: [['purchaseDate', 'DESC']]
|
||||
order: [['createdAt', 'DESC']]
|
||||
});
|
||||
|
||||
const formattedPayments = payments.map(payment => ({
|
||||
id: payment.id,
|
||||
featureName: payment.feature.name,
|
||||
purchaseDate: payment.purchaseDate,
|
||||
expiryDate: payment.expiryDate,
|
||||
amount: payment.amount,
|
||||
duration: payment.duration,
|
||||
status: payment.status
|
||||
}));
|
||||
// 기간 계산 (월 단위)
|
||||
const calculateDuration = (startDate, endDate) => {
|
||||
const start = new Date(startDate);
|
||||
const end = new Date(endDate);
|
||||
const diffTime = Math.abs(end - start);
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
return Math.ceil(diffDays / 30); // 대략적인 월 수 계산
|
||||
};
|
||||
|
||||
const formattedPayments = payments.map(payment => {
|
||||
const duration = calculateDuration(payment.createdAt, payment.expiryDate);
|
||||
const amount = payment.Feature.price * duration;
|
||||
|
||||
return {
|
||||
id: payment.id,
|
||||
featureName: payment.Feature.name,
|
||||
purchaseDate: payment.createdAt,
|
||||
expiryDate: payment.expiryDate,
|
||||
amount: amount,
|
||||
duration: duration,
|
||||
status: payment.enabled ? 'active' : 'inactive'
|
||||
};
|
||||
});
|
||||
|
||||
res.json(formattedPayments);
|
||||
} catch (error) {
|
||||
@@ -172,27 +223,32 @@ exports.purchaseFeature = async (req, res) => {
|
||||
return res.status(400).json({ message: '이미 활성화된 기능입니다.' });
|
||||
}
|
||||
|
||||
// 구매 금액 계산 (duration에 따른 할인 적용 가능)
|
||||
const amount = feature.price * duration;
|
||||
|
||||
// 기능 구매 기록 생성
|
||||
const purchaseDate = new Date();
|
||||
// 만료일 계산
|
||||
const expiryDate = new Date();
|
||||
expiryDate.setMonth(expiryDate.getMonth() + duration);
|
||||
expiryDate.setMonth(expiryDate.getMonth() + parseInt(duration));
|
||||
|
||||
const clubFeature = await ClubFeature.create({
|
||||
clubId,
|
||||
featureId,
|
||||
purchaseDate,
|
||||
expiryDate,
|
||||
amount,
|
||||
duration,
|
||||
status: 'active'
|
||||
enabled: true
|
||||
});
|
||||
|
||||
// 응답용 객체 생성
|
||||
const purchaseInfo = {
|
||||
id: clubFeature.id,
|
||||
clubId: clubFeature.clubId,
|
||||
featureId: clubFeature.featureId,
|
||||
purchaseDate: clubFeature.createdAt,
|
||||
expiryDate: clubFeature.expiryDate,
|
||||
amount: feature.price * parseInt(duration),
|
||||
duration: parseInt(duration),
|
||||
status: 'active'
|
||||
};
|
||||
|
||||
res.json({
|
||||
message: '기능 구매가 완료되었습니다.',
|
||||
purchaseInfo: clubFeature
|
||||
purchaseInfo
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('기능 구매 오류:', error);
|
||||
|
||||
Reference in New Issue
Block a user