From 457cc6cf166d3b6c22be4f78c1db8802a7fbb4c7 Mon Sep 17 00:00:00 2001
From: wujingjing <gersonwu@qq.com>
Date: 星期一, 07 四月 2025 17:53:19 +0800
Subject: [PATCH] DigitalHuman

---
 src/layout/component/header/Header.vue |  202 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 140 insertions(+), 62 deletions(-)

diff --git a/src/layout/component/header/Header.vue b/src/layout/component/header/Header.vue
index 5e71acb..88ad933 100644
--- a/src/layout/component/header/Header.vue
+++ b/src/layout/component/header/Header.vue
@@ -1,56 +1,20 @@
 <template>
-	<div class="top_text flex justify-between px-6 items-center">
-		<div class="flex-items-center">
-			<div class="flex-items-center space-x-3 mr-4 pr-4 border border-solid border-r-1 border-l-0 border-y-0 border-gray-300" v-if="!sidebarIsShow">
-				<el-tooltip content="灞曞紑渚ф爮" placement="right" effect="dark">
-					<span
-						class="ywifont ywicon-cebianlan text-gray-700 active:text-gray-800 !text-[20px] cursor-pointer"
-						@click="emit('toggleSidebar',true)"
-					></span>
-				</el-tooltip>
-				<div
-					class="flex-items-center rounded-full border border-solid px-2 py-1 space-x-1 cursor-pointer border-blue-400 text-blue-500 hover:bg-blue-500 hover:text-white"
-					@click="newChatClick"
-				>
-					<span class="ywifont ywicon-jia"></span>
-					<span>鏂板璇�</span>
-				</div>
-			</div>
-			<div v-if="routerMeta.showTitle" class="font-bold flex items-center">
-				<span class="flex-center cursor-pointer" v-if="routerMeta.showBack" @click="goBack">
-					<SvgIcon name="ele-ArrowLeft" />
-				</span>
-				<span class="text-sm">
-					{{ routerMeta.title }}
-				</span>
-			</div>
-		</div>
-
-		<div class="notice">
-			<el-badge :value="`${state.announcementList.length}`">
-				<el-button link size="small" icon="ele-Message" class="set-notice" @click="handleAnnouncementClick">绯荤粺鍏憡</el-button>
-			</el-badge>
-			<div class="notice_box notice_box_show" v-show="state.isShowAnnouncement">
-				<div class="notice_box_header">
-					<span>鏈�鏂板叕鍛�</span>
-				</div>
-				<div class="notice_box_body">
-					<div
-						class="notice_item"
-						v-for="item in state.announcementList"
-						:key="item.notify_id"
-						@click="announcementContentClick(item)"
-					>
-						<div class="flex items-center">
-							<p class="set-circle"></p>
-							<p>{{ item.notify_message }}</p>
-						</div>
-
-						<p class="text-right mr-[19px]">
-							<span>{{ item.notify_time }}</span>
-						</p>
-					</div>
-				</div>
+	<div class="top_text flex justify-between px-6 items-center pl-[unset] pr-6">
+		<div class="flex-items-center h-full">
+			<div class="nav-menu">
+				<router-link :to="firstToPath" class="nav-item" active-class="active">
+					<i class="icon-park-outline-robot"></i>
+					鏅鸿兘鍔╂墜
+				</router-link>
+				<router-link to="/workspace/situation" class="nav-item" active-class="active">
+					<i class="icon-park-outline-workbench"></i>
+					涓汉宸ヤ綔鍙�
+				</router-link>
+			
+				<!-- <router-link to="/gis/situation" class="nav-item" active-class="active">
+					<i class="icon-park-outline-system"></i>
+					GIS绯荤粺
+				</router-link> -->
 			</div>
 		</div>
 		<el-dialog
@@ -71,16 +35,43 @@
 			</template>
 		</el-dialog>
 	</div>
+	<div class="notice " v-if="!isSharePage">
+		<el-badge :value="`${state.announcementList.length}`" :hidden="announcementIsRead || state.announcementList?.length === 0">
+			<el-button link size="small" icon="ele-Message" class="set-notice" @click="handleAnnouncementClick">绯荤粺鍏憡</el-button>
+		</el-badge>
+		<div class="notice_box notice_box_show" v-show="state.isShowAnnouncement" ref="noticeRef">
+			<div class="notice_box_header">
+				<span>鏈�鏂板叕鍛�</span>
+			</div>
+			<div class="notice_box_body">
+				<div class="notice_item" v-for="item in state.announcementList" :key="item.notify_id" @click="announcementContentClick(item)">
+					<div class="flex items-center">
+						<p class="set-circle"></p>
+						<p>{{ item.notify_message }}</p>
+					</div>
+
+					<p class="text-right mr-[19px]">
+						<span>{{ item.notify_time }}</span>
+					</p>
+				</div>
+			</div>
+		</div>
+	</div>
 </template>
 
 <script setup lang="ts">
-import { computed, onMounted, onUnmounted, reactive, triggerRef } from 'vue';
+import { onClickOutside } from '@vueuse/core';
+import { storeToRefs } from 'pinia';
+import { computed, onMounted, onUnmounted, reactive, ref } from 'vue';
 import { systemNotifyList } from '/@/api/ai/chat';
 import router from '/@/router';
-import { isSharePage, newChatRoomClick } from '/@/stores/chatRoom';
+import pinia from '/@/stores';
+import { activeChatRoom, activeRoomId, isSharePage, newChatRoomClick } from '/@/stores/chatRoom';
+import { useThemeConfig } from '/@/stores/themeConfig';
 import emitter from '/@/utils/mitt';
+import { userInfoKey } from '/@/utils/request';
+import { Local } from '/@/utils/storage';
 
-const emit = defineEmits(['toggleSidebar'])
 const props = defineProps(['sidebarIsShow']);
 let state = reactive({
 	isShowAnnouncement: false,
@@ -89,7 +80,44 @@
 	announcementContent: '',
 	announcementTime: '',
 });
+const firstToPath = computed(() => {
+	if (!activeChatRoom.value)
+		return {
+			path: '/home',
+		};
+	const result = activeChatRoom.value.isInitial
+		? {
+				path: '/home',
+				query: {
+					id: activeChatRoom.value.id,
+				},
+		  }
+		: {
+				path: '/ask_answer',
+				query: { id: activeChatRoom.value.id },
+		  };
 
+	return result;
+});
+
+//#region ====================== 鍏憡鏄惁鐪嬭繃 ======================
+const userInfo = ref(Local.get(userInfoKey));
+const readKey = `announcementIsRead_${userInfo.value?.id}`;
+const getIsRead = () => {
+	if (!userInfo.value?.id) return false;
+	const isRead = Local.get(readKey) ?? false;
+	return isRead;
+};
+
+const setRead = (isRead: boolean) => {
+	if (!userInfo.value?.id) return;
+	announcementIsRead.value = isRead;
+	Local.set(readKey, isRead);
+};
+const announcementIsRead = ref(getIsRead());
+
+//#endregion
+const noticeRef = ref(null);
 const getSystemNotify = async () => {
 	const res = await systemNotifyList();
 	res.messages?.forEach((element) => {
@@ -98,14 +126,19 @@
 	state.announcementList = res.messages?.sort(sortData).slice(0, 5) ?? [];
 };
 const routerMeta = computed(() => router.currentRoute.value.meta);
+const stores = useThemeConfig(pinia);
+const { themeConfig } = storeToRefs(stores);
+const globalTitle = computed(() => themeConfig.value.globalTitle);
 
 const setHeaderTitle = (title: string) => {
-	routerMeta.value.title = title;
-	triggerRef(routerMeta);
+	document.title = `${title} - ${globalTitle.value}`;
 };
 
 const handleAnnouncementClick = () => {
 	state.isShowAnnouncement = !state.isShowAnnouncement;
+	if (!announcementIsRead.value && state.isShowAnnouncement) {
+		setRead(true);
+	}
 };
 
 const goBack = () => {
@@ -124,7 +157,16 @@
 const handleCloseAnnouncement = () => {
 	state.isAnnouncementDialog = false;
 };
-
+// 鍖哄煙鍏抽棴鏈�鏂板叕鍛�
+onClickOutside(
+	noticeRef,
+	() => {
+		state.isShowAnnouncement = false;
+	},
+	{
+		ignore: ['.el-overlay-dialog'],
+	}
+);
 const newChatClick = () => {
 	newChatRoomClick();
 };
@@ -143,20 +185,21 @@
 	height: 42px;
 	background-color: #fff;
 	top: 0;
-	z-index: 0;
+	z-index: 1;
 }
 
 .notice {
 	position: fixed;
-	top: 18px;
+	top: 12px;
 	right: 30px;
-	z-index: 12;
+	z-index: 1;
 	.set-notice {
 		font-size: 12px;
 		font-weight: 400;
 		letter-spacing: 0;
 		line-height: 17.38px;
 		color: #9598b3;
+		z-index: 0;
 	}
 	.notice_box_show {
 		width: 300px !important;
@@ -171,7 +214,7 @@
 	}
 	.notice_box {
 		position: absolute;
-		z-index: 12;
+		z-index: 1;
 		top: calc(100% + 20px);
 		right: -10px;
 		width: 0;
@@ -239,4 +282,39 @@
 	padding: 10px 20px 20px;
 	box-sizing: border-box;
 }
+
+.nav-menu {
+	display: flex;
+	align-items: center;
+	height: 100%;
+	gap: 8px;
+
+	.nav-item {
+		display: flex;
+		align-items: center;
+		padding: 0 16px;
+		height: 100%;
+		color: var(--el-text-color-regular);
+		text-decoration: none;
+		font-size: 14px;
+		transition: all 0.3s ease;
+		border-bottom: 2px solid transparent;
+		gap: 4px;
+
+		i {
+			font-size: 16px;
+		}
+
+		&:hover {
+			color: var(--el-color-primary);
+			background-color: rgba(var(--el-color-primary-rgb), 0.1);
+		}
+
+		&.active {
+			color: var(--el-color-primary);
+			border-bottom-color: var(--el-color-primary);
+			background-color: rgba(var(--el-color-primary-rgb), 0.1);
+		}
+	}
+}
 </style>

--
Gitblit v1.9.3