格式化代码,websocket功能完善
This commit is contained in:
@@ -1,40 +1,40 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import config from '../config'
|
||||
import { useUserStore } from '../stores/modules/user'
|
||||
import systemRoutes from './systemRoutes'
|
||||
import { createRouter, createWebHashHistory } from "vue-router";
|
||||
import NProgress from "nprogress";
|
||||
import "nprogress/nprogress.css";
|
||||
import config from "../config";
|
||||
import { useUserStore } from "../stores/modules/user";
|
||||
import systemRoutes from "./systemRoutes";
|
||||
|
||||
// 配置 NProgress
|
||||
NProgress.configure({
|
||||
showSpinner: false,
|
||||
trickleSpeed: 200,
|
||||
minimum: 0.3
|
||||
})
|
||||
minimum: 0.3,
|
||||
});
|
||||
|
||||
/**
|
||||
* 404 路由
|
||||
*/
|
||||
const notFoundRoute = {
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'NotFound',
|
||||
component: () => import('../layouts/other/404.vue'),
|
||||
path: "/:pathMatch(.*)*",
|
||||
name: "NotFound",
|
||||
component: () => import("../layouts/other/404.vue"),
|
||||
meta: {
|
||||
title: '404',
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
title: "404",
|
||||
hidden: true,
|
||||
},
|
||||
};
|
||||
|
||||
// 创建路由实例
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: systemRoutes
|
||||
})
|
||||
routes: systemRoutes,
|
||||
});
|
||||
|
||||
/**
|
||||
* 组件导入映射
|
||||
*/
|
||||
const modules = import.meta.glob('../pages/**/*.vue')
|
||||
const modules = import.meta.glob("../pages/**/*.vue");
|
||||
|
||||
/**
|
||||
* 动态加载组件
|
||||
@@ -43,16 +43,16 @@ const modules = import.meta.glob('../pages/**/*.vue')
|
||||
*/
|
||||
function loadComponent(componentPath) {
|
||||
// 如果组件路径以 'views/' 或 'pages/' 开头,则从相应目录加载
|
||||
if (componentPath.startsWith('views/')) {
|
||||
const path = componentPath.replace('views/', '../pages/')
|
||||
return modules[`${path}.vue`]
|
||||
if (componentPath.startsWith("views/")) {
|
||||
const path = componentPath.replace("views/", "../pages/");
|
||||
return modules[`${path}.vue`];
|
||||
}
|
||||
|
||||
// 如果是简单的组件名称,从 pages 目录加载
|
||||
if (componentPath.endsWith('index')){
|
||||
return modules[`../pages/${componentPath}.vue`]
|
||||
if (componentPath.endsWith("index")) {
|
||||
return modules[`../pages/${componentPath}.vue`];
|
||||
} else {
|
||||
return modules[`../pages/${componentPath}/index.vue`]
|
||||
return modules[`../pages/${componentPath}/index.vue`];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,147 +63,147 @@ function loadComponent(componentPath) {
|
||||
*/
|
||||
function transformMenusToRoutes(menus) {
|
||||
if (!menus || !Array.isArray(menus)) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
return menus
|
||||
.filter(menu => menu && menu.path)
|
||||
.map(menu => {
|
||||
.filter((menu) => menu && menu.path)
|
||||
.map((menu) => {
|
||||
const route = {
|
||||
path: menu.path,
|
||||
name: menu.name || menu.path.replace(/\//g, '-'),
|
||||
name: menu.name || menu.path.replace(/\//g, "-"),
|
||||
meta: {
|
||||
title: menu.meta?.title || menu.title,
|
||||
icon: menu.meta?.icon || menu.icon,
|
||||
hidden: menu.hidden || menu.meta?.hidden,
|
||||
keepAlive: menu.meta?.keepAlive || false,
|
||||
affix: menu.meta?.affix || 0,
|
||||
role: menu.meta?.role || []
|
||||
}
|
||||
}
|
||||
role: menu.meta?.role || [],
|
||||
},
|
||||
};
|
||||
|
||||
// 处理组件
|
||||
if (menu.component) {
|
||||
route.component = loadComponent(menu.component)
|
||||
route.component = loadComponent(menu.component);
|
||||
}
|
||||
|
||||
// 处理子路由
|
||||
if (menu.children && menu.children.length > 0) {
|
||||
route.children = transformMenusToRoutes(menu.children)
|
||||
route.children = transformMenusToRoutes(menu.children);
|
||||
}
|
||||
|
||||
// 处理重定向
|
||||
if (menu.redirect) {
|
||||
route.redirect = menu.redirect
|
||||
route.redirect = menu.redirect;
|
||||
}
|
||||
|
||||
return route
|
||||
})
|
||||
return route;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 路由守卫
|
||||
*/
|
||||
let isDynamicRouteLoaded = false
|
||||
let isDynamicRouteLoaded = false;
|
||||
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// 开始进度条
|
||||
NProgress.start()
|
||||
NProgress.start();
|
||||
|
||||
// 设置页面标题
|
||||
document.title = to.meta.title
|
||||
? `${to.meta.title} - ${config.APP_NAME}`
|
||||
: config.APP_NAME
|
||||
: config.APP_NAME;
|
||||
|
||||
const userStore = useUserStore()
|
||||
const isLoggedIn = userStore.isLoggedIn()
|
||||
const whiteList = config.whiteList || []
|
||||
const userStore = useUserStore();
|
||||
const isLoggedIn = userStore.isLoggedIn();
|
||||
const whiteList = config.whiteList || [];
|
||||
|
||||
// 1. 如果在白名单中,直接放行
|
||||
if (whiteList.includes(to.path)) {
|
||||
next()
|
||||
return
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 如果未登录,跳转到登录页
|
||||
if (!isLoggedIn) {
|
||||
// 保存目标路由,登录后跳转
|
||||
next({
|
||||
path: '/login',
|
||||
query: { redirect: to.fullPath }
|
||||
})
|
||||
return
|
||||
path: "/login",
|
||||
query: { redirect: to.fullPath },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 已登录情况
|
||||
// 如果访问登录页,重定向到首页
|
||||
if (to.path === '/login') {
|
||||
next({ path: config.DASHBOARD_URL })
|
||||
return
|
||||
if (to.path === "/login") {
|
||||
next({ path: config.DASHBOARD_URL });
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. 动态路由加载
|
||||
if (!isDynamicRouteLoaded) {
|
||||
try {
|
||||
// 获取后端返回的用户菜单
|
||||
const mergedMenus = userStore.getMenu()
|
||||
const mergedMenus = userStore.getMenu();
|
||||
|
||||
if (mergedMenus && mergedMenus.length > 0) {
|
||||
// 将合并后的菜单转换为路由
|
||||
const dynamicRoutes = transformMenusToRoutes(mergedMenus)
|
||||
const dynamicRoutes = transformMenusToRoutes(mergedMenus);
|
||||
|
||||
// 添加动态路由到 Layout 的子路由
|
||||
dynamicRoutes.forEach(route => {
|
||||
router.addRoute('Layout', route)
|
||||
})
|
||||
dynamicRoutes.forEach((route) => {
|
||||
router.addRoute("Layout", route);
|
||||
});
|
||||
|
||||
// 添加 404 路由(必须在最后添加)
|
||||
router.addRoute(notFoundRoute)
|
||||
router.addRoute(notFoundRoute);
|
||||
|
||||
isDynamicRouteLoaded = true
|
||||
isDynamicRouteLoaded = true;
|
||||
|
||||
// 重新导航,确保新添加的路由被正确匹配
|
||||
next({ ...to, replace: true })
|
||||
next({ ...to, replace: true });
|
||||
} else {
|
||||
// 如果没有菜单数据,重置并跳转到登录页
|
||||
userStore.logout()
|
||||
next({ path: '/login', query: { redirect: to.fullPath } })
|
||||
userStore.logout();
|
||||
next({ path: "/login", query: { redirect: to.fullPath } });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('动态路由加载失败:', error)
|
||||
console.error("动态路由加载失败:", error);
|
||||
|
||||
// 加载失败,清除用户信息并跳转到登录页
|
||||
userStore.logout()
|
||||
userStore.logout();
|
||||
next({
|
||||
path: '/login',
|
||||
query: { redirect: to.fullPath }
|
||||
})
|
||||
path: "/login",
|
||||
query: { redirect: to.fullPath },
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 动态路由已加载,直接放行
|
||||
next()
|
||||
next();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
router.afterEach(() => {
|
||||
// 结束进度条
|
||||
NProgress.done()
|
||||
})
|
||||
NProgress.done();
|
||||
});
|
||||
|
||||
/**
|
||||
* 重置路由(用于登出时)
|
||||
*/
|
||||
export function resetRouter() {
|
||||
// 移除所有动态添加的路由
|
||||
isDynamicRouteLoaded = false
|
||||
isDynamicRouteLoaded = false;
|
||||
|
||||
// 重置为初始路由
|
||||
const newRouter = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes: systemRoutes
|
||||
})
|
||||
routes: systemRoutes,
|
||||
});
|
||||
|
||||
router.matcher = newRouter.matcher
|
||||
router.matcher = newRouter.matcher;
|
||||
}
|
||||
|
||||
export default router
|
||||
export default router;
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
import config from '@/config'
|
||||
import config from "@/config";
|
||||
|
||||
/**
|
||||
* 基础路由(不需要登录)
|
||||
*/
|
||||
const systemRoutes = [
|
||||
{
|
||||
path: '/login',
|
||||
name: 'Login',
|
||||
component: () => import('../pages/login/index.vue'),
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
component: () => import("../pages/login/index.vue"),
|
||||
meta: {
|
||||
title: 'login',
|
||||
title: "login",
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/register',
|
||||
name: 'Register',
|
||||
component: () => import('../pages/login/userRegister.vue'),
|
||||
path: "/register",
|
||||
name: "Register",
|
||||
component: () => import("../pages/login/userRegister.vue"),
|
||||
meta: {
|
||||
title: 'register',
|
||||
title: "register",
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/reset-password',
|
||||
name: 'ResetPassword',
|
||||
component: () => import('../pages/login/resetPassword.vue'),
|
||||
path: "/reset-password",
|
||||
name: "ResetPassword",
|
||||
component: () => import("../pages/login/resetPassword.vue"),
|
||||
meta: {
|
||||
title: 'resetPassword',
|
||||
title: "resetPassword",
|
||||
hidden: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
name: 'Layout',
|
||||
component: () => import('@/layouts/index.vue'),
|
||||
path: "/",
|
||||
name: "Layout",
|
||||
component: () => import("@/layouts/index.vue"),
|
||||
redirect: config.DASHBOARD_URL,
|
||||
children: [],
|
||||
},
|
||||
]
|
||||
];
|
||||
|
||||
export default systemRoutes
|
||||
export default systemRoutes;
|
||||
|
||||
Reference in New Issue
Block a user