246 lines
8.7 KiB
JavaScript
246 lines
8.7 KiB
JavaScript
var express = require('express');
|
|
const {ObjectId} = require("mongodb");
|
|
var router = express.Router();
|
|
|
|
// 인증 확인 미들웨어
|
|
const isAuthenticated = (req, res, next) => {
|
|
if (req.session && req.session.isAuthenticated) {
|
|
next();
|
|
} else {
|
|
res.status(401).json({ result: 'AUTH_REQUIRED', message: '로그인이 필요합니다.' });
|
|
}
|
|
};
|
|
|
|
// 코인 잔액 조회
|
|
router.get('/', isAuthenticated, async function(req, res) {
|
|
try {
|
|
const userId = req.session.userId;
|
|
const database = req.app.get('database');
|
|
const users = database.collection('users');
|
|
|
|
const user = await users.findOne({ _id: new ObjectId(userId) });
|
|
|
|
if (!user) {
|
|
return res.status(404).json({ result: 'USER_NOT_FOUND', message: '사용자를 찾을 수 없습니다.' });
|
|
}
|
|
|
|
// 코인 필드가 없는 경우 기본값 0으로 설정
|
|
const coins = user.coins || 0;
|
|
|
|
res.json({
|
|
result: 'SUCCESS',
|
|
coins: coins
|
|
});
|
|
|
|
} catch (err) {
|
|
console.log("코인 잔액 조회 중 오류 발생 : ", err);
|
|
res.status(500).json({ result: 'ERROR', message: '서버 오류가 발생했습니다.' });
|
|
}
|
|
});
|
|
|
|
|
|
// 코인 차감 (100 코인)
|
|
router.post('/deduct', isAuthenticated, async function(req, res) {
|
|
try {
|
|
const userId = req.session.userId;
|
|
const deductAmount = 100; // 고정 차감 금액
|
|
const database = req.app.get('database');
|
|
const users = database.collection('users');
|
|
|
|
// 트랜잭션이 이상적이지만, 간단한 구현을 위해 findOne과 updateOne으로 처리
|
|
const user = await users.findOne({ _id: new ObjectId(userId) });
|
|
|
|
if (!user) {
|
|
return res.status(404).json({ result: 'USER_NOT_FOUND', message: '사용자를 찾을 수 없습니다.' });
|
|
}
|
|
|
|
// 코인 필드가 없는 경우 기본값 0으로 설정
|
|
const currentCoins = user.coins || 0;
|
|
|
|
// 코인이 부족한 경우
|
|
if (currentCoins < deductAmount) {
|
|
return res.status(400).json({
|
|
result: 'INSUFFICIENT_COINS',
|
|
message: '코인이 부족합니다.',
|
|
currentCoins: currentCoins
|
|
});
|
|
}
|
|
|
|
// 코인 차감
|
|
const updateResult = await users.updateOne(
|
|
{ _id: new ObjectId(userId) },
|
|
{ $inc: { coins: -deductAmount } }
|
|
);
|
|
|
|
if (updateResult.modifiedCount !== 1) {
|
|
return res.status(500).json({ result: 'UPDATE_FAILED', message: '코인 차감에 실패했습니다.' });
|
|
}
|
|
|
|
// 코인 차감 로그
|
|
// const coinLogs = database.collection('coinLogs');
|
|
// await coinLogs.insertOne({
|
|
// userId: new ObjectId(userId),
|
|
// type: 'DEDUCT',
|
|
// amount: deductAmount,
|
|
// timestamp: new Date(),
|
|
// balance: currentCoins - deductAmount
|
|
// });
|
|
|
|
res.json({
|
|
result: 'SUCCESS',
|
|
message: `${deductAmount} 코인이 차감되었습니다.`,
|
|
deducted: deductAmount,
|
|
remainingCoins: currentCoins - deductAmount
|
|
});
|
|
|
|
} catch (err) {
|
|
console.log("코인 차감 중 오류 발생 : ", err);
|
|
res.status(500).json({ result: 'ERROR', message: '서버 오류가 발생했습니다.' });
|
|
}
|
|
});
|
|
|
|
// 코인 충전 (광고 시청 후 500 코인)
|
|
router.post('/recharge/ad', isAuthenticated, async function(req, res) {
|
|
try {
|
|
const userId = req.session.userId;
|
|
const rechargeAmount = 500; // 고정 충전 금액
|
|
const database = req.app.get('database');
|
|
const users = database.collection('users');
|
|
|
|
// 광고 시청 완료 여부 확인 (클라이언트에서 전송)
|
|
const { adCompleted } = req.body;
|
|
|
|
if (!adCompleted) {
|
|
return res.status(400).json({ result: 'AD_NOT_COMPLETED', message: '광고 시청이 완료되지 않았습니다.' });
|
|
}
|
|
|
|
// 광고 ID 또는 추가 검증 로직이 필요하다면 여기에 구현
|
|
// 트랜잭션이 이상적이지만, 간단한 구현을 위해 updateOne으로 처리
|
|
const updateResult = await users.updateOne(
|
|
{ _id: new ObjectId(userId) },
|
|
{ $inc: { coins: rechargeAmount } }
|
|
);
|
|
|
|
if (updateResult.modifiedCount !== 1) {
|
|
return res.status(500).json({ result: 'UPDATE_FAILED', message: '코인 충전에 실패했습니다.' });
|
|
}
|
|
|
|
// 업데이트된 사용자 정보 가져오기
|
|
const updatedUser = await users.findOne({ _id: new ObjectId(userId) });
|
|
const currentCoins = updatedUser.coins || 0;
|
|
|
|
// 코인 충전 로그
|
|
// const coinLogs = database.collection('coinLogs');
|
|
// await coinLogs.insertOne({
|
|
// userId: new ObjectId(userId),
|
|
// type: 'RECHARGE',
|
|
// amount: rechargeAmount,
|
|
// adId: req.body.adId, // 광고 ID가 있다면
|
|
// timestamp: new Date(),
|
|
// balance: currentCoins
|
|
// });
|
|
|
|
res.json({
|
|
result: 'SUCCESS',
|
|
message: `광고 시청으로 ${rechargeAmount} 코인이 충전되었습니다.`,
|
|
recharged: rechargeAmount,
|
|
currentCoins: currentCoins
|
|
});
|
|
|
|
} catch (err) {
|
|
console.log("코인 충전 중 오류 발생 : ", err);
|
|
res.status(500).json({ result: 'ERROR', message: '서버 오류가 발생했습니다.' });
|
|
}
|
|
});
|
|
|
|
// 구매를 통한 코인 충전 (충전 수량은 파라미터로 전달 받음)
|
|
router.post('/purchase', isAuthenticated, async function(req, res) {
|
|
try {
|
|
const userId = req.session.userId;
|
|
const database = req.app.get('database');
|
|
const users = database.collection('users');
|
|
|
|
// 구매 정보 확인
|
|
const { amount, paymentId, paymentType } = req.body;
|
|
|
|
// 필수 파라미터 검증
|
|
if (!amount || amount <= 0) {
|
|
return res.status(400).json({
|
|
result: 'INVALID_PARAMETER',
|
|
message: '유효한 충전 수량을 입력해주세요.'
|
|
});
|
|
}
|
|
|
|
// 결제 검증
|
|
// 이 부분은 실제 결제 검증 로직으로 대체해야 합니다
|
|
const paymentVerified = await verifyPayment(paymentId, amount, paymentType);
|
|
|
|
if (!paymentVerified) {
|
|
return res.status(400).json({
|
|
result: 'PAYMENT_VERIFICATION_FAILED',
|
|
message: '결제 검증에 실패했습니다.'
|
|
});
|
|
}
|
|
|
|
// 코인 충전
|
|
const updateResult = await users.updateOne(
|
|
{ _id: new ObjectId(userId) },
|
|
{ $inc: { coins: amount } }
|
|
);
|
|
|
|
if (updateResult.modifiedCount !== 1) {
|
|
// 결제는 성공했는데 코인 충전 실패 시 관리자에게 알림 필요
|
|
console.error(`사용자 ${userId}의 코인 충전 실패. 결제ID: ${paymentId}`);
|
|
return res.status(500).json({ result: 'UPDATE_FAILED', message: '코인 충전에 실패했습니다.' });
|
|
}
|
|
|
|
// 업데이트된 사용자 정보 가져오기
|
|
const updatedUser = await users.findOne({ _id: new ObjectId(userId) });
|
|
const currentCoins = updatedUser.coins || 0;
|
|
|
|
// 코인 충전 로그
|
|
// const coinLogs = database.collection('coinLogs');
|
|
// await coinLogs.insertOne({
|
|
// userId: new ObjectId(userId),
|
|
// type: 'PURCHASE',
|
|
// amount: amount,
|
|
// paymentId: paymentId,
|
|
// paymentType: paymentType,
|
|
// timestamp: new Date(),
|
|
// balance: currentCoins
|
|
// });
|
|
|
|
// 결제 내역 저장
|
|
// const payments = database.collection('payments');
|
|
// await payments.insertOne({
|
|
// userId: new ObjectId(userId),
|
|
// paymentId: paymentId,
|
|
// paymentType: paymentType,
|
|
// amount: amount,
|
|
// status: 'COMPLETED',
|
|
// timestamp: new Date()
|
|
// });
|
|
|
|
res.json({
|
|
result: 'SUCCESS',
|
|
message: `${amount} 코인이 성공적으로 충전되었습니다.`,
|
|
purchased: amount,
|
|
currentCoins: currentCoins
|
|
});
|
|
|
|
} catch (err) {
|
|
console.log("구매 코인 충전 중 오류 발생 : ", err);
|
|
res.status(500).json({ result: 'ERROR', message: '서버 오류가 발생했습니다.' });
|
|
}
|
|
});
|
|
|
|
// 결제 검증 함수 (실제 결제 서비스에 맞게 구현 필요)
|
|
async function verifyPayment(paymentId, amount, paymentType) {
|
|
// 여기에 실제 결제 검증 로직 구현
|
|
// 예: 결제 서비스 API 호출하여 결제 상태 확인
|
|
|
|
// 테스트 목적으로 항상 true 반환 (실제 구현에서는 제거)
|
|
return true;
|
|
}
|
|
|
|
module.exports = router; |