library-picturebook-activity/lesingle-creation-frontend/src/directives/permission.ts
En 98e9ad1d28 feat(前端): 测试环境登录框支持自动填充测试账号
通过 VITE_AUTO_FILL_TEST 环境变量控制,在 .env.test 中启用,
使测试环境构建后登录框也能自动填充测试账号,方便测试人员使用。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 17:03:22 +08:00

147 lines
3.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;