<template>
|
<div class="top_text flex justify-between px-6 items-center" :class="sidebarIsShow ? 'px-6' : '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
|
v-model="state.isAnnouncementDialog"
|
width="500"
|
:before-close="handleCloseAnnouncement"
|
:modal="false"
|
title="公告内容"
|
:align-center="true"
|
>
|
<div class="set-content">
|
<span class="notice-content">{{ state.announcementContent }}</span>
|
</div>
|
<template #footer>
|
<p class="text-right text-[#555]">
|
<span>{{ state.announcementTime }}</span>
|
</p>
|
</template>
|
</el-dialog>
|
|
<el-tooltip content="最小化" placement="bottom">
|
<span class="cursor-pointer ywifont ywicon-tuichuquanping" size="15px" @click="smallScreenClick" />
|
</el-tooltip>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
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 pinia from '/@/stores';
|
import { activeChatRoom, newChatRoomClick, sidebarIsShow } from '/@/stores/chatRoom';
|
import { ParentRegister } from '/@/stores/global';
|
import { useThemeConfig } from '/@/stores/themeConfig';
|
import emitter from '/@/utils/mitt';
|
import { userInfoKey } from '/@/utils/request';
|
import { Local } from '/@/utils/storage';
|
|
const props = defineProps(['sidebarIsShow']);
|
let state = reactive({
|
isShowAnnouncement: false,
|
isAnnouncementDialog: false,
|
announcementList: [],
|
announcementContent: '',
|
announcementTime: '',
|
});
|
|
const smallScreenClick = () => {
|
const pathname = window.location.pathname;
|
const basePath = pathname.replace(/\/web\/index\.html$/, '');
|
window.location.href = basePath || '/';
|
ParentRegister.notify?.({
|
type: 'fullScreen',
|
value: false,
|
});
|
};
|
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) => {
|
element.notify_time = element.notify_time.slice(0, 10);
|
});
|
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) => {
|
document.title = `${title} - ${globalTitle.value}`;
|
};
|
|
const handleAnnouncementClick = () => {
|
state.isShowAnnouncement = !state.isShowAnnouncement;
|
if (!announcementIsRead.value && state.isShowAnnouncement) {
|
setRead(true);
|
}
|
};
|
|
const goBack = () => {
|
router.back();
|
};
|
//根据指定字段 规则排序 这里是获取时间的时间戳然后比较
|
function sortData(a, b) {
|
return new Date(b.notify_time).getTime() - new Date(a.notify_time).getTime();
|
}
|
//公告内容点击事件
|
const announcementContentClick = (item) => {
|
state.announcementContent = item.notify_message;
|
state.announcementTime = item.notify_time.slice(0, 10);
|
state.isAnnouncementDialog = true;
|
};
|
const handleCloseAnnouncement = () => {
|
state.isAnnouncementDialog = false;
|
};
|
// 区域关闭最新公告
|
onClickOutside(
|
noticeRef,
|
() => {
|
state.isShowAnnouncement = false;
|
},
|
{
|
ignore: ['.el-overlay-dialog'],
|
}
|
);
|
const newChatClick = () => {
|
newChatRoomClick();
|
};
|
onMounted(() => {
|
getSystemNotify();
|
emitter.on('updateHeaderTitle', setHeaderTitle);
|
});
|
|
onUnmounted(() => {
|
emitter.off('updateHeaderTitle', setHeaderTitle);
|
});
|
</script>
|
<style scoped lang="scss">
|
.top_text {
|
width: 100%;
|
height: 42px;
|
background-color: #fff;
|
top: 0;
|
z-index: 1;
|
}
|
|
.notice {
|
position: fixed;
|
top: 12px;
|
right: 30px;
|
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;
|
height: 470px !important;
|
// height: 100% !important;
|
padding: 0 20px 10px;
|
::-webkit-scrollbar {
|
height: 0;
|
width: 0;
|
color: transparent;
|
}
|
}
|
.notice_box {
|
position: absolute;
|
z-index: 1;
|
top: calc(100% + 20px);
|
right: -10px;
|
width: 0;
|
height: 0;
|
border-radius: 5px;
|
-webkit-box-shadow: 0 0 5px #ddd;
|
box-shadow: 0 0 5px #ddd;
|
background: #fff;
|
display: block;
|
-webkit-transition: all 0.3s;
|
|
-o-transition: all 0.3s;
|
transition: all 0.3s;
|
overflow: hidden;
|
&_header {
|
line-height: 40px;
|
font-size: 14px;
|
height: 40px;
|
color: #0084ff;
|
}
|
&_body {
|
height: calc(100% - 40px);
|
// overflow: auto;
|
.notice_item {
|
cursor: pointer;
|
padding: 10px;
|
width: 272px;
|
border-top: 1px solid #efefef;
|
color: #767a97;
|
position: relative;
|
box-sizing: border-box;
|
line-height: 19px;
|
font-size: 12px;
|
.set-circle {
|
width: 3px;
|
height: 3px;
|
position: absolute;
|
top: 17px;
|
left: 0;
|
transform: scale(0.8) translate(50%, -50%);
|
display: block;
|
padding: 2px;
|
min-width: 3px;
|
min-height: 3px;
|
text-align: center;
|
border-radius: 50%;
|
background: #ff423d;
|
color: #fff;
|
font-size: 12px;
|
}
|
}
|
}
|
}
|
}
|
|
.set-content {
|
padding: 0px 20px;
|
.notice-content {
|
white-space: pre-wrap;
|
font-size: 14px;
|
}
|
}
|
:deep(.el-dialog__footer) {
|
border-top: unset;
|
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>
|