Files
tydata-webview-v2/src/router/index.js
2025-10-24 17:08:42 +08:00

461 lines
19 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 { 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: '/agent/promote',
name: 'promote',
component: Promote,
meta: {
requiresAuth: true,
requiresAgent: true,
},
},
{
path: '/agent',
name: 'agent',
component: () => import('@/views/Agent.vue'),
},
{
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 },
},
{
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: '/withdraw',
name: 'withdraw',
component: () => import('@/views/Withdraw.vue'),
meta: { title: '提现', requiresAuth: 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 },
},
],
},
{
path: 'agent',
component: PageLayout,
children: [
{
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/Invitation.vue'),
meta: {
title: '邀请下级',
requiresAuth: true,
requiresAgent: true,
},
},
{
path: 'agentVip',
name: 'agentVip',
component: () => import('@/views/AgentVip.vue'),
meta: {
title: '代理会员',
requiresAuth: true,
requiresAgent: true,
},
},
{
path: 'vipApply',
name: 'agentVipApply',
component: () => import('@/views/AgentVipApply.vue'),
meta: {
title: 'VIP代理申请',
requiresAuth: true,
requiresAgent: true,
},
},
{
path: 'vipConfig',
name: 'agentVipConfig',
component: () => import('@/views/AgentVipConfig.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: 'invitationAgentApply/self',
name: 'invitationAgentApplySelf',
component: () => import('@/views/InvitationAgentApply.vue'),
meta: { title: '代理申请', requiresAuth: 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: '/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);
const { isWeixinAuthing, weixinAuthComplete } = storeToRefs(authStore);
// 微信环境下,如果正在进行授权,等待授权完成
if (isWeChat.value && isWeixinAuthing.value && !weixinAuthComplete.value) {
// 等待授权完成,使用响应式监听
await new Promise((resolve) => {
const stopWatcher = watch(
[isWeixinAuthing, weixinAuthComplete],
([authing, complete]) => {
if (!authing || complete) {
stopWatcher();
resolve();
}
},
{ immediate: true }
);
});
}
// 处理需要登录的页面
if (to.meta.requiresAuth && !isAuthenticated) {
if (isWeChat.value) {
// 微信环境下,如果授权失败或超时,重定向到首页
if (!weixinAuthComplete.value) {
next("/");
location.reload();
} else {
// 授权完成但仍无token可能是授权失败
next("/");
location.reload();
}
} else {
next("/login");
}
return;
}
// 已登录状态下的处理
if (isAuthenticated) {
// 确保用户信息已加载
if (!isLoggedIn.value) {
await userStore.fetchUserInfo();
}
// 检查手机号绑定状态
// 只有在未绑定手机号且目标路由需要登录并且没有设置notNeedBindPhone时才弹出绑定手机号弹窗
if (
!mobile.value &&
to.meta.requiresAuth &&
!to.meta.notNeedBindPhone
) {
dialogStore.openBindPhone();
next(false);
return;
}
// 检查代理权限
if (to.meta.requiresAgent) {
if (!isLoaded.value) {
await agentStore.fetchAgentStatus();
}
if (!isAgent.value) {
next("/agent/invitationAgentApply/self");
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