更新首页
This commit is contained in:
@@ -40,46 +40,46 @@
|
||||
</div>
|
||||
|
||||
<!-- 右侧操作区 -->
|
||||
<div class="flex items-center gap-2 flex-shrink-0 nav-right">
|
||||
<!-- PC 端:登录/头像 -->
|
||||
<div class="hidden md:flex items-center gap-3">
|
||||
<template v-if="!isAuthed">
|
||||
<a-button type="primary" @click="navigateTo('/login')">{{ '登录' }}</a-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- 用户头像 -->
|
||||
<a-dropdown :trigger="['hover']" placement="bottomRight">
|
||||
<a-space>
|
||||
<a-avatar :src="userAvatar" :size="32">
|
||||
<template v-if="!userAvatar" #icon>
|
||||
<UserOutlined />
|
||||
</template>
|
||||
</a-avatar>
|
||||
<span class="text-gray-100">{{ userName }}</span>
|
||||
</a-space>
|
||||
<template #overlay>
|
||||
<a-menu @click="onUserMenuClick">
|
||||
<a-menu-item key="profile"><ProfileOutlined style="margin-right: 8px" />个人信息</a-menu-item>
|
||||
<a-menu-item key="my-suggestions"><MessageOutlined style="margin-right: 8px" />我的建言</a-menu-item>
|
||||
<template v-if="isSuperAdmin">
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="admin">⚙️ 后台管理</a-menu-item>
|
||||
</template>
|
||||
<a-menu-divider />
|
||||
<a-menu-item key="logout">{{ '退出登录' }}</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</div>
|
||||
<!-- <div class="flex items-center gap-2 flex-shrink-0 nav-right">-->
|
||||
<!-- <!– PC 端:登录/头像 –>-->
|
||||
<!-- <div class="hidden md:flex items-center gap-3">-->
|
||||
<!-- <template v-if="!isAuthed">-->
|
||||
<!-- <a-button type="primary" @click="navigateTo('/login')">{{ '登录' }}</a-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-else>-->
|
||||
<!-- <!– 用户头像 –>-->
|
||||
<!-- <a-dropdown :trigger="['hover']" placement="bottomRight">-->
|
||||
<!-- <a-space>-->
|
||||
<!-- <a-avatar :src="userAvatar" :size="32">-->
|
||||
<!-- <template v-if="!userAvatar" #icon>-->
|
||||
<!-- <UserOutlined />-->
|
||||
<!-- </template>-->
|
||||
<!-- </a-avatar>-->
|
||||
<!-- <span class="text-gray-100">{{ userName }}</span>-->
|
||||
<!-- </a-space>-->
|
||||
<!-- <template #overlay>-->
|
||||
<!-- <a-menu @click="onUserMenuClick">-->
|
||||
<!-- <a-menu-item key="profile"><ProfileOutlined style="margin-right: 8px" />个人信息</a-menu-item>-->
|
||||
<!-- <a-menu-item key="my-suggestions"><MessageOutlined style="margin-right: 8px" />我的建言</a-menu-item>-->
|
||||
<!-- <template v-if="isSuperAdmin">-->
|
||||
<!-- <a-menu-divider />-->
|
||||
<!-- <a-menu-item key="admin">⚙️ 后台管理</a-menu-item>-->
|
||||
<!-- </template>-->
|
||||
<!-- <a-menu-divider />-->
|
||||
<!-- <a-menu-item key="logout">{{ '退出登录' }}</a-menu-item>-->
|
||||
<!-- </a-menu>-->
|
||||
<!-- </template>-->
|
||||
<!-- </a-dropdown>-->
|
||||
<!-- </template>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- 移动端:汉堡菜单按钮 -->
|
||||
<button class="md:hidden flex flex-col justify-center items-center w-10 h-10 gap-1.5 rounded-lg bg-white/10 hover:bg-white/20 border border-white/20 transition-colors" @click="open = true">
|
||||
<span class="block w-5 h-0.5 bg-white rounded-full"></span>
|
||||
<span class="block w-5 h-0.5 bg-white rounded-full"></span>
|
||||
<span class="block w-5 h-0.5 bg-white rounded-full"></span>
|
||||
</button>
|
||||
</div>
|
||||
<!-- <!– 移动端:汉堡菜单按钮 –>-->
|
||||
<!-- <button class="md:hidden flex flex-col justify-center items-center w-10 h-10 gap-1.5 rounded-lg bg-white/10 hover:bg-white/20 border border-white/20 transition-colors" @click="open = true">-->
|
||||
<!-- <span class="block w-5 h-0.5 bg-white rounded-full"></span>-->
|
||||
<!-- <span class="block w-5 h-0.5 bg-white rounded-full"></span>-->
|
||||
<!-- <span class="block w-5 h-0.5 bg-white rounded-full"></span>-->
|
||||
<!-- </button>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</a-layout-header>
|
||||
</a-affix>
|
||||
@@ -102,14 +102,14 @@
|
||||
</a-menu-item>
|
||||
</template>
|
||||
</a-menu>
|
||||
<div class="mt-4">
|
||||
<a-button v-if="!isAuthed" block type="primary" @click="onNav('/login')">{{ '登录' || '登录' }}</a-button>
|
||||
<template v-else>
|
||||
<a-button block type="primary" class="mb-2" @click="onNav('/profile')">个人中心</a-button>
|
||||
<a-button v-if="isSuperAdmin" block @click="onNav('/admin')">⚙️ 后台管理</a-button>
|
||||
<a-button block danger class="mt-2" @click="logout">{{ '退出登录' || '退出登录' }}</a-button>
|
||||
</template>
|
||||
</div>
|
||||
<!-- <div class="mt-4">-->
|
||||
<!-- <a-button v-if="!isAuthed" block type="primary" @click="onNav('/login')">{{ '登录' || '登录' }}</a-button>-->
|
||||
<!-- <template v-else>-->
|
||||
<!-- <a-button block type="primary" class="mb-2" @click="onNav('/profile')">个人中心</a-button>-->
|
||||
<!-- <a-button v-if="isSuperAdmin" block @click="onNav('/admin')">⚙️ 后台管理</a-button>-->
|
||||
<!-- <a-button block danger class="mt-2" @click="logout">{{ '退出登录' || '退出登录' }}</a-button>-->
|
||||
<!-- </template>-->
|
||||
<!-- </div>-->
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
@@ -128,10 +128,26 @@ const open = ref(false)
|
||||
|
||||
const selectedKeys = computed(() => {
|
||||
const currentPath = route.path
|
||||
const currentType = typeof route.query.type === 'string' ? route.query.type : ''
|
||||
|
||||
const exactChildHit = nav.value
|
||||
.flatMap(item => item.children || [])
|
||||
.find((item) => item.to === route.fullPath || buildPathWithQuery(item.to) === route.fullPath)
|
||||
if (exactChildHit) return [exactChildHit.key]
|
||||
|
||||
const exactHit = nav.value.find((item) => item.to === currentPath)
|
||||
if (exactHit) return [exactHit.key]
|
||||
|
||||
if (currentType) {
|
||||
const childTypeHit = nav.value
|
||||
.flatMap(item => item.children || [])
|
||||
.find((item) => {
|
||||
const child = normalizeNavTarget(item.to)
|
||||
return child.path === currentPath && child.type === currentType
|
||||
})
|
||||
if (childTypeHit) return [childTypeHit.key]
|
||||
}
|
||||
|
||||
const prefixHit = nav.value.find((item) => item.to !== '/' && currentPath.startsWith(`${item.to}/`))
|
||||
if (prefixHit) return [prefixHit.key]
|
||||
|
||||
@@ -141,6 +157,20 @@ const selectedKeys = computed(() => {
|
||||
return ['home']
|
||||
})
|
||||
|
||||
function normalizeNavTarget(to: string) {
|
||||
const [path, search = ''] = to.split('?')
|
||||
const params = new URLSearchParams(search)
|
||||
return {
|
||||
path,
|
||||
type: params.get('type') || '',
|
||||
}
|
||||
}
|
||||
|
||||
function buildPathWithQuery(to: string) {
|
||||
const normalized = normalizeNavTarget(to)
|
||||
return normalized.type ? `${normalized.path}?type=${normalized.type}` : normalized.path
|
||||
}
|
||||
|
||||
// 获取 badge 样式类
|
||||
function getBadgeClass(badge: string) {
|
||||
const baseClass = 'ml-1.5 px-1.5 py-0.5 text-xs font-medium rounded'
|
||||
@@ -157,7 +187,7 @@ const token = ref('')
|
||||
const user = ref<User | null>(null)
|
||||
const isAuthed = computed(() => !!token.value)
|
||||
const userName = computed(() => String(user.value?.nickname || user.value?.username || '已登录'))
|
||||
const isSuperAdmin = computed(() => !!(user.value as any)?.isAdmin)
|
||||
const isSuperAdmin = computed(() => !!(user.value as User & { isAdmin?: boolean } | null)?.isAdmin)
|
||||
const userAvatar = computed(() => {
|
||||
const candidate =
|
||||
user.value?.avatarUrl ||
|
||||
|
||||
Reference in New Issue
Block a user