基于Java spring + vue3 + nuxt构建的内容管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

174 lines
6.4 KiB

<template>
<header class="header bg-white z-100 top-0 w-full" :class="affix ? 'absolute' : 'fixed'">
<div class="flex items-center between md:w-screen-xl m-auto px-2">
<div class="header___left flex items-center">
<div class="logo mt-1 sm:w-[170px] h-7 w-auto py-2 flex items-center">
<nuxt-link v-if="config?.siteLogo" to="/">
<el-image
:src="config.siteLogo"
shape="square"
fit="fill"
class="sm:h-7 h-6 sm:w-auto w-17"
:alt="config.siteName"
:title="config.siteName"
/>
</nuxt-link>
<nuxt-link v-else to="/">
<text>{{ config?.siteName }}</text>
</nuxt-link>
</div>
<nav class="hidden-sm-and-down">
<el-menu
:default-active="currentIndex"
mode="horizontal"
text-color="#000000"
active-text-color="#000000"
:collapse="true"
:ellipsis="true"
style="border: none"
@select="handleSelect"
>
<template v-for="(item, index) in navigations">
<el-menu-item :index="`${item.path}`">
<el-sub-menu v-if="item?.children && item.children.length > 0" :index="`${item.path}`">
<template #title><h3>{{ item.title }}</h3></template>
<el-menu-item v-for="(sub,subIndex) in item.children" :index="`${sub.path}`">{{ sub.title }}</el-menu-item>
<!-- <el-sub-menu index="2-4">-->
<!-- <template #title>item four</template>-->
<!-- <el-menu-item index="2-4-1">item one</el-menu-item>-->
<!-- <el-menu-item index="2-4-2">item two</el-menu-item>-->
<!-- <el-menu-item index="2-4-3">item three</el-menu-item>-->
<!-- </el-sub-menu>-->
</el-sub-menu>
<el-menu-item v-else :index="`${item.path}`"><h3>{{ item.title }}</h3></el-menu-item>
</el-menu-item>
</template>
<!-- 顶部菜单超出数量折叠 -->
<!-- <el-sub-menu index="more" v-if="navigations && navigations.length > (config.elMenuMaxNumber)">-->
<!-- <template #title>更多菜单</template>-->
<!-- <template v-for="(item, index) in navigations">-->
<!-- <el-menu-item :index="item.path" :key="index" v-if="index >= (config.elMenuMaxNumber)">-->
<!-- <text :class="item.style">{{ item.title }}</text>-->
<!-- </el-menu-item-->
<!-- >-->
<!-- </template>-->
<!-- </el-sub-menu>-->
</el-menu>
</nav>
</div>
<div class="header__right items-center">
<el-space class="sm:flex hidden" v-if="config.showSearchTools">
<el-input
class="w-20"
placeholder="站内搜索"
:suffix-icon="ElIconSearch"
v-model="searchValue"
@keyup.enter.native="handleSearch"
/>
<el-button v-if="token" @click="openSpmUrl(`https://${website.tenantId}.websoft.top/token-login`,website,website.websiteId)">控制台</el-button>
<ClientOnly>
<template v-if="token">
<el-dropdown @command="handleCommand">
<el-avatar class="cursor-pointer" :src="userInfo?.avatar" :size="30" />
<el-button circle :icon="ElIconUserFilled" color="#155FAA"></el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="user">个人中心</el-dropdown-item>
<el-dropdown-item divided command="logOut" @click="navigateTo('/user/logout')">退出</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<template v-else>
<!-- <el-button v-if="config.showSearchIcon" circle :icon="ElIconSearch" @click="navigateTo('/search')"></el-button>-->
<el-button v-if="config.showLoginButton" circle :icon="ElIconUserFilled" @click="goLogin"></el-button>
</template>
</ClientOnly>
</el-space>
</div>
</div>
<Passport :visible="showPassport" @done="reload" />
</header>
<div class="header__height__placeholder"></div>
</template>
<script setup lang="ts">
// 引入所需的图标
import {
useConfigInfo,
useMenu,
useProductAffix,
useShowLogin,
useToken, useUser,
useWebsite
} from "~/composables/configState";
import UnderMaintenance from "~/components/UnderMaintenance.vue";
import {useServerRequest} from "~/composables/useServerRequest";
import type {ApiResult} from "~/api";
import type {User} from "~/api/system/user/model";
import {navigateTo, openSpmUrl} from "#imports";
const route = useRoute();
// 配置信息
const runtimeConfig = useRuntimeConfig();
const website = useWebsite()
const showPassport = ref<boolean>(false);
const searchValue = ref<string>();
const token = useToken();
const userInfo = ref<User>();
const showLogin = useShowLogin();
const navigations = useMenu();
const config = useConfigInfo();
const affix = useProductAffix();
// 顶部栏初始数
const visibleNumber = ref<number>(6);
config.value.elMenuMaxNumber = 8;
// 当前激活菜单的 index
const currentIndex = ref<string>('/');
function handleCommand(command: string) {
switch (command) {
case 'logOut':
logOut();
break;
default:
navigateTo('/user');
break;
}
}
function logOut() {
token.value = ''
navigateTo('/passport/login')
}
function goLogin() {
navigateTo('/passport/login')
}
const handleSearch = (key: string, keyPath: string) => {
console.log(key, keyPath);
navigateTo('/search?keyword=' + searchValue.value);
};
function handleSelect(key: string, keyPath: any) {
console.log(key);
console.log(keyPath);
currentIndex.value = key;
navigateTo(`${key}`);
}
const reload = async () => {
const {data: response} = await useServerRequest<ApiResult<User>>('/auth/user',{baseURL: runtimeConfig.public.apiServer})
userInfo.value = response.value?.data;
}
reload();
</script>
<style lang="scss">
body {
background-color: #f3f6f8;
}
</style>