From 9d926b2760b75e1d8e71a68dc7ff6c5026223a43 Mon Sep 17 00:00:00 2001 From: kailong321200875 <321200875@qq.com> Date: Sat, 19 Feb 2022 20:34:44 +0800 Subject: [PATCH] feat: Add dynamic route --- mock/role/index.ts | 475 +++++++++++++++++++++++ mock/user/index.ts | 24 ++ src/api/login/index.ts | 21 +- src/api/login/types.ts | 7 + src/locales/en.ts | 18 +- src/locales/zh-CN.ts | 17 +- src/permission.ts | 10 +- src/router/index.ts | 43 +- src/store/modules/permission.ts | 39 +- src/store/modules/tagsView.ts | 3 - src/utils/routerHelper.ts | 35 +- src/views/Authorization/Role.vue | 88 +++++ src/views/Authorization/User.vue | 88 +++++ src/views/Login/components/LoginForm.vue | 40 +- types/router.d.ts | 9 + 15 files changed, 851 insertions(+), 66 deletions(-) create mode 100644 mock/role/index.ts create mode 100644 src/views/Authorization/Role.vue create mode 100644 src/views/Authorization/User.vue diff --git a/mock/role/index.ts b/mock/role/index.ts new file mode 100644 index 0000000..8c32c8b --- /dev/null +++ b/mock/role/index.ts @@ -0,0 +1,475 @@ +import { config } from '@/config/axios/config' +import { MockMethod } from 'vite-plugin-mock' + +const { result_code } = config + +const timeout = 1000 + +const adminList = [ + { + path: '/dashboard', + component: '#', + redirect: '/dashboard/analysis', + name: 'Dashboard', + meta: { + title: 'router.dashboard', + icon: 'ant-design:dashboard-filled', + alwaysShow: true + }, + children: [ + { + path: 'analysis', + component: 'views/Dashboard/Analysis', + name: 'Analysis', + meta: { + title: 'router.analysis', + noCache: true + } + }, + { + path: 'workplace', + component: 'views/Dashboard/Workplace', + name: 'Workplace', + meta: { + title: 'router.workplace', + noCache: true + } + } + ] + }, + { + path: '/guide', + component: '#', + name: 'Guide', + meta: {}, + children: [ + { + path: 'index', + component: 'views/Guide/Guide', + name: 'GuideDemo', + meta: { + title: 'router.guide', + icon: 'cib:telegram-plane' + } + } + ] + }, + { + path: '/components', + component: '#', + redirect: '/components/icon', + name: 'ComponentsDemo', + meta: { + title: 'router.component', + icon: 'bx:bxs-component', + alwaysShow: true + }, + children: [ + { + path: 'form', + component: '##', + name: 'Form', + meta: { + title: 'router.form', + alwaysShow: true + }, + children: [ + { + path: 'default-form', + component: 'views/Components/Form/DefaultForm', + name: 'DefaultForm', + meta: { + title: 'router.defaultForm' + } + }, + { + path: 'use-form', + component: 'views/Components/Form/UseFormDemo', + name: 'UseForm', + meta: { + title: 'UseForm' + } + }, + { + path: 'ref-form', + component: 'views/Components/Form/RefForm', + name: 'RefForm', + meta: { + title: 'RefForm' + } + } + ] + }, + { + path: 'table', + component: '##', + name: 'TableDemo', + meta: { + title: 'router.table', + alwaysShow: true + }, + children: [ + { + path: 'default-table', + component: 'views/Components/Table/DefaultTable', + name: 'DefaultTable', + meta: { + title: 'router.defaultTable' + } + }, + { + path: 'use-table', + component: 'views/Components/Table/UseTableDemo', + name: 'UseTable', + meta: { + title: 'UseTable' + } + }, + { + path: 'ref-table', + component: 'views/Components/Table/RefTable', + name: 'RefTable', + meta: { + title: 'RefTable' + } + } + ] + }, + { + path: 'editor-demo', + component: '##', + name: 'EditorDemo', + meta: { + title: 'router.editor', + alwaysShow: true + }, + children: [ + { + path: 'editor', + component: 'views/Components/Editor/Editor', + name: 'Editor', + meta: { + title: 'router.richText' + } + } + ] + }, + { + path: 'search', + component: 'views/Components/Search', + name: 'Search', + meta: { + title: 'router.search' + } + }, + { + path: 'descriptions', + component: 'views/Components/Descriptions', + name: 'Descriptions', + meta: { + title: 'router.descriptions' + } + }, + { + path: 'image-viewer', + component: 'views/Components/ImageViewer', + name: 'ImageViewer', + meta: { + title: 'router.imageViewer' + } + }, + { + path: 'dialog', + component: 'views/Components/Dialog', + name: 'Dialog', + meta: { + title: 'router.dialog' + } + }, + { + path: 'icon', + component: 'views/Components/Icon', + name: 'Icon', + meta: { + title: 'router.icon' + } + }, + { + path: 'echart', + component: 'views/Components/Echart', + name: 'Echart', + meta: { + title: 'router.echart' + } + }, + { + path: 'count-to', + component: 'views/Components/CountTo', + name: 'CountTo', + meta: { + title: 'router.countTo' + } + }, + { + path: 'watermark', + component: 'views/Components/Watermark', + name: 'Watermark', + meta: { + title: 'router.watermark' + } + }, + { + path: 'qrcode', + component: 'views/Components/Qrcode', + name: 'Qrcode', + meta: { + title: 'router.qrcode' + } + }, + { + path: 'highlight', + component: 'views/Components/Highlight', + name: 'Highlight', + meta: { + title: 'router.highlight' + } + }, + { + path: 'infotip', + component: 'views/Components/Infotip', + name: 'Infotip', + meta: { + title: 'router.infotip' + } + } + ] + }, + { + path: '/level', + component: '#', + redirect: '/level/menu1/menu1-1/menu1-1-1', + name: 'Level', + meta: { + title: 'router.level', + icon: 'carbon:skill-level-advanced' + }, + children: [ + { + path: 'menu1', + name: 'Menu1', + component: '##', + redirect: '/level/menu1/menu1-1/menu1-1-1', + meta: { + title: 'router.menu1' + }, + children: [ + { + path: 'menu1-1', + name: 'Menu11', + component: '##', + redirect: '/level/menu1/menu1-1/menu1-1-1', + meta: { + title: 'router.menu11', + alwaysShow: true + }, + children: [ + { + path: 'menu1-1-1', + name: 'Menu111', + component: 'views/Level/Menu111', + meta: { + title: 'router.menu111' + } + } + ] + }, + { + path: 'menu1-2', + name: 'Menu12', + component: 'views/Level/Menu12', + meta: { + title: 'router.menu12' + } + } + ] + }, + { + path: 'menu2', + name: 'Menu2Demo', + component: 'views/Level/Menu2', + meta: { + title: 'router.menu2' + } + } + ] + }, + { + path: '/example', + component: '#', + redirect: '/example/example-dialog', + name: 'Example', + meta: { + title: 'router.example', + icon: 'ep:management', + alwaysShow: true + }, + children: [ + { + path: 'example-dialog', + component: 'views/Example/Dialog/ExampleDialog', + name: 'ExampleDialog', + meta: { + title: 'router.exampleDialog' + } + }, + { + path: 'example-page', + component: 'views/Example/Page/ExamplePage', + name: 'ExamplePage', + meta: { + title: 'router.examplePage' + } + }, + { + path: 'example-add', + component: 'views/Example/Page/ExampleAdd', + name: 'ExampleAdd', + meta: { + title: 'router.exampleAdd', + noTagsView: true, + noCache: true, + hidden: true, + showMainRoute: true, + activeMenu: '/example/example-page' + } + }, + { + path: 'example-edit', + component: 'views/Example/Page/ExampleEdit', + name: 'ExampleEdit', + meta: { + title: 'router.exampleEdit', + noTagsView: true, + noCache: true, + hidden: true, + showMainRoute: true, + activeMenu: '/example/example-page' + } + }, + { + path: 'example-detail', + component: 'views/Example/Page/ExampleDetail', + name: 'ExampleDetail', + meta: { + title: 'router.exampleDetail', + noTagsView: true, + noCache: true, + hidden: true, + showMainRoute: true, + activeMenu: '/example/example-page' + } + } + ] + }, + { + path: '/error', + component: '#', + redirect: '/error/404', + name: 'Error', + meta: { + title: 'router.errorPage', + icon: 'ci:error', + alwaysShow: true + }, + children: [ + { + path: '404-demo', + component: 'views/Error/404', + name: '404Demo', + meta: { + title: '404' + } + }, + { + path: '403-demo', + component: 'views/Error/403', + name: '403Demo', + meta: { + title: '403' + } + }, + { + path: '500-demo', + component: 'views/Error/500', + name: '500Demo', + meta: { + title: '500' + } + } + ] + } +] + +const testList: string[] = [ + '/dashboard', + '/dashboard/analysis', + '/dashboard/workplace', + '/guide', + '/guide/index', + '/components', + '/components/form', + '/components/form/default-form', + '/components/form/use-form', + '/components/form/ref-form', + '/components/table', + '/components/table/default-table', + '/components/table/use-table', + '/components/table/ref-table', + '/components/editor-demo', + '/components/editor-demo/editor', + '/components/search', + '/components/descriptions', + '/components/image-viewer', + '/components/dialog', + '/components/icon', + '/components/echart', + '/components/count-to', + '/components/watermark', + '/components/qrcode', + '/components/highlight', + '/components/infotip', + '/level', + '/level/menu1', + '/level/menu1/menu1-1', + '/level/menu1/menu1-1/menu1-1-1', + '/level/menu1/menu1-2', + '/level/menu2', + '/example', + '/example/example-dialog', + '/example/example-page', + '/example/example-add', + '/example/example-edit', + '/example/example-detail', + '/error', + '/error/404-demo', + '/error/403-demo', + '/error/500-demo' +] + +export default [ + // 列表接口 + { + url: '/role/list', + method: 'get', + timeout, + response: ({ query }) => { + const { roleName } = query + return { + code: result_code, + data: { + list: roleName === 'admin' ? adminList : testList + } + } + } + } +] as MockMethod[] diff --git a/mock/user/index.ts b/mock/user/index.ts index 5574300..12a1ccb 100644 --- a/mock/user/index.ts +++ b/mock/user/index.ts @@ -26,6 +26,30 @@ const List: { ] export default [ + // 列表接口 + { + url: '/user/list', + method: 'get', + response: ({ query }) => { + const { username, pageIndex, pageSize } = query + + const mockList = List.filter((item) => { + if (username && item.username.indexOf(username) < 0) return false + return true + }) + const pageList = mockList.filter( + (_, index) => index < pageSize * pageIndex && index >= pageSize * (pageIndex - 1) + ) + + return { + code: result_code, + data: { + total: mockList.length, + list: pageList + } + } + } + }, // 登录接口 { url: '/user/login', diff --git a/src/api/login/index.ts b/src/api/login/index.ts index c2a433e..463c88c 100644 --- a/src/api/login/index.ts +++ b/src/api/login/index.ts @@ -1,5 +1,5 @@ import { useAxios } from '@/hooks/web/useAxios' -import type { UserLoginType } from './types' +import type { UserLoginType, UserType } from './types' const { request } = useAxios() @@ -13,3 +13,22 @@ export const loginApi = (data: UserLoginType) => { export const loginOutApi = () => { return request({ url: '/user/loginOut', method: 'get' }) } + +export const getUserListApi = ({ params }: AxiosConfig) => { + return request<{ + total: number + list: UserType[] + }>({ url: '/user/list', method: 'get', params }) +} + +export const getAdminRoleApi = ({ params }: AxiosConfig) => { + return request<{ + list: AppCustomRouteRecordRaw[] + }>({ url: '/role/list', method: 'get', params }) +} + +export const getTestRoleApi = ({ params }: AxiosConfig) => { + return request<{ + list: string[] + }>({ url: '/role/list', method: 'get', params }) +} diff --git a/src/api/login/types.ts b/src/api/login/types.ts index be52d56..12730b2 100644 --- a/src/api/login/types.ts +++ b/src/api/login/types.ts @@ -2,3 +2,10 @@ export type UserLoginType = { username: string password: string } + +export type UserType = { + username: string + password: string + role: string + roleId: string +} diff --git a/src/locales/en.ts b/src/locales/en.ts index c824668..d55b1e5 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -126,7 +126,10 @@ export default { exampleAdd: 'Example page - add', exampleEdit: 'Example page - edit', exampleDetail: 'Example page - detail', - errorPage: 'Error page' + errorPage: 'Error page', + authorization: 'Authorization', + user: 'User management', + role: 'Role management' }, analysis: { newUser: 'New user', @@ -393,5 +396,18 @@ export default { content: 'Content', save: 'Save', detail: 'Detail' + }, + userDemo: { + title: 'User management', + message: + 'Because it is simulated data, only two accounts with different permissions are provided, which can be modified and combined by developers according to the actual situation.', + index: 'Index', + action: 'Action', + username: 'Username', + password: 'Password', + role: 'Role', + remark: 'Remark', + remarkMessage1: 'Back end control routing permission', + remarkMessage2: 'Front end control routing permission' } } diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index dbb2883..6dcad77 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -126,7 +126,10 @@ export default { exampleAdd: '综合示例 - 新增', exampleEdit: '综合示例 - 编辑', exampleDetail: '综合示例 - 详情', - errorPage: '错误页面' + errorPage: '错误页面', + authorization: '权限管理', + user: '用户管理', + role: '角色管理' }, analysis: { newUser: '新增用户', @@ -390,5 +393,17 @@ export default { content: '内容', save: '保存', detail: '详情' + }, + userDemo: { + title: '用户管理', + message: '由于是模拟数据,所以只提供了两种不同权限的帐号,开发者可根据实际情况自行改造结合。', + index: '序号', + action: '操作', + username: '用户名', + password: '密码', + role: '角色', + remark: '备注', + remarkMessage1: '后端控制路由权限', + remarkMessage2: '前端控制路由权限' } } diff --git a/src/permission.ts b/src/permission.ts index d738c8d..a770869 100644 --- a/src/permission.ts +++ b/src/permission.ts @@ -30,7 +30,15 @@ router.beforeEach(async (to, from, next) => { to.path === '/' ? next({ path: permissionStore.addRouters[0]?.path as string }) : next() return } - await permissionStore.generateRoutes() + + // 开发者可根据实际情况进行修改 + const roleRouters = wsCache.get('roleRouters') || [] + const userInfo = wsCache.get(appStore.getUserInfo) + + userInfo.role === 'admin' + ? await permissionStore.generateRoutes('admin', roleRouters as AppCustomRouteRecordRaw[]) + : await permissionStore.generateRoutes('test', roleRouters as string[]) + permissionStore.getAddRouters.forEach((route) => { router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表 }) diff --git a/src/router/index.ts b/src/router/index.ts index 97e7b86..3193d8a 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -424,31 +424,60 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [ }, children: [ { - path: '404', + path: '404-demo', component: () => import('@/views/Error/404.vue'), - name: '404', + name: '404Demo', meta: { title: '404' } }, { - path: '403', + path: '403-demo', component: () => import('@/views/Error/403.vue'), - name: '403', + name: '403Demo', meta: { title: '403' } }, { - path: '500', + path: '500-demo', component: () => import('@/views/Error/500.vue'), - name: '500', + name: '500Demo', meta: { title: '500' } } ] } + // { + // path: '/authorization', + // component: Layout, + // redirect: '/authorization/user', + // name: 'Authorization', + // meta: { + // title: t('router.authorization'), + // icon: 'eos-icons:role-binding', + // alwaysShow: true + // }, + // children: [ + // { + // path: 'user', + // component: () => import('@/views/Authorization/User.vue'), + // name: 'User', + // meta: { + // title: t('router.user') + // } + // }, + // { + // path: 'role', + // component: () => import('@/views/Authorization/Role.vue'), + // name: 'Role', + // meta: { + // title: t('router.role') + // } + // } + // ] + // } ] const router = createRouter({ @@ -459,7 +488,7 @@ const router = createRouter({ }) export const resetRouter = (): void => { - const resetWhiteNameList = ['RedirectRoot', 'Redirect', 'Login', 'Root', 'Dashboard', 'Page404'] + const resetWhiteNameList = ['Redirect', 'Login', 'NoFind'] router.getRoutes().forEach((route) => { const { name } = route if (name && !resetWhiteNameList.includes(name as string)) { diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 2cabe84..ec9d8eb 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -1,16 +1,9 @@ import { defineStore } from 'pinia' import { asyncRouterMap, constantRouterMap } from '@/router' -// import { useCache } from '@/hooks/web/useCache' -import { flatMultiLevelRoutes } from '@/utils/routerHelper' -// import { generateRoutesFn1, generateRoutesFn2, flatMultiLevelRoutes } from '@/utils/routerHelper' +import { generateRoutesFn1, generateRoutesFn2, flatMultiLevelRoutes } from '@/utils/routerHelper' import { store } from '../index' -// import { useAppStoreWithOut } from '@/store/modules/app' import { cloneDeep } from 'lodash-es' -// const { wsCache } = useCache() - -// const appStore = useAppStoreWithOut() - export interface PermissionState { routers: AppRouteRecordRaw[] addRouters: AppRouteRecordRaw[] @@ -44,21 +37,23 @@ export const usePermissionStore = defineStore({ } }, actions: { - generateRoutes(): Promise { + generateRoutes( + type: 'admin' | 'test' | 'none', + routers?: AppCustomRouteRecordRaw[] | string[] + ): Promise { return new Promise((resolve) => { - // 路由权限控制,如果不需要权限控制,请注释 - // let routerMap: AppRouteRecordRaw[] = [] - // if (wsCache.get(appStore.getUserInfo).username === 'admin') { - // // 模拟前端控制权限 - // routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap)) - // } else { - // // 模拟后端控制权限 - // routerMap = generateRoutesFn2(wsCache.get(appStore.getUserInfo).checkedNodes) - // } - - // 不需要权限控制 - const routerMap: AppRouteRecordRaw[] = cloneDeep(asyncRouterMap) - + let routerMap: AppRouteRecordRaw[] = [] + if (type === 'admin') { + // 模拟后端过滤菜单 + routerMap = generateRoutesFn2(routers as AppCustomRouteRecordRaw[]) + } else if (type === 'test') { + // 模拟前端过滤菜单 + routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap), routers as string[]) + } else { + // 直接读取静态路由表 + routerMap = cloneDeep(asyncRouterMap) + } + console.log(routerMap) // 动态路由,404一定要放到最后面 this.addRouters = routerMap.concat([ { diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts index 7ba7652..66a779c 100644 --- a/src/store/modules/tagsView.ts +++ b/src/store/modules/tagsView.ts @@ -16,9 +16,6 @@ export const useTagsViewStore = defineStore({ visitedViews: [], cachedViews: new Set() }), - persist: { - enabled: true - }, getters: { getVisitedViews(): RouteLocationNormalizedLoaded[] { return this.visitedViews diff --git a/src/utils/routerHelper.ts b/src/utils/routerHelper.ts index ddb399b..5ada30b 100644 --- a/src/utils/routerHelper.ts +++ b/src/utils/routerHelper.ts @@ -1,15 +1,9 @@ import { createRouter, createWebHashHistory } from 'vue-router' import type { Router, RouteLocationNormalized, RouteRecordNormalized, RouteMeta } from 'vue-router' import { isUrl } from '@/utils/is' -import { useCache } from '@/hooks/web/useCache' -import { useAppStoreWithOut } from '@/store/modules/app' import { omit, cloneDeep } from 'lodash-es' -const appStore = useAppStoreWithOut() - -const { wsCache } = useCache() - -const modules = import.meta.glob('../../views/**/*.{vue,tsx}') +const modules = import.meta.glob('../views/**/*.{vue,tsx}') /* Layout */ export const Layout = () => import('@/layout/Layout.vue') @@ -41,6 +35,7 @@ export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormal // 前端控制路由生成 export const generateRoutesFn1 = ( routes: AppRouteRecordRaw[], + keys: string[], basePath = '/' ): AppRouteRecordRaw[] => { const res: AppRouteRecordRaw[] = [] @@ -55,7 +50,6 @@ export const generateRoutesFn1 = ( let data: Nullable = null let onlyOneChild: Nullable = null - if (route.children && route.children.length === 1 && !meta.alwaysShow) { onlyOneChild = ( isUrl(route.children[0].path) @@ -64,16 +58,14 @@ export const generateRoutesFn1 = ( ) as string } - // 权限过滤,通过获取登录信息里面的角色权限,动态的渲染菜单。 - const list = wsCache.get(appStore.getUserInfo).checkedNodes // 开发者可以根据实际情况进行扩展 - for (const item of list) { + for (const item of keys) { // 通过路径去匹配 - if (isUrl(item.path) && (onlyOneChild === item.path || route.path === item.path)) { + if (isUrl(item) && (onlyOneChild === item || route.path === item)) { data = Object.assign({}, route) } else { const routePath = pathResolve(basePath, onlyOneChild || route.path) - if (routePath === item.path || meta.followRoute === item.path) { + if (routePath === item || meta.followRoute === item) { data = Object.assign({}, route) } } @@ -81,7 +73,7 @@ export const generateRoutesFn1 = ( // recursive child routes if (route.children && data) { - data.children = generateRoutesFn1(route.children, pathResolve(basePath, data.path)) + data.children = generateRoutesFn1(route.children, keys, pathResolve(basePath, data.path)) } if (data) { res.push(data as AppRouteRecordRaw) @@ -91,7 +83,7 @@ export const generateRoutesFn1 = ( } // 后端控制路由生成 -export const generateRoutesFn2 = (routes: AppRouteRecordRaw[]): AppRouteRecordRaw[] => { +export const generateRoutesFn2 = (routes: AppCustomRouteRecordRaw[]): AppRouteRecordRaw[] => { const res: AppRouteRecordRaw[] = [] for (const route of routes) { @@ -102,15 +94,14 @@ export const generateRoutesFn2 = (routes: AppRouteRecordRaw[]): AppRouteRecordRa meta: route.meta } if (route.component) { - const comModule = - modules[`../../${route.component}.vue`] || modules[`../../${route.component}.tsx`] - if (comModule) { + const comModule = modules[`../${route.component}.vue`] || modules[`../${route.component}.tsx`] + const component = route.component as string + if (!comModule && !component.includes('#')) { + console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件,请创建`) + } else { // 动态加载路由文件,可根据实际情况进行自定义逻辑 - const component = route.component as string data.component = component === '#' ? Layout : component.includes('##') ? getParentLayout() : comModule - } else { - console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件,请创建`) } } // recursive child routes @@ -124,7 +115,7 @@ export const generateRoutesFn2 = (routes: AppRouteRecordRaw[]): AppRouteRecordRa export const pathResolve = (parentPath: string, path: string) => { const childPath = path.startsWith('/') || !path ? path : `/${path}` - return `${parentPath}${childPath}` + return `${parentPath}${childPath}`.replace(/\/\//g, '/') } // 路由降级 diff --git a/src/views/Authorization/Role.vue b/src/views/Authorization/Role.vue new file mode 100644 index 0000000..cf82877 --- /dev/null +++ b/src/views/Authorization/Role.vue @@ -0,0 +1,88 @@ + + + diff --git a/src/views/Authorization/User.vue b/src/views/Authorization/User.vue new file mode 100644 index 0000000..cf82877 --- /dev/null +++ b/src/views/Authorization/User.vue @@ -0,0 +1,88 @@ + + + diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index 0d964b2..d4866e6 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -5,7 +5,7 @@ import { useI18n } from '@/hooks/web/useI18n' import { ElButton, ElCheckbox, ElLink } from 'element-plus' import { required } from '@/utils/formRules' import { useForm } from '@/hooks/web/useForm' -import { loginApi } from '@/api/login' +import { loginApi, getTestRoleApi, getAdminRoleApi } from '@/api/login' import type { UserLoginType } from '@/api/login/types' import { useCache } from '@/hooks/web/useCache' import { useAppStore } from '@/store/modules/app' @@ -126,17 +126,41 @@ const signIn = async () => { if (res) { const { wsCache } = useCache() wsCache.set(appStore.getUserInfo, res.data) - await permissionStore.generateRoutes().catch(() => {}) - permissionStore.getAddRouters.forEach((route) => { - addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 - }) - permissionStore.setIsAddRouters(true) - // push({ path: redirect.value || permissionStore.addRouters[0].path }) - push({ path: permissionStore.addRouters[0].path }) + getRole() } } } + +// 获取角色信息 +const getRole = async () => { + const { getFormData } = methods + const formData = await getFormData() + const params = { + roleName: formData.username + } + // admin - 模拟后端过滤菜单 + // test - 模拟前端过滤菜单 + const res = + formData.username === 'admin' + ? await getAdminRoleApi({ params }) + : await getTestRoleApi({ params }) + if (res) { + const { wsCache } = useCache() + const routers = res.data.list || [] + wsCache.set('roleRouters', routers) + + formData.username === 'admin' + ? await permissionStore.generateRoutes('admin', routers).catch(() => {}) + : await permissionStore.generateRoutes('test', routers).catch(() => {}) + + permissionStore.getAddRouters.forEach((route) => { + addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 + }) + permissionStore.setIsAddRouters(true) + push({ path: redirect.value || permissionStore.addRouters[0].path }) + } +}