forked from integrated_whb/integrated_whb_vue
264 lines
6.6 KiB
Vue
264 lines
6.6 KiB
Vue
<template>
|
|
<div class="header">
|
|
<div class="left">
|
|
<div class="logo" />
|
|
<div class="menu">
|
|
<ul>
|
|
<li @click="router.push({ path: '/large_screen_data_display' })">
|
|
<div class="title">BI</div>
|
|
</li>
|
|
<template v-for="(item, index) in MENU" :key="index">
|
|
<li
|
|
:class="{ active: item.model === menuStore.getModel }"
|
|
@click="switchMenu(item.model)"
|
|
>
|
|
<div class="title">{{ item.title }}</div>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="user">
|
|
<el-dropdown
|
|
trigger="click"
|
|
placement="bottom-end"
|
|
@command="dropdownCommand"
|
|
>
|
|
<div class="user_info">
|
|
<el-avatar :size="23" fit="fill" :src="data.avatar" />
|
|
<span>{{ userStore.getUserInfo.NAME }}</span>
|
|
<icon-down
|
|
theme="filled"
|
|
size="16"
|
|
fill="#a2c2d3"
|
|
:stroke-width="3"
|
|
/>
|
|
</div>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-item command="modifyInformation">
|
|
修改信息
|
|
</el-dropdown-item>
|
|
<el-dropdown-item command="modifyAvatar">
|
|
修改头像
|
|
</el-dropdown-item>
|
|
<el-dropdown-item command="signOut">退出</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</template>
|
|
</el-dropdown>
|
|
</div>
|
|
<update-info
|
|
v-model:visible="data.userDialog.visible"
|
|
v-model:form="data.userDialog.form"
|
|
@get-data="fnGetInfo"
|
|
/>
|
|
<update-avatar
|
|
v-model:visible="data.avatarDialog.visible"
|
|
v-model:form="data.avatarDialog.form"
|
|
@get-data="fnGetInfo"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { reactive } from "vue";
|
|
import { useRouter } from "vue-router";
|
|
import { useMenuStore } from "@/pinia/menu";
|
|
import { useUserStore } from "@/pinia/user";
|
|
import { MENU } from "@/assets/js/constant";
|
|
import { getInfo, getUserInfo, logout } from "@/request/api";
|
|
import { getSpecialOperationsWarnAmount } from "@/request/special_operations";
|
|
import UpdateInfo from "./components/update_info.vue";
|
|
import UpdateAvatar from "./components/update_avatar.vue";
|
|
import { checkImgExists, addingPrefixToFile } from "@/assets/js/utils.js";
|
|
import { useWebSocket } from "@vueuse/core";
|
|
import { nanoid } from "nanoid";
|
|
import { ElNotification } from "element-plus";
|
|
|
|
defineOptions({
|
|
name: "LayoutHeader",
|
|
});
|
|
const FILE_URL = import.meta.env.VITE_FILE_URL;
|
|
const router = useRouter();
|
|
const menuStore = useMenuStore();
|
|
const userStore = useUserStore();
|
|
const data = reactive({
|
|
avatar: "",
|
|
userDialog: {
|
|
visible: false,
|
|
form: {},
|
|
},
|
|
avatarDialog: {
|
|
visible: false,
|
|
form: {},
|
|
},
|
|
});
|
|
const dropdownCommand = async (command) => {
|
|
if (command === "signOut") {
|
|
await fnSignOut();
|
|
}
|
|
if (command === "modifyInformation") {
|
|
await fnGetUserInfo();
|
|
}
|
|
if (command === "modifyAvatar") {
|
|
data.avatarDialog.visible = true;
|
|
data.avatarDialog.form.file = addingPrefixToFile([
|
|
{ FILEPATH: userStore.getUserInfo.userPhoto },
|
|
]);
|
|
}
|
|
};
|
|
const fnGetUserInfo = async () => {
|
|
const resData = await getUserInfo({
|
|
USER_ID: userStore.getUserInfo.USER_ID,
|
|
});
|
|
data.userDialog.visible = true;
|
|
data.userDialog.form = resData.pd;
|
|
};
|
|
const switchMenu = (model) => {
|
|
menuStore.setModel(model);
|
|
};
|
|
const fnInitWebSocket = () => {
|
|
const { send } = useWebSocket(
|
|
encodeURI(import.meta.env.VITE_ON_LINE_WEB_SOCKET_URL),
|
|
{
|
|
onMessage: (ws, event) => {
|
|
const data = JSON.parse(event.data);
|
|
if (data.type === "goOut") fnSignOut();
|
|
else if (data.type === "thegoout") fnSignOut();
|
|
},
|
|
}
|
|
);
|
|
send("[join]" + nanoid());
|
|
};
|
|
const fnGetInfo = async () => {
|
|
const resData = await getInfo();
|
|
try {
|
|
await checkImgExists(FILE_URL + resData.userPhoto);
|
|
data.avatar = FILE_URL + resData.userPhoto;
|
|
} catch {
|
|
data.avatar = new URL(
|
|
"../../assets/images/public/tx.png",
|
|
import.meta.url
|
|
).href;
|
|
}
|
|
userStore.setUserInfo({
|
|
...userStore.getUserInfo,
|
|
...resData,
|
|
});
|
|
fnInitWebSocket();
|
|
};
|
|
fnGetInfo();
|
|
const fnSignOut = async () => {
|
|
await logout();
|
|
userStore.$reset();
|
|
await router.replace("/login");
|
|
};
|
|
const fnSpecialOperationsWarnAmount = async () => {
|
|
const resData = await getSpecialOperationsWarnAmount();
|
|
if (resData.message) {
|
|
ElNotification({
|
|
title: "温馨提示",
|
|
dangerouslyUseHTMLString: true,
|
|
message: resData.message,
|
|
duration: 0,
|
|
type: "warning",
|
|
});
|
|
}
|
|
};
|
|
fnSpecialOperationsWarnAmount();
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.header {
|
|
background-image: url("/src/assets/images/public/headerbg.png");
|
|
background-repeat: no-repeat;
|
|
background-size: 660px 70px;
|
|
background-color: #030f2f;
|
|
border-bottom: 1px solid #1f3869;
|
|
position: relative;
|
|
|
|
.left {
|
|
display: flex;
|
|
align-items: center;
|
|
position: relative;
|
|
z-index: 99;
|
|
width: max-content;
|
|
|
|
.logo {
|
|
background-image: url("/src/assets/images/public/logo.png");
|
|
width: 500px;
|
|
height: 69px;
|
|
background-repeat: no-repeat;
|
|
background-size: 100% 100%;
|
|
}
|
|
|
|
.menu {
|
|
ul {
|
|
display: flex;
|
|
|
|
li {
|
|
height: 40px;
|
|
line-height: 40px;
|
|
text-align: center;
|
|
cursor: pointer;
|
|
background-color: #051748;
|
|
position: relative;
|
|
box-shadow: rgba(23, 66, 130, 1) 0px 0px 30px inset;
|
|
color: #fff;
|
|
min-width: 100px;
|
|
border: 1px solid #283d6f;
|
|
list-style: none;
|
|
padding: 0 20px;
|
|
margin-right: 20px;
|
|
border-radius: 2px;
|
|
|
|
&.active {
|
|
background-image: url("/src/assets/images/public/tguang.png");
|
|
background-repeat: no-repeat;
|
|
background-size: 100% 100%;
|
|
border: 1px solid #2870bb;
|
|
}
|
|
|
|
.title {
|
|
padding-left: 3px;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.user {
|
|
width: 500px;
|
|
height: 70px;
|
|
background-image: url("/src/assets/images/public/userbg.jpg");
|
|
background-repeat: no-repeat;
|
|
background-size: 100% 100%;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
position: absolute;
|
|
right: 0;
|
|
top: -1px;
|
|
|
|
.el-dropdown {
|
|
margin-right: 55px;
|
|
cursor: pointer;
|
|
position: absolute;
|
|
z-index: 999;
|
|
}
|
|
|
|
.user_info {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
span:nth-child(2) {
|
|
color: #ece8e8;
|
|
margin-left: 10px;
|
|
margin-right: 10px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|