383 lines
11 KiB
Vue
383 lines
11 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: any) => {
|
|
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: '0',
|
|
},
|
|
{
|
|
label: '我的作品',
|
|
key: '2',
|
|
},
|
|
{
|
|
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)
|
|
}
|
|
}
|
|
else if (key === 'like') {
|
|
router.push(`/personal-center?type=${key}`)
|
|
}
|
|
else {
|
|
router.push(`/personal-center?status=${key}`)
|
|
}
|
|
}
|
|
// 发布下拉选项
|
|
async function handlePublishSelect(key: string) {
|
|
if (!userStore?.userInfo.name)
|
|
return
|
|
if (!userStore.isLoggedIn) {
|
|
modalStore.showLoginModal()
|
|
}
|
|
else {
|
|
if (key === 'picture') {
|
|
isShowPublishPicture.value = true
|
|
if (PublishPictureRef.value) {
|
|
PublishPictureRef.value.isVisible = true
|
|
}
|
|
}
|
|
else {
|
|
const baseUrl = window.location.origin
|
|
debugger
|
|
window.open(`${baseUrl}/${key}?type=add`, '_blank', 'noopener,noreferrer')
|
|
// router.push({
|
|
// path: `/${key}`,
|
|
// query: {
|
|
// type: 'add',
|
|
// },
|
|
// })
|
|
}
|
|
}
|
|
}
|
|
function closePublishImg() {
|
|
isShowPublishPicture.value = false
|
|
if (PublishPictureRef.value) {
|
|
PublishPictureRef.value.isVisible = false
|
|
}
|
|
}
|
|
|
|
function handleLogin() {
|
|
modalStore.showLoginModal()
|
|
}
|
|
|
|
const msgList = ref([])
|
|
async function getAllMessage() {
|
|
try {
|
|
const res = await request.get('/advice/getAllMsg')
|
|
if (res.code === 200) {
|
|
msgList.value = res.data
|
|
}
|
|
}
|
|
catch (err) {
|
|
console.log(err)
|
|
}
|
|
}
|
|
// getAllMessage();
|
|
|
|
// 跳转到消息详情
|
|
function toDetail() {
|
|
const baseUrl = window.location.origin
|
|
window.open(`${baseUrl}/message`, '_blank', 'noopener,noreferrer')
|
|
}
|
|
|
|
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">
|
|
<div class="flex items-center cursor-pointer" @click="handleTabClick('/')">
|
|
<img
|
|
src="@/assets/img/logo.png"
|
|
alt="魔创未来"
|
|
class="h-8 w-8"
|
|
>
|
|
<span class="text-[#328AFE] text-xl font-bold ml-2">魔创未来</span>
|
|
</div>
|
|
<NuxtLink to="/" class="text-xl font-semibold tracking-tight no-underline">
|
|
<!-- <img src="/vite.png" alt="Logo" class="h-9 w-9" /> -->
|
|
<!-- 魔创未来 -->
|
|
<!-- <img
|
|
src="https://liblibai-web-static.liblib.cloud/liblibai_v4_online/static/_next/static/images/icon-logo.e3ce24f316fb81dbde1cafc3bf956080.svg"
|
|
alt=""
|
|
/> -->
|
|
<!-- <a class="Topbar_iconLogo__RhuYB" style="background-image: url("https://liblibai-web-static.liblib.cloud/liblibai_v4_online/static/_next/static/images/icon-logo.e3ce24f316fb81dbde1cafc3bf956080.svg");"></a> -->
|
|
</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 -->
|
|
<div class="header-btn-primary">
|
|
<Monitor class="h-4 w-4 mr-1" />
|
|
<span>PC客户端</span>
|
|
</div>
|
|
<!-- <NButton text class="header-btn-primary">
|
|
|
|
</NButton> -->
|
|
|
|
<!-- Tutorials -->
|
|
<NButton text class="header-btn">
|
|
<GraduationCap class="h-4 w-4 mr-1" />
|
|
<span>教程专区</span>
|
|
</NButton>
|
|
|
|
<!-- <div class="header-btn">
|
|
<GraduationCap class="h-4 w-4 mr-1" />
|
|
<span>教程专区</span>
|
|
</div> -->
|
|
|
|
<NDropdown
|
|
:options="publishOptions"
|
|
trigger="hover"
|
|
:on-select="handlePublishSelect"
|
|
>
|
|
<NButton text class="header-btn" size="large">
|
|
<CirclePlus class="h-4 w-4 mr-1" />
|
|
<span>发布</span>
|
|
</NButton>
|
|
</NDropdown>
|
|
|
|
<!-- Notifications -->
|
|
<!-- :options="notificationOptions" -->
|
|
<!-- <NDropdown trigger="click">
|
|
<NBadge :value="5" :max="99" processing>
|
|
<NButton text circle>
|
|
<Bell class="h-5 w-5 mr-1 relative" />
|
|
<div class="absolute top-2 right-1 border-solid border-2 border-[#f0f0f0] py-2">
|
|
<div class="border-b-solid border-b-2 border-b-[#f0f0f0]">
|
|
通知
|
|
</div>
|
|
<div v-for="(item,index) in 3">
|
|
1111
|
|
</div>
|
|
</div>
|
|
</NButton>
|
|
</NBadge>
|
|
</NDropdown> -->
|
|
<client-only v-if="userStore.token">
|
|
<div
|
|
class="p-1 bg-[#f1f1f6] rounded-full flex items-center justify-center relative group"
|
|
>
|
|
<Bell class="h-5 w-5relative cursor-pointer" @mouseenter="getAllMessage" />
|
|
<div class="pt-4 absolute top-5 -right-4 hidden group-hover:block">
|
|
<div
|
|
class="border-solid border border-[#f0f0f0] py-2 w-[300px] rounded-lg bg-white"
|
|
>
|
|
<div
|
|
class="border-b-solid border-b border-b-[#f0f0f0] p-4 text-sm font-bold"
|
|
>
|
|
通知
|
|
</div>
|
|
<div class="px-4 py-2 max-h-[300px] overflow-y-auto">
|
|
<div
|
|
v-for="(item, index) in msgList"
|
|
:key="index"
|
|
class="flex items-center my-2 cursor-pointer"
|
|
>
|
|
<div class="flex-1">
|
|
<n-ellipsis
|
|
style="max-width: 250px"
|
|
:tooltip="false"
|
|
class="font-bold text-gray-600"
|
|
>
|
|
{{ item.content }}
|
|
</n-ellipsis>
|
|
<div class="text-[12px] text-gray-400">
|
|
{{ item.createTime }}
|
|
</div>
|
|
</div>
|
|
<div class="w-4 flex h-[100%] items-center justify-center">
|
|
<div
|
|
v-if="item.isRead === '0'"
|
|
class="w-2 h-2 bg-[#ea5049] rounded"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="my-4 text-gray-500 text-sm text-center">
|
|
更多通知可点击查看全部~
|
|
</div>
|
|
<div class="flex justify-center">
|
|
<div
|
|
class="bg-[#4c79ee] w-[270px] h-10 flex items-center justify-center rounded-lg text-white cursor-pointer"
|
|
@click="toDetail"
|
|
>
|
|
查看全部
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</client-only>
|
|
|
|
<!-- User -->
|
|
<div class="min-w-10 flex items-center">
|
|
<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-gradient-to-r from-[#197dff] to-[#2c4dff] 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"
|
|
type="add"
|
|
: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] flex items-center cursor-pointer;
|
|
}
|
|
.header-btn {
|
|
@apply bg-[#f1f1f7] font-bold px-2 py-2 rounded flex items-center hover:text-black hover:bg-[#f1f1f7] focus:text-blue-600;
|
|
}
|
|
</style>
|