/** * 角色→权限映射表 * 每个角色映射一组权限标识,支持通配符 '*' 和前缀通配 'prefix:*' */ const ROLE_PERMISSIONS = { admin: ['*'], teacher: ['dashboard', 'service:*', 'growth:*', 'biz:*', 'assessment:*', 'messages'], nutritionist: ['dashboard', 'service:family', 'health:*', 'diet:*', 'assessment:dan', 'energy'], article_manager: ['dashboard', 'articles:*'], activity_manager: ['dashboard', 'activity:*'], supplier_admin: ['dashboard', 'commerce:*', 'supply:*', 'system:config'], } /** * 获取用户有效权限列表 * @param {string[]} roles - 用户拥有的角色列表 * @returns {string[]} - 去重后的权限标识列表 */ export function getEffectivePermissions(roles) { if (!roles || roles.length === 0) return [] const permSet = new Set() for (const role of roles) { const perms = ROLE_PERMISSIONS[role] if (perms) { for (const p of perms) { permSet.add(p) } } } return Array.from(permSet) } /** * 判断是否拥有指定权限 * @param {string[]} userPerms - 用户的有效权限列表 * @param {string} required - 需要的权限标识(支持 'prefix:*' 通配匹配) * @returns {boolean} * * 匹配规则: * - 如果 userPerms 包含 '*' → 返回 true * - 如果 required 是 'prefix:sub' 且 userPerms 包含 'prefix:*' → 返回 true * - 如果 required 是 'prefix'(无冒号)且 userPerms 包含 'prefix:*' → 返回 true(组级权限) * - 如果 userPerms 包含 required → 返回 true * - 否则返回 false */ export function hasPermission(userPerms, required) { if (!userPerms || !required) return false if (userPerms.includes('*')) return true // 精确匹配 if (userPerms.includes(required)) return true // 如果 required 不含冒号(组级权限如 'health', 'audit'), // 检查 userPerms 中是否有 'required:*' 前缀通配 var colonIndex = required.indexOf(':') if (colonIndex < 0) { var groupWildcard = required + ':*' if (userPerms.includes(groupWildcard)) return true // 也检查是否有任何以 'required:' 开头的权限 for (var i = 0; i < userPerms.length; i++) { if (userPerms[i].indexOf(required + ':') === 0) return true } } else { // 前缀通配匹配: required = 'articles:manage', 检查 'articles:*' 是否在 userPerms 中 var prefix = required.substring(0, colonIndex) + ':*' if (userPerms.includes(prefix)) return true } return false } /** * 获取角色中文名 */ export function getRoleLabel(role) { const labels = { admin: '管理员', teacher: '成长规划师', nutritionist: '营养师', article_manager: '文章管理员', activity_manager: '活动管理员', supplier_admin: '供应商管理员', } return labels[role] || role }