feat: Improve the front-end permission access logic and sample code
parent
dd71988253
commit
a60467b01c
|
@ -1,9 +1,115 @@
|
|||
<script lang="ts" setup>
|
||||
import { Fallback } from '@vben/universal-ui';
|
||||
import type { LoginAndRegisterParams } from '@vben/universal-ui';
|
||||
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { RoleAuthority, useAccess } from '@vben/access';
|
||||
|
||||
import { Button } from 'ant-design-vue';
|
||||
|
||||
import { useAccessStore, useAppStore } from '#/store';
|
||||
|
||||
defineOptions({ name: 'AccessFrontendButtonControl' });
|
||||
|
||||
const { accessMode, hasAuthByRole } = useAccess();
|
||||
const accessStore = useAccessStore();
|
||||
const appStore = useAppStore();
|
||||
const router = useRouter();
|
||||
|
||||
function roleButtonType(role: string) {
|
||||
return accessStore.userRoles.includes(role) ? 'primary' : 'default';
|
||||
}
|
||||
|
||||
async function changeAccount(role: string) {
|
||||
if (accessStore.userRoles.includes(role)) {
|
||||
return;
|
||||
}
|
||||
const accounts: Record<string, LoginAndRegisterParams> = {
|
||||
admin: {
|
||||
password: '123456',
|
||||
username: 'admin',
|
||||
},
|
||||
super: {
|
||||
password: '123456',
|
||||
username: 'vben',
|
||||
},
|
||||
user: {
|
||||
password: '123456',
|
||||
username: 'jack',
|
||||
},
|
||||
};
|
||||
const account = accounts[role];
|
||||
await appStore.resetAppState();
|
||||
await accessStore.authLogin(account, async () => {
|
||||
router.go(0);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Fallback status="comming-soon" />
|
||||
<div class="p-5">
|
||||
<div class="card-box p-5">
|
||||
<h1 class="text-xl font-semibold">前端按钮访问权限演示</h1>
|
||||
<div class="text-foreground/80 mt-2">
|
||||
切换不同的账号,观察按钮显示变化
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-if="accessMode === 'frontend'">
|
||||
<div class="card-box mt-5 p-5 font-semibold">
|
||||
<div class="mb-3">
|
||||
<span class="text-lg">当前账号:</span>
|
||||
<span class="text-primary mx-4">
|
||||
{{ accessStore.userRoles }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Button :type="roleButtonType('super')" @click="changeAccount('super')">
|
||||
切换为 Super 账号
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
:type="roleButtonType('admin')"
|
||||
class="mx-4"
|
||||
@click="changeAccount('admin')"
|
||||
>
|
||||
切换为 Admin 账号
|
||||
</Button>
|
||||
<Button :type="roleButtonType('user')" @click="changeAccount('user')">
|
||||
切换为 User 账号
|
||||
</Button>
|
||||
</div>
|
||||
<div class="card-box mt-5 p-5 font-semibold">
|
||||
<div class="mb-3 text-lg">组件形式控制</div>
|
||||
<RoleAuthority :roles="['super']">
|
||||
<Button class="mr-4"> Super 角色可见 </Button>
|
||||
</RoleAuthority>
|
||||
<RoleAuthority :roles="['admin']">
|
||||
<Button class="mr-4"> Admin 角色可见 </Button>
|
||||
</RoleAuthority>
|
||||
<RoleAuthority :roles="['user']">
|
||||
<Button class="mr-4"> User 角色可见 </Button>
|
||||
</RoleAuthority>
|
||||
<RoleAuthority :roles="['super', 'admin']">
|
||||
<Button class="mr-4"> Super 和 Admin 角色都可见 </Button>
|
||||
</RoleAuthority>
|
||||
</div>
|
||||
|
||||
<div class="card-box mt-5 p-5 font-semibold">
|
||||
<div class="mb-3 text-lg">函数形式控制</div>
|
||||
<Button v-if="hasAuthByRole(['super'])" class="mr-4">
|
||||
Super 角色可见
|
||||
</Button>
|
||||
<Button v-if="hasAuthByRole(['admin'])" class="mr-4">
|
||||
Admin 角色可见
|
||||
</Button>
|
||||
<Button v-if="hasAuthByRole(['user'])" class="mr-4">
|
||||
User 角色可见
|
||||
</Button>
|
||||
<Button v-if="hasAuthByRole(['super', 'admin'])" class="mr-4">
|
||||
Super 和 Admin 角色都可见
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -49,7 +49,7 @@ async function changeAccount(role: string) {
|
|||
<template>
|
||||
<div class="p-5">
|
||||
<div class="card-box p-5">
|
||||
<h1 class="text-xl font-semibold">前端页面访问演示</h1>
|
||||
<h1 class="text-xl font-semibold">前端页面访问权限演示</h1>
|
||||
<div class="text-foreground/80 mt-2">
|
||||
切换不同的账号,观察左侧菜单变化。
|
||||
</div>
|
||||
|
@ -57,14 +57,14 @@ async function changeAccount(role: string) {
|
|||
|
||||
<template v-if="accessMode === 'frontend'">
|
||||
<div class="card-box mt-5 p-5 font-semibold">
|
||||
当前权限模式:
|
||||
<span class="text-lg">当前权限模式:</span>
|
||||
<span class="text-primary mx-4">{{ accessMode }}</span>
|
||||
<Button type="primary">切换权限模式</Button>
|
||||
</div>
|
||||
|
||||
<div class="card-box mt-5 p-5 font-semibold">
|
||||
<div class="mb-3">
|
||||
当前账号:
|
||||
<span class="text-lg">当前账号:</span>
|
||||
<span class="text-primary mx-4">
|
||||
{{ accessStore.userRoles }}
|
||||
</span>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
Access control component for fine-grained access control.
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import { useAccess } from './use-access';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Specified codes is visible
|
||||
* @default []
|
||||
*/
|
||||
codes?: string[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'CodeAuthority',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
codes: () => [],
|
||||
});
|
||||
|
||||
const { hasAuthByRole } = useAccess();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<slot v-if="!codes"></slot>
|
||||
<slot v-else-if="hasAuthByRole(codes)"></slot>
|
||||
</template>
|
|
@ -1,3 +1,4 @@
|
|||
export { default as CodeAuthority } from './code-authority.vue';
|
||||
export * from './generate-menu-and-routes';
|
||||
export { default as RoleAuthority } from './role-authority.vue';
|
||||
export type * from './types';
|
||||
|
|
|
@ -2,25 +2,28 @@
|
|||
Access control component for fine-grained access control.
|
||||
-->
|
||||
<script lang="ts" setup>
|
||||
import { useAccess } from './use-access';
|
||||
|
||||
interface Props {
|
||||
/**
|
||||
* Specified role is visible
|
||||
* - When the permission mode is 'frontend', the value can be a role value.
|
||||
* - When the permission mode is 'backend', the value can be a code permission value.
|
||||
* @default ''
|
||||
* @default []
|
||||
*/
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
name: 'FrontendAuthority',
|
||||
name: 'RoleAuthority',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
roles: undefined,
|
||||
});
|
||||
|
||||
const { hasAuthByRole } = useAccess();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<slot></slot>
|
||||
<slot v-if="!roles"></slot>
|
||||
<slot v-else-if="hasAuthByRole(roles)"></slot>
|
||||
</template>
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
import { computed } from 'vue';
|
||||
|
||||
import { preferences } from '@vben-core/preferences';
|
||||
import { useCoreAccessStore } from '@vben-core/stores';
|
||||
|
||||
function useAccess() {
|
||||
const coreAccessStore = useCoreAccessStore();
|
||||
const accessMode = computed(() => {
|
||||
return preferences.app.accessMode;
|
||||
});
|
||||
|
||||
return { accessMode };
|
||||
/**
|
||||
* 基于角色判断是否有权限
|
||||
* @description: Determine whether there is permission,The role is judged by the user's role
|
||||
* @param roles
|
||||
*/
|
||||
function hasAuthByRole(roles: string[]) {
|
||||
const userRoleSet = new Set(coreAccessStore.getUserRoles);
|
||||
const intersection = roles.filter((item) => userRoleSet.has(item));
|
||||
return intersection.length > 0;
|
||||
}
|
||||
|
||||
return { accessMode, hasAuthByRole };
|
||||
}
|
||||
|
||||
export { useAccess };
|
||||
|
|
Loading…
Reference in New Issue