Explorar el Código

feat: 添加按钮权限

xiaoxian521 hace 3 años
padre
commit
ad1de9530a

+ 42 - 5
mock/asyncRoutes.ts

@@ -5,7 +5,6 @@ import { MockMethod } from "vite-plugin-mock";
 const systemRouter = {
   path: "/system",
   name: "system",
-  // component: Layout,
   redirect: "/system/user",
   meta: {
     icon: "el-icon-setting",
@@ -18,7 +17,6 @@ const systemRouter = {
     {
       path: "/system/user",
       name: "user",
-      // component: () => import("/@/views/system/user/index.vue"),
       meta: {
         title: "message.hsBaseinfo",
         showLink: true,
@@ -28,7 +26,6 @@ const systemRouter = {
     {
       path: "/system/dict",
       name: "dict",
-      // component: () => import("/@/views/system/dict/index.vue"),
       meta: {
         title: "message.hsDict",
         showLink: true,
@@ -38,6 +35,46 @@ const systemRouter = {
   ],
 };
 
+const permissionRouter = {
+  path: "/permission",
+  name: "permission",
+  redirect: "/permission/page",
+  meta: {
+    title: "message.permission",
+    icon: "el-icon-lollipop",
+    showLink: true,
+    savedPosition: true,
+    rank: 3,
+  },
+  children: [
+    {
+      path: "/permission/page",
+      name: "permissionPage",
+      meta: {
+        title: "message.permissionPage",
+        showLink: true,
+        savedPosition: true,
+      },
+    },
+    {
+      path: "/permission/button",
+      name: "permissionButton",
+      meta: {
+        title: "message.permissionButton",
+        showLink: true,
+        savedPosition: true,
+        authority: [],
+      },
+    },
+  ],
+};
+
+// 添加不同按钮权限到/permission/button页面中
+function setDifAuthority(authority, routes) {
+  routes.children[1].meta.authority = [authority];
+  return routes;
+}
+
 export default [
   {
     url: "/getAsyncRoutes",
@@ -46,12 +83,12 @@ export default [
       if (query.name === "admin") {
         return {
           code: 0,
-          info: systemRouter,
+          info: [systemRouter, setDifAuthority("v-admin", permissionRouter)],
         };
       } else {
         return {
           code: 0,
-          info: [],
+          info: [setDifAuthority("v-test", permissionRouter)],
         };
       }
     },

+ 1 - 0
src/directives/index.ts

@@ -0,0 +1 @@
+export * from "./permission";

+ 17 - 0
src/directives/permission/index.ts

@@ -0,0 +1,17 @@
+import { usePermissionStoreHook } from "/@/store/modules/permission";
+import { Directive } from "vue";
+
+export const auth: Directive = {
+  mounted(el, binding) {
+    const { value } = binding;
+    if (value) {
+      const authRoles = value;
+      const hasAuth = usePermissionStoreHook().buttonAuth.includes(authRoles);
+      if (!hasAuth) {
+        el.style.display = "none";
+      }
+    } else {
+      throw new Error("need roles! Like v-auth=\"['admin','test']\"");
+    }
+  },
+};

+ 12 - 2
src/main.ts

@@ -1,4 +1,4 @@
-import { createApp } from "vue";
+import { createApp, Directive } from "vue";
 import App from "./App.vue";
 import router from "./router";
 import { setupStore } from "/@/store";
@@ -43,6 +43,12 @@ app.use(Storage, {
   },
 });
 
+// 自定义指令
+import * as directives from "/@/directives";
+Object.keys(directives).forEach((key) => {
+  app.directive(key, (directives as { [key: string]: Directive })[key]);
+});
+
 // 获取项目动态全局配置
 export const getServerConfig = async (): Promise<any> => {
   return axios({
@@ -74,7 +80,11 @@ export const getServerConfig = async (): Promise<any> => {
 getServerConfig().then(async () => {
   setupStore(app);
 
-  app.use(router).use(useElementPlus).use(useTable).use(usI18n);
+  app
+    .use(router)
+    .use(useElementPlus)
+    .use(useTable)
+    .use(usI18n);
 
   await router.isReady();
 

+ 4 - 0
src/plugins/element-plus/index.ts

@@ -29,6 +29,8 @@ import {
   ElDrawer,
   ElPagination,
   ElAlert,
+  ElRadioButton,
+  ElRadioGroup,
 } from "element-plus";
 import "element-plus/packages/theme-chalk/src/base.scss";
 
@@ -61,6 +63,8 @@ const components = [
   ElDrawer,
   ElPagination,
   ElAlert,
+  ElRadioButton,
+  ElRadioGroup,
 ];
 
 const plugins = [ElLoading];

+ 6 - 7
src/router/index.ts

@@ -6,7 +6,6 @@ import editorRouter from "./modules/editor";
 import componentsRouter from "./modules/components";
 import nestedRouter from "./modules/nested";
 import errorRouter from "./modules/error";
-import permissionRouter from "./modules/permission";
 import externalLink from "./modules/externalLink";
 import remainingRouter from "./modules/remaining"; //静态路由
 
@@ -26,7 +25,6 @@ const constantRoutes: Array<any> = [
   editorRouter,
   componentsRouter,
   nestedRouter,
-  permissionRouter,
   externalLink,
   errorRouter,
 ];
@@ -83,7 +81,7 @@ export const initRouter = (name, next?, to?) => {
       if (info.length === 0) {
         usePermissionStoreHook().changeSetting(info);
       } else {
-        addAsyncRoutes([info]).map((v: any) => {
+        addAsyncRoutes(info).map((v: any) => {
           // 防止重复添加路由
           if (
             router.options.routes.findIndex(
@@ -99,8 +97,8 @@ export const initRouter = (name, next?, to?) => {
             router.addRoute(v.name, v);
             if (next && to) next({ ...to, replace: true });
             usePermissionStoreHook().changeSetting(info);
-            resolve(router);
           }
+          resolve(router);
         });
       }
       router.addRoute({
@@ -135,9 +133,10 @@ router.beforeEach((to, _from, next) => {
     if (_from?.name) {
       next();
     } else {
-      initRouter(name.username, next, to).then((router: Router) => {
-        router.push(to.path);
-      });
+      if (usePermissionStoreHook().wholeRoutes.length === 0)
+        initRouter(name.username, next, to).then((router: Router) => {
+          router.push(to.path);
+        });
       next();
     }
   } else {

+ 0 - 39
src/router/modules/permission.ts

@@ -1,39 +0,0 @@
-import Layout from "/@/layout/index.vue";
-
-const permissionRouter = {
-  path: "/permission",
-  component: Layout,
-  redirect: "/permission/page",
-  name: "permission",
-  meta: {
-    title: "message.permission",
-    icon: "el-icon-lollipop",
-    showLink: true,
-    savedPosition: false,
-    rank: 3,
-  },
-  children: [
-    {
-      path: "/permission/page",
-      component: () => import("/@/views/permission/page.vue"),
-      name: "permissionPage",
-      meta: {
-        title: "message.permissionPage",
-        showLink: true,
-        savedPosition: false,
-      },
-    },
-    {
-      path: "/permission/button",
-      component: () => import("/@/views/permission/button.vue"),
-      name: "permissionButton",
-      meta: {
-        title: "message.permissionButton",
-        showLink: true,
-        savedPosition: false,
-      },
-    },
-  ],
-};
-
-export default permissionRouter;

+ 16 - 0
src/store/modules/permission.ts

@@ -8,12 +8,28 @@ export const usePermissionStore = defineStore({
   state: () => ({
     constantRoutes: constantRoutesArr, //静态路由
     wholeRoutes: [],
+    buttonAuth: [],
   }),
   actions: {
     asyncActionRoutes(routes) {
+      if (this.wholeRoutes.length > 0) return;
       this.wholeRoutes = ascending(this.constantRoutes.concat(routes)).filter(
         (v) => v.meta.showLink
       );
+
+      const getButtonAuth = (arrRoutes: Array<string>) => {
+        if (!arrRoutes || !arrRoutes.length) return;
+        arrRoutes.forEach((v: any) => {
+          if (v.meta && v.meta.authority) {
+            this.buttonAuth.push(...v.meta.authority);
+          }
+          if (v.children) {
+            getButtonAuth(v.children);
+          }
+        });
+      };
+
+      getButtonAuth(this.wholeRoutes);
     },
     async changeSetting(routes) {
       await this.asyncActionRoutes(routes);

+ 0 - 15
src/views/permission/button.vue

@@ -1,15 +0,0 @@
-<template>
-  <div>button</div>
-</template>
-
-<script lang='ts'>
-export default {
-  name: "permissionButton",
-  setup() {
-    return {};
-  }
-};
-</script>
-
-<style scoped>
-</style>

+ 38 - 0
src/views/permission/button/index.vue

@@ -0,0 +1,38 @@
+<template>
+  <div class="app-container">
+    <el-radio-group v-model="auth" @change="changRole">
+      <el-radio-button label="admin"></el-radio-button>
+      <el-radio-button label="test"></el-radio-button>
+    </el-radio-group>
+    <p v-auth="'v-admin'">只有admin可看</p>
+    <p v-auth="'v-test'">只有test可看</p>
+  </div>
+</template>
+
+<script lang='ts'>
+import { ref, unref } from "vue";
+import { storageSession } from "/@/utils/storage";
+export default {
+  name: "permissionButton",
+  setup() {
+    const auth = ref(storageSession.getItem("info").username || "admin");
+
+    function changRole(value) {
+      storageSession.setItem("info", {
+        username: value,
+        accessToken: `eyJhbGciOiJIUzUxMiJ9.${value}`
+      });
+
+      window.location.reload();
+    }
+
+    return {
+      auth,
+      changRole
+    };
+  }
+};
+</script>
+
+<style scoped>
+</style>

+ 1 - 4
src/views/permission/page.vue → src/views/permission/page/index.vue

@@ -27,7 +27,7 @@ export default {
       } else {
         storageSession.setItem("info", {
           username: "admin",
-          accessToken: "eyJhbGciOiJIUzUxMiJ9.test"
+          accessToken: "eyJhbGciOiJIUzUxMiJ9.admin"
         });
         window.location.reload();
       }
@@ -40,6 +40,3 @@ export default {
   }
 };
 </script>
-
-<style scoped>
-</style>