/** * 用户控制器 * @file userController.js * @description 处理用户相关的请求 */ const { User, Role } = require('../models'); const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); /** * 根据用户名搜索用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.searchUserByUsername = async (req, res) => { const searchStartTime = Date.now(); const requestId = Math.random().toString(36).substr(2, 9); try { const { username } = req.query; const userAgent = req.get('User-Agent') || 'Unknown'; const clientIP = req.ip || req.connection.remoteAddress || 'Unknown'; console.log(`🔍 [后端用户搜索监听] 搜索请求开始:`, { requestId: requestId, keyword: username, timestamp: new Date().toISOString(), clientIP: clientIP, userAgent: userAgent, queryParams: req.query, headers: { 'content-type': req.get('Content-Type'), 'accept': req.get('Accept'), 'referer': req.get('Referer') } }); if (!username || username.trim() === '') { console.log(`❌ [后端用户搜索监听] 搜索关键词为空:`, { requestId: requestId, keyword: username }); return res.status(400).json({ success: false, message: '请提供搜索关键词' }); } console.log(`🔄 [后端用户搜索监听] 开始数据库查询:`, { requestId: requestId, searchKeyword: username, searchPattern: `%${username}%` }); const queryStartTime = Date.now(); // 搜索用户 const users = await User.findAll({ where: { username: { [require('sequelize').Op.like]: `%${username}%` } }, attributes: { exclude: ['password'] }, order: [['created_at', 'DESC']] }); const queryTime = Date.now() - queryStartTime; const totalTime = Date.now() - searchStartTime; console.log(`📊 [后端用户搜索监听] 数据库查询完成:`, { requestId: requestId, queryTime: queryTime + 'ms', totalTime: totalTime + 'ms', resultCount: users.length, searchKeyword: username }); // 获取角色信息 const roleIds = [...new Set(users.map(user => user.roles).filter(id => id))]; const roles = await Role.findAll({ where: { id: roleIds }, attributes: ['id', 'name', 'description'] }); const roleMap = roles.reduce((map, role) => { map[role.id] = role; return map; }, {}); // 转换数据格式,添加角色名称 const usersWithRole = users.map(user => { const userData = user.toJSON(); const role = roleMap[userData.roles]; userData.role = role ? { id: role.id, name: role.name, description: role.description } : null; userData.roleName = role ? role.name : 'user'; userData.status = userData.status || 'active'; return userData; }); // 记录搜索结果详情 if (usersWithRole.length > 0) { console.log(`📋 [后端用户搜索监听] 搜索结果详情:`, { requestId: requestId, results: usersWithRole.map(user => ({ id: user.id, username: user.username, email: user.email, roleName: user.roleName })) }); } console.log(`✅ [后端用户搜索监听] 搜索成功:`, { requestId: requestId, keyword: username, resultCount: usersWithRole.length, responseTime: totalTime + 'ms' }); res.status(200).json({ success: true, data: usersWithRole, meta: { requestId: requestId, searchKeyword: username, resultCount: usersWithRole.length, queryTime: queryTime, totalTime: totalTime, timestamp: new Date().toISOString() } }); } catch (error) { const errorTime = Date.now() - searchStartTime; console.error(`❌ [后端用户搜索监听] 搜索失败:`, { requestId: requestId, error: error.message, stack: error.stack, errorTime: errorTime + 'ms', keyword: req.query.username }); res.status(500).json({ success: false, message: '搜索用户失败', error: error.message, meta: { requestId: requestId, errorTime: errorTime, timestamp: new Date().toISOString() } }); } }; /** * 获取所有用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAllUsers = async (req, res) => { try { console.log('开始获取用户列表...'); // 获取所有用户 const users = await User.findAll({ attributes: { exclude: ['password'] } // 排除密码字段 }); console.log(`查询到 ${users.length} 个用户`); // 获取所有角色信息 const roleIds = [...new Set(users.map(user => user.roles).filter(id => id))]; const roles = await Role.findAll({ where: { id: roleIds }, attributes: ['id', 'name', 'description'] }); const roleMap = roles.reduce((map, role) => { map[role.id] = role; return map; }, {}); // 转换数据格式,添加角色名称 const usersWithRole = users.map(user => { const userData = user.toJSON(); const role = roleMap[userData.roles]; userData.role = role ? { id: role.id, name: role.name, description: role.description } : null; userData.roleName = role ? role.name : 'user'; userData.status = userData.status || 'active'; // 默认状态 return userData; }); console.log('用户数据转换完成'); res.status(200).json({ success: true, data: usersWithRole }); } catch (error) { console.error('获取用户列表失败:', error); res.status(500).json({ success: false, message: '获取用户列表失败', error: error.message }); } }; /** * 根据ID获取用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getUserById = async (req, res) => { try { const { id } = req.params; console.log(`开始获取用户详情,ID: ${id}`); const user = await User.findByPk(id, { attributes: { exclude: ['password'] } // 排除密码字段 }); if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }); } // 获取角色信息 const role = await Role.findByPk(user.roles); // 添加角色名称字段 const userData = user.toJSON(); userData.role = role ? { id: role.id, name: role.name, description: role.description } : null; userData.roleName = role ? role.name : 'user'; userData.status = userData.status || 'active'; // 默认状态 console.log('用户详情获取成功'); res.status(200).json({ success: true, data: userData }); } catch (error) { console.error(`获取用户(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '获取用户详情失败', error: error.message }); } }; /** * 创建用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.createUser = async (req, res) => { try { // 测试参数,用于测试不同的响应情况 if (req.query.testBadRequest === 'true') { return res.status(400).json({ success: false, message: '请求参数错误' }); } if (req.query.testUnauthorized === 'true') { return res.status(401).json({ success: false, message: '未授权' }); } if (req.query.testConflict === 'true') { return res.status(409).json({ success: false, message: '用户名或邮箱已存在' }); } if (req.query.testError === 'true') { return res.status(500).json({ success: false, message: '服务器错误' }); } const { username, email, password, phone, avatar, status, roles } = req.body; // 验证必填字段 if (!username || !email || !password) { return res.status(400).json({ success: false, message: '用户名、邮箱和密码为必填项' }); } // 检查用户名或邮箱是否已存在 const existingUser = await User.findOne({ where: { [require('sequelize').Op.or]: [ { username }, { email } ] } }); if (existingUser) { return res.status(409).json({ success: false, message: '用户名或邮箱已存在' }); } const user = await User.create({ username, email, password, phone, avatar, status: status || 'active', roles: roles || 2 // 默认为普通用户角色ID }); // 返回用户信息(不包含密码) const userResponse = { id: user.id, username: user.username, email: user.email, phone: user.phone, avatar: user.avatar, status: user.status, createdAt: user.createdAt, updatedAt: user.updatedAt }; res.status(201).json({ success: true, message: '用户创建成功', data: userResponse }); } catch (error) { console.error('创建用户失败:', error); res.status(500).json({ success: false, message: '创建用户失败', error: error.message }); } }; /** * 更新用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.updateUser = async (req, res) => { try { // 测试参数,用于测试不同的响应情况 if (req.query.testUnauthorized === 'true') { return res.status(401).json({ success: false, message: '未授权' }); } if (req.query.testNotFound === 'true') { return res.status(404).json({ success: false, message: '用户不存在' }); } if (req.query.testError === 'true') { return res.status(500).json({ success: false, message: '服务器错误' }); } const { id } = req.params; const { username, email, phone, avatar, status, password, roles } = req.body; const user = await User.findByPk(id); if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }); } // 如果更新用户名或邮箱,检查是否与其他用户冲突 if (username || email) { const existingUser = await User.findOne({ where: { id: { [require('sequelize').Op.ne]: id }, [require('sequelize').Op.or]: [ ...(username ? [{ username }] : []), ...(email ? [{ email }] : []) ] } }); if (existingUser) { return res.status(409).json({ success: false, message: '用户名或邮箱已被其他用户使用' }); } } // 准备更新数据 const updateData = {}; if (username !== undefined) updateData.username = username; if (email !== undefined) updateData.email = email; if (phone !== undefined) updateData.phone = phone; if (avatar !== undefined) updateData.avatar = avatar; if (status !== undefined) updateData.status = status; if (roles !== undefined) updateData.roles = roles; // 直接更新roles字段 // 如果需要更新密码,先加密 if (password) { updateData.password = await bcrypt.hash(password, 10); } await user.update(updateData); // 获取角色信息 const role = await Role.findByPk(user.roles); // 构建响应数据 const userData = { id: user.id, username: user.username, email: user.email, phone: user.phone, avatar: user.avatar, roles: user.roles, status: user.status, created_at: user.created_at, updated_at: user.updated_at, role: role ? { id: role.id, name: role.name, description: role.description } : null, roleName: role ? role.name : 'user' }; res.status(200).json({ success: true, message: '用户更新成功', data: userData }); } catch (error) { console.error(`更新用户(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '更新用户失败', error: error.message }); } }; /** * 删除用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.deleteUser = async (req, res) => { try { // 测试参数,用于测试不同的响应情况 if (req.query.testUnauthorized === 'true') { return res.status(401).json({ success: false, message: '未授权' }); } if (req.query.testNotFound === 'true') { return res.status(404).json({ success: false, message: '用户不存在' }); } if (req.query.testError === 'true') { return res.status(500).json({ success: false, message: '服务器错误' }); } const { id } = req.params; const user = await User.findByPk(id); if (!user) { return res.status(404).json({ success: false, message: '用户不存在' }); } await user.destroy(); res.status(200).json({ success: true, message: '用户删除成功' }); } catch (error) { console.error(`删除用户(ID: ${req.params.id})失败:`, error); res.status(500).json({ success: false, message: '删除用户失败', error: error.message }); } }; /** * 根据用户名搜索用户 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.searchUserByUsername = async (req, res) => { try { const { username } = req.query; if (!username) { return res.status(400).json({ success: false, message: '请提供用户名参数' }); } console.log(`开始搜索用户名包含: ${username}`); // 使用模糊查询搜索用户名 const users = await User.findAll({ where: { username: { [require('sequelize').Op.like]: `%${username}%` } }, attributes: { exclude: ['password'] } // 排除密码字段 }); console.log(`找到 ${users.length} 个匹配的用户`); // 获取所有角色信息 const roleIds = [...new Set(users.map(user => user.roles).filter(id => id))]; const roles = await Role.findAll({ where: { id: roleIds }, attributes: ['id', 'name', 'description'] }); const roleMap = roles.reduce((map, role) => { map[role.id] = role; return map; }, {}); // 转换数据格式,添加角色名称 const usersWithRole = users.map(user => { const userData = user.toJSON(); const role = roleMap[userData.roles]; userData.role = role ? { id: role.id, name: role.name, description: role.description } : null; userData.roleName = role ? role.name : 'user'; userData.status = userData.status || 'active'; // 默认状态 return userData; }); res.status(200).json({ success: true, data: usersWithRole, message: `找到 ${usersWithRole.length} 个匹配的用户` }); } catch (error) { console.error('搜索用户失败:', error); res.status(500).json({ success: false, message: '搜索用户失败', error: error.message }); } }; /** * 用户登录 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.login = async (req, res) => { try { // 测试参数,用于测试不同的响应情况 if (req.query.testBadRequest === 'true') { return res.status(400).json({ success: false, message: '请求参数错误' }); } if (req.query.testUnauthorized === 'true') { return res.status(401).json({ success: false, message: '用户名或密码错误' }); } if (req.query.testError === 'true') { return res.status(500).json({ success: false, message: '服务器错误' }); } const { username, password } = req.body; if (!username || !password) { return res.status(400).json({ success: false, message: '用户名和密码为必填项' }); } // 查找用户(支持用户名或邮箱登录) const user = await User.findOne({ where: { [require('sequelize').Op.or]: [ { username }, { email: username } ] } }); if (!user) { return res.status(401).json({ success: false, message: '用户名或密码错误' }); } // 验证密码 const isValidPassword = await user.validPassword(password); if (!isValidPassword) { return res.status(401).json({ success: false, message: '用户名或密码错误' }); } // 检查用户状态 if (user.status !== 'active') { return res.status(401).json({ success: false, message: '账户已被禁用' }); } // 生成JWT token const token = jwt.sign( { userId: user.id, username: user.username }, process.env.JWT_SECRET || 'your-secret-key', { expiresIn: '24h' } ); // 返回用户信息和token(不包含密码) const userResponse = { id: user.id, username: user.username, email: user.email, phone: user.phone, avatar: user.avatar, status: user.status, createdAt: user.createdAt, updatedAt: user.updatedAt }; res.status(200).json({ success: true, message: '登录成功', data: { user: userResponse, token } }); } catch (error) { console.error('用户登录失败:', error); res.status(500).json({ success: false, message: '登录失败', error: error.message }); } };