Files
tydata-webview-v2/src/router/index.js

461 lines
19 KiB
JavaScript
Raw Normal View History

2025-09-27 17:41:14 +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 { 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),
2025-10-24 17:08:42 +08:00
// 路由切换时的滚动行为
scrollBehavior(to, from, savedPosition) {
// 如果有保存的位置(浏览器前进/后退)
if (savedPosition) {
return savedPosition;
} else {
// 否则滚动到顶部
return { top: 0, behavior: "smooth" };
}
},
2025-09-27 17:41:14 +08:00
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) => {
2025-10-24 17:08:42 +08:00
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 }
);
});
}
2025-09-27 17:41:14 +08:00
// 处理需要登录的页面
if (to.meta.requiresAuth && !isAuthenticated) {
if (isWeChat.value) {
2025-10-24 17:08:42 +08:00
// 微信环境下,如果授权失败或超时,重定向到首页
if (!weixinAuthComplete.value) {
next("/");
location.reload();
} else {
// 授权完成但仍无token可能是授权失败
next("/");
location.reload();
}
2025-09-27 17:41:14 +08:00
} else {
2025-10-24 17:08:42 +08:00
next("/login");
2025-09-27 17:41:14 +08:00
}
2025-10-24 17:08:42 +08:00
return;
2025-09-27 17:41:14 +08:00
}
// 已登录状态下的处理
if (isAuthenticated) {
// 确保用户信息已加载
if (!isLoggedIn.value) {
2025-10-24 17:08:42 +08:00
await userStore.fetchUserInfo();
2025-09-27 17:41:14 +08:00
}
// 检查手机号绑定状态
// 只有在未绑定手机号且目标路由需要登录并且没有设置notNeedBindPhone时才弹出绑定手机号弹窗
2025-10-24 17:08:42 +08:00
if (
!mobile.value &&
to.meta.requiresAuth &&
!to.meta.notNeedBindPhone
) {
dialogStore.openBindPhone();
next(false);
return;
2025-09-27 17:41:14 +08:00
}
// 检查代理权限
if (to.meta.requiresAgent) {
if (!isLoaded.value) {
2025-10-24 17:08:42 +08:00
await agentStore.fetchAgentStatus();
2025-09-27 17:41:14 +08:00
}
if (!isAgent.value) {
2025-10-24 17:08:42 +08:00
next("/agent/invitationAgentApply/self");
return;
2025-09-27 17:41:14 +08:00
}
}
}
// 其他情况正常通过
2025-10-24 17:08:42 +08:00
next();
2025-09-27 17:41:14 +08:00
})
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