const express = require('express'); const router = express.Router(); const { getDB } = require('../database'); const { agentAuth } = require('../middleware/agentAuth'); const { logger } = require('../config/logger'); /** * 获取代理下级用户列表 * GET /api/users */ router.get('/', agentAuth, async (req, res) => { try { const agentId = req.agent.id; const { page = 1, limit = 20, search, role, sort_by = 'created_at', sort_order = 'desc', city, district } = req.query; const pageNum = parseInt(page) || 1; const limitNum = parseInt(limit) || 20; const offset = (pageNum - 1) * limitNum; // 构建查询条件 let whereConditions = ['am.agent_id = ?']; let queryParams = [agentId]; if (search) { whereConditions.push('(u.username LIKE ? OR u.real_name LIKE ? OR u.phone LIKE ?)'); queryParams.push(`%${search}%`, `%${search}%`, `%${search}%`); } if (role) { whereConditions.push('u.role = ?'); queryParams.push(role); } if (city) { whereConditions.push('u.city = ?'); queryParams.push(city); } if (district) { whereConditions.push('u.district = ?'); queryParams.push(district); } const whereClause = whereConditions.join(' AND '); // 验证排序字段 const allowedSortFields = ['created_at', 'updated_at', 'balance', 'username', 'real_name']; const sortBy = allowedSortFields.includes(sort_by) ? sort_by : 'created_at'; const sortOrder = sort_order.toLowerCase() === 'asc' ? 'ASC' : 'DESC'; // 查询用户列表 const usersQuery = ` SELECT u.id, u.username, u.real_name, u.phone, u.email, u.avatar, u.role, u.city, u.balance, u.points, u.created_at, u.updated_at, am.created_at as join_date, ( SELECT CAST(COALESCE(SUM(amount), 0) AS DECIMAL(10,2)) FROM transfers WHERE from_user_id = u.id AND DATE(created_at) = CURDATE() ) as today_transfer_out, ( SELECT CAST(COALESCE(SUM(amount), 0) AS DECIMAL(10,2)) FROM transfers WHERE to_user_id = u.id AND DATE(created_at) = CURDATE() ) as today_transfer_in FROM agent_merchants am LEFT JOIN users u ON am.merchant_id = u.id WHERE ${whereClause} ORDER BY u.${sortBy} ${sortOrder} LIMIT ${limitNum} OFFSET ${offset} `; const [users] = await getDB().execute(usersQuery, queryParams); // 查询总数 const countQuery = ` SELECT COUNT(*) as total FROM agent_merchants am LEFT JOIN users u ON am.merchant_id = u.id WHERE ${whereClause} `; const [countResult] = await getDB().execute(countQuery, queryParams); const total = countResult[0]?.total || 0; // 查询统计信息 const [statsResult] = await getDB().execute(` SELECT COUNT(*) as total_users, COUNT(CASE WHEN u.audit_status = 'approved' THEN 1 END) as active_users, CAST(COALESCE(SUM(u.balance), 0) AS DECIMAL(10,2)) as total_balance, COUNT(CASE WHEN DATE(am.created_at) = CURDATE() THEN 1 END) as today_new_users FROM agent_merchants am LEFT JOIN users u ON am.merchant_id = u.id WHERE am.agent_id = ? `, [agentId]); const stats = statsResult[0] || { total_users: 0, active_users: 0, total_balance: '0.00', today_new_users: 0 }; res.json({ success: true, data: { users, pagination: { current_page: pageNum, per_page: limitNum, total, total_pages: Math.ceil(total / limitNum) }, stats } }); } catch (error) { logger.error('获取用户列表失败', { error: error.message, stack: error.stack, agentId: req.agent?.id }); res.status(500).json({ success: false, message: '获取用户列表失败' }); } }); /** * 获取单个用户详情 * GET /api/users/:id */ router.get('/:id', agentAuth, async (req, res) => { try { const agentId = req.agent.id; const userId = req.params.id; // 验证用户是否属于当前代理 const [users] = await getDB().execute(` SELECT u.id, u.username, u.real_name, u.phone, u.email, u.avatar, u.role, u.city, u.district, u.balance, u.points, u.id_card, u.business_license, u.payment_qr_code, u.created_at, u.updated_at, am.created_at as join_date FROM agent_merchants am LEFT JOIN users u ON am.merchant_id = u.id WHERE am.agent_id = ? AND u.id = ? `, [agentId, userId]); if (users.length === 0) { return res.status(404).json({ success: false, message: '用户不存在或不属于当前代理' }); } const user = users[0]; // 获取用户转账统计 const [transferStats] = await getDB().execute(` SELECT COUNT(*) as total_transfers, CAST(COALESCE(SUM(CASE WHEN from_user_id = ? THEN amount ELSE 0 END), 0) AS DECIMAL(10,2)) as total_transfer_out, CAST(COALESCE(SUM(CASE WHEN to_user_id = ? THEN amount ELSE 0 END), 0) AS DECIMAL(10,2)) as total_transfer_in, COUNT(CASE WHEN DATE(created_at) = CURDATE() THEN 1 END) as today_transfers, CAST(COALESCE(SUM(CASE WHEN from_user_id = ? AND DATE(created_at) = CURDATE() THEN amount ELSE 0 END), 0) AS DECIMAL(10,2)) as today_transfer_out, CAST(COALESCE(SUM(CASE WHEN to_user_id = ? AND DATE(created_at) = CURDATE() THEN amount ELSE 0 END), 0) AS DECIMAL(10,2)) as today_transfer_in FROM transfers WHERE from_user_id = ? OR to_user_id = ? `, [userId, userId, userId, userId, userId, userId]); user.transfer_stats = transferStats[0] || { total_transfers: 0, total_transfer_out: '0.00', total_transfer_in: '0.00', today_transfers: 0, today_transfer_out: '0.00', today_transfer_in: '0.00' }; res.json({ success: true, data: user }); } catch (error) { logger.error('获取用户详情失败', { error: error.message, stack: error.stack, agentId: req.agent?.id, userId: req.params.id }); res.status(500).json({ success: false, message: '获取用户详情失败' }); } }); /** * 导出用户数据 * GET /api/users/export */ router.get('/export/data', agentAuth, async (req, res) => { try { const agentId = req.agent.id; const { format = 'json', search, role, city, district } = req.query; // 构建查询条件 let whereConditions = ['am.agent_id = ?']; let queryParams = [agentId]; if (search) { whereConditions.push('(u.username LIKE ? OR u.real_name LIKE ? OR u.phone LIKE ?)'); queryParams.push(`%${search}%`, `%${search}%`, `%${search}%`); } if (role) { whereConditions.push('u.role = ?'); queryParams.push(role); } if (city) { whereConditions.push('u.city = ?'); queryParams.push(city); } if (district) { whereConditions.push('u.district = ?'); queryParams.push(district); } const whereClause = whereConditions.join(' AND '); // 查询用户数据 const [users] = await getDB().execute(` SELECT u.id, u.username, u.real_name, u.phone, u.email, u.role, u.city, u.balance, u.points, u.created_at, am.created_at as join_date FROM agent_merchants am LEFT JOIN users u ON am.merchant_id = u.id WHERE ${whereClause} ORDER BY u.created_at DESC `, queryParams); if (format === 'csv') { // 生成CSV格式 const csvHeader = 'ID,用户名,真实姓名,手机号,邮箱,角色,城市,地区,账户类型,余额,积分,状态,注册时间,加入时间\n'; const csvData = users.map(user => { return [ user.id, user.username || '', user.real_name || '', user.phone || '', user.email || '', user.role || '', user.city || '', user.district || '', user.account_type || '', user.balance || '0.00', user.points || 0, user.status || '', user.created_at || '', user.join_date || '' ].join(','); }).join('\n'); res.setHeader('Content-Type', 'text/csv; charset=utf-8'); res.setHeader('Content-Disposition', `attachment; filename="users_${Date.now()}.csv"`); res.send(csvHeader + csvData); } else { // 默认JSON格式 res.json({ success: true, data: users, exported_at: new Date().toISOString(), total: users.length }); } } catch (error) { logger.error('导出用户数据失败', { error: error.message, stack: error.stack, agentId: req.agent?.id }); res.status(500).json({ success: false, message: '导出用户数据失败' }); } }); module.exports = router;