diff --git a/.env b/.env
index b48df03..77ad0d3 100644
--- a/.env
+++ b/.env
@@ -5,7 +5,7 @@ VITE_APP_NAME=Nova - Admin
# 路由模式
VITE_ROUTE_MODE = web
# 权限路由模式: static | dynamic
-VITE_AUTH_ROUTE_MODE=static
+VITE_AUTH_ROUTE_MODE=dynamic
# 设置登陆后跳转地址
VITE_HOME_PATH = /dashboard/workbench
diff --git a/src/router/routes.static.ts b/src/router/routes.static.ts
index 9971d0a..2acfc26 100644
--- a/src/router/routes.static.ts
+++ b/src/router/routes.static.ts
@@ -5,6 +5,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '仪表盘',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:analysis',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 1,
'pid': null,
@@ -16,6 +17,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:alarm',
'meta.pinTab': true,
+ 'meta.menuType': 'page',
'componentPath': '/dashboard/workbench/index.vue',
'id': 2,
'pid': 1,
@@ -26,6 +28,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '监控页',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:anchor',
+ 'meta.menuType': 'page',
'componentPath': '/dashboard/monitor/index.vue',
'id': 3,
'pid': 1,
@@ -36,6 +39,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '多级菜单演示',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:list',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 4,
'pid': null,
@@ -46,6 +50,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '多级菜单子页',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:list',
+ 'meta.menuType': 'page',
'componentPath': '/test/test2/index.vue',
'id': 6,
'pid': 4,
@@ -58,6 +63,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.icon': 'icon-park-outline:list',
'meta.hide': true,
'meta.activeMenu': '/test/test2',
+ 'meta.menuType': 'page',
'componentPath': '/test/test2/detail/index.vue',
'id': 7,
'pid': 4,
@@ -68,6 +74,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '多级菜单',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:list',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 8,
'pid': 4,
@@ -88,6 +95,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '列表页',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:list-two',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 10,
'pid': null,
@@ -118,6 +126,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '功能示例',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:application-one',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 13,
'pid': null,
@@ -159,6 +168,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '编辑器',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:editor',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 18,
'pid': 13,
@@ -219,6 +229,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '外链文档',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:file-doc',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 24,
'pid': null,
@@ -260,6 +271,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '权限',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:people-safe',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 28,
'pid': null,
@@ -293,6 +305,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '异常页',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:error-computer',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 31,
'pid': null,
@@ -336,6 +349,7 @@ export const staticRoutes: AppRoute.RowRoute[] = [
'meta.title': '系统设置',
'meta.requiresAuth': true,
'meta.icon': 'icon-park-outline:setting',
+ 'meta.menuType': 'dir',
'componentPath': null,
'id': 35,
'pid': null,
diff --git a/src/service/api/login.ts b/src/service/api/login.ts
index 59b41b4..09bd04b 100644
--- a/src/service/api/login.ts
+++ b/src/service/api/login.ts
@@ -1,7 +1,7 @@
import { request } from '../http'
interface Ilogin {
- username: string
+ userName: string
password: string
}
diff --git a/src/store/auth.ts b/src/store/auth.ts
index ff66f27..8605590 100644
--- a/src/store/auth.ts
+++ b/src/store/auth.ts
@@ -52,8 +52,8 @@ export const useAuthStore = defineStore('auth-store', {
},
/* 用户登录 */
- async login(username: string, password: string) {
- const { isSuccess, data } = await fetchLogin({ username, password })
+ async login(userName: string, password: string) {
+ const { isSuccess, data } = await fetchLogin({ userName, password })
if (!isSuccess) {
window.$message.error('登录失败,请检查用户名和密码')
return
diff --git a/src/store/route.ts b/src/store/route.ts
index 4274b88..316172e 100644
--- a/src/store/route.ts
+++ b/src/store/route.ts
@@ -72,7 +72,7 @@ export const useRouteStore = defineStore('route-store', {
id: item.id,
pid: item.pid,
label:
- (!item.children || item.children.length === 0)
+ (!item.meta.menuType || item.meta.menuType === 'page')
? () =>
h(
RouterLink,
@@ -83,36 +83,13 @@ export const useRouteStore = defineStore('route-store', {
},
{ default: () => $t(`route.${String(item.name)}`, item.meta.title) },
)
- : $t(`route.${String(item.name)}`, item.meta.title),
+ : () => $t(`route.${String(item.name)}`, item.meta.title),
key: item.path,
icon: item.meta.icon ? renderIcon(item.meta.icon) : undefined,
}
return target
})
},
- setRedirect(routes: AppRoute.Route[]) {
- routes.forEach((route) => {
- if (route.children) {
- if (!route.redirect) {
- // 过滤出没有隐藏的子元素集
- const visibleChilds = route.children.filter(child => !child.meta.hide)
-
- // 过滤出含有order属性的页面
- const orderChilds = visibleChilds.filter(child => child.meta.order)
-
- // 重定向页默认第一个子元素的路径
- let target = route.children[0]
- if (orderChilds.length > 0)
- // 有order则取最小者重定向
- target = min(orderChilds, i => i.meta.order as number) as AppRoute.Route
-
- route.redirect = target.path
- }
-
- this.setRedirect(route.children)
- }
- })
- },
createRoutes(routes: AppRoute.RowRoute[]) {
const { hasPermission } = usePermission()
// 结构化meta字段
@@ -128,14 +105,19 @@ export const useRouteStore = defineStore('route-store', {
// 生成路由,有redirect的不需要引入文件
const modules = import.meta.glob('@/views/**/*.vue')
- resultRouter = resultRouter.map((item: any) => {
+ resultRouter = resultRouter.map((item: AppRoute.Route) => {
if (item.componentPath && !item.redirect)
item.component = modules[`/src/views${item.componentPath}`]
+
+ // 判断是否是目录,代表目录的路由没有实际页面
+ if (item.meta.menuType === 'dir')
+ item.redirect = '/404'
+
return item
})
+ // 生成路由表
resultRouter = arrayToTree(resultRouter) as AppRoute.Route[]
- this.setRedirect(resultRouter)
const appRootRoute: RouteRecordRaw = {
path: '/appRoot',
name: 'appRoot',
diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts
index 337f3ca..e561316 100644
--- a/src/typings/api.d.ts
+++ b/src/typings/api.d.ts
@@ -7,7 +7,7 @@ declare namespace ApiAuth {
/** 用户id */
id: number
/** 用户名 */
- username: string
+ userName: string
/* 用户头像 */
avatar?: string
/* 用户邮箱 */
diff --git a/src/typings/route.d.ts b/src/typings/route.d.ts
index 85c4a22..7b89166 100644
--- a/src/typings/route.d.ts
+++ b/src/typings/route.d.ts
@@ -23,10 +23,10 @@ declare namespace AppRoute {
withoutTab?: boolean
/** 当前路由是否会被固定在Tab中,用于一些常驻页面 */
pinTab?: boolean
- /** 当前路由i18n标识 */
- i18nKey?: string
+ /** 当前路由在左侧菜单是目录还是页面,不设置默认为page */
+ menuType?: 'dir' | 'page'
}
- /** 单个路由的类型结构(动态路由模式:后端返回此类型结构的路由) */
+
interface baseRoute {
/** 路由名称(路由唯一标识) */
name: string
@@ -42,6 +42,7 @@ declare namespace AppRoute {
pid: number | null
}
+ /** 单个路由的类型结构(动态路由模式:后端返回此类型结构的路由) */
type RowRoute = {
[K in keyof RouteMeta as `meta.${K}`]?: RouteMeta[K]
} & baseRoute
diff --git a/src/views/userCenter/index.vue b/src/views/userCenter/index.vue
index 7e440ae..33c7e1e 100644
--- a/src/views/userCenter/index.vue
+++ b/src/views/userCenter/index.vue
@@ -52,7 +52,7 @@ function handleValidateClick() {
{{ userInfo?.id }}
- {{ userInfo?.username }}
+ {{ userInfo?.userName }}
{{ userInfo?.nickname }}