You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.3 KiB

1 year ago
import { createRouter, createWebHashHistory } from "vue-router";
import { useTitle } from "@vueuse/core";
import NProgress from "../lib/nprogress/nprogress.vite-esm.js";
import { isLogin, hasPermission } from "../api/user.js";
import { useAppStore } from "../store/index.js";
import { listToTree } from "../utils/index.js";
import { connection, connect } from "../signalr/index.js";
NProgress.configure({ showSpinner: false });
const routes = [
{
path: "/",
redirect: "/home",
component: () => import("../layouts/index.js"),
children: [
{
path: "home",
component: () => import("../views/home.js"),
meta: {
title: "首页",
icon: "home",
},
},
],
},
{
path: "/login",
component: () => import("../views/login.js"),
meta: {
title: "登录",
},
},
{
path: "/403",
component: () => import("../views/403.js"),
meta: {
title: "权限不足",
},
},
{
path: "/:pathMatch(.*)*",
component: () => import("../views/404.js"),
meta: {
title: "无法找到",
},
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
router.beforeEach(async (to, from, next) => {
console.log(`before: ${from.path} -> ${to.path}`);
NProgress.start();
try {
if (to.path !== "/login") {
if (!(await isLogin())) {
next({ path: "/login", query: { redirect: to.fullPath } });
} else {
if (!hasPermission(to)) {
next({ path: "/403", query: { redirect: to.fullPath } });
} else {
next();
}
}
} else {
next();
}
} catch (error) {
NProgress.done();
}
});
router.afterEach((to, from) => {
console.log(`after: ${from.path} -> ${to.path}`);
try {
if (to.meta.title) {
useTitle().value = `${to.meta.title}`;
}
if (to.fullPath.startsWith("/")) {
const appStore = useAppStore();
appStore.add(to);
}
} finally {
NProgress.done();
}
});
1 year ago
const reset = async (list, parent = null) => {
return list.map(async (o) => {
1 year ago
const item = {
path: o.path,
meta: o.meta,
};
1 year ago
if (o.component && typeof o.component === "string" && o.component !== "Layout") {
try {
item.component = await import(`../views/${o.component}.js`);
} catch (error) {
item.component = await import(`../views/list.js`);
}
1 year ago
}
item.meta.path = `${parent === null ? "" : parent.meta.path + "/"}${item.path}`;
item.meta.fullName = `${parent === null ? "" : parent.meta.title + " > "}${item.meta.title}`;
if (o.type === "Resource") {
if (o.children.length) {
item.meta.buttons = o.children.map((b) => {
return {
path: b.path,
meta: b.meta,
};
});
}
} else if (o.type !== "Operation" && o.children?.length) {
item.children = reset(o.children, item);
}
return item;
});
};
const refreshRouter = async () => {
await connect();
const appStore = useAppStore();
const permissions = appStore.user.permissions.filter((o) => !o.isHidden);
1 year ago
const serverRoutes = await reset(permissions);
1 year ago
const route = {
name: "layout",
path: "",
children: serverRoutes,
};
router.removeRoute("layout");
router.addRoute("/", route);
};
export default router;
export { refreshRouter };