index.ts 5.75 KB
import { createRouter, createWebHashHistory } from "vue-router";
import { useAuthStore } from "@/stores/auth";

declare module "vue-router" {
  interface RouteMeta {
    title?: string;
    requiresAuth?: boolean;
    icon?: string;
    hidden?: boolean;
    hideIntelligencePanel?: boolean;
  }
}

const routes = [
  // 根路径:登录跳 PGX,未登录跳 Auth
  {
    path: "/",
    redirect: () => {
      const authStore = useAuthStore();
      return authStore.isAuthenticated ? { name: "PGXDashboard" } : { name: "Auth" };
    },
  },

  // 认证页(登录/注册)
  {
    path: "/auth",
    name: "Auth",
    component: () => import("@/pages/Auth.vue"),
    meta: { title: "登录 / 注册", requiresAuth: false, hidden: true },
  },

  // ===== 嘉宝仁和样本流转系统(主入口)=====
  {
    path: "/pgx",
    component: () => import("@/pages/pgx/PGXApp.vue"),
    meta: { requiresAuth: true, title: "样本流转系统" },
    children: [
      { path: "", redirect: "dashboard" },
      {
        path: "dashboard",
        name: "PGXDashboard",
        component: () => import("@/pages/pgx/Dashboard.vue"),
        meta: { title: "工作台" },
      },
      {
        path: "register",
        name: "PGXRegister",
        component: () => import("@/pages/pgx/Register.vue"),
        meta: { title: "信息登记" },
      },
      {
        path: "orders",
        name: "PGXOrders",
        component: () => import("@/pages/pgx/Orders.vue"),
        meta: { title: "申请单管理" },
      },
      {
        path: "orders/:id",
        name: "PGXOrderDetail",
        component: () => import("@/pages/pgx/OrderDetail.vue"),
        meta: { title: "申请单详情" },
      },
      {
        path: "tracking",
        name: "PGXTracking",
        component: () => import("@/pages/pgx/Tracking.vue"),
        meta: { title: "状态追踪" },
      },
      {
        path: "post",
        name: "PGXPost",
        component: () => import("@/pages/pgx/Post.vue"),
        meta: { title: "邮寄查询" },
      },
      {
        path: "samples",
        name: "PGXSamples",
        component: () => import("@/pages/pgx/Samples.vue"),
        meta: { title: "样本检测状态" },
      },
      {
        path: "lims",
        name: "PGXLims",
        component: () => import("@/pages/pgx/LIMSVerify.vue"),
        meta: { title: "样本核对接收" },
      },
      {
        path: "batch",
        name: "PGXBatch",
        component: () => import("@/pages/pgx/Batch.vue"),
        meta: { title: "批量订单" },
      },
      {
        path: "bio",
        name: "PGXBio",
        component: () => import("@/pages/pgx/Bioinformatics.vue"),
        meta: { title: "生信分析平台" },
      },
      {
        path: "report-gen",
        name: "PGXReportGen",
        component: () => import("@/pages/pgx/ReportGenerate.vue"),
        meta: { title: "报告生成审核" },
      },
      // 设置页嵌入 PGX 布局
      {
        path: "settings",
        name: "PGXSettings",
        component: () => import("@/pages/Settings.vue"),
        meta: { title: "账号设置" },
      },
    ],
  },

  // 保留原有认证辅助路由
  {
    path: "/forgot-password",
    name: "ForgotPassword",
    component: () => import("@/components/auth/ForgotPassword.vue"),
    meta: { title: "忘记密码", requiresAuth: false, hidden: true },
  },
  {
    path: "/phone-forgot-password",
    name: "PhoneForgotPassword",
    component: () => import("@/components/auth/PhoneForgotPassword.vue"),
    meta: { title: "手机号重置密码", requiresAuth: false, hidden: true },
  },
  {
    path: "/reset-password",
    name: "ResetPassword",
    component: () => import("@/components/auth/ResetPassword.vue"),
    meta: { title: "重置密码", requiresAuth: false, hidden: true },
  },
  {
    path: "/go-activate",
    name: "GoActivate",
    component: () => import("@/components/auth/GoActivate.vue"),
    meta: { title: "激活账号", requiresAuth: false, hidden: true },
  },
  {
    path: "/bind-email",
    name: "BindEmailConfirm",
    component: () => import("@/components/Settings/BindEmailConfirm.vue"),
    meta: { title: "绑定邮箱", requiresAuth: false, hidden: true },
  },
  {
    path: "/wechat-login",
    name: "WechatLogin",
    component: () => import("@/components/auth/WechatLoginPage.vue"),
    meta: { title: "微信登录", requiresAuth: false, hidden: true },
  },
  {
    path: "/:pathMatch(.*)*",
    name: "NotFound",
    redirect: "/pgx/dashboard",
    meta: { hidden: true },
  },
];

const router = createRouter({
  history: createWebHashHistory(),
  routes,
  scrollBehavior(_to, _from, savedPosition) {
    if (savedPosition) return savedPosition;
    return { top: 0, behavior: "smooth" };
  },
});

// 全局守卫
router.beforeEach(async (to, _from, next) => {
  document.title = "嘉宝仁和 · 样本流转系统";

  const authStore = useAuthStore();

  if (to.name === "Auth" || to.path === "/auth") {
    if (authStore.isAuthenticated) {
      next({ name: "PGXDashboard", replace: true });
      return;
    }
    // token 免登支持
    const tokenQuery = (to.query?.token) as string | string[] | undefined;
    const tokenFromQuery = Array.isArray(tokenQuery) ? tokenQuery[0] : tokenQuery;
    if (tokenFromQuery) {
      try {
        const result = await authStore.loginWithToken(tokenFromQuery);
        if (result?.success) {
          next({ name: "PGXDashboard", replace: true });
          return;
        }
      } catch (_e) { /* ignore */ }
    }
  }

  if (to.meta.requiresAuth && !authStore.isAuthenticated) {
    next({ name: "Auth" });
  } else {
    next();
  }
});

router.afterEach((to, _from, failure) => {
  if (failure) console.error("路由导航失败:", failure);
});

router.onError((error) => {
  console.error("路由错误:", error);
});

export default router;