const express = require('express'); const router = express.Router(); const { getDB } = require('../../database'); const bcrypt = require('bcryptjs'); 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, city, search } = 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('ra.status = ?'); queryParams.push(status); } if (city) { whereConditions.push('zr.city_name = ?'); queryParams.push(city); } if (search) { whereConditions.push('(ra.real_name LIKE ? OR ra.phone LIKE ?)'); queryParams.push(`%${search}%`, `%${search}%`); } const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : ''; // 查询代理列表 const agentsQuery = ` SELECT ra.*, u.real_name, u.phone, u.id_card, zr.city_name, zr.district_name, ( SELECT COUNT(DISTINCT merchant_id) FROM agent_merchants WHERE agent_id = ra.id ) as merchant_count, ( SELECT CAST(COALESCE(SUM(commission_amount), 0) AS DECIMAL(10,2)) FROM agent_commission_records WHERE agent_id = ra.id ) as total_commission, 0 as paid_commission, ( SELECT CAST(COALESCE(SUM(commission_amount), 0) AS DECIMAL(10,2)) FROM agent_commission_records WHERE agent_id = ra.id ) as pending_commission FROM regional_agents ra LEFT JOIN users u ON ra.user_id = u.id LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id ${whereClause} ORDER BY ra.created_at DESC LIMIT ${limitNum} OFFSET ${offset} `; const agents = await db.query(agentsQuery, queryParams); // 查询总数 const countQuery = ` SELECT COUNT(DISTINCT ra.id) as total FROM regional_agents ra LEFT JOIN users u ON ra.user_id = u.id LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id ${whereClause} `; const totalResult = await db.query(countQuery, queryParams); const total = totalResult && totalResult.length > 0 ? totalResult[0].total : 0; // 查询统计信息 const statsQuery = ` SELECT COUNT(*) as total_agents, COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending_agents, COUNT(CASE WHEN status = 'active' THEN 1 END) as active_agents, CAST(COALESCE(SUM(commission_stats.total_commission), 0) AS DECIMAL(10,2)) as total_commission FROM regional_agents ra LEFT JOIN ( SELECT agent_id, SUM(commission_amount) as total_commission FROM agent_commission_records GROUP BY agent_id ) commission_stats ON ra.id = commission_stats.agent_id `; const statsResult = await db.query(statsQuery); const stats = statsResult && statsResult.length > 0 ? statsResult[0] : { total_agents: 0, pending_agents: 0, active_agents: 0, total_commission: 0 }; res.json({ success: true, data: { agents, total: parseInt(total), stats } }); } 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 agentQuery = ` SELECT ra.*, u.real_name as name, u.phone, u.id_card, CONCAT(u.city, ' ', zr.district_name) as address, zr.city_name, zr.district_name, ( SELECT COUNT(DISTINCT merchant_id) FROM agent_merchants WHERE agent_id = ra.id ) as merchant_count, ( SELECT COALESCE(SUM(commission_amount), 0) FROM agent_commission_records WHERE agent_id = ra.id ) as total_commission, 0 as paid_commission, ( SELECT COALESCE(SUM(commission_amount), 0) FROM agent_commission_records WHERE agent_id = ra.id ) as pending_commission FROM regional_agents ra LEFT JOIN users u ON ra.user_id = u.id LEFT JOIN zhejiang_regions zr ON ra.region_id = zr.id WHERE ra.id = ? `; const agentResult = await db.query(agentQuery, [id]); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在' }); } const agent = agentResult[0]; res.json({ success: true, data: agent }); } catch (error) { console.error('获取代理详情失败:', error); res.status(500).json({ success: false, message: '获取代理详情失败' }); } }); // 审核通过代理申请 router.put('/:id/approve', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { password } = req.body; if (!password || password.length < 6) { return res.status(400).json({ success: false, message: '密码长度不能少于6位' }); } // 检查代理是否存在且状态为待审核 const agents = await db.query( 'SELECT * FROM regional_agents WHERE id = ? AND status = "pending"', [id] ); if (!agents || agents.length === 0) { return res.status(404).json({ success: false, message: '代理不存在或状态不正确' }); } const agent = agents[0]; // 检查该区域是否已有其他激活的代理 const existingActiveAgents = await db.query( 'SELECT id FROM regional_agents WHERE region_id = ? AND status = "active" AND id != ?', [agent.region_id, id] ); if (existingActiveAgents && existingActiveAgents.length > 0) { return res.status(400).json({ success: false, message: '该区域已有激活的代理,每个区域只能有一个代理账号' }); } // 加密密码并更新用户表 const hashedPassword = await bcrypt.hash(password, 10); // 更新用户密码 await db.query( `UPDATE users SET password = ? WHERE id = ( SELECT user_id FROM regional_agents WHERE id = ? )`, [hashedPassword, id] ); // 更新代理状态 await db.query( `UPDATE regional_agents SET status = 'active', approved_at = NOW(), approved_by_admin_id = ? WHERE id = ?`, [req.user.id, id] ); res.json({ success: true, message: '代理申请已通过' }); } catch (error) { console.error('审核代理申请失败:', error); res.status(500).json({ success: false, message: '审核代理申请失败' }); } }); // 拒绝代理申请 router.put('/:id/reject', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { reason } = req.body; if (!reason || reason.trim() === '') { return res.status(400).json({ success: false, message: '请输入拒绝原因' }); } // 检查代理是否存在且状态为待审核 const agentResult = await db.query( 'SELECT * FROM regional_agents WHERE id = ? AND status = "pending"', [id] ); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在或状态不正确' }); } const agent = agentResult[0]; // 更新代理状态 await db.query( `UPDATE regional_agents SET status = 'rejected', reject_reason = ?, rejected_at = NOW(), rejected_by_admin_id = ? WHERE id = ?`, [reason.trim(), req.user.id, id] ); res.json({ success: true, message: '代理申请已拒绝' }); } catch (error) { console.error('拒绝代理申请失败:', error); res.status(500).json({ success: false, message: '拒绝代理申请失败' }); } }); // 禁用代理 router.put('/:id/disable', authenticateAdmin, async (req, res) => { try { const { id } = req.params; // 检查代理是否存在且状态为激活 const agentResult = await db.query( 'SELECT * FROM regional_agents WHERE id = ? AND status = "active"', [id] ); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在或状态不正确' }); } const agent = agentResult[0]; // 更新代理状态 await db.query( 'UPDATE regional_agents SET status = "disabled", disabled_at = NOW() WHERE id = ?', [id] ); res.json({ success: true, message: '代理已禁用' }); } catch (error) { console.error('禁用代理失败:', error); res.status(500).json({ success: false, message: '禁用代理失败' }); } }); // 启用代理 router.put('/:id/enable', authenticateAdmin, async (req, res) => { try { const { id } = req.params; // 检查代理是否存在且状态为禁用 const agentResult = await db.query( 'SELECT * FROM regional_agents WHERE id = ? AND status = "disabled"', [id] ); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在或状态不正确' }); } const agent = agentResult[0]; // 检查该区域是否已有其他激活的代理 const existingActiveAgentResult = await db.query( 'SELECT id FROM regional_agents WHERE region_id = ? AND status = "active" AND id != ?', [agent.region_id, id] ); if (existingActiveAgentResult && existingActiveAgentResult.length > 0) { return res.status(400).json({ success: false, message: '该区域已有激活的代理,每个区域只能有一个代理账号' }); } // 更新代理状态 await db.query( 'UPDATE regional_agents SET status = "active", disabled_at = NULL WHERE id = ?', [id] ); res.json({ success: true, message: '代理已启用' }); } catch (error) { console.error('启用代理失败:', error); res.status(500).json({ success: false, message: '启用代理失败' }); } }); // 获取代理商户列表 router.get('/:id/merchants', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { page = 1, limit = 20 } = req.query; const pageNum = parseInt(page) || 1; const limitNum = parseInt(limit) || 20; const offset = (pageNum - 1) * limitNum; // 检查代理是否存在 const agentResult = await db.query('SELECT * FROM regional_agents WHERE id = ?', [id]); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在' }); } const agent = agentResult[0]; // 查询代理的商户列表 const merchantsQuery = ` SELECT u.id, u.real_name, u.phone, u.created_at, am.created_at as joined_at, COUNT(mo.id) as match_count, COUNT(CASE WHEN mo.status = 'completed' THEN 1 END) as completed_matches FROM agent_merchants am JOIN users u ON am.merchant_id = u.id LEFT JOIN matching_orders mo ON u.id = mo.initiator_id WHERE am.agent_id = ? GROUP BY u.id, am.created_at ORDER BY am.created_at DESC LIMIT ${limitNum} OFFSET ${offset} `; const merchants = await db.query(merchantsQuery, [id]); // 查询总数 const totalResult = await db.query( 'SELECT COUNT(*) as total FROM agent_merchants WHERE agent_id = ?', [id] ); const total = totalResult && totalResult.length > 0 ? totalResult[0].total : 0; res.json({ success: true, data: { merchants, total: parseInt(total) } }); } catch (error) { console.error('获取代理商户列表失败:', error); res.status(500).json({ success: false, message: '获取代理商户列表失败' }); } }); // 获取代理佣金记录 router.get('/:id/commissions', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { page = 1, limit = 20 } = req.query; const pageNum = parseInt(page) || 1; const limitNum = parseInt(limit) || 20; const offset = (pageNum - 1) * limitNum; // 检查代理是否存在 const agentResult = await db.query('SELECT * FROM regional_agents WHERE id = ?', [id]); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在' }); } const agent = agentResult[0]; // 查询佣金记录 const commissionsQuery = ` SELECT acr.*, u.phone as merchant_phone FROM agent_commission_records acr JOIN users u ON acr.merchant_id = u.id WHERE acr.agent_id = ? ORDER BY acr.created_at DESC LIMIT ${limitNum} OFFSET ${offset} `; const commissions = await db.query(commissionsQuery, [id]); // 查询总数 const totalResult = await db.query( 'SELECT COUNT(*) as total FROM agent_commission_records WHERE agent_id = ?', [id] ); const total = totalResult && totalResult.length > 0 ? totalResult[0].total : 0; res.json({ success: true, data: { commissions, total: parseInt(total) } }); } catch (error) { console.error('获取代理佣金记录失败:', error); res.status(500).json({ success: false, message: '获取代理佣金记录失败' }); } }); // 获取代理商户的转账记录 router.get('/:id/merchant-transfers', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { page = 1, limit = 20, merchant_id } = req.query; const pageNum = parseInt(page) || 1; const limitNum = parseInt(limit) || 20; const offset = (pageNum - 1) * limitNum; // 检查代理是否存在 const agentResult = await db.query('SELECT * FROM regional_agents WHERE id = ?', [id]); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在' }); } // 构建查询条件 let whereConditions = ['am.agent_id = ?']; let queryParams = [id]; if (merchant_id) { whereConditions.push('t.from_user_id = ?'); queryParams.push(merchant_id); } const whereClause = whereConditions.join(' AND '); // 查询商户转账记录 const transfersQuery = ` SELECT t.id, t.from_user_id, t.to_user_id, t.amount, t.status, t.transfer_type, t.description, t.created_at, t.confirmed_at, from_user.real_name as from_real_name, CONCAT(SUBSTRING(from_user.phone, 1, 3), '****', SUBSTRING(from_user.phone, -4)) as from_phone_masked, to_user.real_name as to_real_name, CONCAT(SUBSTRING(to_user.phone, 1, 3), '****', SUBSTRING(to_user.phone, -4)) as to_phone_masked FROM agent_merchants am JOIN transfers t ON am.merchant_id = t.from_user_id LEFT JOIN users from_user ON t.from_user_id = from_user.id LEFT JOIN users to_user ON t.to_user_id = to_user.id WHERE ${whereClause} ORDER BY t.created_at DESC LIMIT ${limitNum} OFFSET ${offset} `; const transfers = await db.query(transfersQuery, queryParams); // 查询总数 const totalQuery = ` SELECT COUNT(*) as total FROM agent_merchants am JOIN transfers t ON am.merchant_id = t.from_user_id WHERE ${whereClause} `; const totalResult = await db.query(totalQuery, queryParams); const total = totalResult && totalResult.length > 0 ? totalResult[0].total : 0; res.json({ success: true, data: { transfers, total: parseInt(total) } }); } catch (error) { console.error('1:', error); res.status(500).json({ success: false, message: '1获取代理商户转账记录失败' }); } }); /** * 修改代理密码 */ router.put('/:id/password', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { password } = req.body; if (!password || password.length < 6) { return res.status(400).json({ success: false, message: '密码长度不能少于6位' }); } // 检查代理是否存在且状态为激活 const agentResult = await db.query( 'SELECT * FROM regional_agents WHERE id = ? AND status = "active"', [id] ); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在或状态不正确' }); } // 加密新密码 const hashedPassword = await bcrypt.hash(password, 10); // 更新用户表中的密码(与审核通过时的逻辑一致) await db.query( `UPDATE users SET password = ? WHERE id = ( SELECT user_id FROM regional_agents WHERE id = ? )`, [hashedPassword, id] ); res.json({ success: true, message: '代理密码修改成功' }); } catch (error) { console.error('修改代理密码失败:', error); res.status(500).json({ success: false, message: '修改代理密码失败' }); } }); /** * 删除代理 */ router.delete('/:id', authenticateAdmin, async (req, res) => { try { const { id } = req.params; const { force = 'false' } = req.query; // 是否强制删除 const forceDelete = force === 'true' // 检查代理是否存在 const agentResult = await db.query( 'SELECT * FROM regional_agents WHERE id = ?', [id] ); if (!agentResult || agentResult.length === 0) { return res.status(404).json({ success: false, message: '代理不存在' }); } const agent = agentResult[0]; // 检查代理是否有关联的商户 const merchantCount = await db.query( 'SELECT COUNT(*) as count FROM agent_merchants WHERE agent_id = ?', [id] ); const hasMerchants = merchantCount && merchantCount.length > 0 && merchantCount[0].count > 0; // 检查代理是否有佣金记录 const commissionCount = await db.query( 'SELECT COUNT(*) as count FROM agent_commission_records WHERE agent_id = ?', [id] ); const hasCommissions = commissionCount && commissionCount.length > 0 && commissionCount[0].count > 0; // 如果有关联数据且不是强制删除,则提示用户 // if ((hasMerchants || hasCommissions) && !forceDelete) { // return res.status(400).json({ // success: false, // message: '该代理存在关联数据(商户或佣金记录),请确认是否强制删除', // data: { // has_merchants: hasMerchants, // has_commissions: hasCommissions, // merchant_count: hasMerchants ? merchantCount[0].count : 0, // commission_count: hasCommissions ? commissionCount[0].count : 0 // }, // require_force: true // }); // } // 开始事务删除 const pool = getDB(); const connection = await pool.getConnection(); await connection.beginTransaction(); try { // 删除代理商户关系 if (hasMerchants) { await connection.execute('DELETE FROM agent_merchants WHERE agent_id = ?', [id]); } // 删除佣金记录(根据业务需求,可能需要保留历史记录) if (hasCommissions && forceDelete) { await connection.execute('DELETE FROM agent_commission_records WHERE agent_id = ?', [id]); } // 删除代理记录 await connection.execute('DELETE FROM regional_agents WHERE id = ?', [id]); // 获取区域信息用于日志 const [regionResult] = await connection.execute( 'SELECT * FROM zhejiang_regions WHERE id = ?', [agent.region_id] ); const region = regionResult && regionResult.length > 0 ? regionResult[0] : null; await connection.commit(); // 记录操作日志 const logMessage = `删除代理: ${agent.user_id} (区域: ${region ? `${region.city_name} ${region.district_name}` : '未知区域'})`; console.log(`管理员 ${req.user.id} 执行操作: ${logMessage}`); res.json({ success: true, message: '代理删除成功', data: { deleted_agent_id: id, deleted_merchants: hasMerchants ? merchantCount[0].count : 0, deleted_commissions: (hasCommissions && forceDelete) ? commissionCount[0].count : 0 } }); } catch (error) { await connection.rollback(); throw error; } finally { connection.release(); } } catch (error) { console.error('删除代理失败:', error); res.status(500).json({ success: false, message: '删除代理失败' }); } }); /** * 获取可用的城市区域列表(用于代理城市更换) */ router.get('/available-regions', authenticateAdmin, async (req, res) => { try { // 查询所有区域,并标记是否已有激活代理 const regionsQuery = ` SELECT zr.id, zr.city_name, zr.district_name, CASE WHEN ra.id IS NOT NULL THEN 1 ELSE 0 END as has_active_agent, ra.id as agent_id, u.real_name as agent_name FROM zhejiang_regions zr LEFT JOIN regional_agents ra ON zr.id = ra.region_id AND ra.status = 'active' LEFT JOIN users u ON ra.user_id = u.id ORDER BY zr.city_name, zr.district_name `; const regions = await db.query(regionsQuery); res.json({ success: true, data: regions }); } catch (error) { console.error('获取可用区域列表失败:', error); res.status(500).json({ success: false, message: '获取可用区域列表失败' }); } }); module.exports = router;