first commit
This commit is contained in:
518
src/router/index.js
Normal file
518
src/router/index.js
Normal file
@@ -0,0 +1,518 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user