|
|
<template> |
|
|
<div class="min-h-screen p-3 sm:p-4 md:p-6"> |
|
|
|
|
|
<AppHeader /> |
|
|
|
|
|
|
|
|
<div |
|
|
class="glass-strong rounded-xl p-3 shadow-xl sm:rounded-2xl sm:p-4 md:rounded-3xl md:p-6" |
|
|
style="z-index: 1; min-height: calc(100vh - 120px)" |
|
|
> |
|
|
|
|
|
<TabBar :active-tab="activeTab" @tab-change="handleTabChange" /> |
|
|
|
|
|
|
|
|
<div class="tab-content"> |
|
|
<router-view /> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</template> |
|
|
|
|
|
<script setup> |
|
|
import { ref, watch, nextTick, computed } from 'vue' |
|
|
import { useRoute, useRouter } from 'vue-router' |
|
|
import { useAuthStore } from '@/stores/auth' |
|
|
import AppHeader from './AppHeader.vue' |
|
|
import TabBar from './TabBar.vue' |
|
|
|
|
|
const route = useRoute() |
|
|
const router = useRouter() |
|
|
const authStore = useAuthStore() |
|
|
|
|
|
|
|
|
const activeTab = ref('dashboard') |
|
|
|
|
|
|
|
|
const tabRouteMap = computed(() => { |
|
|
const baseMap = { |
|
|
dashboard: '/dashboard', |
|
|
apiKeys: '/api-keys', |
|
|
accounts: '/accounts', |
|
|
tutorial: '/tutorial', |
|
|
settings: '/settings' |
|
|
} |
|
|
|
|
|
|
|
|
if (authStore.oemSettings?.ldapEnabled) { |
|
|
baseMap.userManagement = '/user-management' |
|
|
} |
|
|
|
|
|
return baseMap |
|
|
}) |
|
|
|
|
|
|
|
|
const initActiveTab = () => { |
|
|
const currentPath = route.path |
|
|
const tabKey = Object.keys(tabRouteMap.value).find( |
|
|
(key) => tabRouteMap.value[key] === currentPath |
|
|
) |
|
|
|
|
|
if (tabKey) { |
|
|
activeTab.value = tabKey |
|
|
} else { |
|
|
|
|
|
const routeName = route.name |
|
|
const nameToTabMap = { |
|
|
Dashboard: 'dashboard', |
|
|
ApiKeys: 'apiKeys', |
|
|
Accounts: 'accounts', |
|
|
Tutorial: 'tutorial', |
|
|
Settings: 'settings' |
|
|
} |
|
|
if (routeName && nameToTabMap[routeName]) { |
|
|
activeTab.value = nameToTabMap[routeName] |
|
|
} else { |
|
|
|
|
|
activeTab.value = 'dashboard' |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
initActiveTab() |
|
|
|
|
|
|
|
|
watch( |
|
|
() => route.path, |
|
|
(newPath) => { |
|
|
const tabKey = Object.keys(tabRouteMap.value).find((key) => tabRouteMap.value[key] === newPath) |
|
|
if (tabKey) { |
|
|
activeTab.value = tabKey |
|
|
} else { |
|
|
|
|
|
const routeName = route.name |
|
|
const nameToTabMap = { |
|
|
Dashboard: 'dashboard', |
|
|
ApiKeys: 'apiKeys', |
|
|
Accounts: 'accounts', |
|
|
Tutorial: 'tutorial', |
|
|
Settings: 'settings' |
|
|
} |
|
|
if (routeName && nameToTabMap[routeName]) { |
|
|
activeTab.value = nameToTabMap[routeName] |
|
|
} |
|
|
} |
|
|
} |
|
|
) |
|
|
|
|
|
|
|
|
const handleTabChange = async (tabKey) => { |
|
|
|
|
|
if (tabRouteMap.value[tabKey] === route.path) { |
|
|
return |
|
|
} |
|
|
|
|
|
|
|
|
activeTab.value = tabKey |
|
|
|
|
|
|
|
|
try { |
|
|
await router.push(tabRouteMap.value[tabKey]) |
|
|
|
|
|
await nextTick() |
|
|
} catch (err) { |
|
|
|
|
|
if (err.name !== 'NavigationDuplicated') { |
|
|
console.error('路由切换失败:', err) |
|
|
|
|
|
initActiveTab() |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
</script> |
|
|
|
|
|
<style scoped> |
|
|
|
|
|
</style> |
|
|
|