// middleware/permissions.js —— RBAC 权限检查 + 数据范围过滤 /** * 检查当前用户是否拥有指定权限 * @param {string} resource - 资源名,如 'customer' * @param {string} action - 操作名,如 'read' */ function checkPermission(resource, action) { return (req, res, next) => { const permName = `${resource}:${action}` if (!req.user || !req.user.permissions || !req.user.permissions.includes(permName)) { return res.status(403).json({ code: 403, message: '权限不足' }) } next() } } /** * 根据当前用户角色,返回该资源的数据范围过滤条件 * @param {object} user - req.user(含 roleName, id, department) * @param {string} resource - 资源名:customers / contracts / after_sales / products / suppliers / employees / users * @returns {{ where?: string, values?: any[], deny?: boolean }} * - where + values:追加到 SQL WHERE 子句的条件 * - deny:true 表示该角色无权访问此资源 */ function getDataScope(user, resource) { const { roleName, id: userId, department } = user // admin 和 general_manager(总经理):全量数据,无限制 if (roleName === 'admin' || roleName === 'general_manager') { return {} } switch (resource) { case 'customers': if (roleName === 'finance') return {} return { where: 'responsible_user_id = ?', values: [userId] } case 'contracts': if (roleName === 'finance') return {} if (roleName === 'procurement_manager') { return { where: 'c.type = ?', values: ['supply'] } } if (roleName === 'franchise_manager' || roleName === 'operations_manager') { return { where: 'c.responsible_user_id = ? AND c.type = ?', values: [userId, 'franchise'] } } return {} case 'after_sales': if (roleName === 'finance') return {} if (roleName === 'operations_manager') { return { where: 'responsible_user_id = ?', values: [userId], tableAlias: 'a' } } // franchise_manager 和 procurement_manager 无权限(checkPermission 已拦截) return {} case 'employees': if (roleName === 'finance') return {} // 所有非管理员/总经理角色:只能看自己部门的员工 return { where: 'department = ?', values: [department] } case 'products': case 'suppliers': case 'users': // 无数据范围过滤,仅靠 checkPermission 控制访问 return {} default: return {} } } module.exports = { checkPermission, getDataScope }