<template>
|
<div>
|
<el-container>
|
<div id="aside">
|
<div class="sys-name">
|
<h3 style="margin-top: 0px">XXX管理系统</h3>
|
</div>
|
<el-menu
|
id="menu"
|
:default-active="$route.path"
|
mode="vertical"
|
class="el-menu-vertical-demo"
|
text-color="#000000FF"
|
:router="true"
|
>
|
<MenuContent :menus="menuList"></MenuContent>
|
</el-menu>
|
</div>
|
<el-main>
|
<el-row id="top-info">
|
<!-- <div id="top-left">-->
|
<!-- <i v-if="isCollapse" class="el-icon-s-unfold" id="icon" @click="controlAside"></i>-->
|
<!-- <i v-else class="el-icon-s-fold" id="icon" @click="controlAside"></i>-->
|
<!-- </div>-->
|
<div id="top-right">
|
<span style="padding-right: 5px; line-height: 35px; font-size: 14px;">你好,<strong>{{userInfo.nickName ? userInfo.nickName : userInfo.username}}</strong></span>
|
<el-dropdown @command="handleCommand">
|
<el-avatar id="avatar" :size="35" :src="userInfo.avatar"></el-avatar>
|
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-item command="editUser">修改个人信息</el-dropdown-item>
|
<el-dropdown-item command="resetPwd">修改密码</el-dropdown-item>
|
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
</el-dropdown-menu>
|
</el-dropdown>
|
</div>
|
</el-row>
|
<el-dialog width="20%" title="修改密码" :visible.sync="resetPwdFormVisible" :destroy-on-close="true" :append-to-body="true" :close-on-click-modal="false">
|
<el-form :model="resetPwdForm" :rules="pwdRules" ref="pwdRules">
|
<el-form-item label="旧密码" :label-width="formLabelWidth" prop="oldPwd">
|
<el-input type="password" show-password v-model="resetPwdForm.oldPwd" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="新密码" :label-width="formLabelWidth" prop="newPwd">
|
<el-input type="password" show-password v-model="resetPwdForm.newPwd" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="确认新密码" :label-width="formLabelWidth" prop="confirmPwd">
|
<el-input type="password" show-password v-model="resetPwdForm.confirmPwd" autocomplete="off"></el-input>
|
</el-form-item>
|
</el-form>
|
<div slot="footer" class="dialog-footer">
|
<el-button @click="closeResetDialog">取 消</el-button>
|
<el-button type="primary" @click="resetPwd">确 定</el-button>
|
</div>
|
</el-dialog>
|
<Tabs></Tabs>
|
<UserDialog></UserDialog>
|
</el-main>
|
|
</el-container>
|
</div>
|
</template>
|
|
<script>
|
import Tabs from "@/components/TabC.vue";
|
import MenuContent from '@/components/MenuContent.vue';
|
import UserDialog from "@/components/dialog/UserSelfUpdateDialog";
|
import {resetPwd, getAuth} from '@/api/user';
|
import {logout} from '@/api/login';
|
export default {
|
name: "IndexView",
|
components: { Tabs, MenuContent, UserDialog },
|
data() {
|
return {
|
// websocket 心跳定时器
|
heartbeatInterval: null,
|
// 用户个人信息
|
userInfo: JSON.parse(sessionStorage.getItem("userInfo")),
|
// 菜单栏折叠
|
isCollapse: false,
|
// 重置密码表单
|
resetPwdForm: {
|
oldPwd: "",
|
newPwd: "",
|
confirmPwd: ""
|
},
|
resetPwdFormVisible: false,
|
formLabelWidth: "60",
|
pwdRules: {
|
oldPwd: [
|
{ required: true, message: '请输入旧密码', trigger: 'blur' }
|
],
|
newPwd: [
|
{ required: true, message: '请输入新密码', trigger: 'blur' }
|
],
|
confirmPwd: [
|
{ required: true, message: '请填写确认新密码', trigger: 'blur' }
|
],
|
}
|
}
|
},
|
computed: {
|
menuList: {
|
get() {
|
return JSON.parse(sessionStorage.getItem("permissions"));
|
}
|
}
|
},
|
methods: {
|
resetPwd() {
|
if (this.resetPwdForm.newPwd != this.resetPwdForm.confirmPwd) {
|
this.$message.error("两次密码输入不一致")
|
return;
|
}
|
resetPwd(this.resetPwdForm).then((res) => {
|
this.resetPwdFormVisible = false;
|
this.$message.success(res.data.msg);
|
this.$router.push("/");
|
})
|
},
|
closeResetDialog() {
|
this.resetPwdFormVisible = false;
|
},
|
handleCommand(command) {
|
if (command === "editUser") {
|
this.$store.dispatch("user/editUserBySelf", this.userInfo.id)
|
} else if (command === "resetPwd") {
|
this.resetPwdFormVisible = true;
|
} else if (command === "logout") {
|
// 调用后端的退出
|
logout().then((res) => {
|
this.$message.success(res.data.msg)
|
// 清空缓存
|
sessionStorage.removeItem("token");
|
sessionStorage.removeItem("permissions");
|
sessionStorage.removeItem("userInfo");
|
sessionStorage.removeItem("doIt")
|
|
this.$router.push("/");
|
});
|
|
}
|
},
|
changeMenu(item) {
|
var params = {
|
title: item.menuName,
|
name: item.routerName
|
}
|
this.$store.commit("addTab", params)
|
},
|
senMsg(msg) {
|
// 发送文本消息
|
this.$websocket.send(msg);
|
},
|
// 发送心跳消息
|
sendHeartbeat() {
|
if (this.$websocket.readyState === WebSocket.OPEN) {
|
// 发送心跳消息,可以是任意格式的字符串,用于表示心跳
|
this.senMsg('ping');
|
}
|
},
|
// 开始心跳定时器
|
startHeartbeat() {
|
this.heartbeatInterval = setInterval(() => {
|
this.sendHeartbeat();
|
}, 10000); // 每 10 秒发送一次心跳
|
},
|
// 停止心跳定时器
|
stopHeartbeat() {
|
clearInterval(this.heartbeatInterval);
|
},
|
initWebsocket() {
|
// this.$websocket = new WebSocket('ws://127.0.0.1:8044/ws', [sessionStorage.getItem("token")])
|
this.$websocket = new WebSocket('ws://127.0.0.1:8044/ws')
|
// 监听 WebSocket 连接成功事件
|
this.$websocket.onopen = event => {
|
console.log('WebSocket 连接成功', event);
|
let msg = {
|
"token": sessionStorage.getItem("token")
|
}
|
// 发送身份认证
|
this.senMsg(JSON.stringify(msg))
|
// 设置心跳定时器,定期发送心跳消息
|
this.startHeartbeat();
|
};
|
|
// 监听 WebSocket 接收消息事件
|
this.$websocket.onmessage = event => {
|
const message = event.data;
|
console.log('接收到消息:', message);
|
};
|
|
// 监听 WebSocket 连接关闭事件
|
this.$websocket.onclose = event => {
|
console.log('WebSocket 连接关闭', event);
|
// 清除心跳定时器
|
this.stopHeartbeat();
|
};
|
},
|
getAuth() {
|
let params = {
|
"username": this.userInfo.userName
|
}
|
getAuth(params).then(res => {
|
if (res.data.code === 200) {
|
this.$store.commit("dynamicRouters", res.data.data.menuPermissions);
|
// 菜单权限
|
sessionStorage.setItem("permissions", JSON.stringify(res.data.data.menuPermissions));
|
// 按钮权限
|
sessionStorage.setItem("button-permissions", JSON.stringify(res.data.data.buttonPermissions));
|
}
|
})
|
},
|
},
|
mounted() {
|
this.initWebsocket();
|
this.getAuth();
|
},
|
beforeDestroy() {
|
this.$websocket.close();
|
},
|
}
|
</script>
|
|
<style scope>
|
.sys-name {
|
width: 100%;
|
text-align: center;
|
background-color: #d6efe6;
|
height: 60px;
|
line-height: 60px;
|
}
|
.el-divider {
|
margin-top: 2px !important;
|
}
|
#top-info {
|
height: 40px;
|
}
|
#top-left {
|
float: left;
|
}
|
#top-right {
|
float: right;
|
display: flex;
|
flex-direction: row;
|
}
|
#avatar {
|
|
}
|
#avatar:hover {
|
cursor: pointer
|
}
|
.el-main {
|
min-width: 900px;
|
height: 100vh;
|
padding: 5px 8px;
|
}
|
#icon {
|
float: left;
|
font-size: 25px;
|
}
|
#icon:hover {
|
cursor: pointer;
|
}
|
.el-menu {
|
border-right: none;
|
text-align: left;
|
}
|
#aside {
|
height: 100vh;
|
min-width: 200px;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);
|
}
|
.el-header {
|
height: 20px !important;
|
}
|
.el-divider {
|
margin: 10px 0;
|
}
|
.el-tabs {
|
padding-top: 0px !important;
|
padding-bottom: 10px !important;
|
border: 1px;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)
|
}
|
.el-footer {
|
float: right;
|
height: 45px !important;
|
padding-top: 10px;
|
}
|
.el-menu-vertical-demo:not(.el-menu--collapse) {
|
width: 200px;
|
min-height: 400px;
|
}
|
</style>
|