/** * 角色权限管理控制器 * @file rolePermissionController.js * @description 处理角色权限管理相关的请求 */ const { Role, MenuPermission, User, Permission } = require('../models'); const { Op } = require('sequelize'); const logger = require('../utils/logger'); /** * 获取所有角色 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAllRoles = async (req, res) => { try { const { page = 1, pageSize = 10, search = '' } = req.query; const offset = (page - 1) * pageSize; const limit = parseInt(pageSize); // 构建查询条件 const whereCondition = {}; if (search) { whereCondition[Op.or] = [ { name: { [Op.like]: `%${search}%` } }, { description: { [Op.like]: `%${search}%` } } ]; } const { count, rows } = await Role.findAndCountAll({ where: whereCondition, include: [ { model: MenuPermission, as: 'menuPermissions', through: { attributes: [] } }, { model: Permission, as: 'permissions', through: { attributes: [] } } ], order: [['created_at', 'DESC']], offset, limit }); res.status(200).json({ success: true, data: { list: rows, pagination: { current: parseInt(page), pageSize: limit, total: count, pages: Math.ceil(count / limit) } }, message: '获取角色列表成功' }); } catch (error) { console.error('获取角色列表失败:', error); res.status(500).json({ success: false, message: '获取角色列表失败', error: error.message }); } }; /** * 获取角色详情 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getRoleById = async (req, res) => { try { const { id } = req.params; const role = await Role.findByPk(id, { include: [ { model: MenuPermission, as: 'menuPermissions', through: { attributes: [] }, order: [['sort_order', 'ASC']] }, { model: User, as: 'users', attributes: ['id', 'username', 'email'], through: { attributes: [] } } ] }); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } res.status(200).json({ success: true, data: role, message: '获取角色详情成功' }); } catch (error) { console.error('获取角色详情失败:', error); res.status(500).json({ success: false, message: '获取角色详情失败', error: error.message }); } }; /** * 创建角色 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.createRole = async (req, res) => { try { const { name, description, status = true, menuIds = [] } = req.body; // 验证必填字段 if (!name) { return res.status(400).json({ success: false, message: '角色名称为必填项' }); } // 检查角色名称是否重复 const existingRole = await Role.findOne({ where: { name } }); if (existingRole) { return res.status(400).json({ success: false, message: '角色名称已存在' }); } // 创建角色 const role = await Role.create({ name, description, status }); // 设置菜单权限 if (menuIds && menuIds.length > 0) { await role.setMenuPermissions(menuIds); } // 重新获取角色信息(包含关联数据) const roleWithPermissions = await Role.findByPk(role.id, { include: [ { model: MenuPermission, as: 'menuPermissions', through: { attributes: [] } } ] }); res.status(201).json({ success: true, data: roleWithPermissions, message: '角色创建成功' }); } catch (error) { console.error('创建角色失败:', error); res.status(500).json({ success: false, message: '创建角色失败', error: error.message }); } }; /** * 更新角色 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.updateRole = async (req, res) => { try { const { id } = req.params; const updateData = req.body; const role = await Role.findByPk(id); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 如果更新名称,检查是否重复 if (updateData.name && updateData.name !== role.name) { const existingRole = await Role.findOne({ where: { name: updateData.name, id: { [Op.ne]: id } } }); if (existingRole) { return res.status(400).json({ success: false, message: '角色名称已存在' }); } } // 更新角色基本信息 const { menuIds, ...roleData } = updateData; await role.update(roleData); // 更新菜单权限 if (menuIds !== undefined) { await role.setMenuPermissions(menuIds || []); } // 重新获取角色信息(包含关联数据) const updatedRole = await Role.findByPk(id, { include: [ { model: MenuPermission, as: 'menuPermissions', through: { attributes: [] } } ] }); res.status(200).json({ success: true, data: updatedRole, message: '角色更新成功' }); } catch (error) { console.error('更新角色失败:', error); res.status(500).json({ success: false, message: '更新角色失败', error: error.message }); } }; /** * 删除角色 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.deleteRole = async (req, res) => { try { const { id } = req.params; const role = await Role.findByPk(id); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 检查是否有用户使用该角色 const userCount = await User.count({ where: { roles: id } }); if (userCount > 0) { return res.status(400).json({ success: false, message: '该角色下还有用户,无法删除' }); } await role.destroy(); res.status(200).json({ success: true, message: '角色删除成功' }); } catch (error) { console.error('删除角色失败:', error); res.status(500).json({ success: false, message: '删除角色失败', error: error.message }); } }; /** * 获取角色的菜单权限 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getRoleMenuPermissions = async (req, res) => { try { const { roleId } = req.params; const role = await Role.findByPk(roleId, { include: [ { model: MenuPermission, as: 'menuPermissions', through: { attributes: [] }, order: [['sort_order', 'ASC']] } ] }); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } res.status(200).json({ success: true, data: { roleId: role.id, roleName: role.name, permissions: role.menuPermissions }, message: '获取角色菜单权限成功' }); } catch (error) { console.error('获取角色菜单权限失败:', error); res.status(500).json({ success: false, message: '获取角色菜单权限失败', error: error.message }); } }; /** * 设置角色的菜单权限 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.setRoleMenuPermissions = async (req, res) => { try { const { roleId } = req.params; const { menuIds } = req.body; const role = await Role.findByPk(roleId); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 设置菜单权限 await role.setMenuPermissions(menuIds || []); res.status(200).json({ success: true, message: '设置角色菜单权限成功' }); } catch (error) { console.error('设置角色菜单权限失败:', error); res.status(500).json({ success: false, message: '设置角色菜单权限失败', error: error.message }); } }; /** * 获取所有菜单权限(用于权限分配) * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAllMenuPermissions = async (req, res) => { try { const menus = await MenuPermission.findAll({ order: [['sort_order', 'ASC'], ['id', 'ASC']] }); // 构建树形结构 const menuTree = buildMenuTree(menus); res.status(200).json({ success: true, data: menuTree, message: '获取菜单权限列表成功' }); } catch (error) { console.error('获取菜单权限列表失败:', error); res.status(500).json({ success: false, message: '获取菜单权限列表失败', error: error.message }); } }; /** * 构建菜单树形结构 * @param {Array} menus - 菜单数组 * @returns {Array} 树形结构的菜单数组 */ function buildMenuTree(menus) { const menuMap = new Map(); const rootMenus = []; // 创建菜单映射 menus.forEach(menu => { menuMap.set(menu.id, { ...menu.toJSON(), children: [] }); }); // 构建树形结构 menus.forEach(menu => { const menuItem = menuMap.get(menu.id); if (menu.parent_id) { const parent = menuMap.get(menu.parent_id); if (parent) { parent.children.push(menuItem); } } else { rootMenus.push(menuItem); } }); return rootMenus; } /** * 获取所有权限(用于权限分配) * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getAllPermissions = async (req, res) => { try { const { module, action } = req.query; const whereCondition = {}; if (module) { whereCondition.module = module; } if (action) { whereCondition.action = action; } const permissions = await Permission.findAll({ where: whereCondition, order: [['module', 'ASC'], ['action', 'ASC'], ['id', 'ASC']] }); // 按模块分组 const groupedPermissions = permissions.reduce((acc, permission) => { const module = permission.module; if (!acc[module]) { acc[module] = []; } acc[module].push(permission); return acc; }, {}); res.status(200).json({ success: true, data: { permissions: permissions, groupedPermissions: groupedPermissions, modules: Object.keys(groupedPermissions) }, message: '获取权限列表成功' }); } catch (error) { console.error('获取权限列表失败:', error); res.status(500).json({ success: false, message: '获取权限列表失败', error: error.message }); } }; /** * 获取角色的功能权限 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getRolePermissions = async (req, res) => { try { const { roleId } = req.params; const role = await Role.findByPk(roleId, { include: [ { model: Permission, as: 'permissions', through: { attributes: [] }, order: [['module', 'ASC'], ['action', 'ASC']] } ] }); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 按模块分组权限 const groupedPermissions = role.permissions.reduce((acc, permission) => { const module = permission.module; if (!acc[module]) { acc[module] = []; } acc[module].push(permission); return acc; }, {}); res.status(200).json({ success: true, data: { roleId: role.id, roleName: role.name, permissions: role.permissions, groupedPermissions: groupedPermissions, modules: Object.keys(groupedPermissions) }, message: '获取角色权限成功' }); } catch (error) { console.error('获取角色权限失败:', error); res.status(500).json({ success: false, message: '获取角色权限失败', error: error.message }); } }; /** * 设置角色的功能权限 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.setRolePermissions = async (req, res) => { try { const { roleId } = req.params; const { permissionIds } = req.body; const role = await Role.findByPk(roleId); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 设置权限 await role.setPermissions(permissionIds || []); // 重新获取角色信息(包含关联数据) const updatedRole = await Role.findByPk(roleId, { include: [ { model: Permission, as: 'permissions', through: { attributes: [] } } ] }); res.status(200).json({ success: true, data: updatedRole, message: '设置角色权限成功' }); } catch (error) { console.error('设置角色权限失败:', error); res.status(500).json({ success: false, message: '设置角色权限失败', error: error.message }); } }; /** * 获取权限模块列表 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.getPermissionModules = async (req, res) => { try { const modules = await Permission.findAll({ attributes: ['module'], group: ['module'], order: [['module', 'ASC']] }); res.status(200).json({ success: true, data: modules.map(m => m.module), message: '获取权限模块列表成功' }); } catch (error) { console.error('获取权限模块列表失败:', error); res.status(500).json({ success: false, message: '获取权限模块列表失败', error: error.message }); } }; /** * 切换角色状态 * @param {Object} req - 请求对象 * @param {Object} res - 响应对象 */ exports.toggleRoleStatus = async (req, res) => { try { const { id } = req.params; const { status } = req.body; const role = await Role.findByPk(id); if (!role) { return res.status(404).json({ success: false, message: '角色不存在' }); } // 更新状态 await role.update({ status }); res.status(200).json({ success: true, data: { id: role.id, name: role.name, status: role.status }, message: `角色${status ? '启用' : '禁用'}成功` }); } catch (error) { console.error('切换角色状态失败:', error); res.status(500).json({ success: false, message: '切换角色状态失败', error: error.message }); } };