library-picturebook-activity/lesingle-creation-frontend/src/directives/permission.ts

147 lines
3.9 KiB
TypeScript
Raw Normal View History

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<string | string[] | PermissionDirectiveValue>
) {
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;