permissions.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /**
  2. * 角色→权限映射表
  3. * 每个角色映射一组权限标识,支持通配符 '*' 和前缀通配 'prefix:*'
  4. */
  5. const ROLE_PERMISSIONS = {
  6. admin: ['*'],
  7. teacher: ['dashboard', 'service:*', 'growth:*', 'biz:*', 'assessment:*', 'messages'],
  8. nutritionist: ['dashboard', 'service:family', 'health:*', 'diet:*', 'assessment:dan', 'energy'],
  9. article_manager: ['dashboard', 'articles:*'],
  10. activity_manager: ['dashboard', 'activity:*'],
  11. supplier_admin: ['dashboard', 'commerce:*', 'supply:*', 'system:config'],
  12. }
  13. /**
  14. * 获取用户有效权限列表
  15. * @param {string[]} roles - 用户拥有的角色列表
  16. * @returns {string[]} - 去重后的权限标识列表
  17. */
  18. export function getEffectivePermissions(roles) {
  19. if (!roles || roles.length === 0) return []
  20. const permSet = new Set()
  21. for (const role of roles) {
  22. const perms = ROLE_PERMISSIONS[role]
  23. if (perms) {
  24. for (const p of perms) {
  25. permSet.add(p)
  26. }
  27. }
  28. }
  29. return Array.from(permSet)
  30. }
  31. /**
  32. * 判断是否拥有指定权限
  33. * @param {string[]} userPerms - 用户的有效权限列表
  34. * @param {string} required - 需要的权限标识(支持 'prefix:*' 通配匹配)
  35. * @returns {boolean}
  36. *
  37. * 匹配规则:
  38. * - 如果 userPerms 包含 '*' → 返回 true
  39. * - 如果 required 是 'prefix:sub' 且 userPerms 包含 'prefix:*' → 返回 true
  40. * - 如果 required 是 'prefix'(无冒号)且 userPerms 包含 'prefix:*' → 返回 true(组级权限)
  41. * - 如果 userPerms 包含 required → 返回 true
  42. * - 否则返回 false
  43. */
  44. export function hasPermission(userPerms, required) {
  45. if (!userPerms || !required) return false
  46. if (userPerms.includes('*')) return true
  47. // 精确匹配
  48. if (userPerms.includes(required)) return true
  49. // 如果 required 不含冒号(组级权限如 'health', 'audit'),
  50. // 检查 userPerms 中是否有 'required:*' 前缀通配
  51. var colonIndex = required.indexOf(':')
  52. if (colonIndex < 0) {
  53. var groupWildcard = required + ':*'
  54. if (userPerms.includes(groupWildcard)) return true
  55. // 也检查是否有任何以 'required:' 开头的权限
  56. for (var i = 0; i < userPerms.length; i++) {
  57. if (userPerms[i].indexOf(required + ':') === 0) return true
  58. }
  59. } else {
  60. // 前缀通配匹配: required = 'articles:manage', 检查 'articles:*' 是否在 userPerms 中
  61. var prefix = required.substring(0, colonIndex) + ':*'
  62. if (userPerms.includes(prefix)) return true
  63. }
  64. return false
  65. }
  66. /**
  67. * 获取角色中文名
  68. */
  69. export function getRoleLabel(role) {
  70. const labels = {
  71. admin: '管理员',
  72. teacher: '成长规划师',
  73. nutritionist: '营养师',
  74. article_manager: '文章管理员',
  75. activity_manager: '活动管理员',
  76. supplier_admin: '供应商管理员',
  77. }
  78. return labels[role] || role
  79. }