tanghaolin
2025-04-17 63465b857a7e7fa2ac18701f01d966bb2c5fa421
src/components/AppHeader.vue
@@ -1,43 +1,68 @@
<template>
   <header class="bg-white shadow-sm flex items-center">
      <div class="flex w-full">
         <div class="flex items-center h-20 mx-auto">
   <header class="bg-white shadow-sm flex header-div">
      <div class="flex w-full h-full" style="flex-direction: column">
         <div class="flex w-full h-full header-layout-div">
            <!-- Logo -->
            <div class="flex items-center cursor-pointer">
            <div class="flex items-center cursor-pointer h-full">
               <router-link to="/">
                  <img :src="headerLogo" alt="Logo" class="h-20 w-auto" />
                  <img :src="headerLogo" alt="Logo" class="header-logo w-auto" />
               </router-link>
               <!-- <span class="text-extra-large font-bold">工业大数据平台</span> -->
            </div>
            <!-- Navigation Menu -->
            <nav class="flex ml-8">
               <el-menu mode="horizontal" :ellipsis="false" class="border-none" router :default-active="activeRoute">
                  <el-menu-item index="/" class="!px-4">首页</el-menu-item>
                  <el-menu-item index="/certified-products" class="!px-4">认证产品</el-menu-item>
            <nav class="flex ml-8 flex-1 navbar-div-style">
               <el-menu mode="horizontal" :ellipsis="false" class="border-none menu-div-sytle" router :default-active="activeRoute">
                  <el-menu-item index="/home" class="!px-4">首页</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="/certified-products" class="!px-4">能效产品</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="/eec-label-search" class="!px-4">证书查询</el-menu-item>
                  <el-menu-item index="/news-detail/99" class="!px-4">补贴政策</el-menu-item>
                  <el-menu-item class="!px-4" @click="linkClick('http://xpump.net/#/Index')">查泵网</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="/news-detail/99" class="!px-4">政策文件</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="/select-selpara" class="!px-4" @click="linkClick">泵选型</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="/gb19762-2025" class="!px-4">计算工具</el-menu-item>
                  <span class="w-[20px] h-full gap-style">|</span>
                  <el-menu-item index="" class="!px-4">联系我们</el-menu-item>
               </el-menu>
            </nav>
            <!-- Search and User Actions -->
            <div class="flex items-center space-x-8 ml-[65px]">
               <el-input v-model="searchQuery" placeholder="找工业/找大数据" class="w-48">
                  <template #suffix>
                     <el-icon><Search /></el-icon>
         </div>
         <!-- 顶部产品搜索框 -->
         <div class="header-tool-div">
            <div class="search-input-div">
               <input placeholder="全部商品|请输入公司名称/型号/产品名称" />
               <button>搜索</button>
            </div>
            <span class="text-[20px] text-[#000] gap-div"></span>
            <!-- 省份选择 -->
            <div>
               <el-cascader v-model="AreaValue" :options="options" @change="handleChange">
                  <template #prefix>
                     123123
                  </template>
               </el-input>
               <div class="flex items-center text-gray-600 text-sm text-nowrap">
                  <template v-if="!userInfo">
                     <a href="#" class="hover:text-blue-500">注册</a>
                     <span class="mx-2">·</span>
                     <router-link to="/login" class="hover:text-blue-500">登录</router-link>
               </el-cascader>
            </div>
            <span class="text-[20px] text-[#000] gap-div"></span>
            <div class="flex gap-[22px]">
               <button class="flex items-center gap-[10px]">
                  <div class="flex items-center gap-4" @click="goToCart">
                     <el-badge :value="cartCount" :max="99" class="cart-badge">
                           <el-icon class="text-lg" color="#000" style="font-size: 20px"><ShoppingCart /></el-icon>
                     </el-badge>
                  </div>
                  我的购物车
               </button>
               <button>批量下载</button>
               <button>我的订单</button>
               <div class="flex items-center">
                  <template v-if="!userInfo.Token">
                     <button @click="toLogin">登录</button>
                  </template>
                  <template v-else>
                     <span class="text-blue-500 mr-2">{{ userInfo.username }}</span>
                     <a href="#" class="hover:text-blue-500" @click.prevent="handleLogout">退出</a>
                     <span class="text-blue-500 mr-2 text-[20px] text-[#000]">{{ userInfo.RealName }}</span>
                     <a href="#" class="hover:text-blue-500 text-[20px]" @click.prevent="handleLogout">退出</a>
                  </template>
               </div>
            </div>
@@ -48,43 +73,283 @@
<script setup lang="ts">
import headerLogo from '@/assets/logo/header_logo.png';
import { Search } from '@element-plus/icons-vue';
import { Search, ShoppingCart } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { computed, ref } from 'vue';
import { computed, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useLogin } from '@/stores/useLogin';
import { useCartStore } from '@/stores/useCartStore';
const loginStore = useLogin();
const cartStore = useCartStore();
const route = useRoute();
const router = useRouter();
const searchQuery = ref('');
const AreaValue = ref(null);
const props = {
   expandTrigger: 'hover' as const,
};
const handleChange = (value) => {
   console.log(value);
};
const options = [
   {
      value: 'shanghai',
      label: '上海市',
      children: [
         {
            value: 'minhang',
            label: '闵行区',
         },
         {
            value: 'pudongxinqu',
            label: '浦东新区',
         },
         {
            value: 'huanpuqu',
            label: '黄浦区',
         },
         {
            value: 'hongkouqu',
            label: '虹口区',
         },
         {
            value: 'fengxian',
            label: '奉贤区',
         },
         {
            value: 'jingan',
            label: '静安区',
         },
      ],
   },
];
const activeRoute = computed(() => route.path);
// 获取用户信息
const userInfo = computed(() => {
   const info = localStorage.getItem('userInfo');
   return info ? JSON.parse(info) : null;
   const UserInfo = loginStore.getUserInfo();
   return UserInfo ? UserInfo : null;
});
const toLogin = () => {
   router.replace({
      path: '/login',
      query: {
         redirectPath: route.fullPath,
      },
   });
};
// 处理登出
const handleLogout = () => {
   localStorage.removeItem('userInfo');
   loginStore.logOut();
   ElMessage.success('已退出登录');
   router.push('/login');
   router.replace({
      path: '/login',
      query: { redirectPath: route.fullPath },
   });
};
const linkClick = (url) => {
   window.open(url, '_blank');
const linkClick = () => {
   if (userInfo.value.Token) {
      router.push('/select-selpara');
   } else {
      loginStore.logOut();
      router.replace({
         path: '/login',
         query: { redirectPath: route.fullPath },
      });
   }
};
// 从 Pinia store 获取购物车数量
const cartCount = computed(() => cartStore.cartItemCount);
const goToCart = () => {
   if (userInfo.value.Token) {
      router.push('/cart');
   } else {
      loginStore.logOut();
      router.replace({
         path: '/login',
         query: { redirectPath: route.fullPath },
      });
      return;
   }
};
</script>
<style scoped>
<style lang="scss" scoped>
:deep(.el-menu--horizontal .el-menu-item) {
   height: 64px;
   line-height: 64px;
   font-size: 14px;
   height: 69px;
   line-height: 69px;
   font-size: 20px;
   width: 130px;
}
:deep(.el-menu--horizontal > .el-menu-item.is-active) {
   color: #76b432 !important;
   border-bottom: none !important;
}
:deep(.el-menu--horizontal > .el-menu-item) {
   color: #fff !important;
   border-bottom: none;
}
:deep(.el-menu--horizontal) {
   border-bottom: none;
}
:deep(.el-menu--horizontal .el-menu-item:not(.is-disabled):hover) {
   background: transparent !important;
   color: #76b432 !important;
}
:deep(.el-menu--horizontal .el-menu-item:not(.is-disabled):focus) {
   background: transparent !important;
   color: #76b432 !important;
}
.header-layout-div {
   padding-left: 231px;
   height: 87px;
   width: 100%;
   box-sizing: border-box;
}
.header-logo {
   height: 68px;
}
.header-tool-div {
   display: flex;
   gap: 20px;
   align-items: center;
   padding-left: 240px;
   width: 100%;
   height: 69px;
   background: rgb(242, 242, 242);
   border: 1px solid rgba(158, 158, 158, 0.4);
   box-sizing: border-box;
   .search-input-div {
      display: flex;
      align-items: center;
      gap: 10px;
   }
   :deep(.el-input__wrapper) {
      width: 237px;
      height: 39px;
      background: transparent;
      box-shadow: inset -1px -1px 3px 0px #ffffff, inset 0px 2px 3px 0px rgba(0, 0, 0, 0.4) !important;
      border-radius: 6px;
      border: none;
      padding: 0 15px;
      font-size: 16px;
      outline: none;
      box-sizing: border-box;
   }
   :deep(.el-input__inner) {
      height: 39px;
      background: transparent;
      font-size: 16px;
      outline: none;
      box-sizing: border-box;
      // &:focus {
      //    box-shadow:inset -1px -1px 3px 0px #ffffff,inset 0px 2px 5px 0px rgba(0, 0, 0, 0.5);
      // }
   }
   input {
      width: 482px;
      height: 39px;
      background: #d3d3d3;
      box-shadow: inset -1px -1px 3px 0px #ffffff, inset 0px 2px 3px 0px rgba(0, 0, 0, 0.4);
      border-radius: 6px;
      border: none;
      padding: 0 15px;
      font-size: 16px;
      outline: none;
      box-sizing: border-box;
      &:focus {
         box-shadow: inset -1px -1px 3px 0px #ffffff, inset 0px 2px 5px 0px rgba(0, 0, 0, 0.5);
      }
   }
   button {
      min-width: 68px;
      height: 39px;
      background: linear-gradient(180deg, #ffffff 0%, #e0e0e0 100%);
      box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.3);
      border: 1px solid #c2c2c2;
      border-radius: 6px;
      color: #333333;
      font-size: 16px;
      cursor: pointer;
      transition: all 0.3s ease;
      &:hover {
         background: linear-gradient(180deg, #f5f5f5 0%, #d5d5d5 100%);
      }
      &:active {
         background: linear-gradient(180deg, #e0e0e0 0%, #cccccc 100%);
         box-shadow: inset 0px 1px 3px 0px rgba(0, 0, 0, 0.2);
      }
   }
}
.navbar-div-style {
   background: url('@/assets/images/navbar_background.png') no-repeat;
   background-size: 100% 100%;
   .menu-div-sytle {
      background: transparent;
      height: 100%;
      justify-content: center;
      align-items: center;
      margin-left: 100px;
      padding-bottom: 15px;
      box-sizing: border-box;
   }
}
.cart-badge{
   display: flex;
   :deep(.el-badge__content) {
      // animation: cartBadgeAnimation 0.3s cubic-bezier(0.4, 0, 0.2, 1);
   }
}
.gap-style {
   font-size: 20px;
   color: #ffffff;
   font-family: 微软雅黑;
   font-weight: 500;
   line-height: 69px;
}
.gap-div{
   height: 69px;
   display: flex;
   align-items: center;
   justify-content: center;
   padding: 0 20px;
   &::before{
      content: "";
      display: block;
      width: 2px;
      height: 65%;
      background: #D3D3D3;
   }
}
@keyframes cartBadgeAnimation {
   0% {
      transform: scale(0);
      opacity: 0;
   }
   50% {
      transform: scale(1.2);
   }
   100% {
      transform: scale(1);
      opacity: 1;
   }
}
</style>