feat: 按钮权限自定义指令
This commit is contained in:
parent
0025244927
commit
d3ff41aa8b
@ -1,7 +1,8 @@
|
|||||||
import { App } from "vue";
|
import { App } from "vue";
|
||||||
import antiShake from "@/directives/modules/anti-shake";
|
import antiShake from "@/directives/modules/global/anti-shake";
|
||||||
import throttle from "@/directives/modules/throttle";
|
import throttle from "@/directives/modules/global/throttle";
|
||||||
import custom from "@/directives/modules/custom";
|
import custom from "@/directives/modules/global/custom";
|
||||||
|
import hasPerm from "@/directives/modules/permission/has-perm";
|
||||||
|
|
||||||
// 定义安装函数
|
// 定义安装函数
|
||||||
// install 函数是一个对象中的方法,其作用是将一系列指令对象安装到 Vue 应用实例中,它自带两个参数:app 和 options
|
// install 函数是一个对象中的方法,其作用是将一系列指令对象安装到 Vue 应用实例中,它自带两个参数:app 和 options
|
||||||
@ -13,6 +14,7 @@ const directives = {
|
|||||||
app.directive("antiShake", antiShake);
|
app.directive("antiShake", antiShake);
|
||||||
app.directive("throttle", throttle);
|
app.directive("throttle", throttle);
|
||||||
app.directive("custom", custom);
|
app.directive("custom", custom);
|
||||||
|
app.directive("hasPerm", hasPerm);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
57
src/directives/modules/permission/has-perm.ts
Normal file
57
src/directives/modules/permission/has-perm.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { Directive } from "vue";
|
||||||
|
import { useUserInfoStore } from "@/store/modules/user-info";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检测指令绑定值是否为空
|
||||||
|
* @param value 指令绑定值
|
||||||
|
* @returns {Array<string>} 指令绑定值数组
|
||||||
|
*/
|
||||||
|
const bindingValueEmpty = (value: unknown): Array<string> => {
|
||||||
|
// 处理未定义或空值情况
|
||||||
|
if (!value) throw new Error("v-permission 指令需要配置权限标识");
|
||||||
|
|
||||||
|
// 标准化为数组格式
|
||||||
|
// 如果 value 是一个数组,则直接返回该数组
|
||||||
|
// 如果 value 不是数组,则将其转换为包含单个字符串元素的数组
|
||||||
|
return Array.isArray(value) ? (value as string[]) : [String(value)];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查自定义指令权限
|
||||||
|
* @param {HTMLElement} el dom元素
|
||||||
|
* @param {unknown} bindingValue 指令绑定值
|
||||||
|
*/
|
||||||
|
const checkPermissions = (el: HTMLElement, bindingValue: unknown) => {
|
||||||
|
try {
|
||||||
|
// 检测自定义指令并转化为数组格式
|
||||||
|
const requiredPermissions = bindingValueEmpty(bindingValue);
|
||||||
|
|
||||||
|
// 超级管理员标识
|
||||||
|
const all_permission = "*:*:*";
|
||||||
|
|
||||||
|
// 获取用户权限标识-Array[string]
|
||||||
|
let { permissions } = useUserInfoStore().account;
|
||||||
|
|
||||||
|
// 如果是超级管理员则放行
|
||||||
|
if (permissions.includes(all_permission)) return;
|
||||||
|
|
||||||
|
const hasPermissions = requiredPermissions.some((perm: string) => permissions.includes(perm));
|
||||||
|
|
||||||
|
// 无权限、父节点存在时
|
||||||
|
if (!hasPermissions && el.parentNode) {
|
||||||
|
// 则删除当前子节点
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`权限指令错误: ${error}`);
|
||||||
|
// 删除当前节点
|
||||||
|
if (el.parentNode) el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const hasPerm: Directive = {
|
||||||
|
mounted: (el, binding) => checkPermissions(el, binding.value),
|
||||||
|
updated: (el, binding) => checkPermissions(el, binding.value)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default hasPerm;
|
||||||
@ -1474,7 +1474,7 @@ export const permissionData = [
|
|||||||
hide: false,
|
hide: false,
|
||||||
disable: false,
|
disable: false,
|
||||||
roles: ["admin", "common"],
|
roles: ["admin", "common"],
|
||||||
permission: "common:btn:delete",
|
permission: "common:btn:add",
|
||||||
sort: 1,
|
sort: 1,
|
||||||
type: 3
|
type: 3
|
||||||
}
|
}
|
||||||
@ -1487,7 +1487,7 @@ export const permissionData = [
|
|||||||
hide: false,
|
hide: false,
|
||||||
disable: false,
|
disable: false,
|
||||||
roles: ["admin", "common"],
|
roles: ["admin", "common"],
|
||||||
permission: "common:btn:delete",
|
permission: "common:btn:edit",
|
||||||
sort: 2,
|
sort: 2,
|
||||||
type: 3
|
type: 3
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,11 +13,33 @@
|
|||||||
<a-typography-title :heading="4"> 当前页面角色权限 </a-typography-title>
|
<a-typography-title :heading="4"> 当前页面角色权限 </a-typography-title>
|
||||||
<code-view :code-json="pageRule" style="width: 100%" />
|
<code-view :code-json="pageRule" style="width: 100%" />
|
||||||
<br />
|
<br />
|
||||||
|
<a-row :gutter="[24, 12]">
|
||||||
|
<a-col :span="24">
|
||||||
|
<code-view type="vue" :code-json="sysBtn" style="width: 100%" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary">新增</a-button>
|
<span>权限按钮:</span>
|
||||||
<a-button type="primary" status="success">编辑</a-button>
|
<a-button v-hasPerm="['sys:btn:add']" type="primary">新增</a-button>
|
||||||
<a-button type="primary" status="danger">删除</a-button>
|
<a-button v-hasPerm="['sys:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<br />
|
||||||
|
<a-row :gutter="[24, 12]">
|
||||||
|
<a-col :span="24">
|
||||||
|
<code-view type="vue" :code-json="commonBtn" style="width: 100%" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-space>
|
||||||
|
<span>权限按钮:</span>
|
||||||
|
<a-button v-hasPerm="['common:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -30,7 +52,18 @@ let userInfoStore = useUserInfoStore();
|
|||||||
let { account } = storeToRefs(userInfoStore);
|
let { account } = storeToRefs(userInfoStore);
|
||||||
const permissions = computed(() => JSON.stringify(account.value.permissions, null));
|
const permissions = computed(() => JSON.stringify(account.value.permissions, null));
|
||||||
const pageRule = computed(() => JSON.stringify(route.meta.roles, null));
|
const pageRule = computed(() => JSON.stringify(route.meta.roles, null));
|
||||||
console.log("权限数据", account.value);
|
|
||||||
|
let sysBtn = `<a-space>
|
||||||
|
<a-button v-hasPerm="['sys:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>`;
|
||||||
|
|
||||||
|
let commonBtn = `<a-space>
|
||||||
|
<a-button v-hasPerm="['common:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>`;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
@ -2,22 +2,44 @@
|
|||||||
<div class="snow-page">
|
<div class="snow-page">
|
||||||
<div class="snow-inner">
|
<div class="snow-inner">
|
||||||
<a-alert>
|
<a-alert>
|
||||||
当前页面为
|
当前页面
|
||||||
<a-tag color="green"> 超级管理员 </a-tag>
|
<a-tag color="green"> 超级管理员 </a-tag>
|
||||||
权限页面,
|
和
|
||||||
<a-tag color="orange"> 普通角色 </a-tag>
|
<a-tag color="green"> 普通角色 </a-tag>
|
||||||
无法查看
|
都可以查看
|
||||||
</a-alert>
|
</a-alert>
|
||||||
<a-typography-title :heading="4"> 当前用户权限 </a-typography-title>
|
<a-typography-title :heading="4"> 当前用户权限 </a-typography-title>
|
||||||
<code-view :code-json="userPermissions" style="width: 100%" />
|
<code-view :code-json="permissions" style="width: 100%" />
|
||||||
<a-typography-title :heading="4"> 当前页面角色权限 </a-typography-title>
|
<a-typography-title :heading="4"> 当前页面角色权限 </a-typography-title>
|
||||||
<code-view :code-json="pageRule" style="width: 100%" />
|
<code-view :code-json="pageRule" style="width: 100%" />
|
||||||
<br />
|
<br />
|
||||||
|
<a-row :gutter="[24, 12]">
|
||||||
|
<a-col :span="24">
|
||||||
|
<code-view type="vue" :code-json="sysBtn" style="width: 100%" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary">新增</a-button>
|
<span>权限按钮:</span>
|
||||||
<a-button type="primary" status="success">编辑</a-button>
|
<a-button v-hasPerm="['sys:btn:add']" type="primary">新增</a-button>
|
||||||
<a-button type="primary" status="danger">删除</a-button>
|
<a-button v-hasPerm="['sys:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<br />
|
||||||
|
<a-row :gutter="[24, 12]">
|
||||||
|
<a-col :span="24">
|
||||||
|
<code-view type="vue" :code-json="commonBtn" style="width: 100%" />
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-space>
|
||||||
|
<span>权限按钮:</span>
|
||||||
|
<a-button v-hasPerm="['common:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="'common:btn:delete'" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -28,9 +50,20 @@ import { useUserInfoStore } from "@/store/modules/user-info";
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
let userInfoStore = useUserInfoStore();
|
let userInfoStore = useUserInfoStore();
|
||||||
let { account } = storeToRefs(userInfoStore);
|
let { account } = storeToRefs(userInfoStore);
|
||||||
const userPermissions = computed(() => JSON.stringify(account.value.permissions, null));
|
const permissions = computed(() => JSON.stringify(account.value.permissions, null));
|
||||||
const pageRule = computed(() => JSON.stringify(route.meta.roles, null));
|
const pageRule = computed(() => JSON.stringify(route.meta.roles, null));
|
||||||
console.log("权限数据", account.value);
|
|
||||||
|
let sysBtn = `<a-space>
|
||||||
|
<a-button v-hasPerm="['sys:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['sys:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>`;
|
||||||
|
|
||||||
|
let commonBtn = `<a-space>
|
||||||
|
<a-button v-hasPerm="['common:btn:add']" type="primary">新增</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:edit']" type="primary" status="success">编辑</a-button>
|
||||||
|
<a-button v-hasPerm="['common:btn:delete']" type="primary" status="danger">删除</a-button>
|
||||||
|
</a-space>`;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user