zhou zhou
7 小时以前 e9283ffe6822b12ec5dd2ccf4dc13a369b227a61
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { useRoute } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useUserStore } from '@/store/modules/user'
import { useAppMode } from '@/hooks/core/useAppMode'
 
function extractRouteAuthMarks(authList) {
  if (!Array.isArray(authList)) {
    return []
  }
 
  return authList
    .map((item) => {
      if (typeof item === 'string') {
        return item
      }
      if (item && typeof item === 'object') {
        return item.authMark || ''
      }
      return ''
    })
    .filter(Boolean)
}
 
function extractUserButtons(info) {
  return Array.isArray(info?.buttons) ? info.buttons : []
}
 
const BUTTON_ACTION_MAP = {
  query: 'list',
  add: 'save',
  edit: 'update',
  delete: 'remove'
}
 
function resolveRouteResourceKey(routePath) {
  const pathSegments = String(routePath || '')
    .split('/')
    .filter(Boolean)
 
  const rawSegment = pathSegments[pathSegments.length - 1]
  if (!rawSegment) {
    return ''
  }
 
  return rawSegment.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
}
 
function matchesBackendButton(requiredAuth, buttons, routePath) {
  if (buttons.includes(requiredAuth)) {
    return true
  }
 
  const action = BUTTON_ACTION_MAP[requiredAuth]
  const resourceKey = resolveRouteResourceKey(routePath)
  if (!action || !resourceKey) {
    return false
  }
 
  return buttons.some(
    (item) =>
      typeof item === 'string' && item.includes(`:${resourceKey}:`) && item.endsWith(`:${action}`)
  )
}
 
function hasAuthPermission(
  requiredAuth,
  { authList = [], buttons = [], isBackendMode = false, routePath = '' } = {}
) {
  const requiredList = Array.isArray(requiredAuth) ? requiredAuth : [requiredAuth]
 
  if (!requiredList.length) {
    return true
  }
 
  if (isBackendMode) {
    return requiredList.some((item) => matchesBackendButton(item, buttons, routePath))
  }
 
  return requiredList.some((item) => authList.includes(item))
}
 
const useAuth = () => {
  const userStore = useUserStore()
  const route = useRoute()
  const { isBackendMode } = useAppMode()
  const { info } = storeToRefs(userStore)
  const authList = computed(() => extractRouteAuthMarks(route.meta.authList))
  const buttons = computed(() => extractUserButtons(info.value))
  const hasAuth = (auth) => {
    return hasAuthPermission(auth, {
      authList: authList.value,
      buttons: buttons.value,
      isBackendMode: isBackendMode.value,
      routePath: route.path
    })
  }
  return {
    hasAuth
  }
}
export {
  extractRouteAuthMarks,
  extractUserButtons,
  hasAuthPermission,
  resolveRouteResourceKey,
  useAuth
}