113 lines
3.0 KiB
TypeScript
113 lines
3.0 KiB
TypeScript
import { createRouter, createWebHistory, type RouteRecordRaw } from "vue-router";
|
|
import StartTask from "@/components/StartTask.vue";
|
|
|
|
const routes: RouteRecordRaw[] = [
|
|
{
|
|
path: "/",
|
|
redirect: "/login",
|
|
},
|
|
{
|
|
path: "/login",
|
|
component: () => import("@/components/Login.vue"),
|
|
meta: { requiresAuth: false },
|
|
},
|
|
{
|
|
path: "/welcome",
|
|
component: () => import("@/components/Welcome.vue"),
|
|
meta: { requiresAuth: true },
|
|
},
|
|
{
|
|
path: "/study",
|
|
name: "study",
|
|
component: () => import("@/components/Study.vue"),
|
|
meta: { requiresAuth: true, title: "学习任务" },
|
|
},
|
|
{
|
|
path: "/review",
|
|
component: () => import("@/components/Review.vue"),
|
|
meta: { requiresAuth: true, title: "复习总览" },
|
|
},
|
|
{
|
|
path: "/review/detail/task/:taskNum",
|
|
component: () => import("@/components/ReviewDetail.vue"),
|
|
meta: { requiresAuth: true, title: "复习详情" },
|
|
},
|
|
{
|
|
path: "/review/detail/:type/:id",
|
|
component: () => import("@/components/ReviewDetail.vue"),
|
|
meta: { requiresAuth: true, title: "复习详情" },
|
|
},
|
|
{
|
|
path: "/review/recall/:taskNum",
|
|
component: () => import("@/components/ReviewRecall.vue"),
|
|
meta: { requiresAuth: true, title: "回忆复习", wide: true },
|
|
},
|
|
{
|
|
path: "/start-task/:taskNum",
|
|
name: "start-task",
|
|
component: StartTask,
|
|
meta: { requiresAuth: true, title: "学习会话" },
|
|
},
|
|
{
|
|
path: "/add-task",
|
|
name: "add-task",
|
|
component: () => import("@/components/TaskForm.vue"),
|
|
meta: {
|
|
requiresAuth: true,
|
|
title: "创建学习任务",
|
|
action: "add",
|
|
buttonText: "添加",
|
|
},
|
|
},
|
|
{
|
|
path: "/update-task/:taskId",
|
|
name: "update-task",
|
|
component: () => import("@/components/TaskForm.vue"),
|
|
meta: {
|
|
requiresAuth: true,
|
|
title: "更新学习任务",
|
|
action: "update",
|
|
buttonText: "更新",
|
|
},
|
|
},
|
|
];
|
|
|
|
const router = createRouter({
|
|
history: createWebHistory(),
|
|
routes,
|
|
});
|
|
|
|
router.onError((error, to) => {
|
|
const message = String((error as Error)?.message || "");
|
|
const isChunkLoadError =
|
|
message.includes("Failed to fetch dynamically imported module") ||
|
|
message.includes("Importing a module script failed") ||
|
|
message.includes("Loading chunk");
|
|
if (isChunkLoadError && typeof window !== "undefined") {
|
|
window.location.assign(to.fullPath);
|
|
}
|
|
});
|
|
|
|
router.beforeEach((to) => {
|
|
if (to.meta.requiresAuth === false) return true;
|
|
const isLoggedIn = localStorage.getItem("isLoggedIn") === "true";
|
|
if (!isLoggedIn) {
|
|
return "/login";
|
|
}
|
|
// 如果有活跃会话且未处于 start-task 页面,自动恢复
|
|
if (!to.path.startsWith("/start-task")) {
|
|
const stored = localStorage.getItem("activeSession");
|
|
if (stored) {
|
|
try {
|
|
const { taskNum } = JSON.parse(stored);
|
|
if (taskNum) {
|
|
return `/start-task/${encodeURIComponent(taskNum)}?resume=true`;
|
|
}
|
|
} catch {}
|
|
}
|
|
}
|
|
return true;
|
|
});
|
|
|
|
export default router;
|