feat: Add dynamic route
This commit is contained in:
parent
d5b6e2a777
commit
9d926b2760
|
@ -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[]
|
|
@ -26,6 +26,30 @@ const List: {
|
||||||
]
|
]
|
||||||
|
|
||||||
export default [
|
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',
|
url: '/user/login',
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useAxios } from '@/hooks/web/useAxios'
|
import { useAxios } from '@/hooks/web/useAxios'
|
||||||
import type { UserLoginType } from './types'
|
import type { UserLoginType, UserType } from './types'
|
||||||
|
|
||||||
const { request } = useAxios()
|
const { request } = useAxios()
|
||||||
|
|
||||||
|
@ -13,3 +13,22 @@ export const loginApi = (data: UserLoginType) => {
|
||||||
export const loginOutApi = () => {
|
export const loginOutApi = () => {
|
||||||
return request({ url: '/user/loginOut', method: 'get' })
|
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 })
|
||||||
|
}
|
||||||
|
|
|
@ -2,3 +2,10 @@ export type UserLoginType = {
|
||||||
username: string
|
username: string
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type UserType = {
|
||||||
|
username: string
|
||||||
|
password: string
|
||||||
|
role: string
|
||||||
|
roleId: string
|
||||||
|
}
|
||||||
|
|
|
@ -126,7 +126,10 @@ export default {
|
||||||
exampleAdd: 'Example page - add',
|
exampleAdd: 'Example page - add',
|
||||||
exampleEdit: 'Example page - edit',
|
exampleEdit: 'Example page - edit',
|
||||||
exampleDetail: 'Example page - detail',
|
exampleDetail: 'Example page - detail',
|
||||||
errorPage: 'Error page'
|
errorPage: 'Error page',
|
||||||
|
authorization: 'Authorization',
|
||||||
|
user: 'User management',
|
||||||
|
role: 'Role management'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: 'New user',
|
newUser: 'New user',
|
||||||
|
@ -393,5 +396,18 @@ export default {
|
||||||
content: 'Content',
|
content: 'Content',
|
||||||
save: 'Save',
|
save: 'Save',
|
||||||
detail: 'Detail'
|
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'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,10 @@ export default {
|
||||||
exampleAdd: '综合示例 - 新增',
|
exampleAdd: '综合示例 - 新增',
|
||||||
exampleEdit: '综合示例 - 编辑',
|
exampleEdit: '综合示例 - 编辑',
|
||||||
exampleDetail: '综合示例 - 详情',
|
exampleDetail: '综合示例 - 详情',
|
||||||
errorPage: '错误页面'
|
errorPage: '错误页面',
|
||||||
|
authorization: '权限管理',
|
||||||
|
user: '用户管理',
|
||||||
|
role: '角色管理'
|
||||||
},
|
},
|
||||||
analysis: {
|
analysis: {
|
||||||
newUser: '新增用户',
|
newUser: '新增用户',
|
||||||
|
@ -390,5 +393,17 @@ export default {
|
||||||
content: '内容',
|
content: '内容',
|
||||||
save: '保存',
|
save: '保存',
|
||||||
detail: '详情'
|
detail: '详情'
|
||||||
|
},
|
||||||
|
userDemo: {
|
||||||
|
title: '用户管理',
|
||||||
|
message: '由于是模拟数据,所以只提供了两种不同权限的帐号,开发者可根据实际情况自行改造结合。',
|
||||||
|
index: '序号',
|
||||||
|
action: '操作',
|
||||||
|
username: '用户名',
|
||||||
|
password: '密码',
|
||||||
|
role: '角色',
|
||||||
|
remark: '备注',
|
||||||
|
remarkMessage1: '后端控制路由权限',
|
||||||
|
remarkMessage2: '前端控制路由权限'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,15 @@ router.beforeEach(async (to, from, next) => {
|
||||||
to.path === '/' ? next({ path: permissionStore.addRouters[0]?.path as string }) : next()
|
to.path === '/' ? next({ path: permissionStore.addRouters[0]?.path as string }) : next()
|
||||||
return
|
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) => {
|
permissionStore.getAddRouters.forEach((route) => {
|
||||||
router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
|
router.addRoute(route as unknown as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
|
|
|
@ -424,31 +424,60 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '404',
|
path: '404-demo',
|
||||||
component: () => import('@/views/Error/404.vue'),
|
component: () => import('@/views/Error/404.vue'),
|
||||||
name: '404',
|
name: '404Demo',
|
||||||
meta: {
|
meta: {
|
||||||
title: '404'
|
title: '404'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '403',
|
path: '403-demo',
|
||||||
component: () => import('@/views/Error/403.vue'),
|
component: () => import('@/views/Error/403.vue'),
|
||||||
name: '403',
|
name: '403Demo',
|
||||||
meta: {
|
meta: {
|
||||||
title: '403'
|
title: '403'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '500',
|
path: '500-demo',
|
||||||
component: () => import('@/views/Error/500.vue'),
|
component: () => import('@/views/Error/500.vue'),
|
||||||
name: '500',
|
name: '500Demo',
|
||||||
meta: {
|
meta: {
|
||||||
title: '500'
|
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({
|
const router = createRouter({
|
||||||
|
@ -459,7 +488,7 @@ const router = createRouter({
|
||||||
})
|
})
|
||||||
|
|
||||||
export const resetRouter = (): void => {
|
export const resetRouter = (): void => {
|
||||||
const resetWhiteNameList = ['RedirectRoot', 'Redirect', 'Login', 'Root', 'Dashboard', 'Page404']
|
const resetWhiteNameList = ['Redirect', 'Login', 'NoFind']
|
||||||
router.getRoutes().forEach((route) => {
|
router.getRoutes().forEach((route) => {
|
||||||
const { name } = route
|
const { name } = route
|
||||||
if (name && !resetWhiteNameList.includes(name as string)) {
|
if (name && !resetWhiteNameList.includes(name as string)) {
|
||||||
|
|
|
@ -1,16 +1,9 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import { asyncRouterMap, constantRouterMap } from '@/router'
|
import { asyncRouterMap, constantRouterMap } from '@/router'
|
||||||
// import { useCache } from '@/hooks/web/useCache'
|
import { generateRoutesFn1, generateRoutesFn2, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
||||||
import { flatMultiLevelRoutes } from '@/utils/routerHelper'
|
|
||||||
// import { generateRoutesFn1, generateRoutesFn2, flatMultiLevelRoutes } from '@/utils/routerHelper'
|
|
||||||
import { store } from '../index'
|
import { store } from '../index'
|
||||||
// import { useAppStoreWithOut } from '@/store/modules/app'
|
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
// const { wsCache } = useCache()
|
|
||||||
|
|
||||||
// const appStore = useAppStoreWithOut()
|
|
||||||
|
|
||||||
export interface PermissionState {
|
export interface PermissionState {
|
||||||
routers: AppRouteRecordRaw[]
|
routers: AppRouteRecordRaw[]
|
||||||
addRouters: AppRouteRecordRaw[]
|
addRouters: AppRouteRecordRaw[]
|
||||||
|
@ -44,21 +37,23 @@ export const usePermissionStore = defineStore({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
generateRoutes(): Promise<unknown> {
|
generateRoutes(
|
||||||
|
type: 'admin' | 'test' | 'none',
|
||||||
|
routers?: AppCustomRouteRecordRaw[] | string[]
|
||||||
|
): Promise<unknown> {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
// 路由权限控制,如果不需要权限控制,请注释
|
let routerMap: AppRouteRecordRaw[] = []
|
||||||
// let routerMap: AppRouteRecordRaw[] = []
|
if (type === 'admin') {
|
||||||
// if (wsCache.get(appStore.getUserInfo).username === 'admin') {
|
// 模拟后端过滤菜单
|
||||||
// // 模拟前端控制权限
|
routerMap = generateRoutesFn2(routers as AppCustomRouteRecordRaw[])
|
||||||
// routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap))
|
} else if (type === 'test') {
|
||||||
// } else {
|
// 模拟前端过滤菜单
|
||||||
// // 模拟后端控制权限
|
routerMap = generateRoutesFn1(cloneDeep(asyncRouterMap), routers as string[])
|
||||||
// routerMap = generateRoutesFn2(wsCache.get(appStore.getUserInfo).checkedNodes)
|
} else {
|
||||||
// }
|
// 直接读取静态路由表
|
||||||
|
routerMap = cloneDeep(asyncRouterMap)
|
||||||
// 不需要权限控制
|
}
|
||||||
const routerMap: AppRouteRecordRaw[] = cloneDeep(asyncRouterMap)
|
console.log(routerMap)
|
||||||
|
|
||||||
// 动态路由,404一定要放到最后面
|
// 动态路由,404一定要放到最后面
|
||||||
this.addRouters = routerMap.concat([
|
this.addRouters = routerMap.concat([
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,9 +16,6 @@ export const useTagsViewStore = defineStore({
|
||||||
visitedViews: [],
|
visitedViews: [],
|
||||||
cachedViews: new Set()
|
cachedViews: new Set()
|
||||||
}),
|
}),
|
||||||
persist: {
|
|
||||||
enabled: true
|
|
||||||
},
|
|
||||||
getters: {
|
getters: {
|
||||||
getVisitedViews(): RouteLocationNormalizedLoaded[] {
|
getVisitedViews(): RouteLocationNormalizedLoaded[] {
|
||||||
return this.visitedViews
|
return this.visitedViews
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||||
import type { Router, RouteLocationNormalized, RouteRecordNormalized, RouteMeta } from 'vue-router'
|
import type { Router, RouteLocationNormalized, RouteRecordNormalized, RouteMeta } from 'vue-router'
|
||||||
import { isUrl } from '@/utils/is'
|
import { isUrl } from '@/utils/is'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
|
||||||
import { useAppStoreWithOut } from '@/store/modules/app'
|
|
||||||
import { omit, cloneDeep } from 'lodash-es'
|
import { omit, cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
const appStore = useAppStoreWithOut()
|
const modules = import.meta.glob('../views/**/*.{vue,tsx}')
|
||||||
|
|
||||||
const { wsCache } = useCache()
|
|
||||||
|
|
||||||
const modules = import.meta.glob('../../views/**/*.{vue,tsx}')
|
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
export const Layout = () => import('@/layout/Layout.vue')
|
export const Layout = () => import('@/layout/Layout.vue')
|
||||||
|
@ -41,6 +35,7 @@ export const getRawRoute = (route: RouteLocationNormalized): RouteLocationNormal
|
||||||
// 前端控制路由生成
|
// 前端控制路由生成
|
||||||
export const generateRoutesFn1 = (
|
export const generateRoutesFn1 = (
|
||||||
routes: AppRouteRecordRaw[],
|
routes: AppRouteRecordRaw[],
|
||||||
|
keys: string[],
|
||||||
basePath = '/'
|
basePath = '/'
|
||||||
): AppRouteRecordRaw[] => {
|
): AppRouteRecordRaw[] => {
|
||||||
const res: AppRouteRecordRaw[] = []
|
const res: AppRouteRecordRaw[] = []
|
||||||
|
@ -55,7 +50,6 @@ export const generateRoutesFn1 = (
|
||||||
let data: Nullable<AppRouteRecordRaw> = null
|
let data: Nullable<AppRouteRecordRaw> = null
|
||||||
|
|
||||||
let onlyOneChild: Nullable<string> = null
|
let onlyOneChild: Nullable<string> = null
|
||||||
|
|
||||||
if (route.children && route.children.length === 1 && !meta.alwaysShow) {
|
if (route.children && route.children.length === 1 && !meta.alwaysShow) {
|
||||||
onlyOneChild = (
|
onlyOneChild = (
|
||||||
isUrl(route.children[0].path)
|
isUrl(route.children[0].path)
|
||||||
|
@ -64,16 +58,14 @@ export const generateRoutesFn1 = (
|
||||||
) as string
|
) 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)
|
data = Object.assign({}, route)
|
||||||
} else {
|
} else {
|
||||||
const routePath = pathResolve(basePath, onlyOneChild || route.path)
|
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)
|
data = Object.assign({}, route)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +73,7 @@ export const generateRoutesFn1 = (
|
||||||
|
|
||||||
// recursive child routes
|
// recursive child routes
|
||||||
if (route.children && data) {
|
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) {
|
if (data) {
|
||||||
res.push(data as AppRouteRecordRaw)
|
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[] = []
|
const res: AppRouteRecordRaw[] = []
|
||||||
|
|
||||||
for (const route of routes) {
|
for (const route of routes) {
|
||||||
|
@ -102,15 +94,14 @@ export const generateRoutesFn2 = (routes: AppRouteRecordRaw[]): AppRouteRecordRa
|
||||||
meta: route.meta
|
meta: route.meta
|
||||||
}
|
}
|
||||||
if (route.component) {
|
if (route.component) {
|
||||||
const comModule =
|
const comModule = modules[`../${route.component}.vue`] || modules[`../${route.component}.tsx`]
|
||||||
modules[`../../${route.component}.vue`] || modules[`../../${route.component}.tsx`]
|
|
||||||
if (comModule) {
|
|
||||||
// 动态加载路由文件,可根据实际情况进行自定义逻辑
|
|
||||||
const component = route.component as string
|
const component = route.component as string
|
||||||
|
if (!comModule && !component.includes('#')) {
|
||||||
|
console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件,请创建`)
|
||||||
|
} else {
|
||||||
|
// 动态加载路由文件,可根据实际情况进行自定义逻辑
|
||||||
data.component =
|
data.component =
|
||||||
component === '#' ? Layout : component.includes('##') ? getParentLayout() : comModule
|
component === '#' ? Layout : component.includes('##') ? getParentLayout() : comModule
|
||||||
} else {
|
|
||||||
console.error(`未找到${route.component}.vue文件或${route.component}.tsx文件,请创建`)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// recursive child routes
|
// recursive child routes
|
||||||
|
@ -124,7 +115,7 @@ export const generateRoutesFn2 = (routes: AppRouteRecordRaw[]): AppRouteRecordRa
|
||||||
|
|
||||||
export const pathResolve = (parentPath: string, path: string) => {
|
export const pathResolve = (parentPath: string, path: string) => {
|
||||||
const childPath = path.startsWith('/') || !path ? path : `/${path}`
|
const childPath = path.startsWith('/') || !path ? path : `/${path}`
|
||||||
return `${parentPath}${childPath}`
|
return `${parentPath}${childPath}`.replace(/\/\//g, '/')
|
||||||
}
|
}
|
||||||
|
|
||||||
// 路由降级
|
// 路由降级
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { Table } from '@/components/Table'
|
||||||
|
import { getUserListApi } from '@/api/login'
|
||||||
|
import { UserType } from '@/api/login/types'
|
||||||
|
import { ref, h } from 'vue'
|
||||||
|
import { ElButton } from 'element-plus'
|
||||||
|
|
||||||
|
interface Params {
|
||||||
|
pageIndex?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const columns: TableColumn[] = [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
label: t('userDemo.index'),
|
||||||
|
type: 'index'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
label: t('userDemo.username')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'password',
|
||||||
|
label: t('userDemo.password')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'role',
|
||||||
|
label: t('userDemo.role')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: t('userDemo.remark'),
|
||||||
|
formatter: (row: UserType) => {
|
||||||
|
return h(
|
||||||
|
'span',
|
||||||
|
row.username === 'admin' ? t('userDemo.remarkMessage1') : t('userDemo.remarkMessage2')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
label: t('userDemo.action')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
let tableDataList = ref<UserType[]>([])
|
||||||
|
|
||||||
|
const getTableList = async (params?: Params) => {
|
||||||
|
const res = await getUserListApi({
|
||||||
|
params: params || {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
tableDataList.value = res.data.list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTableList()
|
||||||
|
|
||||||
|
const acitonFn = (data: TableSlotDefault) => {
|
||||||
|
console.log(data)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="t('userDemo.title')" :message="t('userDemo.message')">
|
||||||
|
<Table :columns="columns" :data="tableDataList" :loading="loading" :selection="false">
|
||||||
|
<template #action="data">
|
||||||
|
<ElButton type="primary" @click="acitonFn(data as TableSlotDefault)">
|
||||||
|
{{ t('tableDemo.action') }}
|
||||||
|
</ElButton>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
|
@ -0,0 +1,88 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ContentWrap } from '@/components/ContentWrap'
|
||||||
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
|
import { Table } from '@/components/Table'
|
||||||
|
import { getUserListApi } from '@/api/login'
|
||||||
|
import { UserType } from '@/api/login/types'
|
||||||
|
import { ref, h } from 'vue'
|
||||||
|
import { ElButton } from 'element-plus'
|
||||||
|
|
||||||
|
interface Params {
|
||||||
|
pageIndex?: number
|
||||||
|
pageSize?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
const columns: TableColumn[] = [
|
||||||
|
{
|
||||||
|
field: 'index',
|
||||||
|
label: t('userDemo.index'),
|
||||||
|
type: 'index'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'username',
|
||||||
|
label: t('userDemo.username')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'password',
|
||||||
|
label: t('userDemo.password')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'role',
|
||||||
|
label: t('userDemo.role')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'remark',
|
||||||
|
label: t('userDemo.remark'),
|
||||||
|
formatter: (row: UserType) => {
|
||||||
|
return h(
|
||||||
|
'span',
|
||||||
|
row.username === 'admin' ? t('userDemo.remarkMessage1') : t('userDemo.remarkMessage2')
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
label: t('userDemo.action')
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
let tableDataList = ref<UserType[]>([])
|
||||||
|
|
||||||
|
const getTableList = async (params?: Params) => {
|
||||||
|
const res = await getUserListApi({
|
||||||
|
params: params || {
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false
|
||||||
|
})
|
||||||
|
if (res) {
|
||||||
|
tableDataList.value = res.data.list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTableList()
|
||||||
|
|
||||||
|
const acitonFn = (data: TableSlotDefault) => {
|
||||||
|
console.log(data)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<ContentWrap :title="t('userDemo.title')" :message="t('userDemo.message')">
|
||||||
|
<Table :columns="columns" :data="tableDataList" :loading="loading" :selection="false">
|
||||||
|
<template #action="data">
|
||||||
|
<ElButton type="primary" @click="acitonFn(data as TableSlotDefault)">
|
||||||
|
{{ t('tableDemo.action') }}
|
||||||
|
</ElButton>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
</ContentWrap>
|
||||||
|
</template>
|
|
@ -5,7 +5,7 @@ import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
|
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import { useForm } from '@/hooks/web/useForm'
|
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 type { UserLoginType } from '@/api/login/types'
|
||||||
import { useCache } from '@/hooks/web/useCache'
|
import { useCache } from '@/hooks/web/useCache'
|
||||||
import { useAppStore } from '@/store/modules/app'
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
@ -126,15 +126,39 @@ const signIn = async () => {
|
||||||
if (res) {
|
if (res) {
|
||||||
const { wsCache } = useCache()
|
const { wsCache } = useCache()
|
||||||
wsCache.set(appStore.getUserInfo, res.data)
|
wsCache.set(appStore.getUserInfo, res.data)
|
||||||
await permissionStore.generateRoutes().catch(() => {})
|
|
||||||
|
getRole()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取角色信息
|
||||||
|
const getRole = async () => {
|
||||||
|
const { getFormData } = methods
|
||||||
|
const formData = await getFormData<UserLoginType>()
|
||||||
|
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) => {
|
permissionStore.getAddRouters.forEach((route) => {
|
||||||
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
addRoute(route as RouteRecordRaw) // 动态添加可访问路由表
|
||||||
})
|
})
|
||||||
permissionStore.setIsAddRouters(true)
|
permissionStore.setIsAddRouters(true)
|
||||||
// push({ path: redirect.value || permissionStore.addRouters[0].path })
|
push({ path: redirect.value || permissionStore.addRouters[0].path })
|
||||||
push({ path: permissionStore.addRouters[0].path })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -62,4 +62,13 @@ declare global {
|
||||||
props?: Recordable
|
props?: Recordable
|
||||||
fullPath?: string
|
fullPath?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare interface AppCustomRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
|
||||||
|
name: string
|
||||||
|
meta: RouteMeta
|
||||||
|
component: string
|
||||||
|
path: string
|
||||||
|
redirect: string
|
||||||
|
children?: AppCustomRouteRecordRaw[]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue