WholeProcessPlatform/frontend/src/layout/components/Navbar.vue

168 lines
4.0 KiB
Vue
Raw Normal View History

2026-03-25 10:02:19 +08:00
<script setup lang="ts">
2026-03-27 14:50:35 +08:00
import { ref, onMounted, onBeforeUnmount } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessageBox } from "element-plus";
import { getToken } from "@/utils/auth";
import { UserOutlined, LogoutOutlined } from "@ant-design/icons-vue";
// 国际化
import { useI18n } from "vue-i18n";
const { t } = useI18n();
2026-03-25 10:02:19 +08:00
// import LangSelect from '@/components/LangSelect/index.vue';
2026-03-27 14:50:35 +08:00
import Sidebar from "./Sidebar/index.vue";
2026-03-25 10:02:19 +08:00
2026-03-27 14:50:35 +08:00
import { useTagsViewStore } from "@/store/modules/tagsView";
import { useUserStore } from "@/store/modules/user";
import Cookies from "js-cookie";
import { storeToRefs } from "pinia";
2026-03-25 10:02:19 +08:00
const url = import.meta.env.VITE_APP_BASE_API;
2026-03-27 14:50:35 +08:00
const username = Cookies.get("username");
2026-03-25 10:02:19 +08:00
const tagsViewStore = useTagsViewStore();
const userStore = useUserStore();
const route = useRoute();
const router = useRouter();
function logout() {
2026-03-27 14:50:35 +08:00
ElMessageBox.confirm("确定注销并退出系统吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
2026-03-25 10:02:19 +08:00
}).then(() => {
userStore
.logout()
.then(() => {
tagsViewStore.delAllViews();
})
.then(() => {
router.push(`/login?redirect=${route.fullPath}`);
});
});
}
2026-03-27 14:50:35 +08:00
const badgeval = ref(0);
const isbadge = ref(true);
var source = new EventSource(url + `/sse/connect/` + getToken());
2026-03-25 10:02:19 +08:00
onMounted(() => {
if ("EventSource" in window) {
2026-03-27 14:50:35 +08:00
source.onmessage = function (e) {
if (e.data > 0) {
badgeval.value = e.data;
isbadge.value = false;
2026-03-25 10:02:19 +08:00
} else {
2026-03-27 14:50:35 +08:00
isbadge.value = true;
2026-03-25 10:02:19 +08:00
}
};
2026-03-27 14:50:35 +08:00
source.onopen = function (e) {};
source.onerror = function (e: any) {
2026-03-25 10:02:19 +08:00
if (e.readyState == EventSource.CLOSED) {
} else {
}
};
} else {
2026-03-27 14:50:35 +08:00
}
});
onBeforeUnmount(() => {
2026-03-25 10:02:19 +08:00
source.close();
2026-03-27 14:50:35 +08:00
});
2026-03-25 10:02:19 +08:00
</script>
<template>
<div class="navbar">
2026-03-27 14:50:35 +08:00
<a-layout-header class="header">
<transition class="bg-white-800">
<a
href="/"
class="h-[50px] min-w-[350px] flex items-center justify-center text-white"
>
<h1 class="text-blank font-bold fontSize-16">{{ t("login.title") }}</h1></a
>
</transition>
<Sidebar />
2026-03-25 10:02:19 +08:00
2026-03-27 14:50:35 +08:00
<a-dropdown :trigger="['click']" placement="bottomRight">
<a-space class="username">
<div>
<span class="icon">
<UserOutlined />
</span>
<span class="text">{{ username }}</span>
</div>
</a-space>
<template #overlay>
<a-menu>
<a-menu-item key="changePassword">
<UserOutlined />
修改密码
</a-menu-item>
<a-menu-divider />
<a-menu-item key="logout" @click="logout">
<LogoutOutlined />
退出登录
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</a-layout-header>
2026-03-25 10:02:19 +08:00
</div>
</template>
<style lang="scss" scoped>
2026-03-27 14:50:35 +08:00
@use "@/styles/variables.module.scss" as *;
2026-03-25 10:02:19 +08:00
.navbar {
width: 100%;
position: relative;
2026-03-27 14:50:35 +08:00
height: 110px;
2026-03-25 10:02:19 +08:00
display: -webkit-flex;
z-index: 98;
2026-03-27 14:50:35 +08:00
.header {
width: 100%;
display: flex;
align-items: center;
background-color: #005293;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
height: $layout-header-height;
position: sticky;
top: 0;
z-index: 100;
padding-left: 0;
padding-right: 10px;
}
.username {
height: $layout-header-height;
line-height: $layout-header-height;
display: flex;
cursor: pointer;
div {
display: flex;
align-items: center;
}
2026-03-25 10:02:19 +08:00
2026-03-27 14:50:35 +08:00
.icon {
width: 32px;
height: 32px;
line-height: 32px;
text-align: center;
color: $main-menu-color;
border-radius: 50%;
display: inline-block;
font-size: 18px;
background-color: rgba(255, 255, 255, 0.2);
}
.text {
color: $main-menu-color;
padding-left: 10px;
margin-top: -5px;
}
2026-03-25 10:02:19 +08:00
}
}
2026-03-27 14:50:35 +08:00
.heighta {
border-left: 1px solid #dcdfe6;
2026-03-25 10:02:19 +08:00
height: 1em;
margin-right: 15px;
}
</style>