docs: 更新项目文档,完善需求和技术细节
This commit is contained in:
239
backend/routes/promotions.js
Normal file
239
backend/routes/promotions.js
Normal file
@@ -0,0 +1,239 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const dbConnector = require('../utils/dbConnector');
|
||||
|
||||
// 获取用户推广信息
|
||||
router.get('/info', async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
|
||||
// 获取或创建推广信息
|
||||
let promotion = await dbConnector.query(
|
||||
'SELECT * FROM promotions WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (promotion.length === 0) {
|
||||
// 创建新的推广信息
|
||||
const promotionCode = generatePromotionCode(userId);
|
||||
await dbConnector.query(
|
||||
`INSERT INTO promotions
|
||||
(user_id, promotion_code, total_invites, successful_orders, total_earnings, available_balance, withdrawn_amount, created_at, updated_at)
|
||||
VALUES (?, ?, 0, 0, 0, 0, 0, NOW(), NOW())`,
|
||||
[userId, promotionCode]
|
||||
);
|
||||
|
||||
promotion = await dbConnector.query(
|
||||
'SELECT * FROM promotions WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
}
|
||||
|
||||
// 生成推广链接和二维码(这里简化处理,实际项目中需要生成真实二维码)
|
||||
const promotionInfo = {
|
||||
promotion_code: promotion[0].promotion_code,
|
||||
qr_code_url: `/uploads/qrcodes/promo_${promotion[0].promotion_code}.png`,
|
||||
promotion_url: `https://aijianhua.com/promo/${promotion[0].promotion_code}`,
|
||||
total_invites: promotion[0].total_invites,
|
||||
successful_orders: promotion[0].successful_orders,
|
||||
total_earnings: promotion[0].total_earnings,
|
||||
available_balance: promotion[0].available_balance,
|
||||
withdrawn_amount: promotion[0].withdrawn_amount
|
||||
};
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: promotionInfo
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取推广信息失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 获取推广记录
|
||||
router.get('/records', async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const { page = 1, limit = 10, type } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
let query = `
|
||||
SELECT 'invite' as type, u.username as user_name, u.phone,
|
||||
NULL as order_amount, 10.0 as amount, 'completed' as status, u.created_at
|
||||
FROM users u
|
||||
WHERE u.invited_by = ?
|
||||
`;
|
||||
|
||||
let countQuery = 'SELECT COUNT(*) as count FROM users WHERE invited_by = ?';
|
||||
let queryParams = [userId];
|
||||
|
||||
if (type === 'order_commission') {
|
||||
query = `
|
||||
SELECT 'order_commission' as type, u.username as user_name, u.phone,
|
||||
o.total_amount as order_amount, o.total_amount * 0.1 as amount,
|
||||
'pending' as status, o.created_at
|
||||
FROM orders o
|
||||
JOIN users u ON o.user_id = u.id
|
||||
WHERE u.invited_by = ? AND o.payment_status = 1
|
||||
`;
|
||||
countQuery = `
|
||||
SELECT COUNT(*) as count
|
||||
FROM orders o
|
||||
JOIN users u ON o.user_id = u.id
|
||||
WHERE u.invited_by = ? AND o.payment_status = 1
|
||||
`;
|
||||
}
|
||||
|
||||
query += ' ORDER BY created_at DESC LIMIT ? OFFSET ?';
|
||||
queryParams.push(parseInt(limit), parseInt(offset));
|
||||
|
||||
const records = await dbConnector.query(query, queryParams);
|
||||
const countResult = await dbConnector.query(countQuery, [userId]);
|
||||
const total = countResult[0].count;
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: {
|
||||
records: records,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total: total,
|
||||
pages: Math.ceil(total / limit)
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取推广记录失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 申请提现
|
||||
router.post('/withdraw', async (req, res) => {
|
||||
try {
|
||||
const { amount, payment_method, account_info } = req.body;
|
||||
const userId = req.user.id;
|
||||
|
||||
// 检查可用余额
|
||||
const promotion = await dbConnector.query(
|
||||
'SELECT available_balance FROM promotions WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
|
||||
if (promotion.length === 0 || promotion[0].available_balance < amount) {
|
||||
return res.status(400).json({
|
||||
code: 2001,
|
||||
message: '可提现余额不足'
|
||||
});
|
||||
}
|
||||
|
||||
// 检查最小提现金额
|
||||
if (amount < 50) {
|
||||
return res.status(400).json({
|
||||
code: 2001,
|
||||
message: '提现金额不能少于50元'
|
||||
});
|
||||
}
|
||||
|
||||
// 创建提现记录
|
||||
const result = await dbConnector.query(
|
||||
`INSERT INTO withdrawals
|
||||
(user_id, amount, payment_method, account_info, status, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, 'pending', NOW(), NOW())`,
|
||||
[userId, amount, payment_method, account_info]
|
||||
);
|
||||
|
||||
// 更新可用余额
|
||||
await dbConnector.query(
|
||||
'UPDATE promotions SET available_balance = available_balance - ?, updated_at = NOW() WHERE user_id = ?',
|
||||
[amount, userId]
|
||||
);
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '提现申请已提交',
|
||||
data: {
|
||||
withdraw_id: result.insertId,
|
||||
amount: amount,
|
||||
status: 'processing',
|
||||
estimated_arrival: new Date(Date.now() + 2 * 24 * 60 * 60 * 1000).toISOString() // 2天后
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('申请提现失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 获取提现记录
|
||||
router.get('/withdrawals', async (req, res) => {
|
||||
try {
|
||||
const userId = req.user.id;
|
||||
const { page = 1, limit = 10 } = req.query;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const withdrawals = await dbConnector.query(
|
||||
`SELECT id, amount, payment_method, account_info, status, transaction_id, completed_at, created_at
|
||||
FROM withdrawals
|
||||
WHERE user_id = ?
|
||||
ORDER BY created_at DESC
|
||||
LIMIT ? OFFSET ?`,
|
||||
[userId, parseInt(limit), parseInt(offset)]
|
||||
);
|
||||
|
||||
const countResult = await dbConnector.query(
|
||||
'SELECT COUNT(*) as count FROM withdrawals WHERE user_id = ?',
|
||||
[userId]
|
||||
);
|
||||
const total = countResult[0].count;
|
||||
|
||||
res.json({
|
||||
code: 200,
|
||||
message: '获取成功',
|
||||
data: {
|
||||
withdrawals: withdrawals,
|
||||
pagination: {
|
||||
page: parseInt(page),
|
||||
limit: parseInt(limit),
|
||||
total: total,
|
||||
pages: Math.ceil(total / limit)
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('获取提现记录失败:', error);
|
||||
res.status(500).json({
|
||||
code: 500,
|
||||
message: '服务器内部错误',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 生成推广码
|
||||
function generatePromotionCode(userId) {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
let code = 'PROMO';
|
||||
for (let i = 0; i < 6; i++) {
|
||||
code += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
return code + userId.toString().padStart(4, '0');
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
Reference in New Issue
Block a user