Files
Situation-Awareness-Platfor…/src/components/Header/index.vue
2025-07-05 13:03:19 +08:00

277 lines
8.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="full-w" :style="{ height: `${height}px` }">
<div class="g-header fixed z-20" ref="headerRef" :class="{ 'home-background': isHome }">
<div class="g-toolbar w-full overflow-hidden" :class="[searchClass, route?.meta?.headerClassName]">
<div class="g-toolbar-left flex-shrink items-center">
<div class="flex-center gap-[16px]" v-if="!isHome">
<!-- <g-icon v-if="!asideSetShow" @click="$emit('clickMenu')" name="gt-hamburger" size="20px" class="cursor-pointer hover:!text-black" color="#1D1F3A"></g-icon>-->
<GLink class="g-toolbar-left-logo" :href="baseUrl" />
<!-- <GLink class="g-toolbar-left-title" :href="baseUrl">可信代码库</GLink>-->
<!-- <Entrance v-if="isLogin" :is-mobile="isMobile" /> -->
</div>
</div>
<div class="flex-1 flex items-center justify-end" v-if="!isHome">
<Search class="g-toolbar-left-search" v-if="!isMobile" :key="$route.fullPath" />
</div>
<!--AI-->
<a v-if="!isHome" @click="gotoAI">
<img style="width: 98px;height: 32px;cursor: pointer" src="@/assets/imgs/jyh/ai/ai_zh.png" />
</a>
<div class="g-toolbar-right gap-[12px] flex-grow-0 flex-shrink-0">
<GLink
class="g-toolbar-right-link"
v-for="item in defaultLinkList"
:key="item.label"
:to="item.to"
:href="item.href"
:target="item.target"
>
{{ item.label }}
</GLink>
<template v-if="!isLogin">
<d-button class="border-none w-84 h-32 btn-add hidden-m" @click="handleLogin('login')" v-if="inSearch">
<GIcon name="gt-plane-add" size="16px" color="#9C9DB4" />
<span>新建</span>
</d-button>
<div class="cursor-pointer hidden-m" @click="handleLogin('login')" v-if="inSearch">
<span>搜索记录</span>
</div>
<d-button @click="handleLogin('register')" class="min-w-[64px]">注册</d-button>
<d-button variant="solid" color="primary" @click="handleLogin('login')">账号密码登录</d-button>
</template>
<template v-else>
<!--ai copilot-->
<!-- <a class="g-header-copilot" href="/ai-copilot/">-->
<!-- <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">-->
<!-- <path fill-rule="evenodd" clip-rule="evenodd" d="M2.5 6C2.5 4.89543 3.39543 4 4.5 4H11.5C12.6046 4 13.5 4.89543 13.5 6V12C13.5 13.1046 12.6046 14 11.5 14H4.5C3.39543 14 2.5 13.1046 2.5 12V6ZM4.5 8C4.5 7.44772 4.94772 7 5.5 7C6.05228 7 6.5 7.44772 6.5 8V9C6.5 9.55228 6.05228 10 5.5 10C4.94772 10 4.5 9.55228 4.5 9V8ZM10.5 7C9.94772 7 9.5 7.44772 9.5 8V9C9.5 9.55228 9.94772 10 10.5 10C11.0523 10 11.5 9.55228 11.5 9V8C11.5 7.44772 11.0523 7 10.5 7Z" fill="white"/>-->
<!-- <path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M8.75 3.29933C9.19835 3.03997 9.5 2.55521 9.5 2C9.5 1.17157 8.82843 0.5 8 0.5C7.17157 0.5 6.5 1.17157 6.5 2C6.5 2.55521 6.80165 3.03997 7.25 3.29933V5.5H8.75V3.29933ZM0 7C0 6.44772 0.447715 6 1 6H1.5V12H1C0.447715 12 0 11.5523 0 11V7ZM15 6H14.5V12H15C15.5523 12 16 11.5523 16 11V7C16 6.44772 15.5523 6 15 6Z" fill="white"/>-->
<!-- </svg>-->
<!-- <span class="ml-xs">AI Copilot</span>-->
<!-- </a>-->
<!-- <Create />-->
<!-- <SearchAiHistory />-->
<!-- <d-popover content="提示!" trigger="hover" style="background-color: #7693f5; color: #fff">
<d-icon style="font-size: 16px" name="icon-helping" />
</d-popover> -->
<Notice />
<UserAvatar />
</template>
</div>
</div>
<div v-if="$slots.info || $slots.menu || $slots.bodyHeader" class="g-header-body">
<slot name="bodyHeader">
<div class="g-header-body-left h-full">
<slot name="info" />
</div>
<div class="g-header-body-right h-full">
<slot name="menu"></slot>
</div>
</slot>
</div>
<div v-if="$slots.headerBottom">
<slot name="headerBottom"></slot>
</div>
</div>
</div>
</template>
<script setup>
import { onBeforeUnmount, ref, watchEffect, computed } from 'vue';
import { useElementSize } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useRoute, useRouter } from 'vue-router';
import { useAccountStore } from '@/stores/user';
import { emitEvent } from '@/utils/eventBus';
import Create from './Create.vue';
import Entrance from './Entrance.vue';
import Notice from './Notice.vue';
import Search from './Search.vue';
import SearchAiHistory from './searchAiHistory.vue';
import UserAvatar from './UserAvatar.vue';
import { useWindowScroll } from '@vueuse/core';
import { usePageResize } from '@/utils/hooks/usePageResize';
import microApp from '@micro-zoe/micro-app';
const baseUrl = import.meta.env.VITE_BASE_URL;
const { y } = useWindowScroll();
const defaultLinkList = ref([]);
const route = useRoute();
const inSearch = ref(false);
const searchClass = computed(() => ({ 'border-b-transparent': inSearch.value && y.value === 0 }));
// header fixed布局高度自适应
const headerRef = ref(null);
const { height = 56 } = useElementSize(headerRef);
const userInfo = useAccountStore();
const { isLogin } = storeToRefs(userInfo);
const showSearch = computed(() => route.name !== 'home' && route.name !== 'search');
const isHome = computed(() => route.name === 'home');
const handleLogin = (type) => {
emitEvent('login', { type, triggerType: '主动注册' });
};
const { isMobile } = usePageResize();
const router = useRouter();
const gotoAI = (row) => {
// 后续请换成params暂时params传参没传过去
router.push({ name: 'aihome' });
};
/* store 用户信息 */
/* @test 后面将清除 */
watchEffect(() => {});
microApp.router.beforeEach({
'micoro-app-homeweb-app': (to, from) => {
if (to.pathname === '/search') {
inSearch.value = true;
} else {
inSearch.value = false;
}
}
});
defineExpose({
height
});
</script>
<style lang="scss" scoped>
@import 'devui-theme/styles-var/devui-var.scss';
$radius: 4px;
$add-radius: 48px;
$header-bg: #fff;
.home-background {
background-color: #fff0 !important;
}
.g-header {
// overflow: hidden;
width: 100%;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: space-between;
background-color: $header-bg;
:deep(.g-link) {
color: $devui-text-weak;
}
.g-header-copilot {
background: rgba(41, 81, 224, 1);
color: #fff;
width: 120px;
border-radius: 48px;
height: 32px;
display: flex;
align-items: center;
cursor: pointer;
justify-content: center;
&:hover {
background: rgba(41, 81, 224, 0.8);
}
}
.g-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
flex: 1;
gap: 16px;
flex-basis: 56px;
overflow: hidden;
padding: 0 24px;
border-bottom: 1px solid #f1f1f8;
:deep(.devui-button) {
padding: 6px 16px;
border-radius: $add-radius;
}
&-left {
display: flex;
align-items: center;
gap: 25px;
&-logo {
display: inline-block;
width: 90px;
height: 32px;
background: url(../../assets/imgs/logo2.png) no-repeat;
background-size: contain;
vertical-align: middle;
background-position: 0 center;
}
&-title {
font-size: 1rem;
font-weight: 600;
}
&-search {
max-width: 340px;
border-radius: $radius;
}
}
&-right {
display: flex;
align-items: center;
@media screen and (max-width: 576px) {
@apply gap-[16px];
}
}
&.border-b-transparent {
border-bottom-color: transparent !important;
}
&.border-b-show {
border-bottom-color: #f1f1f8 !important;
}
}
.g-header-gray {
@apply bg-[#F9F9FB];
}
&-body {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 32px;
background-color: $header-bg;
border-bottom: 1px solid $devui-dividing-line;
flex-basis: 48px;
}
}
@media screen and (max-width: 1000px) {
.g-header {
.g-toolbar {
padding: 20px;
border-color: transparent;
}
.g-toolbar-left-logo {
width: 28px;
background-size: cover;
}
&-body {
padding: 0;
}
}
}
.btn-add {
background-color: #000;
color: #fff !important;
width: 84px;
font-size: 14px;
line-height: 20px;
span {
margin-left: 8px;
}
&:hover {
color: #fff;
background-color: #333;
}
}
@media screen and (max-width: 576px) {
.hidden-m {
display: none;
}
.g-header-copilot {
display: none !important;
}
}
</style>