qa_portal_vue/app/components/AppHead/index.vue

325 lines
8.5 KiB
Vue
Raw Normal View History

2026-01-28 11:35:14 +08:00
<template>
2026-02-03 14:09:03 +08:00
<header class="head_container" :class="{ scrolled: isScrolled }">
2026-01-28 11:35:14 +08:00
<div class="logo">
2026-02-03 14:09:03 +08:00
<div class="logo_b"><img src="../../assets/images/logo.png" alt="河北秦安安全科技股份有限公司"/></div>
<div class="logo_w"> <img src="../../assets/images/logo1.png" alt="河北秦安安全科技股份有限公司"/></div>
2026-01-28 11:35:14 +08:00
</div>
<div style="display: flex">
<nav class="nav_list">
<ul>
2026-03-09 14:19:18 +08:00
<li :class="{ active: isActive('/') }"><NuxtLink to="/">首页</NuxtLink></li>
2026-01-28 11:35:14 +08:00
<li
2026-02-02 17:48:44 +08:00
:class="{ active: isActive('/product') }"
2026-01-28 11:35:14 +08:00
@mouseenter="isProductHovered = true"
@mouseleave="isProductHovered = false"
>
2026-02-03 14:09:03 +08:00
<NuxtLink to="">产品</NuxtLink>
2026-01-28 11:35:14 +08:00
<span v-if="isProductHovered">
2026-02-02 17:48:44 +08:00
<NuxtLink
v-for="(item, index) in proList"
2026-01-28 11:35:14 +08:00
:key="index"
v-motion
2026-02-02 17:48:44 +08:00
:to="item.path"
2026-01-28 11:35:14 +08:00
:initial="{ opacity: 0, y: -10 }"
:enter="{ opacity: 1, y: 0, transition: { delay: index * 50, duration: 300 } }"
:leave="{ opacity: 0, y: -10, transition: { duration: 200 } }"
>
2026-02-02 17:48:44 +08:00
{{item.name}}
</NuxtLink>
2026-01-28 11:35:14 +08:00
</span>
</li>
2026-02-02 17:48:44 +08:00
<li :class="{ active: isActive('/solution') }">
2026-02-02 16:50:43 +08:00
<NuxtLink to="/solution">解决方案</NuxtLink>
</li>
2026-02-02 17:48:44 +08:00
<li :class="{ active: isActive('/new') }"><NuxtLink to="/new">新闻资讯</NuxtLink></li>
2026-03-09 17:06:41 +08:00
<li :class="{ active: isActive('/rule') }"><NuxtLink to="/rule">政策法规</NuxtLink></li>
<li :class="{ active: isActive('/service') }"><NuxtLink to="/service">业务与服务</NuxtLink></li>
<li :class="{ active: isActive('/public') }"><NuxtLink to="/public">网上公开</NuxtLink></li>
2026-02-02 17:48:44 +08:00
<li :class="{ active: isActive('/case') }"><NuxtLink to="/case">合作案例</NuxtLink></li>
2026-03-09 18:01:07 +08:00
<li :class="{ active: isActive('/job') }"><NuxtLink to="/job">人力资源</NuxtLink></li>
2026-03-09 13:54:04 +08:00
<li
:class="{ active: isActive('/product') }"
@mouseenter="isAboutHovered = true"
@mouseleave="isAboutHovered = false"
>
<NuxtLink to="">关于秦安</NuxtLink>
<span v-if="isAboutHovered">
<NuxtLink
v-for="(item, index) in AboutList"
:key="index"
v-motion
:to="item.path"
:initial="{ opacity: 0, y: -10 }"
:enter="{ opacity: 1, y: 0, transition: { delay: index * 50, duration: 300 } }"
:leave="{ opacity: 0, y: -10, transition: { duration: 200 } }"
>
{{item.name}}
</NuxtLink>
</span>
</li>
2026-02-03 14:09:03 +08:00
<li :class="{ active: isActive('https://safetyds.qhdsafety.com/#/safety_chat') }"><NuxtLink to="https://safetyds.qhdsafety.com/#/safety_chat" target="_blank">秦安安全大模型</NuxtLink></li>
2026-01-28 11:35:14 +08:00
</ul>
<div class="num">股票代码871771</div>
</nav>
</div>
</header>
</template>
<script setup lang="ts">
2026-02-03 14:09:03 +08:00
import { ref, onMounted, onUnmounted } from "vue";
2026-01-28 11:35:14 +08:00
const isProductHovered = ref(false);
2026-03-09 13:54:04 +08:00
const isAboutHovered = ref(false);
const isRuleHovered = ref(false);
2026-02-03 14:09:03 +08:00
const isScrolled = ref(false);
2026-02-02 17:48:44 +08:00
const route = useRoute();
2026-02-03 14:09:03 +08:00
const handleScroll = () => {
isScrolled.value = window.scrollY > 50;
};
onMounted(() => {
window.addEventListener("scroll", handleScroll);
});
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll);
});
2026-02-02 17:48:44 +08:00
const isActive = (path: string) => {
if (path === "/") {
return route.path === "/";
}
return route.path.startsWith(path);
};
const proList = [
2026-02-03 14:09:03 +08:00
{ name: "基层监管平台", path: "/product/regulatory" },
{ name: "GBS数字底座", path: "" },
{ name: "一体化智能云平台", path: "" },
{ name: "安全培训开发者平台", path: "" },
{ name: "服务机构自我赋能平台", path: "" },
{ name: "应急管理大数据中心", path: "" },
2026-02-02 17:48:44 +08:00
];
2026-03-09 13:54:04 +08:00
const AboutList=[
{ name: "公司简介", path: "/about" },
{ name: "领导致词", path: "/about/leaderSpeech" },
{ name: "发展战略", path: "/about/developmentStrategy" },
{ name: "组织架构", path: "/about/organizationalStructure" },
{ name: "资质荣誉", path: "/about/honor" },
{ name: "发展历程", path: "/about/developmentHistory" },
];
const RuleList= [
{ name: "法律法规", path: "/rule/legal" },
{ name: "政府规章", path: "/rule/government" },
{ name: "规范文件", path: "/rule/specification" },
{ name: "技术标准", path: "/rule/technicalStandards" },
];
2026-01-28 11:35:14 +08:00
</script>
<style scoped lang="scss">
.head_container{
min-width: 1400px;
width: 100%;
height: 70px;
background: rgba(4,17,40,0.52);
display: flex;
justify-content: space-between;
border-bottom: 1px solid rgba(255,255,255,0.2);
align-items: center;
padding: 0 20px;
box-sizing: border-box;
position: absolute;
top: 0;
left: 0;
z-index: 999;
2026-02-03 14:09:03 +08:00
transition: all 0.3s ease;
&.scrolled{
position: fixed;
background: #ffffff;
border-bottom: 1px solid #eeeeee;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
.nav_list{
.num{
color: #222222;
}
ul li{
color: #222222;
a{
color: #222222;
text-decoration: none;
&:before{
background-color: #1d78ff;
2026-02-03 14:12:30 +08:00
left: 50%;
right: 50%;
}
}
&.active a:before,
&:hover a:before{
left: 0;
right: 0;
2026-02-03 14:09:03 +08:00
}
&.active a{
color: #222222;
}
&:hover{
color: #1d78ff;
background: #ddebff;
}
span{
a{
color: #222222;
&:before{
display: none;
}
&:hover{
color: #222222;
background: #ddebff;
}
}
}
}
}
}
.logo{
position: relative;
width: 150px;
height: 50px;
.logo_b, .logo_w{
position: absolute;
top: 10px;
left: 0;
width: 128px;
height: 32px;
transition: opacity 0.3s ease;
img{
width: 128px;
height: 32px;
object-fit: contain;
}
}
.logo_w{
opacity: 0;
}
.logo_b{
opacity: 1;
}
}
&.scrolled{
.logo{
.logo_b{
opacity: 0;
}
.logo_w{
opacity: 1;
}
}
}
2026-01-28 11:35:14 +08:00
.nav_list{
display: flex;
justify-content: space-between;
align-items: center;
.num{
color: #ffffff;
font-size: 14px;
margin-left: 50px;
}
ul{
display: flex;
justify-content: space-between;
li{
list-style: none;
color: #ffffff;
padding: 0 15px;
font-size: 14px;
box-sizing: border-box;
position: relative;
a{
color: #ffffff;
text-decoration: none;
cursor: pointer;
display: inline-block;
position: relative;
height: 70px;
line-height: 70px;
&:before{
content: "";
position: absolute;
z-index: 1;
2026-02-03 14:12:30 +08:00
transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94);
2026-01-28 11:35:14 +08:00
bottom: 0;
background-color: #ffffff;
height: 2px;
2026-02-03 14:12:30 +08:00
left: 50%;
right: 50%;
2026-01-28 11:35:14 +08:00
border-radius: 2px 2px 0 0;
opacity: 0;
}
}
2026-02-03 14:09:03 +08:00
2026-02-02 17:48:44 +08:00
&.active{
a{
&:before{
opacity: 1;
left: 0;
2026-02-03 14:12:30 +08:00
right: 0;
2026-02-02 17:48:44 +08:00
}
}
}
2026-01-28 11:35:14 +08:00
&:hover{
a{
&:before{
opacity: 1;
left: 0;
2026-02-03 14:12:30 +08:00
right: 0;
2026-01-28 11:35:14 +08:00
}
}
}
span{
position: absolute;
top: 70px;
background: #fff;
2026-02-03 14:09:03 +08:00
width: 200px;
2026-01-28 11:35:14 +08:00
text-align: center;
left: 50%;
2026-02-03 14:09:03 +08:00
margin-left: -100px;
2026-01-28 11:35:14 +08:00
box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.08);
padding: 10px 0;
border-radius: 4px;
2026-02-03 14:09:03 +08:00
z-index: 999999;
border-bottom: 1px solid #eeeeee !important;
2026-01-28 11:35:14 +08:00
a{
color: #333333;
display: block;
width: 100%;
height: 50px;
line-height: 50px;
2026-02-03 14:09:03 +08:00
border-bottom: 1px solid #eeeeee !important;
text-decoration: none;
2026-01-28 11:35:14 +08:00
&:hover{
2026-02-03 14:09:03 +08:00
color: #222222;
2026-01-28 11:35:14 +08:00
background: #ddebff;
}
}
}
}
}
}
}
</style>