274 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| const express = require('express');
 | |
| const router = express.Router();
 | |
| const { getDB } = require('../../database');
 | |
| const { auth, adminAuth } = require('../../middleware/auth');
 | |
| 
 | |
| // 创建管理员认证中间件组合
 | |
| const authenticateAdmin = [auth, adminAuth];
 | |
| 
 | |
| // 获取数据库连接
 | |
| const db = {
 | |
|   query: async (sql, params = []) => {
 | |
|     const connection = getDB();
 | |
|     const [rows] = await connection.execute(sql, params);
 | |
|     return rows;
 | |
|   }
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * 获取提现申请列表
 | |
|  */
 | |
| router.get('/', authenticateAdmin, async (req, res) => {
 | |
|   try {
 | |
|     const { page = 1, limit = 20, status, agent_id } = req.query;
 | |
|     const pageNum = parseInt(page) || 1;
 | |
|     const limitNum = parseInt(limit) || 20;
 | |
|     const offset = (pageNum - 1) * limitNum;
 | |
|     
 | |
|     // 构建查询条件
 | |
|     let whereConditions = [];
 | |
|     let queryParams = [];
 | |
|     
 | |
|     if (status) {
 | |
|       whereConditions.push('aw.status = ?');
 | |
|       queryParams.push(status);
 | |
|     }
 | |
|     
 | |
|     if (agent_id) {
 | |
|       whereConditions.push('aw.agent_id = ?');
 | |
|       queryParams.push(agent_id);
 | |
|     }
 | |
|     
 | |
|     const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : '';
 | |
|     
 | |
|     // 查询提现申请列表
 | |
|     const withdrawalsQuery = `
 | |
|       SELECT 
 | |
|         aw.*,
 | |
|         ra.agent_code,
 | |
|         u.real_name as agent_name,
 | |
|         u.phone as agent_phone,
 | |
|         zr.city_name,
 | |
|         zr.district_name,
 | |
|         admin.real_name as processed_by_name
 | |
|       FROM agent_withdrawals aw
 | |
|       JOIN regional_agents ra ON aw.agent_id = ra.id
 | |
|       JOIN users u ON ra.user_id = u.id
 | |
|       LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id
 | |
|       LEFT JOIN users admin ON aw.processed_by = admin.id
 | |
|       ${whereClause}
 | |
|       ORDER BY aw.created_at DESC
 | |
|       LIMIT ${limitNum} OFFSET ${offset}
 | |
|     `;
 | |
|     
 | |
|     const withdrawals = await db.query(withdrawalsQuery, queryParams);
 | |
|     
 | |
|     // 查询总数
 | |
|     const countQuery = `
 | |
|       SELECT COUNT(*) as total
 | |
|       FROM agent_withdrawals aw
 | |
|       ${whereClause}
 | |
|     `;
 | |
|     
 | |
|     const totalResult = await db.query(countQuery, queryParams);
 | |
|     const total = totalResult && totalResult.length > 0 ? totalResult[0].total : 0;
 | |
|     
 | |
|     // 查询统计信息
 | |
|     const statsQuery = `
 | |
|       SELECT 
 | |
|         COUNT(*) as total_applications,
 | |
|         COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending_count,
 | |
|         COUNT(CASE WHEN status = 'approved' THEN 1 END) as approved_count,
 | |
|         COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed_count,
 | |
|         COUNT(CASE WHEN status = 'rejected' THEN 1 END) as rejected_count,
 | |
|         CAST(COALESCE(SUM(CASE WHEN status = 'pending' THEN amount END), 0) AS DECIMAL(10,2)) as pending_amount,
 | |
|         CAST(COALESCE(SUM(CASE WHEN status = 'completed' THEN amount END), 0) AS DECIMAL(10,2)) as completed_amount
 | |
|       FROM agent_withdrawals
 | |
|     `;
 | |
|     
 | |
|     const statsResult = await db.query(statsQuery);
 | |
|     const stats = statsResult && statsResult.length > 0 ? statsResult[0] : {
 | |
|       total_applications: 0,
 | |
|       pending_count: 0,
 | |
|       approved_count: 0,
 | |
|       completed_count: 0,
 | |
|       rejected_count: 0,
 | |
|       pending_amount: 0,
 | |
|       completed_amount: 0
 | |
|     };
 | |
|     
 | |
|     res.json({
 | |
|       success: true,
 | |
|       data: {
 | |
|         withdrawals,
 | |
|         total: parseInt(total),
 | |
|         stats
 | |
|       }
 | |
|     });
 | |
|   } catch (error) {
 | |
|     console.error('获取提现申请列表失败:', error);
 | |
|     res.status(500).json({ success: false, message: '获取提现申请列表失败' });
 | |
|   }
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * 审核提现申请
 | |
|  */
 | |
| router.put('/:id/review', authenticateAdmin, async (req, res) => {
 | |
|   try {
 | |
|     const { id } = req.params;
 | |
|     const { action, admin_note } = req.body;
 | |
|     const adminId = req.user.id;
 | |
|     
 | |
|     if (!['approve', 'reject'].includes(action)) {
 | |
|       return res.status(400).json({ success: false, message: '无效的审核操作' });
 | |
|     }
 | |
|     
 | |
|     // 检查提现申请是否存在且状态为待审核
 | |
|     const withdrawalResult = await db.query(
 | |
|       'SELECT * FROM agent_withdrawals WHERE id = ? AND status = "pending"',
 | |
|       [id]
 | |
|     );
 | |
|     
 | |
|     if (!withdrawalResult || withdrawalResult.length === 0) {
 | |
|       return res.status(404).json({ success: false, message: '提现申请不存在或已处理' });
 | |
|     }
 | |
|     
 | |
|     const withdrawal = withdrawalResult[0];
 | |
|     const newStatus = action === 'approve' ? 'approved' : 'rejected';
 | |
|     
 | |
|     // 开始事务
 | |
|     const pool = getDB();
 | |
|     const connection = await pool.getConnection();
 | |
|     await connection.beginTransaction();
 | |
|     
 | |
|     try {
 | |
|       // 更新提现申请状态
 | |
|       await connection.execute(
 | |
|         'UPDATE agent_withdrawals SET status = ?, admin_note = ?, processed_by = ?, processed_at = NOW() WHERE id = ?',
 | |
|         [newStatus, admin_note || null, adminId, id]
 | |
|       );
 | |
|       
 | |
|       // 如果是拒绝,需要恢复代理的待提现金额
 | |
|       if (action === 'reject') {
 | |
|         await connection.execute(
 | |
|           'UPDATE regional_agents SET pending_withdrawal = pending_withdrawal - ? WHERE id = ?',
 | |
|           [withdrawal.amount, withdrawal.agent_id]
 | |
|         );
 | |
|       }
 | |
|       
 | |
|       await connection.commit();
 | |
|       connection.release(); // 释放连接回连接池
 | |
|       
 | |
|       res.json({
 | |
|         success: true,
 | |
|         message: action === 'approve' ? '提现申请已通过审核' : '提现申请已拒绝'
 | |
|       });
 | |
|     } catch (error) {
 | |
|       await connection.rollback();
 | |
|       connection.release(); // 释放连接回连接池
 | |
|       throw error;
 | |
|     }
 | |
|   } catch (error) {
 | |
|     console.error('审核提现申请失败:', error);
 | |
|     res.status(500).json({ success: false, message: '审核提现申请失败' });
 | |
|   }
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * 标记提现完成
 | |
|  */
 | |
| router.put('/:id/complete', authenticateAdmin, async (req, res) => {
 | |
|   try {
 | |
|     const { id } = req.params;
 | |
|     const adminId = req.user.id;
 | |
|     
 | |
|     // 检查提现申请是否存在且状态为已审核
 | |
|     const withdrawalResult = await db.query(
 | |
|       'SELECT * FROM agent_withdrawals WHERE id = ? AND status = "approved"',
 | |
|       [id]
 | |
|     );
 | |
|     
 | |
|     if (!withdrawalResult || withdrawalResult.length === 0) {
 | |
|       return res.status(404).json({ success: false, message: '提现申请不存在或状态不正确' });
 | |
|     }
 | |
|     
 | |
|     const withdrawal = withdrawalResult[0];
 | |
|     
 | |
|     // 开始事务
 | |
|     const pool = getDB();
 | |
|     const connection = await pool.getConnection();
 | |
|     await connection.beginTransaction();
 | |
|     
 | |
|     try {
 | |
|       // 更新提现申请状态为已完成
 | |
|       await connection.execute(
 | |
|         'UPDATE agent_withdrawals SET status = "completed", processed_by = ?, processed_at = NOW() WHERE id = ?',
 | |
|         [adminId, id]
 | |
|       );
 | |
|       
 | |
|       // 更新代理的已提现金额和待提现金额
 | |
|       await connection.execute(
 | |
|         'UPDATE regional_agents SET withdrawn_amount = withdrawn_amount + ?, pending_withdrawal = pending_withdrawal - ? WHERE id = ?',
 | |
|         [withdrawal.amount, withdrawal.amount, withdrawal.agent_id]
 | |
|       );
 | |
|       
 | |
|       await connection.commit();
 | |
|       connection.release(); // 释放连接回连接池
 | |
|       
 | |
|       res.json({
 | |
|         success: true,
 | |
|         message: '提现已标记为完成'
 | |
|       });
 | |
|     } catch (error) {
 | |
|       await connection.rollback();
 | |
|       connection.release(); // 释放连接回连接池
 | |
|       throw error;
 | |
|     }
 | |
|   } catch (error) {
 | |
|     console.error('标记提现完成失败:', error);
 | |
|     res.status(500).json({ success: false, message: '标记提现完成失败' });
 | |
|   }
 | |
| });
 | |
| 
 | |
| /**
 | |
|  * 获取提现申请详情
 | |
|  */
 | |
| router.get('/:id', authenticateAdmin, async (req, res) => {
 | |
|   try {
 | |
|     const { id } = req.params;
 | |
|     
 | |
|     const withdrawalQuery = `
 | |
|       SELECT 
 | |
|         aw.*,
 | |
|         ra.agent_code,
 | |
|         u.real_name as agent_name,
 | |
|         u.phone as agent_phone,
 | |
|         zr.city_name,
 | |
|         zr.district_name,
 | |
|         admin.real_name as processed_by_name
 | |
|       FROM agent_withdrawals aw
 | |
|       JOIN regional_agents ra ON aw.agent_id = ra.id
 | |
|       JOIN users u ON ra.user_id = u.id
 | |
|       LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id
 | |
|       LEFT JOIN users admin ON aw.processed_by = admin.id
 | |
|       WHERE aw.id = ?
 | |
|     `;
 | |
|     
 | |
|     const withdrawalResult = await db.query(withdrawalQuery, [id]);
 | |
|     
 | |
|     if (!withdrawalResult || withdrawalResult.length === 0) {
 | |
|       return res.status(404).json({ success: false, message: '提现申请不存在' });
 | |
|     }
 | |
|     
 | |
|     res.json({
 | |
|       success: true,
 | |
|       data: withdrawalResult[0]
 | |
|     });
 | |
|   } catch (error) {
 | |
|     console.error('获取提现申请详情失败:', error);
 | |
|     res.status(500).json({ success: false, message: '获取提现申请详情失败' });
 | |
|   }
 | |
| });
 | |
| 
 | |
| module.exports = router; |