<template>
<div ref="centerContainer1" class="bottom-wrapper">
<vue-draggable-resizable
:draggable="false"
:handles="['tm']"
:min-height="50"
:max-height="300"
:h="50"
:w="stretch.width"
:x="stretch.left"
:parent="false"
class="bottom-container"
>
<el-tabs v-model="activeName" type="card">
<el-tab-pane label="全部" name="1">
<div v-if="logs.log1.length !== 0" class="log-content">
<div
v-for="(item, index) in logs.log1"
:key="index"
class="log-warpper"
>
<div class="info-time">
{{ filterTime(item.time) }}
</div>
<div
class="info-type"
:class="[
{ blue: item.type === 1 },
{ yellow: item.type === 2 },
{ green: item.type === 3 }
]"
>
{{ item.type | filterType }}
</div>
<div class="log-info">
{{ item.info }}
</div>
<div v-if="item.type === 2" class="view-info">
<el-button type="text">查看详情</el-button>
</div>
</div>
</div>
<no-data v-if="logs.log1.length === 0"></no-data>
</el-tab-pane>
<el-tab-pane label="操作" name="2">
<div v-if="logs.log2.length !== 0" class="log-content">
<div
v-for="(item1, index1) in logs.log2"
:key="index1"
class="log-warpper"
>
<div class="info-time">
{{ filterTime(item1.time) }}
</div>
<div class="info-type blue">
{{ item1.type | filterType }}
</div>
<div class="log-info">
{{ item1.info }}
</div>
</div>
</div>
<no-data v-if="logs.log2.length === 0"></no-data>
</el-tab-pane>
<el-tab-pane label="试运行" name="3">
<div v-if="logs.log3.length !== 0" class="log-content">
<div
v-for="(item2, index2) in logs.log3"
:key="index2"
class="log-warpper"
>
<div class="info-time">
{{ filterTime(item2.time) }}
</div>
<div class="info-type yellow">
{{ item2.type | filterType }}
</div>
<div class="log-info">
{{ item2.info }}
</div>
<div class="view-info">
<el-button type="text">查看详情</el-button>
</div>
</div>
</div>
<no-data v-if="logs.log3.length === 0"></no-data>
</el-tab-pane>
<el-tab-pane label="审批" name="4">
<div v-if="logs.log4 !== 0" class="log-content">
<div
v-for="(item3, index3) in logs.log4"
:key="index3"
class="log-warpper"
>
<div class="info-time">
{{ filterTime(item3.time) }}
</div>
<div class="info-type green">
{{ item3.type | filterType }}
</div>
<div class="log-info">
{{ item3.info }}
</div>
</div>
</div>
<no-data v-if="logs.log4.length === 0"></no-data>
</el-tab-pane>
</el-tabs>
</vue-draggable-resizable>
</div>
</template>
<script>
import { Base64 } from "js-base64";
import Cookies from "js-cookie";
import VueDraggableResizable from "vue-draggable-resizable";
import NoData from "@/components/NoData";
// 表单无数据时显示
import "vue-draggable-resizable/dist/VueDraggableResizable.css";
import { filterTime } from "@/filters";
export default {
components: {
VueDraggableResizable,
NoData
},
filters: {
filterType(type) {
const lists = {
1: "操作",
2: "试运行",
3: "审批"
};
return lists[type];
}
},
props: {
stretch: {
type: Object,
default: () => {
return {
width: 800,
left: 100
};
}
}
},
data() {
return {
activeName: "1",
webSock: null, //webScoket
logs: {
log1: [], //全部
log2: [], //操作
log3: [], //试运行
log4: [] //审批
},
filterTime
};
},
watch: {
activeName(nv, ov) {
if (nv !== ov) {
let params = {
modelId: Number(Base64.decode(this.$route.query.id)),
type: Number(nv) //1全部日志2操作日志3试运行日志4审批日志
};
this.websocketSend(params);
}
}
},
created() {
this.initWebSocket();
},
mounted() {},
beforeDestroy() {
this.wbReset(); //取消心跳时间
this.webSock.close();
},
methods: {
//初始化websocket
initWebSocket() {
let token = Cookies.get("token");
let id = Base64.decode(this.$route.query.id);
let localHost = window.location.host;
const url =
"ws://" + localHost + "/ws/modelLog/" + id + "/" + token; //与对应url建立连接
this.webSock = new WebSocket(url);
this.webSock.onopen = this.websocketOnOpen;
this.webSock.onmessage = this.websocketOnMessage;
this.webSock.onerror = this.websocketOnError;
this.webSock.onclose = this.websocketClose; },
//连接建立之后执行send方法发送数据
websocketOnOpen() {
// console.log("open");
// this.wbReset().wbstart(); //消息建立成功后重置心跳时间
let token = Cookies.get("token");
let params = {
modelId: Number(Base64.decode(this.$route.query.id)),
type: Number(this.activeName), //1全部日志2操作日志3试运行日志4审批日志
token: token
};
this.websocketSend(params);
},
websocketOnError() {
//连接建立失败重连
this.$message.error("websocket连接失败");
// this.initWebSocket();
},
//连接成功后,后端返回的数据
websocketOnMessage(event) {
if (event.data === "连接成功") return;
const res = JSON.parse(event.data);
if (res.log) {
let { type, log } = res;
this.logs["log" + type].unshift(log);
} else {
let { type, logs } = res;
let endLogs = logs.sort((a, b) => {
return b.time - a.time;
});
this.logs["log" + type] = endLogs;
this.wbReset().wbstart(); //消息接收成功后重置心跳时间
}
},
//主动向后端发送参数的方法--
websocketSend(params) {
//数据发送
this.webSock.send(JSON.stringify(params));
},
/** * 心跳检测, 每隔一段时间检测连接状态,
* 如果处于连接中,就向server端主动发送消息,
来重置server端与客户端的最大连接时间,
* 如果已经断开了,发起重连。
*/
wbReset() {
//心跳时间重置
clearInterval(this.wsHeartCheckTimeoutObj);
return this;
},
//其实就是类似一个节流函数,在固定时间长度下,给后端发信息,保持通道处于连接状态
wbstart() {
//心跳启动
this.wsHeartCheckTimeoutObj = setInterval(() => {
if (this.webSock.readyState == 1) {
// console.log("当前为连接状态,开始发送消息保持连接");
let token = Cookies.get("token");
let modelId = Number(Base64.decode(this.$route.query.id))
let params = {
modelId: modelId,
type: 0,
token: token
};
this.webSock.send(JSON.stringify(params));
this.wbReset().wbstart(); // 如果获取到消息,说明连接是正常的,重置心跳检测
} else {
// console.log("当前为断开状态,开始尝试重连");
this.initWebSocket();
}
}, 1000 * 30);
},
//连接断开时
websocketClose() {}
//切换
}};
</script>
<style lang="scss" scoped>
.bottom-wrapper {
height: 50px;
width: 100%;
position: fixed;
z-index: 0;
bottom: 0;
.bottom-container {
width: 1000px;
height: 100%;
background-color: rgba(250, 250, 250, 1);
border: 0px solid rgba(232, 232, 232, 1);
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.16);
}
}
.log-content {
width: 100%;
height: 100%;
font-size: 13px;
overflow-y: scroll;
.log-warpper {
display: flex;
justify-content: flex-start;
margin-bottom: 20px;
.info-time {
color: #666666;
width: 150px;
margin-left: 24px;
} .info-type {
width: 60px;
margin-left: 15px;
}
.log-info {
color: #666666;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 400px;
}
.view-info {
width: 80px;
/deep/.el-button.el-button--text.el-button--small {
padding: 0;
}
}
}
}
</style>