Compare commits
75 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83a9b3fa57 | ||
|
|
cc3157c578 | ||
|
|
d7b78da80f | ||
|
|
5f68b966ba | ||
|
|
d175d834d1 | ||
|
|
bb188483a7 | ||
|
|
32a2359e0d | ||
|
|
c425d87b00 | ||
|
|
34e16fc890 | ||
|
|
c0487a708a | ||
|
|
68596189b4 | ||
|
|
29d89ee6e4 | ||
|
|
14c53bd5ad | ||
|
|
f39c4d8fc4 | ||
|
|
6827d4f031 | ||
|
|
1cb4c43b9e | ||
|
|
e1bf796f0c | ||
|
|
94c15e0933 | ||
|
|
043b785547 | ||
|
|
b0b8de2712 | ||
|
|
93933502e4 | ||
|
|
e5b636905f | ||
|
|
078ec2f69f | ||
|
|
7c77c3c79a | ||
|
|
0d89b3c23b | ||
|
|
a6ea1fa4e6 | ||
|
|
70c38fe2de | ||
|
|
12b7290ecd | ||
|
|
60cbebe1cc | ||
|
|
096517e34f | ||
|
|
2020423c0a | ||
|
|
da03a3658c | ||
|
|
45de9c8107 | ||
|
|
14f661b78f | ||
|
|
b5718a039f | ||
|
|
6845bb4ea4 | ||
|
|
5f448c0ccb | ||
|
|
d568c748db | ||
|
|
07e137d5e0 | ||
|
|
3093c3e3a8 | ||
|
|
db105804b3 | ||
|
|
49eb4d42ce | ||
|
|
e019f8a02e | ||
|
|
e7cf758ffd | ||
|
|
64610304c1 | ||
|
|
2da2172f03 | ||
|
|
c2c3898d5b | ||
|
|
04e4371ac1 | ||
|
|
06c86b8172 | ||
|
|
ced28fd3e7 | ||
|
|
943d64918d | ||
|
|
de5040d9f4 | ||
|
|
64e41c3170 | ||
|
|
8bee5301bc | ||
|
|
b75e975421 | ||
|
|
21c3ead654 | ||
|
|
74cbcf0d46 | ||
|
|
2e27cd5add | ||
|
|
e2b03c5d7f | ||
|
|
a87b096c1c | ||
|
|
2a6958f61b | ||
|
|
ae8918f7f7 | ||
|
|
f9e6250e2a | ||
|
|
bb81059529 | ||
|
|
c38b5ef000 | ||
|
|
75dd68f403 | ||
|
|
e39e24258b | ||
|
|
5767fe896b | ||
|
|
53fc6475e2 | ||
|
|
59ae26e078 | ||
|
|
15cfd48770 | ||
|
|
111f731712 | ||
|
|
c5a78887cb | ||
|
|
add13f463d | ||
|
|
c1dd39fb66 |
11
src/App.vue
11
src/App.vue
@@ -5,6 +5,17 @@
|
||||
</template>
|
||||
<script>
|
||||
import { storageKey } from '@/utils/constants'
|
||||
const dayjs = require('dayjs')
|
||||
const utc = require('dayjs/plugin/utc')
|
||||
const timezone = require('dayjs/plugin/timezone')
|
||||
const advancedFormat = require('dayjs/plugin/advancedFormat')
|
||||
const weekday = require('dayjs/plugin/weekday')
|
||||
dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
dayjs.extend(advancedFormat)
|
||||
dayjs.extend(weekday)
|
||||
window.$dayJs = dayjs
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
setup () {
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
margin: 0 5px;
|
||||
color: #353636;
|
||||
.cn-icon-Data {
|
||||
color: #575757;
|
||||
}
|
||||
@@ -122,7 +123,8 @@
|
||||
}
|
||||
|
||||
.date-range-history {
|
||||
height: 116px;
|
||||
height: 140px;
|
||||
line-height: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
.date-range-history-item {
|
||||
|
||||
@@ -1,46 +1,58 @@
|
||||
.network-overview-apps {
|
||||
height: 100%;
|
||||
|
||||
.line-select-metric {
|
||||
.network-overview-apps-header {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
&>span {
|
||||
font-size: 12px;
|
||||
color: #575757;
|
||||
font-weight: 400;
|
||||
margin-right: 3px;
|
||||
.network-overview-apps-title {
|
||||
font-size: 14px;
|
||||
color: #353636;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.line-select__operation {
|
||||
height: 24px;
|
||||
margin-left: 3px;
|
||||
box-shadow: none;
|
||||
border-radius: 2px;
|
||||
.el-input__inner {
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
padding-left: 4px;
|
||||
line-height: 24px;
|
||||
|
||||
.line-select-metric {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
&>span {
|
||||
font-size: 12px;
|
||||
color: #2C72C6;
|
||||
color: #575757;
|
||||
font-weight: 400;
|
||||
margin-right: 3px;
|
||||
}
|
||||
.el-input__suffix {
|
||||
display: flex;
|
||||
.el-input__suffix-inner {
|
||||
.line-select__operation {
|
||||
height: 24px;
|
||||
margin-left: 3px;
|
||||
box-shadow: none;
|
||||
border-radius: 2px;
|
||||
.el-input__inner {
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
padding-left: 4px;
|
||||
line-height: 24px;
|
||||
.el-select__caret {
|
||||
font-size: 12px;
|
||||
color: #2C72C6;
|
||||
font-weight: 400;
|
||||
}
|
||||
.el-input__suffix {
|
||||
display: flex;
|
||||
.el-input__suffix-inner {
|
||||
line-height: 24px;
|
||||
width: 16px;
|
||||
color: #575757;
|
||||
.el-select__caret {
|
||||
line-height: 24px;
|
||||
width: 16px;
|
||||
color: #575757;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.app-cards {
|
||||
display: grid;
|
||||
grid-template-rows: repeat(auto-fill, 100px);
|
||||
@@ -48,7 +60,6 @@
|
||||
grid-gap: 20px;
|
||||
width: 100%;
|
||||
padding-top: 10px;
|
||||
height: calc(100% - 24px);
|
||||
|
||||
.app-card {
|
||||
border: 1px solid #E2E5EC;
|
||||
|
||||
@@ -115,6 +115,29 @@
|
||||
.el-table thead {
|
||||
color: $grey;
|
||||
}
|
||||
.score-cell {
|
||||
display: flex !important;
|
||||
justify-content: center;
|
||||
.data-score {
|
||||
border-radius: 10px;
|
||||
font-size: 12px;
|
||||
color: #FFFFFF;
|
||||
font-weight: 500;
|
||||
height: 20px;
|
||||
width: 34px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.data-score-red {
|
||||
background: #E26154;
|
||||
}
|
||||
.data-score-yellow {
|
||||
background: #E5A219;
|
||||
}
|
||||
.data-score-green {
|
||||
background: #749F4D;
|
||||
}
|
||||
}
|
||||
}
|
||||
.el-tabs__header {
|
||||
margin-bottom: 10px;
|
||||
|
||||
@@ -53,6 +53,9 @@
|
||||
border-radius: 4px;
|
||||
height: calc(100% - 32px);
|
||||
width: 100%;
|
||||
.panel-chart__no-data {
|
||||
height: calc(100% - 32px);
|
||||
}
|
||||
.chart-drawing {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
background: #749F4D;
|
||||
}
|
||||
height:24px;
|
||||
font-family: NotoSansHans-Medium;
|
||||
font-size: 12px;
|
||||
color: #353636;
|
||||
font-weight: 500;
|
||||
@@ -46,8 +45,30 @@
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.panel__time {
|
||||
.panel__tools {
|
||||
display: flex;
|
||||
|
||||
&>.el-select {
|
||||
width: 162px;
|
||||
margin-right: 10px;
|
||||
|
||||
.select-prefix {
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
padding: 0 6px 0 3px;
|
||||
}
|
||||
.el-input__inner {
|
||||
font-size: 14px;
|
||||
color: #353636;
|
||||
background-color: #F5F8FA;
|
||||
}
|
||||
.common-select {
|
||||
top: 32px !important;
|
||||
}
|
||||
}
|
||||
.panel__time {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
.chart-list {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-ele-click-outside="changeDropdown" style="position: relative" class="date-range-box">
|
||||
<div v-ele-click-outside="changeDropdown" style="position: relative;z-index: 99" class="date-range-box">
|
||||
<div @click="showDropdown" class="date-range-text">
|
||||
<div class="calendar-popover-text"><i class="cn-icon cn-icon-Data"></i></div>
|
||||
<div class="calendar-popover-text" style="display: flex" v-if="isCustom">
|
||||
@@ -10,25 +10,22 @@
|
||||
<div class="calendar-popover-text" v-else>
|
||||
{{ showDetail }}
|
||||
</div>
|
||||
<div class="calendar-popover-text calendar-popover__small"><i class="cn-icon cn-icon-dropdown"
|
||||
:class="dropdownFlag ? 'cn-icon-up' : ''"></i></div>
|
||||
<div class="calendar-popover-text calendar-popover__small">
|
||||
<i class="cn-icon cn-icon-dropdown" :class="dropdownFlag ? 'cn-icon-up' : ''"></i>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<div v-if="dropdownFlag" class="date-range-panel">
|
||||
<el-row class="date-range-panel-top" style="position: relative">
|
||||
<el-col :span="16" class="date-range-panel-content date-range-panel-content-left">
|
||||
<div class="date-range-title" style="padding-left: 0">Absolute time range</div>
|
||||
<MyDatePicker
|
||||
:clearable='false'
|
||||
:editable='false'
|
||||
v-model="timeArr"
|
||||
<el-date-picker
|
||||
v-model="newDateValue"
|
||||
ref="newDatePicker"
|
||||
class="date_style"
|
||||
style="position: absolute;top: -53px;left: -536px;"
|
||||
:clearable="false"
|
||||
type="datetimerange"
|
||||
ref="myDatePicker"
|
||||
:popper-class="'myDatePicker'"
|
||||
class="panel-time-picker-hidden"
|
||||
:size="'small'"
|
||||
placement="left-start"
|
||||
style="position: absolute"
|
||||
@change="timeArrChange"
|
||||
/>
|
||||
<div class="content-title">From</div>
|
||||
@@ -39,9 +36,7 @@
|
||||
<div @click="myDatePickerShow" tabindex="2" class="content-input">
|
||||
{{ dateFormatByAppearance(getMillisecond(myEndTime)) }}
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="timeRange" type="primary" size="mini">Apply time range</el-button>
|
||||
</div>
|
||||
|
||||
<div class="date-range-title" style="padding-left: 0">Recently used absolute ranges</div>
|
||||
<div class="date-range-history">
|
||||
<div v-for="(item, index) in rangeHistoryArr" :key="index" class="date-range-history-item"
|
||||
@@ -52,23 +47,26 @@
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="8" class="date-range-panel-content date-range-panel-content-right"
|
||||
style="border-left: 1px solid rgba(0,0,0,0.09);">
|
||||
<el-col
|
||||
:span="8"
|
||||
class="date-range-panel-content date-range-panel-content-right"
|
||||
style="border-left: 1px solid rgba(0,0,0,0.09);">
|
||||
<div class="date-range-title">Relatime time ranges</div>
|
||||
<ul class="date-range-item">
|
||||
<li v-for="item in dateRangeArr" @click="quickChange(item.value)"
|
||||
:class="(item.value==dateRangeValue.value || item.value==dateRangeValue)?'active':''"
|
||||
<li v-for="item in dateRangeArr"
|
||||
@click="quickChange(item.value)"
|
||||
:class="(item.value===dateRangeValue.value || item.value===dateRangeValue)?'active':''"
|
||||
:key="item.value">
|
||||
<span style="position: relative">
|
||||
{{ item.name }}
|
||||
<i v-if="(item.value==dateRangeValue.value || item.value==dateRangeValue)"
|
||||
<i v-if="(item.value===dateRangeValue.value || item.value===dateRangeValue)"
|
||||
class="cn-icon cn-icon-check"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="date-range-panel-bottom" style="">
|
||||
<el-row class="date-range-panel-bottom">
|
||||
<el-col :span="12">{{ address }}</el-col>
|
||||
<el-col :span="12" class="utc-str">{{ utcStr }}</el-col>
|
||||
</el-row>
|
||||
@@ -79,9 +77,9 @@
|
||||
|
||||
<script>
|
||||
import { ref, computed } from 'vue'
|
||||
import MyDatePicker from '../MyDatePicker'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import { getMillisecond } from '@/utils/date-util'
|
||||
import { getMillisecond, timestampToList } from '@/utils/date-util'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DateTimeRange',
|
||||
@@ -97,68 +95,39 @@ export default {
|
||||
dateRange: {
|
||||
type: Number
|
||||
}
|
||||
/* useRefresh: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
useDateRange: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
} */
|
||||
},
|
||||
emits: ['change'],
|
||||
components: {
|
||||
MyDatePicker
|
||||
},
|
||||
setup (props, ctx) {
|
||||
// data
|
||||
const store = useStore()
|
||||
const myStartTime = ref(props.startTime)
|
||||
const myEndTime = ref(props.endTime)
|
||||
const timeArr = ref([myStartTime.value, myEndTime.value])
|
||||
// 时间选择器绑定的值
|
||||
const newDateValue = ref([
|
||||
new Date(...timestampToList(myStartTime.value)),
|
||||
new Date(...timestampToList(myEndTime.value))
|
||||
])
|
||||
// 时区地址
|
||||
const address = localStorage.getItem(storageKey.sysTimezone)
|
||||
// 当前所在时区
|
||||
const utc = localStorage.getItem(storageKey.timezoneOffset)
|
||||
// 历史选择时间
|
||||
const rangeHistory = ref(localStorage.getItem(storageKey.dataRangeHistory) ? JSON.parse(localStorage.getItem(storageKey.dataRangeHistory)) : [])
|
||||
const dateRangeValue = props.dateRange ? ref(props.dateRange) : ref(60)
|
||||
const isCustom = ref(dateRangeValue.value === -1)
|
||||
const dateRangeArr = [
|
||||
{
|
||||
value: 5,
|
||||
name: 'last 5 Min'
|
||||
},
|
||||
{
|
||||
value: 15,
|
||||
name: 'last 15 Min'
|
||||
},
|
||||
{
|
||||
value: 30,
|
||||
name: 'last 30 Min'
|
||||
},
|
||||
{
|
||||
value: 60,
|
||||
name: 'last 1 hour'
|
||||
},
|
||||
{
|
||||
value: 180,
|
||||
name: 'last 3 hour'
|
||||
},
|
||||
{
|
||||
value: 360,
|
||||
name: 'last 6 hour'
|
||||
},
|
||||
{
|
||||
value: 720,
|
||||
name: 'last 12 hour'
|
||||
},
|
||||
{
|
||||
value: 1440,
|
||||
name: 'last 1 days'
|
||||
},
|
||||
{
|
||||
value: 2880,
|
||||
name: 'last 2 days'
|
||||
}
|
||||
{ value: 5, name: 'last 5 Min' },
|
||||
{ value: 15, name: 'last 15 Min' },
|
||||
{ value: 30, name: 'last 30 Min' },
|
||||
{ value: 60, name: 'last 1 hour' },
|
||||
{ value: 180, name: 'last 3 hour' },
|
||||
{ value: 360, name: 'last 6 hour' },
|
||||
{ value: 720, name: 'last 12 hour' },
|
||||
{ value: 1440, name: 'last 1 days' },
|
||||
{ value: 2880, name: 'last 2 days' }
|
||||
]
|
||||
const dropdownFlag = ref(false)
|
||||
|
||||
// computed
|
||||
const utcStr = computed(() => {
|
||||
let str = 'UTC '
|
||||
@@ -183,20 +152,25 @@ export default {
|
||||
}
|
||||
return str
|
||||
})
|
||||
const rangeHistoryArr = computed(() => {
|
||||
return rangeHistory.value.slice(0, 4)
|
||||
})
|
||||
const rangeHistoryArr = rangeHistory
|
||||
|
||||
// refs
|
||||
const myDatePicker = ref(null)
|
||||
const newDatePicker = ref(null)
|
||||
|
||||
// methods
|
||||
/**
|
||||
* 打开/关闭时间面板
|
||||
*/
|
||||
const showDropdown = () => {
|
||||
dropdownFlag.value = !dropdownFlag.value
|
||||
if (dropdownFlag.value) {
|
||||
myStartTime.value = props.startTime
|
||||
myEndTime.value = props.endTime
|
||||
timeArr.value = [getMillisecond(myStartTime.value), getMillisecond(myEndTime.value)]
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 点击空白处隐藏时间面板
|
||||
*/
|
||||
const changeDropdown = () => {
|
||||
if (dropdownFlag.value) {
|
||||
dropdownFlag.value = false
|
||||
@@ -205,19 +179,36 @@ export default {
|
||||
dropdownFlag.value = false
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 打开时间选择器,从时间面板的“开始时间”、“结束时间”调用
|
||||
*/
|
||||
const myDatePickerShow = () => {
|
||||
myDatePicker.value.focus()
|
||||
myDatePicker.value.pickerVisible = true
|
||||
newDateValue.value = [
|
||||
new Date(...timestampToList(myStartTime.value)),
|
||||
new Date(...timestampToList(myEndTime.value))
|
||||
]
|
||||
newDatePicker.value.focus()
|
||||
|
||||
// todo 此处为弹窗打开的方向标识,控制css的position修改其left与top属性未生效,只好隐藏,后续有更好的处理办法再修改
|
||||
const dom = document.getElementsByClassName('el-picker__popper el-popper is-light is-pure')
|
||||
const dom1 = dom[0].getElementsByClassName('el-popper__arrow')
|
||||
dom1[0].style.display = 'none'
|
||||
}
|
||||
/**
|
||||
* 时间选择器,选择时间,点击OK后的回调
|
||||
* @param val,开始/结束时间数组
|
||||
*/
|
||||
const timeArrChange = (val) => {
|
||||
myStartTime.value = getMillisecond(val[0])
|
||||
myEndTime.value = getMillisecond(val[1])
|
||||
}
|
||||
const timeRange = () => {
|
||||
isCustom.value = true
|
||||
dateRangeValue.value = -1
|
||||
returnValue()
|
||||
}
|
||||
/**
|
||||
* 历史时间列表中点击一项,对时间进行赋值
|
||||
* @param item
|
||||
*/
|
||||
const historyChange = (item) => {
|
||||
myStartTime.value = item.start
|
||||
myEndTime.value = item.end
|
||||
@@ -232,39 +223,63 @@ export default {
|
||||
myStartTime.value = myEndTime.value - value * 60 * 1000
|
||||
returnValue()
|
||||
}
|
||||
/**
|
||||
* 重置时间,将时间存入缓存,并触发方法请求接口刷新界面
|
||||
*/
|
||||
const returnValue = () => {
|
||||
cancelHttp()
|
||||
rangeHistory.value.unshift({
|
||||
start: myStartTime.value,
|
||||
end: myEndTime.value
|
||||
})
|
||||
if (rangeHistory.value.length > 4) {
|
||||
rangeHistory.value.splice(4, rangeHistory.value.length - 1)
|
||||
}
|
||||
localStorage.setItem(storageKey.dataRangeHistory, JSON.stringify(rangeHistory.value))
|
||||
ctx.emit('change', myStartTime.value, myEndTime.value, dateRangeValue)
|
||||
dropdownFlag.value = false
|
||||
}
|
||||
/**
|
||||
* 终止http请求
|
||||
*/
|
||||
const cancelHttp = () => {
|
||||
const cancelList = store.state.panel.httpCancel
|
||||
if (cancelList.length > 0) {
|
||||
cancelList.forEach((cancel, index) => {
|
||||
cancel()
|
||||
delete cancelList[index]
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
myStartTime,
|
||||
myEndTime,
|
||||
getMillisecond,
|
||||
dropdownFlag,
|
||||
utcStr,
|
||||
address,
|
||||
dateRangeArr,
|
||||
dateRangeValue,
|
||||
isCustom,
|
||||
timeArr,
|
||||
myDatePicker,
|
||||
newDateValue,
|
||||
newDatePicker,
|
||||
showDetail,
|
||||
rangeHistory,
|
||||
rangeHistoryArr,
|
||||
getMillisecond,
|
||||
myDatePickerShow,
|
||||
showDropdown,
|
||||
changeDropdown,
|
||||
timeArrChange,
|
||||
returnValue,
|
||||
quickChange,
|
||||
timeRange,
|
||||
historyChange
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/.el-input__inner {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
<transition name="el-zoom-in-top">
|
||||
<div v-if="dropdownShow" class="refresh-list">
|
||||
<div v-for="(item, index) in refreshArr" :key="index" @click="setRefresh(item)" class="refresh-list-item" :class="item.value==interval ? 'active' : ''">
|
||||
{{item.label}}
|
||||
<i v-if="item.value==interval" class="cn-icon cn-icon-check"></i>
|
||||
{{ item.label }}
|
||||
<i v-if="item.value===interval" class="cn-icon cn-icon-check"></i>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
@@ -103,7 +103,16 @@ export default {
|
||||
this.interLabel = val.value == -1 ? '' : val.label
|
||||
this.dropdownShow = false
|
||||
const now = window.$dayJs.tz().valueOf()
|
||||
if (val && val.value != -1) {
|
||||
if (val && val.value !== -1) {
|
||||
// 切换轮询请求时间频率时,发现有未结束的请求,终止请求
|
||||
const cancelList = this.$store.state.panel.httpCancel
|
||||
// console.log('timeRefresh.vue------setRefresh------查看终止数量', cancelList, cancelList.length)
|
||||
if (cancelList.length > 0) {
|
||||
cancelList.forEach((cancel, index) => {
|
||||
cancel()
|
||||
delete cancelList[index]
|
||||
})
|
||||
}
|
||||
// 向地址栏添加自动刷新频率
|
||||
const dateParam = {
|
||||
refreshTime: val.value
|
||||
@@ -121,7 +130,7 @@ export default {
|
||||
}
|
||||
return
|
||||
}
|
||||
if (val && val.value == -1) {
|
||||
if (val && val.value === -1) {
|
||||
// 清除定时器
|
||||
clearInterval(this.intervalTimer)
|
||||
|
||||
|
||||
@@ -53,7 +53,17 @@
|
||||
trigger="click">
|
||||
<template #reference>
|
||||
<div class="breadcrumb-button" id="breadcrumbButton" :class="showBackground?'breadcrumb-button__active':''" >
|
||||
<span id="breadcrumbValue"> {{item}}</span><i class="cn-icon-xiala cn-icon"></i>
|
||||
<span id="breadcrumbValue">
|
||||
<template v-if="curTabProp === 'qtype'">
|
||||
<span>{{dnsQtypeMapData.get(item) ? dnsQtypeMapData.get(item):item}}</span>
|
||||
</template>
|
||||
<template v-else-if="curTabProp === 'rcode'">
|
||||
<span>{{dnsRcodeMapData.get(item) ? dnsRcodeMapData.get(item):item}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{item}}</span>
|
||||
</template>
|
||||
</span><i class="cn-icon-xiala cn-icon"></i>
|
||||
</div>
|
||||
</template>
|
||||
<el-row type="flex" justify="center" style="width: fit-content;flex-direction: column;">
|
||||
@@ -65,7 +75,15 @@
|
||||
</div>
|
||||
<ul class="select-dropdown" id="breadcrumbSelectDropdown" @scroll="scrollList()">
|
||||
<li v-for="item in breadcrumbColumnValueListShow" title='' :key="item" :id="item" class="select-dropdown__item" @click="changeValue(item)" :class="selected?'':''">
|
||||
<span>{{item}}</span>
|
||||
<template v-if="curTabProp === 'qtype'">
|
||||
<span>{{dnsQtypeMapData.get(item) ? dnsQtypeMapData.get(item):item}}</span>
|
||||
</template>
|
||||
<template v-else-if="curTabProp === 'rcode'">
|
||||
<span>{{dnsRcodeMapData.get(item) ? dnsRcodeMapData.get(item):item}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>{{item}}</span>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</el-row>
|
||||
@@ -190,11 +208,12 @@ import {
|
||||
networkTable,
|
||||
operationType,
|
||||
storageKey,
|
||||
wholeScreenRouterMapping
|
||||
wholeScreenRouterMapping,
|
||||
fromRoute
|
||||
} from '@/utils/constants'
|
||||
import { api } from '@/utils/api'
|
||||
import { ref } from 'vue'
|
||||
import { combineTabList, getDefaultCurTab, getTabList, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||
import { combineTabList, getDefaultCurTab, getTabList, overwriteUrl, urlParamsHandler, combinDrilldownTableWithUserConfig,getDnsMapData } from '@/utils/tools'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { db } from '@/indexedDB'
|
||||
|
||||
@@ -226,10 +245,15 @@ export default {
|
||||
showMenu: false,
|
||||
dropDownValue: '',
|
||||
breadcrumbColumnValueListShow: [],
|
||||
curTabProp:'',
|
||||
dnsRcodeMapData:[],
|
||||
dnsQtypeMapData:[],
|
||||
isDnsMapType:false,
|
||||
valueMeta: [],
|
||||
showBackground: false,
|
||||
selected: false,
|
||||
valueMenuId: '',
|
||||
fromRoute: fromRoute,
|
||||
detectionMenuList: [
|
||||
{
|
||||
name: 'securityEvents',
|
||||
@@ -270,6 +294,7 @@ export default {
|
||||
},
|
||||
breadcrumb () {
|
||||
const breadcrumbMap = []
|
||||
this.curTabProp = this.$route.query.dimensionType ? this.$route.query.dimensionType : null
|
||||
this.$store.getters.menuList.forEach(menu => {
|
||||
if (this.$_.isEmpty(menu.children) && menu.route) {
|
||||
breadcrumbMap.push({ name: this.$t(menu.i18n), path: menu.route, columnName: menu.columnName, columnValue: menu.columnValue })
|
||||
@@ -312,8 +337,10 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
async mounted () {
|
||||
this.from = Object.keys(this.entityType)[0]
|
||||
this.dnsQtypeMapData = await getDnsMapData('dnsQtype')
|
||||
this.dnsRcodeMapData = await getDnsMapData('dnsRcode')
|
||||
this.initDropdownList()
|
||||
},
|
||||
setup () {
|
||||
@@ -350,14 +377,25 @@ export default {
|
||||
window.location.reload()
|
||||
})
|
||||
},
|
||||
initDropdownList () {
|
||||
const currentValue = document.getElementById('breadcrumbValue') ? document.getElementById('breadcrumbValue').innerText : ''
|
||||
const columnName = this.getUrlParam(this.curTabState.thirdMenu, '')
|
||||
let type = 'ip'
|
||||
const tableType = this.$route.params ? this.$route.params.typeName : 'networkOverview'
|
||||
const curTableInCode = networkTable[tableType] ? networkTable[tableType] : networkTable.networkOverview
|
||||
getCurTabByLabel(label){
|
||||
let curTab = null
|
||||
let tableType = this.$route.params ? this.$route.params.typeName : 'networkOverview'
|
||||
let curTableInCode = networkTable[tableType] ? networkTable[tableType] : networkTable.networkOverview
|
||||
if (curTableInCode && curTableInCode.tabList) {
|
||||
const curTab = curTableInCode.tabList.find(item => item.label == columnName)
|
||||
curTab = curTableInCode.tabList.find(item => item.label == label)
|
||||
}
|
||||
return curTab
|
||||
},
|
||||
async initDropdownList () {
|
||||
//是否需要dns的qtype和rcode的数据字典
|
||||
this.curTabProp = this.$route.query.dimensionType ? this.$route.query.dimensionType : null
|
||||
let currentValue = document.getElementById('breadcrumbValue') ? document.getElementById('breadcrumbValue').innerText : ''
|
||||
let columnName = this.getUrlParam(this.curTabState.thirdMenu, '')
|
||||
let type = 'ip'
|
||||
let tableType = this.$route.params ? this.$route.params.typeName : 'networkOverview'
|
||||
let curTableInCode = networkTable[tableType] ? networkTable[tableType] : networkTable.networkOverview
|
||||
if (curTableInCode && curTableInCode.tabList) {
|
||||
let curTab = curTableInCode.tabList.find(item => item.label == columnName)
|
||||
if (curTab) {
|
||||
type = curTab.prop
|
||||
}
|
||||
@@ -369,14 +407,22 @@ export default {
|
||||
type: type,
|
||||
name: this.dropDownValue ? this.dropDownValue : ''
|
||||
}
|
||||
get(curTableInCode.url.drilldownList, params).then(response => {
|
||||
get(curTableInCode.url.drilldownList, params).then(async response => {
|
||||
if (response.code === 200) {
|
||||
this.breadcrumbColumnValueListShow = response.data.result
|
||||
this.dnsQtypeMapData = await getDnsMapData('dnsQtype')
|
||||
this.dnsRcodeMapData = await getDnsMapData('dnsRcode')
|
||||
this.$nextTick(() => {
|
||||
this.breadcrumbColumnValueListShow.forEach(item => {
|
||||
const selectedDom = document.getElementById(item)
|
||||
if (selectedDom) {
|
||||
if (item === currentValue) {
|
||||
let itemName = item
|
||||
if(this.curTabProp === 'qtype'){
|
||||
itemName = this.dnsQtypeMapData.get(item)
|
||||
}else if(this.curTabProp === 'rcode'){
|
||||
itemName = this.dnsRcodeMapData.get(item)
|
||||
}
|
||||
if (itemName === currentValue) {
|
||||
selectedDom.style.cssText = 'color:#0091ff;font-weight: bold;'
|
||||
} else {
|
||||
selectedDom.style.cssText = ''
|
||||
@@ -407,32 +453,37 @@ export default {
|
||||
},
|
||||
changeValue (value) {
|
||||
// 设置面包屑显示的内容及hover时的title
|
||||
let valName = value
|
||||
if(this.tab === 'qtype'){
|
||||
valName =this.dnsQtypeMapData.get(value)
|
||||
}else if(this.tab === 'rcode'){
|
||||
valName =this.dnsRcodeMapData.get(value)
|
||||
}
|
||||
this.curTabProp = this.$route.query.dimensionType ? this.$route.query.dimensionType : null
|
||||
document.getElementById('breadcrumbValue').innerText = value
|
||||
document.getElementById('breadcrumbButton').setAttribute('title', value)
|
||||
document.getElementById(this.valueMenuId).setAttribute('title', value)
|
||||
//document.getElementById('breadcrumbButton').setAttribute('title', valName)
|
||||
document.getElementById(this.valueMenuId).setAttribute('title', valName)
|
||||
document.getElementById('breadcrumbButton').click()
|
||||
// const columnName = this.$store.getters.getBreadcrumbColumnName
|
||||
const columnName = this.getUrlParam(this.curTabState.thirdMenu, '')
|
||||
const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
|
||||
if (tabObjGroup && tabObjGroup.length > 0) {
|
||||
const curTab = tabObjGroup[0]
|
||||
if (curTab) {
|
||||
const queryCondition = []
|
||||
const searchProps = curTab.dillDownProp
|
||||
if (curTab.prop === 'protocolPort') {
|
||||
const valueGroup = value.split(':')
|
||||
if (valueGroup) {
|
||||
queryCondition.push("common_l7_protocol='" + valueGroup[0] + "'")
|
||||
queryCondition.push('common_server_port=' + valueGroup[1])
|
||||
}
|
||||
console.log(queryCondition.join(' AND '))
|
||||
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' AND ')
|
||||
} else {
|
||||
searchProps.forEach(item => {
|
||||
queryCondition.push(item + "='" + value + "'")
|
||||
})
|
||||
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' OR ')
|
||||
//const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
|
||||
let curTab = this.getCurTabByLabel()
|
||||
if (curTab) {
|
||||
const queryCondition = []
|
||||
const searchProps = curTab.dillDownProp
|
||||
if (curTab.prop === 'protocolPort') {
|
||||
const valueGroup = value.split(':')
|
||||
if (valueGroup) {
|
||||
queryCondition.push("common_l7_protocol='" + valueGroup[0] + "'")
|
||||
queryCondition.push('common_server_port=' + valueGroup[1])
|
||||
}
|
||||
console.log(queryCondition.join(' AND '))
|
||||
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' AND ')
|
||||
} else {
|
||||
searchProps.forEach(item => {
|
||||
queryCondition.push(item + "='" + value.replaceAll("'", "\\\\'") + "'")
|
||||
})
|
||||
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' OR ')
|
||||
}
|
||||
}
|
||||
this.changeUrlTabState()
|
||||
@@ -468,19 +519,7 @@ export default {
|
||||
async handleCurDrilldownTableConfig (thirdMenu, fourthMenu) {
|
||||
const userId = localStorage.getItem(storageKey.userId)
|
||||
const tableType = this.$route.params ? this.$route.params.typeName : 'networkOverview'
|
||||
|
||||
// 先从localStorage中获取用户定制的自定义配置,如果没有,则使用默认的自定义配置
|
||||
const userLocalConfig = await db[dbDrilldownTableConfig].get({ id: userId })
|
||||
let drillDownTableConfigs = []
|
||||
if (userLocalConfig) {
|
||||
drillDownTableConfigs = userLocalConfig.config
|
||||
}
|
||||
if (!drillDownTableConfigs || drillDownTableConfigs.length === 0) { // 未找到当前用户的配置,使用默认配置
|
||||
const defaultConfig = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
||||
if (defaultConfig) {
|
||||
drillDownTableConfigs = defaultConfig.config
|
||||
}
|
||||
}
|
||||
const drillDownTableConfigs = await combinDrilldownTableWithUserConfig()
|
||||
const currentTableConfig = drillDownTableConfigs.find(config => config.route === tableType)
|
||||
const tables = currentTableConfig ? currentTableConfig.tables : []
|
||||
const commonTabList = currentTableConfig ? currentTableConfig.tabs : []
|
||||
@@ -499,10 +538,6 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
await db[dbDrilldownTableConfig].put({
|
||||
id: userId,
|
||||
config: this.$_.cloneDeep(drillDownTableConfigs)
|
||||
})
|
||||
},
|
||||
jump (route, columnName, columnValue, opeType) {
|
||||
this.showMenu = false
|
||||
@@ -511,7 +546,9 @@ export default {
|
||||
this.urlChangeParams[this.curTabState.tabOperationBeforeType] = this.getUrlParam(this.curTabState.tabOperationType, '', true)
|
||||
this.urlChangeParams[this.curTabState.tabOperationType] = opeType
|
||||
if (opeType === 3) {
|
||||
this.urlChangeParams.queryCondition = ''
|
||||
if (route !== '/panel/networkOverview') {
|
||||
this.urlChangeParams.queryCondition = ''
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.urlChangeParams[this.curTabState.tabOperationType] = operationType.mainMenu
|
||||
@@ -519,7 +556,6 @@ export default {
|
||||
if (!columnName) { // 点击第二级菜单
|
||||
this.$store.commit('setNetworkOverviewTabList', [])
|
||||
}
|
||||
|
||||
// 清空网络概况的特殊面包屑
|
||||
this.$store.getters.menuList.forEach(menu => {
|
||||
if (!this.$_.isEmpty(menu.children)) {
|
||||
@@ -530,16 +566,18 @@ export default {
|
||||
child.columnName = columnName
|
||||
this.urlChangeParams[this.curTabState.thirdMenu] = columnName
|
||||
this.urlChangeParams[this.curTabState.fourthMenu] = columnValue
|
||||
const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
|
||||
const type = tabObjGroup && tabObjGroup[0] ? tabObjGroup[0].prop : ''
|
||||
this.urlChangeParams[this.curTabState.dimensionType] = type
|
||||
//const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
|
||||
//let curTab = this.getCurTabByLabel()
|
||||
//const type = curTab ? curTab.prop : ''
|
||||
//this.curTabProp = this.$route.query.dimensionType ? this.$route.query.dimensionType : null
|
||||
//this.urlChangeParams[this.curTabState.dimensionType] = type
|
||||
this.urlChangeParams[this.curTabState.panelName] = columnValue
|
||||
} else if (columnName) { // 点击的为列名
|
||||
child.columnValue = ''
|
||||
child.columnName = columnName
|
||||
this.urlChangeParams[this.curTabState.thirdMenu] = columnName
|
||||
this.urlChangeParams[this.curTabState.fourthMenu] = ''
|
||||
this.urlChangeParams[this.curTabState.panelName] = columnName
|
||||
this.urlChangeParams[this.curTabState.panelName] = columnValue
|
||||
const tableType = this.$route.params ? this.$route.params.typeName : 'networkOverview'
|
||||
const metric = this.getUrlParam(this.curTabState.tableMetric, 'Bits/s')
|
||||
const curTab = getDefaultCurTab(tableType, metric, columnName)
|
||||
|
||||
@@ -74,6 +74,9 @@
|
||||
size="small"
|
||||
:format="dateFormat"
|
||||
:disabled="!!editObject.id"
|
||||
:disabled-date="startDisabledDate"
|
||||
@change="startTimeChang"
|
||||
@focus="startFocus"
|
||||
prefix-icon="cn-icon cn-icon-shijian"
|
||||
type="datetime"
|
||||
placeholder=" "
|
||||
@@ -91,6 +94,9 @@
|
||||
size="small"
|
||||
:format="dateFormat"
|
||||
:disabled="!!editObject.id"
|
||||
:disabled-date="endDisabledDate"
|
||||
@change="endTimeChange"
|
||||
@focus="endFocus"
|
||||
prefix-icon="cn-icon cn-icon-shijian"
|
||||
type="datetime"
|
||||
placeholder=" "
|
||||
@@ -277,6 +283,7 @@ import { api } from '@/utils/api'
|
||||
import _ from 'lodash'
|
||||
import { get, post, put } from '@/utils/http'
|
||||
import { dateFormat, getMillisecond } from '@/utils/date-util'
|
||||
import { ref } from 'vue'
|
||||
const paramValidator = (rule, value, callback) => {
|
||||
let validate = true
|
||||
if (value && value.length > 0) {
|
||||
@@ -305,6 +312,58 @@ export default {
|
||||
categoryList: Array,
|
||||
currentCategoryId: Number
|
||||
},
|
||||
setup () {
|
||||
const startTime = ref('')
|
||||
const endTime = ref('')
|
||||
const focus = ref('')
|
||||
const focusDate = ref('')
|
||||
function endTimeChange (val) {
|
||||
endTime.value = val
|
||||
}
|
||||
function startTimeChang (val) {
|
||||
startTime.value = val
|
||||
}
|
||||
function startFocus (val) {
|
||||
focus.value = val.target.value
|
||||
}
|
||||
function endFocus (val) {
|
||||
focusDate.value = val.target.value
|
||||
}
|
||||
const endDisabledDate = (time) => {
|
||||
if (time.getTime() > new Date()) {
|
||||
return true
|
||||
}
|
||||
if (startTime.value != '' && startTime.value > time) {
|
||||
return true
|
||||
}
|
||||
if (focusDate.value != '' && endTime.value > time) {
|
||||
return false
|
||||
} else if (endTime.value != '' && endTime.value < time) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
const startDisabledDate = (time) => {
|
||||
if (time.getTime() > new Date()) {
|
||||
return true
|
||||
}
|
||||
if (focus.value != '' && startTime.value > time) {
|
||||
return false
|
||||
} else if (startTime.value != '' && startTime.value > time) {
|
||||
return true
|
||||
}
|
||||
if (endTime.value != '' && endTime.value < time) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return {
|
||||
endDisabledDate,
|
||||
startDisabledDate,
|
||||
startTimeChang,
|
||||
endTimeChange,
|
||||
startFocus,
|
||||
endFocus
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
url: api.reportTemp,
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
<el-table-column type="expand" width="30">
|
||||
<template #default="props">
|
||||
<div class="down">
|
||||
<loading :loading="loadingDown"></loading>
|
||||
<div class="block drop-down-time">
|
||||
<el-date-picker
|
||||
v-model="timeRange"
|
||||
@@ -34,6 +33,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="expand">
|
||||
<loading :loading="loadingDown"></loading>
|
||||
<chart-no-data v-if="downDataList.length === 0 && !loadingDown"></chart-no-data>
|
||||
<div class="expand-cell" v-for="(item, index) in downDataList" :key="index">
|
||||
<div class="expand-right">
|
||||
|
||||
@@ -9,7 +9,7 @@ import commonMixin from '@/mixins/common'
|
||||
import { cancelWithChange, noData } from '@/utils/tools'
|
||||
import { ClickOutside } from 'element-plus/lib/directives'
|
||||
import i18n from '@/i18n'
|
||||
import '@/mock/index.js'
|
||||
// import '@/mock/index.js'
|
||||
import hljsVuePlugin from '@highlightjs/vue-plugin'
|
||||
import 'highlight.js/styles/color-brewer.css'
|
||||
import '@/assets/css/main.scss' // 样式入口
|
||||
@@ -26,12 +26,6 @@ const emitter = new bus()
|
||||
|
||||
const _ = require('lodash') // lodash工具
|
||||
|
||||
/* dayjs.extend(utc)
|
||||
dayjs.extend(timezone)
|
||||
dayjs.extend(advancedFormat)
|
||||
dayjs.extend(weekday)
|
||||
window.$dayJs = dayjs */
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
|
||||
@@ -51,7 +51,11 @@ const panel = {
|
||||
npmLocationCountry: '', // npm location的查询条件--国家
|
||||
npmLocationSide: 'server', // npm location的查询条件--方向
|
||||
refreshTime: null, // 自动刷新时间的秒数
|
||||
refreshFlag: true // 关闭自动刷新标志,true为off,false即开启自动刷新
|
||||
refreshFlag: true, // 关闭自动刷新标志,true为off,false即开启自动刷新
|
||||
timeRangeArray: [], // 时间范围列表:开始/结束时间
|
||||
timeRangeFlag: null, // 时间范围标志,默认60即一小时,-1为手动选择的时间范围
|
||||
routerPath: '', // 当前路由路径
|
||||
httpCancel: null // 终止http请求
|
||||
},
|
||||
mutations: {
|
||||
setShowRightBox (state, flag) {
|
||||
@@ -146,6 +150,18 @@ const panel = {
|
||||
},
|
||||
setRefreshFlag (state, flag) {
|
||||
state.refreshFlag = flag
|
||||
},
|
||||
setTimeRangeArray (state, array) {
|
||||
state.timeRangeArray = array
|
||||
},
|
||||
setTimeRangeFlag (state, flag) {
|
||||
state.timeRangeFlag = flag
|
||||
},
|
||||
setRouterPath (state, path) {
|
||||
state.routerPath = path
|
||||
},
|
||||
setHttpCancel (state, cancel) {
|
||||
state.httpCancel = cancel
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
@@ -229,6 +245,15 @@ const panel = {
|
||||
},
|
||||
getNpmThirdLevelMenuScore (state) {
|
||||
return state.npmThirdLevelMenuScore
|
||||
},
|
||||
getTimeRangeArray (state) {
|
||||
return state.timeRangeArray
|
||||
},
|
||||
getTimeRangeFlag (state) {
|
||||
return state.timeRangeFlag
|
||||
},
|
||||
getRouterPath (state) {
|
||||
return state.routerPath
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -3,6 +3,7 @@ import router from '@/router'
|
||||
import { sortByOrderNum, getWelcomeMenu } from '@/permission'
|
||||
import { ElMessage } from 'element-plus' // dependent on utc plugin
|
||||
import { storageKey, dbDrilldownTableConfig } from '@/utils/constants'
|
||||
import { readDrilldownTableConfigByUser } from '@/utils/tools'
|
||||
import { api } from '@/utils/api'
|
||||
import { db } from '@/indexedDB'
|
||||
|
||||
@@ -11,7 +12,8 @@ const user = {
|
||||
return {
|
||||
menuList: [],
|
||||
buttonList: [],
|
||||
roleList: []
|
||||
roleList: [],
|
||||
drilldownTableConfigList: []
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
@@ -24,6 +26,9 @@ const user = {
|
||||
setRoleList (state, roleList) {
|
||||
state.roleList = [...roleList]
|
||||
},
|
||||
setDrilldownTableList (state, drilldownTableConfigList) {
|
||||
state.drilldownTableConfigList = [...drilldownTableConfigList]
|
||||
},
|
||||
clean (state) {
|
||||
state.menuList = []
|
||||
state.buttonList = []
|
||||
@@ -39,6 +44,9 @@ const user = {
|
||||
},
|
||||
roleList (state) {
|
||||
return state.roleList
|
||||
},
|
||||
drilldownTableConfigList (state) {
|
||||
return state.drilldownTableConfigList
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@@ -82,13 +90,12 @@ const user = {
|
||||
})
|
||||
get(api.config, { ckey: 'drill_down_table_config' }).then(async res => {
|
||||
if (res.code === 200 && res.page.list && res.page.list.length > 0) {
|
||||
// 从接口返回整体配置,再读取用户缓存,将对应条目覆盖,作为使用的配置
|
||||
const defaultConfigs = JSON.parse(res.page.list[0].cvalue)
|
||||
await db[dbDrilldownTableConfig].put({
|
||||
id: 'default',
|
||||
config: JSON.parse(res.page.list[0].cvalue)
|
||||
config: defaultConfigs
|
||||
})
|
||||
// const a = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
||||
// console.info(a)
|
||||
// localStorage.setItem(storageKey.drillDownTableConfig, res.page.list[0].cvalue)
|
||||
}
|
||||
})
|
||||
get(api.config, { ckey: 'link_info' }).then(res => {
|
||||
|
||||
@@ -161,6 +161,11 @@ export const api = {
|
||||
appSslConDelay: '/interface/application/performance/overview/appSslConDelay',
|
||||
appTcpLostlenPercent: '/interface/application/performance/overview/appTcpLostlenPercent',
|
||||
appPacketRetransPercent: '/interface/application/performance/overview/appPacketRetransPercent',
|
||||
// 整体流量折线图
|
||||
totalTrafficAnalysis: '/interface/application/performance/overview/totalTrafficAnalysis',
|
||||
totalNetworkAnalysis: '/interface/application/performance/overview/totalNetworkAnalysis',
|
||||
totalHttpResponseDelay: '/interface/application/performance/overview/totalHttpResponseDelay',
|
||||
totalSslConDelay: '/interface/application/performance/overview/totalSslConDelay',
|
||||
// 各维度下钻会话统计
|
||||
relatedSessions: '/interface/application/performance/relatedSessions',
|
||||
// 各维度下钻流量曲线图
|
||||
@@ -220,7 +225,8 @@ export const api = {
|
||||
recentEvents: '/interface/dnsInsight/recentEvents',
|
||||
activeMaliciousDomain: '/interface/dnsInsight/activeMaliciousDomain',
|
||||
totalTrafficAnalysis: '/interface/dns/overview/totalTrafficAnalysis',
|
||||
eventChart: '/interface/dnsInsight/eventChart'
|
||||
eventChart: '/interface/dnsInsight/eventChart',
|
||||
drilldownTrafficAnalysis: '/interface/dns/overview/drilldown/trafficAnalysis'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export const storageKey = {
|
||||
echartLegendFontSize: 'echartLegendFontSize',
|
||||
echartLabelFontSize: 'echartLabelFontSize',
|
||||
tokenExpireCurrentPath: 'token-expire-current-path',
|
||||
drillDownTableConfig: 'cn-drill-down-table-config',
|
||||
drillDownTableConfig: 'drilldownTableConfig',
|
||||
userCustomizationConfig: 'userCustomizationConfig',
|
||||
linkInfo: 'cn-link-info',
|
||||
history: 'cn-history'
|
||||
@@ -186,6 +186,21 @@ export const networkOverviewTabs = [
|
||||
'network.protocolPorts'
|
||||
] */
|
||||
|
||||
export const metricOptions = [
|
||||
{
|
||||
value: 'Bits/s',
|
||||
label: 'Bits/s'
|
||||
},
|
||||
{
|
||||
value: 'Packets/s',
|
||||
label: 'Packets/s'
|
||||
},
|
||||
{
|
||||
value: 'Sessions/s',
|
||||
label: 'Sessions/s'
|
||||
}
|
||||
]
|
||||
|
||||
export const operationType = {
|
||||
mainMenu: 0, // 菜单
|
||||
secondMenu: 2, // 二级菜单
|
||||
@@ -287,11 +302,11 @@ export const scoreUrl = [
|
||||
|
||||
// AppPerformance类型表格的列:有属性cycleDataUrl的,代表此数据的来源为对应接口返回的数据,无cycleDataUrl的属性代表数据来源于主url:npmSearchUrl.curUrl、npmSearchUrl.cycleUrl、npmSearchUrl.drilldownCurUrl、npmSearchUrl.drilldownCycleUrl
|
||||
export const customTableTitlesForAppPerformance = [
|
||||
{ label: 'network.ips', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{ label: 'IP', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{ label: 'network.score', prop: 'score', checked: true, tabColumn: false, columnType: tableColumnType.normal },
|
||||
{
|
||||
label: 'networkAppPerformance.throughput',
|
||||
prop: 'through',
|
||||
prop: 'totalBytes',
|
||||
checked: true,
|
||||
tabColumn: false,
|
||||
columnType: tableColumnType.chainRatio,
|
||||
@@ -375,11 +390,11 @@ export const customTableTitlesForAppPerformance = [
|
||||
}
|
||||
]
|
||||
export const customTableTitlesForLinkMonitor = [
|
||||
{ label: 'network.ips', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{ label: 'IP', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{ label: 'network.score', prop: 'score', checked: true, tabColumn: false, columnType: tableColumnType.normal },
|
||||
{
|
||||
label: 'networkAppPerformance.throughput',
|
||||
prop: 'through',
|
||||
prop: 'totalBytes',
|
||||
checked: true,
|
||||
tabColumn: false,
|
||||
columnType: tableColumnType.chainRatio,
|
||||
@@ -479,7 +494,7 @@ export const customTableTitlesForDns = [
|
||||
]
|
||||
// NetworkOverview类型表格的列:prop 为接口响应数据中的属性名
|
||||
export const customTableTitlesForNetworkOverview = [
|
||||
{ label: 'network.ips', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{ label: 'IP', prop: 'tab', checked: true, tabColumn: true, columnType: tableColumnType.dillDown },
|
||||
{
|
||||
label: 'network.total',
|
||||
prop: 'total',
|
||||
@@ -953,6 +968,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'dnsServerRole',
|
||||
queryCycleTotalProp: 'roles',
|
||||
dillDownProp: ['dns_server_role'],
|
||||
queryCondition: ['has(dns_server_role,\'$param\')'],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -971,6 +987,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'sld',
|
||||
queryCycleTotalProp: 'slds',
|
||||
dillDownProp: ['dns_qname'],
|
||||
queryCondition: ['cutToFirstSignificantSubdomain(dns_qname) = \'$param\''],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -980,6 +997,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'tld',
|
||||
queryCycleTotalProp: 'tlds',
|
||||
dillDownProp: ['dns_qname'],
|
||||
queryCondition: [' topLevelDomain(dns_qname) = \'$param\''],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -989,6 +1007,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'qtype',
|
||||
queryCycleTotalProp: 'qtypes',
|
||||
dillDownProp: ['dns_qtype'],
|
||||
queryCondition: ['dns_qtype = $param'],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -998,6 +1017,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'rcode',
|
||||
queryCycleTotalProp: 'rcodes',
|
||||
dillDownProp: ['dns_rcode'],
|
||||
queryCondition: ['dns_rcode = $param'],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -1007,6 +1027,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'a',
|
||||
queryCycleTotalProp: 'a',
|
||||
dillDownProp: ['rr_a'],
|
||||
queryCondition: ['notEmpty(dns_rr) AND has(JSONExtractArrayRaw(JSON_QUERY(\'$.rr[*].type\', dns_rr) ), \'1\') AND arrayJoin(tupleElement(tupleElement(JSONExtract(dns_rr,\'Tuple(rr Nested(name String, type UInt32, a String))\'), \'rr\'), \'a\')) = \'$param\''],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -1016,6 +1037,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'aaaa',
|
||||
queryCycleTotalProp: 'aaaa',
|
||||
dillDownProp: ['rr_aaaa'],
|
||||
queryCondition: ['notEmpty(dns_rr) and has(JSONExtractArrayRaw(JSON_QUERY(\'$.rr[*].type\', dns_rr) ), \'28\') AND arrayJoin(tupleElement(tupleElement(JSONExtract(dns_rr,\'Tuple(rr Nested(name String, type UInt32, aaaa String))\'), \'rr\'), \'aaaa\')) = \'$param\''],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -1025,6 +1047,7 @@ export const dnsServiceInsightsTabList = [
|
||||
prop: 'cname',
|
||||
queryCycleTotalProp: 'cnames',
|
||||
dillDownProp: ['rr_cname'],
|
||||
queryCondition: ['notEmpty(dns_rr) and has(JSONExtractArrayRaw(JSON_QUERY(\'$.rr[*].type\', dns_rr) ), \'5\') AND arrayJoin(tupleElement(tupleElement(JSONExtract(dns_rr,\'Tuple(rr Nested(name String, type UInt32, cname String))\'), \'rr\'), \'cname\')) = \'$param\''],
|
||||
checked: true,
|
||||
disabled: false,
|
||||
panelId: drillDownPanelTypeMapping.dnsFourthMenu
|
||||
@@ -1033,7 +1056,7 @@ export const dnsServiceInsightsTabList = [
|
||||
|
||||
// 用于组织数据时的名称,对应的属性名称
|
||||
export const bytesColumnNameGroupForNpm = {
|
||||
through: 'throughBitsRate',
|
||||
totalBytes: 'totalBytes',
|
||||
tcpConEstLatency: 'establishLatencyMs',
|
||||
packetLoss: 'tcpLostlenPercent',
|
||||
packetRetrans: 'pktRetransPercent',
|
||||
@@ -1041,8 +1064,8 @@ export const bytesColumnNameGroupForNpm = {
|
||||
httpResponseLatency: 'httpResponseLatency'
|
||||
}
|
||||
|
||||
export const bytesCycleColumnNameGroupForNmp = {
|
||||
through: 'throughBitsRate'
|
||||
export const bytesCycleColumnNameGroupForNpm = {
|
||||
totalBytes: 'totalBytes'
|
||||
}
|
||||
|
||||
// 用于组织数据时的名称,对应的属性名称
|
||||
@@ -1059,14 +1082,14 @@ export const bytesCycleColumnNameGroupForDns = {
|
||||
|
||||
// networkOverview 当前周期返回数据对应的属性名称(与上一周期中的属性名称不一致,total),之所以写在这里是因为有byte,packets,sessions3种,如果只有一种,可以直接写在customTableTitlesForAppPerformance
|
||||
export const bytesColumnNameGroup = {
|
||||
total: 'bytesTotalRate',
|
||||
total: 'totalBitsRate',
|
||||
inbound: 'inboundBitsRate',
|
||||
outbound: 'outboundBitsRate',
|
||||
internal: 'internalBitsRate',
|
||||
through: 'throughBitsRate'
|
||||
}
|
||||
export const packetsColumnNameGroup = {
|
||||
total: 'packetsTotalRate',
|
||||
total: 'totalPacketsRate',
|
||||
inbound: 'inboundPacketsRate',
|
||||
outbound: 'outboundPacketsRate',
|
||||
internal: 'internalPacketsRate',
|
||||
@@ -1077,7 +1100,7 @@ export const sessionsColumnNameGroup = {
|
||||
}
|
||||
|
||||
export const bytesCycleColumnNameGroup = {
|
||||
total: 'bytesRate'
|
||||
total: 'bitsRate'
|
||||
}
|
||||
export const packetsCycleColumnNameGroup = {
|
||||
total: 'packetsRate'
|
||||
@@ -1110,7 +1133,7 @@ export const networkTable = {
|
||||
bytesColumnNameGroup: bytesColumnNameGroupForNpm,
|
||||
packetsColumnNameGroup: {}, // 无metric下拉列表条件,用不到此属性
|
||||
sessionsColumnNameGroup: {}, // 无metric下拉列表条件,用不到此属性
|
||||
bytesCycleColumnNameGroup: bytesCycleColumnNameGroupForNmp,
|
||||
bytesCycleColumnNameGroup: bytesCycleColumnNameGroupForNpm,
|
||||
packetsCycleColumnNameGroup: {},
|
||||
sessionsCycleColumnNameGroup: {}
|
||||
},
|
||||
@@ -1131,7 +1154,7 @@ export const networkTable = {
|
||||
hasMetricSearch: false, // 是否有metric下拉列表
|
||||
panelIdOfThirdMenu: drillDownPanelTypeMapping.linkMonitor,
|
||||
bytesColumnNameGroup: bytesColumnNameGroupForNpm,
|
||||
bytesCycleColumnNameGroup: bytesCycleColumnNameGroupForNmp
|
||||
bytesCycleColumnNameGroup: bytesCycleColumnNameGroupForNpm
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,3 +69,26 @@ export function dateFormatToUTC (date, format = 'YYYY-MM-DD HH:mm:ss') {
|
||||
d = window.$dayJs(d).tz().format(format)
|
||||
return d
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间戳转年月日时分秒,置于数组中,配合el-date-picker使用
|
||||
* @param time
|
||||
* @returns {number[]}
|
||||
*/
|
||||
export function timestampToList (time) {
|
||||
// 根据地址获取当前时区
|
||||
const newTimezone = window.$dayJs.tz().utcOffset() / 60
|
||||
// 缓存的本地时区
|
||||
const localTimezone = parseInt(localStorage.getItem(storageKey.timezoneLocalOffset))
|
||||
const date = new Date(getMillisecond(time + (newTimezone - localTimezone) * 3600))
|
||||
|
||||
const Y = date.getFullYear()
|
||||
const M = date.getMonth()
|
||||
const D = date.getDate()
|
||||
const H = date.getHours()
|
||||
const m = date.getMinutes()
|
||||
const s = date.getSeconds()
|
||||
|
||||
const arr = [Y, M, D, H, m, s]
|
||||
return arr
|
||||
}
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
import axios from 'axios'
|
||||
import { storageKey } from '@/utils/constants'
|
||||
import store from '@/store'
|
||||
|
||||
const CancelToken = axios.CancelToken
|
||||
|
||||
axios.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem(storageKey.token)
|
||||
|
||||
// 添加http请求终止方法
|
||||
const arr = []
|
||||
const cancelToken = new CancelToken(function executor (c) {
|
||||
arr.push(c)
|
||||
store.commit('setHttpCancel', arr)
|
||||
})
|
||||
|
||||
config.cancelToken = cancelToken
|
||||
if (token) {
|
||||
config.headers['Cn-Authorization'] = token // 请求头token
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import i18n from '@/i18n'
|
||||
import _ from 'lodash'
|
||||
import { storageKey, iso36112, topDomain, echartsFontSize, dbGeoDataTableName, networkTable, dbDrilldownTableConfig } from '@/utils/constants'
|
||||
import { getIso36112JsonData } from '@/utils/api'
|
||||
import { getIso36112JsonData,getDictList } from '@/utils/api'
|
||||
import { format } from 'echarts'
|
||||
import router from '@/router'
|
||||
import { db } from '@/indexedDB'
|
||||
@@ -780,66 +780,55 @@ export function getChainRatio (current, prev) {
|
||||
}
|
||||
}
|
||||
|
||||
export function computeScore (data, index) {
|
||||
export function computeScore (data) {
|
||||
let score = 0
|
||||
let k = 0
|
||||
if (index === 0) {
|
||||
k = 0.3
|
||||
if (!data.establishLatencyMs && data.establishLatencyMs !== 0) {
|
||||
score = 0
|
||||
} else if (data.establishLatencyMs <= 50) {
|
||||
score = 1
|
||||
} else if (data.establishLatencyMs > 500) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data.establishLatencyMs - 500) / (50 - 500)
|
||||
let totalScore = 0
|
||||
const scoreArr = []
|
||||
let num = 0
|
||||
Object.keys(data).forEach(t => {
|
||||
if (!data[t]) {
|
||||
num += 1
|
||||
}
|
||||
} else if (index === 1) {
|
||||
k = 0.05
|
||||
if (!data.httpResponseLatency && data.httpResponseLatency !== 0) {
|
||||
score = 1
|
||||
} else if (data.httpResponseLatency <= 50) {
|
||||
score = 1
|
||||
} else if (data.httpResponseLatency > 500) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data.httpResponseLatency - 500) / (50 - 500)
|
||||
if (t === 'establishLatencyMs' || t === 'tcpLostlenPercent' || t === 'pktRetransPercent') {
|
||||
k = 0.3
|
||||
} else if (t === 'httpResponseLatency' || t === 'sslConLatency') {
|
||||
k = 0.05
|
||||
}
|
||||
} else if (index === 2) {
|
||||
k = 0.05
|
||||
if (!data.sslConLatency && data.sslConLatency !== 0) {
|
||||
score = 1
|
||||
} else if (data.sslConLatency <= 50) {
|
||||
score = 1
|
||||
} else if (data.sslConLatency > 500) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data.sslConLatency - 500) / (50 - 500)
|
||||
}
|
||||
} else if (index === 3) {
|
||||
k = 0.3
|
||||
if (!data.tcpLostlenPercent && data.tcpLostlenPercent !== 0) {
|
||||
score = 0
|
||||
} else if (data.tcpLostlenPercent <= 0.01) {
|
||||
score = 1
|
||||
} else if (data.tcpLostlenPercent > 0.5) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data.tcpLostlenPercent - 0.5) / (0.01 - 0.5)
|
||||
}
|
||||
} else if (index === 4) {
|
||||
k = 0.3
|
||||
if (!data.pktRetransPercent && data.pktRetransPercent !== 0) {
|
||||
score = 0
|
||||
} else if (data.pktRetransPercent <= 0.01) {
|
||||
score = 1
|
||||
} else if (data.pktRetransPercent > 0.5) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data.pktRetransPercent - 0.5) / (0.01 - 0.5)
|
||||
if (t === 'establishLatencyMs' || t === 'httpResponseLatency' || t === 'sslConLatency') {
|
||||
if (!data[t] && data[t] !== 0) {
|
||||
score = 1
|
||||
} else if (data[t] <= 50) {
|
||||
score = 1
|
||||
} else if (data[t] > 200) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data[t] - 200) / (50 - 200)
|
||||
}
|
||||
} else if (t === 'tcpLostlenPercent' || t === 'pktRetransPercent') {
|
||||
if (!data[t] && data[t] !== 0) {
|
||||
score = 1
|
||||
} else if (data[t] <= 0.01) {
|
||||
score = 1
|
||||
} else if (data[t] > 0.05) {
|
||||
score = 0
|
||||
} else {
|
||||
score = (data[t] - 0.05) / (0.01 - 0.05)
|
||||
}
|
||||
}
|
||||
scoreArr.push(score * k)
|
||||
})
|
||||
scoreArr.forEach(t => {
|
||||
totalScore += t
|
||||
})
|
||||
totalScore = Math.ceil(totalScore * 6)
|
||||
if (totalScore > 6) {
|
||||
totalScore = 6
|
||||
}
|
||||
return score * k
|
||||
if (num === 5) {
|
||||
return '-'
|
||||
}
|
||||
return totalScore
|
||||
}
|
||||
|
||||
// 改变tab状态(url中):当前tab,
|
||||
@@ -866,35 +855,55 @@ export function getTabList (curTable, curMetric) {
|
||||
}
|
||||
return tabs
|
||||
}
|
||||
export async function getDnsMapData(type){
|
||||
let codeValueMap = new Map()
|
||||
const dnsData = await getDictList({ type:type,pageSize: -1 })
|
||||
if(dnsData && dnsData.length>0) {
|
||||
dnsData.forEach(mapData => {
|
||||
let code = mapData.code
|
||||
if(code.indexOf('-')>-1){
|
||||
let range = mapData.code.split('-')
|
||||
if(range && range.length >= 2){
|
||||
let start = range[0].trim()
|
||||
let eEnd = range[1].trim()
|
||||
mapData.value = (start <= code && code <= eEnd) ? mapData.value : code
|
||||
for (let i = start; i <= eEnd; i++) {
|
||||
codeValueMap.set(i,mapData.value)
|
||||
}
|
||||
}
|
||||
}else {
|
||||
codeValueMap.set(code,mapData.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
return codeValueMap
|
||||
}
|
||||
export function combineTabList (tableType, list, commonTabList) {
|
||||
const curTableInCode = networkTable[tableType] ? networkTable[tableType] : networkTable.networkOverview
|
||||
const listInCode = curTableInCode ? curTableInCode.tabList : []
|
||||
list.forEach(tab => {
|
||||
// 配置的内容
|
||||
const tabName = tab ? (tab.name ? tab.name : tab) : ''
|
||||
// 配置的内容
|
||||
const commonTab = commonTabList.find(item => item.name === tabName)
|
||||
tab.label = commonTab ? commonTab.i18n : ''
|
||||
tab.prop = commonTab ? commonTab.prop : ''
|
||||
if (!tab.hasOwnProperty('checked')) {
|
||||
const tabName = tab ? (tab.name ? tab.name : tab) : ''
|
||||
// 配置的内容
|
||||
tab = {}
|
||||
const commonTab = commonTabList.find(item => item.name === tabName)
|
||||
tab.label = commonTab ? commonTab.i18n : ''
|
||||
tab.prop = commonTab ? commonTab.prop : ''
|
||||
if (!tab.hasOwnProperty('checked')) {
|
||||
tab.checked = tab ? tab.show : true
|
||||
}
|
||||
if (!tab.hasOwnProperty('disabled')) {
|
||||
tab.disabled = tab ? !tab.enable : false
|
||||
}
|
||||
if (!tab.hasOwnProperty('panelId')) {
|
||||
tab.panelId = tab ? tab.panelIdOfFourthMenu : null
|
||||
}
|
||||
// 代码里写死的
|
||||
const tabInCode = listInCode ? listInCode.find(item => item.label === tab.label) : {}
|
||||
tab.queryCycleTotalProp = tabInCode ? tabInCode.queryCycleTotalProp : null
|
||||
tab.dillDownProp = tabInCode ? tabInCode.dillDownProp : []
|
||||
tab.checked = tab ? tab.show : true
|
||||
}
|
||||
if (!tab.hasOwnProperty('disabled')) {
|
||||
tab.disabled = tab ? !tab.enable : false
|
||||
}
|
||||
if (!tab.hasOwnProperty('panelId')) {
|
||||
tab.panelId = tab ? tab.panelIdOfFourthMenu : null
|
||||
}
|
||||
// 代码里写死的
|
||||
const tabInCode = listInCode ? listInCode.find(item => item.label === tab.label) : {}
|
||||
tab.queryCycleTotalProp = tabInCode ? tabInCode.queryCycleTotalProp : null
|
||||
tab.dillDownProp = tabInCode ? tabInCode.dillDownProp : []
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
export function setUserConfig () {
|
||||
const userTableConfig = this.getUserLocalConfig()
|
||||
if (userTableConfig) {
|
||||
@@ -911,45 +920,92 @@ export function setUserConfig () {
|
||||
this.list = newTabConfigs
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
export async function getDefaultCurTab (tableType, metric, columnName) {
|
||||
const tabList = await getUserDrilldownTableConfig(tableType, metric)
|
||||
const curTab = tabList.filter(item => item.label === columnName)[0]
|
||||
return curTab
|
||||
}
|
||||
|
||||
export async function getUserDrilldownTableConfig (tableType, curMetric) {
|
||||
let list = []
|
||||
// 先从localStorage中获取用户定制的自定义配置,如果没有,则使用默认的自定义配置
|
||||
export async function readDrilldownTableConfigByUser (tableType, curMetric) {
|
||||
// 获取用户定制的自定义配置
|
||||
const userId = localStorage.getItem(storageKey.userId)
|
||||
const userLocalCongfig = await db[dbDrilldownTableConfig].get({ id: userId })
|
||||
let defaultDrillDownTableConfigs = []
|
||||
if (userLocalCongfig) {
|
||||
defaultDrillDownTableConfigs = userLocalCongfig.config
|
||||
}
|
||||
if (!defaultDrillDownTableConfigs || defaultDrillDownTableConfigs.length === 0) { // 未找到当前用户的配置,使用默认配置
|
||||
console.log('default..............')
|
||||
const defaultCongfig = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
||||
if (defaultCongfig) {
|
||||
defaultDrillDownTableConfigs = defaultCongfig.config
|
||||
return defaultDrillDownTableConfigs
|
||||
}
|
||||
|
||||
export async function combinDrilldownTableWithUserConfig () {
|
||||
const defaultCongfigInDb = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
||||
const defaultConfigs = defaultCongfigInDb ? defaultCongfigInDb.config : []
|
||||
const curUserConfig = await readDrilldownTableConfigByUser()
|
||||
if (defaultConfigs && curUserConfig && curUserConfig.length > 0) {
|
||||
defaultConfigs.forEach(defaultConfig => {
|
||||
const currentTableConfig = curUserConfig.find(config => config.route === defaultConfig.route)
|
||||
if (currentTableConfig) {
|
||||
const tableConfig = defaultConfig.tables.find(table => table.id === defaultConfig.route)
|
||||
const newTableConfig = currentTableConfig.tables.find(table => table.id === defaultConfig.route)
|
||||
tableConfig.hiddenColumns = newTableConfig.hiddenColumns
|
||||
tableConfig.tabs.forEach(tab => {
|
||||
const newTab = newTableConfig.tabs.find(newTab => newTab.name === tab.name)
|
||||
tab.hiddenDrilldownTabs = newTab.hiddenDrilldownTabs
|
||||
tab.checked = newTab.checked
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return defaultConfigs
|
||||
}
|
||||
|
||||
/*
|
||||
export async function readDrilldownTableConfigByUser2 (tableType, curMetric) {
|
||||
let list = []
|
||||
// 获取用户定制的自定义配置,如果没有,则使用默认的自定义配置
|
||||
const userId = localStorage.getItem(storageKey.userId)
|
||||
const userLocalCongfig = await db[dbDrilldownTableConfig].get({ id: userId })
|
||||
let defaultDrillDownTableConfigs = []
|
||||
if (userLocalCongfig) {
|
||||
defaultDrillDownTableConfigs = userLocalCongfig.config
|
||||
if(defaultDrillDownTableConfigs && defaultDrillDownTableConfigs.length > 0){
|
||||
const currentTableConfig = defaultDrillDownTableConfigs.find(config => config.route === tableType)
|
||||
const commonTabList = currentTableConfig ? currentTableConfig.tabs : []
|
||||
const tables = currentTableConfig ? currentTableConfig.tables : []
|
||||
if (tables && tables.length > 0) {
|
||||
const curTableOldConfig = tables.find(table => table.id === tableType)
|
||||
const curTable = curTableOldConfig || null
|
||||
if (curTable) {
|
||||
if (curTable.hasMetricSearch) { // 有metric
|
||||
const metricsList = curTable ? curTable.metrics : []
|
||||
if (metricsList && metricsList.length > 0) {
|
||||
const metricTab = metricsList.find(metric => metric.name === curMetric)
|
||||
list = metricTab ? metricTab.tabs : []
|
||||
}
|
||||
} else { // 无metric
|
||||
list = curTable ? curTable.tabs : []
|
||||
}
|
||||
//combineTabList(tableType, list, commonTabList)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const currentTableConfig = defaultDrillDownTableConfigs.find(config => config.route === tableType)
|
||||
return list
|
||||
}
|
||||
*/
|
||||
export async function getUserDrilldownTableConfig (tableType, curMetric) {
|
||||
let list = []
|
||||
// 获取用户定制的自定义配置,如果没有,则使用默认的自定义配置
|
||||
const drillDownTableConfigs = await combinDrilldownTableWithUserConfig()
|
||||
const currentTableConfig = drillDownTableConfigs.find(config => config.route === tableType)
|
||||
const commonTabList = currentTableConfig ? currentTableConfig.tabs : []
|
||||
const tables = currentTableConfig ? currentTableConfig.tables : []
|
||||
if (tables && tables.length > 0) {
|
||||
const curTableOldConfig = tables.find(table => table.id === tableType)
|
||||
const curTable = curTableOldConfig || null
|
||||
if (curTable) {
|
||||
if (curTable.hasMetricSearch) { // 有metric
|
||||
const metricsList = curTable ? curTable.metrics : []
|
||||
if (metricsList && metricsList.length > 0) {
|
||||
const metricTab = metricsList.find(metric => metric.name === curMetric)
|
||||
list = metricTab ? metricTab.tabs : []
|
||||
}
|
||||
} else { // 无metric
|
||||
list = curTable ? curTable.tabs : []
|
||||
}
|
||||
list = curTable ? curTable.tabs : []
|
||||
combineTabList(tableType, list, commonTabList)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,12 @@ export function valueToRangeValue (value, unitType) {
|
||||
}
|
||||
break
|
||||
}
|
||||
case unitTypes.qps: {
|
||||
if (values[0] < 0.01) {
|
||||
return ['<0.01', 'qps']
|
||||
}
|
||||
break
|
||||
}
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,14 +150,14 @@ export default {
|
||||
if (panels && panels.length > 0) {
|
||||
this.panel = panels[0]
|
||||
}
|
||||
console.log(this.panel)
|
||||
// console.log(this.panel)
|
||||
if (this.panel.id) {
|
||||
if (this.panel.params) {
|
||||
this.panel.params = JSON.parse(this.panel.params)
|
||||
} else {
|
||||
this.panel.params = {}
|
||||
}
|
||||
console.log(this.panel)
|
||||
// console.log(this.panel)
|
||||
const allCharts = (await getChartList({ panelId: this.panel.id, pageSize: -1 })).map(chart => {
|
||||
chart.i = chart.id
|
||||
this.recursionParamsConvert(chart)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="activeTab !== 709 && activeTab !== 710" class="panel-chart__no-data">No data</div>
|
||||
<div v-if="activeTab !== 709 && activeTab !== 710" class="panel-chart__no-data">{{ $t('npm.noData') }}</div>
|
||||
<div v-else class="panel-chart__no-data all-clear">
|
||||
<div class="no-recent-alerts">
|
||||
<i class="el-icon-circle-check"></i>
|
||||
|
||||
@@ -474,10 +474,8 @@ export function stackedLineTooltipFormatter (params) {
|
||||
str += '<div class="cn-chart-tooltip">'
|
||||
params.forEach((item, i) => {
|
||||
str += '<span class="cn-chart-tooltip-box">'
|
||||
str += item.marker
|
||||
str += `<span class="cn-chart-tooltip-content">
|
||||
${item.seriesName}
|
||||
</span>`
|
||||
str += `<span style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:${item.borderColor};"></span>`
|
||||
str += `<span class="cn-chart-tooltip-content">${item.seriesName.split('(')[0]}</span>`
|
||||
str += '</span>'
|
||||
})
|
||||
str += '</div>'
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<network-overview-line
|
||||
v-if="chart.type === typeMapping.networkOverview.line"
|
||||
:chart="chart"
|
||||
:metric="metric"
|
||||
:time-filter="timeFilter"
|
||||
ref="networkLine"
|
||||
@toggleLoading="toggleLoading"
|
||||
@@ -23,6 +24,7 @@
|
||||
<network-overview-tabs
|
||||
v-else-if="chart.type === typeMapping.networkOverview.table"
|
||||
:time-filter="timeFilter"
|
||||
:metric="metric"
|
||||
:chart="chart"
|
||||
:ref="`tab${chart.id}`"
|
||||
@toggleLoading="toggleLoading"
|
||||
@@ -38,6 +40,7 @@
|
||||
<network-overview-apps
|
||||
v-else-if="chart.type === typeMapping.networkOverview.appList"
|
||||
:chart="chart"
|
||||
:metric="metric"
|
||||
:time-filter="timeFilter"
|
||||
@toggleLoading="toggleLoading"
|
||||
>
|
||||
@@ -188,8 +191,7 @@ import DnsEventChart from '@/views/charts2/charts/dnsInsight/DnsEventChart'
|
||||
import DnsRecentEvents from '@/views/charts2/charts/dnsInsight/DnsRecentEvents'
|
||||
import DnsTrafficLine from '@/views/charts2/charts/dnsInsight/DnsTrafficLine'
|
||||
|
||||
import { get } from '@/utils/http'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { getNowTime } from '@/utils/date-util'
|
||||
import { ref } from 'vue'
|
||||
import LinkDirectionGrid from '@/views/charts2/charts/linkMonitor/LinkDirectionGrid'
|
||||
export default {
|
||||
@@ -224,6 +226,7 @@ export default {
|
||||
},
|
||||
props: {
|
||||
chart: Object,
|
||||
metric: String,
|
||||
timeFilter: Object,
|
||||
extraParams: Object
|
||||
},
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
:col-num="24"
|
||||
:is-draggable="!panelLock"
|
||||
:is-resizable="!panelLock"
|
||||
:margin="[20, 20]"
|
||||
:row-height="40"
|
||||
:margin="[rowMargin, colMargin]"
|
||||
:row-height="rowHeight"
|
||||
:vertical-compact="true"
|
||||
:use-css-transforms="false"
|
||||
>
|
||||
@@ -21,6 +21,7 @@
|
||||
:key="item.i">
|
||||
<chart
|
||||
:time-filter="timeFilter"
|
||||
:metric="metric"
|
||||
:extra-params="extraParams"
|
||||
:id="item.id"
|
||||
ref="chartGrid"
|
||||
@@ -36,7 +37,7 @@
|
||||
import VueGridLayout from 'vue-grid-layout'
|
||||
import _ from 'lodash'
|
||||
import Chart from '@/views/charts2/Chart'
|
||||
import { panelTypeAndRouteMapping, storageKey, drillDownPanelTypeMapping } from '@/utils/constants'
|
||||
import { panelTypeAndRouteMapping, drillDownPanelTypeMapping } from '@/utils/constants'
|
||||
import { typeMapping } from '@/views/charts2/chart-tools'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
@@ -44,6 +45,7 @@ export default {
|
||||
name: 'ChartList',
|
||||
props: {
|
||||
timeFilter: Object,
|
||||
metric: String,
|
||||
panelType: Number,
|
||||
chartList: Array,
|
||||
panelLock: Boolean,
|
||||
@@ -54,7 +56,11 @@ export default {
|
||||
return {
|
||||
panelTypeAndRouteMapping,
|
||||
typeMapping,
|
||||
layout: []
|
||||
layout: [],
|
||||
rowHeight: 40,
|
||||
rowMargin: 20,
|
||||
colMargin: 20,
|
||||
debounceFunc: null
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -73,14 +79,16 @@ export default {
|
||||
watch: {
|
||||
chartList (n) {
|
||||
if (!_.isEmpty(n)) {
|
||||
let layout = []
|
||||
if (this.panelType === panelTypeAndRouteMapping.networkAppPerformance) {
|
||||
this.layout = n.filter(c => c.type === typeMapping.npm.npmTabs || c.params.tabIndex === this.npmTabIndex)
|
||||
layout = n.filter(c => c.type === typeMapping.npm.npmTabs || c.params.tabIndex === this.npmTabIndex)
|
||||
} else if (Object.values(drillDownPanelTypeMapping).indexOf(this.panelType) >= -1) {
|
||||
this.layout = n.filter(c => c.type === typeMapping.npm.npmTabs || c.params.tabIndex === this.npmTabIndex || !c.params.hasOwnProperty('tabIndex'))
|
||||
layout = n.filter(c => c.type === typeMapping.npm.npmTabs || c.params.tabIndex === this.npmTabIndex || !c.params.hasOwnProperty('tabIndex'))
|
||||
} else {
|
||||
this.layout = [...n]
|
||||
layout = [...n]
|
||||
}
|
||||
const overviewAppChart = n.find(c => c.type === typeMapping.networkOverview.appList)
|
||||
|
||||
/*const overviewAppChart = layout.find(c => c.type === typeMapping.networkOverview.appList)
|
||||
let actuallyLength = 0
|
||||
if (overviewAppChart) {
|
||||
const params = overviewAppChart.params.app ? overviewAppChart.params : { app: [] }
|
||||
@@ -90,6 +98,13 @@ export default {
|
||||
actuallyLength = params.app.find(p => p.user === 'default').list.length + 1
|
||||
}
|
||||
overviewAppChart.h = actuallyLength % 3 > 0 ? (Math.floor(actuallyLength / 3) + 1) * 2 + 2 : Math.floor(actuallyLength / 3) * 2 + 2
|
||||
}*/
|
||||
this.layout = layout
|
||||
const overviewAppChart = layout.find(c => c.type === typeMapping.networkOverview.appList)
|
||||
if (overviewAppChart) {
|
||||
this.$nextTick(() => {
|
||||
this.resizeAppChart()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -106,11 +121,27 @@ export default {
|
||||
},
|
||||
resizeLine () {
|
||||
this.$refs.chartGrid.resizeLine()
|
||||
},
|
||||
resizeAppChart () {
|
||||
const appCardsDom = document.querySelector('.app-cards')
|
||||
const layout = _.cloneDeep(this.layout)
|
||||
const overviewAppChart = layout.find(c => c.type === typeMapping.networkOverview.appList)
|
||||
if (appCardsDom) {
|
||||
const cardsHeight = appCardsDom.offsetHeight
|
||||
if (cardsHeight) {
|
||||
const headerHeight = 24
|
||||
overviewAppChart.h = (cardsHeight + headerHeight + this.rowMargin) / (this.rowHeight + this.rowMargin)
|
||||
this.layout = layout
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.debounceFunc = _.debounce(this.resizeAppChart, 400)
|
||||
window.addEventListener('resize', this.debounceFunc)
|
||||
},
|
||||
beforeUnmount () {
|
||||
window.removeEventListener('resize', this.debounceFunc)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -9,25 +9,42 @@
|
||||
Score:{{score}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel__time">
|
||||
<date-time-range
|
||||
class="date-time-range"
|
||||
:start-time="timeFilter.startTime"
|
||||
:end-time="timeFilter.endTime"
|
||||
:date-range="timeFilter.dateRangeValue"
|
||||
ref="dateTimeRange"
|
||||
@change="reload"
|
||||
/>
|
||||
<time-refresh
|
||||
class="date-time-range"
|
||||
@change="timeRefreshChange"
|
||||
:end-time="timeFilter.endTime"
|
||||
/>
|
||||
<div class="panel__tools">
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="metric"
|
||||
placeholder=""
|
||||
popper-class="common-select"
|
||||
v-if="panelType === panelTypeAndRouteMapping.networkOverview"
|
||||
:popper-append-to-body="false"
|
||||
@change="metricChange"
|
||||
>
|
||||
<template #prefix>
|
||||
<span class="select-prefix">Metric:</span>
|
||||
</template>
|
||||
<el-option v-for="item in metricOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
<div class="panel__time">
|
||||
<date-time-range
|
||||
class="date-time-range"
|
||||
:start-time="timeFilter.startTime"
|
||||
:end-time="timeFilter.endTime"
|
||||
:date-range="timeFilter.dateRangeValue"
|
||||
ref="dateTimeRange"
|
||||
@change="reload"
|
||||
/>
|
||||
<time-refresh
|
||||
class="date-time-range"
|
||||
@change="timeRefreshChange"
|
||||
:end-time="timeFilter.endTime"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<chart-list
|
||||
ref="chartList"
|
||||
:time-filter="timeFilter"
|
||||
:metric="metric"
|
||||
:chart-list="chartList"
|
||||
:panel-type="panelType"
|
||||
:panel-lock="panelLock"
|
||||
@@ -42,19 +59,16 @@ import { useRoute } from 'vue-router'
|
||||
import { ref } from 'vue'
|
||||
import {
|
||||
panelTypeAndRouteMapping,
|
||||
bytesColumnNameGroupForNpm,
|
||||
scoreUrl,
|
||||
customTableTitlesForAppPerformance,
|
||||
operationType,
|
||||
curTabState,
|
||||
drillDownPanelTypeMapping
|
||||
drillDownPanelTypeMapping,
|
||||
metricOptions
|
||||
} from '@/utils/constants'
|
||||
import { getPanelList, getChartList } from '@/utils/api'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { getTypeCategory } from '@/views/charts/charts/tools'
|
||||
import { computeScore, urlParamsHandler, overwriteUrl } from '@/utils/tools'
|
||||
import { urlParamsHandler, overwriteUrl,getDnsMapData } from '@/utils/tools'
|
||||
import ChartList from '@/views/charts2/ChartList'
|
||||
import { get } from '@/utils/http'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'Panel',
|
||||
@@ -67,10 +81,14 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
panelTypeAndRouteMapping,
|
||||
metricOptions,
|
||||
chartList: [], // 普通panel的chart
|
||||
panelLock: true,
|
||||
extraParams: {},
|
||||
panelName: '',
|
||||
dnsRcodeMapData: [],
|
||||
dnsQtypeMapData: [],
|
||||
score: null,
|
||||
curTabState: curTabState
|
||||
}
|
||||
@@ -91,7 +109,18 @@ export default {
|
||||
},
|
||||
async mounted () {
|
||||
// this.panelName = this.$store.getters.getPanelName
|
||||
this.panelName = this.$route.query.panelName ? this.$t(this.$route.query.panelName) : ''
|
||||
let pName = this.$route.query.panelName ? this.$t(this.$route.query.panelName) : ''
|
||||
let curTabProp = this.$route.query.dimensionType ? this.$route.query.dimensionType : null
|
||||
this.dnsQtypeMapData = await getDnsMapData('dnsQtype')
|
||||
this.dnsRcodeMapData = await getDnsMapData('dnsRcode')
|
||||
if(curTabProp === 'qtype'){
|
||||
this.panelName = this.dnsQtypeMapData.get(pName)
|
||||
}else if(curTabProp === 'rcode'){
|
||||
this.panelName = this.dnsRcodeMapData.get(pName)
|
||||
}else {
|
||||
this.panelName = pName
|
||||
}
|
||||
|
||||
// const curOperationType = this.$store.getters.getTabOperationType
|
||||
/* const curOperationType = this.getUrlParam(this.curTabState.tabOperationType, '', true)
|
||||
if (this.panelName && this.$route.path === '/panel/networkAppPerformance' && curOperationType !== operationType.thirdMenu) {
|
||||
@@ -156,9 +185,34 @@ export default {
|
||||
})
|
||||
},
|
||||
setup (props, ctx) {
|
||||
// todo 目前在panel页面测试,后续会挪到router里
|
||||
const store = useStore()
|
||||
const cancelList = store.state.panel.httpCancel
|
||||
|
||||
// 进入页面时,发现有未结束的请求,终止请求
|
||||
// console.log('panel.vue------setup------查看http终止情况', cancelList, cancelList.length)
|
||||
if (cancelList.length > 0) {
|
||||
cancelList.forEach((cancel, index) => {
|
||||
cancel()
|
||||
delete cancelList[index]
|
||||
})
|
||||
}
|
||||
|
||||
const panel = ref({})
|
||||
let panelType = 1 // 取得panel的type
|
||||
const { params, query } = useRoute()
|
||||
const { params, query, path } = useRoute()
|
||||
// 只要当前路由和vuex里的路由一致,且vuex存储的range有值,即代表已经下钻后返回,此时直接使用vuex里存储的时间范围
|
||||
if (path === store.getters.getRouterPath && store.getters.getTimeRangeFlag !== null) {
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
startTime: store.getters.getTimeRangeArray[0],
|
||||
endTime: store.getters.getTimeRangeArray[1],
|
||||
range: store.getters.getTimeRangeFlag
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
} else {
|
||||
store.commit('setTimeRangeArray', [])
|
||||
store.commit('setTimeRangeFlag', null)
|
||||
}
|
||||
const thirdPanel = query.thirdPanel
|
||||
const fourthPanel = query.fourthPanel
|
||||
if (fourthPanel) {
|
||||
@@ -187,15 +241,19 @@ export default {
|
||||
timeFilter.value.startTime = parseInt(startTimeParam)
|
||||
timeFilter.value.endTime = parseInt(endTimeParam)
|
||||
}
|
||||
store.commit('setRouterPath', path)
|
||||
|
||||
// npm是否展示分数
|
||||
const showScorePanel = [drillDownPanelTypeMapping.npmOverviewIp, drillDownPanelTypeMapping.npmOverviewDomain, drillDownPanelTypeMapping.npmOverviewApp, drillDownPanelTypeMapping.npmOverviewCommon, drillDownPanelTypeMapping.npmThirdMenu]
|
||||
const showScore = showScorePanel.indexOf(panelType) > -1
|
||||
|
||||
const metric = ref(query.metric || 'Bits/s')
|
||||
return {
|
||||
panelType,
|
||||
panel,
|
||||
timeFilter,
|
||||
showScore
|
||||
showScore,
|
||||
metric
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -233,6 +291,9 @@ export default {
|
||||
reload (startTime, endTime, dateRangeValue) {
|
||||
this.timeFilter = { startTime: getSecond(startTime), endTime: getSecond(endTime), dateRangeValue: dateRangeValue }
|
||||
const { query } = this.$route
|
||||
this.$store.commit('setTimeRangeArray', [this.timeFilter.startTime, this.timeFilter.endTime])
|
||||
this.$store.commit('setTimeRangeFlag', dateRangeValue.value)
|
||||
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
startTime: this.timeFilter.startTime,
|
||||
endTime: this.timeFilter.endTime,
|
||||
@@ -255,6 +316,13 @@ export default {
|
||||
} else {
|
||||
return this.$route.query[param] ? this.$route.query[param] : defaultValue
|
||||
}
|
||||
},
|
||||
metricChange (value) {
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
metric: value
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,9 +189,20 @@ export default {
|
||||
params.q = this.queryCondition
|
||||
}
|
||||
this.toggleLoading(true)
|
||||
get(api.dnsInsight.totalTrafficAnalysis, params).then((res) => {
|
||||
let url = api.dnsInsight.totalTrafficAnalysis
|
||||
if (this.queryCondition) {
|
||||
url = api.dnsInsight.drilldownTrafficAnalysis
|
||||
}
|
||||
get(url, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.mpackets = [
|
||||
{ analysis: {}, name: 'network.total', class: 'total', show: true, invertTab: true, positioning: 0, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.inbound', class: 'inbound', show: true, invertTab: true, positioning: 1, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.outbound', class: 'outbound', show: true, invertTab: true, positioning: 2, data: [], unitType: '' }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
@@ -201,10 +212,12 @@ export default {
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.inboundBitsRate.values ? t.inboundBitsRate.values : []
|
||||
mpackets[2].data = t.outboundBitsRate.values ? t.outboundBitsRate.values : []
|
||||
let num = 0
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'bps'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
num += 1
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && show !== this.lineRefer) {
|
||||
@@ -212,16 +225,26 @@ export default {
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 0) {
|
||||
if (e.analysis.avg <= 0) {
|
||||
this.lineTab = ''
|
||||
this.lineRefer = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
if (num === 3) {
|
||||
mpackets[0].invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(mpackets[0], 0)
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
}
|
||||
} else if (t.type === 'queries' && val === 'Queries/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalQueryRate.analysis
|
||||
@@ -231,13 +254,13 @@ export default {
|
||||
e.show = false
|
||||
}
|
||||
e.unitType = 'queries/s'
|
||||
if (show !== this.lineRefer) {
|
||||
this.legendSelectChange(e, 0)
|
||||
}
|
||||
e.invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(e, 0)
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
this.echartsInit(this.mpackets, true)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -346,6 +369,11 @@ export default {
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
this.mpackets.forEach(e => {
|
||||
if (this.$t(e.name) === t.seriesName) {
|
||||
t.borderColor = chartColor3[e.positioning]
|
||||
}
|
||||
})
|
||||
})
|
||||
const str = stackedLineTooltipFormatter(params)
|
||||
return str
|
||||
|
||||
@@ -223,7 +223,6 @@ export default {
|
||||
})
|
||||
this.linkData = sorted
|
||||
|
||||
// todo 此处去重不优美,后续再处理
|
||||
let directionArr = []
|
||||
nextHopData.forEach((item) => {
|
||||
if (item.egressLinkDirection !== '' && item.ingressLinkDirection !== '') {
|
||||
|
||||
@@ -236,17 +236,16 @@ export default {
|
||||
* 本地计算npm分数
|
||||
*/
|
||||
localComputeScore (data, bandwidth) {
|
||||
const keyPre = ['tcp', 'http', 'ssl', 'tcpLost', 'packetRetrans']
|
||||
let score = 0
|
||||
keyPre.forEach((item, index) => {
|
||||
score = computeScore(data, index)
|
||||
data[keyPre[index] + 'Score'] = score
|
||||
})
|
||||
let npmScore = Math.ceil((data.tcpScore + data.httpScore + data.sslScore + data.tcpLostScore + data.packetRetransScore) * 6)
|
||||
if (npmScore > 6) {
|
||||
npmScore = 6
|
||||
const dataScore = {
|
||||
establishLatencyMs: data.establishLatencyMs || null,
|
||||
httpResponseLatency: data.httpResponseLatency || null,
|
||||
sslConLatency: data.sslConLatency || null,
|
||||
tcpLostlenPercent: data.tcpLostlenPercent || null,
|
||||
pktRetransPercent: data.pktRetransPercent || null
|
||||
}
|
||||
return npmScore
|
||||
score = computeScore(dataScore)
|
||||
return score
|
||||
},
|
||||
/**
|
||||
* 计算popover弹窗和右侧数据模块的宽度
|
||||
|
||||
@@ -177,6 +177,13 @@ export default {
|
||||
get(api.linkMonitor.totalTrafficAnalysis, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.mpackets = [
|
||||
{ analysis: {}, name: 'network.total', class: 'total', show: true, invertTab: true, positioning: 0, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'linkMonitor.ingress', class: 'ingress', show: true, invertTab: true, positioning: 1, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'linkMonitor.egress', class: 'egress', show: true, invertTab: true, positioning: 2, data: [], unitType: '' }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
@@ -186,10 +193,12 @@ export default {
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.ingressBitsRate.values ? t.ingressBitsRate.values : []
|
||||
mpackets[2].data = t.egressBitsRate.values ? t.egressBitsRate.values : []
|
||||
let num = 0
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'bps'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
num += 1
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && !show) {
|
||||
@@ -197,16 +206,26 @@ export default {
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 1) {
|
||||
if (e.analysis.avg <= 0) {
|
||||
this.lineTab = ''
|
||||
this.lineRefer = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
if (num === 3) {
|
||||
mpackets[0].invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(mpackets[0], 0)
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
}
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalPacketsRate.analysis
|
||||
@@ -215,10 +234,12 @@ export default {
|
||||
mpackets[0].data = t.totalPacketsRate.values ? t.totalPacketsRate.values : []
|
||||
mpackets[1].data = t.ingressPacketsRate.values ? t.ingressPacketsRate.values : []
|
||||
mpackets[2].data = t.egressPacketsRate.values ? t.egressPacketsRate.values : []
|
||||
let num = 0
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'packets/s'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
num += 1
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && !show) {
|
||||
@@ -226,16 +247,26 @@ export default {
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 1) {
|
||||
if (e.analysis.avg <= 0) {
|
||||
this.lineTab = ''
|
||||
this.lineRefer = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
if (num === 3) {
|
||||
mpackets[0].invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(mpackets[0], 0)
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
} else {
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -291,12 +322,17 @@ export default {
|
||||
}
|
||||
])
|
||||
},
|
||||
data: t.data.map(v => [Number(v[0]) * 1000, Number(v[1]), 'number']),
|
||||
data: t.data.map(v => [Number(v[0]) * 1000, Number(v[1]), 'number'])
|
||||
}
|
||||
})
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
this.mpackets.forEach(e => {
|
||||
if (this.$t(e.name) === t.seriesName) {
|
||||
t.borderColor = chartColor3[e.positioning]
|
||||
}
|
||||
})
|
||||
})
|
||||
const str = stackedLineTooltipFormatter(params)
|
||||
return str
|
||||
|
||||
@@ -1,418 +0,0 @@
|
||||
<template>
|
||||
<div class="line network link-traffic">
|
||||
<loading :loading="loading"></loading>
|
||||
<div class="line-header">
|
||||
<div class="line-header-left">
|
||||
<div class="line-value-active" v-if="lineTab"></div>
|
||||
<div class="line-value">
|
||||
<div class="line-value-mpackets"
|
||||
v-show="item.show"
|
||||
:class=" {'is-active': lineTab === item.class, 'mousemove-cursor': mousemoveCursor === item.class}"
|
||||
v-for="(item, index) in mpackets"
|
||||
:key="index"
|
||||
@mouseenter="mouseenter(item)"
|
||||
@mouseleave="mouseleave(item)"
|
||||
@click="activeChange(item, index)">
|
||||
<div class="line-value-mpackets-name">
|
||||
<div :class="item.class"></div>
|
||||
<div class="mpackets-name">{{$t(item.name)}}</div>
|
||||
</div>
|
||||
<div class="line-value-unit">
|
||||
<span class="line-value-unit-number">{{unitConvert(item.analysis.avg, unitTypes.number)[0]}}</span>
|
||||
<span class="line-value-unit-number2">
|
||||
<span>{{unitConvert(item.analysis.avg, unitTypes.number)[1]}}</span><span v-if="item.unitType">{{item.unitType}}</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-select line-header-right">
|
||||
<div class="line-select-metric">
|
||||
<span>{{$t('network.metric')}}:</span>
|
||||
<div class="line-select__operation">
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="lineMetric"
|
||||
popper-class="common-select"
|
||||
:popper-append-to-body="false"
|
||||
@change="metricSelectChange"
|
||||
>
|
||||
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: calc(100% - 74px); position: relative">
|
||||
<chart-no-data v-if="isNoData"></chart-no-data>
|
||||
<div class="chart-drawing" v-show="showMarkLine && !isNoData" id="linkTrafficLineChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts'
|
||||
import { linkTrafficLineChartOption } from '@/views/charts2/charts/options/echartOption'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
import { unitTypes, chartColor3, chartColor4 } from '@/utils/constants.js'
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import { stackedLineTooltipFormatter } from '@/views/charts/charts/tools'
|
||||
import _ from 'lodash'
|
||||
import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import { getSecond } from '@/utils/date-util'
|
||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||
import chartMixin from '@/views/charts2/chart-mixin'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||
import Loading from '@/components/common/Loading'
|
||||
export default {
|
||||
name: 'linkTrafficDrillDownLine',
|
||||
components: {
|
||||
ChartNoData,
|
||||
Loading
|
||||
},
|
||||
setup () {
|
||||
const { query } = useRoute()
|
||||
const lineMetric = ref(query.lineMetric || 'Bits/s')
|
||||
const lineTab = ref(query.lineTab || '')
|
||||
const queryCondition = ref(query.queryCondition || '')
|
||||
return {
|
||||
lineMetric,
|
||||
lineTab,
|
||||
queryCondition,
|
||||
myChart: shallowRef(null)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
linkTrafficShow: Boolean,
|
||||
linkTrafficData: Array
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
data () {
|
||||
return {
|
||||
options1: [
|
||||
{
|
||||
value: 'Bits/s',
|
||||
label: 'Bits/s'
|
||||
},
|
||||
{
|
||||
value: 'Packets/s',
|
||||
label: 'Packets/s'
|
||||
}
|
||||
],
|
||||
mpackets: [
|
||||
{ analysis: {}, name: 'network.total', class: 'total', show: true, invertTab: true, positioning: 0, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'linkMonitor.ingress', class: 'ingress', show: true, invertTab: true, positioning: 1, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'linkMonitor.egress', class: 'egress', show: true, invertTab: true, positioning: 2, data: [], unitType: '' }
|
||||
],
|
||||
unitConvert,
|
||||
unitTypes,
|
||||
chartDateObject: [],
|
||||
timer: null,
|
||||
mousemoveCursor: '',
|
||||
leftOffset: 0,
|
||||
sizes: [3, 4, 6, 8, 9, 10],
|
||||
dynamicVariable: '',
|
||||
showMarkLine: true,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
lineTab (n) {
|
||||
this.$nextTick(() => {
|
||||
this.handleActiveBar(n)
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
lineTab: n
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
})
|
||||
},
|
||||
lineMetric (n) {
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
lineMetric: n
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
},
|
||||
timeFilter: {
|
||||
handler (n) {
|
||||
if (this.lineTab) {
|
||||
this.init(this.lineMetric, this.showMarkLine, 'active')
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init (val, show, active) {
|
||||
if (!val) {
|
||||
val = this.lineMetric
|
||||
}
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime)
|
||||
}
|
||||
if (this.queryCondition) {
|
||||
const condition = this.queryCondition.toLowerCase().split(' or ')
|
||||
if (condition.length > 1) {
|
||||
params.egressParam = condition.find(c => c.indexOf('common_egress_link_id') > -1 || c.indexOf('egress_link_direction') > -1)
|
||||
params.ingressParam = condition.find(c => c.indexOf('common_ingress_link_id') > -1 || c.indexOf('ingress_link_direction') > -1)
|
||||
}
|
||||
}
|
||||
this.loading = true
|
||||
get(api.linkMonitor.totalTrafficAnalysis, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalBitsRate.analysis
|
||||
mpackets[1].analysis = t.ingressBitsRate.analysis
|
||||
mpackets[2].analysis = t.egressBitsRate.analysis
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.ingressBitsRate.values ? t.ingressBitsRate.values : []
|
||||
mpackets[2].data = t.egressBitsRate.values ? t.egressBitsRate.values : []
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'bps'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && !show) {
|
||||
this.legendSelectChange(e, 'index')
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 0) {
|
||||
this.lineTab = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalPacketsRate.analysis
|
||||
mpackets[1].analysis = t.ingressPacketsRate.analysis
|
||||
mpackets[2].analysis = t.egressPacketsRate.analysis
|
||||
mpackets[0].data = t.totalPacketsRate.values ? t.totalPacketsRate.values : []
|
||||
mpackets[1].data = t.ingressPacketsRate.values ? t.ingressPacketsRate.values : []
|
||||
mpackets[2].data = t.egressPacketsRate.values ? t.egressPacketsRate.values : []
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'packets/s'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && !show) {
|
||||
this.legendSelectChange(e, 'index')
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 0) {
|
||||
this.lineTab = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
echartsInit (echartsData) {
|
||||
if (this.lineTab) {
|
||||
this.handleActiveBar()
|
||||
echartsData = echartsData.filter(t => t.show === true && t.invertTab === false)
|
||||
} else {
|
||||
echartsData = echartsData.filter(t => t.show === true)
|
||||
}
|
||||
const _this = this
|
||||
const dom = document.getElementById('linkTrafficLineChart')
|
||||
!this.myChart && (this.myChart = echarts.init(dom))
|
||||
this.chartOption = linkTrafficLineChartOption
|
||||
const chartOption = this.chartOption.series[0]
|
||||
this.chartOption.series = echartsData.map((t, i) => {
|
||||
return {
|
||||
...chartOption,
|
||||
name: t.name,
|
||||
lineStyle: {
|
||||
color: chartColor3[t.positioning],
|
||||
width: 1
|
||||
},
|
||||
stack: t.name !== 'network.total' ? 'network.total' : '',
|
||||
symbolSize: function (value, params) {
|
||||
return _this.symbolSizeSortChange(i, value[0])
|
||||
},
|
||||
itemStyle: {
|
||||
emphasis: {
|
||||
borderColor: chartColor4[t.positioning],
|
||||
borderWidth: 2,
|
||||
shadowColor: chartColor4[t.positioning],
|
||||
shadowBlur: this.sizes[t.positioning] + 2
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.1,
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: chartColor3[t.positioning]
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: chartColor3[t.positioning]
|
||||
}
|
||||
])
|
||||
},
|
||||
data: t.data.map(v => [Number(v[0]) * 1000, Number(v[1]), 'number']),
|
||||
}
|
||||
})
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
})
|
||||
const str = stackedLineTooltipFormatter(params)
|
||||
return str
|
||||
}
|
||||
this.showMarkLine = true
|
||||
this.myChart.setOption(this.chartOption)
|
||||
},
|
||||
activeChange (item, index) {
|
||||
this.lineTab = item.class
|
||||
this.legendSelectChange(item, index, 'active')
|
||||
this.showMarkLine = !item.invertTab
|
||||
this.init(this.lineMetric, this.showMarkLine, 'active')
|
||||
},
|
||||
mouseenter (item) {
|
||||
this.mousemoveCursor = item.class
|
||||
this.handleActiveBar(item.class)
|
||||
},
|
||||
mouseleave () {
|
||||
this.mousemoveCursor = ''
|
||||
},
|
||||
dispatchLegendSelectAction (name) {
|
||||
this.myChart && this.myChart.dispatchAction({
|
||||
type: 'legendSelect',
|
||||
name: name
|
||||
})
|
||||
},
|
||||
dispatchLegendUnSelectAction (name) {
|
||||
this.myChart && this.myChart.dispatchAction({
|
||||
type: 'legendUnSelect',
|
||||
name: name
|
||||
})
|
||||
},
|
||||
legendSelectChange (item, index, val) {
|
||||
if (index === 'index') {
|
||||
this.dispatchLegendSelectAction(item.name)
|
||||
} else if (this.mpackets[index] && this.mpackets[index].name === item.name) {
|
||||
this.dispatchLegendSelectAction(item.name)
|
||||
this.mpackets.forEach((t) => {
|
||||
if (t.name !== item.name) {
|
||||
this.dispatchLegendUnSelectAction(t.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (val === 'active') {
|
||||
this.mpackets.forEach(t => {
|
||||
if (item.name === t.name) {
|
||||
t.invertTab = !t.invertTab
|
||||
} else {
|
||||
t.invertTab = true
|
||||
}
|
||||
if (t.invertTab && item.name === t.name) {
|
||||
if (this.lineTab) {
|
||||
this.lineTab = ''
|
||||
} else {
|
||||
this.lineTab = t.class
|
||||
}
|
||||
this.mpackets.forEach((e) => {
|
||||
this.dispatchLegendSelectAction(e.name)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
handleActiveBar (value) {
|
||||
if (document.querySelector('.network .line-value-mpackets.is-active')) {
|
||||
const { offsetLeft, clientWidth, clientLeft } = document.querySelector('.network .line-value-mpackets.is-active')
|
||||
const activeBar = document.querySelector('.network .line-value-active')
|
||||
activeBar.style.cssText += `width: ${clientWidth}px; left: ${offsetLeft + this.leftOffset + clientLeft}px;`
|
||||
}
|
||||
},
|
||||
resize () {
|
||||
this.myChart.resize()
|
||||
},
|
||||
metricSelectChange (val) {
|
||||
this.lineMetric = val
|
||||
this.lineTab = ''
|
||||
this.handleActiveBar()
|
||||
this.showMarkLine = !this.showMarkLine
|
||||
this.mpackets.forEach((e, i) => {
|
||||
if (!e.invertTab) {
|
||||
e.invertTab = true
|
||||
}
|
||||
})
|
||||
this.init(val, this.showMarkLine)
|
||||
},
|
||||
symbolSizeSortChange (index, time) {
|
||||
const dataIntegrationArray = []
|
||||
if (linkTrafficLineChartOption.series[0]) {
|
||||
const totalData = linkTrafficLineChartOption.series[0].data.find(t => t[0] === time) // [time, value]
|
||||
if (totalData) {
|
||||
dataIntegrationArray.push(totalData)
|
||||
totalData[2] = 0
|
||||
}
|
||||
}
|
||||
if (linkTrafficLineChartOption.series[1]) {
|
||||
const ingressData = linkTrafficLineChartOption.series[1].data.find(t => t[0] === time)
|
||||
if (ingressData) {
|
||||
dataIntegrationArray.push(ingressData)
|
||||
ingressData[2] = 1
|
||||
}
|
||||
}
|
||||
if (linkTrafficLineChartOption.series[2]) {
|
||||
const egressData = linkTrafficLineChartOption.series[2].data.find(t => t[0] === time)
|
||||
if (egressData) {
|
||||
dataIntegrationArray.push(egressData)
|
||||
egressData[2] = 2
|
||||
}
|
||||
}
|
||||
dataIntegrationArray.sort((a, b) => { return a[1] - b[1] })
|
||||
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
||||
return this.sizes[sortIndex]
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lineTab) {
|
||||
const data = this.mpackets.find(t => t.class === this.lineTab)
|
||||
this.activeChange(data, data.positioning)
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
}, 200)
|
||||
window.addEventListener('resize', this.resize)
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearTimeout(this.timer)
|
||||
window.removeEventListener('resize', this.resize)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -3,11 +3,11 @@
|
||||
<loading :loading="loading"></loading>
|
||||
<div class="link-traffic-list-center">
|
||||
<div class="link-traffic-list-center-label">{{$t('network.total')}}</div>
|
||||
<div class="link-traffic-list-center-value">{{unitConvert(lineData[0].analysis.avg, unitTypes.bps).join('')}}</div>
|
||||
<div class="link-traffic-list-center-value" v-if="lineData[0] && lineData[0].analysis">{{unitConvert(lineData[0].analysis.avg, unitTypes.bps).join('')}}</div>
|
||||
</div>
|
||||
<div class="link-traffic-list-center">
|
||||
<div class="link-traffic-list-center-label">{{$t('linkMonitor.bandwidthUsage')}}</div>
|
||||
<div class="link-traffic-list-center-value" v-if="bandWidth">{{unitConvert(lineData[0].analysis.avg / bandWidth, unitTypes.percent).join('')}}</div>
|
||||
<div class="link-traffic-list-center-value" v-if="bandWidth && lineData[0] && lineData[0].analysis">{{unitConvert(lineData[0].analysis.avg / bandWidth, unitTypes.percent).join('')}}</div>
|
||||
<div class="link-traffic-list-center-value" v-else>-</div>
|
||||
</div>
|
||||
<div class="link-traffic-list-center">
|
||||
@@ -130,17 +130,15 @@ export default {
|
||||
get(api.linkMonitor.networkAnalysis, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
const dataArr = [0, 1, 2, 3, 4]
|
||||
let scoreAll = 0
|
||||
dataArr.forEach(e => {
|
||||
const score = computeScore(res.data.result[0], e)
|
||||
scoreAll += score
|
||||
})
|
||||
this.linkTrafficListData = res.data.result[0]
|
||||
this.linkTrafficListData.npmScore = Math.ceil(scoreAll * 6)
|
||||
if (this.linkTrafficListData.npmScore > 6) {
|
||||
this.linkTrafficListData.npmScore = 6
|
||||
const data = {
|
||||
establishLatencyMs: res.data.result[0].establishLatencyMs || null,
|
||||
httpResponseLatency: res.data.result[0].httpResponseLatency || null,
|
||||
sslConLatency: res.data.result[0].sslConLatency || null,
|
||||
tcpLostlenPercent: res.data.result[0].tcpLostlenPercent || null,
|
||||
pktRetransPercent: res.data.result[0].pktRetransPercent || null
|
||||
}
|
||||
this.linkTrafficListData = res.data.result[0]
|
||||
this.linkTrafficListData.npmScore = computeScore(data)
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
|
||||
@@ -1,30 +1,19 @@
|
||||
<template>
|
||||
<div class="network-overview-apps">
|
||||
<div class="line-select-metric">
|
||||
<span>{{$t('network.metric')}}:</span>
|
||||
<div class="line-select__operation">
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="metricFilter"
|
||||
placeholder=""
|
||||
popper-class="common-select"
|
||||
:popper-append-to-body="false"
|
||||
@change="metricChange"
|
||||
>
|
||||
<el-option v-for="item in metricOptions" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="network-overview-apps-header">
|
||||
<div class="network-overview-apps-title">{{$t('networkOverview.appType.providerAndApp')}}</div>
|
||||
</div>
|
||||
|
||||
<div class="app-cards">
|
||||
<div class="app-card" v-for="(app, index) in appData" :key="index">
|
||||
<div class="app-card" @mouseenter="mouseenter(app)" @mouseleave="mouseleave(app)" v-for="(app, index) in appData" :key="app.type + app.name">
|
||||
<div class="app-card-title">
|
||||
<div class="app-card-title-name">
|
||||
<i class="cn-icon" :class="app.type === 'provider' ? 'cn-icon-entity' : 'cn-icon-app2'"></i>
|
||||
<span @click="drillDownData(app.type, app.name)">{{app.name}}</span>
|
||||
</div>
|
||||
<div class="app-card-title-more" v-ele-click-outside="clickOutSide">
|
||||
<span><i class="cn-icon cn-icon-more-dark" @click="moreChange(app)"></i></span>
|
||||
<span class="app-card-title-more-delete" @click="del(app, index)" v-show="app.moreOptions"><i class="cn-icon cn-icon-delete"></i>{{$t('overall.delete')}}</span>
|
||||
<div class="app-card-title-more">
|
||||
<span v-show="app.showMore"><i class="cn-icon cn-icon-more-dark" @mouseenter="mouseenterMore(app)"></i></span>
|
||||
<span class="app-card-title-more-delete" @click="del(app, index)" v-show="app.moreOptions" @mouseleave="mouseleaveMore(app)"><i class="cn-icon cn-icon-delete"></i>{{$t('overall.delete')}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-card__bodys">
|
||||
@@ -44,12 +33,13 @@
|
||||
</span>
|
||||
<span v-else>>500.00%</span>
|
||||
</div>
|
||||
<div v-else-if="app.value === '-' || app.value === 0" class="app-card__body-content-percent">0</div>
|
||||
<div v-else-if="app.value === '-' || app.value === 0" class="app-card__body-content-percent">+0.00%</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-card__body-previous">
|
||||
<div>Total</div>
|
||||
<div>{{unitConvert(app.total, unitTypes.number).join(' ')}}</div>
|
||||
<div v-if="metric === 'Bits/s'">{{unitConvert(app.total, unitTypes.byte).join(' ')}}</div>
|
||||
<div v-else>{{unitConvert(app.total, unitTypes.number).join(' ')}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart__drawing" v-show="!isNoData" :id="`chart-${app.name}-${app.type}`"></div>
|
||||
@@ -77,7 +67,7 @@
|
||||
</div>
|
||||
<div class="add-app__body">
|
||||
<el-tabs v-model="appTypeTab" @tab-click="appTypeTabChange">
|
||||
<el-tab-pane :label="$t('networkOverview.appType.provider')" :name="0">
|
||||
<el-tab-pane :label="$t('network.providers')" :name="0">
|
||||
<div class="body__apps" :class="{'body__apps-no-grid': providerOptions.length === 0}">
|
||||
<loading :loading="loadingBody"></loading>
|
||||
<chart-no-data v-if="providerOptions.length === 0 && !loadingBody"></chart-no-data>
|
||||
@@ -127,7 +117,7 @@ import unitConvert from '@/utils/unit-convert'
|
||||
import { storageKey, unitTypes, networkTable, operationType, curTabState } from '@/utils/constants'
|
||||
import * as echarts from 'echarts'
|
||||
import { appListChartOption } from '@/views/charts2/charts/options/echartOption'
|
||||
import { ref, shallowRef } from 'vue'
|
||||
import { shallowRef } from 'vue'
|
||||
import { get, put } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import _ from 'lodash'
|
||||
@@ -137,7 +127,6 @@ import loading from '@/components/common/Loading'
|
||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||
import { appStackedLineTooltipFormatter } from '@/views/charts/charts/tools'
|
||||
import chartMixin from '@/views/charts2/chart-mixin'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
export default {
|
||||
name: 'NetworkOverviewApps',
|
||||
@@ -148,20 +137,6 @@ export default {
|
||||
mixins: [chartMixin],
|
||||
data () {
|
||||
return {
|
||||
metricOptions: [
|
||||
{
|
||||
value: 'Bits/s',
|
||||
label: 'Bits/s'
|
||||
},
|
||||
{
|
||||
value: 'Packets/s',
|
||||
label: 'Packets/s'
|
||||
},
|
||||
{
|
||||
value: 'Sessions/s',
|
||||
label: 'Sessions/s'
|
||||
}
|
||||
],
|
||||
appData: [],
|
||||
// 假数据
|
||||
appTempData: [],
|
||||
@@ -191,22 +166,18 @@ export default {
|
||||
urlChangeParams: {}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
metric: {
|
||||
type: String,
|
||||
default: 'Bits/s'
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
const { query } = useRoute()
|
||||
const metricFilter = ref(query.appListMetric || 'Bits/s')
|
||||
return {
|
||||
metricFilter,
|
||||
myChart: shallowRef([])
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
metricFilter (n) {
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
appListMetric: n
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
},
|
||||
showAddApp: {
|
||||
deep: true,
|
||||
handler (n) {
|
||||
@@ -218,10 +189,11 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
timeFilter: {
|
||||
handler (n) {
|
||||
this.init()
|
||||
}
|
||||
timeFilter (n) {
|
||||
this.init()
|
||||
},
|
||||
metric (n) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -273,13 +245,21 @@ export default {
|
||||
this.toggleLoading(true)
|
||||
Promise.all([prevRequest, request]).then(res => {
|
||||
this.isNoData = (res[0].data.result.length && res[1].data.result.length) === 0
|
||||
if (this.isNoData) {
|
||||
this.appData = this.appData.map(t => {
|
||||
return {
|
||||
name: t.name,
|
||||
type: t.type
|
||||
}
|
||||
})
|
||||
}
|
||||
if (res[0].code === 200 && res[1].code === 200) {
|
||||
const prevData = res[0].data.result
|
||||
const data = res[1].data.result
|
||||
let toCompareType = 'bytes'
|
||||
if (this.metricFilter === 'Sessions/s') {
|
||||
if (this.metric === 'Sessions/s') {
|
||||
toCompareType = 'sessions'
|
||||
} else if (this.metricFilter === 'Packets/s') {
|
||||
} else if (this.metric === 'Packets/s') {
|
||||
toCompareType = 'packets'
|
||||
}
|
||||
data.forEach(d => {
|
||||
@@ -463,7 +443,6 @@ export default {
|
||||
},
|
||||
addApp (pageNo, val, show) {
|
||||
this.showAddApp = true
|
||||
const letter = 'abcdefghijklmnopqrstuvwxyz'
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
@@ -482,7 +461,7 @@ export default {
|
||||
} else {
|
||||
params.pageNo = 1
|
||||
}
|
||||
if (this.appTypeTab == 0) {
|
||||
if (parseFloat(this.appTypeTab) === 0) {
|
||||
params.type = 'overviewProvide'
|
||||
get(api.dict, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
@@ -507,7 +486,7 @@ export default {
|
||||
this.loading = false
|
||||
this.loadingBody = false
|
||||
})
|
||||
} else if (this.appTypeTab == 1) {
|
||||
} else if (parseFloat(this.appTypeTab) === 1) {
|
||||
params.type = 'overviewApp'
|
||||
get(api.dict, params).then(res => {
|
||||
res.data.list = res.data.list.filter(l => !this.appData.some(pd => pd.type === 'app' && pd.name === l.value))
|
||||
@@ -547,7 +526,7 @@ export default {
|
||||
cancelApp () {
|
||||
this.showAddApp = false
|
||||
},
|
||||
appTypeTabChange (val) {
|
||||
appTypeTabChange () {
|
||||
this.pageObj.pageNo = 1
|
||||
this.searcherApp = ''
|
||||
this.addApp()
|
||||
@@ -690,17 +669,46 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
moreChange (app) {
|
||||
this.appData.forEach(t => {
|
||||
if (t.name === app.name && t.type === app.type) {
|
||||
t.moreOptions = !t.moreOptions
|
||||
}
|
||||
})
|
||||
},
|
||||
// moreChange (app) {
|
||||
// this.appData.forEach(t => {
|
||||
// if (t.name === app.name && t.type === app.type) {
|
||||
// t.moreOptions = !t.moreOptions
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
resize () {
|
||||
this.myChart.forEach(t => {
|
||||
t.resize()
|
||||
})
|
||||
},
|
||||
mouseenterMore (app) {
|
||||
this.appData.forEach(t => {
|
||||
if (t.name === app.name && t.type === app.type) {
|
||||
t.moreOptions = true
|
||||
}
|
||||
})
|
||||
},
|
||||
mouseleaveMore (app) {
|
||||
this.appData.forEach(t => {
|
||||
if (t.name === app.name && t.type === app.type) {
|
||||
t.moreOptions = false
|
||||
}
|
||||
})
|
||||
},
|
||||
mouseenter (app) {
|
||||
this.appData.forEach(t => {
|
||||
if (t.name === app.name && t.type === app.type) {
|
||||
t.showMore = true
|
||||
}
|
||||
})
|
||||
},
|
||||
mouseleave (app) {
|
||||
this.appData.forEach(t => {
|
||||
if (t.name === app.name && t.type === app.type) {
|
||||
t.showMore = false
|
||||
t.moreOptions = false
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
|
||||
@@ -26,20 +26,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-select line-header-right">
|
||||
<div class="line-select-metric">
|
||||
<span>{{$t('network.metric')}}:</span>
|
||||
<div class="line-select__operation">
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="lineMetric"
|
||||
popper-class="common-select"
|
||||
:popper-append-to-body="false"
|
||||
@change="metricSelectChange"
|
||||
>
|
||||
<el-option v-for="item in options1" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line-select-reference-line">
|
||||
<span>{{$t('network.referenceLine')}}:</span>
|
||||
<div class="line-select__operation">
|
||||
@@ -84,37 +70,31 @@ export default {
|
||||
components: {
|
||||
ChartNoData
|
||||
},
|
||||
props: {
|
||||
metric: {
|
||||
type: String,
|
||||
default: 'Bits/s'
|
||||
}
|
||||
},
|
||||
setup () {
|
||||
const { query } = useRoute()
|
||||
const lineMetric = ref(query.lineMetric || 'Bits/s')
|
||||
const lineRefer = ref(query.lineRefer || 'Average')
|
||||
const lineTab = ref(query.lineTab || '')
|
||||
const queryCondition = ref(query.queryCondition || '')
|
||||
const tabOperationType = ref(query.tabOperationType)
|
||||
const networkOverviewBeforeTab = ref(query.networkOverviewBeforeTab)
|
||||
return {
|
||||
lineMetric,
|
||||
lineRefer,
|
||||
lineTab,
|
||||
queryCondition,
|
||||
tabOperationType,
|
||||
networkOverviewBeforeTab,
|
||||
myChart: shallowRef(null)
|
||||
}
|
||||
},
|
||||
mixins: [chartMixin],
|
||||
data () {
|
||||
return {
|
||||
options1: [
|
||||
{
|
||||
value: 'Bits/s',
|
||||
label: 'Bits/s'
|
||||
},
|
||||
{
|
||||
value: 'Packets/s',
|
||||
label: 'Packets/s'
|
||||
},
|
||||
{
|
||||
value: 'Sessions/s',
|
||||
label: 'Sessions/s'
|
||||
}
|
||||
],
|
||||
options2: [
|
||||
{
|
||||
value: 'Average',
|
||||
@@ -159,13 +139,6 @@ export default {
|
||||
overwriteUrl(newUrl)
|
||||
})
|
||||
},
|
||||
lineMetric (n) {
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
lineMetric: n
|
||||
})
|
||||
overwriteUrl(newUrl)
|
||||
},
|
||||
lineRefer (n) {
|
||||
const { query } = this.$route
|
||||
const newUrl = urlParamsHandler(window.location.href, query, {
|
||||
@@ -176,31 +149,63 @@ export default {
|
||||
timeFilter: {
|
||||
handler (n) {
|
||||
if (this.lineTab) {
|
||||
this.init(this.lineMetric, this.showMarkLine, 'active')
|
||||
this.init(this.metric, this.showMarkLine, 'active')
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
metric (n) {
|
||||
this.handleActiveBar()
|
||||
this.showMarkLine = !this.showMarkLine
|
||||
this.mpackets.forEach((e, i) => {
|
||||
if (!e.invertTab) {
|
||||
e.invertTab = true
|
||||
}
|
||||
})
|
||||
this.init(n, this.showMarkLine, '', n)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init (val, show, active) {
|
||||
init (val, show, active, n) {
|
||||
if (!val) {
|
||||
val = this.lineMetric
|
||||
val = this.metric
|
||||
}
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime)
|
||||
}
|
||||
// const condition = this.$store.getters.getQueryCondition
|
||||
// const condition = this.$route.query.queryCondition ? this.$route.query.queryCondition : ''
|
||||
if (this.queryCondition) {
|
||||
let condition = ''
|
||||
if (this.queryCondition && this.tabOperationType !== '3') {
|
||||
params.q = this.queryCondition
|
||||
} else if (this.tabOperationType == '3' && this.queryCondition) {
|
||||
if (this.queryCondition.indexOf(' OR ') > -1) {
|
||||
if (this.networkOverviewBeforeTab === 'isp') {
|
||||
condition = this.queryCondition.split(/["|'= ](.*?)["|'= ]/)
|
||||
params.q = `notEmpty(${condition[0]}) OR notEmpty(${condition[9]})`
|
||||
} else {
|
||||
condition = this.queryCondition.split(/["|'= ](.*?)["|'= ]/)
|
||||
params.q = `notEmpty(${condition[0]}) OR notEmpty(${condition[5]})`
|
||||
}
|
||||
} else {
|
||||
condition = this.queryCondition.split(/['=](.*?)['=]/)
|
||||
params.q = `notEmpty(${condition[0]})`
|
||||
}
|
||||
}
|
||||
this.toggleLoading(true)
|
||||
get(api.netWorkOverview.totalTrafficAnalysis, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.mpackets = [
|
||||
{ analysis: {}, name: 'network.total', class: 'total', show: true, invertTab: true, positioning: 0, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.inbound', class: 'inbound', show: true, invertTab: true, positioning: 1, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.outbound', class: 'outbound', show: true, invertTab: true, positioning: 2, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.internal', class: 'internal', show: true, invertTab: true, positioning: 3, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.through', class: 'through', show: true, invertTab: true, positioning: 4, data: [], unitType: '' },
|
||||
{ analysis: {}, name: 'network.other', class: 'other', show: true, invertTab: true, positioning: 5, data: [], unitType: '' }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
@@ -216,10 +221,12 @@ export default {
|
||||
mpackets[3].data = t.internalBitsRate.values ? t.internalBitsRate.values : []
|
||||
mpackets[4].data = t.throughBitsRate.values ? t.throughBitsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
let num = 0
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'bps'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
num += 1
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && show !== this.lineRefer) {
|
||||
@@ -227,16 +234,27 @@ export default {
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 0) {
|
||||
if (e.analysis.avg <= 0) {
|
||||
this.lineTab = ''
|
||||
this.lineRefer = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
if (num === 5) {
|
||||
mpackets[0].invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(mpackets[0], 0)
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, true)
|
||||
})
|
||||
} else {
|
||||
if (n) this.lineTab = ''
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
}
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalPacketsRate.analysis
|
||||
@@ -251,10 +269,12 @@ export default {
|
||||
mpackets[3].data = t.internalPacketsRate.values ? t.internalPacketsRate.values : []
|
||||
mpackets[4].data = t.throughPacketsRate.values ? t.throughPacketsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
let num = 0
|
||||
mpackets.forEach(e => {
|
||||
e.unitType = 'packets/s'
|
||||
if (e.name !== 'network.total' && e.analysis.avg == 0) {
|
||||
e.show = false
|
||||
num += 1
|
||||
} else {
|
||||
e.show = true
|
||||
if (!active && show !== this.lineRefer) {
|
||||
@@ -262,16 +282,27 @@ export default {
|
||||
}
|
||||
}
|
||||
if (this.lineTab === e.class) {
|
||||
if (e.analysis.avg < 0) {
|
||||
if (e.analysis.avg <= 0) {
|
||||
this.lineTab = ''
|
||||
this.lineRefer = ''
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
if (num === 5) {
|
||||
mpackets[0].invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(mpackets[0], 0)
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, true)
|
||||
})
|
||||
} else {
|
||||
if (n) this.lineTab = ''
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
})
|
||||
}
|
||||
} else if (t.type === 'sessions' && val === 'Sessions/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].analysis = t.totalSessionsRate.analysis
|
||||
@@ -281,13 +312,13 @@ export default {
|
||||
e.show = false
|
||||
}
|
||||
e.unitType = 'sessions/s'
|
||||
if (show !== this.lineRefer) {
|
||||
this.legendSelectChange(e, 0)
|
||||
}
|
||||
e.invertTab = false
|
||||
this.lineTab = 'total'
|
||||
this.legendSelectChange(e, 0)
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.$nextTick(() => {
|
||||
this.echartsInit(this.mpackets, show)
|
||||
this.echartsInit(this.mpackets, true)
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -396,6 +427,11 @@ export default {
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
this.mpackets.forEach(e => {
|
||||
if (this.$t(e.name) === t.seriesName) {
|
||||
t.borderColor = chartColor3[e.positioning]
|
||||
}
|
||||
})
|
||||
})
|
||||
const str = stackedLineTooltipFormatter(params)
|
||||
return str
|
||||
@@ -407,7 +443,7 @@ export default {
|
||||
this.lineTab = item.class
|
||||
this.legendSelectChange(item, index, 'active')
|
||||
this.showMarkLine = !item.invertTab
|
||||
this.init(this.lineMetric, this.showMarkLine, 'active')
|
||||
this.init(this.metric, this.showMarkLine, 'active')
|
||||
},
|
||||
mouseenter (item) {
|
||||
this.mousemoveCursor = item.class
|
||||
@@ -469,18 +505,6 @@ export default {
|
||||
resize () {
|
||||
this.myChart.resize()
|
||||
},
|
||||
metricSelectChange (val) {
|
||||
this.lineMetric = val
|
||||
this.lineTab = ''
|
||||
this.handleActiveBar()
|
||||
this.showMarkLine = !this.showMarkLine
|
||||
this.mpackets.forEach((e, i) => {
|
||||
if (!e.invertTab) {
|
||||
e.invertTab = true
|
||||
}
|
||||
})
|
||||
this.init(val, this.showMarkLine)
|
||||
},
|
||||
referenceSelectChange (val) {
|
||||
this.lineRefer = val
|
||||
this.echartsInit(this.mpackets, this.showMarkLine)
|
||||
@@ -538,7 +562,9 @@ export default {
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lineTab) {
|
||||
const data = this.mpackets.find(t => t.class === this.lineTab)
|
||||
this.activeChange(data, data.positioning)
|
||||
if (data && data.positioning) {
|
||||
this.activeChange(data, data.positioning)
|
||||
}
|
||||
} else {
|
||||
this.init()
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div class="chart-drawing" id="chart2" v-show="!isNoData2"></div>
|
||||
</div>
|
||||
</div>
|
||||
<el-button class="pie-button" size="small">{{$t('network.dashboards')}}<i class="cn-icon cn-icon-arrow-right"></i></el-button>
|
||||
<el-button class="pie-button" size="small" @click="routerJump">{{$t('network.dashboards')}}<i class="cn-icon cn-icon-arrow-right"></i></el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -125,6 +125,15 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
routerJump () {
|
||||
this.$router.push({
|
||||
path: '/panel/networkAppPerformance',
|
||||
query: {
|
||||
tabIndex: 2,
|
||||
t: +new Date()
|
||||
}
|
||||
})
|
||||
},
|
||||
resize () {
|
||||
this.myChart.resize()
|
||||
this.myChart2.resize()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -134,7 +134,14 @@ import unitConvert from '@/utils/unit-convert'
|
||||
import { api } from '@/utils/api'
|
||||
import { getSecond } from '@/utils/date-util'
|
||||
import { get } from '@/utils/http'
|
||||
import { getChainRatio, computeScore, changeCurTab, urlParamsHandler, overwriteUrl, getUserDrilldownTableConfig } from '@/utils/tools'
|
||||
import {
|
||||
getChainRatio,
|
||||
computeScore,
|
||||
changeCurTab,
|
||||
urlParamsHandler,
|
||||
overwriteUrl,
|
||||
getUserDrilldownTableConfig
|
||||
} from '@/utils/tools'
|
||||
import chartMixin from '@/views/charts2/chart-mixin'
|
||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||
export default {
|
||||
@@ -220,24 +227,20 @@ export default {
|
||||
res.forEach((r, i) => {
|
||||
if (r.code === 200) {
|
||||
tableData.forEach(t => {
|
||||
let score = 0
|
||||
const find = r.data.result.find(d => d.appSubcategory === t.appSubcategory)
|
||||
if (find) {
|
||||
score = computeScore(find, i)
|
||||
}
|
||||
t[keyPre[i] + 'Score'] = score
|
||||
})
|
||||
} else {
|
||||
tableData.forEach(t => {
|
||||
t[keyPre[i] + 'Score'] = 0
|
||||
t[keyPre[i] + 'Score'] = find
|
||||
})
|
||||
}
|
||||
})
|
||||
tableData.forEach(t => {
|
||||
t.score = Math.ceil((t.tcpScore + t.httpScore + t.sslScore + t.tcpLostScore + t.packetRetransScore) * 6)
|
||||
if (t.score > 6) {
|
||||
t.score = 6
|
||||
const data = {
|
||||
establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null,
|
||||
httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null,
|
||||
sslConLatency: t.sslScore ? t.sslScore.sslConLatency : null,
|
||||
tcpLostlenPercent: t.tcpLostScore ? t.tcpLostScore.tcpLostlenPercent : null,
|
||||
pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null
|
||||
}
|
||||
t.score = computeScore(data)
|
||||
})
|
||||
this.tableData = tableData
|
||||
}).finally(() => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="cn-chart__map-title" v-if="tabIndex == 1">{{$t('npm.clientLocation')}}</div>
|
||||
<div class="cn-chart__map" :class="{'cn-chart__map-drilldown': tabIndex == 1}">
|
||||
<div class="cn-chart__map-title" v-if="queryCondition">{{$t('npm.clientLocation')}}</div>
|
||||
<div class="cn-chart__map" :class="{'cn-chart__map-drilldown': queryCondition}">
|
||||
<div class="map-canvas" id="npmDrillDownMap"></div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,8 +22,10 @@ export default {
|
||||
setup () {
|
||||
const { query } = useRoute()
|
||||
const tabIndex = ref(query.tabIndex || '')
|
||||
const queryCondition = ref(query.queryCondition || '')
|
||||
return {
|
||||
tabIndex
|
||||
tabIndex,
|
||||
queryCondition
|
||||
}
|
||||
},
|
||||
data () {
|
||||
@@ -105,24 +107,20 @@ export default {
|
||||
res2.forEach((r, i) => {
|
||||
if (r.code === 200) {
|
||||
mapData.forEach(t => {
|
||||
let score = 0
|
||||
const find = r.data.result.find(d => d.country === t.country)
|
||||
if (find) {
|
||||
score = computeScore(find, i)
|
||||
}
|
||||
t[keyPre[i] + 'Score'] = score
|
||||
})
|
||||
} else {
|
||||
mapData.forEach(t => {
|
||||
t[keyPre[i] + 'Score'] = 0
|
||||
t[keyPre[i] + 'Score'] = find
|
||||
})
|
||||
}
|
||||
})
|
||||
mapData.forEach(t => {
|
||||
t.score = Math.ceil((t.tcpScore + t.httpScore + t.sslScore + t.tcpLostScore + t.packetRetransScore) * 6)
|
||||
if (t.score > 6) {
|
||||
t.score = 6
|
||||
const data = {
|
||||
establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null,
|
||||
httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null,
|
||||
sslConLatency: t.sslScore ? t.sslScore.sslConLatency : null,
|
||||
tcpLostlenPercent: t.tcpLostScore ? t.tcpLostScore.tcpLostlenPercent : null,
|
||||
pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null
|
||||
}
|
||||
t.score = computeScore(data)
|
||||
})
|
||||
this.loadMarkerData(imageSeries, mapData)
|
||||
})
|
||||
|
||||
@@ -14,23 +14,23 @@
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
<template v-else-if="chartData.id === 12">
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}</div>
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}(ms)</div>
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
<template v-else-if="chartData.id === 13">
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}</div>
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}(ms)</div>
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
<template v-else-if="chartData.id === 14">
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}</div>
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}(ms)</div>
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
<template v-else-if="chartData.id === 15">
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}</div>
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}(%)</div>
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
<template v-else-if="chartData.id === 16">
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}</div>
|
||||
<div class="npm-line-title">{{$t(chartData.i18n) || chartData.name}}(%)</div>
|
||||
<div v-show="!isNoData" class="chart-drawing" :id="`chart${chartData.name}`"></div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -47,6 +47,7 @@ import { get } from '@/utils/http'
|
||||
import { api } from '@/utils/api'
|
||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||
import chartMixin from '@/views/charts2/chart-mixin'
|
||||
import unitConvert from '@/utils/unit-convert'
|
||||
|
||||
export default {
|
||||
name: 'NpmLine',
|
||||
@@ -131,11 +132,11 @@ export default {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.chart.params.index === 0) {
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'totalBytesRate') {
|
||||
if (t.type === 'totalBitsRate') {
|
||||
this.chartOptionLineData[i].values = t.values
|
||||
} else if (t.type === 'inboundBytesRate') {
|
||||
} else if (t.type === 'inboundBitsRate') {
|
||||
this.chartOptionLineData[i].values = t.values
|
||||
} else if (t.type === 'outboundBytesRate') {
|
||||
} else if (t.type === 'outboundBitsRate') {
|
||||
this.chartOptionLineData[i].values = t.values
|
||||
}
|
||||
})
|
||||
@@ -177,9 +178,24 @@ export default {
|
||||
data: t.values.map((v) => [Number(v[0]) * 1000, Number(v[1]), type])
|
||||
}
|
||||
})
|
||||
this.chartOption.yAxis[0].axisLabel.formatter = (value) => {
|
||||
if (type === 'percent') {
|
||||
return unitConvert(value, type)[0]
|
||||
} else {
|
||||
return unitConvert(value, 'number').join('')
|
||||
}
|
||||
}
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
this.chartOptionLineData.forEach(e => {
|
||||
if (this.$t(e.legend) === t.seriesName) {
|
||||
t.borderColor = e.color
|
||||
}
|
||||
if (this.$t(chartData.i18n) === t.seriesName) {
|
||||
t.borderColor = t.color
|
||||
}
|
||||
})
|
||||
})
|
||||
return stackedLineTooltipFormatter(params)
|
||||
}
|
||||
|
||||
@@ -129,23 +129,22 @@ export default {
|
||||
res2.forEach((r, i) => {
|
||||
if (r.code === 200) {
|
||||
mapData.forEach(t => {
|
||||
let score = 0
|
||||
const find = r.data.result.find(d => d.country === t.country)
|
||||
if (find) {
|
||||
score = computeScore(find, i)
|
||||
}
|
||||
t[keyPre[i] + 'Score'] = score
|
||||
})
|
||||
} else {
|
||||
mapData.forEach(t => {
|
||||
t[keyPre[i] + 'Score'] = 0
|
||||
t[keyPre[i] + 'Score'] = find
|
||||
})
|
||||
}
|
||||
})
|
||||
mapData.forEach(t => {
|
||||
t.score = Math.ceil((t.tcpScore + t.httpScore + t.sslScore + t.tcpLostScore + t.packetRetransScore) * 6)
|
||||
if (t.score > 6) {
|
||||
t.score = 6
|
||||
const data = {
|
||||
establishLatencyMs: t.tcpScore ? t.tcpScore.establishLatencyMs : null,
|
||||
httpResponseLatency: t.httpScore ? t.httpScore.httpResponseLatency : null,
|
||||
sslConLatency: t.sslScore ? t.sslScore.sslConLatency : null,
|
||||
tcpLostlenPercent: t.tcpLostScore ? t.tcpLostScore.tcpLostlenPercent : null,
|
||||
pktRetransPercent: t.packetRetransScore ? t.packetRetransScore.pktRetransPercent : null
|
||||
}
|
||||
t.score = computeScore(data)
|
||||
if (t.score === '-') {
|
||||
t.score = ''
|
||||
}
|
||||
})
|
||||
this.loadMarkerData(imageSeries, mapData)
|
||||
|
||||
@@ -98,43 +98,20 @@ export default {
|
||||
if (type && condition) {
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.networkAnalysis, params).then(res => {
|
||||
const keyPre = ['tcp', 'http', 'ssl', 'tcpLost', 'packetRetrans']
|
||||
const scoreInfo = {}
|
||||
let index = 0
|
||||
let score = 0
|
||||
if (res.code === 200) {
|
||||
if (res.data.result.establishLatencyMsAvg || res.data.result.establishLatencyMsAvg === 0) {
|
||||
res.data.result.establishLatencyMs = res.data.result.establishLatencyMsAvg
|
||||
index = 0
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(res.data.result, index)
|
||||
}
|
||||
if (res.data.result.httpResponseLatencyAvg || res.data.result.httpResponseLatencyAvg === 0) {
|
||||
res.data.result.httpResponseLatency = res.data.result.httpResponseLatencyAvg
|
||||
index = 1
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(res.data.result, index)
|
||||
}
|
||||
if (res.data.result.tcpLostlenPercentAvg || res.data.result.tcpLostlenPercentAvg === 0) {
|
||||
res.data.result.tcpLostlenPercent = res.data.result.tcpLostlenPercentAvg
|
||||
index = 3
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(res.data.result, index)
|
||||
}
|
||||
if (res.data.result.pktRetransPercentAvg || res.data.result.pktRetransPercentAvg === 0) {
|
||||
res.data.result.pktRetransPercent = res.data.result.pktRetransPercentAvg
|
||||
index = 4
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(res.data.result, index)
|
||||
}
|
||||
if (res.data.result.sslConLatencyAvg || res.data.result.sslConLatencyAvg === 0) {
|
||||
res.data.result.sslConLatency = res.data.result.sslConLatencyAvg
|
||||
index = 2
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(res.data.result, index)
|
||||
const data = {
|
||||
establishLatencyMs: res.data.result.establishLatencyMsAvg || null,
|
||||
httpResponseLatency: res.data.result.httpResponseLatencyAvg || null,
|
||||
sslConLatency: res.data.result.sslConLatencyAvg || null,
|
||||
tcpLostlenPercent: res.data.result.tcpLostlenPercentAvg || null,
|
||||
pktRetransPercent: res.data.result.pktRetransPercentAvg || null
|
||||
}
|
||||
score = computeScore(data)
|
||||
this.npmNetworkCycleData = res.data.result
|
||||
this.npmNetworkLastCycleQuery()
|
||||
}
|
||||
scoreInfo.score = Math.ceil((scoreInfo.tcpScore + scoreInfo.httpScore + scoreInfo.sslScore + scoreInfo.tcpLostScore + scoreInfo.packetRetransScore) * 6)
|
||||
if (scoreInfo.score > 6) {
|
||||
scoreInfo.score = 6
|
||||
}
|
||||
this.$store.commit('setNpmThirdLevelMenuScore', scoreInfo.score)
|
||||
this.$store.commit('setNpmThirdLevelMenuScore', score)
|
||||
}).catch(e => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
@@ -147,40 +124,21 @@ export default {
|
||||
this.toggleLoading(true)
|
||||
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
|
||||
this.npmNetworkCycleData = []
|
||||
const keyPre = ['tcp', 'http', 'ssl', 'tcpLost', 'packetRetrans']
|
||||
const scoreInfo = {}
|
||||
let index = 0
|
||||
let score = 0
|
||||
res.forEach(t => {
|
||||
if (t.code === 200) {
|
||||
if (t.data.result.establishLatencyMsAvg || t.data.result.establishLatencyMsAvg === 0) {
|
||||
t.data.result.establishLatencyMs = t.data.result.establishLatencyMsAvg
|
||||
index = 0
|
||||
}
|
||||
if (t.data.result.httpResponseLatencyAvg || t.data.result.httpResponseLatencyAvg === 0) {
|
||||
t.data.result.httpResponseLatency = t.data.result.httpResponseLatencyAvg
|
||||
index = 1
|
||||
}
|
||||
if (t.data.result.tcpLostlenPercentAvg || t.data.result.tcpLostlenPercentAvg === 0) {
|
||||
t.data.result.tcpLostlenPercent = t.data.result.tcpLostlenPercentAvg
|
||||
index = 3
|
||||
}
|
||||
if (t.data.result.pktRetransPercentAvg || t.data.result.pktRetransPercentAvg === 0) {
|
||||
t.data.result.pktRetransPercent = t.data.result.pktRetransPercentAvg
|
||||
index = 4
|
||||
}
|
||||
if (t.data.result.sslConLatencyAvg || t.data.result.sslConLatencyAvg === 0) {
|
||||
t.data.result.sslConLatency = t.data.result.sslConLatencyAvg
|
||||
index = 2
|
||||
}
|
||||
scoreInfo[keyPre[index] + 'Score'] = computeScore(t.data.result, index)
|
||||
this.npmNetworkCycleData.push(t.data.result)
|
||||
const data = {
|
||||
establishLatencyMs: t.data.result.establishLatencyMsAvg,
|
||||
httpResponseLatency: t.data.result.httpResponseLatencyAvg,
|
||||
sslConLatency: t.data.result.sslConLatencyAvg,
|
||||
tcpLostlenPercent: t.data.result.tcpLostlenPercentAvg,
|
||||
pktRetransPercent: t.data.result.pktRetransPercentAvg
|
||||
}
|
||||
score = computeScore(data)
|
||||
}
|
||||
})
|
||||
scoreInfo.score = Math.ceil((scoreInfo.tcpScore + scoreInfo.httpScore + scoreInfo.sslScore + scoreInfo.tcpLostScore + scoreInfo.packetRetransScore) * 6)
|
||||
if (scoreInfo.score > 6) {
|
||||
scoreInfo.score = 6
|
||||
}
|
||||
this.$store.commit('setNpmThirdLevelMenuScore', scoreInfo.score)
|
||||
this.$store.commit('setNpmThirdLevelMenuScore', score)
|
||||
this.npmNetworkLastCycleQuery()
|
||||
}).catch(e => {
|
||||
this.toggleLoading(false)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="npm-traffic-line">
|
||||
<div class="npm-traffic-line-header">
|
||||
<div class="npm-traffic-line-title">{{$t('overall.traffic')}}</div>
|
||||
<div class="npm-traffic-line-title"></div>
|
||||
<div class="line-select-metric">
|
||||
<span>{{$t('network.metric')}}:</span>
|
||||
<div class="line-select__operation">
|
||||
@@ -64,19 +64,19 @@ export default {
|
||||
unitTypes,
|
||||
side: '',
|
||||
mpackets: [
|
||||
{ name: 'network.total', show: true, positioning: 0, data: [], unitType: '' },
|
||||
{ name: 'network.inbound', show: true, positioning: 1, data: [], unitType: '' },
|
||||
{ name: 'network.outbound', show: true, positioning: 2, data: [], unitType: '' },
|
||||
{ name: 'network.internal', show: true, positioning: 3, data: [], unitType: '' },
|
||||
{ name: 'network.through', show: true, positioning: 4, data: [], unitType: '' },
|
||||
{ name: 'network.other', show: true, positioning: 5, data: [], unitType: '' }
|
||||
{ name: 'network.total', show: true, positioning: 0, data: [], unitType: 'number' },
|
||||
{ name: 'network.inbound', show: true, positioning: 1, data: [], unitType: 'number' },
|
||||
{ name: 'network.outbound', show: true, positioning: 2, data: [], unitType: 'number' },
|
||||
{ name: 'network.internal', show: true, positioning: 3, data: [], unitType: 'number' },
|
||||
{ name: 'network.through', show: true, positioning: 4, data: [], unitType: 'number' },
|
||||
{ name: 'network.other', show: true, positioning: 5, data: [], unitType: 'number' }
|
||||
],
|
||||
npmQuantity: [
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: '' },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: '' },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: '' },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: '' },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: '' }
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
||||
],
|
||||
chartData: {},
|
||||
metricOptions: [
|
||||
@@ -150,8 +150,10 @@ export default {
|
||||
}
|
||||
const params = {
|
||||
startTime: getSecond(this.timeFilter.startTime),
|
||||
endTime: getSecond(this.timeFilter.endTime),
|
||||
type: type
|
||||
endTime: getSecond(this.timeFilter.endTime)
|
||||
}
|
||||
if (type) {
|
||||
params.type = type
|
||||
}
|
||||
if (condition && (typeof condition !== 'object') && type) {
|
||||
params.q = condition
|
||||
@@ -167,129 +169,346 @@ export default {
|
||||
}
|
||||
}
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.trafficGraph, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.inboundBitsRate.values ? t.inboundBitsRate.values : []
|
||||
mpackets[2].data = t.outboundBitsRate.values ? t.outboundBitsRate.values : []
|
||||
mpackets[3].data = t.internalBitsRate.values ? t.internalBitsRate.values : []
|
||||
mpackets[4].data = t.throughBitsRate.values ? t.throughBitsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalPacketsRate.values ? t.totalPacketsRate.values : []
|
||||
mpackets[1].data = t.inboundPacketsRate.values ? t.inboundPacketsRate.values : []
|
||||
mpackets[2].data = t.outboundPacketsRate.values ? t.outboundPacketsRate.values : []
|
||||
mpackets[3].data = t.internalPacketsRate.values ? t.internalPacketsRate.values : []
|
||||
mpackets[4].data = t.throughPacketsRate.values ? t.throughPacketsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'sessions' && val === 'Sessions/s') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[0].data = t.sessionsRate.values ? t.sessionsRate.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
} else if (t.type === 'establishLatencyMs' && val === 'establishLatencyMs') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[0].data = t.establishLatencyMsAvg.values ? t.establishLatencyMsAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
} else if (t.type === 'httpResponseLatency' && val === 'httpResponseLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[1].data = t.httpResponseLatencyAvg.values ? t.httpResponseLatencyAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
console.log(e)
|
||||
if (i !== 1) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
} else if (t.type === 'sslConLatency' && val === 'sslConLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[2].data = t.sslConLatencyAvg.values ? t.sslConLatencyAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 2) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
} else if (t.type === 'tcpLostlenPercent' && val === 'tcpLostlenPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[3].data = t.tcpLostlenPercentAvg.values ? t.tcpLostlenPercentAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 3) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
} else if (t.type === 'pktRetransPercent' && val === 'pktRetransPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[4].data = t.pktRetransPercentAvg.values ? t.pktRetransPercentAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 4) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity)
|
||||
if (params.type && params.q) {
|
||||
get(api.npm.overview.trafficGraph, params).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.mpackets = [
|
||||
{ name: 'network.total', show: true, positioning: 0, data: [], unitType: 'number' },
|
||||
{ name: 'network.inbound', show: true, positioning: 1, data: [], unitType: 'number' },
|
||||
{ name: 'network.outbound', show: true, positioning: 2, data: [], unitType: 'number' },
|
||||
{ name: 'network.internal', show: true, positioning: 3, data: [], unitType: 'number' },
|
||||
{ name: 'network.through', show: true, positioning: 4, data: [], unitType: 'number' },
|
||||
{ name: 'network.other', show: true, positioning: 5, data: [], unitType: 'number' }
|
||||
]
|
||||
this.npmQuantity = [
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
||||
]
|
||||
}
|
||||
})
|
||||
} else {
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.inboundBitsRate.values ? t.inboundBitsRate.values : []
|
||||
mpackets[2].data = t.outboundBitsRate.values ? t.outboundBitsRate.values : []
|
||||
mpackets[3].data = t.internalBitsRate.values ? t.internalBitsRate.values : []
|
||||
mpackets[4].data = t.throughBitsRate.values ? t.throughBitsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalPacketsRate.values ? t.totalPacketsRate.values : []
|
||||
mpackets[1].data = t.inboundPacketsRate.values ? t.inboundPacketsRate.values : []
|
||||
mpackets[2].data = t.outboundPacketsRate.values ? t.outboundPacketsRate.values : []
|
||||
mpackets[3].data = t.internalPacketsRate.values ? t.internalPacketsRate.values : []
|
||||
mpackets[4].data = t.throughPacketsRate.values ? t.throughPacketsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'sessions' && val === 'Sessions/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalSessionsRate.values ? t.totalSessionsRate.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'establishLatencyMs' && val === 'establishLatencyMs') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[0].data = t.establishLatencyMsAvg.values ? t.establishLatencyMsAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
} else if (t.type === 'httpResponseLatency' && val === 'httpResponseLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[1].data = t.httpResponseLatencyAvg.values ? t.httpResponseLatencyAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 1) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
} else if (t.type === 'sslConLatency' && val === 'sslConLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[2].data = t.sslConLatencyAvg.values ? t.sslConLatencyAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 2) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
} else if (t.type === 'tcpLostlenPercent' && val === 'tcpLostlenPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[3].data = t.tcpLostlenPercentAvg.values ? t.tcpLostlenPercentAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 3) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(%)')
|
||||
} else if (t.type === 'pktRetransPercent' && val === 'pktRetransPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[4].data = t.pktRetransPercentAvg.values ? t.pktRetransPercentAvg.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 4) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(%)')
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.isNoData = true
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
} else {
|
||||
if (val === 'Bits/s' || val === 'Packets/s' || val === 'Sessions/s') {
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.totalTrafficAnalysis, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.mpackets = [
|
||||
{ name: 'network.total', show: true, positioning: 0, data: [], unitType: 'number' },
|
||||
{ name: 'network.inbound', show: true, positioning: 1, data: [], unitType: 'number' },
|
||||
{ name: 'network.outbound', show: true, positioning: 2, data: [], unitType: 'number' },
|
||||
{ name: 'network.internal', show: true, positioning: 3, data: [], unitType: 'number' },
|
||||
{ name: 'network.through', show: true, positioning: 4, data: [], unitType: 'number' },
|
||||
{ name: 'network.other', show: true, positioning: 5, data: [], unitType: 'number' }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalBitsRate.values ? t.totalBitsRate.values : []
|
||||
mpackets[1].data = t.inboundBitsRate.values ? t.inboundBitsRate.values : []
|
||||
mpackets[2].data = t.outboundBitsRate.values ? t.outboundBitsRate.values : []
|
||||
mpackets[3].data = t.internalBitsRate.values ? t.internalBitsRate.values : []
|
||||
mpackets[4].data = t.throughBitsRate.values ? t.throughBitsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalPacketsRate.values ? t.totalPacketsRate.values : []
|
||||
mpackets[1].data = t.inboundPacketsRate.values ? t.inboundPacketsRate.values : []
|
||||
mpackets[2].data = t.outboundPacketsRate.values ? t.outboundPacketsRate.values : []
|
||||
mpackets[3].data = t.internalPacketsRate.values ? t.internalPacketsRate.values : []
|
||||
mpackets[4].data = t.throughPacketsRate.values ? t.throughPacketsRate.values : []
|
||||
mpackets[5].data = t.other.values ? t.other.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
e.show = true
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
} else if (t.type === 'sessions' && val === 'Sessions/s') {
|
||||
const mpackets = _.cloneDeep(this.mpackets)
|
||||
mpackets[0].data = t.totalSessionsRate.values ? t.totalSessionsRate.values : []
|
||||
mpackets.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
}
|
||||
})
|
||||
this.mpackets = mpackets
|
||||
this.echartsInit(this.mpackets)
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
} else if (val === 'establishLatencyMs' || val === 'tcpLostlenPercent' || val === 'pktRetransPercent') {
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.totalNetworkAnalysis, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.npmQuantity = [
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach((t, i) => {
|
||||
if (t.type === 'establishLatencyMs' && val === 'establishLatencyMs') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[0].data = t.establishLatencyMs.values ? t.establishLatencyMs.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 0) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
} else if (t.type === 'tcpLostlenPercent' && val === 'tcpLostlenPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[3].data = t.tcpLostlenPercent.values ? t.tcpLostlenPercent.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 3) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(%)')
|
||||
} else if (t.type === 'pktRetransPercent' && val === 'pktRetransPercent') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[4].data = t.pktRetransPercent.values ? t.pktRetransPercent.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 4) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(%)')
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
} else if (val === 'httpResponseLatency') {
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.totalHttpResponseDelay, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.npmQuantity = [
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach(t => {
|
||||
if (t.type === 'httpResponseLatency' && val === 'httpResponseLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[1].data = t.httpResponseLatency.values ? t.httpResponseLatency.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 1) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
} else if (val === 'sslConLatency') {
|
||||
this.toggleLoading(true)
|
||||
get(api.npm.overview.totalSslConDelay, params).then(res => {
|
||||
if (res.code === 200) {
|
||||
this.isNoData = res.data.result.length === 0
|
||||
if (this.isNoData) {
|
||||
this.npmQuantity = [
|
||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
||||
]
|
||||
}
|
||||
res.data.result.forEach(t => {
|
||||
if (t.type === 'sslConLatency' && val === 'sslConLatency') {
|
||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||
npmQuantity[2].data = t.sslConLatency.values ? t.sslConLatency.values : []
|
||||
npmQuantity.forEach((e, i) => {
|
||||
if (i !== 2) {
|
||||
e.show = false
|
||||
} else {
|
||||
e.show = true
|
||||
}
|
||||
})
|
||||
this.npmQuantity = npmQuantity
|
||||
this.echartsInit(this.npmQuantity, '(ms)')
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
}
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
this.isNoData = true
|
||||
}).finally(() => {
|
||||
this.toggleLoading(false)
|
||||
})
|
||||
}
|
||||
},
|
||||
echartsInit (echartsData) {
|
||||
echartsInit (echartsData, legendUnit) {
|
||||
echartsData = echartsData.filter(t => t.show === true)
|
||||
const dom = document.getElementById('chart')
|
||||
!this.myChart && (this.myChart = echarts.init(dom))
|
||||
this.chartOption = trafficLineChartOption
|
||||
const chartOption = this.chartOption.series[0]
|
||||
this.chartOption.series = echartsData.map((t, i) => {
|
||||
this.chartOption.yAxis[0].axisLabel.formatter = (value) => {
|
||||
if (t.unitType === 'percent') {
|
||||
return unitConvert(value, t.unitType)[0]
|
||||
} else if (t.unitType === 'time') {
|
||||
return unitConvert(value, 'number').join('')
|
||||
} else {
|
||||
return unitConvert(value, t.unitType).join('')
|
||||
}
|
||||
}
|
||||
return {
|
||||
...chartOption,
|
||||
name: this.$t(t.name),
|
||||
name: this.$t(t.name) + (legendUnit || ''),
|
||||
lineStyle: {
|
||||
color: chartColor3[t.positioning],
|
||||
width: 1
|
||||
@@ -308,12 +527,26 @@ export default {
|
||||
}
|
||||
])
|
||||
},
|
||||
data: t.data.map(v => [Number(v[0]) * 1000, Number(v[1]), 'number'])
|
||||
data: t.data.map(v => [Number(v[0]) * 1000, Number(v[1]), t.unitType])
|
||||
}
|
||||
})
|
||||
this.chartOption.tooltip.formatter = (params) => {
|
||||
params.forEach(t => {
|
||||
t.seriesName = this.$t(t.seriesName)
|
||||
this.mpackets.forEach(e => {
|
||||
if (this.$t(e.name) === t.seriesName) {
|
||||
t.borderColor = chartColor3[e.positioning]
|
||||
}
|
||||
})
|
||||
this.npmQuantity.forEach(d => {
|
||||
const nameMs = this.$t(d.name) + '(ms)'
|
||||
const namePrent = this.$t(d.name) + '(%)'
|
||||
if (nameMs === t.seriesName) {
|
||||
t.borderColor = chartColor3[d.positioning]
|
||||
} else if (namePrent === t.seriesName) {
|
||||
t.borderColor = chartColor3[d.positioning]
|
||||
}
|
||||
})
|
||||
})
|
||||
const str = stackedLineTooltipFormatter(params)
|
||||
return str
|
||||
|
||||
@@ -345,9 +345,9 @@ export const npmLineChartOption = {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: function (value) {
|
||||
return unitConvert(value, unitTypes.number).join('')
|
||||
}
|
||||
// formatter: function (value) {
|
||||
// return unitConvert(value, unitTypes.number).join('')
|
||||
// }
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -384,7 +384,6 @@ export const trafficLineChartOption = {
|
||||
padding: [0, 0, 0, 2],
|
||||
fontSize: 12,
|
||||
color: '#717171',
|
||||
fontWeight: 400,
|
||||
fontFamily: 'NotoSansSChineseRegular'
|
||||
}
|
||||
},
|
||||
@@ -416,9 +415,9 @@ export const trafficLineChartOption = {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
formatter: function (value) {
|
||||
return unitConvert(value, unitTypes.number).join('')
|
||||
}
|
||||
// formatter: function (value) {
|
||||
// return unitConvert(value, unitTypes.number).join('')
|
||||
// }
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -143,7 +143,6 @@ import { api } from '@/utils/api'
|
||||
import { getNowTime, getSecond } from '@/utils/date-util'
|
||||
import { ref } from 'vue'
|
||||
import _ from 'lodash'
|
||||
import Pagination from '@/components/common/Pagination'
|
||||
import Loading from '@/components/common/Loading'
|
||||
|
||||
export default {
|
||||
@@ -154,8 +153,7 @@ export default {
|
||||
DateTimeRange,
|
||||
TimeRefresh,
|
||||
EntityFilter,
|
||||
EntityList,
|
||||
Pagination
|
||||
EntityList
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
@@ -345,7 +343,9 @@ export default {
|
||||
loadingIpActive: false,
|
||||
|
||||
// 实体详情列表页面 左侧筛选条件
|
||||
loadingLeft: false
|
||||
loadingLeft: false,
|
||||
initFlag: false, // 初始化标志,避免初始化时pageSize和pageNo会调用搜索
|
||||
timer: null // 初始化标志的延时器,需要销毁
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -463,16 +463,36 @@ export default {
|
||||
this.queryFilter({ entityType: 'dns', ...this.timeFilter })
|
||||
this.queryList({ ...this.pageObj, ...this.timeFilter })
|
||||
this.queryListTotal({ ...this.timeFilter })
|
||||
|
||||
// todo 当前页面选择其他值,重刷界面仍会被重置,后续记得添加上
|
||||
// 延时一秒,避免初始化时pageSize为20,pageNo为1也会调用“搜索”的情况
|
||||
if (!this.initFlag) {
|
||||
this.timer = setTimeout(() => {
|
||||
this.initFlag = true
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
},
|
||||
pageSize (val) {
|
||||
this.pageObj.pageSize = val
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
if (this.initFlag) {
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
} else {
|
||||
if (val !== 20) {
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
}
|
||||
}
|
||||
},
|
||||
pageNo (val) {
|
||||
this.pageObj.pageNo = val
|
||||
this.pageObj.resetPageNo = false
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
if (this.initFlag) {
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
} else {
|
||||
if (val !== 1) {
|
||||
this.search({ metaList: this.metaList, q: this.q })
|
||||
}
|
||||
}
|
||||
},
|
||||
// 点击上一页箭头
|
||||
prev () {
|
||||
@@ -703,6 +723,9 @@ export default {
|
||||
return {
|
||||
timeFilter
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user