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;