Files
backmanager-server/middleware/permissions.js
2026-06-24 22:44:14 +08:00

74 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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 子句的条件
* - denytrue 表示该角色无权访问此资源
*/
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 }