Files
qnc-webview-v3/src/router/index.js

519 lines
21 KiB
JavaScript
Raw Normal View History

2025-12-16 12:33:02 +08:00
import { createRouter, createWebHistory } from "vue-router";
import NProgress from "nprogress";
import GlobalLayout from "@/layouts/GlobalLayout.vue";
import HomeLayout from "@/layouts/HomeLayout.vue";
import PageLayout from "@/layouts/PageLayout.vue";
import index from "@/views/index.vue";
import Promote from "@/views/Promote.vue";
import PromotePage from "@/views/PromotePage.vue";
import { useAgentStore } from "@/stores/agentStore";
import { useUserStore } from "@/stores/userStore";
import { useDialogStore } from "@/stores/dialogStore";
import { useEnv } from "@/composables/useEnv";
import { storeToRefs } from "pinia";
import { useSEO } from "@/composables/useSEO";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
// 路由切换时的滚动行为
scrollBehavior(to, from, savedPosition) {
// 如果有保存的位置(浏览器前进/后退)
if (savedPosition) {
return savedPosition;
} else {
// 否则滚动到顶部
return { top: 0, behavior: "smooth" };
}
},
routes: [
{
path: "/",
component: GlobalLayout, // 使用 Layout 作为父组件
children: [
{
path: "",
component: HomeLayout, // 使用 Layout 作为父组件
children: [
{
path: "",
name: "index",
component: index,
},
{
path: "promote",
name: "promote",
component: PromotePage,
},
{
path: "/agent",
name: "agent",
component: () => import("@/views/Agent.vue"),
meta: { title: "代理主页", requiresAuth: true },
},
{
path: "me",
name: "me",
component: () => import("@/views/Me.vue"),
},
],
},
{
path: "",
component: PageLayout,
children: [
{
path: "/historyQuery",
name: "history",
component: () => import("@/views/HistoryQuery.vue"),
meta: {
title: "历史报告",
requiresAuth: true,
notNeedBindPhone: true,
},
},
{
path: "/help",
name: "help",
component: () => import("@/views/Help.vue"),
meta: { title: "帮助中心" },
},
{
path: "/help/detail",
name: "helpDetail",
component: () => import("@/views/HelpDetail.vue"),
meta: { title: "帮助中心" },
},
{
path: "/help/guide",
name: "helpGuide",
component: () => import("@/views/HelpGuide.vue"),
meta: { title: "引导指南" },
},
{
path: "/agent/system-guide",
name: "agentSystemGuide",
component: () =>
import("@/views/AgentSystemGuide.vue"),
meta: { title: "代理系统指南" },
},
{
path: "/withdraw",
name: "withdraw",
component: () => import("@/views/Withdraw.vue"),
meta: {
title: "提现",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "/service",
name: "service",
component: () => import("@/views/Service.vue"),
meta: { title: "客服" },
},
{
path: "/complaint",
name: "complaint",
component: () => import("@/views/Complaint.vue"),
meta: { title: "投诉" },
},
{
path: "/report",
name: "report",
component: () => import("@/views/Report.vue"),
meta: {
title: "报告结果",
requiresAuth: true,
notNeedBindPhone: true,
},
},
{
path: "/example",
name: "example",
component: () => import("@/views/Example.vue"),
meta: { title: "示例报告", notNeedBindPhone: true },
},
{
path: "/vant-theme-test",
name: "vantThemeTest",
component: () =>
import("@/views/VantThemeTest.vue"),
meta: { title: "Vant主题色测试" },
},
{
path: "/privacyPolicy",
name: "privacyPolicy",
component: () =>
import("@/views/PrivacyPolicy.vue"),
meta: { title: "隐私政策" },
},
{
path: "/userAgreement",
name: "userAgreement",
component: () =>
import("@/views/UserAgreement.vue"),
meta: { title: "用户协议" },
},
{
path: "/agentManageAgreement",
name: "agentManageAgreement",
component: () =>
import("@/views/AgentManageAgreement.vue"),
meta: { title: "代理管理协议" },
},
{
path: "/agentSerivceAgreement",
name: "agentSerivceAgreement",
component: () =>
import("@/views/AgentServiceAgreement.vue"),
meta: { title: "信息技术服务合同" },
},
{
path: "/inquire/:feature",
name: "inquire",
component: () => import("@/views/Inquire.vue"),
meta: { title: "查询报告" },
},
{
path: "/authorization",
name: "authorization",
component: () =>
import("@/views/Authorization.vue"),
meta: { title: "授权书" },
},
{
path: "/payment/result",
name: "paymentResult",
component: () =>
import("@/views/PaymentResult.vue"),
meta: {
title: "支付结果",
requiresAuth: true,
notNeedBindPhone: true,
},
},
],
},
{
path: "agent",
component: PageLayout,
children: [
{
path: "/agent/promote",
name: "agentPromote",
component: Promote,
meta: {
title: "推广报告",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "/agent/promotion/query/list",
name: "agentPromotionQueryList",
component: () =>
import("@/views/AgentPromotionHistory.vue"),
meta: {
title: "推广查询记录",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "promoteDetails",
name: "promoteDetails",
component: () =>
import("@/views/AgentPromoteDetails.vue"),
meta: {
title: "我的推广收益",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "rewardsDetails",
name: "rewardsDetails",
component: () =>
import("@/views/AgentRewardsDetails.vue"),
meta: {
title: "下级推广收益",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "invitation",
name: "invitation",
component: () =>
import("@/views/InvitationPage.vue"),
meta: {
title: "邀请下级",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "withdraw",
name: "withdraw",
component: () => import("@/views/Withdraw.vue"),
meta: {
title: "提现",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "withdrawDetails",
name: "withdrawDetails",
component: () =>
import("@/views/WithdrawDetails.vue"),
meta: {
title: "提现记录",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "teamList",
name: "teamList",
component: () => import("@/views/TeamList.vue"),
meta: {
title: "我的团队",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "upgradeSubordinate",
name: "upgradeSubordinate",
component: () =>
import("@/views/UpgradeSubordinate.vue"),
meta: {
title: "调整下级级别",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "upgrade",
name: "agentUpgrade",
component: () => import("@/views/AgentUpgrade.vue"),
meta: {
title: "升级代理",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "subordinateList",
name: "subordinateList",
component: () =>
import("@/views/SubordinateList.vue"),
meta: {
title: "我的下级",
requiresAuth: true,
requiresAgent: true,
},
},
{
path: "subordinateDetail/:id",
name: "subordinateDetail",
component: () =>
import("@/views/SubordinateDetail.vue"),
meta: {
title: "下级贡献详情",
requiresAuth: true,
requiresAgent: true,
},
},
],
},
{
path: "app",
children: [
{
path: "authorization",
name: "appAuthorization",
component: () =>
import("@/views/Authorization.vue"),
meta: { title: "授权书" },
},
{
path: "privacyPolicy",
name: "appPrivacyPolicy",
component: () =>
import("@/views/PrivacyPolicy.vue"),
meta: { title: "隐私政策" },
},
{
path: "userAgreement",
name: "appUserAgreement",
component: () =>
import("@/views/UserAgreement.vue"),
meta: { title: "用户协议" },
},
{
path: "agentManageAgreement",
name: "appAgentManageAgreement",
component: () =>
import("@/views/AgentManageAgreement.vue"),
meta: { title: "代理管理协议" },
},
{
path: "agentSerivceAgreement",
name: "appAgentSerivceAgreement",
component: () =>
import("@/views/AgentServiceAgreement.vue"),
meta: { title: "信息技术服务合同" },
},
],
},
],
},
{
path: "/login",
name: "login",
component: () => import("@/views/Login.vue"),
},
{
path: "/register",
name: "register",
component: () => import("@/views/Register.vue"),
},
{
path: "/agent/promotionInquire/:linkIdentifier",
name: "promotionInquire",
component: () => import("@/views/PromotionInquire.vue"),
meta: { notNeedBindPhone: true },
},
{
path: "/agent/invitationAgentApply/:linkIdentifier",
name: "invitationAgentApply",
component: () => import("@/views/InvitationAgentApply.vue"),
meta: { title: "代理申请" },
},
{
path: "/report/share/:linkIdentifier",
name: "reportShare",
component: () => import("@/views/ReportShare.vue"),
},
{
path: "/:pathMatch(.*)*",
name: "NotFound",
component: () => import("@/views/NotFound.vue"),
},
],
});
NProgress.configure({
easing: "ease", // 动画方式
speed: 500, // 递增进度条的速度(毫秒)
showSpinner: false, // 是否显示加载的圆圈
trickleSpeed: 200, // 自动递增间隔
minimum: 0.3, // 初始化最小百分比
});
// 路由导航守卫
router.beforeEach(async (to, from, next) => {
NProgress.start();
const isAuthenticated = localStorage.getItem("token");
const agentStore = useAgentStore();
const userStore = useUserStore();
const dialogStore = useDialogStore();
const authStore = useAuthStore();
const { isWeChat } = useEnv();
const { isAgent, isLoaded } = storeToRefs(agentStore);
const { mobile, isLoggedIn } = storeToRefs(userStore);
// 检查 token 是否过期
const accessExpire = localStorage.getItem("accessExpire");
const now = Date.now();
let isTokenExpired = false;
if (accessExpire) {
isTokenExpired = now > parseInt(accessExpire) * 1000;
}
// ============================================================
// 场景 2: 需要登录的页面 + 无 token 或 token 过期 → 跳转登录
// ============================================================
if (to.meta.requiresAuth && (!isAuthenticated || isTokenExpired)) {
const loginQuery = {
redirect: to.fullPath,
};
if (from && from.name === "promotionInquire") {
loginQuery.from = "promotionInquire";
}
next({ path: "/login", query: loginQuery });
return;
}
// ============================================================
// 场景 3: 已登录状态下的处理
// ============================================================
if (isAuthenticated && !isTokenExpired) {
// 确保用户信息已加载
if (!isLoggedIn.value) {
try {
await userStore.fetchUserInfo();
} catch (err) {
console.error("Error loading user info:", err);
}
}
// 检查代理权限(仅在 requiresAgent 为 true 时)
if (to.meta.requiresAgent) {
if (!mobile.value) {
if (to.meta.notNeedBindPhone) {
dialogStore.openBindPhone();
} else {
next("/register");
return;
}
}
// 确保代理信息已加载
if (!isLoaded.value) {
try {
await agentStore.fetchAgentStatus();
} catch (err) {
console.error("Error loading agent info:", err);
}
}
// 如果不是代理,跳转到注册页(带上手机号参数)
if (!isAgent.value) {
const registerQuery = {};
if (mobile.value) {
registerQuery.mobile = mobile.value;
}
next({ path: "/register", query: registerQuery });
return;
}
}
}
// ============================================================
// 其他情况正常通过
// ============================================================
next();
});
router.afterEach((to) => {
NProgress.done(); // 结束进度条
// SEO优化更新页面标题和meta信息
const { updateSEO } = useSEO();
// 根据路由meta信息更新SEO
if (to.meta.title) {
const seoConfig = {
title: `${to.meta.title} - 全能查`,
description: `全能查${to.meta.title}页面,提供专业的大数据风险管控服务。`,
url: `https://www.zhinengcha.cn${to.path}`,
};
updateSEO(seoConfig);
}
});
export default router;