import { createRouter, createWebHistory } from 'vue-router' import Layout from '@/views/Layout.vue' import request from '@/utils/request' import { ensureMenuAccess, getMenuAccess, getDefaultLandingPath, getEffectiveVisiblePaths, isMenuSessionFresh, JITUAN_API, } from '@/utils/club-context' const routes = [ { path: '/login', component: () => import('@/views/Login.vue') }, { path: '/', component: Layout, redirect: () => getDefaultLandingPath() || '/welcome', children: [ { path: 'welcome', component: () => import('@/views/Welcome.vue'), meta: { title: '首页' } }, // ========== 板块与财务 ========== { path: 'finance/bankuai', component: () => import('@/views/finance/BankuaiConfig.vue'), meta: { title: '板块配置' } }, { path: 'finance/data', component: () => import('@/views/finance/FinanceData.vue'), meta: { title: '财务数据' } }, // ========== 考核管理 ========== { path: 'assessment/examiner', component: () => import('@/views/assessment/ExaminerManage.vue'), meta: { title: '考核官管理' } }, { path: 'assessment/config', component: () => import('@/views/assessment/ExamConfig.vue'), meta: { title: '考核配置' } }, { path: 'assessment/record', component: () => import('@/views/assessment/ExamRecord.vue'), meta: { title: '考核记录' } }, // 订单管理(原有) { path: 'order/platform', component: () => import('@/views/order/PlatformOrder.vue'), meta: { title: '平台订单' } }, { path: 'order/merchant', component: () => import('@/views/order/MerchantOrder.vue'), meta: { title: '商家订单' } }, { path: 'order/detail/:id', component: () => import('@/views/order/Detail.vue'), meta: { title: '订单详情' } }, // 跨平台管理(原有) { path: 'cross-order', component: () => import('@/views/cross-platform/Order.vue'), meta: { title: '跨平台订单' } }, { path: 'cross-settings', component: () => import('@/views/cross-platform/Settings.vue'), meta: { title: '跨平台设置' } }, { path: 'cross-data', component: () => import('@/views/cross-platform/Data.vue'), meta: { title: '跨平台数据' } }, { path: 'cross-pre', component: () => import('@/views/cross-platform/Pre.vue'), meta: { title: '预结算处理' } }, { path: 'cross-order/detail/:id', component: () => import('@/views/cross-platform/OrderDetail.vue'), meta: { title: '跨平台订单详情' } }, // 用户管理(原有) { path: 'user/player', component: () => import('@/views/user/Player.vue'), meta: { title: '打手管理' } }, { path: 'user/player/detail/:playerId', component: () => import('@/views/user/PlayerDetail.vue'), meta: { title: '打手详情' } }, { path: 'user/guanli', component: () => import('@/views/user/Guanli.vue'), meta: { title: '管事管理' } }, { path: 'user/guanli/detail/:id', component: () => import('@/views/user/GuanliDetail.vue'), meta: { title: '管事详情' } }, { path: 'user/shangjia', component: () => import('@/views/user/Shangjia.vue'), meta: { title: '商家管理' } }, { path: 'user/shangjia/detail/:id', component: () => import('@/views/user/ShangjiaDetail.vue'), meta: { title: '商家详情' } }, { path: 'user/zuzhang', component: () => import('@/views/user/Zuzhang.vue'), meta: { title: '组长管理' } }, { path: 'user/zuzhang/detail/:id', component: () => import('@/views/user/ZuzhangDetail.vue'), meta: { title: '组长详情' } }, { path: 'user/identity-tag', component: () => import('@/views/user/IdentityTag.vue'), meta: { title: '身份装饰标签' } }, // 提现管理(原有) { path: 'withdraw/audit', component: () => import('@/views/withdraw/Audit.vue'), meta: { title: '提现审核' } }, { path: 'withdraw/data', component: () => import('@/views/withdraw/Data.vue'), meta: { title: '提现数据' } }, { path: 'withdraw/settings', component: () => import('@/views/withdraw/Settings.vue'), meta: { title: '提现设置' } }, { path: 'withdraw/detail/:id', component: () => import('@/views/withdraw/Detail.vue'), meta: { title: '提现详情' } }, // 管理员管理(原有) { path: 'admin/club-config', component: () => import('@/views/admin/ClubConfig.vue'), meta: { title: '俱乐部密钥配置' } }, { path: 'admin/data-scope', component: () => import('@/views/admin/DataScope.vue'), meta: { title: '数据范围配置' } }, { path: 'admin/role', component: () => import('@/views/admin/Role.vue'), meta: { title: '角色管理' } }, { path: 'admin/role/detail/:id', component: () => import('@/views/admin/RoleDetail.vue'), meta: { title: '角色详情' } }, { path: 'admin/user', component: () => import('@/views/admin/AdminUser.vue'), meta: { title: '后台用户' } }, { path: 'admin/user/detail/:id', component: () => import('@/views/admin/AdminUserDetail.vue'), meta: { title: '后台用户详情' } }, { path: 'admin/operation-log', component: () => import('@/views/admin/OperationLog.vue'), meta: { title: '操作日志' } }, // 处罚管理(原有) { path: 'punishment', component: () => import('@/views/Punishment.vue'), meta: { title: '处罚管理' } }, { path: 'punishment/detail/:id', component: () => import('@/views/punishment/Detail.vue'), meta: { title: '处罚详情' } }, // ========== 商品管理(原有) ========== { path: 'product/list', component: () => import('@/views/product/List.vue'), meta: { title: '商品列表' } }, { path: 'product/type-zone', component: () => import('@/views/product/TypeZone.vue'), meta: { title: '商品类型专区管理' } }, { path: 'product/data', component: () => import('@/views/product/Data.vue'), meta: { title: '商品数据分析' } }, { path: 'product/detail/:id', component: () => import('@/views/product/Detail.vue'), meta: { title: '商品详情' } }, // ========== 会员管理(原有) ========== { path: 'member/list', component: () => import('@/views/member/List.vue'), meta: { title: '会员管理' } }, { path: 'member/data', component: () => import('@/views/member/Data.vue'), meta: { title: '会员数据分析' } }, { path: 'miniapp/popup-notice', component: () => import('@/views/miniapp/PopupNotice.vue'), meta: { title: '弹窗公告管理' } }, { path: 'miniapp/carousel', component: () => import('@/views/miniapp/CarouselManage.vue'), meta: { title: '轮播图与公告' } }, { path: 'miniapp/assets', component: () => import('@/views/miniapp/MiniappAssets.vue'), meta: { title: '图标与频道' } }, { path: 'miniapp/leixing', component: () => import('@/views/miniapp/ShangpinLeixingClub.vue'), meta: { title: '抢单商品类型' } }, { path: 'miniapp/kaohe-tags', component: () => import('@/views/miniapp/KaoheTagClub.vue'), meta: { title: '抢单考核标签' } }, { path: 'miniapp/dashou-exam', component: () => import('@/views/miniapp/DashouExam.vue'), meta: { title: '打手接单考试' } }, // ========== 店铺管理(原有) ========== { path: 'shop/list', component: () => import('@/views/shop/List.vue'), meta: { title: '店铺列表' } }, { path: 'shop/withdraw-apply', component: () => import('@/views/shop/WithdrawApply.vue'), meta: { title: '店铺提现申请' } }, { path: 'shop/products', component: () => import('@/views/shop/Products.vue'), meta: { title: '店铺商品管理' } }, // ========== 🔥 新增:客服会话管理 ========== { path: 'chat/agent', component: () => import('@/views/chat/Agent.vue'), meta: { title: '会话管理' } } ] } ] const router = createRouter({ history: createWebHistory(), routes }) /** 详情页等子路由:父模块在 visible_paths 中即允许访问 */ function isRouteAllowed(path, visiblePaths) { if (!visiblePaths?.length) return true if (visiblePaths.some((p) => p && (path === p || path.startsWith(`${p}/`)))) { return true } const rules = [ { prefix: '/withdraw/detail/', parents: ['/withdraw/audit', '/withdraw/data'] }, { prefix: '/punishment/detail/', parents: ['/punishment'] }, { prefix: '/order/detail/', parents: ['/order/platform', '/order/merchant'] }, { prefix: '/cross-order/detail/', parents: ['/cross-order'] }, { prefix: '/user/player/detail/', parents: ['/user/player'] }, { prefix: '/user/guanli/detail/', parents: ['/user/guanli'] }, { prefix: '/user/shangjia/detail/', parents: ['/user/shangjia'] }, { prefix: '/user/zuzhang/detail/', parents: ['/user/zuzhang'] }, { prefix: '/product/detail/', parents: ['/product/list'] }, { prefix: '/admin/role/detail/', parents: ['/admin/role'] }, { prefix: '/admin/user/detail/', parents: ['/admin/user'] }, { prefix: '/miniapp/assets', parents: ['/miniapp/carousel', '/miniapp/assets'] }, ] for (const { prefix, parents } of rules) { if (path.startsWith(prefix)) { return visiblePaths.some((p) => parents.includes(p)) } } return false } router.beforeEach(async (to, from, next) => { const token = localStorage.getItem('token') if (to.path !== '/login' && !token) { next('/login') return } if (to.path === '/login') { next() return } try { await ensureMenuAccess(async () => { const res = await request.get(JITUAN_API.menuAccess) return res.code === 0 ? res.data : null }) } catch (e) { console.error('路由加载菜单权限失败:', e) } const access = getMenuAccess() if (!isMenuSessionFresh()) { next() return } if (to.path === '/welcome') { next() return } if (!getEffectiveVisiblePaths(access).length) { if (to.path !== '/welcome') { next('/welcome') return } next() return } const path = to.path if (!isRouteAllowed(path, getEffectiveVisiblePaths(access))) { const fallback = getDefaultLandingPath(access) || '/welcome' next(fallback) return } next() }) export default router