import type { App, DirectiveBinding } from "vue"; import { useAuthStore } from "@/stores/auth"; /** * 权限指令配置 */ interface PermissionDirectiveValue { // 权限码或权限码数组 permission: string | string[]; // 是否隐藏元素(默认 false,即禁用) hide?: boolean; // 是否需要所有权限(默认 false,即任一权限即可) all?: boolean; } /** * 检查权限 */ function checkPermission( value: string | string[] | PermissionDirectiveValue, all: boolean = false ): boolean { // 在指令中,我们需要通过 getCurrentInstance 获取 store // 但更好的方式是直接导入 store,因为 Pinia store 是全局的 const authStore = useAuthStore(); // 如果值是字符串或数组,直接检查权限 if (typeof value === "string") { return authStore.hasPermission(value); } if (Array.isArray(value)) { return all ? value.every((perm) => authStore.hasPermission(perm)) : authStore.hasAnyPermission(value); } // 如果是对象配置 if (typeof value === "object" && value !== null) { const { permission, all: needAll = false } = value as PermissionDirectiveValue; if (typeof permission === "string") { return authStore.hasPermission(permission); } if (Array.isArray(permission)) { return needAll ? permission.every((perm) => authStore.hasPermission(perm)) : authStore.hasAnyPermission(permission); } } return false; } /** * 处理元素权限 */ function handlePermission( el: HTMLElement, binding: DirectiveBinding ) { const { value, modifiers } = binding; // 如果没有值,默认允许 if (!value) { return; } // 检查是否需要所有权限 const needAll = modifiers.all || false; // 解析配置 let config: PermissionDirectiveValue; if (typeof value === "string" || Array.isArray(value)) { config = { permission: value, hide: modifiers.hide || false, all: needAll, }; } else { config = { permission: value.permission, hide: value.hide ?? modifiers.hide ?? false, all: value.all ?? needAll, }; } const hasPermission = checkPermission(config.permission, config.all); if (config.hide) { // 隐藏元素 if (hasPermission) { el.style.display = ""; el.removeAttribute("data-permission-hidden"); } else { el.style.display = "none"; el.setAttribute("data-permission-hidden", "true"); } } else { // 禁用元素(默认行为) if (hasPermission) { // 恢复元素状态 if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement) { el.disabled = false; el.classList.remove("permission-disabled"); } else { el.style.pointerEvents = ""; el.style.opacity = ""; el.classList.remove("permission-disabled"); } el.removeAttribute("data-permission-disabled"); } else { // 禁用元素 if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement) { el.disabled = true; el.classList.add("permission-disabled"); } else { el.style.pointerEvents = "none"; el.style.opacity = "0.6"; el.classList.add("permission-disabled"); } el.setAttribute("data-permission-disabled", "true"); } } } /** * 权限指令 */ const permissionDirective = { mounted(el: HTMLElement, binding: DirectiveBinding) { handlePermission(el, binding); }, updated(el: HTMLElement, binding: DirectiveBinding) { handlePermission(el, binding); }, }; /** * 注册权限指令 */ export function setupPermissionDirective(app: App) { app.directive("permission", permissionDirective); } export default permissionDirective;