Files
admin-sjzx/src/layouts/admin/components/navMenus.vue
guanj 6c70a776a0 列设置添加缓存
调整监测点台账导出id重复问题
2026-07-17 08:50:25 +08:00

229 lines
6.4 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="nav-menus" :class="configStore.layout.layoutMode">
<el-tooltip effect="dark" content="暂降事件" placement="bottom">
<div @click="temporaryLandingEvent" class="nav-menu-item">
<Icon
:color="configStore.getColorVal('headerBarTabColor')"
class="nav-menu-icon"
name="el-icon-BellFilled"
size="18"
/>
<span class="nav-menu-text" v-if="globalPopUpRef?.eventList?.length > 0">
{{ globalPopUpRef.eventList.length > 99 ? '99+' : globalPopUpRef.eventList.length }}
</span>
</div>
</el-tooltip>
<el-dropdown style="height: 100%" @command="handleCommand">
<div class="admin-info" :class="state.currentNavMenu === 'adminInfo' ? 'hover' : ''">
<el-avatar :size="25" fit="fill">
<img src="@/assets/avatar.png" alt="" />
</el-avatar>
<div class="admin-name">{{ adminInfo.nickname }}</div>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="adminInfo">个人资料</el-dropdown-item>
<el-dropdown-item command="changePwd" v-if="!IS_LNQR">修改密码</el-dropdown-item>
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<Config />
<PopupPwd ref="popupPwd" />
<AdminInfo ref="popupAdminInfo" />
<globalPopUp ref="globalPopUpRef" />
</div>
</template>
<script lang="ts" setup>
import { reactive, ref } from 'vue'
import { useConfig } from '@/stores/config'
import { useAdminInfo } from '@/stores/adminInfo'
import { useNavTabs } from '@/stores/navTabs'
import { logout } from '@/api/user-boot/user'
import { Local } from '@/utils/storage'
import Config from './config.vue'
import PopupPwd from './popup/password.vue'
import AdminInfo from './popup/adminInfo.vue'
import globalPopUp from './globalPopUp.vue'
const { replace } = useRouter()
// 环境标识
const IS_LNQR = import.meta.env.VITE_NAME === 'LNqr'
const adminInfo = useAdminInfo()
const navTabs = useNavTabs()
const configStore = useConfig()
// 引用
const popupPwd = ref()
const popupAdminInfo = ref()
const globalPopUpRef = ref()
// 状态
const state = reactive({
currentNavMenu: ''
})
// 打开暂降事件
const temporaryLandingEvent = () => {
if (globalPopUpRef.value) {
globalPopUpRef.value.open()
}
}
// 下拉菜单命令
const handleCommand = async (key: string) => {
switch (key) {
case 'adminInfo':
popupAdminInfo.value?.open()
break
case 'changePwd':
popupPwd.value?.open()
break
case 'logout':
await handleLogout()
break
}
}
// 统一登出逻辑
const handleLogout = async () => {
try {
// 1. 调用后端登出接口
await logout()
// console.log('✅ 后端登出成功')
} catch (err) {
// console.error('❌ 登出接口异常', err)
} finally {
// 2. 清理本地所有数据
clearLocalData()
// 3. LNqr 环境跳 CAS 登出
if (IS_LNQR) {
redirectToCasLogout()
} else {
// 普通环境直接跳登录页
window.location.reload()
setTimeout(() => {
replace('/login')
}, 1000)
}
}
}
// 清理本地数据
const clearLocalData = () => {
// 清空 localStorage保留 VXE 自定义列、DevTools 配置)
Local.clear()
// 清空用户状态
adminInfo.reset()
// 清空标签页
navTabs.closeTabs()
}
// CAS 登出跳转
const redirectToCasLogout = () => {
const casLogoutUrl =
'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/logout?service=http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn'
window.location.href = casLogoutUrl
// 清 Cookie
document.cookie.split(';').forEach(cookie => {
const name = cookie.split('=')[0].trim()
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
})
}
</script>
<style scoped lang="scss">
.nav-menus.Default {
border-radius: var(--el-border-radius-base);
box-shadow: var(--el-box-shadow-light);
}
.nav-menus {
height: 60px;
display: flex;
align-items: center;
margin-left: auto;
background-color: v-bind('configStore.getColorVal("headerBarBackground")');
.nav-menu-item {
position: relative;
height: 100%;
width: 40px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
.nav-menu-icon {
box-sizing: content-box;
color: v-bind('configStore.getColorVal("headerBarTabColor")');
}
&:hover {
.icon {
animation: twinkle 0.3s ease-in-out;
}
}
}
.admin-info {
display: flex;
height: 100%;
padding: 0 10px;
align-items: center;
cursor: pointer;
user-select: none;
color: v-bind('configStore.getColorVal("headerBarTabColor")');
&:hover {
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")');
}
}
.admin-name {
padding-left: 6px;
white-space: nowrap;
}
.nav-menu-item:hover,
.admin-info:hover,
.nav-menu-item.hover,
.admin-info.hover {
background: v-bind('configStore.getColorVal("headerBarHoverBackground")');
.nav-menu-icon {
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")') !important;
}
}
}
.nav-menu-text {
position: absolute;
top: 13px;
left: 20px;
font-size: 12px;
background: #ff0000;
color: #fff;
border-radius: 5px;
padding: 0 3px;
}
@keyframes twinkle {
0% {
transform: scale(0);
}
80% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
</style>