2fec2108ca
- Home: hide duplicate create/join buttons when user has no groups - Invite links: /join/group/:id and /join/team/:id pages for one-click joining - Admin: group admins field, ownership transfer, member management toggle - Events: new events collection with RSVP (going/interested/maybe) and comments Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
131 lines
3.1 KiB
TypeScript
131 lines
3.1 KiB
TypeScript
// src/router/index.ts
|
|
import { createRouter, createWebHistory } from 'vue-router'
|
|
import type { RouteRecordRaw } from 'vue-router'
|
|
import { isAuthenticated } from '@/api/pocketbase'
|
|
|
|
// 路由配置
|
|
const routes: RouteRecordRaw[] = [
|
|
{
|
|
path: '/login',
|
|
name: 'Login',
|
|
component: () => import('@/views/Login.vue'),
|
|
meta: { requiresGuest: true }
|
|
},
|
|
{
|
|
path: '/register',
|
|
name: 'Register',
|
|
component: () => import('@/views/Register.vue'),
|
|
meta: { requiresGuest: true }
|
|
},
|
|
{
|
|
path: '/',
|
|
component: () => import('@/views/Layout.vue'),
|
|
meta: { requiresAuth: true },
|
|
children: [
|
|
{
|
|
path: '',
|
|
name: 'Home',
|
|
component: () => import('@/views/Home.vue')
|
|
},
|
|
{
|
|
path: 'group/:id',
|
|
name: 'GroupView',
|
|
component: () => import('@/views/GroupView.vue'),
|
|
props: true
|
|
},
|
|
{
|
|
path: 'group/:groupId/ledger',
|
|
name: 'LedgerView',
|
|
component: () => import('@/views/LedgerView.vue'),
|
|
props: true,
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'group/:groupId/assets',
|
|
name: 'AssetView',
|
|
component: () => import('@/views/AssetView.vue'),
|
|
props: true,
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'group/:groupId/blacklist',
|
|
name: 'BlacklistView',
|
|
component: () => import('@/views/BlacklistView.vue'),
|
|
props: true,
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'group/:groupId/voice/:sessionId',
|
|
name: 'VoiceRoom',
|
|
component: () => import('@/views/VoiceRoom.vue'),
|
|
props: true,
|
|
meta: { requiresAuth: true }
|
|
},
|
|
{
|
|
path: 'games',
|
|
name: 'GamesLibrary',
|
|
component: () => import('@/views/GamesLibrary.vue')
|
|
},
|
|
{
|
|
path: 'profile',
|
|
name: 'Profile',
|
|
component: () => import('@/views/Profile.vue')
|
|
},
|
|
{
|
|
path: 'settings',
|
|
name: 'Settings',
|
|
component: () => import('@/views/Settings.vue')
|
|
},
|
|
{
|
|
path: 'changelog',
|
|
name: 'Changelog',
|
|
component: () => import('@/views/Changelog.vue')
|
|
}
|
|
]
|
|
},
|
|
{
|
|
path: '/join/group/:groupId',
|
|
name: 'JoinGroup',
|
|
component: () => import('@/views/JoinGroupPage.vue'),
|
|
props: true
|
|
},
|
|
{
|
|
path: '/join/team/:sessionId',
|
|
name: 'JoinTeam',
|
|
component: () => import('@/views/JoinTeamPage.vue'),
|
|
props: true
|
|
},
|
|
{
|
|
path: '/:pathMatch(.*)*',
|
|
name: 'NotFound',
|
|
component: () => import('@/views/NotFound.vue')
|
|
}
|
|
]
|
|
|
|
// 创建路由实例
|
|
const router = createRouter({
|
|
history: createWebHistory(import.meta.env.BASE_URL),
|
|
routes
|
|
})
|
|
|
|
// 路由守卫
|
|
router.beforeEach((to, _from, next) => {
|
|
const authenticated = isAuthenticated()
|
|
|
|
// 需要登录的页面
|
|
if (to.meta.requiresAuth && !authenticated) {
|
|
next({ name: 'Login', query: { redirect: to.fullPath } })
|
|
return
|
|
}
|
|
|
|
// 已登录用户访问登录/注册页
|
|
if (to.meta.requiresGuest && authenticated) {
|
|
next({ name: 'Home' })
|
|
return
|
|
}
|
|
|
|
next()
|
|
})
|
|
|
|
export default router
|