diff --git a/src/layouts/Layout/index.vue b/src/layouts/Layout/index.vue
index 86af8e67..3acf7710 100644
--- a/src/layouts/Layout/index.vue
+++ b/src/layouts/Layout/index.vue
@@ -1,7 +1,9 @@
-
+
+
+
diff --git a/src/router/routes/constant.ts b/src/router/routes/constant.ts
index b03b2665..d9ff75c3 100644
--- a/src/router/routes/constant.ts
+++ b/src/router/routes/constant.ts
@@ -1,5 +1,5 @@
import { getLoginModuleRegExp } from '@/utils';
-import type { LoginModuleKey } from '@/interface';
+import { LoginModuleKey } from '@/interface';
/** 固定的路由 */
const constantRoutes: AuthRoute.Route[] = [
@@ -23,7 +23,8 @@ const constantRoutes: AuthRoute.Route[] = [
},
meta: {
title: '登录',
- single: true
+ single: true,
+ singleOriginPath: '/login'
}
},
{
diff --git a/src/styles/css/global.css b/src/styles/css/global.css
index f92e90b2..1c332b65 100644
--- a/src/styles/css/global.css
+++ b/src/styles/css/global.css
@@ -1,4 +1,5 @@
@import './scrollbar.css';
+@import './transition.css';
html, body, #app {
height: 100%;
diff --git a/src/styles/css/transition.css b/src/styles/css/transition.css
new file mode 100644
index 00000000..535d477a
--- /dev/null
+++ b/src/styles/css/transition.css
@@ -0,0 +1,13 @@
+/* fade-slide */
+.fade-slide-leave-active,
+.fade-slide-enter-active {
+ transition: all 0.3s;
+}
+.fade-slide-enter-from {
+ opacity: 0;
+ transform: translateX(-30px);
+}
+.fade-slide-leave-to {
+ opacity: 0;
+ transform: translateX(30px);
+}
diff --git a/src/typings/common/route.d.ts b/src/typings/common/route.d.ts
index 0db524da..40b0d2d0 100644
--- a/src/typings/common/route.d.ts
+++ b/src/typings/common/route.d.ts
@@ -18,15 +18,11 @@ declare namespace AuthRoute {
| 'multi-menu_first_second'
| 'about';
- /** 路由Key转换路由Path */
- type KeyToPath = Key extends `${infer Left}_${infer Right}`
- ? KeyToPath<`${Left}/${Right}`>
- : `/${Key}`;
-
/** 路由路径 */
type RoutePath =
| '/'
| Exclude, '/root' | '/redirect'>
+ | SingleRouteParentPath
| Key
| '/:path(.*)*'
| '/:pathMatch(.*)*';
@@ -61,6 +57,8 @@ declare namespace AuthRoute {
hide?: boolean;
/** 是否作为单独的路由(作为菜单时只有自身,没有子菜单) */
single?: boolean;
+ /** 作为单独的路由且path为动态path的原始path */
+ singleOriginPath?: SingleRoutePath;
/** 路由顺序,可用于菜单的排序 */
order?: number;
};
@@ -91,4 +89,27 @@ declare namespace AuthRoute {
/** 属性 */
props?: boolean | Record | ((to: any) => Record);
}
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ type GetMultiRouteParentKey = Key extends `${infer Left}_${infer Right}` ? Left : never;
+
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ type GetSingleRouteKey = Key extends `${infer Left}_${infer Right}` ? never : Key;
+
+ /** 单独一级路由的key (单独路由需要添加一个父路由用于应用布局组件) */
+ type SingleRouteKey = Exclude<
+ GetSingleRouteKey,
+ GetMultiRouteParentKey | 'root' | 'redirect-not-found'
+ >;
+
+ /** 单独路由需要添加一个父路由用于应用布局组件 */
+ type SingleRouteParentKey = `${SingleRouteKey}-parent`;
+
+ /** 路由key转换路由path */
+ type KeyToPath = Key extends `${infer Left}_${infer Right}`
+ ? KeyToPath<`${Left}/${Right}`>
+ : `/${Key}`;
+
+ type SingleRoutePath = KeyToPath;
+ type SingleRouteParentPath = KeyToPath;
}
diff --git a/src/utils/router/component.ts b/src/utils/router/component.ts
index 5b8fcc1f..3d4b15e4 100644
--- a/src/utils/router/component.ts
+++ b/src/utils/router/component.ts
@@ -47,7 +47,7 @@ export function getViewComponent(routeKey: AuthRoute.RouteKey) {
'redirect-not-found': NotFound
};
- return () => setViewComponentName(viewComponent[key], key);
+ return () => setViewComponentName(viewComponent[key], key) as Promise;
}
/** 给页面组件设置名称 */
diff --git a/src/utils/router/helpers.ts b/src/utils/router/helpers.ts
index 5645acfd..926402dd 100644
--- a/src/utils/router/helpers.ts
+++ b/src/utils/router/helpers.ts
@@ -9,11 +9,11 @@ type ComponentAction = {
/** 将权限路由类型转换成vue路由类型 */
export function transformAuthRouteToVueRoute(item: AuthRoute.Route) {
- const { name, path } = item;
+ const { name, path, meta } = item;
const itemRoute: Partial = {
name,
path,
- meta: item.meta
+ meta
};
if (hasRedirect(item)) {
itemRoute.redirect = item.redirect;
@@ -41,21 +41,40 @@ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) {
}
}
- if (hasProps(item) && !isSingleRoute(item)) {
+ if (hasProps(item)) {
(itemRoute as any).props = item.props;
}
if (isSingleRoute(item)) {
- itemRoute.children = [
- {
- path: '',
- name: item.name,
- component: getViewComponent(item.name),
- props: hasProps(item) ? item.props : undefined
- }
- ];
- } else if (hasChildren(item)) {
- itemRoute.children = item.children!.map(child => transformAuthRouteToVueRoute(child));
+ if (item.name === 'redirect-not-found') {
+ itemRoute.children = [
+ {
+ path: '',
+ component: getViewComponent('redirect-not-found')
+ }
+ ];
+ return itemRoute as RouteRecordRaw;
+ }
+ const singleRoute = {
+ ...itemRoute
+ };
+ Object.assign(singleRoute, { component: getViewComponent(item.name) });
+
+ const singlePath = (
+ hasSingleOriginPath(item) ? item.meta.singleOriginPath : item.path
+ ) as AuthRoute.SingleRoutePath;
+ const parenPath = `${singlePath}-parent` as AuthRoute.SingleRouteParentPath;
+
+ const parentRoute: Partial = {
+ path: parenPath,
+ component: itemRoute.component,
+ redirect: singlePath,
+ children: [singleRoute as RouteRecordRaw]
+ };
+ return parentRoute as RouteRecordRaw;
+ }
+ if (hasChildren(item)) {
+ itemRoute.children = item.children!.map(child => transformAuthRouteToVueRoute(child)) as RouteRecordRaw[];
}
return itemRoute as RouteRecordRaw;
@@ -81,6 +100,10 @@ function isSingleRoute(item: AuthRoute.Route) {
return Boolean(item.meta.single);
}
+function hasSingleOriginPath(item: AuthRoute.Route) {
+ return Boolean(item.meta.singleOriginPath);
+}
+
/**
* 根据路由key获取AuthRoute数据
* @param key - 路由key
diff --git a/src/views/system/exception/403.vue b/src/views/system/exception/403.vue
index a49ec556..d77f1a3a 100644
--- a/src/views/system/exception/403.vue
+++ b/src/views/system/exception/403.vue
@@ -1,5 +1,5 @@
-
+ 403
diff --git a/src/views/system/exception/500.vue b/src/views/system/exception/500.vue
index 37e5be1e..d8396bbf 100644
--- a/src/views/system/exception/500.vue
+++ b/src/views/system/exception/500.vue
@@ -1,5 +1,5 @@
- NotFound
+ 500
diff --git a/src/views/system/login/components/PwdLogin/index.vue b/src/views/system/login/components/PwdLogin/index.vue
index b91e59f0..e012c37b 100644
--- a/src/views/system/login/components/PwdLogin/index.vue
+++ b/src/views/system/login/components/PwdLogin/index.vue
@@ -9,7 +9,7 @@
记住我
- 忘记密码?
+ 忘记密码?
{{ activeModule.label }}
-
+