mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
refactor(projects): 精简版+动态路由权限初步
This commit is contained in:
@ -1,319 +0,0 @@
|
||||
import type { RouteKey } from '@/interface';
|
||||
|
||||
interface RouteConst {
|
||||
/** 路由名称 */
|
||||
name: RouteKey;
|
||||
/** 路由路径 */
|
||||
path: string;
|
||||
/** 路由标题 */
|
||||
title: string;
|
||||
}
|
||||
|
||||
/** 声明的路由名称、路径和标题 */
|
||||
const routeConstMap = new Map<RouteKey, RouteConst>([
|
||||
[
|
||||
'root',
|
||||
{
|
||||
name: 'root',
|
||||
path: '/',
|
||||
title: 'Root'
|
||||
}
|
||||
],
|
||||
[
|
||||
'login',
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
title: '登录'
|
||||
}
|
||||
],
|
||||
[
|
||||
'no-permission',
|
||||
{
|
||||
name: 'no-permission',
|
||||
path: '/403',
|
||||
title: '无权限'
|
||||
}
|
||||
],
|
||||
[
|
||||
'not-found',
|
||||
{
|
||||
name: 'not-found',
|
||||
path: '/404',
|
||||
title: '未找到'
|
||||
}
|
||||
],
|
||||
[
|
||||
'service-error',
|
||||
{
|
||||
name: 'service-error',
|
||||
path: '/500',
|
||||
title: '服务器错误'
|
||||
}
|
||||
],
|
||||
[
|
||||
'dashboard',
|
||||
{
|
||||
name: 'dashboard',
|
||||
path: '/dashboard',
|
||||
title: '仪表盘'
|
||||
}
|
||||
],
|
||||
[
|
||||
'dashboard_analysis',
|
||||
{
|
||||
name: 'dashboard_analysis',
|
||||
path: '/dashboard/analysis',
|
||||
title: '分析页'
|
||||
}
|
||||
],
|
||||
[
|
||||
'dashboard_workbench',
|
||||
{
|
||||
name: 'dashboard_workbench',
|
||||
path: '/dashboard/workbench',
|
||||
title: '工作台'
|
||||
}
|
||||
],
|
||||
[
|
||||
'document',
|
||||
{
|
||||
name: 'document',
|
||||
path: '/document',
|
||||
title: '文档'
|
||||
}
|
||||
],
|
||||
[
|
||||
'document_vue',
|
||||
{
|
||||
name: 'document_vue',
|
||||
path: '/document/vue',
|
||||
title: 'vue文档'
|
||||
}
|
||||
],
|
||||
[
|
||||
'document_vite',
|
||||
{
|
||||
name: 'document_vite',
|
||||
path: '/document/vite',
|
||||
title: 'vite文档'
|
||||
}
|
||||
],
|
||||
[
|
||||
'document_naive',
|
||||
{
|
||||
name: 'document_naive',
|
||||
path: '/document/naive',
|
||||
title: 'naive文档'
|
||||
}
|
||||
],
|
||||
[
|
||||
'document_project',
|
||||
{
|
||||
name: 'document_project',
|
||||
path: 'https://docs.soybean.pro/',
|
||||
title: '项目文档(外链)'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin',
|
||||
{
|
||||
name: 'plugin',
|
||||
path: '/plugins',
|
||||
title: '插件示例'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_map',
|
||||
{
|
||||
name: 'plugin_map',
|
||||
path: '/plugin/map',
|
||||
title: '地图'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_video',
|
||||
{
|
||||
name: 'plugin_video',
|
||||
path: '/plugin/video',
|
||||
title: '视频'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_editor',
|
||||
{
|
||||
name: 'plugin_editor',
|
||||
path: '/plugin/editor',
|
||||
title: '编辑器'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_editor_quill',
|
||||
{
|
||||
name: 'plugin_editor_quill',
|
||||
path: '/plugin/editor/quill',
|
||||
title: '富文本编辑器'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_editor_markdown',
|
||||
{
|
||||
name: 'plugin_editor_markdown',
|
||||
path: '/plugin/editor/markdown',
|
||||
title: 'markdown编辑器'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_swiper',
|
||||
{
|
||||
name: 'plugin_swiper',
|
||||
path: '/plugin/swiper',
|
||||
title: 'Swiper插件'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_copy',
|
||||
{
|
||||
name: 'plugin_copy',
|
||||
path: '/plugin/copy',
|
||||
title: '剪贴板'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_icon',
|
||||
{
|
||||
name: 'plugin_icon',
|
||||
path: '/plugin/icon',
|
||||
title: '图标'
|
||||
}
|
||||
],
|
||||
[
|
||||
'plugin_print',
|
||||
{
|
||||
name: 'plugin_print',
|
||||
path: '/plugin/print',
|
||||
title: '打印'
|
||||
}
|
||||
],
|
||||
[
|
||||
'component',
|
||||
{
|
||||
name: 'component',
|
||||
path: '/component',
|
||||
title: '组件示例'
|
||||
}
|
||||
],
|
||||
[
|
||||
'component_button',
|
||||
{
|
||||
name: 'component_button',
|
||||
path: '/component/button',
|
||||
title: '按钮'
|
||||
}
|
||||
],
|
||||
[
|
||||
'component_card',
|
||||
{
|
||||
name: 'component_card',
|
||||
path: '/component/card',
|
||||
title: '卡片'
|
||||
}
|
||||
],
|
||||
[
|
||||
'component_table',
|
||||
{
|
||||
name: 'component_table',
|
||||
path: '/component/table',
|
||||
title: '表格'
|
||||
}
|
||||
],
|
||||
[
|
||||
'multi-menu',
|
||||
{
|
||||
name: 'multi-menu',
|
||||
path: '/multi-menu',
|
||||
title: '多级菜单'
|
||||
}
|
||||
],
|
||||
[
|
||||
'multi-menu_first',
|
||||
{
|
||||
name: 'multi-menu_first',
|
||||
path: '/multi-menu/first',
|
||||
title: '一级菜单'
|
||||
}
|
||||
],
|
||||
[
|
||||
'multi-menu_first_second',
|
||||
{
|
||||
name: 'multi-menu_first_second',
|
||||
path: '/multi-menu/first/second',
|
||||
title: '二级菜单'
|
||||
}
|
||||
],
|
||||
[
|
||||
'exception',
|
||||
{
|
||||
name: 'exception',
|
||||
path: '/exception',
|
||||
title: '异常页'
|
||||
}
|
||||
],
|
||||
[
|
||||
'exception_403',
|
||||
{
|
||||
name: 'exception_403',
|
||||
path: '/exception/403',
|
||||
title: '异常页-403'
|
||||
}
|
||||
],
|
||||
[
|
||||
'exception_404',
|
||||
{
|
||||
name: 'exception_404',
|
||||
path: '/exception/404',
|
||||
title: '异常页-404'
|
||||
}
|
||||
],
|
||||
[
|
||||
'exception_500',
|
||||
{
|
||||
name: 'exception_500',
|
||||
path: '/exception/500',
|
||||
title: '异常页-500'
|
||||
}
|
||||
],
|
||||
[
|
||||
'about',
|
||||
{
|
||||
name: 'about',
|
||||
path: '/about',
|
||||
title: '关于'
|
||||
}
|
||||
],
|
||||
[
|
||||
'website',
|
||||
{
|
||||
name: 'website',
|
||||
path: '/website',
|
||||
title: '网址导航'
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
||||
/** 获取路由的声明(name、path、title) */
|
||||
export function getRouteConst(key: RouteKey) {
|
||||
return routeConstMap.get(key)!;
|
||||
}
|
||||
/** 路由名称 */
|
||||
export function routeName(key: RouteKey) {
|
||||
return routeConstMap.get(key)!.name;
|
||||
}
|
||||
/** 路由路径 */
|
||||
export function routePath(key: RouteKey) {
|
||||
return routeConstMap.get(key)!.path;
|
||||
}
|
||||
/** 路由标题 */
|
||||
export function routeTitle(key: RouteKey) {
|
||||
return routeConstMap.get(key)!.title;
|
||||
}
|
@ -1,27 +1,29 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { useTitle } from '@vueuse/core';
|
||||
import { useAppStore } from '@/store';
|
||||
import { handlePagePermission } from './permission';
|
||||
import { useRouteStore } from '@/store';
|
||||
|
||||
/**
|
||||
* 路由守卫函数
|
||||
* @param router - 路由实例
|
||||
*/
|
||||
export function createRouterGuide(router: Router) {
|
||||
const { resetScrollBehavior } = useAppStore();
|
||||
const routeStore = useRouteStore();
|
||||
const { initDynamicRoute } = useRouteStore();
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
if (!routeStore.isAddedDynamicRoute) {
|
||||
await initDynamicRoute(router);
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// 开始 loadingBar
|
||||
window.$loadingBar?.start();
|
||||
// 页面跳转逻辑
|
||||
handlePagePermission(to, from, next);
|
||||
next();
|
||||
});
|
||||
router.afterEach(to => {
|
||||
// 设置document title
|
||||
useTitle(to.meta.title as string);
|
||||
useTitle(to.meta.title);
|
||||
// 结束 loadingBar
|
||||
window.$loadingBar?.finish();
|
||||
// 重置滚动条行为
|
||||
resetScrollBehavior();
|
||||
});
|
||||
}
|
||||
|
@ -1,56 +1 @@
|
||||
import type { RouteLocationNormalized, NavigationGuardNext } from 'vue-router';
|
||||
import { routeName } from '@/router';
|
||||
import { getToken } from '@/utils';
|
||||
|
||||
type RouterAction = [boolean, () => void];
|
||||
|
||||
/** 处理页面的权限 */
|
||||
export function handlePagePermission(
|
||||
to: RouteLocationNormalized,
|
||||
from: RouteLocationNormalized,
|
||||
next: NavigationGuardNext
|
||||
) {
|
||||
const token = getToken();
|
||||
const isLogin = Boolean(token);
|
||||
const needLogin = Boolean(to.meta?.requiresAuth);
|
||||
|
||||
const routerAction: RouterAction[] = [
|
||||
// 已登录状态跳转登录页,跳转至首页
|
||||
[
|
||||
isLogin && to.name === routeName('login'),
|
||||
() => {
|
||||
next({ name: routeName('root') });
|
||||
}
|
||||
],
|
||||
// 不需要登录权限的页面直接通行
|
||||
[
|
||||
!needLogin,
|
||||
() => {
|
||||
next();
|
||||
}
|
||||
],
|
||||
// 未登录状态进入需要登录权限的页面
|
||||
[
|
||||
!isLogin && needLogin,
|
||||
() => {
|
||||
const redirect = to.fullPath;
|
||||
next({ name: routeName('login'), query: { redirect } });
|
||||
}
|
||||
],
|
||||
// 登录状态进入需要登录权限的页面,直接通行
|
||||
[
|
||||
isLogin && needLogin,
|
||||
() => {
|
||||
next();
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
routerAction.some(item => {
|
||||
const [flag, callback] = item;
|
||||
if (flag) {
|
||||
callback();
|
||||
}
|
||||
return flag;
|
||||
});
|
||||
}
|
||||
export default {};
|
||||
|
@ -1,3 +1,18 @@
|
||||
export * from './constant';
|
||||
export * from './routes';
|
||||
export * from './setup';
|
||||
import type { App } from 'vue';
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import { routes, constantRoutes } from './routes';
|
||||
import { createRouterGuide } from './guard';
|
||||
|
||||
export const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
routes,
|
||||
scrollBehavior: () => ({ left: 0, top: 0 })
|
||||
});
|
||||
|
||||
export async function setupRouter(app: App) {
|
||||
app.use(router);
|
||||
createRouterGuide(router);
|
||||
await router.isReady();
|
||||
}
|
||||
|
||||
export { constantRoutes };
|
||||
|
@ -1,29 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { setSingleRoute } from '@/utils';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import { About } from '@/views';
|
||||
import { getRouteConst, routeName } from '../constant';
|
||||
|
||||
const { name, path, title } = getRouteConst('about');
|
||||
|
||||
const about: RouteRecordRaw = setSingleRoute({
|
||||
route: {
|
||||
name,
|
||||
path,
|
||||
component: About,
|
||||
meta: {
|
||||
title,
|
||||
requiresAuth: true,
|
||||
keepAlive: true,
|
||||
icon: 'fluent:book-information-24-regular'
|
||||
}
|
||||
},
|
||||
container: BasicLayout,
|
||||
containerMeta: {
|
||||
title,
|
||||
order: 7
|
||||
},
|
||||
notFoundName: routeName('not-found')
|
||||
});
|
||||
|
||||
export default about;
|
@ -1,50 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import { ComponentButton, ComponentCard, ComponentTable } from '@/views';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const component: RouteRecordRaw = {
|
||||
name: routeName('component'),
|
||||
path: routePath('component'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('component_button') },
|
||||
meta: {
|
||||
title: routeTitle('component'),
|
||||
icon: 'fluent:app-store-24-regular',
|
||||
order: 4
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('component_button'),
|
||||
path: routePath('component_button'),
|
||||
component: ComponentButton,
|
||||
meta: {
|
||||
title: routeTitle('component_button'),
|
||||
requiresAuth: true,
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('component_card'),
|
||||
path: routePath('component_card'),
|
||||
component: ComponentCard,
|
||||
meta: {
|
||||
title: routeTitle('component_card'),
|
||||
requiresAuth: true,
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('component_table'),
|
||||
path: routePath('component_table'),
|
||||
component: ComponentTable,
|
||||
meta: {
|
||||
title: routeTitle('component_table'),
|
||||
requiresAuth: true,
|
||||
keepAlive: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default component;
|
@ -1,40 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import { DashboardAnalysis, DashboardWorkbench } from '@/views';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const dashboard: RouteRecordRaw = {
|
||||
name: routeName('dashboard'),
|
||||
path: routePath('dashboard'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('dashboard_analysis') },
|
||||
meta: {
|
||||
title: routeTitle('dashboard'),
|
||||
icon: 'carbon:dashboard',
|
||||
order: 1
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('dashboard_analysis'),
|
||||
path: routePath('dashboard_analysis'),
|
||||
component: DashboardAnalysis,
|
||||
meta: {
|
||||
keepAlive: true,
|
||||
requiresAuth: true,
|
||||
title: routeTitle('dashboard_analysis')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('dashboard_workbench'),
|
||||
path: routePath('dashboard_workbench'),
|
||||
component: DashboardWorkbench,
|
||||
meta: {
|
||||
keepAlive: true,
|
||||
requiresAuth: true,
|
||||
title: routeTitle('dashboard_workbench')
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default dashboard;
|
@ -1,62 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout, BlankLayout } from '@/layouts';
|
||||
import { DocumentVue, DocumentVite, DocumentNaive } from '@/views';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const document: RouteRecordRaw = {
|
||||
name: routeName('document'),
|
||||
path: routePath('document'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('document_vue') },
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('document'),
|
||||
icon: 'carbon:document',
|
||||
order: 2
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('document_vue'),
|
||||
path: routePath('document_vue'),
|
||||
component: DocumentVue,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('document_vue'),
|
||||
fullPage: true,
|
||||
keepAlive: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('document_vite'),
|
||||
path: routePath('document_vite'),
|
||||
component: DocumentVite,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('document_vite'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('document_naive'),
|
||||
path: routePath('document_naive'),
|
||||
component: DocumentNaive,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('document_naive'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('document_project'),
|
||||
path: routePath('document_project'),
|
||||
component: BlankLayout,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('document_project'),
|
||||
fullPage: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default document;
|
@ -1,51 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import { NoPermission, NotFound, ServiceError } from '@/views';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const exception: RouteRecordRaw = {
|
||||
name: routeName('exception'),
|
||||
path: routePath('exception'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('exception_403') },
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('exception'),
|
||||
icon: 'ant-design:exception-outlined',
|
||||
order: 5
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('exception_403'),
|
||||
path: routePath('exception_403'),
|
||||
component: NoPermission,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('exception_403'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('exception_404'),
|
||||
path: routePath('exception_404'),
|
||||
component: NotFound,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('exception_404'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('exception_500'),
|
||||
path: routePath('exception_500'),
|
||||
component: ServiceError,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('exception_500'),
|
||||
fullPage: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default exception;
|
@ -1,8 +0,0 @@
|
||||
import { transformRouteModules } from '@/utils';
|
||||
import type { ImportedRouteModules } from '@/interface';
|
||||
|
||||
const modules = import.meta.globEager('./*.ts') as ImportedRouteModules;
|
||||
|
||||
const customRoutes = transformRouteModules(modules);
|
||||
|
||||
export default customRoutes;
|
@ -1,41 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import MultiMenuFirstSecond from '@/views/multi-menu/first/second/index.vue';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const multiMenu: RouteRecordRaw = {
|
||||
name: routeName('multi-menu'),
|
||||
path: routePath('multi-menu'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('multi-menu_first') },
|
||||
meta: {
|
||||
title: routeTitle('multi-menu'),
|
||||
icon: 'carbon:menu',
|
||||
order: 6
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('multi-menu_first'),
|
||||
path: routePath('multi-menu_first'),
|
||||
redirect: { name: routeName('multi-menu_first_second') },
|
||||
meta: {
|
||||
title: routeTitle('multi-menu_first')
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('multi-menu_first_second'),
|
||||
path: routePath('multi-menu_first_second'),
|
||||
component: MultiMenuFirstSecond,
|
||||
meta: {
|
||||
title: routeTitle('multi-menu_first_second'),
|
||||
requiresAuth: true,
|
||||
keepAlive: true,
|
||||
fullPage: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default multiMenu;
|
@ -1,118 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BasicLayout } from '@/layouts';
|
||||
import {
|
||||
PluginMap,
|
||||
PluginVideo,
|
||||
PluginEditorQuill,
|
||||
PluginEditorMarkdown,
|
||||
PluginSwiper,
|
||||
PluginCopy,
|
||||
PluginIcon,
|
||||
PluginPrint
|
||||
} from '@/views';
|
||||
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
|
||||
const plugin: RouteRecordRaw = {
|
||||
name: routeName('plugin'),
|
||||
path: routePath('plugin'),
|
||||
component: BasicLayout,
|
||||
redirect: { name: routeName('plugin_map') },
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin'),
|
||||
icon: 'clarity:plugin-line',
|
||||
order: 3
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('plugin_map'),
|
||||
path: routePath('plugin_map'),
|
||||
component: PluginMap,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_map'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_video'),
|
||||
path: routePath('plugin_video'),
|
||||
component: PluginVideo,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_video'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_editor'),
|
||||
path: routePath('plugin_editor'),
|
||||
redirect: { name: routeName('plugin_editor_quill') },
|
||||
meta: {
|
||||
title: routeTitle('plugin_editor')
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: routeName('plugin_editor_quill'),
|
||||
path: routePath('plugin_editor_quill'),
|
||||
component: PluginEditorQuill,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_editor_quill'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_editor_markdown'),
|
||||
path: routePath('plugin_editor_markdown'),
|
||||
component: PluginEditorMarkdown,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_editor_markdown'),
|
||||
fullPage: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_swiper'),
|
||||
path: routePath('plugin_swiper'),
|
||||
component: PluginSwiper,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_swiper')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_copy'),
|
||||
path: routePath('plugin_copy'),
|
||||
component: PluginCopy,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_copy'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_icon'),
|
||||
path: routePath('plugin_icon'),
|
||||
component: PluginIcon,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_icon')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: routeName('plugin_print'),
|
||||
path: routePath('plugin_print'),
|
||||
component: PluginPrint,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
title: routeTitle('plugin_print')
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default plugin;
|
@ -1,28 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { setSingleRoute } from '@/utils';
|
||||
import { BlankLayout } from '@/layouts';
|
||||
import { Website } from '@/views';
|
||||
import { getRouteConst, routeName } from '../constant';
|
||||
|
||||
const { name, path, title } = getRouteConst('website');
|
||||
|
||||
const website: RouteRecordRaw = setSingleRoute({
|
||||
route: {
|
||||
name,
|
||||
path,
|
||||
component: Website,
|
||||
meta: {
|
||||
title,
|
||||
icon: 'codicon:remote-explorer',
|
||||
notAsMenu: true
|
||||
}
|
||||
},
|
||||
container: BlankLayout,
|
||||
containerMeta: {
|
||||
title,
|
||||
order: 8
|
||||
},
|
||||
notFoundName: routeName('not-found')
|
||||
});
|
||||
|
||||
export default website;
|
@ -1,85 +0,0 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { BlankLayout } from '@/layouts';
|
||||
import type { LoginModuleType } from '@/interface';
|
||||
import { Login, NoPermission, NotFound, ServiceError } from '@/views';
|
||||
import { getLoginModuleRegExp } from '@/utils';
|
||||
import { routeName, routePath, routeTitle } from '../constant';
|
||||
import { ROUTE_HOME_NAME } from './route-home';
|
||||
|
||||
/**
|
||||
* 固定不变的路由
|
||||
* @description !最后一项重定向未找到的路由须放置路由的最后一项
|
||||
*/
|
||||
const constantRoutes: RouteRecordRaw[] = [
|
||||
{
|
||||
name: routeName('root'),
|
||||
path: routePath('root'),
|
||||
redirect: { name: ROUTE_HOME_NAME }
|
||||
},
|
||||
{
|
||||
// 名称、路径随意,不在路由声明里面,只是为各个子路由充当应用BlankLayout布局的桥梁,因此访问该路由时重定向到404
|
||||
name: 'constant-single_',
|
||||
path: '/constant-single_',
|
||||
component: BlankLayout,
|
||||
redirect: { name: routeName('not-found') },
|
||||
meta: {
|
||||
title: 'constant-single_',
|
||||
keepAlive: true
|
||||
},
|
||||
children: [
|
||||
// 登录
|
||||
{
|
||||
name: routeName('login'),
|
||||
path: `${routePath('login')}/:module(${getLoginModuleRegExp()})?`,
|
||||
component: Login,
|
||||
props: route => {
|
||||
const moduleType = (route.params.module as LoginModuleType) || 'pwd-login';
|
||||
return {
|
||||
module: moduleType
|
||||
};
|
||||
},
|
||||
meta: {
|
||||
title: routeTitle('login'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
// 403
|
||||
{
|
||||
name: routeName('no-permission'),
|
||||
path: routePath('no-permission'),
|
||||
component: NoPermission,
|
||||
meta: {
|
||||
title: routeTitle('no-permission'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
// 404
|
||||
{
|
||||
name: routeName('not-found'),
|
||||
path: routePath('not-found'),
|
||||
component: NotFound,
|
||||
meta: {
|
||||
title: routeTitle('not-found'),
|
||||
fullPage: true
|
||||
}
|
||||
},
|
||||
// 500
|
||||
{
|
||||
name: routeName('service-error'),
|
||||
path: routePath('service-error'),
|
||||
component: ServiceError,
|
||||
meta: {
|
||||
title: routeTitle('service-error'),
|
||||
fullPage: true
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
// 匹配无效的路径重定向404
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
redirect: { name: routeName('not-found') }
|
||||
}
|
||||
];
|
||||
|
||||
export default constantRoutes;
|
59
src/router/routes/constant.ts
Normal file
59
src/router/routes/constant.ts
Normal file
@ -0,0 +1,59 @@
|
||||
/** 固定的路由 */
|
||||
const constantRoutes: AuthRoute.Route[] = [
|
||||
{
|
||||
name: 'root',
|
||||
path: '/',
|
||||
redirect: '/dashboard/analysis',
|
||||
meta: {
|
||||
title: 'Root'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
component: 'blank',
|
||||
meta: {
|
||||
title: '登录',
|
||||
single: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'no-permission',
|
||||
path: '/no-permission',
|
||||
component: 'blank',
|
||||
meta: {
|
||||
title: '无权限',
|
||||
single: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'not-found',
|
||||
path: '/not-found',
|
||||
component: 'blank',
|
||||
meta: {
|
||||
title: '未找到',
|
||||
single: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'service-error',
|
||||
path: '/service-error',
|
||||
component: 'blank',
|
||||
meta: {
|
||||
title: '服务器错误',
|
||||
single: true
|
||||
}
|
||||
},
|
||||
// 匹配无效的路径重定向not-found的页面
|
||||
{
|
||||
name: 'redirect-not-found',
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: 'blank',
|
||||
meta: {
|
||||
title: '未找到',
|
||||
single: true
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
export default constantRoutes;
|
@ -1,11 +1,8 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { transformMultiDegreeRoutes } from '@/utils';
|
||||
import customRoutes from '../modules';
|
||||
import constantRoutes from './constant-routes';
|
||||
|
||||
const transformRoutes = transformMultiDegreeRoutes(customRoutes);
|
||||
import { transformAuthRouteToVueRoute } from '@/utils';
|
||||
import constantRoutes from './constant';
|
||||
|
||||
/** 所有路由 */
|
||||
export const routes: RouteRecordRaw[] = [...transformRoutes, ...constantRoutes];
|
||||
export const routes: RouteRecordRaw[] = constantRoutes.map(item => transformAuthRouteToVueRoute(item));
|
||||
|
||||
export { ROUTE_HOME } from './route-home';
|
||||
export { constantRoutes };
|
||||
|
@ -1,9 +0,0 @@
|
||||
import { getRouteHome } from '@/utils';
|
||||
import { routeName } from '../constant';
|
||||
import customRoutes from '../modules';
|
||||
|
||||
/** 路由首页的名字 */
|
||||
export const ROUTE_HOME_NAME = routeName('dashboard_analysis');
|
||||
|
||||
/** 路由首页 */
|
||||
export const ROUTE_HOME = getRouteHome(customRoutes, ROUTE_HOME_NAME);
|
@ -1,7 +0,0 @@
|
||||
import { getCacheRoutes } from '@/utils';
|
||||
import { routes } from '../routes';
|
||||
|
||||
/** 缓存的路由对应vue页面的名称 */
|
||||
const cacheRoutes = getCacheRoutes(routes);
|
||||
|
||||
export default cacheRoutes;
|
@ -1,21 +0,0 @@
|
||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
|
||||
import type { App } from 'vue';
|
||||
import { routes } from '../routes';
|
||||
import { createRouterGuide } from '../guard';
|
||||
|
||||
/** 用于部署vercel托管服务 */
|
||||
const isStaging = import.meta.env.VITE_HTTP_ENV === 'STAGING';
|
||||
|
||||
export const router = createRouter({
|
||||
history: isStaging ? createWebHashHistory() : createWebHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
export async function setupRouter(app: App) {
|
||||
app.use(router);
|
||||
createRouterGuide(router);
|
||||
await router.isReady();
|
||||
}
|
||||
|
||||
export { default as cacheRoutes } from './cache';
|
||||
export { menusList, menus } from './menus';
|
@ -1,9 +0,0 @@
|
||||
import { transformRouteToMenu, transformRouteToList } from '@/utils';
|
||||
import customRoutes from '../modules';
|
||||
|
||||
/** 菜单 */
|
||||
const menus = transformRouteToMenu(customRoutes);
|
||||
/** 菜单搜索列表 */
|
||||
const menusList = transformRouteToList(customRoutes);
|
||||
|
||||
export { menus, menusList };
|
Reference in New Issue
Block a user