Files
bowlingManager/backend/controllers/featureController.js
T
2025-05-11 17:27:39 +09:00

258 lines
7.2 KiB
JavaScript

const { Feature, ClubFeature, Club, ClubSubscription, SubscriptionPlan, SubscriptionPlanFeature } = require('../models');
const { Op } = require('sequelize');
// 전체 기능 목록 조회
exports.getFeatures = async (req, res) => {
try {
const features = await Feature.findAll({
where: {
status: 'active'
},
attributes: ['id', 'name', 'description', 'price']
});
res.json(features);
} catch (error) {
console.error('기능 목록 조회 오류:', error);
res.status(500).json({ message: '기능 목록을 가져오는 중 오류가 발생했습니다.' });
}
};
// 사용 가능한 기능 목록 조회
exports.getAvailableFeatures = async (req, res) => {
try {
const { clubId } = req.body;
if (!clubId) {
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
}
// 모든 기능 목록 조회
const features = await Feature.findAll({
where: {
status: 'active'
},
attributes: ['id', 'name', 'description', 'price']
});
// 클럽의 활성화된 기능 조회
const activeFeatures = await ClubFeature.findAll({
where: {
clubId,
expiryDate: {
[Op.gt]: new Date()
}
},
attributes: ['featureId']
});
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),
isIncludedInPlan: planFeatureIds.includes(feature.id)
}));
res.json(formattedFeatures);
} catch (error) {
console.error('사용 가능한 기능 목록 조회 오류:', error);
res.status(500).json({ message: '기능 목록을 가져오는 중 오류가 발생했습니다.' });
}
};
// 활성화된 기능 목록 조회
exports.getActiveFeatures = async (req, res) => {
try {
const { clubId } = req.body;
if (!clubId) {
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
}
const activeFeatures = await ClubFeature.findAll({
where: {
clubId,
expiryDate: {
[Op.gt]: new Date()
}
},
include: [{
model: Feature,
attributes: ['name', 'description']
}],
attributes: ['id', 'featureId', 'createdAt', 'expiryDate']
});
// 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: '활성화된 기능 목록을 가져오는 중 오류가 발생했습니다.' });
}
};
// 기능 구매 내역 조회
exports.getFeaturePayments = async (req, res) => {
try {
const { clubId } = req.body;
if (!clubId) {
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
}
const payments = await ClubFeature.findAll({
where: {
clubId
},
include: [{
model: Feature,
attributes: ['name', 'price']
}],
attributes: [
'id',
'featureId',
'createdAt',
'expiryDate',
'enabled'
],
order: [['createdAt', 'DESC']]
});
// 기간 계산 (월 단위)
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) {
console.error('기능 구매 내역 조회 오류:', error);
res.status(500).json({ message: '구매 내역을 가져오는 중 오류가 발생했습니다.' });
}
};
// 기능 구매
exports.purchaseFeature = async (req, res) => {
try {
const { clubId, featureId, duration } = req.body;
if (!clubId) {
return res.status(400).json({ message: '클럽 ID가 필요합니다.' });
}
// 기능 정보 조회
const feature = await Feature.findByPk(featureId);
if (!feature) {
return res.status(404).json({ message: '존재하지 않는 기능입니다.' });
}
// 클럽 정보 조회
const club = await Club.findByPk(clubId);
if (!club) {
return res.status(404).json({ message: '존재하지 않는 클럽입니다.' });
}
// 이미 활성화된 기능인지 확인
const existingFeature = await ClubFeature.findOne({
where: {
clubId,
featureId,
expiryDate: {
[Op.gt]: new Date()
}
}
});
if (existingFeature) {
return res.status(400).json({ message: '이미 활성화된 기능입니다.' });
}
// 만료일 계산
const expiryDate = new Date();
expiryDate.setMonth(expiryDate.getMonth() + parseInt(duration));
const clubFeature = await ClubFeature.create({
clubId,
featureId,
expiryDate,
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
});
} catch (error) {
console.error('기능 구매 오류:', error);
res.status(500).json({ message: '기능 구매 중 오류가 발생했습니다.' });
}
};