Files
zmAI/demo/frontend/src/components/TopHeader.vue

121 lines
2.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<header class="top-header">
<div class="header-left">
<slot name="left" />
</div>
<div class="header-right">
<slot name="right">
<!-- 默认右侧内容积分 + 语言切换 + 头像 -->
<div v-if="showPoints" class="points-badge">
<div class="points-icon">
<StarOutlined />
</div>
<span class="points-number">{{ userStore.availablePoints }}</span>
</div>
<LanguageSwitcher />
<div v-if="showAvatar" ref="avatarRef" class="user-avatar" @click="$emit('avatar-click')">
<img src="/images/backgrounds/avatar-default.svg" alt="Avatar" />
</div>
</slot>
</div>
</header>
</template>
<script setup>
import { ref } from 'vue'
import { StarOutlined } from '@ant-design/icons-vue'
import LanguageSwitcher from '@/components/LanguageSwitcher.vue'
import { useUserStore } from '@/stores/user'
defineProps({
showPoints: { type: Boolean, default: true },
showAvatar: { type: Boolean, default: true }
})
defineEmits(['avatar-click'])
const userStore = useUserStore()
const avatarRef = ref(null)
defineExpose({ avatarRef })
</script>
<style scoped>
.top-header {
height: var(--header-height, 64px);
padding: 0 var(--space-8);
border-bottom: 1px solid var(--border-subtle);
display: flex;
align-items: center;
justify-content: space-between;
background: var(--bg-surface);
flex-shrink: 0;
z-index: var(--z-sticky, 200);
}
.header-left {
display: flex;
align-items: center;
}
.header-right {
display: flex;
align-items: center;
gap: var(--space-5);
margin-left: auto;
}
/* Points Badge */
.points-badge {
display: flex;
align-items: center;
gap: var(--space-2);
padding: 6px 14px;
background: var(--gradient-brand);
border-radius: var(--radius-full, 9999px);
border: none;
box-shadow: 0 2px 10px rgba(124, 58, 237, 0.2);
}
.points-icon {
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.25);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 11px;
}
.points-number {
color: #fff;
font-size: var(--text-sm);
font-weight: var(--font-semibold, 600);
}
/* User Avatar */
.user-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
cursor: pointer;
transition: transform 250ms ease;
overflow: hidden;
border: 1px solid var(--border-subtle);
}
.user-avatar:hover {
transform: scale(1.08);
border-color: var(--border-default);
}
.user-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
}
</style>