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.
273 lines
10 KiB
273 lines
10 KiB
<template>
|
|
<header
|
|
class="header fixed w-full bg-[#cf1313] opacity-90 border-b border-gray-200 dark:border-gray-800 -mb-px top-0 z-50 lg:mb-0 lg:border-0">
|
|
<div class="xl:w-screen-xl xl:p-0 px-4 flex items-center between w-full m-auto bg-[#cf1313]">
|
|
<div class="header___left flex items-center">
|
|
<div class="logo mt-1 sm:w-[250px] h-7 w-auto py-2 flex items-center">
|
|
<nuxt-link v-if="config?.siteLogo" to="/">
|
|
<div class="flex flex-col text-center xl:p-0">
|
|
<el-image
|
|
:src="config.siteLogo"
|
|
shape="square"
|
|
fit="fill"
|
|
class="w-[190px]"
|
|
:alt="config.siteName"
|
|
:title="config.siteName"
|
|
/>
|
|
</div>
|
|
|
|
</nuxt-link>
|
|
<nuxt-link v-else to="/">
|
|
<text>{{ config?.siteName }}</text>
|
|
</nuxt-link>
|
|
</div>
|
|
<div class="hidden sm:flex">
|
|
<el-menu
|
|
:default-active="currentIndex"
|
|
mode="horizontal"
|
|
background-color="transparent"
|
|
:collapse="true"
|
|
:ellipsis="false"
|
|
style="border: none"
|
|
>
|
|
<template v-for="(item, index) in navigations">
|
|
<!-- <el-sub-menu v-if="item?.children && item.children.length > 0" :index="`${item.path}`">-->
|
|
<!-- <template #title><h3 class="text-white">{{ item.title }}</h3></template>-->
|
|
<!-- <el-menu-item v-for="(sub,subIndex) in item.children" :index="`${sub.path}`">-->
|
|
<!-- <el-space @click="openSpmUrl(`${item.path}`,sub,sub.navigationId)">-->
|
|
<!-- <el-avatar v-if="sub.icon" :src="sub.icon" shape="square" size="small"></el-avatar>-->
|
|
<!-- <span class="font-bold">{{ sub.title }}</span>-->
|
|
<!-- </el-space>-->
|
|
<!-- </el-menu-item>-->
|
|
<!-- </el-sub-menu>-->
|
|
<div v-if="item?.children && item.children.length > 0">
|
|
<div class="px-[20px] relative h-[60px] w-[95px] flex justify-center items-center top-menu">
|
|
<h3 class="text-white cursor-pointer">
|
|
{{
|
|
item.title
|
|
}}</h3>
|
|
<div
|
|
class="absolute top-[60px] bg-white p-2 shadow border-t-2 border-[#409eff] left-0 overflow-hidden child-menu">
|
|
<div v-for="(sub,subIndex) in item.children" :key="index"
|
|
class="w-[200px] p-1 cursor-pointer hover:text-[#409eff]">
|
|
<el-space
|
|
@click="openSpmUrl(`${item.path}`,sub,sub.navigationId)">
|
|
<el-avatar v-if="sub.icon" :src="sub.icon" shape="square"
|
|
size="small"></el-avatar>
|
|
<span class="font-bold">{{ sub.title }}</span>
|
|
</el-space>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<el-menu-item v-else :index="`${item.path}`">
|
|
<h3
|
|
@click="openSpmUrl(`${item.path}`,item,item.navigationId)" class="text-white">{{ item.title }}</h3>
|
|
</el-menu-item>
|
|
</template>
|
|
</el-menu>
|
|
</div>
|
|
</div>
|
|
<div class="header__right items-center pr-4 xl:pr-0 md:flex hidden">
|
|
<el-space class="sm:flex hidden" size="large" v-if="config.showSearchTools">
|
|
<el-button v-if="token" @click="loginAdminByToken">控制台</el-button>
|
|
<ClientOnly>
|
|
<template v-if="token">
|
|
<el-dropdown @command="handleCommand">
|
|
<el-space class="flex items-center cursor-pointer">
|
|
<el-avatar class="cursor-pointer" :src="user?.logo" :size="30"/>
|
|
<span>{{ user?.tenantName }}</span>
|
|
</el-space>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="user" @click="openSpmUrl(`/user`)">账户中心</el-dropdown-item>
|
|
<el-dropdown-item command="password" @click="openSpmUrl(`/user/password`)">修改密码
|
|
</el-dropdown-item>
|
|
<el-dropdown-item command="auth" @click="openSpmUrl(`/user/auth`)">实名认证</el-dropdown-item>
|
|
<el-dropdown-item command="order" @click="openSpmUrl(`/user/order`)">我的订单</el-dropdown-item>
|
|
<el-dropdown-item divided command="logOut" @click="openSpmUrl('/user/logout')">退出登录
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</template>
|
|
<template v-else>
|
|
<!-- <el-button type="primary" v-if="!token" @click="navigateTo(`/passport/login`)">登录/注册</el-button>-->
|
|
<!-- <el-button v-if="config.showLoginButton" circle :icon="ElIconUserFilled" @click="goLogin"></el-button>-->
|
|
</template>
|
|
</ClientOnly>
|
|
</el-space>
|
|
</div>
|
|
<!-- 移动端菜单 -->
|
|
<div class="sm:hidden flex xl:p-0 px-8">
|
|
<el-dropdown>
|
|
<el-space class="el-dropdown-link flex items-center">
|
|
<el-avatar v-if="token" class="cursor-pointer" :src="user?.avatar" :size="30"/>
|
|
<el-button v-else :icon="ElIconMenu"></el-button>
|
|
</el-space>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<template v-for="(item, index) in navigations">
|
|
<el-dropdown-item>
|
|
<span @click="openSpmUrl(`${item.path}`,item,item.navigationId)">{{ item.title }}</span>
|
|
</el-dropdown-item>
|
|
</template>
|
|
<template v-if="token">
|
|
<el-dropdown-item divided @click="loginDeveloperCenterByToken">会员中心</el-dropdown-item>
|
|
<el-dropdown-item divided command="logOut" @click="navigateTo('/user/logout')">退出</el-dropdown-item>
|
|
</template>
|
|
<!-- <el-dropdown-item v-if="!token" divided @click="navigateTo(`/passport/login`)">登录</el-dropdown-item>-->
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
</div>
|
|
<Passport :visible="showPassport" @done="reload"/>
|
|
</header>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
// 引入所需的图标
|
|
import {
|
|
useCompany,
|
|
useConfigInfo,
|
|
useMenu,
|
|
useProductAffix,
|
|
useSysDomain,
|
|
useToken,
|
|
useUser
|
|
} from "~/composables/configState";
|
|
import {useServerRequest} from "~/composables/useServerRequest";
|
|
import type {ApiResult} from "~/api";
|
|
import type {User} from "~/api/system/user/model";
|
|
import {navigateTo, openSpmUrl} from "#imports";
|
|
import type {Company} from "~/api/system/company/model";
|
|
import {loginAdminByToken} from "~/utils/common";
|
|
|
|
const route = useRoute();
|
|
// 配置信息
|
|
const runtimeConfig = useRuntimeConfig();
|
|
const showPassport = ref<boolean>(false);
|
|
const token = useToken();
|
|
const user = useUser();
|
|
const company = useCompany();
|
|
const navigations = useMenu();
|
|
const config = useConfigInfo();
|
|
const affix = useProductAffix();
|
|
const sysDomain = useSysDomain();
|
|
|
|
const setNav = () => {
|
|
navigations.value = navigations.value.map(item => {
|
|
item.showChild = false
|
|
item.childHeight = item.children ? parseInt((item.children?.length * 31).toString()) : 0;
|
|
return item
|
|
})
|
|
nextTick(() => {
|
|
const childMenuList = document.getElementsByClassName('.child-menu')
|
|
console.log('childMenuList', childMenuList)
|
|
})
|
|
}
|
|
setNav()
|
|
|
|
|
|
// 顶部栏初始数
|
|
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;
|
|
}
|
|
}
|
|
|
|
const onAffix = (index: boolean) => {
|
|
affix.value = index;
|
|
}
|
|
|
|
function logOut() {
|
|
token.value = ''
|
|
localStorage.clear();
|
|
navigateTo('/passport/login')
|
|
}
|
|
|
|
function goLogin() {
|
|
navigateTo('/passport/login')
|
|
}
|
|
|
|
function handleSelect(key: string, keyPath: any) {
|
|
currentIndex.value = key;
|
|
navigateTo(`${key}`);
|
|
}
|
|
|
|
const reload = async () => {
|
|
const token = localStorage.getItem('token');
|
|
// const domain = localStorage.getItem('SysDomain');
|
|
// if (domain) {
|
|
// sysDomain.value = domain;
|
|
// }
|
|
// 获取用户信息
|
|
if (token && token != '') {
|
|
const {data: response} = await useServerRequest<ApiResult<User>>('/auth/user', {baseURL: runtimeConfig.public.apiServer})
|
|
if (response.value?.data) {
|
|
user.value = response.value?.data;
|
|
}
|
|
// 获取企业信息
|
|
const {data: companyInfo} = await useServerRequest<ApiResult<Company>>('/system/company/profile', {baseURL: runtimeConfig.public.apiServer})
|
|
if (companyInfo.value?.data) {
|
|
company.value = companyInfo.value?.data;
|
|
// sysDomain.value = company.value?.domain || undefined;
|
|
// user.value.tenantName = company.value?.tenantName;
|
|
// localStorage.setItem('SysDomain', `${company.value?.domain}`);
|
|
localStorage.setItem('CompanyLogo', `${company.value?.companyLogo}`)
|
|
localStorage.setItem('TenantName', `${company.value?.tenantName}`)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
reload();
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
body {
|
|
background-color: #f3f6f8;
|
|
}
|
|
|
|
.el-menu-item:visited, .el-menu-item:hover {
|
|
background: none !important; /* 你可以根据需要设置不同的颜色 */
|
|
transition: background-color 0.3s linear;
|
|
}
|
|
|
|
.is-active:hover {
|
|
border-bottom: none !important;
|
|
}
|
|
|
|
.top-menu:hover .child-menu {
|
|
display: block;
|
|
animation: revealMask 0.5s forwards;
|
|
}
|
|
|
|
.child-menu {
|
|
//background-color: #f40505;
|
|
display: none;
|
|
max-height: 0; /* 初始最大高度为0 */
|
|
overflow: hidden; /* 隐藏超出部分 */
|
|
transition: max-height 0.5s ease; /* 平滑过渡 */
|
|
}
|
|
|
|
@keyframes revealMask {
|
|
from {
|
|
max-height: 0;
|
|
}
|
|
to {
|
|
max-height: 600px; /* 设置一个足够大的值,确保内容完全显示 */
|
|
}
|
|
}
|
|
</style>
|