422 lines
17 KiB
JavaScript
422 lines
17 KiB
JavaScript
|
|
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),
|
|||
|
|
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 { isWeChat } = useEnv()
|
|||
|
|
const { isAgent, isLoaded } = storeToRefs(agentStore)
|
|||
|
|
const { mobile, isLoggedIn } = storeToRefs(userStore)
|
|||
|
|
|
|||
|
|
// 处理需要登录的页面
|
|||
|
|
if (to.meta.requiresAuth && !isAuthenticated) {
|
|||
|
|
if (isWeChat.value) {
|
|||
|
|
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
|