From d1574b0d28b70fd3a5f1c3fd2881001c5db92410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=BB=A4?= <2603820757@qq.com> Date: Tue, 11 Oct 2022 17:38:59 +0800 Subject: [PATCH 1/9] =?UTF-8?q?:recycle:=20=E8=B7=AF=E7=94=B1=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E6=9A=82=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/plugin/styleImport.ts | 1 + src/api/user.ts | 3 +- src/mock/index.ts | 2 +- src/mock/user.ts | 39 +++++++++++++++++++++---- src/router/guard/permission.ts | 5 +++- src/router/routes/modules/dashboard.ts | 1 + src/router/routes/modules/system.ts | 22 ++++++++++++++ src/router/typings.d.ts | 6 ++-- src/store/modules/app/index.ts | 8 ++--- src/store/modules/app/types.ts | 4 +-- src/store/modules/tab-bar/index.ts | 1 + src/types/modules/system.ts | 18 ++++++++++++ src/utils/menu.ts | 29 ++++++++++++++++++ src/views/dashboard/workplace/index.vue | 1 + src/views/system/roles/index.vue | 13 +++++++++ src/views/system/user/index.vue | 15 ++++++++++ 16 files changed, 150 insertions(+), 18 deletions(-) create mode 100644 src/router/routes/modules/system.ts create mode 100644 src/types/modules/system.ts create mode 100644 src/utils/menu.ts create mode 100644 src/views/system/roles/index.vue create mode 100644 src/views/system/user/index.vue diff --git a/config/plugin/styleImport.ts b/config/plugin/styleImport.ts index acd74dd..80e81c3 100644 --- a/config/plugin/styleImport.ts +++ b/config/plugin/styleImport.ts @@ -74,6 +74,7 @@ export default function configStyleImportPlugin() { if (ignoreList.includes(name)) return ''; // eslint-disable-next-line no-prototype-builtins return replaceList.hasOwnProperty(name) + // @ts-ignore ? `@arco-design/web-vue/es/${replaceList[name]}/style/css.js` : `@arco-design/web-vue/es/${name}/style/css.js`; // less diff --git a/src/api/user.ts b/src/api/user.ts index 35b8812..a179021 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -1,6 +1,7 @@ import axios from 'axios'; import type { RouteRecordNormalized } from 'vue-router'; import { UserState } from '@/store/modules/user/types'; +import { Menu } from "@/types/modules/system"; export interface LoginData { username: string; @@ -23,5 +24,5 @@ export function getUserInfo() { } export function getMenuList() { - return axios.post('/api/user/menu'); + return axios.post('/api/user/menu'); } diff --git a/src/mock/index.ts b/src/mock/index.ts index cf1af17..9ea3734 100644 --- a/src/mock/index.ts +++ b/src/mock/index.ts @@ -6,5 +6,5 @@ import './message-box'; import '@/views/dashboard/workplace/mock'; Mock.setup({ - timeout: '600-1000', + timeout: '100-500', }); diff --git a/src/mock/user.ts b/src/mock/user.ts index dedd60f..8bcd81e 100644 --- a/src/mock/user.ts +++ b/src/mock/user.ts @@ -73,26 +73,53 @@ setupMock({ { path: '/dashboard', name: 'dashboard', + component: '@/layout/default-layout.vue', meta: { title: '仪表盘', - requiresAuth: true, icon: 'icon-dashboard', - order: 1, }, children: [ { path: 'workplace', name: 'Workplace', + component: '@/views/dashboard/workplace/index.vue', meta: { title: '工作台', - requiresAuth: true, + cache: true, + affix: true + } + } + ] + }, + { + path: '/system', + name: 'system', + component: '@/layout/default-layout.vue', + meta: { + title: '系统管理', + icon: 'icon-dashboard', + order: 1, + cache: true + }, + children: [ + { + path: 'user', + name: 'user', + component: '@/views/system/user/index.vue', + meta: { + title: '用户管理', + cache: true, + affix: true, }, }, { - path: 'https://arco.design', - name: 'arcoWebsite', + path: 'role', + name: 'role', + component: '@/views/system/roles/index.vue', meta: { - title: 'arcoWebsite' + title: '角色管理', + cache: true, + affix: true, }, }, ], diff --git a/src/router/guard/permission.ts b/src/router/guard/permission.ts index ad3724e..ab270c9 100644 --- a/src/router/guard/permission.ts +++ b/src/router/guard/permission.ts @@ -3,6 +3,7 @@ import NProgress from 'nprogress'; // progress bar import usePermission from '@/hooks/permission'; import { useUserStore, useAppStore } from '@/store'; +import { buildVueRouter } from "@/utils/menu"; import { appRoutes } from '../routes'; import { WHITE_LIST, NOT_FOUND } from '../constants'; @@ -24,6 +25,8 @@ export default function setupPermissionGuard(router: Router) { ) { await appStore.fetchServerMenuConfig(); } + // @ts-ignore + appStore.appAsyncMenus.map(buildVueRouter).forEach(router.addRoute) const serverMenuConfig = [...appStore.appAsyncMenus, ...WHITE_LIST]; let exist = false; @@ -33,7 +36,7 @@ export default function setupPermissionGuard(router: Router) { if (element?.children) { serverMenuConfig.push( - ...(element.children as unknown as RouteRecordNormalized[]) + ...element.children ); } } diff --git a/src/router/routes/modules/dashboard.ts b/src/router/routes/modules/dashboard.ts index fa6c425..4afe6ca 100644 --- a/src/router/routes/modules/dashboard.ts +++ b/src/router/routes/modules/dashboard.ts @@ -5,6 +5,7 @@ const DASHBOARD: AppRouteRecordRaw = { path: '/dashboard', name: 'dashboard', component: DEFAULT_LAYOUT, + redirect: '/dashboard/workplace', meta: { title: '仪表盘', requiresAuth: true, diff --git a/src/router/routes/modules/system.ts b/src/router/routes/modules/system.ts new file mode 100644 index 0000000..92babd4 --- /dev/null +++ b/src/router/routes/modules/system.ts @@ -0,0 +1,22 @@ +import { AppRouteRecordRaw } from "@/router/routes/types"; +import { DEFAULT_LAYOUT } from "@/router/constants"; + +const SYSTEM: AppRouteRecordRaw = { + path: '/system', + name: 'system', + component: DEFAULT_LAYOUT, + children: [ + { + path: 'user', + name: 'user', + component: '@/views/system/user/index.vue', + }, + { + path: 'role', + name: 'role', + component: '@/views/system/roles/index.vue', + }, + ], +}; + +export default SYSTEM diff --git a/src/router/typings.d.ts b/src/router/typings.d.ts index e3e7c2e..7094bb7 100644 --- a/src/router/typings.d.ts +++ b/src/router/typings.d.ts @@ -3,14 +3,14 @@ import 'vue-router'; declare module 'vue-router' { interface RouteMeta { roles?: string[]; // Controls roles that have access to the page - requiresAuth: boolean; // Whether login is required to access the current page (every route must declare) + requiresAuth?: boolean; // Whether login is required to access the current page (every route must declare) icon?: string; // The icon show in the side menu title?: string; // The title name show in side menu and breadcrumb hidden?: boolean; // If true, it is not displayed in the side menu hideChildrenInMenu?: boolean; // if set true, the children are not displayed in the side menu activeMenu?: string; // if set name, the menu will be highlighted according to the name you set order?: number; // Sort routing menu items. If set key, the higher the value, the more forward it is - affix?: boolean; // if set true, the tag will not affix in the tab-bar - cache?: boolean; // if set true, the page will not be cached + affix?: boolean; // if set true, the tag will affix in the tab-bar + cache?: boolean; // if set true, the page will be cached } } diff --git a/src/store/modules/app/index.ts b/src/store/modules/app/index.ts index 77c6c35..89b7cba 100644 --- a/src/store/modules/app/index.ts +++ b/src/store/modules/app/index.ts @@ -1,10 +1,10 @@ import { defineStore } from 'pinia'; import { Notification } from '@arco-design/web-vue'; import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface'; -import type { RouteRecordNormalized } from 'vue-router'; import defaultSettings from '@/config/settings.json'; import { getMenuList } from '@/api/user'; -import { AppState } from './types'; +import type { Menu } from "@/types/modules/system"; +import type { AppState } from './types'; const useAppStore = defineStore('app', { state: (): AppState => ({ ...defaultSettings }), @@ -16,8 +16,8 @@ const useAppStore = defineStore('app', { appDevice(state: AppState) { return state.device; }, - appAsyncMenus(state: AppState): RouteRecordNormalized[] { - return state.serverMenu as unknown as RouteRecordNormalized[]; + appAsyncMenus(state: AppState): Menu[] { + return state.serverMenu; }, }, diff --git a/src/store/modules/app/types.ts b/src/store/modules/app/types.ts index 0ee2329..fc11d64 100644 --- a/src/store/modules/app/types.ts +++ b/src/store/modules/app/types.ts @@ -1,4 +1,4 @@ -import type { RouteRecordNormalized } from 'vue-router'; +import type { Menu } from "@/types/modules/system"; export interface AppState { theme: string; @@ -13,6 +13,6 @@ export interface AppState { device: string; tabBar: boolean; menuFromServer: boolean; - serverMenu: RouteRecordNormalized[]; + serverMenu: Menu[]; [key: string]: unknown; } diff --git a/src/store/modules/tab-bar/index.ts b/src/store/modules/tab-bar/index.ts index d17bdb5..f6fce9b 100644 --- a/src/store/modules/tab-bar/index.ts +++ b/src/store/modules/tab-bar/index.ts @@ -5,6 +5,7 @@ import { TabBarState, TagProps } from './types'; const formatTag = (route: RouteLocationNormalized): TagProps => { const { name, meta, fullPath, query } = route; + console.log('cache', meta.cache); return { title: meta.title || '', name: String(name), diff --git a/src/types/modules/system.ts b/src/types/modules/system.ts new file mode 100644 index 0000000..fe3383b --- /dev/null +++ b/src/types/modules/system.ts @@ -0,0 +1,18 @@ +export interface Meta { + title: string // 标题 + cache?: boolean // 缓存 + icon?: string // 图标 + hidden?: boolean // 是否在菜单栏中隐藏 + open?: boolean // 是否展开菜单 + order?: number // 排序路由菜单项。如果设置该值,值越高,越靠前 + affix?: boolean // 如果设置为false,标签将不会添加到tab-bar中 +} + +export interface Menu { + path: string + name: string + component?: string + meta?: Meta + redirect?: string + children?: Menu[] +} diff --git a/src/utils/menu.ts b/src/utils/menu.ts new file mode 100644 index 0000000..ed3542a --- /dev/null +++ b/src/utils/menu.ts @@ -0,0 +1,29 @@ +import type { Menu } from "@/types/modules/system"; +import { AppRouteRecordRaw } from "@/router/routes/types"; + +// eslint-disable-next-line import/prefer-default-export +export const buildVueRouter = (menu: Menu): AppRouteRecordRaw => { + const { name, path, component, children, redirect, meta } = menu + const route: AppRouteRecordRaw = { + redirect, + name, + path, + component: component? () => import(component.replace("@/", "/src/")): undefined, + children: children && children.length? children.map(buildVueRouter): undefined + } + if (meta) { + const { title, cache, hidden, order, icon, affix } = meta + route.meta = { + title, + icon, + cache, + hidden, + order, + affix + } + } + return route +} + + + diff --git a/src/views/dashboard/workplace/index.vue b/src/views/dashboard/workplace/index.vue index 379e5ce..abd3184 100644 --- a/src/views/dashboard/workplace/index.vue +++ b/src/views/dashboard/workplace/index.vue @@ -2,6 +2,7 @@
+ diff --git a/src/views/system/roles/index.vue b/src/views/system/roles/index.vue new file mode 100644 index 0000000..7c8ddea --- /dev/null +++ b/src/views/system/roles/index.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue new file mode 100644 index 0000000..11f6fae --- /dev/null +++ b/src/views/system/user/index.vue @@ -0,0 +1,15 @@ + + + + + -- Gitee From b4d30d88556efe4e3ca7cc3fabf5a23fb46088d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E4=BB=A4?= <2603820757@qq.com> Date: Wed, 12 Oct 2022 12:25:23 +0800 Subject: [PATCH 2/9] =?UTF-8?q?:bug:=20=E8=B7=AF=E7=94=B1=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E7=BC=93=E5=AD=98=E6=97=A0=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/user.ts | 5 ++--- src/components/menu/index.vue | 4 ++-- src/layout/page-layout.vue | 7 +------ src/mock/user.ts | 17 +++++++-------- src/router/app-menus/index.ts | 4 ++-- src/router/guard/permission.ts | 6 +++--- src/router/index.ts | 4 ++-- src/router/routes/external-modules/arco.ts | 10 --------- src/router/routes/external-modules/faq.ts | 10 --------- src/router/routes/index.ts | 6 ------ src/router/routes/modules/system.ts | 22 -------------------- src/store/modules/tab-bar/index.ts | 1 - src/types/modules/system.ts | 12 ++--------- src/utils/menu.ts | 24 ++++++++++++++-------- src/views/login/components/login-form.vue | 5 +++-- 15 files changed, 41 insertions(+), 96 deletions(-) delete mode 100644 src/router/routes/external-modules/arco.ts delete mode 100644 src/router/routes/external-modules/faq.ts delete mode 100644 src/router/routes/modules/system.ts diff --git a/src/api/user.ts b/src/api/user.ts index a179021..04ca91e 100644 --- a/src/api/user.ts +++ b/src/api/user.ts @@ -1,7 +1,6 @@ import axios from 'axios'; -import type { RouteRecordNormalized } from 'vue-router'; -import { UserState } from '@/store/modules/user/types'; -import { Menu } from "@/types/modules/system"; +import type { UserState } from '@/store/modules/user/types'; +import type { Menu } from "@/types/modules/system"; export interface LoginData { username: string; diff --git a/src/components/menu/index.vue b/src/components/menu/index.vue index f7b3ef8..2361dc9 100644 --- a/src/components/menu/index.vue +++ b/src/components/menu/index.vue @@ -71,8 +71,8 @@ return result; }; listenerRouteChange((newRoute) => { - const { requiresAuth, activeMenu, hidden } = newRoute.meta; - if (requiresAuth && (!hidden || activeMenu)) { + const { activeMenu, hidden } = newRoute.meta; + if (!hidden || activeMenu) { const menuOpenKeys = findMenuOpenKeys( (activeMenu || newRoute.name) as string ); diff --git a/src/layout/page-layout.vue b/src/layout/page-layout.vue index 69d5a54..cbf7326 100644 --- a/src/layout/page-layout.vue +++ b/src/layout/page-layout.vue @@ -1,12 +1,7 @@