mcwl-pc/app/components/Header.vue

257 lines
6.1 KiB
Vue

<script setup lang="ts">
// 输入框搜索
import { headerRole } from '@/constants/index'
import {
Bell,
CirclePlus,
GraduationCap,
HardDriveUpload,
Image,
Monitor,
Workflow,
} from 'lucide-vue-next'
import { NConfigProvider, NMessageProvider } from 'naive-ui'
// import { AtCircle } from '@vicons/ionicons5'
import { NIcon } from 'naive-ui'
import { onMounted, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const modalStore = useModalStore()
const currentUseRoute = ref('')
const isShowPublishPicture = ref<boolean>(false)
const PublishPictureRef = ref<Payment | null>(null)
const publishPicture = ref({
title: '',
tags: [],
description: '',
imagePaths: [],
})
watch(
() => route.path, // 监听 route.path 的变化
(newPath) => {
currentUseRoute.value = newPath
},
{ immediate: true }, // 立即执行一次
)
function hasItem(path: string, list: any) {
return !list.includes(path)
}
const searchText = ref('')
function onSearch(value: any) {
console.log('搜索:', value)
// 执行搜索逻辑
}
// 用户下拉选项
const notificationOptions = [
{
label: '系统通知',
key: 'system',
},
{
label: '互动消息',
key: 'interaction',
},
]
function renderIcon(icon: Component) {
return () => {
return h(NIcon, null, {
default: () => h(icon),
})
}
}
// 发布下拉选项
const publishOptions = [
{
label: '模型',
key: 'publish-model',
icon: renderIcon(HardDriveUpload),
},
{
label: '图片',
key: 'picture',
icon: renderIcon(Image),
},
{
label: '工作流',
key: 'publish-workflow',
icon: renderIcon(Workflow),
},
]
const userOptions = ref([
{
label: '我的模型',
key: 'model',
},
{
label: '我的作品',
key: 'project',
},
{
label: '我的点赞',
key: 'like',
},
{
label: '账号设置',
key: 'userSettings',
},
{
label: '退出登录',
key: 'logout',
},
])
// 用户下拉选项
async function handleUserSelect(key: string) {
if (key === 'logout') {
try {
await request.post('/logout')
userStore.logout()
navigateTo('/model-square')
}
catch (error) {
console.error('Logout failed:', error)
}
}
}
// 发布下拉选项
async function handlePublishSelect(key: string) {
if (key === 'picture') {
isShowPublishPicture.value = true
if (PublishPictureRef.value) {
PublishPictureRef.value.isVisible = true
}
}
else {
router.push({
path: `/${key}`,
query: {
type: 'add',
},
})
}
}
function closePublishImg() {
isShowPublishPicture.value = false
if (PublishPictureRef.value) {
PublishPictureRef.value.isVisible = false
}
}
function handleLogin() {
modalStore.showLoginModal()
}
onMounted(() => {
})
</script>
<template>
<div>
<header
class="sticky top-0 z-50 flex h-12 items-center justify-between border-b border-gray-100 bg-white/80 px-6 backdrop-blur dark:border-dark-700 dark:bg-dark-800/80"
>
<div class="flex items-center gap-6">
<!-- Logo 区域调整 -->
<div class="flex min-w-[130px] items-center gap-3 pr-4">
<div class="flex items-center gap-2">
<NuxtLink to="/" class="text-xl font-semibold tracking-tight no-underline">
<!-- <img src="/vite.png" alt="Logo" class="h-9 w-9" /> -->
魔创未来
</NuxtLink>
<!-- <span class="text-xl font-semibold tracking-tight">魔创未来</span> -->
</div>
</div>
<!-- <HeaderSearchInput /> -->
<HeaderSearchInput
v-if="hasItem(currentUseRoute, headerRole.inputSearch)"
v-model="searchText"
@search="onSearch"
/>
</div>
<!-- Right Actions -->
<NSpace align="center" :size="24">
<!-- PC Client -->
<NButton text class="header-btn-primary">
<Monitor class="h-4 w-4 mr-1" />
<span>PC客户端</span>
</NButton>
<!-- Tutorials -->
<NButton text class="header-btn">
<GraduationCap class="h-4 w-4 mr-1" />
<span>教程专区</span>
</NButton>
<NDropdown
:options="publishOptions"
trigger="hover"
:on-select="handlePublishSelect"
>
<NButton text class="header-btn">
<CirclePlus class="h-4 w-4 mr-1" />
<span>发布</span>
</NButton>
</NDropdown>
<!-- Notifications -->
<NDropdown :options="notificationOptions" trigger="click">
<NBadge :value="5" :max="99" processing>
<NButton text circle>
<Bell class="h-5 w-5 mr-1" />
</NButton>
</NBadge>
</NDropdown>
<!-- User -->
<div class="min-w-10">
<client-only>
<NDropdown
v-if="userStore.token"
:options="userOptions"
:on-select="handleUserSelect"
trigger="hover"
>
<NAvatar
class="cursor-pointer w-10 h-10"
round
size="small"
:src="userStore.userInfo.avatar"
/>
</NDropdown>
<div
v-if="!userStore.token"
class="flex text-white bg-[#197dff] rounded-[4px] px-4 py-2 text-xs cursor-pointer hover:bg-[#1a6eff]"
@click="handleLogin"
>
登录/注册
</div>
</client-only>
</div>
</NSpace>
</header>
<div>
<NConfigProvider>
<NMessageProvider>
<Publish-picture v-if="isShowPublishPicture" ref="PublishPictureRef" :form-data="publishPicture" @close-publish-img="closePublishImg" />
</NMessageProvider>
</NConfigProvider>
</div>
</div>
</template>
<style scoped>
.header-btn-primary {
@apply border border-solid border-[#3162ff] px-1 py-1 text-[#3162ff] rounded-md hover:text-[#3162ff];
}
.header-btn {
@apply bg-[#f1f1f7] font-bold px-2 py-2 rounded flex items-center hover:text-black hover:bg-[#f1f1f7];
}
</style>