统一角色体系为admin/agent/user,修复代理查询角色错误,添加语言切换和明暗切换
This commit is contained in:
@@ -7,10 +7,10 @@ import TeamSwitcher from '@/components/app-sidebar/team-switcher.vue'
|
||||
import NavFooter from '@/components/developer-sidebar/nav-footer.vue'
|
||||
|
||||
const user = reactive({
|
||||
name: '开发者',
|
||||
email: 'developer@example.com',
|
||||
avatar: '/avatars/developer.jpg',
|
||||
role: 'developer',
|
||||
name: '管理员',
|
||||
email: 'admin@example.com',
|
||||
avatar: '/avatars/admin.jpg',
|
||||
role: 'admin',
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -228,7 +228,7 @@ watch(route, () => {
|
||||
{{ t('nav.pricing') }}
|
||||
</router-link>
|
||||
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'developer'">
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'admin'">
|
||||
<div class="w-px h-4 bg-border mx-1" />
|
||||
|
||||
<UiDropdownMenu>
|
||||
@@ -300,79 +300,6 @@ watch(route, () => {
|
||||
</UiDropdownMenuContent>
|
||||
</UiDropdownMenu>
|
||||
</template>
|
||||
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'admin'">
|
||||
<div class="w-px h-4 bg-border mx-1" />
|
||||
|
||||
<UiDropdownMenu>
|
||||
<UiDropdownMenuTrigger as-child>
|
||||
<button
|
||||
class="transition-colors hover:text-foreground/80 px-3 py-2 rounded-lg flex items-center gap-1"
|
||||
:class="isMenuActive(adminMenus.main.items) ? 'text-foreground bg-accent' : 'text-foreground/60'"
|
||||
>
|
||||
{{ adminMenus.main.title }}
|
||||
<Icon icon="lucide:chevron-down" class="h-4 w-4" />
|
||||
</button>
|
||||
</UiDropdownMenuTrigger>
|
||||
<UiDropdownMenuContent align="start" class="w-40">
|
||||
<UiDropdownMenuItem
|
||||
v-for="item in adminMenus.main.items"
|
||||
:key="item.url"
|
||||
:class="route.path === item.url ? 'bg-accent' : ''"
|
||||
@click="router.push(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="mr-2 h-4 w-4" />
|
||||
{{ item.title }}
|
||||
</UiDropdownMenuItem>
|
||||
</UiDropdownMenuContent>
|
||||
</UiDropdownMenu>
|
||||
|
||||
<UiDropdownMenu>
|
||||
<UiDropdownMenuTrigger as-child>
|
||||
<button
|
||||
class="transition-colors hover:text-foreground/80 px-3 py-2 rounded-lg flex items-center gap-1"
|
||||
:class="isMenuActive(adminMenus.content.items) ? 'text-foreground bg-accent' : 'text-foreground/60'"
|
||||
>
|
||||
{{ adminMenus.content.title }}
|
||||
<Icon icon="lucide:chevron-down" class="h-4 w-4" />
|
||||
</button>
|
||||
</UiDropdownMenuTrigger>
|
||||
<UiDropdownMenuContent align="start" class="w-40">
|
||||
<UiDropdownMenuItem
|
||||
v-for="item in adminMenus.content.items"
|
||||
:key="item.url"
|
||||
:class="route.path === item.url ? 'bg-accent' : ''"
|
||||
@click="router.push(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="mr-2 h-4 w-4" />
|
||||
{{ item.title }}
|
||||
</UiDropdownMenuItem>
|
||||
</UiDropdownMenuContent>
|
||||
</UiDropdownMenu>
|
||||
|
||||
<UiDropdownMenu>
|
||||
<UiDropdownMenuTrigger as-child>
|
||||
<button
|
||||
class="transition-colors hover:text-foreground/80 px-3 py-2 rounded-lg flex items-center gap-1"
|
||||
:class="isMenuActive(adminMenus.system.items) ? 'text-foreground bg-accent' : 'text-foreground/60'"
|
||||
>
|
||||
{{ adminMenus.system.title }}
|
||||
<Icon icon="lucide:chevron-down" class="h-4 w-4" />
|
||||
</button>
|
||||
</UiDropdownMenuTrigger>
|
||||
<UiDropdownMenuContent align="start" class="w-40">
|
||||
<UiDropdownMenuItem
|
||||
v-for="item in adminMenus.system.items"
|
||||
:key="item.url"
|
||||
:class="route.path === item.url ? 'bg-accent' : ''"
|
||||
@click="router.push(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="mr-2 h-4 w-4" />
|
||||
{{ item.title }}
|
||||
</UiDropdownMenuItem>
|
||||
</UiDropdownMenuContent>
|
||||
</UiDropdownMenu>
|
||||
</template>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -438,18 +365,14 @@ watch(route, () => {
|
||||
<Icon icon="lucide:user" class="mr-2 h-4 w-4" />
|
||||
<span>{{ t('nav.profile') }}</span>
|
||||
</UiDropdownMenuItem>
|
||||
<UiDropdownMenuItem v-if="currentUser?.role === 'developer'" @click="router.push('/developer')">
|
||||
<UiDropdownMenuItem v-if="currentUser?.role === 'admin'" @click="router.push('/developer')">
|
||||
<Icon icon="lucide:layout-dashboard" class="mr-2 h-4 w-4" />
|
||||
<span>{{ t('nav.developerDashboard') }}</span>
|
||||
</UiDropdownMenuItem>
|
||||
<UiDropdownMenuItem v-if="currentUser?.role === 'agent'" @click="router.push('/agent/dashboard')">
|
||||
<UiDropdownMenuItem v-if="currentUser?.role === 'agent'" @click="router.push('/agent')">
|
||||
<Icon icon="lucide:layout-dashboard" class="mr-2 h-4 w-4" />
|
||||
<span>{{ t('nav.agentDashboard') }}</span>
|
||||
</UiDropdownMenuItem>
|
||||
<UiDropdownMenuItem v-if="currentUser?.role === 'admin'" @click="router.push('/admin')">
|
||||
<Icon icon="lucide:shield" class="mr-2 h-4 w-4" />
|
||||
<span>{{ t('nav.adminDashboard') }}</span>
|
||||
</UiDropdownMenuItem>
|
||||
<UiDropdownMenuSeparator />
|
||||
<UiDropdownMenuItem @click="handleLogout">
|
||||
<Icon icon="lucide:log-out" class="mr-2 h-4 w-4" />
|
||||
@@ -502,7 +425,7 @@ watch(route, () => {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'developer'">
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'admin'">
|
||||
<div class="space-y-1">
|
||||
<p class="text-xs font-medium text-muted-foreground px-3 mb-2">
|
||||
{{ developerMenus.main.title }}
|
||||
@@ -551,56 +474,6 @@ watch(route, () => {
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="isLoggedIn && currentUser?.role === 'admin'">
|
||||
<div class="space-y-1">
|
||||
<p class="text-xs font-medium text-muted-foreground px-3 mb-2">
|
||||
{{ adminMenus.main.title }}
|
||||
</p>
|
||||
<button
|
||||
v-for="item in adminMenus.main.items"
|
||||
:key="item.url"
|
||||
class="w-full flex items-center gap-3 px-3 py-2 text-sm rounded-lg transition-colors"
|
||||
:class="isActive(item.url) ? 'bg-accent text-foreground' : 'text-muted-foreground hover:bg-accent hover:text-foreground'"
|
||||
@click="navigateTo(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="size-4" />
|
||||
{{ item.title }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<p class="text-xs font-medium text-muted-foreground px-3 mb-2">
|
||||
{{ adminMenus.content.title }}
|
||||
</p>
|
||||
<button
|
||||
v-for="item in adminMenus.content.items"
|
||||
:key="item.url"
|
||||
class="w-full flex items-center gap-3 px-3 py-2 text-sm rounded-lg transition-colors"
|
||||
:class="isActive(item.url) ? 'bg-accent text-foreground' : 'text-muted-foreground hover:bg-accent hover:text-foreground'"
|
||||
@click="navigateTo(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="size-4" />
|
||||
{{ item.title }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="space-y-1">
|
||||
<p class="text-xs font-medium text-muted-foreground px-3 mb-2">
|
||||
{{ adminMenus.system.title }}
|
||||
</p>
|
||||
<button
|
||||
v-for="item in adminMenus.system.items"
|
||||
:key="item.url"
|
||||
class="w-full flex items-center gap-3 px-3 py-2 text-sm rounded-lg transition-colors"
|
||||
:class="isActive(item.url) ? 'bg-accent text-foreground' : 'text-muted-foreground hover:bg-accent hover:text-foreground'"
|
||||
@click="navigateTo(item.url)"
|
||||
>
|
||||
<Icon :icon="item.icon" class="size-4" />
|
||||
{{ item.title }}
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</nav>
|
||||
|
||||
<div v-if="!isLoggedIn" class="pt-4 border-t mt-4 space-y-2">
|
||||
|
||||
Reference in New Issue
Block a user