<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                # 權限 項目中集成了三種權限處理方式: 1. 通過用戶角色來過濾菜單(前端方式控制),菜單和路由分開配置 2. 通過用戶角色來過濾菜單(前端方式控制),菜單由路由配置自動生成 3. 通過后臺來動態生成路由表(后臺方式控制) ## 前端角色權限 **實現原理:** 在前端固定寫死路由的權限,指定路由有哪些權限可以查看。只初始化通用的路由,需要權限才能訪問的路由沒有被加入路由表內。在登陸后或者其他方式獲取用戶角色后,通過角色去遍歷路由表,獲取該角色可以訪問的路由表,生成路由表,再通過 `router.addRoutes` 添加到路由實例,實現權限的過濾。 **缺點:** 權限相對不自由,如果后臺改動角色,前臺也需要跟著改動。適合角色較固定的系統 ### 實現 1. 在[項目配置](./settings.md#項目配置)將系統內權限模式改為 `ROLE` 模式 ```ts // ! 改動后需要清空瀏覽器緩存 const setting: ProjectConfig = { // 權限模式 permissionMode: PermissionModeEnum.ROLE, }; ``` 2. 在路由表配置路由所需的權限,如果不配置,默認可見(見注釋) ```ts import type { AppRouteModule } from '/@/router/types'; import { getParentLayout, LAYOUT } from '/@/router/constant'; import { RoleEnum } from '/@/enums/roleEnum'; import { t } from '/@/hooks/web/useI18n'; const permission: AppRouteModule = { path: '/permission', name: 'Permission', component: LAYOUT, redirect: '/permission/front/page', meta: { icon: 'ion:key-outline', title: t('routes.demo.permission.permission'), }, children: [ { path: 'front', name: 'PermissionFrontDemo', component: getParentLayout('PermissionFrontDemo'), meta: { title: t('routes.demo.permission.front'), }, children: [ { path: 'auth-pageA', name: 'FrontAuthPageA', component: () => import('/@/views/demo/permission/front/AuthPageA.vue'), meta: { title: t('routes.demo.permission.frontTestA'), roles: [RoleEnum.SUPER], }, }, { path: 'auth-pageB', name: 'FrontAuthPageB', component: () => import('/@/views/demo/permission/front/AuthPageB.vue'), meta: { title: t('routes.demo.permission.frontTestB'), roles: [RoleEnum.TEST], }, }, ], }, ], }; export default permission; ``` 3. 在路由鉤子內動態判斷 ```ts // 這里只列舉了主要代碼 const routes = await permissionStore.buildRoutesAction(); routes.forEach((route) => { router.addRoute(route as unknown as RouteRecordRaw); }); const redirectPath = (from.query.redirect || to.path) as string; const redirect = decodeURIComponent(redirectPath); const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }; permissionStore.setDynamicAddedRoute(true); next(nextData); ``` **permissionStore.buildRoutesAction** 用于**過濾動態路由** ```ts // 主要代碼 if (permissionMode === PermissionModeEnum.ROLE) { const routeFilter = (route: AppRouteRecordRaw) => { const { meta } = route; const { roles } = meta || {}; if (!roles) return true; return roleList.some((role) => roles.includes(role)); }; routes = filter(asyncRoutes, routeFilter); routes = routes.filter(routeFilter); // Convert multi-level routing to level 2 routing routes = flatMultiLevelRoutes(routes); } ``` ### 動態更換角色 系統提供方便角色相關操作 ```ts import { usePermission } from '/@/hooks/web/usePermission'; import { RoleEnum } from '/@/enums/roleEnum'; export default defineComponent({ setup() { const { changeRole } = usePermission(); // 更換為test角色 // 動態更改角色,傳入角色名稱,可以是數組 changeRole(RoleEnum.TEST); return {}; }, }); ``` ### 細粒度權限 **函數方式** [usePermission]還提供了按鈕級別的權限控制。 ```vue <template> <a-button v-if="hasPermission([RoleEnum.TEST, RoleEnum.SUPER])" color="error" class="mx-4"> 擁有[test,super]角色權限可見 </a-button> </template> <script lang="ts"> import { usePermission } from '/@/hooks/web/usePermission'; import { RoleEnum } from '/@/enums/roleEnum'; export default defineComponent({ setup() { const { hasPermission } = usePermission(); return { hasPermission }; }, }); </script> ``` **組件方式** 具體查看[權限組件使用](../components/auth.md) **指令方式** ::: tip 指令方式不能動態更改權限 ::: ```html <a-button v-auth="RoleEnum.SUPER" type="primary" class="mx-4"> 擁有super角色權限可見</a-button> ``` ## 后臺動態獲取 **實現原理:** 是通過接口動態生成路由表,且遵循一定的數據結構返回。前端根據需要處理該數據為可識別的結構,再通過 `router.addRoutes` 添加到路由實例,實現權限的動態生成。 ### 實現 1. 在[項目配置](./settings.md#項目配置)將系統內權限模式改為 `BACK` 模式 ```ts // ! 改動后需要清空瀏覽器緩存 const setting: ProjectConfig = { // 權限模式 permissionMode: PermissionModeEnum.BACK, }; ``` 2. 路由攔截,與角色權限模式一致 **permissionStore.buildRoutesAction** 用于**過濾動態路由** ```ts // 主要代碼 if (permissionMode === PermissionModeEnum.BACK) { const { createMessage } = useMessage(); createMessage.loading({ content: t('sys.app.menuLoading'), duration: 1, }); // !Simulate to obtain permission codes from the background, // this function may only need to be executed once, and the actual project can be put at the right time by itself let routeList: AppRouteRecordRaw[] = []; try { this.changePermissionCode(); routeList = (await getMenuList()) as AppRouteRecordRaw[]; } catch (error) { console.error(error); } // Dynamically introduce components routeList = transformObjToRoute(routeList); // Background routing to menu structure const backMenuList = transformRouteToMenu(routeList); this.setBackMenuList(backMenuList); routeList = flatMultiLevelRoutes(routeList); routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; } ``` **getMenuList 返回值格式** 返回值由多個路由模塊組成 ::: warning 注意 后端接口返回的數據中必須包含`PageEnum.BASE_HOME`指定的路由(path定義于`src/enums/pageEnum.ts`) ::: ```ts [ { path: '/dashboard', name: 'Dashboard', component: '/dashboard/welcome/index', meta: { title: 'routes.dashboard.welcome', affix: true, icon: 'ant-design:home-outlined', }, }, { path: '/permission', name: 'Permission', component: 'LAYOUT', redirect: '/permission/front/page', meta: { icon: 'carbon:user-role', title: 'routes.demo.permission.permission', }, children: [ { path: 'back', name: 'PermissionBackDemo', meta: { title: 'routes.demo.permission.back', }, children: [ { path: 'page', name: 'BackAuthPage', component: '/demo/permission/back/index', meta: { title: 'routes.demo.permission.backPage', }, }, { path: 'btn', name: 'BackAuthBtn', component: '/demo/permission/back/Btn', meta: { title: 'routes.demo.permission.backBtn', }, }, ], }, ], }, ]; ``` ### 動態更換菜單 ```ts import { usePermission } from '/@/hooks/web/usePermission'; import { RoleEnum } from '/@/enums/roleEnum'; export default defineComponent({ setup() { const { changeMenu } = usePermission(); // 更改菜單的實現需要自行去修改 changeMenu(); return {}; }, }); ``` ### 細粒度權限 **函數方式** ```vue <template> <a-button v-if="hasPermission(['20000', '2000010'])" color="error" class="mx-4"> 擁有[20000,2000010]code可見 </a-button> </template> <script lang="ts"> import { usePermission } from '/@/hooks/web/usePermission'; import { RoleEnum } from '/@/enums/roleEnum'; export default defineComponent({ setup() { const { hasPermission } = usePermission(); return { hasPermission }; }, }); </script> ``` **組件方式** 具體查看[權限組件使用](../components/auth.md) **指令方式** ::: tip 指令方式不能動態更改權限 ::: ```html <a-button v-auth="'1000'" type="primary" class="mx-4"> 擁有code ['1000']權限可見 </a-button> ``` ### 組件禁用控制 ~~~ const {disabled} = usePermission(); <a-checkbox :disabled="disabled('權限code)">{{ item.ruleName }}</a-checkbox> dynamicDisabled: ({ values }) => { return !disabled('user:add'); }, ~~~ ### 如何初始化 code 通常,如需做按鈕級別權限,后臺會提供相應的 code,或者類型的判斷標識。這些編碼只需要在登錄后獲取一次即可。 ```ts import { getPermCodeByUserId } from '/@/api/sys/user'; import { permissionStore } from '/@/store/modules/permission'; async function changePermissionCode(userId: string) { // 從后臺獲取當前用戶擁有的編碼 const codeList = await getPermCodeByUserId({ userId }); permissionStore.commitPermCodeListState(codeList); } ``` ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看