diff --git a/src/directives/index.ts b/src/directives/index.ts new file mode 100644 index 0000000..11b1da8 --- /dev/null +++ b/src/directives/index.ts @@ -0,0 +1,10 @@ +import type { App } from 'vue' +import { setupPermissionDirective } from './permission/hasPermi' + +/** + * 导出指令:v-xxx + * @methods hasPermi 按钮权限,用法: v-hasPermi + */ +export const setupPermission = (app: App) => { + setupPermissionDirective(app) +} diff --git a/src/directives/permission/hasPermi.ts b/src/directives/permission/hasPermi.ts new file mode 100644 index 0000000..81f5022 --- /dev/null +++ b/src/directives/permission/hasPermi.ts @@ -0,0 +1,46 @@ +import type { App, Directive, DirectiveBinding } from 'vue' +import { useI18n } from '@/hooks/web/useI18n' +import { useCache } from '@/hooks/web/useCache' +import { intersection } from 'lodash-es' +import { isArray } from '@/utils/is' + +const { t } = useI18n() +const { wsCache } = useCache() +// 全部权限 +const all_permission = '*:*:*' +const permissions = wsCache.get('userInfo').permissions + +function hasPermi(el: Element, binding: DirectiveBinding) { + const value = binding.value + + const hasPermission = (value: string | string[]): boolean => { + if (all_permission === permissions) return true + + if (!value) return true + + if (!isArray(value)) { + return permissions?.includes(value as string) + } + return (intersection(value, permissions) as string[]).length > 0 + } + + if (!hasPermission(value)) { + el.parentNode?.removeChild(el) + } else { + el.parentNode && el.parentNode.removeChild(el) + throw new Error(t('permission.hasPermission')) + } +} +const mounted = (el: Element, binding: DirectiveBinding) => { + hasPermi(el, binding) +} + +const permiDirective: Directive = { + mounted +} + +export function setupPermissionDirective(app: App) { + app.directive('hasPermi', permiDirective) +} + +export default permiDirective diff --git a/src/locales/en.ts b/src/locales/en.ts index a7d64c9..24597ea 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -143,6 +143,9 @@ export default { inputPassword: 'InputPassword', sticky: 'Sticky' }, + permission: { + hasPermission: 'Please set the operation permission value' + }, analysis: { newUser: 'New user', unreadInformation: 'Unread information', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 817facc..51abe94 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -143,6 +143,9 @@ export default { inputPassword: '密码输入框', sticky: '黏性' }, + permission: { + hasPermission: '请设置操作权限值' + }, analysis: { newUser: '新增用户', unreadInformation: '未读消息', diff --git a/src/main.ts b/src/main.ts index 4a71197..f6bfd39 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,6 +25,9 @@ import '@/plugins/animate.css' // 路由 import { setupRouter } from './router' +// 权限 +import { setupPermission } from './directives' + import { createApp } from 'vue' import App from './App.vue' @@ -44,6 +47,8 @@ const setupAll = async () => { setupRouter(app) + setupPermission(app) + app.mount('#app') } diff --git a/src/views/Example/Dialog/ExampleDialog.vue b/src/views/Example/Dialog/ExampleDialog.vue index c2b23d5..e3f5e40 100644 --- a/src/views/Example/Dialog/ExampleDialog.vue +++ b/src/views/Example/Dialog/ExampleDialog.vue @@ -237,7 +237,7 @@ const save = async () => { {{ t('exampleDemo.detail') }} - + {{ t('exampleDemo.del') }}