| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  | const express = require('express'); | 
					
						
							|  |  |  |  | const router = express.Router(); | 
					
						
							|  |  |  |  | const { getDB } = require('../../database'); | 
					
						
							|  |  |  |  | const bcrypt = require('bcryptjs'); | 
					
						
							|  |  |  |  | const { auth, adminAuth } = require('../../middleware/auth'); | 
					
						
							| 
									
										
										
										
											2025-09-10 18:10:40 +08:00
										 |  |  |  | const dayjs = require('dayjs'); | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | // 创建管理员认证中间件组合
 | 
					
						
							|  |  |  |  | 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 { | 
					
						
							| 
									
										
										
										
											2025-09-15 17:27:13 +08:00
										 |  |  |  |     const { page = 1, limit = 20, status, city, search,district } = req.query; | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  |     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); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							| 
									
										
										
										
											2025-09-15 17:27:13 +08:00
										 |  |  |  |     if (district) { | 
					
						
							|  |  |  |  |       whereConditions.push('zr.name = ?'); | 
					
						
							|  |  |  |  |       queryParams.push(district); | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     if (search) { | 
					
						
							| 
									
										
										
										
											2025-09-15 17:27:13 +08:00
										 |  |  |  |       whereConditions.push('(u.real_name LIKE ? OR u.phone LIKE ?)'); | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  |       queryParams.push(`%${search}%`, `%${search}%`); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(' AND ')}` : ''; | 
					
						
							|  |  |  |  |      | 
					
						
							|  |  |  |  |     // 查询代理列表
 | 
					
						
							|  |  |  |  |     const agentsQuery = `
 | 
					
						
							| 
									
										
										
										
											2025-09-15 17:27:13 +08:00
										 |  |  |  |         SELECT ra.*, | 
					
						
							|  |  |  |  |                u.real_name, | 
					
						
							|  |  |  |  |                u.phone, | 
					
						
							|  |  |  |  |                u.id_card, | 
					
						
							|  |  |  |  |                province.name            AS province_name, | 
					
						
							|  |  |  |  |                city.name                AS city_name, | 
					
						
							|  |  |  |  |                zr.name                  AS 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 china_regions zr ON ra.region_id = zr.code -- 区 | 
					
						
							|  |  |  |  |                  LEFT JOIN china_regions city ON zr.parent_code = city.code -- 市 | 
					
						
							|  |  |  |  |                  LEFT JOIN china_regions province ON city.parent_code = province.code -- 省 | 
					
						
							|  |  |  |  |             ${whereClause} | 
					
						
							|  |  |  |  |         ORDER BY ra.created_at | 
					
						
							|  |  |  |  |         DESC | 
					
						
							|  |  |  |  |             LIMIT ${limitNum} OFFSET ${offset};`;
 | 
					
						
							|  |  |  |  |       console.log(agentsQuery,queryParams) | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  |     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 | 
					
						
							| 
									
										
										
										
											2025-09-15 17:27:13 +08:00
										 |  |  |  |       LEFT JOIN china_regions zr ON ra.region_id = zr.code | 
					
						
							| 
									
										
										
										
											2025-09-02 09:38:16 +08:00
										 |  |  |  |       ${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 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; |