From ba443b4a39ae7f694dbf055e16a38c794020b49e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=98chen=2Ehome=E2=80=99?= <1147347984@qq.com>
Date: Sun, 14 Aug 2022 00:23:42 +0800
Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E4=BE=A7=E8=BE=B9=E6=A0=8F?=
 =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=A0=B9=E6=8D=AE=E8=BF=94=E5=9B=9E=E8=B7=AF?=
 =?UTF-8?q?=E7=94=B1=E5=8A=A8=E6=80=81=E6=B8=B2=E6=9F=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

BREAKING CHANGE:
未完成
---
 mock/module/user.ts                   | 50 +++++++++++++++++++++++-
 src/layouts/components/sider/Menu.vue | 55 ++-------------------------
 src/store/modules/auth.ts             |  9 ++++-
 src/store/modules/route.ts            | 21 ++++++++--
 src/types/business.d.ts               |  8 +++-
 src/types/system.d.ts                 |  7 ++++
 6 files changed, 90 insertions(+), 60 deletions(-)

diff --git a/mock/module/user.ts b/mock/module/user.ts
index 004810d..6dde547 100644
--- a/mock/module/user.ts
+++ b/mock/module/user.ts
@@ -16,14 +16,60 @@ const userInfo = {
   permissions: [
     {
       label: '主控台',
-      value: 'dashboard_console',
+      key: 'dashboard_console',
       icon: 'icon-park-outline:alarm',
     },
     {
       label: '监控页',
-      value: 'dashboard_monitor',
+      key: 'dashboard_monitor',
       icon: 'icon-park-outline:anchor',
     },
+    {
+      label: 'test1',
+      key: '/test1',
+      icon: 'icon-park-outline:alarm',
+    },
+    {
+      label: 'test2',
+      key: '/test2',
+      icon: 'icon-park-outline:pic',
+    },
+    {
+      label: 'test3',
+      key: '/test3',
+      icon: 'icon-park-outline:tool',
+    },
+    {
+      label: '舞,舞,舞',
+      key: 'dance-dance-dance',
+      icon: 'icon-park-outline:command',
+      children: [
+        {
+          label: '饮品',
+          key: 'beverage',
+          children: [
+            {
+              label: '威士忌',
+              key: 'whisky',
+            },
+          ],
+        },
+        {
+          label: '食物',
+          key: 'food',
+          children: [
+            {
+              label: '三明治',
+              key: 'sandwich',
+            },
+          ],
+        },
+        {
+          label: '过去增多,未来减少',
+          key: 'the-past-increases-the-future-recedes',
+        },
+      ],
+    },
   ],
 };
 
diff --git a/src/layouts/components/sider/Menu.vue b/src/layouts/components/sider/Menu.vue
index 77cbb8d..c7e176e 100644
--- a/src/layouts/components/sider/Menu.vue
+++ b/src/layouts/components/sider/Menu.vue
@@ -4,7 +4,7 @@
     :collapsed-width="64"
     :collapsed-icon-size="24"
     :indent="20"
-    :options="menuOptions"
+    :options="routesStore.menus"
     @update:value="handleClickMenu"
   />
 </template>
@@ -12,64 +12,15 @@
 <script setup lang="ts">
 import { useAppStore } from '@/store';
 import { useAppRouter } from '@/hook';
-import type { MenuOption } from 'naive-ui';
-import { renderIcon } from '@/utils/icon';
+import { useRouteStore } from '~/src/store/modules/route';
 
 const { routerPush } = useAppRouter();
 const appStore = useAppStore();
+const routesStore = useRouteStore();
 
 const handleClickMenu = (key: string) => {
   routerPush(key);
 };
-const menuOptions: MenuOption[] = [
-  {
-    label: 'test1',
-    key: '/test1',
-    icon: renderIcon('icon-park-outline:alarm'),
-  },
-  {
-    label: 'test2',
-    key: '/test2',
-    icon: renderIcon('icon-park-outline:tool'),
-  },
-  {
-    label: 'test3',
-    key: '/test3',
-    icon: renderIcon('icon-park-outline:pic'),
-  },
-  {
-    label: '舞,舞,舞',
-    key: 'dance-dance-dance',
-    icon: renderIcon('icon-park-outline:command'),
-    children: [
-      {
-        label: '饮品',
-        key: 'beverage',
-        // icon: renderIcon(WineIcon),
-        children: [
-          {
-            label: '威士忌',
-            key: 'whisky',
-          },
-        ],
-      },
-      {
-        label: '食物',
-        key: 'food',
-        children: [
-          {
-            label: '三明治',
-            key: 'sandwich',
-          },
-        ],
-      },
-      {
-        label: '过去增多,未来减少',
-        key: 'the-past-increases-the-future-recedes',
-      },
-    ],
-  },
-];
 </script>
 
 <style scoped></style>
diff --git a/src/store/modules/auth.ts b/src/store/modules/auth.ts
index e4d77fa..f96149f 100644
--- a/src/store/modules/auth.ts
+++ b/src/store/modules/auth.ts
@@ -4,6 +4,7 @@ import { setUserInfo, getUserInfo, getToken, setToken, clearAuthStorage } from '
 import { router } from '@/router';
 import { useAppRouter } from '@/hook';
 import { unref } from 'vue';
+import { useRouteStore } from './route';
 
 export const useAuthStore = defineStore('auth-store', {
   state: () => {
@@ -49,7 +50,7 @@ export const useAuthStore = defineStore('auth-store', {
       // 等待数据写入完成
       const catchSuccess = await this.catchUserInfo(data);
       // 初始化侧边菜单
-
+      await this.setRouterStore(data.permissions);
       // 登录写入信息成功
       if (catchSuccess) {
         // 进行重定向跳转
@@ -81,5 +82,11 @@ export const useAuthStore = defineStore('auth-store', {
 
       return catchSuccess;
     },
+
+    /* 将路由表等信息推送到routeStore */
+    async setRouterStore(permissions: Auth.UserInfoPermissions[]) {
+      const { setMenus } = useRouteStore();
+      setMenus(permissions);
+    },
   },
 });
diff --git a/src/store/modules/route.ts b/src/store/modules/route.ts
index 07f229a..4811568 100644
--- a/src/store/modules/route.ts
+++ b/src/store/modules/route.ts
@@ -1,15 +1,28 @@
 import { defineStore } from 'pinia';
+import { renderIcon } from '@/utils/icon';
 
+interface RuutesStatus {
+  menus: any;
+}
 export const useRouteStore = defineStore('route-store', {
-  state: () => {
+  state: (): RuutesStatus => {
     return {
       menus: [],
     };
   },
   actions: {
-    setMenus(data: any) {
-      // TODO不应为any
-      this.menus = data;
+    setMenus(data: Auth.UserInfoPermissions[]) {
+      this.menus = this.transformAuthRoutesToMenus(data);
+    },
+    // 将返回的路由表渲染成侧边栏
+    transformAuthRoutesToMenus(data: Auth.UserInfoPermissions[]) {
+      return data.map((item) => {
+        item.icon = renderIcon(item.icon);
+        if (item.children) {
+          this.transformAuthRoutesToMenus(item.children);
+        }
+        return item;
+      });
     },
   },
 });
diff --git a/src/types/business.d.ts b/src/types/business.d.ts
index a06d2ee..f31966c 100644
--- a/src/types/business.d.ts
+++ b/src/types/business.d.ts
@@ -26,6 +26,12 @@ declare namespace Auth {
     /* token */
     token: string;
     /* 权限路由 */
-    permissions: [];
+    permissions: UserInfoPermissions[];
+  }
+  interface UserInfoPermissions {
+    label: string;
+    key: string;
+    icon: any;
+    children: UserInfoPermissions[];
   }
 }
diff --git a/src/types/system.d.ts b/src/types/system.d.ts
index 995e772..5890ef9 100644
--- a/src/types/system.d.ts
+++ b/src/types/system.d.ts
@@ -12,3 +12,10 @@ declare namespace Service {
     successCode: number | string;
   }
 }
+/** 菜单项配置 */
+type GlobalMenuOption = import('naive-ui').MenuOption & {
+  key: string;
+  label: string;
+  icon?: () => import('vue').VNodeChild;
+  children?: GlobalMenuOption[];
+};