Files
qnc-webview-v3/src/router/index.js
2026-02-28 14:33:47 +08:00

519 lines
21 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.quannengcha.com${to.path}`,
};
updateSEO(seoConfig);
}
});
export default router;