Merge branch 'dev-3.3' of https://git.mesalab.cn/nezha/nezha-fronted into dev-3.3
This commit is contained in:
@@ -102,6 +102,7 @@
|
||||
@import './page/dashboard/panel.scss';
|
||||
@import './page/monitor/project/project.scss';
|
||||
@import './page/tool/ping.scss';
|
||||
@import './page/tool/trace.scss';
|
||||
|
||||
@import './common/v-selectpagenew/selectpage.scss';
|
||||
@import './common/paramBpx/paramBox.scss';
|
||||
|
||||
125
nezha-fronted/src/assets/css/components/page/tool/trace.scss
Normal file
125
nezha-fronted/src/assets/css/components/page/tool/trace.scss
Normal file
@@ -0,0 +1,125 @@
|
||||
.trace{
|
||||
.choose{
|
||||
width: 50px !important;
|
||||
height: 36px !important;
|
||||
line-height: 36px !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 2px 0px 0px 2px !important;
|
||||
border-right: none !important;
|
||||
span{
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
i{
|
||||
font-size: 20px !important;
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
width: 50px !important;
|
||||
height: 36px !important;
|
||||
line-height: 36px !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 0px 2px 2px 0px !important;
|
||||
span{
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
i{
|
||||
font-size: 22px !important;
|
||||
color: $--color-primary !important;
|
||||
}
|
||||
i.quadrate{
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
background: $--color-primary;
|
||||
}
|
||||
}
|
||||
|
||||
.nz-table2{
|
||||
height: calc(100% - 64px) !important;
|
||||
.empty{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
.el-steps{
|
||||
width: 620px;
|
||||
}
|
||||
.el-step__icon{
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border: 1px solid $--border-color-light;
|
||||
background-color: $--background-color-empty;
|
||||
}
|
||||
.el-step__line{
|
||||
top: 32px;
|
||||
height: 1px;
|
||||
}
|
||||
span{
|
||||
color: #BEBEBE;
|
||||
}
|
||||
.nz-icon-edit{
|
||||
font-size: 26px;
|
||||
}
|
||||
.el-icon-more{
|
||||
font-size: 22px;
|
||||
}
|
||||
.msg{
|
||||
font-size: 18px;
|
||||
}
|
||||
.txt{
|
||||
color: $--color-text-regular;
|
||||
}
|
||||
}
|
||||
.data-wrap{
|
||||
height: 100%;
|
||||
.data-top{
|
||||
width: 100%;
|
||||
padding-left: 15px;
|
||||
box-sizing: border-box;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
border: 1px solid $--border-color-light;
|
||||
margin-bottom: 14px;
|
||||
span{
|
||||
color: $--color-text-primary;
|
||||
margin-right: 30px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.data-bottom{
|
||||
height: calc(100% - 50px) !important;
|
||||
.details{
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrap{
|
||||
.el-input,.el-input__inner{
|
||||
height: 100%;
|
||||
}
|
||||
.el-input-group__append{
|
||||
color: $--color-text-primary;
|
||||
}
|
||||
}
|
||||
.pop-tit{
|
||||
font-size: 14px;
|
||||
color: $--color-text-primary;
|
||||
line-height: 40px;
|
||||
}
|
||||
.pop-list-wrap{
|
||||
border: 1px solid $--button-light-border-color !important;
|
||||
}
|
||||
.pop-list{
|
||||
max-height: 144px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -142,13 +142,17 @@ export default {
|
||||
this.$emit('showText')
|
||||
},
|
||||
severityDataColor () {
|
||||
this.severityData.map(item => {
|
||||
this.severityColor = item.color
|
||||
this.severityData.forEach(item => {
|
||||
if (this.alertRuleData.severityId === item.id) {
|
||||
this.severityColor = item.color
|
||||
}
|
||||
})
|
||||
},
|
||||
returnColor (obj) {
|
||||
let color = '#23bf9a'
|
||||
console.log(obj, this.severityDataWeight)
|
||||
let color = ''
|
||||
if (!obj) {
|
||||
color = '#23bf9a'
|
||||
return color
|
||||
} else {
|
||||
this.severityDataWeight.forEach(severity => {
|
||||
@@ -168,8 +172,8 @@ export default {
|
||||
this.$get('/alert/rule/' + this.id).then((res) => {
|
||||
if (res.msg === 'success') {
|
||||
this.loading = false
|
||||
this.severityDataColor()
|
||||
this.alertRuleData = res.data
|
||||
this.severityDataColor()
|
||||
this.alertColor = this.returnColor(res.data.alert)
|
||||
const weekDays = this.getWeeksTime()
|
||||
if (this.trendTimer) {
|
||||
|
||||
@@ -368,8 +368,9 @@ export const fromRoute = {
|
||||
ipam: 'ipam',
|
||||
apiKey: 'apiKey',
|
||||
chartTemp: 'chartTemp',
|
||||
backups:'backups',
|
||||
ping: 'ping'
|
||||
backups: 'backups',
|
||||
ping: 'ping',
|
||||
trace: 'trace'
|
||||
}
|
||||
|
||||
export const chartdatasource = [
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<el-table
|
||||
id="traceTable"
|
||||
ref="dataTable"
|
||||
:height="height"
|
||||
:data="tableData"
|
||||
border
|
||||
@header-dragend="dragend"
|
||||
>
|
||||
<el-table-column type="expand">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="details">
|
||||
<pre>{{row.raw}}</pre>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
v-for="(item, index) in customTableTitle"
|
||||
:key="`col-${index}`"
|
||||
:label="item.label"
|
||||
:min-width="`${item.minWidth}`"
|
||||
:prop="item.prop"
|
||||
:resizable="true"
|
||||
:width="`${item.width}`"
|
||||
class="data-column"
|
||||
>
|
||||
<template slot="header">
|
||||
<span class="data-column__span">{{item.label}}</span>
|
||||
<div class="col-resize-area"></div>
|
||||
</template>
|
||||
<template slot-scope="scope" :column="item">
|
||||
<template v-if="item.prop === 'state'">
|
||||
<div class="active-icon green-bg inline-block" v-if="scope.row.state"></div>
|
||||
<div class="active-icon gray-bg inline-block" v-else></div>
|
||||
</template>
|
||||
<span v-else-if="item.prop === 'dc'&&scope.row[item.prop]!==undefined">{{scope.row[item.prop].name}}</span>
|
||||
<span v-else-if="item.prop === 'rate'&&scope.row[item.prop]!==undefined">{{scope.row[item.prop]}}%</span>
|
||||
<span v-else-if="(item.prop === 'avg'||item.prop === 'min'||item.prop === 'max')&&scope.row[item.prop]!==undefined">{{scope.row[item.prop]}}ms</span>
|
||||
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template slot="empty">
|
||||
<div v-if="!loading" class="table-no-data">
|
||||
<svg class="icon" aria-hidden="true">
|
||||
<use xlink:href="#nz-icon-no-data-list"></use>
|
||||
</svg>
|
||||
<div class="table-no-data__title">No results found</div>
|
||||
</div>
|
||||
<div v-else> </div>
|
||||
</template>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import table from '@/components/common/mixin/table'
|
||||
export default {
|
||||
name: 'traceTable',
|
||||
mixins: [table],
|
||||
props: {
|
||||
loading: Boolean
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tableTitle: [ // 原table列
|
||||
{
|
||||
label: this.$t('overall.dc'),
|
||||
prop: 'dc'
|
||||
}, {
|
||||
label: this.$t('ping.sourceIp'),
|
||||
prop: 'source'
|
||||
}, {
|
||||
label: this.$t('ping.targetIp'),
|
||||
prop: 'ip'
|
||||
}, {
|
||||
label: this.$t('overall.state'),
|
||||
prop: 'state'
|
||||
}, {
|
||||
label: this.$t('ping.packetLossRate'),
|
||||
prop: 'rate'
|
||||
}, {
|
||||
label: this.$t('ping.rttAverage'),
|
||||
prop: 'avg'
|
||||
}, {
|
||||
label: this.$t('ping.rttMinimum'),
|
||||
prop: 'min'
|
||||
}, {
|
||||
label: this.$t('ping.rttMaximum'),
|
||||
prop: 'max'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -96,7 +96,7 @@
|
||||
<script>
|
||||
import nzDataList from '@/components/common/table/nzDataList'
|
||||
import dataListMixin from '@/components/common/mixin/dataList'
|
||||
import pingTable from '@/components/common/table/settings/pingTable'
|
||||
import pingTable from '@/components/common/table/tool/pingTable'
|
||||
import { positiveInteger } from '../../common/js/validate'
|
||||
export default {
|
||||
mixins: [dataListMixin],
|
||||
@@ -200,6 +200,7 @@ export default {
|
||||
},
|
||||
// 请求任务id
|
||||
async getId () {
|
||||
this.loading = true
|
||||
const params = {
|
||||
ip: this.ip,
|
||||
dcIds: this.checked.join(','),
|
||||
@@ -221,6 +222,10 @@ export default {
|
||||
this.clearTask()
|
||||
}
|
||||
}, 300)
|
||||
// 如果没有数据,loading取消
|
||||
if (!response.data.task.total) {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 请求表格数据
|
||||
@@ -232,6 +237,10 @@ export default {
|
||||
this.total = response.data.task.total
|
||||
this.process = response.data.task.process
|
||||
this.tableData.push(...response.data.list)
|
||||
// 收到数据,loading取消
|
||||
if (this.tableData.length) {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -248,6 +257,7 @@ export default {
|
||||
await this.$get('/tool/ping/cancel/' + this.tid)
|
||||
this.isStart = false
|
||||
this.flag = true
|
||||
this.loading = false
|
||||
},
|
||||
// 空函数 防止mixins中的函数执行
|
||||
getTableData () { }
|
||||
|
||||
287
nezha-fronted/src/components/page/tool/trace.vue
Normal file
287
nezha-fronted/src/components/page/tool/trace.vue
Normal file
@@ -0,0 +1,287 @@
|
||||
<template>
|
||||
<nz-data-list
|
||||
ref="dataList"
|
||||
:layout="[]"
|
||||
:from="fromRoute.trace"
|
||||
>
|
||||
<template v-slot:top-tool-left>
|
||||
<el-input v-model="ip" size='medium' style="width:250px" :placeholder="$t('overall.placeHolder')+' IP/Hostname'"></el-input>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
width="220"
|
||||
trigger="manual"
|
||||
v-model="visible"
|
||||
v-clickoutside="close"
|
||||
popper-class="no-style-class"
|
||||
>
|
||||
<el-form size="small" ref="ruleForm" label-position="top" :model="ruleForm" :rules="formRules">
|
||||
<el-form-item style="margin-bottom:0px">
|
||||
<p class="pop-tit">{{$t('ping.dcs')}}</p>
|
||||
<ul class="pop-list-wrap">
|
||||
<li class="el-dropdown-menu__item">
|
||||
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="checkAllChange">{{$t('overall.all')}}</el-checkbox>
|
||||
</li>
|
||||
<ul class="pop-list">
|
||||
<el-checkbox-group v-model="checked" @change="checkedChange">
|
||||
<li class="el-dropdown-menu__item" v-for="item in dataCenter" :key="item.id">
|
||||
<el-checkbox :label="item.id">{{item.name}}</el-checkbox>
|
||||
</li>
|
||||
</el-checkbox-group>
|
||||
</ul>
|
||||
</ul>
|
||||
</el-form-item>
|
||||
<el-form-item prop="maxHops" style="margin-bottom:0px">
|
||||
<div class="pop-tit">{{$t('trace.maxHops')}}</div>
|
||||
<div class="wrap" style="height:32px">
|
||||
<el-input v-model.number="ruleForm.maxHops" placeholder=""></el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item prop="timeout" style="margin-bottom:10px">
|
||||
<div class="pop-tit">{{$t('ping.timeout')}}</div>
|
||||
<div class="wrap" style="height:32px">
|
||||
<el-input v-model.number="ruleForm.timeout" placeholder="" >
|
||||
<template slot="append">{{$t('config.system.basic.second')}}</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-button slot="reference" class="top-tool-btn margin-l-10 choose" @click="triggerVisible">
|
||||
<i class="el-icon-more"></i>
|
||||
</el-button>
|
||||
</el-popover>
|
||||
|
||||
<el-button class="top-tool-btn btn" v-if="!isStart" @click="startTask">
|
||||
<i class="el-icon-caret-right"></i>
|
||||
</el-button>
|
||||
<el-button class="top-tool-btn btn" v-else @click="clearTask">
|
||||
<i class="quadrate"></i>
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template v-slot:default>
|
||||
<!-- 初始展示的内容 ip输入框聚焦后消失 -->
|
||||
<div class="empty" v-if="tid===undefined">
|
||||
<el-steps align-center>
|
||||
<el-step>
|
||||
<span class="nz-icon nz-icon-edit" slot="icon"></span>
|
||||
<p class="txt" slot="title">{{$t('overall.placeHolder')}} IP/Hostname</p>
|
||||
</el-step>
|
||||
<el-step>
|
||||
<span class="el-icon-more" slot="icon"></span>
|
||||
<p class="txt" slot="title">{{$t('ping.filter')}}</p>
|
||||
</el-step>
|
||||
<el-step>
|
||||
<span class="msg" slot="icon">Trace</span>
|
||||
<p class="txt" slot="title">Trace {{$t('config.terminallog.cmd.cmd')}}</p>
|
||||
</el-step>
|
||||
</el-steps>
|
||||
</div>
|
||||
<!-- 存在任务id时展示表格 -->
|
||||
<div class="data-wrap" v-show="tid!==undefined">
|
||||
<div class="data-top">
|
||||
<span>IP {{$t('ping.total')}}:{{total}}</span>
|
||||
<span>{{$t('ping.done')}}:{{done}}</span>
|
||||
<span>{{$t('ping.progress')}}:{{process}}%</span>
|
||||
</div>
|
||||
<div class="data-bottom">
|
||||
<trace-table
|
||||
ref="dataTable"
|
||||
:loading="loading"
|
||||
v-my-loading="loading"
|
||||
:custom-table-title="tools.customTableTitle"
|
||||
:height="mainTableHeight"
|
||||
:table-data="tableData"
|
||||
>
|
||||
</trace-table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</nz-data-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import nzDataList from '@/components/common/table/nzDataList'
|
||||
import dataListMixin from '@/components/common/mixin/dataList'
|
||||
import traceTable from '@/components/common/table/tool/traceTable'
|
||||
import { positiveInteger } from '../../common/js/validate'
|
||||
export default {
|
||||
mixins: [dataListMixin],
|
||||
components: {
|
||||
nzDataList,
|
||||
traceTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
// 防止用户重复点击
|
||||
flag: true,
|
||||
loading: false,
|
||||
// 弹出框是否显示
|
||||
visible: false,
|
||||
ip: '',
|
||||
// 是否全选
|
||||
checkAll: true,
|
||||
isIndeterminate: false,
|
||||
// 数据中心
|
||||
dataCenter: [],
|
||||
// 复选框选中的值
|
||||
checked: [],
|
||||
// 是否正在请求数据
|
||||
isStart: false,
|
||||
// 定时器id
|
||||
timer: null,
|
||||
// 任务id
|
||||
tid: undefined,
|
||||
// 表格总数据
|
||||
total: 0,
|
||||
// 已完成
|
||||
done: 0,
|
||||
// 进度
|
||||
process: 0,
|
||||
// 表格数据
|
||||
tableData: [],
|
||||
ruleForm: {
|
||||
// 最大跃点数
|
||||
maxHops: '',
|
||||
// 超时时间
|
||||
timeout: ''
|
||||
},
|
||||
formRules: {
|
||||
timeout: [{ validator: positiveInteger, trigger: 'blur' }],
|
||||
maxHops: [{ validator: positiveInteger, trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getDataCenter()
|
||||
},
|
||||
methods: {
|
||||
close () {
|
||||
this.$refs.ruleForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.visible = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 切换弹框显示隐藏
|
||||
triggerVisible () {
|
||||
if (!this.visible) {
|
||||
this.visible = true
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
// 点击全选
|
||||
checkAllChange (value) {
|
||||
const allId = this.dataCenter.map(item => {
|
||||
return item.id
|
||||
})
|
||||
this.checked = value ? allId : []
|
||||
this.isIndeterminate = false
|
||||
},
|
||||
// 点击单个选中
|
||||
checkedChange (value) {
|
||||
const checkedCount = value.length
|
||||
this.checkAll = checkedCount === this.dataCenter.length
|
||||
this.isIndeterminate = checkedCount > 0 && checkedCount < this.dataCenter.length
|
||||
},
|
||||
// 开始任务
|
||||
startTask () {
|
||||
const ipv4 = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\:\d{0,5})?$/
|
||||
const ipv6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
|
||||
if (!ipv4.test(this.ip) && !ipv6.test(this.ip)) {
|
||||
return this.$message.error(this.$t('validate.host'))
|
||||
}
|
||||
if (!this.flag) {
|
||||
return false
|
||||
}
|
||||
this.flag = false
|
||||
this.getId()
|
||||
},
|
||||
// 请求dataCenter
|
||||
getDataCenter () {
|
||||
this.$get('/dc?pageSize=-1').then(response => {
|
||||
this.dataCenter = response.data.list
|
||||
// 默认全选
|
||||
this.checked = this.dataCenter.map(item => {
|
||||
return item.id
|
||||
})
|
||||
})
|
||||
},
|
||||
// 请求任务id
|
||||
async getId () {
|
||||
this.loading = true
|
||||
const params = {
|
||||
ip: this.ip,
|
||||
dcIds: this.checked.join(','),
|
||||
maxHops: this.ruleForm.maxHops,
|
||||
timeout: this.ruleForm.timeout
|
||||
}
|
||||
this.$get('/tool/traceroute', params).then(response => {
|
||||
// 清空上一次任务的数据
|
||||
this.done = 0
|
||||
this.total = 0
|
||||
this.process = 0
|
||||
this.tableData = []
|
||||
this.tid = response.data.tid
|
||||
this.isStart = true // 标记正在请求数据中
|
||||
this.flag = true
|
||||
this.timer = setInterval(() => {
|
||||
if (parseInt(this.process) < 100) {
|
||||
this.getData()
|
||||
} else {
|
||||
this.clearTask()
|
||||
}
|
||||
}, 300)
|
||||
// 如果没有数据,loading取消
|
||||
if (!response.data.task.total) {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 请求表格数据
|
||||
getData () {
|
||||
const currentId = this.tid
|
||||
this.$get('/tool/traceroute/result/' + this.tid).then(response => {
|
||||
if (currentId === this.tid && parseInt(this.process) < 100) {
|
||||
this.done = response.data.task.done
|
||||
this.total = response.data.task.total
|
||||
this.process = response.data.task.process
|
||||
this.tableData.push(...response.data.list)
|
||||
// 收到数据,loading取消
|
||||
if (this.tableData.length) {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
// 清除任务
|
||||
async clearTask () {
|
||||
if (!this.flag) {
|
||||
return false
|
||||
}
|
||||
this.flag = false
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
await this.$get('/tool/traceroute/cancel/' + this.tid)
|
||||
this.isStart = false
|
||||
this.flag = true
|
||||
this.loading = false
|
||||
},
|
||||
// 空函数 防止mixins中的函数执行
|
||||
getTableData () { }
|
||||
},
|
||||
// 离开页面的时候触发
|
||||
async beforeRouteLeave (to, from, next) {
|
||||
if (this.tid) {
|
||||
await this.clearTask()
|
||||
}
|
||||
next()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
</style>
|
||||
@@ -201,6 +201,10 @@ export default new Router({
|
||||
{
|
||||
path: '/ping',
|
||||
component: resolve => require(['../components/page/tool/ping.vue'], resolve)
|
||||
},
|
||||
{
|
||||
path: '/trace',
|
||||
component: resolve => require(['../components/page/tool/trace.vue'], resolve)
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user