feat: terminal日志回放,节前提交一半关机没提成功
This commit is contained in:
@@ -43,6 +43,7 @@ $dropdown-hover-background-color: #fafafa; //下拉鼠标悬停背景色
|
|||||||
|
|
||||||
$danger-color: #DE5D3F; //全局警告色红色
|
$danger-color: #DE5D3F; //全局警告色红色
|
||||||
$success-color: #23BF9A; //全局正常色绿色
|
$success-color: #23BF9A; //全局正常色绿色
|
||||||
|
$warning-color: $btn-light-txt-color-hover-new; //全局警告橙色
|
||||||
$suspended-color: #9e9c98; //全局停用色灰色
|
$suspended-color: #9e9c98; //全局停用色灰色
|
||||||
|
|
||||||
$left-menu-bgcolor:#FFF;
|
$left-menu-bgcolor:#FFF;
|
||||||
|
|||||||
@@ -917,8 +917,8 @@ li{
|
|||||||
padding:2px 5px;
|
padding:2px 5px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.nz-table td.success .cell>span {
|
.nz-table td.warning .cell>span {
|
||||||
background-color: $success-color;
|
background-color: $warning-color;
|
||||||
color: white;
|
color: white;
|
||||||
padding:2px 5px;
|
padding:2px 5px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|||||||
@@ -16,20 +16,24 @@
|
|||||||
<div class="window-control-btn" @click="closeSubList" :id="from+'-bottom-close'"><i class="nz-icon nz-icon-close"></i></div>
|
<div class="window-control-btn" @click="closeSubList" :id="from+'-bottom-close'"><i class="nz-icon nz-icon-close"></i></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!------TAB区------>
|
<!------TAB区------>
|
||||||
<!--机柜-->
|
<!--机柜-->
|
||||||
<cabinet-tab :obj="obj" @changeTab="changeTab" v-if="from == $CONSTANTS.fromRoute.dc && targetTab == 'cabinet'" v-show="subResizeShow"></cabinet-tab>
|
<cabinet-tab :obj="obj" @changeTab="changeTab" v-if="from == $CONSTANTS.fromRoute.dc && targetTab == 'cabinet'" v-show="subResizeShow"></cabinet-tab>
|
||||||
<!--告警信息-->
|
<!--告警信息-->
|
||||||
<alert-message-tab :from="from" :obj="obj" @changeTab="changeTab" v-if="((from == $CONSTANTS.fromRoute.rule || from == $CONSTANTS.fromRoute.asset || from == $CONSTANTS.fromRoute.endpoint) && targetTab == 'alertMessage')" v-show="subResizeShow"></alert-message-tab>
|
<alert-message-tab :from="from" :obj="obj" @changeTab="changeTab" v-if="((from == $CONSTANTS.fromRoute.rule || from == $CONSTANTS.fromRoute.asset || from == $CONSTANTS.fromRoute.endpoint) && targetTab == 'alertMessage')" v-show="subResizeShow"></alert-message-tab>
|
||||||
<!--asset页的endpoint列表-->
|
<!--asset页的endpoint列表-->
|
||||||
<endpoint-tab :from="from" :obj="obj" @changeTab="changeTab" v-if="from == $CONSTANTS.fromRoute.asset && targetTab == $CONSTANTS.fromRoute.endpoint" v-show="subResizeShow"></endpoint-tab>
|
<endpoint-tab :from="from" :obj="obj" @changeTab="changeTab" v-if="from == $CONSTANTS.fromRoute.asset && targetTab == $CONSTANTS.fromRoute.endpoint" v-show="subResizeShow"></endpoint-tab>
|
||||||
<!--endpoint-query-->
|
<!--endpoint-query-->
|
||||||
<endpoint-query-tab :from="from" :obj="obj" @changeTab="changeTab" ref="endpointQuery" v-if="(from == $CONSTANTS.fromRoute.endpoint && targetTab == 'endpointQuery')" v-show="subResizeShow"></endpoint-query-tab>
|
<endpoint-query-tab :from="from" :obj="obj" @changeTab="changeTab" ref="endpointQuery" v-if="(from == $CONSTANTS.fromRoute.endpoint && targetTab == 'endpointQuery')" v-show="subResizeShow"></endpoint-query-tab>
|
||||||
|
|
||||||
<!-- model-panel/asset-detail/project-overview的panel-->
|
<!-- model-panel/asset-detail/project-overview的panel-->
|
||||||
<panel-tab :from="from" :obj="obj" ref="panelTab" v-if="(from == $CONSTANTS.fromRoute.model || from == $CONSTANTS.fromRoute.asset || from == $CONSTANTS.fromRoute.project || from == $CONSTANTS.fromRoute.rule || from == $CONSTANTS.fromRoute.endpoint) && targetTab == 'panel'" v-show="subResizeShow"
|
<panel-tab :from="from" :obj="obj" ref="panelTab" v-if="(from == $CONSTANTS.fromRoute.model || from == $CONSTANTS.fromRoute.asset || from == $CONSTANTS.fromRoute.project || from == $CONSTANTS.fromRoute.rule || from == $CONSTANTS.fromRoute.endpoint) && targetTab == 'panel'" v-show="subResizeShow"
|
||||||
@changeTab="changeTab" :targetTab.sync="targetTab" :detail="detail"></panel-tab>
|
@changeTab="changeTab" :targetTab.sync="targetTab" :detail="detail"></panel-tab>
|
||||||
|
|
||||||
|
<!--terminal-log的记录和回放-->
|
||||||
|
<terminal-log-record-tab :from="from" :obj="obj" @changeTab="changeTab" ref="reminalLogRecordTab" v-if="from == $CONSTANTS.fromRoute.terminalLog && targetTab == 'record'"></terminal-log-record-tab>
|
||||||
|
<terminal-log-replay-tab :from="from" :obj="obj" @changeTab="changeTab" ref="reminalLogReplayTab" v-if="from == $CONSTANTS.fromRoute.terminalLog && targetTab == 'replay'"></terminal-log-replay-tab>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -40,6 +44,8 @@
|
|||||||
import endpointQueryTab from "./tabs/endpointQueryTab";
|
import endpointQueryTab from "./tabs/endpointQueryTab";
|
||||||
import endpointTab from "./tabs/endpointTab";
|
import endpointTab from "./tabs/endpointTab";
|
||||||
import panelTab from "./tabs/panelTab";
|
import panelTab from "./tabs/panelTab";
|
||||||
|
import terminalLogRecordTab from "./tabs/terminalLogRecordTab";
|
||||||
|
import terminalLogReplayTab from "./tabs/terminalLogReplayTab";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "bottomBox",
|
name: "bottomBox",
|
||||||
@@ -49,6 +55,8 @@
|
|||||||
'endpoint-query-tab': endpointQueryTab,
|
'endpoint-query-tab': endpointQueryTab,
|
||||||
'endpoint-tab': endpointTab,
|
'endpoint-tab': endpointTab,
|
||||||
'panel-tab': panelTab,
|
'panel-tab': panelTab,
|
||||||
|
terminalLogRecordTab,
|
||||||
|
terminalLogReplayTab
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
isFullScreen: false, //是否全屏
|
isFullScreen: false, //是否全屏
|
||||||
|
|||||||
@@ -0,0 +1,252 @@
|
|||||||
|
<template>
|
||||||
|
<div style="height: 100%;">
|
||||||
|
<div class="sub-top-tools">
|
||||||
|
<div class="sub-list-tabs">
|
||||||
|
<div class="sub-list-tab-title">ID:{{obj.id}}</div><div
|
||||||
|
@click="changeTab('replay')" class="sub-list-tab">{{$t("config.terminallog.replay")}}</div><div
|
||||||
|
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.record.record")}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="record-container">
|
||||||
|
<div class="record-container--record">
|
||||||
|
<div class="record--title">{{$t('config.terminallog.record.history')}}</div>
|
||||||
|
<div class="record--list">
|
||||||
|
<template v-for="(record, index) in records">
|
||||||
|
<template v-for="item in record.list">
|
||||||
|
<div class="detail--time"><span>{{calcTime(item.time)}}</span></div>
|
||||||
|
<div class="detail--cmd"><span :class="matchBgColor(item.cmd)">{{item.cmd}}</span></div>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<div class="record--more" v-if="hasNext">
|
||||||
|
<span @click="loadMore" class="nz-btn nz-btn-size-small nz-btn-style-light"><i class="nz-icon nz-icon-arrow-down"></i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="record-container--record record-container--record__tip">
|
||||||
|
<div class="record--title">{{$t('config.terminallog.record.legendTip')}}</div>
|
||||||
|
<div class="record--list">
|
||||||
|
<div class="detail--time"><span>yyyy-MM-dd HH:mm:ss</span></div>
|
||||||
|
<div class="detail--cmd"><span class="detail--cmd__red">{{$t("config.terminallog.record.dangerTip")}}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "terminalLogRecordTab",
|
||||||
|
components: {
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
obj: Object, //关联的实体对象
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
calcTime() {
|
||||||
|
return function(time) {
|
||||||
|
if (this.obj.startTime) {
|
||||||
|
let startTime = new Date(this.obj.startTime).getTime();
|
||||||
|
if (startTime) {
|
||||||
|
let thisTime = startTime+time;
|
||||||
|
return this.dateFormat(thisTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
matchBgColor() {
|
||||||
|
return function(cmd) {
|
||||||
|
let className = "";
|
||||||
|
let dangerCmd = this.$CONSTANTS.terminalLog.dangerCmd;
|
||||||
|
let infoCmd = this.$CONSTANTS.terminalLog.infoCmd;
|
||||||
|
let cmdSplit = cmd.split(" ");
|
||||||
|
if (this.intersection(infoCmd, cmdSplit).length > 0) {
|
||||||
|
className = "detail--cmd__green";
|
||||||
|
}
|
||||||
|
if (this.intersection(dangerCmd, cmdSplit).length > 0) {
|
||||||
|
className = "detail--cmd__red";
|
||||||
|
}
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hasNext() {
|
||||||
|
if (this.records.length > 0) {
|
||||||
|
return this.records[this.records.length-1].hasNext;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
filter: {
|
||||||
|
uuid: this.obj.uuid,
|
||||||
|
cmd: "",
|
||||||
|
time: "",
|
||||||
|
size: 200
|
||||||
|
},
|
||||||
|
records: [ // 加载更多时有多个record,否则只有一个
|
||||||
|
|
||||||
|
],
|
||||||
|
/*record: { // cmd记录,含hasNext、time(最后一条时间)、total和list
|
||||||
|
total: 4,
|
||||||
|
hasNext: true,
|
||||||
|
time: 9889,
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
uuid: 1,
|
||||||
|
time: 1024,
|
||||||
|
cmd: "ls -ef|grep java"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
uuid: 2,
|
||||||
|
time: 3824,
|
||||||
|
cmd: "su root ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|ls -ef|grep java|afaewrafaser aolewr | awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|awk fajpoerja;welkrjfa;wle|"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
uuid: 3,
|
||||||
|
time: 7740,
|
||||||
|
cmd: "rm -rf /"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
uuid: 4,
|
||||||
|
time: 9889,
|
||||||
|
cmd: "exit"
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initData(filter) {
|
||||||
|
this.$get("/terminal/cmd", filter).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.records.push(res.data);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
loadMore() {
|
||||||
|
let filter = Object.assign({}, this.filter);
|
||||||
|
filter.time = this.records[this.records.length-1].time;
|
||||||
|
this.initData(filter);
|
||||||
|
},
|
||||||
|
// 切换tab
|
||||||
|
changeTab(tab) {
|
||||||
|
this.$emit('changeTab', tab);
|
||||||
|
},
|
||||||
|
intersection(a, b) {
|
||||||
|
let s = new Set(b);
|
||||||
|
return a.filter(x => s.has(x));
|
||||||
|
},
|
||||||
|
dateFormat(time) {
|
||||||
|
if (!time) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
let date = new Date(time);
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||||
|
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||||
|
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||||
|
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||||
|
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||||
|
|
||||||
|
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
|
||||||
|
},
|
||||||
|
formatUpdateTime(date) {
|
||||||
|
let time=new Date(date);
|
||||||
|
let hours=time.getHours()>9?time.getHours():'0'+time.getHours();
|
||||||
|
let minutes=time.getMinutes()>9?time.getMinutes():'0'+time.getMinutes();
|
||||||
|
|
||||||
|
return hours+':'+minutes;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
obj: {
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
handler(n) {
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initData(this.filter);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.record-container {
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.record-container--record {
|
||||||
|
background-color: white;
|
||||||
|
width: calc(50% - 14px);
|
||||||
|
padding: 16px 15px 14px 15px;
|
||||||
|
border: 1px solid #d8dce1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-height: 100px;
|
||||||
|
|
||||||
|
.record--title {
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record--list {
|
||||||
|
display: grid;
|
||||||
|
gap: 6px 12px;
|
||||||
|
grid-template-columns: 150px auto;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
padding-left: 16px;
|
||||||
|
|
||||||
|
.detail--time {
|
||||||
|
line-height: 18px;
|
||||||
|
grid-column: 1/span 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
span {
|
||||||
|
background-color: #ECECEC;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail--cmd {
|
||||||
|
line-height: 18px;
|
||||||
|
grid-column: 2/span 1;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
span {
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail--cmd__green {
|
||||||
|
background-color: #B4FDB1;
|
||||||
|
}
|
||||||
|
.detail--cmd__red {
|
||||||
|
background-color: #FFD2C2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.record--more {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.record-container--record.record-container--record__tip {
|
||||||
|
margin-top: 10px;
|
||||||
|
min-height: unset;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
<template>
|
||||||
|
<div style="height: 100%;">
|
||||||
|
<div class="sub-top-tools">
|
||||||
|
<div class="sub-list-tabs">
|
||||||
|
<div class="sub-list-tab-title">ID:{{obj.id}}</div><div
|
||||||
|
class="sub-list-tab sub-list-tab-active">{{$t("config.terminallog.replay")}}</div><div
|
||||||
|
@click="changeTab('record')" class="sub-list-tab">{{$t("config.terminallog.record.record")}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="replay-container">
|
||||||
|
<div class="replay-operate">
|
||||||
|
<button @click="pause" class="nz-btn nz-btn-style-light nz-btn-size-large">暂停</button>
|
||||||
|
<button @click="play" class="nz-btn nz-btn-style-light nz-btn-size-large">播放</button>
|
||||||
|
<button @click="restart" class="nz-btn nz-btn-style-light nz-btn-size-large">重新播放</button>
|
||||||
|
<el-tag>{{progress}}</el-tag>
|
||||||
|
</div>
|
||||||
|
<div class="replay-console">
|
||||||
|
<div :id="obj.uuid" class="replay-terminal"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Terminal from '../../js/Xterm';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "terminalLogReplayTab",
|
||||||
|
components: {
|
||||||
|
Terminal
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
obj: Object, //关联的实体对象
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
filter: {
|
||||||
|
size: 1,
|
||||||
|
uuid: ""
|
||||||
|
},
|
||||||
|
operate: {
|
||||||
|
pause: false, // 是否暂停
|
||||||
|
|
||||||
|
},
|
||||||
|
terminal: null,
|
||||||
|
|
||||||
|
recordData: [],
|
||||||
|
isNeedStop: false, // 是否需要停止
|
||||||
|
playedCount: 0, // 当前已经播放完的数量
|
||||||
|
isPlaying: true, // 是否正在播放
|
||||||
|
isFinish: false, //是否已结束
|
||||||
|
recordTick: 50, // 输出间隔时间ms,默认50
|
||||||
|
playerTimer: null, // 定时器
|
||||||
|
playerCurrentTime: 0, // 当前时间进度
|
||||||
|
speedTable: [ // 快进倍速选项
|
||||||
|
{speed: 1, name: 'Normal'},
|
||||||
|
{speed: 2, name: 'x2'},
|
||||||
|
{speed: 4, name: 'x4'},
|
||||||
|
{speed: 8, name: 'x8'},
|
||||||
|
{speed: 16, name: 'x16'}
|
||||||
|
],
|
||||||
|
speedOffset: 0, // 快进倍数index
|
||||||
|
progress: 0, // 进度条进度
|
||||||
|
needSkip: false, // 需要时间刻度,即是否跳过无操作时间,为true时表示需要,即不跳过无操作时间
|
||||||
|
timeUsed: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 切换tab
|
||||||
|
changeTab(tab) {
|
||||||
|
this.$emit('changeTab', tab);
|
||||||
|
},
|
||||||
|
|
||||||
|
getReplayData() {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
this.$get("/terminal/record", this.filter).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
this.recordData = res.data.list;
|
||||||
|
this.timeUsed = res.data.endTime;
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
initAndPlay() {
|
||||||
|
// terminal初始化
|
||||||
|
if (!this.terminal) {
|
||||||
|
this.terminal = new Terminal(
|
||||||
|
{
|
||||||
|
cols: 70,
|
||||||
|
rows: 28
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.terminal.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.terminal.open(document.getElementById(this.obj.uuid));
|
||||||
|
this.terminal.resize(70, 28);
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (this.recordData.length > 0) {
|
||||||
|
this.isNeedStop = false;
|
||||||
|
this.isPlaying = true;
|
||||||
|
this.isFinished = false;
|
||||||
|
this.playedCount = 0;
|
||||||
|
this.doPlay();
|
||||||
|
} else {
|
||||||
|
let req = this.getReplayData();
|
||||||
|
req.then(() => {
|
||||||
|
if (this.recordData.length > 0) {
|
||||||
|
// 请求得到数据后,开始播放
|
||||||
|
this.isNeedStop = false;
|
||||||
|
this.isPlaying = true;
|
||||||
|
this.isFinished = false;
|
||||||
|
this.playedCount = 0;
|
||||||
|
this.doPlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 800);
|
||||||
|
},
|
||||||
|
|
||||||
|
/*原理:利用setTimeout和数据的时间偏移量来模拟实现视频播放效果*/
|
||||||
|
doPlay() {
|
||||||
|
if (this.isNeedStop) {
|
||||||
|
this.isPlaying = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.recordData.length <= this.playedCount) {
|
||||||
|
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.playerCurrentTime += this.recordTick * this.speedTable[this.speedOffset].speed;
|
||||||
|
|
||||||
|
let recordTick = this.recordTick;
|
||||||
|
|
||||||
|
let playData;
|
||||||
|
for (let i = this.playedCount; i < this.recordData.length; i++) {
|
||||||
|
if (this.isNeedStop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
playData = this.recordData[i];
|
||||||
|
if (playData.t < this.playerCurrentTime) {
|
||||||
|
this.terminal.write(playData.c);
|
||||||
|
|
||||||
|
if ((this.playedCount + 1) === this.recordData.length) {
|
||||||
|
//播放完成
|
||||||
|
this.progress = 100;
|
||||||
|
this.isFinished = true;
|
||||||
|
this.isPlaying = false;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
this.playedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.isNeedStop) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.needSkip) {
|
||||||
|
if (playData.t - this.playerCurrentTime > 800) {
|
||||||
|
this.playerCurrentTime = playData.t; // - this.record_tick * this.speed_table[this.speed_offset].speed;
|
||||||
|
recordTick = 800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同步进度条
|
||||||
|
this.progress = parseInt(this.playerCurrentTime * 100 / this.timeUsed);
|
||||||
|
|
||||||
|
if (this.playedCount >= this.recordData.length) {
|
||||||
|
this.progress = 100;
|
||||||
|
//播放完成
|
||||||
|
this.isFinished = true;
|
||||||
|
this.isPlaying = false;
|
||||||
|
} else {
|
||||||
|
if (!this.isNeedStop)
|
||||||
|
this.playerTimer = setTimeout(this.doPlay, recordTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
play() {
|
||||||
|
if (this.isPlaying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isFinished) {
|
||||||
|
this.restart();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isNeedStop = false;
|
||||||
|
this.isPlaying = true;
|
||||||
|
this.playerTimer = setTimeout(this.doPlay, this.recordTick);
|
||||||
|
},
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
if (this.playerTimer) {
|
||||||
|
clearTimeout(this.playerTimer);
|
||||||
|
}
|
||||||
|
this.isNeedStop = true;
|
||||||
|
this.isPlaying = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
if (this.playerTimer) {
|
||||||
|
clearTimeout(this.playerTimer);
|
||||||
|
}
|
||||||
|
this.playerCurrentTime = 0;
|
||||||
|
this.initAndPlay();
|
||||||
|
},
|
||||||
|
|
||||||
|
dateFormat(time) {
|
||||||
|
if (!time) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
let date = new Date(time * 1000);
|
||||||
|
let year = date.getFullYear();
|
||||||
|
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
|
||||||
|
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
|
||||||
|
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
|
||||||
|
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
|
||||||
|
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
|
||||||
|
|
||||||
|
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
|
||||||
|
},
|
||||||
|
formatUpdateTime(date) {
|
||||||
|
let time=new Date(date);
|
||||||
|
let hours=time.getHours()>9?time.getHours():'0'+time.getHours();
|
||||||
|
let minutes=time.getMinutes()>9?time.getMinutes():'0'+time.getMinutes();
|
||||||
|
|
||||||
|
return hours+':'+minutes;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 入口,监听terminal session的变化,开始功能
|
||||||
|
obj: {
|
||||||
|
immediate: true,
|
||||||
|
deep: true,
|
||||||
|
handler(n) {
|
||||||
|
if (n.uuid) {
|
||||||
|
this.filter.uuid = n.uuid;
|
||||||
|
this.initAndPlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.replay-console {
|
||||||
|
width: 660px;
|
||||||
|
height: 480px;
|
||||||
|
padding: 10px 4px 10px 10px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -149,6 +149,18 @@ export const setting = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const terminalLog = {
|
||||||
|
status: {
|
||||||
|
0: i18n.t('config.terminallog.statusItem.connecting'),
|
||||||
|
1: i18n.t('config.terminallog.statusItem.connectionFailed'),
|
||||||
|
2: i18n.t('config.terminallog.statusItem.over'),
|
||||||
|
3: i18n.t('config.terminallog.statusItem.kickedOut'),
|
||||||
|
4: i18n.t('config.terminallog.statusItem.unknownError'),
|
||||||
|
},
|
||||||
|
dangerCmd: ['chmod', 'chown', 'kill', 'rm', 'su', 'sudo'],
|
||||||
|
infoCmd: ['exit']
|
||||||
|
};
|
||||||
|
|
||||||
//公共组件的跳转来源
|
//公共组件的跳转来源
|
||||||
export const fromRoute = {
|
export const fromRoute = {
|
||||||
panel: "panel",
|
panel: "panel",
|
||||||
@@ -160,5 +172,6 @@ export const fromRoute = {
|
|||||||
dc: "dc",
|
dc: "dc",
|
||||||
endpoint: "endpoint",
|
endpoint: "endpoint",
|
||||||
project: "project",
|
project: "project",
|
||||||
endpointQuery: "endpointQuery"
|
endpointQuery: "endpointQuery",
|
||||||
|
terminalLog: "terminal"
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -284,7 +284,17 @@ export function stringTimeParseToUnix(stringTime){
|
|||||||
let time=new Date(stringTime).getTime();
|
let time=new Date(stringTime).getTime();
|
||||||
return time/1000;
|
return time/1000;
|
||||||
}
|
}
|
||||||
|
export function calcDurationByStringTime(startTime, endTime) {
|
||||||
|
let durationSecond = stringTimeParseToUnix(endTime)-stringTimeParseToUnix(startTime);
|
||||||
|
let result = `${durationSecond%60}s`;
|
||||||
|
if (durationSecond > 60) {
|
||||||
|
result = `${(Math.floor(durationSecond/60))%60}m ${result}`;
|
||||||
|
}
|
||||||
|
if (durationSecond > 60*60) {
|
||||||
|
result = `${Math.floor(durationSecond/(60*60))}h ${result}`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
export function unixTimeParseToString(unixTime,fmt='yyyy-MM-dd hh:mm:ss'){
|
export function unixTimeParseToString(unixTime,fmt='yyyy-MM-dd hh:mm:ss'){
|
||||||
let date=new Date(unixTime * 1000);
|
let date=new Date(unixTime * 1000);
|
||||||
var o = {
|
var o = {
|
||||||
@@ -592,13 +602,8 @@ export const tableSet = {
|
|||||||
}
|
}
|
||||||
case 'temrminallog':
|
case 'temrminallog':
|
||||||
switch(prop){
|
switch(prop){
|
||||||
case 'id': return 'id';
|
|
||||||
case 'host': return 'host';
|
|
||||||
case 'port': return 'port';
|
|
||||||
case 'protocol': return 'protocol';
|
case 'protocol': return 'protocol';
|
||||||
case 'user': return 'user';
|
case 'startTime': return 'startTime';
|
||||||
case 'cmd': return 'cmd';
|
|
||||||
case 'time': return 'time';
|
|
||||||
default : return prop;
|
default : return prop;
|
||||||
}
|
}
|
||||||
case 'alertRules':
|
case 'alertRules':
|
||||||
|
|||||||
@@ -631,6 +631,13 @@ const cn = {
|
|||||||
terminallog: {
|
terminallog: {
|
||||||
terminallog: "终端日志",
|
terminallog: "终端日志",
|
||||||
status: "状态",
|
status: "状态",
|
||||||
|
statusItem: {
|
||||||
|
connecting: "连接中",
|
||||||
|
connectionFailed: "连接失败",
|
||||||
|
over: "已结束",
|
||||||
|
kickedOut: "被踢出",
|
||||||
|
unknownError: "未知错误"
|
||||||
|
},
|
||||||
option: "操作",
|
option: "操作",
|
||||||
host: "主机",
|
host: "主机",
|
||||||
cmd: "命令",
|
cmd: "命令",
|
||||||
@@ -655,7 +662,18 @@ const cn = {
|
|||||||
path: "路径",
|
path: "路径",
|
||||||
file: "文件",
|
file: "文件",
|
||||||
success: "成功",
|
success: "成功",
|
||||||
fail: "失败"
|
fail: "失败",
|
||||||
|
startTime: "开始时间",
|
||||||
|
duration: "持续",
|
||||||
|
remote: "远程连接",
|
||||||
|
replay: "回放",
|
||||||
|
log: "日志",
|
||||||
|
record: {
|
||||||
|
record: "记录",
|
||||||
|
history: "历史记录",
|
||||||
|
dangerTip: "这条命令可能是危险的",
|
||||||
|
legendTip: "图例说明",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
dc: {
|
dc: {
|
||||||
dc: "数据中心",
|
dc: "数据中心",
|
||||||
|
|||||||
@@ -669,6 +669,13 @@ const en = {
|
|||||||
terminallog: {
|
terminallog: {
|
||||||
terminallog: 'Terminal log',
|
terminallog: 'Terminal log',
|
||||||
status: 'Status',//"状态"
|
status: 'Status',//"状态"
|
||||||
|
statusItem: {
|
||||||
|
connecting: "Connecting",
|
||||||
|
connectionFailed: "Connection failed",
|
||||||
|
over: "Over",
|
||||||
|
kickedOut: "Kicked out",
|
||||||
|
unknownError: "Unknown error"
|
||||||
|
},
|
||||||
option: 'Operation',//"操作",
|
option: 'Operation',//"操作",
|
||||||
host: 'Host',
|
host: 'Host',
|
||||||
cmd: 'CMD',
|
cmd: 'CMD',
|
||||||
@@ -693,7 +700,18 @@ const en = {
|
|||||||
path: 'Path',
|
path: 'Path',
|
||||||
file: 'File',
|
file: 'File',
|
||||||
success: 'Success',
|
success: 'Success',
|
||||||
fail: 'Fail'
|
fail: 'Fail',
|
||||||
|
startTime: "Start time",
|
||||||
|
duration: "Duration",
|
||||||
|
remote: "Remote",
|
||||||
|
replay: "Replay",
|
||||||
|
log: "Log",
|
||||||
|
record: {
|
||||||
|
record: "Record",
|
||||||
|
history: "History record",
|
||||||
|
dangerTip: "This CMD may be dangerous",
|
||||||
|
legendTip: "Legend description",
|
||||||
|
}
|
||||||
},
|
},
|
||||||
operationlog: {
|
operationlog: {
|
||||||
operationlog: 'Operation log',
|
operationlog: 'Operation log',
|
||||||
|
|||||||
@@ -96,14 +96,6 @@
|
|||||||
<span>-</span>
|
<span>-</span>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<span v-else-if="item.prop == 'lang'">
|
|
||||||
{{scope.row[item.prop] == 'en' ? 'English' : ''}}
|
|
||||||
{{scope.row[item.prop] == 'zh' ? '中文' : ''}}
|
|
||||||
{{scope.row[item.prop] == 'ru' ? 'русский' : ''}}
|
|
||||||
</span>
|
|
||||||
<span v-else-if="item.prop == 'receiver'">
|
|
||||||
<template v-for="rec in scope.row[item.prop]">{{rec.name}} </template>
|
|
||||||
</span>
|
|
||||||
<span v-else-if="item.prop == 'status'">
|
<span v-else-if="item.prop == 'status'">
|
||||||
<el-switch
|
<el-switch
|
||||||
v-model="scope.row.status"
|
v-model="scope.row.status"
|
||||||
|
|||||||
@@ -5,79 +5,110 @@
|
|||||||
</style>
|
</style>
|
||||||
<template>
|
<template>
|
||||||
<div class="terminallog">
|
<div class="terminallog">
|
||||||
<div class="top-tools">
|
<div :class="{'main-list-with-sub': bottomBox.showSubList}" class="main-list">
|
||||||
<div></div>
|
<!-- 顶部工具栏 -->
|
||||||
<div>
|
<div class="main-modal"></div>
|
||||||
<div class="top-tool-search margin-r-5">
|
<div class="top-tools" v-show="bottomBox.mainResizeShow">
|
||||||
<search-input :searchMsg="searchMsg" @search="search"></search-input>
|
<div :class="{'top-tool-main-right-to-left': bottomBox.showSubList}" class="top-tool-main-right">
|
||||||
|
<div class="top-tool-search margin-r-5">
|
||||||
|
<search-input :searchMsg="searchMsg" @search="search"></search-input>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pagination-top pagination-top-hide display-none"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- 自定义table列 -->
|
||||||
<!-- 自定义table列 -->
|
<transition name="el-zoom-in-top">
|
||||||
<transition name="el-zoom-in-top">
|
<element-set
|
||||||
<element-set
|
:custom-table-title.sync="tools.customTableTitle"
|
||||||
id="terminal-log"
|
:original-table-title="tableTitle"
|
||||||
v-if="tools.showCustomTableTitle"
|
@close="tools.showCustomTableTitle = false"
|
||||||
@close="tools.showCustomTableTitle = false"
|
ref="customTableTitle"
|
||||||
:custom-table-title.sync="tools.customTableTitle"
|
v-if="tools.showCustomTableTitle"
|
||||||
:original-table-title="tableTitle"
|
></element-set>
|
||||||
ref="customTableTitle"
|
</transition>
|
||||||
></element-set>
|
<el-table
|
||||||
</transition>
|
:cell-class-name="messageStyle"
|
||||||
<el-table
|
:data="tableData"
|
||||||
id="terminal-log-table"
|
:height="$tableHeight.normal"
|
||||||
class="nz-table"
|
@sort-change="tableDataSort"
|
||||||
:data="tableData"
|
border
|
||||||
border
|
class="nz-table"
|
||||||
ref="terminalLogTable"
|
ref="terminalLogTable"
|
||||||
:height="$tableHeight.normal"
|
style="width: 100%;"
|
||||||
v-loading="tools.loading"
|
v-loading="tools.loading">
|
||||||
:cell-class-name="messageStyle"
|
<el-table-column
|
||||||
style="width: 100%;"
|
:key="`col-${index}`"
|
||||||
@sort-change="tableDataSort">
|
:label="item.label"
|
||||||
<el-table-column
|
:prop="$tableSet.propTitle(item.prop,'temrminallog')"
|
||||||
:resizable="true"
|
:resizable="true"
|
||||||
v-for="(item, index) in tools.customTableTitle"
|
:sort-orders="['ascending', 'descending']"
|
||||||
v-if="item.show"
|
:sortable="$tableSet.sortableShow(item.prop,'temrminallog')"
|
||||||
:key="`col-${index}`"
|
v-for="(item, index) in tools.customTableTitle"
|
||||||
:label="item.label"
|
v-if="item.show"
|
||||||
:sortable="$tableSet.sortableShow(item.prop,'temrminallog')"
|
>
|
||||||
:prop="$tableSet.propTitle(item.prop,'temrminallog')"
|
<template :column="item" slot-scope="scope">
|
||||||
:sort-orders="['ascending', 'descending']"
|
<span v-if="item.prop == 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
|
||||||
>
|
<template v-else-if="item.prop == 'status'">
|
||||||
<template slot-scope="scope" :column="item">
|
<span>{{getStatusText(scope.row.status)}}</span>
|
||||||
<span v-if="item.prop == 'lang'">
|
</template>
|
||||||
{{scope.row[item.prop] == 'en' ? 'English' : ''}}
|
<template v-else-if="item.prop == 'remote'">
|
||||||
{{scope.row[item.prop] == 'zh' ? '中文' : ''}}
|
<span>{{getRemoteText(scope.row)}}</span>
|
||||||
{{scope.row[item.prop] == 'ru' ? 'русский' : ''}}
|
</template>
|
||||||
</span>
|
<template v-else-if="item.prop == 'duration'">
|
||||||
<span v-else-if="item.prop == 'time'">{{utcTimeToTimezoneStr(scope.row[item.prop])}}</span>
|
<span>{{getDuration(scope.row)}}</span>
|
||||||
<template v-else-if="item.prop == 'status'">
|
</template>
|
||||||
<span>{{scope.row.status==='1' ? $t("config.terminallog.success") : $t("config.terminallog.fail")}}</span>
|
<template v-else-if="item.prop == 'option'">
|
||||||
|
<span :id="'terminalLog-replay-'+scope.row.id" :title="$t('config.terminallog.replay')" @click="showReplay(scope.row)" class="content-right-option"><i class="el-icon-video-play"></i></span>
|
||||||
|
|
||||||
|
<span :id="'terminalLog-log-'+scope.row.id" :title="$t('config.terminallog.log')" @click="showRecord(scope.row)" class="content-right-option"><i class="el-icon-tickets"></i></span>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<span v-else>{{scope.row[item.prop]}}</span>
|
||||||
</template>
|
</template>
|
||||||
<span v-else>{{scope.row[item.prop]}}</span>
|
</el-table-column>
|
||||||
</template>
|
<el-table-column width="28">
|
||||||
</el-table-column>
|
<template slot="header" slot-scope="scope">
|
||||||
<el-table-column width="28">
|
|
||||||
<template slot="header" slot-scope="scope">
|
|
||||||
<span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
|
<span @mousedown.stop="!tools.showCustomTableTitle && (tools.showCustomTableTitle = true)" class="nz-table-gear">
|
||||||
<i class="nz-icon nz-icon-gear"></i>
|
<i class="nz-icon nz-icon-gear"></i>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn" id="terminal-log-totop"><i class="nz-icon nz-icon-top"></i></button>
|
<button :class="{'to-top-is-hover': tools.tableHover}" :style="{top: tools.toTopBtnTop}" @click="toTop(scrollbarWrap)" class="to-top" v-show="tools.showTopBtn"><i class="nz-icon nz-icon-top"></i></button>
|
||||||
<Pagination :tableId="tableId" :pageObj="pageObj" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
|
<div class="pagination-bottom" v-show="!bottomBox.showSubList">
|
||||||
|
<Pagination :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize' ref="Pagination"></Pagination>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部上滑框 -->
|
||||||
|
<transition name="el-zoom-in-bottom">
|
||||||
|
<bottom-box :detail="bottomBox.terminalLog" :is-full-screen="bottomBox.isFullScreen" :obj="bottomBox.terminalLog" :sub-resize-show="bottomBox.subResizeShow" :target-tab.sync="bottomBox.targetTab" @closeSubList="bottomBox.showSubList = false" @exitFullScreen="exitFullScreen"
|
||||||
|
@fullScreen="fullScreen" @listResize="listResize" from="terminal" v-if="bottomBox.showSubList" ></bottom-box>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import bus from "../../../libs/bus";
|
import bus from "../../../libs/bus";
|
||||||
|
import {terminalLog} from "../../common/js/constants";
|
||||||
|
import {calcDurationByStringTime} from "../../common/js/tools";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "terminallog",
|
name: "terminallog",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableId: 'terminalLogTable', //需要分页的table的id,用于记录每页数量
|
tableId: 'terminalLogTable', //需要分页的table的id,用于记录每页数量
|
||||||
|
|
||||||
|
/*二级页面相关*/
|
||||||
|
bottomBox: {
|
||||||
|
terminalLog: {},
|
||||||
|
mainResizeShow: true, //dom高度改变时是否展示|隐藏
|
||||||
|
subResizeShow: true,
|
||||||
|
isFullScreen: false, //全屏状态
|
||||||
|
showSubList: false, //是否显示二级列表
|
||||||
|
targetTab: '', //显示二级列表中的哪个页签
|
||||||
|
inTransform: false, //搜索框相关,搜索条件下拉框是否在transform里
|
||||||
|
},
|
||||||
|
|
||||||
/*工具参数*/
|
/*工具参数*/
|
||||||
tools: {
|
tools: {
|
||||||
loading: false, //是否显示table加载动画
|
loading: false, //是否显示table加载动画
|
||||||
@@ -108,18 +139,6 @@
|
|||||||
isAdd: false, //false,true:resize
|
isAdd: false, //false,true:resize
|
||||||
title: ''
|
title: ''
|
||||||
},
|
},
|
||||||
terminallog: {
|
|
||||||
id: '',
|
|
||||||
host: '',
|
|
||||||
status: '1',
|
|
||||||
time: '',
|
|
||||||
protocol: '',
|
|
||||||
port: '',
|
|
||||||
user: '',
|
|
||||||
cmd: '',
|
|
||||||
authType: '',
|
|
||||||
userName: ''
|
|
||||||
},
|
|
||||||
pageObj: {
|
pageObj: {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: this.$CONSTANTS.defaultPageSize,
|
pageSize: this.$CONSTANTS.defaultPageSize,
|
||||||
@@ -132,12 +151,17 @@
|
|||||||
show: true,
|
show: true,
|
||||||
width: 80
|
width: 80
|
||||||
}, {
|
}, {
|
||||||
label: this.$t('config.terminallog.host'),
|
label: "Session ID",
|
||||||
prop: 'host',
|
prop: 'uuid',
|
||||||
show: true,
|
show: true,
|
||||||
}, {
|
}, {
|
||||||
label: this.$t('config.terminallog.port'),
|
label: "Username",
|
||||||
prop: 'port',
|
prop: 'username',
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.terminallog.remote'),
|
||||||
|
prop: 'remote',
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -146,8 +170,13 @@
|
|||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('config.terminallog.user'),
|
label: this.$t('config.terminallog.startTime'),
|
||||||
prop: 'user',
|
prop: 'startTime',
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.terminallog.duration'),
|
||||||
|
prop: 'duration',
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -156,25 +185,17 @@
|
|||||||
show: false
|
show: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: this.$t('config.terminallog.cmd'),
|
label: this.$t('config.terminallog.status'), // killusername鼠标悬停形式
|
||||||
prop: 'cmd',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'UserName',
|
|
||||||
prop: 'userName',
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('config.terminallog.time'),
|
|
||||||
prop: 'time',
|
|
||||||
show: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: this.$t('config.terminallog.status'),
|
|
||||||
prop: 'status',
|
prop: 'status',
|
||||||
show: true,
|
show: true,
|
||||||
width: 100
|
width: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.$t('config.account.option'),
|
||||||
|
prop: 'option',
|
||||||
|
show: true,
|
||||||
|
width: 120,
|
||||||
|
fixed: "right"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tableData: [],
|
tableData: [],
|
||||||
@@ -200,12 +221,6 @@
|
|||||||
type: 'input',
|
type: 'input',
|
||||||
label: 'user',
|
label: 'user',
|
||||||
disabled: false
|
disabled: false
|
||||||
},{
|
|
||||||
id: 13,
|
|
||||||
name: this.$t('config.terminallog.cmd'),
|
|
||||||
type: 'input',
|
|
||||||
label: 'cmd',
|
|
||||||
disabled: false
|
|
||||||
},{
|
},{
|
||||||
id: 14,
|
id: 14,
|
||||||
name: this.$t('config.terminallog.userId'),
|
name: this.$t('config.terminallog.userId'),
|
||||||
@@ -217,19 +232,72 @@
|
|||||||
},
|
},
|
||||||
searchLabel: {}, //搜索参数
|
searchLabel: {}, //搜索参数
|
||||||
scrollbarWrap: null,
|
scrollbarWrap: null,
|
||||||
|
|
||||||
|
testData: {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 2,
|
||||||
|
pages: 1,
|
||||||
|
list: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
uuid: "abcdde",
|
||||||
|
host: "192.168.40.42",
|
||||||
|
port: 22,
|
||||||
|
protocol: "SSH",
|
||||||
|
authType: 1,
|
||||||
|
username: "admin",
|
||||||
|
loginUser: "root",
|
||||||
|
startTime: "2021-02-01 14:20:08",
|
||||||
|
endTime: "2021-02-01 14:30:08",
|
||||||
|
status: 3,
|
||||||
|
killUserName: "leader",
|
||||||
|
}, {
|
||||||
|
id: 2,
|
||||||
|
uuid: "zpppoe",
|
||||||
|
host: "192.168.40.42",
|
||||||
|
port: 22,
|
||||||
|
protocol: "SSH",
|
||||||
|
authType: 1,
|
||||||
|
username: "admin",
|
||||||
|
loginUser: "root",
|
||||||
|
startTime: "2021-02-01 14:41:08",
|
||||||
|
endTime: "2021-02-01 14:51:08",
|
||||||
|
status: 2,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
getStatusText() {
|
||||||
|
return function(status) {
|
||||||
|
return terminalLog.status[status];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getRemoteText() {
|
||||||
|
return function(record) {
|
||||||
|
return `${record.loginUser}@${record.host}:${record.port}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDuration() {
|
||||||
|
return function(record) {
|
||||||
|
if (record.endTime) {
|
||||||
|
return calcDurationByStringTime(record.startTime, record.endTime);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getTableData: function () {
|
getTableData() {
|
||||||
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
|
this.$get('terminal/session', this.searchLabel).then(response => {
|
||||||
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
|
|
||||||
this.tools.loading = true;
|
|
||||||
this.$get('terminal/log', this.searchLabel).then(response => {
|
|
||||||
this.tools.loading = false;
|
this.tools.loading = false;
|
||||||
|
//response = this.testData;
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
for (let i = 0; i < response.data.list.length; i++) {
|
|
||||||
response.data.list[i].status = response.data.list[i].status + "";
|
|
||||||
}
|
|
||||||
this.tableData = response.data.list;
|
this.tableData = response.data.list;
|
||||||
this.pageObj.total = response.data.total;
|
this.pageObj.total = response.data.total;
|
||||||
if (!this.scrollbarWrap) {
|
if (!this.scrollbarWrap) {
|
||||||
@@ -241,11 +309,62 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/*getTableData: function () {
|
||||||
|
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
|
||||||
|
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
|
||||||
|
this.tools.loading = true;
|
||||||
|
this.$get('terminal/log', this.searchLabel).then(response => {
|
||||||
|
this.tools.loading = false;
|
||||||
|
response = this.testData;
|
||||||
|
if (response.code === 200) {
|
||||||
|
this.tableData = response.data.list;
|
||||||
|
this.pageObj.total = response.data.total;
|
||||||
|
if (!this.scrollbarWrap) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.scrollbarWrap = this.$refs.terminalLogTable.bodyWrapper;
|
||||||
|
this.toTopBtnHandler(this.scrollbarWrap);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},*/
|
||||||
|
showReplay(record) {
|
||||||
|
this.bottomBox.targetTab = 'replay';
|
||||||
|
this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record));
|
||||||
|
this.bottomBox.showSubList = true;
|
||||||
|
},
|
||||||
|
showRecord(record) {
|
||||||
|
this.bottomBox.targetTab = 'record';
|
||||||
|
this.bottomBox.terminalLog = JSON.parse(JSON.stringify(record));
|
||||||
|
this.bottomBox.showSubList = true;
|
||||||
|
},
|
||||||
|
// 全屏
|
||||||
|
fullScreen() {
|
||||||
|
let vm = this;
|
||||||
|
this.$bottomBoxWindow.fullScreen(vm);
|
||||||
|
},
|
||||||
|
// 退出全屏
|
||||||
|
exitFullScreen() {
|
||||||
|
let vm = this;
|
||||||
|
this.$bottomBoxWindow.exitFullScreen(vm);
|
||||||
|
},
|
||||||
|
// 鼠标拖动二级列表
|
||||||
|
listResize(e) {
|
||||||
|
let vm = this;
|
||||||
|
this.$bottomBoxWindow.listResize(vm, e);
|
||||||
|
},
|
||||||
messageStyle(e) {
|
messageStyle(e) {
|
||||||
if (e.column.label == this.$t('config.terminallog.status')) {
|
if (e.column.label == this.$t('config.terminallog.status')) {
|
||||||
if (e.row.status == '1') {
|
if (e.row.status == '0') {
|
||||||
return 'success';
|
return 'success';
|
||||||
} else {
|
} else if (e.row.status == '1') {
|
||||||
|
return 'warning';
|
||||||
|
} else if (e.row.status == '2') {
|
||||||
|
return 'suspended';
|
||||||
|
} else if (e.row.status == '3') {
|
||||||
|
return 'danger';
|
||||||
|
} else if (e.row.status == '4') {
|
||||||
return 'danger';
|
return 'danger';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user