Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53c24fe51b | ||
|
|
2aa7f6edfb | ||
|
|
6ed9c4f5fe | ||
|
|
6f8631f947 | ||
|
|
63ab36f4d2 | ||
|
|
cccc1f0e6a | ||
|
|
4651709529 | ||
|
|
6ab98be4c8 | ||
|
|
7b96f979a4 | ||
|
|
a59bff2cb7 | ||
|
|
04651581fe | ||
|
|
84ca05dccc | ||
|
|
780de66ddf | ||
|
|
9205d7645d | ||
|
|
ec486fe930 | ||
|
|
12c31b5bf6 | ||
|
|
96591cb9ef | ||
|
|
949a8e9d86 | ||
|
|
3604783570 | ||
|
|
f60a6bd778 | ||
|
|
5ece1b6c8e | ||
|
|
86c2c8364d | ||
|
|
1f130a6ac8 | ||
|
|
c8af5fd5a1 | ||
|
|
48b7493b2e | ||
|
|
98ba09b586 | ||
|
|
7d85d332df | ||
|
|
6ee5ea6f6e | ||
|
|
6756812c34 | ||
|
|
d2aa5c9b7a | ||
|
|
049d5f92b4 | ||
|
|
7ce190f3c7 | ||
|
|
e9edd9cf05 | ||
|
|
4655eed55f | ||
|
|
cf625c196e | ||
|
|
55fdd3f0e4 | ||
|
|
8aa96da577 | ||
|
|
22bf16a01d | ||
|
|
04e186e7d8 | ||
|
|
38006bd964 | ||
|
|
05677d5fb6 | ||
|
|
156979e79e | ||
|
|
0f2fcbe9e6 | ||
|
|
089887f05b | ||
|
|
c83f64706f | ||
|
|
c82d33fa39 | ||
|
|
eed1d398d8 | ||
|
|
a8643b8543 | ||
|
|
bd1eeec770 | ||
|
|
8cb3f00aa4 | ||
|
|
4fed5a9b8c | ||
|
|
d54054510b | ||
|
|
27bd8260d2 | ||
|
|
29916f8517 | ||
|
|
2bac72eb5d | ||
|
|
dfcc03f11a | ||
|
|
a608ac72f6 | ||
|
|
b5d897608c | ||
|
|
431821154e | ||
|
|
9f488adcb9 | ||
|
|
a31c408327 | ||
|
|
d84483c0dc | ||
|
|
4804748564 |
@@ -29,7 +29,7 @@ generate_git-log:
|
|||||||
- public/index.html
|
- public/index.html
|
||||||
- public/git-log.html
|
- public/git-log.html
|
||||||
only:
|
only:
|
||||||
- dev
|
- 6suo
|
||||||
tags:
|
tags:
|
||||||
- galaxy
|
- galaxy
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ build_project:
|
|||||||
- echo "npm run build"
|
- echo "npm run build"
|
||||||
- cnpm run build
|
- cnpm run build
|
||||||
only:
|
only:
|
||||||
- dev
|
- 6suo
|
||||||
- tags
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- galaxy
|
- galaxy
|
||||||
@@ -51,14 +51,14 @@ build_image:
|
|||||||
stage: build_image
|
stage: build_image
|
||||||
script:
|
script:
|
||||||
- echo "docker build"
|
- echo "docker build"
|
||||||
- sudo docker build --no-cache -t cn-ui:$CNUI_TAG .
|
- sudo docker build --no-cache -t cn-ui-$CI_COMMIT_REF_NAME:$CNUI_TAG .
|
||||||
- echo "docker tag"
|
- echo "docker tag"
|
||||||
- sudo docker tag cn-ui:$CNUI_TAG 192.168.40.153:9080/cyber-narrator/cn-ui:$CNUI_TAG
|
- sudo docker tag cn-ui-$CI_COMMIT_REF_NAME:$CNUI_TAG 192.168.40.153:9080/cyber-narrator/cn-ui-$CI_COMMIT_REF_NAME:$CNUI_TAG
|
||||||
- echo "docker push"
|
- echo "docker push"
|
||||||
- sudo docker push 192.168.40.153:9080/cyber-narrator/cn-ui:$CNUI_TAG
|
- sudo docker push 192.168.40.153:9080/cyber-narrator/cn-ui-$CI_COMMIT_REF_NAME:$CNUI_TAG
|
||||||
when: on_success
|
when: on_success
|
||||||
only:
|
only:
|
||||||
- dev
|
- 6suo
|
||||||
tags:
|
tags:
|
||||||
- galaxy
|
- galaxy
|
||||||
|
|
||||||
@@ -71,11 +71,11 @@ build_release_image:
|
|||||||
- echo '提交的版本是'
|
- echo '提交的版本是'
|
||||||
- echo $CI_COMMIT_REF_NAME
|
- echo $CI_COMMIT_REF_NAME
|
||||||
- echo "docker build"
|
- echo "docker build"
|
||||||
- sudo docker build --no-cache -t cn-ui:$CI_COMMIT_TAG .
|
- sudo docker build --no-cache -t cn-ui-$CI_COMMIT_REF_NAME:$CI_COMMIT_TAG .
|
||||||
- echo "docker tag"
|
- echo "docker tag"
|
||||||
- sudo docker tag cn-ui:$CI_COMMIT_TAG 192.168.40.153:9080/cyber-narrator/cn-ui:$CI_COMMIT_TAG
|
- sudo docker tag cn-ui-$CI_COMMIT_REF_NAME:$CI_COMMIT_TAG 192.168.40.153:9080/cyber-narrator/cn-ui-$CI_COMMIT_REF_NAME:$CI_COMMIT_TAG
|
||||||
- echo "docker push"
|
- echo "docker push"
|
||||||
- sudo docker push 192.168.40.153:9080/cyber-narrator/cn-ui:$CI_COMMIT_TAG
|
- sudo docker push 192.168.40.153:9080/cyber-narrator/cn-ui-$CI_COMMIT_REF_NAME:$CI_COMMIT_TAG
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ module.exports = {
|
|||||||
'<rootDir>/test/**/__tests__/**/*.{vue,js,jsx,ts,tsx}',
|
'<rootDir>/test/**/__tests__/**/*.{vue,js,jsx,ts,tsx}',
|
||||||
'<rootDir>/test/**/*.{spec,test}.{vue,js,jsx,ts,tsx}'
|
'<rootDir>/test/**/*.{spec,test}.{vue,js,jsx,ts,tsx}'
|
||||||
],
|
],
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/test/init.js'],
|
||||||
|
verbose: true,
|
||||||
testEnvironment: 'jsdom',
|
testEnvironment: 'jsdom',
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.(vue)$': '<rootDir>/node_modules/vue-jest',
|
'^.+\\.(vue)$': '<rootDir>/node_modules/vue-jest',
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
"@vue/cli-service": "~4.5.0",
|
"@vue/cli-service": "~4.5.0",
|
||||||
"@vue/compiler-sfc": "^3.0.0",
|
"@vue/compiler-sfc": "^3.0.0",
|
||||||
"@vue/component-compiler-utils": "^3.2.0",
|
"@vue/component-compiler-utils": "^3.2.0",
|
||||||
"@vue/test-utils": "^2.0.0-rc.18",
|
"@vue/test-utils": "^2.2.7",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"babel-jest": "^26.0.0",
|
"babel-jest": "^26.0.0",
|
||||||
"compression-webpack-plugin": "^8.0.1",
|
"compression-webpack-plugin": "^8.0.1",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
var BASE_CONFIG = {
|
var BASE_CONFIG = {
|
||||||
baseUrl: 'http://192.168.44.54:8090/',
|
baseUrl: 'http://192.168.44.54:8093/',
|
||||||
version: '2.0.2021.05.11.19.43'
|
version: '23.02.08',
|
||||||
|
logUrl: 'http://192.168.44.114:8088/superset/explore/?r=12&standalone=1'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>images/logo.svg">
|
<link rel="icon" href="<%= BASE_URL %>images/logo.svg">
|
||||||
<script src="config.js"></script>
|
<script src="config.js"></script>
|
||||||
<title>Cyber Narrator</title>
|
<title>域名解析服务监测系统</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="theme-light">
|
<body class="theme-light">
|
||||||
<noscript>
|
<noscript>
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="logins">
|
<div class="logins">
|
||||||
<div class="inside">
|
<div class="inside">
|
||||||
<div class="title">
|
<div class="title">域名解析服务监测系统</div>
|
||||||
<img src="../public/images/logo-title.svg" />
|
|
||||||
</div>
|
|
||||||
<el-form class="login__box">
|
<el-form class="login__box">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-input
|
<el-input
|
||||||
@@ -193,12 +191,12 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-top: 65px;
|
margin-top: 90px;
|
||||||
|
padding: 0 70px;
|
||||||
|
color: white;
|
||||||
|
font-size: 40px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.title > img {
|
|
||||||
height: 135px;
|
|
||||||
}
|
|
||||||
.login__box {
|
.login__box {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|||||||
107
src/Test.vue
107
src/Test.vue
@@ -1,27 +1,120 @@
|
|||||||
<template>
|
<template>
|
||||||
<span data-test="count">{{count}}</span>
|
<span test-id="count">{{count}}</span>
|
||||||
<button data-test="button" @click="click">click</button>
|
<span test-id="id">{{obj.id}}</span>
|
||||||
|
<span test-id="title">{{obj.title}}</span>
|
||||||
|
<button test-id="button" @click="click">click</button>
|
||||||
|
<span test-id="tab">{{lineTab}}</span>
|
||||||
|
<el-table
|
||||||
|
:data="tableData"
|
||||||
|
class="test-table"
|
||||||
|
height="100%"
|
||||||
|
empty-text=" "
|
||||||
|
>
|
||||||
|
<template v-for="(item, index) in tableTitles" :key="index">
|
||||||
|
<el-table-column>
|
||||||
|
<template #default="scope" :column="item">
|
||||||
|
<span :test-id="`${item.prop}${scope.$index}`">{{scope.row[item.prop]}}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</template>
|
||||||
|
</el-table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* vue-jest的测试示例 */
|
/* vue-jest的测试示例 */
|
||||||
import VueRouter from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import indexedDBUtils from '@/indexedDB'
|
||||||
export default {
|
export default {
|
||||||
name: 'Test',
|
name: 'Test',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
count: 0
|
count: 0,
|
||||||
|
obj: { id: 1, title: 'title' },
|
||||||
|
differentParamData0: null,
|
||||||
|
differentParamData1: null,
|
||||||
|
indexedDBValue: null,
|
||||||
|
tableData: [
|
||||||
|
{
|
||||||
|
name: 'a',
|
||||||
|
age: 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
age: 11
|
||||||
|
}
|
||||||
|
],
|
||||||
|
tableTitles: [
|
||||||
|
{ label: 'Name', prop: 'name' },
|
||||||
|
{ label: 'Age', prop: 'age' }
|
||||||
|
],
|
||||||
|
mergeRequestData0: null,
|
||||||
|
mergeRequestData1: null,
|
||||||
|
mergeRequestChildData0: null,
|
||||||
|
mergeRequestChildData1: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
click () {
|
click () {
|
||||||
this.count++
|
this.count++
|
||||||
|
},
|
||||||
|
async getObj () {
|
||||||
|
axios.get('/api/getObjId').then(response => {
|
||||||
|
this.obj.id = response.data
|
||||||
|
})
|
||||||
|
axios.get('/api/getObjTitle').then(response => {
|
||||||
|
this.obj.title = response.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async getCount () {
|
||||||
|
axios.get('/api/getCount').then(response => {
|
||||||
|
this.count = response.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async differentRequestParam () {
|
||||||
|
axios.get('/api/differentParam', { params: { name: 0 } }).then(response => {
|
||||||
|
this.differentParamData0 = response.data
|
||||||
|
})
|
||||||
|
axios.get('/api/differentParam', { params: { name: 1 } }).then(response => {
|
||||||
|
this.differentParamData1 = response.data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 同一url,不同入参的axios请求内包含多个不同url请求的demo
|
||||||
|
* @returns {Promise<void>}
|
||||||
|
*/
|
||||||
|
async mergeRequest () {
|
||||||
|
axios.get('/api/differentParam', { params: { name: 0 } }).then(response => {
|
||||||
|
this.mergeRequestData0 = response.data
|
||||||
|
})
|
||||||
|
axios.get('/api/differentParam', { params: { name: 1 } }).then(response => {
|
||||||
|
this.mergeRequestData1 = response.data
|
||||||
|
axios.get('/api/getChildId').then(response1 => {
|
||||||
|
this.mergeRequestChildData0 = response1.data
|
||||||
|
})
|
||||||
|
axios.get('/api/getChildTitle').then(response2 => {
|
||||||
|
this.mergeRequestChildData1 = response2.data
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async setIndexedDBValue () {
|
||||||
|
await indexedDBUtils.selectTable('test').put({ id: 1, name: 'test' })
|
||||||
|
},
|
||||||
|
async getIndexedDBValue () {
|
||||||
|
this.indexedDBValue = await indexedDBUtils.selectTable('test').get(1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
setup () {
|
||||||
const { currentRoute } = VueRouter.useRouter()
|
const { query } = useRoute()
|
||||||
|
const { currentRoute } = useRouter()
|
||||||
|
const localstorageValue = localStorage.getItem('key')
|
||||||
|
const lineTab = ref(query.lineTab || '')
|
||||||
|
const path = currentRoute.value.path
|
||||||
return {
|
return {
|
||||||
currentRoute
|
lineTab,
|
||||||
|
path,
|
||||||
|
localstorageValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@
|
|||||||
z-index: 999999;
|
z-index: 999999;
|
||||||
box-shadow: 0 0 10px #CCC;
|
box-shadow: 0 0 10px #CCC;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
.pop-title {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
.el-button--mini{
|
.el-button--mini{
|
||||||
padding: 5px 7px;
|
padding: 5px 7px;
|
||||||
}
|
}
|
||||||
@@ -23,7 +25,6 @@
|
|||||||
top: 33px;
|
top: 33px;
|
||||||
}
|
}
|
||||||
.custom-labels {
|
.custom-labels {
|
||||||
margin-top: 12px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 300px;
|
||||||
}
|
}
|
||||||
@@ -41,8 +42,7 @@
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
.custom-label:hover{
|
.custom-label:hover{
|
||||||
color: #cccccc;
|
background-color: rgba(220, 223, 230, .5)
|
||||||
background-color: #DCDFE6;
|
|
||||||
}
|
}
|
||||||
.custom-title{
|
.custom-title{
|
||||||
padding: 2px 0 2px 2px;
|
padding: 2px 0 2px 2px;
|
||||||
@@ -57,6 +57,14 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
.custom-bottom-btns-right {
|
||||||
|
.el-button:nth-of-type(1) {
|
||||||
|
margin-right: 3px;
|
||||||
|
}
|
||||||
|
.el-button .top-tool-btn-save {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.unshow {
|
.unshow {
|
||||||
display: none;
|
display: none;
|
||||||
|
|||||||
@@ -98,6 +98,8 @@
|
|||||||
.domain-detail-list {
|
.domain-detail-list {
|
||||||
display: table;
|
display: table;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
.domain-detail-list__row {
|
.domain-detail-list__row {
|
||||||
display: table-row;
|
display: table-row;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
.cn-chart__whois {
|
.cn-chart__whois {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
&.panel__time--scrolled-out {
|
&.panel__time--scrolled-out {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 70px;
|
top: 120px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
}
|
||||||
&>div {
|
&>div {
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
.chart-list {
|
.chart-list {
|
||||||
&.chart-list--screen {
|
&.chart-list--screen {
|
||||||
display: grid;
|
display: grid;
|
||||||
height: calc(100vh - 90px);
|
height: calc(100vh - 130px);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
grid-template-columns: repeat(30,1fr);
|
grid-template-columns: repeat(30,1fr);
|
||||||
grid-template-rows: repeat(19,1fr);
|
grid-template-rows: repeat(19,1fr);
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
|
|
||||||
&.row__label--width130 {
|
&.row__label--width130 {
|
||||||
flex-basis: 130px;
|
flex-basis: 140px;
|
||||||
padding-right: unset;
|
padding-right: unset;
|
||||||
}
|
}
|
||||||
&.row__label--width160 {
|
&.row__label--width160 {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ChartTabs',
|
name: 'ChartTabs',
|
||||||
@@ -69,8 +70,9 @@ export default {
|
|||||||
setup (props) {
|
setup (props) {
|
||||||
const tabsData = ref([])
|
const tabsData = ref([])
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const store = useStore()
|
||||||
const routerPath = router.currentRoute.value.path
|
const routerPath = router.currentRoute.value.path
|
||||||
const tabList = window.currentChartTabList
|
const tabList = store.getters.getChartTabList
|
||||||
let currentTab = '0'
|
let currentTab = '0'
|
||||||
|
|
||||||
if (props.data) {
|
if (props.data) {
|
||||||
@@ -94,7 +96,7 @@ export default {
|
|||||||
return item.path === routerPath
|
return item.path === routerPath
|
||||||
})
|
})
|
||||||
currentTab = JSON.stringify(currentTab)
|
currentTab = JSON.stringify(currentTab)
|
||||||
window.currentChartTabList = [{ path: routerPath, index: currentTab }]
|
store.dispatch('dispatchChartTabList', [{ path: routerPath, index: currentTab }])
|
||||||
} else {
|
} else {
|
||||||
// 此处为切换界面,如果window里保存的路径和tabsData里的路径一致,选择window数据并使用
|
// 此处为切换界面,如果window里保存的路径和tabsData里的路径一致,选择window数据并使用
|
||||||
// 两个不一致的话,则默认选择tabsData里的第一条
|
// 两个不一致的话,则默认选择tabsData里的第一条
|
||||||
@@ -108,10 +110,15 @@ export default {
|
|||||||
|
|
||||||
if (obj0 && obj1) {
|
if (obj0 && obj1) {
|
||||||
currentTab = tabList[1].index
|
currentTab = tabList[1].index
|
||||||
|
// 场景:从遮罩面板进入界面时,重置状态,默认选中第一个tab
|
||||||
|
if (routerPath === tabList[0].path) {
|
||||||
|
currentTab = tabList[0].index
|
||||||
|
store.dispatch('dispatchChartTabList', [{ path: tabsData.value[0].path, index: '0' }])
|
||||||
|
}
|
||||||
} else if (obj0) {
|
} else if (obj0) {
|
||||||
currentTab = tabList[0].index
|
currentTab = tabList[0].index
|
||||||
} else {
|
} else {
|
||||||
window.currentChartTabList = [{ path: tabsData.value[0].path, index: '0' }]
|
store.dispatch('dispatchChartTabList', [{ path: tabsData.value[0].path, index: '0' }])
|
||||||
currentTab = '0'
|
currentTab = '0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,9 +163,10 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const tabList = this.$store.getters.getChartTabList
|
||||||
|
|
||||||
if (window.currentChartTabList && this.router !== 'noRouter') {
|
if (tabList && this.router !== 'noRouter') {
|
||||||
window.currentChartTabList.forEach((item) => {
|
tabList.forEach((item) => {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.handleActiveBar(parseFloat(item.index))
|
this.handleActiveBar(parseFloat(item.index))
|
||||||
})
|
})
|
||||||
@@ -167,7 +175,7 @@ export default {
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.handleActiveBar(this.currentTab)
|
this.handleActiveBar(this.currentTab)
|
||||||
})
|
})
|
||||||
window.currentChartTabList = null
|
this.$store.dispatch('dispatchChartTabList', null)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleActiveBar (index) {
|
handleActiveBar (index) {
|
||||||
@@ -186,7 +194,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
// 数组长度为1,即代表刚刷新界面,获取active的dom添加样式,避免原模式错位问题
|
// 数组长度为1,即代表刚刷新界面,获取active的dom添加样式,避免原模式错位问题
|
||||||
// 可添加css样式,也可添加class类名,两个操作选一即可
|
// 可添加css样式,也可添加class类名,两个操作选一即可
|
||||||
if (window.currentChartTabList.length === 1) {
|
if (this.$store.getters.getChartTabList.length === 1) {
|
||||||
// 此处操作是因为初始化时给active加border,导致tab下移,故需要将整体往上移动对应高度
|
// 此处操作是因为初始化时给active加border,导致tab下移,故需要将整体往上移动对应高度
|
||||||
const topDom = document.getElementsByClassName('el-tabs__header is-top')
|
const topDom = document.getElementsByClassName('el-tabs__header is-top')
|
||||||
topDom[0].style.cssText += 'top: -3px'
|
topDom[0].style.cssText += 'top: -3px'
|
||||||
@@ -201,6 +209,7 @@ export default {
|
|||||||
},
|
},
|
||||||
handleClick (item) {
|
handleClick (item) {
|
||||||
this.$emit('click', item)
|
this.$emit('click', item)
|
||||||
|
const tabList = this.$store.getters.getChartTabList
|
||||||
|
|
||||||
if (this.router === 'noRouter') {
|
if (this.router === 'noRouter') {
|
||||||
const { query } = this.$route
|
const { query } = this.$route
|
||||||
@@ -210,14 +219,15 @@ export default {
|
|||||||
})
|
})
|
||||||
overwriteUrl(newUrl)
|
overwriteUrl(newUrl)
|
||||||
} else {
|
} else {
|
||||||
window.currentChartTabList.push({
|
tabList.push({
|
||||||
path: this.tabsData[item.index].path,
|
path: this.tabsData[item.index].path,
|
||||||
index: item.index
|
index: item.index
|
||||||
})
|
})
|
||||||
|
|
||||||
if (window.currentChartTabList.length > 2) {
|
if (tabList.length > 2) {
|
||||||
window.currentChartTabList.splice(0, 1)
|
tabList.splice(0, 1)
|
||||||
}
|
}
|
||||||
|
this.$store.dispatch('dispatchChartTabList', tabList)
|
||||||
|
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: this.tabsData[item.index].path,
|
path: this.tabsData[item.index].path,
|
||||||
@@ -230,6 +240,19 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
|
const path = this.$router.currentRoute.value.path
|
||||||
|
const list = this.$store.getters.getChartTabList
|
||||||
|
if (list && this.router !== 'noRouter') {
|
||||||
|
if (list[1]) {
|
||||||
|
// 去其他界面,清除状态
|
||||||
|
if (path !== list[0].path && path !== list[1].path) {
|
||||||
|
this.$store.dispatch('dispatchChartTabList', null)
|
||||||
|
}
|
||||||
|
} else if (path !== list[0].path) {
|
||||||
|
// 避免刷新页面之后又点击菜单栏进入该界面,还保留上次点击状态
|
||||||
|
this.$store.dispatch('dispatchChartTabList', null)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
class="date_style"
|
class="date_style"
|
||||||
style="position: absolute;top: -53px;left: -536px;"
|
style="position: absolute;top: -53px;left: -536px;"
|
||||||
:clearable="false"
|
:clearable="false"
|
||||||
|
:default-time="defaultTime"
|
||||||
type="datetimerange"
|
type="datetimerange"
|
||||||
@change="timeArrChange"
|
@change="timeArrChange"
|
||||||
/>
|
/>
|
||||||
@@ -127,6 +128,11 @@ export default {
|
|||||||
{ value: 2880, name: 'last 2 days' }
|
{ value: 2880, name: 'last 2 days' }
|
||||||
]
|
]
|
||||||
const dropdownFlag = ref(false)
|
const dropdownFlag = ref(false)
|
||||||
|
// 默认日历选择时间,即开始时间YYYY-MM-DD 00:00:00,结束时间YYYY-MM-DD 59:59:59
|
||||||
|
const defaultTime = ref([
|
||||||
|
new Date(2023, 1, 1, 0, 0, 0),
|
||||||
|
new Date(2023, 1, 2, 23, 59, 59)
|
||||||
|
])
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
const utcStr = computed(() => {
|
const utcStr = computed(() => {
|
||||||
@@ -274,6 +280,7 @@ export default {
|
|||||||
rangeEchartsData,
|
rangeEchartsData,
|
||||||
address,
|
address,
|
||||||
dateRangeArr,
|
dateRangeArr,
|
||||||
|
defaultTime,
|
||||||
dateRangeValue,
|
dateRangeValue,
|
||||||
isCustom,
|
isCustom,
|
||||||
newDateValue,
|
newDateValue,
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
<div class="banner__left">
|
<div class="banner__left">
|
||||||
<span @click="shrink" class="shrink-button" :class="{'shrink-button--collapse': showMenu}"><i
|
<span @click="shrink" class="shrink-button" :class="{'shrink-button--collapse': showMenu}"><i
|
||||||
class="cn-icon cn-icon-navigation"></i></span>
|
class="cn-icon cn-icon-navigation"></i></span>
|
||||||
<img alt="loading..." height="26" :src="logo?logo:require('../../assets/img/logo-header.svg')" @click="jump('/panel/networkOverview', '', '', 0)" style="cursor: pointer"/>
|
<span style="color: white; font-size: 20px;">域名解析服务监测系统</span>
|
||||||
</div>
|
</div>
|
||||||
<!--个人操作-->
|
<!--个人操作-->
|
||||||
<div class="personal">
|
<div class="personal">
|
||||||
<el-dropdown>
|
<!-- <el-dropdown>
|
||||||
<div class="header-menu--item"><i class="cn-icon cn-icon-language"></i></div>
|
<div class="header-menu--item"><i class="cn-icon cn-icon-language"></i></div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item>
|
<el-dropdown-item>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</el-dropdown-item>
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>-->
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<div class='login-user header-menu--item'>{{ username }} <i class="cn-icon cn-icon-arrow-down"></i></div>
|
<div class='login-user header-menu--item'>{{ username }} <i class="cn-icon cn-icon-arrow-down"></i></div>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
@@ -103,32 +103,7 @@
|
|||||||
<span v-else class="route-menu" @click="jump(route,item,'',3)">{{ $t(item) }}</span>
|
<span v-else class="route-menu" @click="jump(route,item,'',3)">{{ $t(item) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="index===1">
|
<template v-else-if="index===1">
|
||||||
<span class="route-menu" @click="jump(route,'','',2)"
|
<span class="route-menu" @click="jump(route,'','',2)">{{ item }}</span>
|
||||||
v-if="route.indexOf('detection') === -1 && route.indexOf('administration') === -1">{{ item }}</span>
|
|
||||||
<!-- <div class="header__left-breadcrumb-item-select" v-if="route.indexOf('detection') > -1">-->
|
|
||||||
<!-- <el-popover placement="bottom-start"-->
|
|
||||||
<!-- v-if="route.indexOf('detection') > -1"-->
|
|
||||||
<!-- ref="breadcrumbPopover"-->
|
|
||||||
<!-- :show-arrow="false"-->
|
|
||||||
<!-- :append-to-body="false"-->
|
|
||||||
<!-- :hide-after="0"-->
|
|
||||||
<!-- :show-after="0"-->
|
|
||||||
<!-- popper-class="breadcrumb__popper"-->
|
|
||||||
<!-- trigger="click">-->
|
|
||||||
<!-- <template #reference>-->
|
|
||||||
<!-- <div class="breadcrumb-button" id="breadcrumbButton2" :class="showBackground?'breadcrumb-button__active':''" v-if="route.indexOf('detection') > -1">-->
|
|
||||||
<!-- <span id="breadcrumbValue2"> {{item}}</span><i class="cn-icon-xiala cn-icon"></i>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </template>-->
|
|
||||||
<!-- <el-row type="flex" justify="center" style="width: fit-content;flex-direction: column;">-->
|
|
||||||
<!-- <ul class="select-dropdown" id="breadcrumbSelectDropdown2">-->
|
|
||||||
<!-- <li v-for="item in detectionMenuList" title='' :key="item.name" :id="item.name" class="select-dropdown__item" @click="jump(item.path,'','',2)">-->
|
|
||||||
<!-- <span>{{$t(item.i18n)}}</span>-->
|
|
||||||
<!-- </li>-->
|
|
||||||
<!-- </ul>-->
|
|
||||||
<!-- </el-row>-->
|
|
||||||
<!-- </el-popover>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<span>{{ item }}</span>
|
<span>{{ item }}</span>
|
||||||
@@ -552,7 +527,7 @@ export default {
|
|||||||
queryCondition.push('common_l7_protocol=\'' + valueGroup[0] + '\'')
|
queryCondition.push('common_l7_protocol=\'' + valueGroup[0] + '\'')
|
||||||
queryCondition.push('common_server_port=' + valueGroup[1])
|
queryCondition.push('common_server_port=' + valueGroup[1])
|
||||||
}
|
}
|
||||||
console.log(queryCondition.join(' AND '))
|
// console.log(queryCondition.join(' AND '))
|
||||||
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' AND ')
|
this.urlChangeParams[this.curTabState.queryCondition] = queryCondition.join(' AND ')
|
||||||
} else {
|
} else {
|
||||||
searchProps.forEach(item => {
|
searchProps.forEach(item => {
|
||||||
@@ -627,9 +602,10 @@ export default {
|
|||||||
this.urlChangeParams[this.curTabState.tabOperationBeforeType] = this.getUrlParam(this.curTabState.tabOperationType, '', true)
|
this.urlChangeParams[this.curTabState.tabOperationBeforeType] = this.getUrlParam(this.curTabState.tabOperationType, '', true)
|
||||||
this.urlChangeParams[this.curTabState.tabOperationType] = opeType
|
this.urlChangeParams[this.curTabState.tabOperationType] = opeType
|
||||||
if (opeType === 3) {
|
if (opeType === 3) {
|
||||||
if (route !== '/panel/networkOverview') {
|
/* if (route !== '/panel/networkOverview') {
|
||||||
this.urlChangeParams.queryCondition = ''
|
this.urlChangeParams.queryCondition = ''
|
||||||
}
|
} */
|
||||||
|
this.urlChangeParams.queryCondition = ''
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.urlChangeParams[this.curTabState.tabOperationType] = operationType.mainMenu
|
this.urlChangeParams[this.curTabState.tabOperationType] = operationType.mainMenu
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="right-box__container">
|
<div class="right-box__container">
|
||||||
<div class="container__form">
|
<div class="container__form">
|
||||||
<el-form ref="userForm" :model="editObject" :rules="rules" label-position="top" label-width="120px">
|
<el-form ref="reportForm" :model="editObject" :rules="rules" label-position="top" label-width="120px">
|
||||||
<!--name-->
|
<!--name-->
|
||||||
<el-form-item :label="$t('report.name')" prop="name">
|
<el-form-item :label="$t('report.name')" prop="name">
|
||||||
<el-input id="account-input-name" v-model="editObject.name" maxlength="64" placeholder=" " show-word-limit size="small" type="text"></el-input>
|
<el-input id="account-input-name" v-model="editObject.name" maxlength="64" placeholder=" " show-word-limit size="small" type="text"></el-input>
|
||||||
@@ -76,7 +76,6 @@
|
|||||||
:disabled="!!editObject.id"
|
:disabled="!!editObject.id"
|
||||||
:disabled-date="startDisabledDate"
|
:disabled-date="startDisabledDate"
|
||||||
@change="startTimeChang"
|
@change="startTimeChang"
|
||||||
@focus="startFocus"
|
|
||||||
prefix-icon="cn-icon cn-icon-shijian"
|
prefix-icon="cn-icon cn-icon-shijian"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
@@ -96,7 +95,6 @@
|
|||||||
:disabled="!!editObject.id"
|
:disabled="!!editObject.id"
|
||||||
:disabled-date="endDisabledDate"
|
:disabled-date="endDisabledDate"
|
||||||
@change="endTimeChange"
|
@change="endTimeChange"
|
||||||
@focus="endFocus"
|
|
||||||
prefix-icon="cn-icon cn-icon-shijian"
|
prefix-icon="cn-icon cn-icon-shijian"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
@@ -283,28 +281,8 @@ import { api } from '@/utils/api'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { get, post, put } from '@/utils/http'
|
import { get, post, put } from '@/utils/http'
|
||||||
import { dateFormat, getMillisecond } from '@/utils/date-util'
|
import { dateFormat, getMillisecond } from '@/utils/date-util'
|
||||||
import { ref } from 'vue'
|
import { ref, getCurrentInstance } from 'vue'
|
||||||
const paramValidator = (rule, value, callback) => {
|
import i18n from '@/i18n'
|
||||||
let validate = true
|
|
||||||
if (value && value.length > 0) {
|
|
||||||
const hasEmpty = value.some(v => {
|
|
||||||
return !v.value && v.value !== 0
|
|
||||||
})
|
|
||||||
validate = !hasEmpty
|
|
||||||
}
|
|
||||||
return validate
|
|
||||||
}
|
|
||||||
const nameValidator = (rule, value, callback) => {
|
|
||||||
let validate = true
|
|
||||||
const reg = /^[\u4e00-\u9fa5A-Za-z0-9\-\_]*$/
|
|
||||||
if (reg.test(value)) {
|
|
||||||
validate = true
|
|
||||||
} else {
|
|
||||||
validate = false
|
|
||||||
}
|
|
||||||
return validate
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ReportBox',
|
name: 'ReportBox',
|
||||||
mixins: [rightBoxMixin],
|
mixins: [rightBoxMixin],
|
||||||
@@ -313,32 +291,21 @@ export default {
|
|||||||
currentCategoryId: Number
|
currentCategoryId: Number
|
||||||
},
|
},
|
||||||
setup () {
|
setup () {
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
const startTime = ref('')
|
const startTime = ref('')
|
||||||
const endTime = ref('')
|
const endTime = ref('')
|
||||||
const focus = ref('')
|
|
||||||
const focusDate = ref('')
|
|
||||||
function endTimeChange (val) {
|
function endTimeChange (val) {
|
||||||
endTime.value = val
|
endTime.value = val
|
||||||
}
|
}
|
||||||
function startTimeChang (val) {
|
function startTimeChang (val) {
|
||||||
startTime.value = val
|
startTime.value = val
|
||||||
}
|
}
|
||||||
function startFocus (val) {
|
|
||||||
focus.value = val.target.value
|
|
||||||
}
|
|
||||||
function endFocus (val) {
|
|
||||||
focusDate.value = val.target.value
|
|
||||||
}
|
|
||||||
const endDisabledDate = (time) => {
|
const endDisabledDate = (time) => {
|
||||||
if (time.getTime() > new Date()) {
|
if (time.getTime() > new Date()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (startTime.value != '' && startTime.value > time) {
|
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
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,22 +313,71 @@ export default {
|
|||||||
if (time.getTime() > new Date()) {
|
if (time.getTime() > new Date()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (focus.value != '' && startTime.value > time) {
|
if (endTime.value !== '' && endTime.value < time) {
|
||||||
return false
|
|
||||||
} else if (startTime.value != '' && startTime.value > time) {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (endTime.value != '' && endTime.value < time) {
|
}
|
||||||
return true
|
|
||||||
|
const paramValidator = (rule, value, callback) => {
|
||||||
|
let validate = true
|
||||||
|
if (value && value.length > 0) {
|
||||||
|
const hasEmpty = value.some(v => {
|
||||||
|
return !v.value && v.value !== 0
|
||||||
|
})
|
||||||
|
validate = !hasEmpty
|
||||||
}
|
}
|
||||||
|
return validate
|
||||||
|
}
|
||||||
|
const nameValidator = (rule, value, callback) => {
|
||||||
|
let validate = true
|
||||||
|
const reg = /^[\u4e00-\u9fa5A-Za-z0-9\-\_]*$/
|
||||||
|
validate = reg.test(value)
|
||||||
|
return validate
|
||||||
|
}
|
||||||
|
const startTimeValidator = (rule, value, callback) => {
|
||||||
|
const form = proxy.$refs.reportForm
|
||||||
|
if (form.model.config.endTime) {
|
||||||
|
form.validateField('config.endTime', () => null)
|
||||||
|
}
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
const endTimeValidator = (rule, value, callback) => {
|
||||||
|
let validate = true
|
||||||
|
if (startTime.value !== '' && value <= startTime.value) {
|
||||||
|
validate = false
|
||||||
|
}
|
||||||
|
return validate
|
||||||
|
}
|
||||||
|
const rules = { // 表单校验规则
|
||||||
|
name: [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'blur' },
|
||||||
|
{ validator: nameValidator, message: i18n.global.t('validate.onlyAllowNumberLetterChinese-_'), trigger: 'blur' }
|
||||||
|
],
|
||||||
|
categoryId: [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' }
|
||||||
|
],
|
||||||
|
schedulerStart: [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' }
|
||||||
|
],
|
||||||
|
'config.startTime': [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' },
|
||||||
|
{ validator: startTimeValidator, trigger: 'change' }
|
||||||
|
],
|
||||||
|
'config.endTime': [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'change' },
|
||||||
|
{ validator: endTimeValidator, message: i18n.global.t('validate.endTimeGreaterThanStart'), trigger: 'change' }
|
||||||
|
],
|
||||||
|
categoryParams: [
|
||||||
|
{ required: true, message: i18n.global.t('validate.required'), trigger: 'blur' },
|
||||||
|
{ validator: paramValidator, message: i18n.global.t('validate.required'), trigger: 'blur' }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
endDisabledDate,
|
endDisabledDate,
|
||||||
startDisabledDate,
|
startDisabledDate,
|
||||||
startTimeChang,
|
startTimeChang,
|
||||||
endTimeChange,
|
endTimeChange,
|
||||||
startFocus,
|
rules
|
||||||
endFocus
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
@@ -391,28 +407,6 @@ export default {
|
|||||||
monthWeekdayCheckedAll: false,
|
monthWeekdayCheckedAll: false,
|
||||||
monthWeekdayIsIndeterminate: false,
|
monthWeekdayIsIndeterminate: false,
|
||||||
|
|
||||||
rules: { // 表单校验规则
|
|
||||||
name: [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
|
||||||
{ validator: nameValidator, message: this.$t('validate.onlyAllowNumberLetterChinese-_'), trigger: 'blur' }
|
|
||||||
],
|
|
||||||
categoryId: [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
|
||||||
],
|
|
||||||
schedulerStart: [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
|
||||||
],
|
|
||||||
'config.startTime': [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
|
||||||
],
|
|
||||||
'config.endTime': [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'change' }
|
|
||||||
],
|
|
||||||
categoryParams: [
|
|
||||||
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
|
|
||||||
{ validator: paramValidator, message: this.$t('validate.required'), trigger: 'blur' }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
paramsOptions: []
|
paramsOptions: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -592,7 +586,7 @@ export default {
|
|||||||
if (this.blockOperation.save) { return }
|
if (this.blockOperation.save) { return }
|
||||||
this.blockOperation.save = true
|
this.blockOperation.save = true
|
||||||
|
|
||||||
this.$refs.userForm.validate((valid) => {
|
this.$refs.reportForm.validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
let startTime = ''
|
let startTime = ''
|
||||||
let endTime = ''
|
let endTime = ''
|
||||||
|
|||||||
@@ -25,12 +25,12 @@
|
|||||||
<el-button size="mini" v-if="!isCancel" :id="tableId+'-element-set-all'" class="cn-btn cn-btn-size-small-new cn-btn-style-light-new" type="button" @click="batchHandler(true)">
|
<el-button size="mini" v-if="!isCancel" :id="tableId+'-element-set-all'" class="cn-btn cn-btn-size-small-new cn-btn-style-light-new" type="button" @click="batchHandler(true)">
|
||||||
<span class="top-tool-btn-txt">{{$t('overall.all')}}</span>
|
<span class="top-tool-btn-txt">{{$t('overall.all')}}</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<div>
|
<div class="custom-bottom-btns-right">
|
||||||
<el-button size="mini" :id="tableId+'-element-set-esc'" class="cn-btn cn-btn-size-small-new cn-btn-style-light-new" type="button" @click="esc">
|
<el-button size="mini" :id="tableId+'-element-set-esc'" class="cn-btn cn-btn-size-small-new cn-btn-style-light-new" type="button" @click="esc">
|
||||||
<span class="top-tool-btn-txt">{{$t('overall.cancel')}}</span>
|
<span class="top-tool-btn-txt">{{$t('overall.cancel')}}</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="mini" :id="tableId+'-element-set-save'" class="cn-btn cn-btn-size-small-new cn-btn-style-normal-new" type="button" @click="save" style="background-color: #0091ff;color:#DCDFE6">
|
<el-button size="mini" :id="tableId+'-element-set-save'" class="cn-btn cn-btn-size-small-new cn-btn-style-normal-new" type="button" @click="save" style="background-color: #0091ff;color:#DCDFE6">
|
||||||
<span class="top-tool-btn-txt">{{$t('overall.save')}}</span>
|
<span class="top-tool-btn-txt top-tool-btn-save">{{$t('overall.save')}}</span>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
import { dbName, dbGeoDataTableName, dbDrilldownTableConfig } from '@/utils/constants'
|
import { dbName, dbGeoDataTableName, dbDrilldownTableConfig } from '@/utils/constants'
|
||||||
import Dexie from 'dexie'
|
import Dexie from 'dexie'
|
||||||
|
/* https://dexie.org/ */
|
||||||
|
|
||||||
export const db = new Dexie(dbName)
|
const db = new Dexie(dbName)
|
||||||
db.version(2).stores({
|
db.version(3).stores({
|
||||||
[dbGeoDataTableName]: '++name, geo',
|
[dbGeoDataTableName]: '++name, geo',
|
||||||
[dbDrilldownTableConfig]: '++id, config'
|
[dbDrilldownTableConfig]: '++id, config',
|
||||||
|
test: '++id, name'
|
||||||
})
|
})
|
||||||
|
function selectTable (tableName) {
|
||||||
|
return db[tableName]
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexedDBUtils = {
|
||||||
|
db,
|
||||||
|
selectTable
|
||||||
|
}
|
||||||
|
export default indexedDBUtils
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { hasButton } from '@/permission'
|
import { hasButton } from '@/permission'
|
||||||
import { dateFormatByAppearance } from '@/utils/date-util'
|
import { dateFormatByAppearance } from '@/utils/date-util'
|
||||||
import { storageKey } from '@/utils/constants'
|
|
||||||
export default {
|
export default {
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -21,7 +20,9 @@ export default {
|
|||||||
query: false
|
query: false
|
||||||
},
|
},
|
||||||
timeout: null,
|
timeout: null,
|
||||||
debounceFunc: null
|
debounceFunc: null,
|
||||||
|
// 是否正在单元测试
|
||||||
|
isUnitTesting: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ const routes = [
|
|||||||
path: '/panel/:typeName',
|
path: '/panel/:typeName',
|
||||||
component: () => import('@/views/charts2/Panel')
|
component: () => import('@/views/charts2/Panel')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'dns6',
|
||||||
|
path: '/dns6/:typeName',
|
||||||
|
component: () => import('@/views/charts/Panel')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/report/builtIn',
|
path: '/report/builtIn',
|
||||||
component: () => import('@/views/report/reportTest')
|
component: () => import('@/views/report/reportTest')
|
||||||
|
|||||||
@@ -59,7 +59,8 @@ const panel = {
|
|||||||
rangeEchartsData: {}, // 框选echarts图表
|
rangeEchartsData: {}, // 框选echarts图表
|
||||||
routerHistoryList: [], // 路由跳转记录列表
|
routerHistoryList: [], // 路由跳转记录列表
|
||||||
dnsQtypeMapData: [],
|
dnsQtypeMapData: [],
|
||||||
dnsRcodeMapData: []
|
dnsRcodeMapData: [],
|
||||||
|
chartTabList: null // chartTabs组件的tab状态点击列表,初始化为null方便原有逻辑计算
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setShowRightBox (state, flag) {
|
setShowRightBox (state, flag) {
|
||||||
@@ -151,6 +152,9 @@ const panel = {
|
|||||||
},
|
},
|
||||||
setRouterHistoryList (state, list) {
|
setRouterHistoryList (state, list) {
|
||||||
state.routerHistoryList = list
|
state.routerHistoryList = list
|
||||||
|
},
|
||||||
|
setChartTabList (state, list) {
|
||||||
|
state.chartTabList = list
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
@@ -225,6 +229,9 @@ const panel = {
|
|||||||
},
|
},
|
||||||
getRouterHistoryList (state) {
|
getRouterHistoryList (state) {
|
||||||
return state.routerHistoryList
|
return state.routerHistoryList
|
||||||
|
},
|
||||||
|
getChartTabList (state) {
|
||||||
|
return state.chartTabList
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -253,6 +260,9 @@ const panel = {
|
|||||||
},
|
},
|
||||||
clearPanel (store) {
|
clearPanel (store) {
|
||||||
store.commit('cleanPanel')
|
store.commit('cleanPanel')
|
||||||
|
},
|
||||||
|
dispatchChartTabList (store, list) {
|
||||||
|
store.commit('setChartTabList', list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ElMessage } from 'element-plus' // dependent on utc plugin
|
|||||||
import { storageKey, dbDrilldownTableConfig } from '@/utils/constants'
|
import { storageKey, dbDrilldownTableConfig } from '@/utils/constants'
|
||||||
import { getConfigVersion } from '@/utils/tools'
|
import { getConfigVersion } from '@/utils/tools'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { db } from '@/indexedDB'
|
import indexedDBUtils from '@/indexedDB'
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
state () {
|
state () {
|
||||||
@@ -92,7 +92,7 @@ const user = {
|
|||||||
if (res.code === 200 && res.page.list && res.page.list.length > 0) {
|
if (res.code === 200 && res.page.list && res.page.list.length > 0) {
|
||||||
// 从接口返回整体配置,再读取用户缓存,将对应条目覆盖,作为使用的配置
|
// 从接口返回整体配置,再读取用户缓存,将对应条目覆盖,作为使用的配置
|
||||||
const defaultConfigs = JSON.parse(res.page.list[0].cvalue)
|
const defaultConfigs = JSON.parse(res.page.list[0].cvalue)
|
||||||
await db[dbDrilldownTableConfig].put({
|
await indexedDBUtils.selectTable(dbDrilldownTableConfig).put({
|
||||||
id: 'default',
|
id: 'default',
|
||||||
version: defaultConfigs.version,
|
version: defaultConfigs.version,
|
||||||
config: defaultConfigs.config
|
config: defaultConfigs.config
|
||||||
@@ -100,7 +100,7 @@ const user = {
|
|||||||
const userId = localStorage.getItem(storageKey.userId)
|
const userId = localStorage.getItem(storageKey.userId)
|
||||||
const oldVersion = await getConfigVersion(userId)
|
const oldVersion = await getConfigVersion(userId)
|
||||||
if (oldVersion !== defaultConfigs.version) {
|
if (oldVersion !== defaultConfigs.version) {
|
||||||
db[dbDrilldownTableConfig].delete(userId)
|
indexedDBUtils.selectTable(dbDrilldownTableConfig).delete(userId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -318,11 +318,12 @@ export async function getI18n () {
|
|||||||
|
|
||||||
/* 获得原始的3611-2 json字符串数据 */
|
/* 获得原始的3611-2 json字符串数据 */
|
||||||
export async function getIso36112JsonData (suffix) {
|
export async function getIso36112JsonData (suffix) {
|
||||||
|
const url = `${window.location.protocol}//${window.location.host}/geojson/${suffix}.json`
|
||||||
const request = new Promise(resolve => {
|
const request = new Promise(resolve => {
|
||||||
axios({
|
axios({ url }).then(response => {
|
||||||
url: `${window.location.protocol}//${window.location.host}:${window.location.port}/geojson/${suffix}.json`
|
|
||||||
}).then(response => {
|
|
||||||
resolve(response.data || response || null)
|
resolve(response.data || response || null)
|
||||||
|
}).catch(err => {
|
||||||
|
console.error(err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
return await request
|
return await request
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
export const defaultPageSize = 20
|
export const defaultPageSize = 20
|
||||||
|
|
||||||
|
// indexedDB库名
|
||||||
export const dbName = 'cn-db'
|
export const dbName = 'cn-db'
|
||||||
|
// indexedDB表名
|
||||||
export const dbGeoDataTableName = 'geodata'
|
export const dbGeoDataTableName = 'geodata'
|
||||||
export const dbDrilldownTableConfig = 'cn-drilldown-table-config'
|
export const dbDrilldownTableConfig = 'cn-drilldown-table-config'
|
||||||
export const storageKey = {
|
export const storageKey = {
|
||||||
@@ -61,7 +63,8 @@ export const panelTypeAndRouteMapping = {
|
|||||||
cryptocurrency: 7,
|
cryptocurrency: 7,
|
||||||
ipDrillDownTest: 8,
|
ipDrillDownTest: 8,
|
||||||
linkMonitor: 14,
|
linkMonitor: 14,
|
||||||
linkMonitorDrillDown: 15
|
linkMonitorDrillDown: 15,
|
||||||
|
dns6: 18
|
||||||
}
|
}
|
||||||
|
|
||||||
/* operationLog state 执行状态属性 值与名称之间的映射 */
|
/* operationLog state 执行状态属性 值与名称之间的映射 */
|
||||||
@@ -1552,7 +1555,7 @@ export const npmCategoryInfoMapping = [
|
|||||||
|
|
||||||
// 整屏滚动的路径映射
|
// 整屏滚动的路径映射
|
||||||
export const wholeScreenRouterMapping = {
|
export const wholeScreenRouterMapping = {
|
||||||
dns: '/panel/dnsServiceInsights'
|
dns: '/dns6/dns6'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const themeData = [
|
export const themeData = [
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import { storageKey, iso36112, topDomain, echartsFontSize, dbGeoDataTableName, n
|
|||||||
import { getIso36112JsonData, getDictList } from '@/utils/api'
|
import { getIso36112JsonData, getDictList } from '@/utils/api'
|
||||||
import { format } from 'echarts'
|
import { format } from 'echarts'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { db } from '@/indexedDB'
|
import indexedDBUtils from '@/indexedDB'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
|
|
||||||
export const tableSort = {
|
export const tableSort = {
|
||||||
// 是否需要排序
|
// 是否需要排序
|
||||||
@@ -488,11 +487,11 @@ export function loadGeoData () {
|
|||||||
keys.push(storageKey.iso36112Capital)
|
keys.push(storageKey.iso36112Capital)
|
||||||
keys.push(storageKey.iso36112WorldLow)
|
keys.push(storageKey.iso36112WorldLow)
|
||||||
keys.forEach(async k => {
|
keys.forEach(async k => {
|
||||||
const queryData = await db[dbGeoDataTableName].get({ name: k })
|
const queryData = await indexedDBUtils.selectTable(dbGeoDataTableName).get({ name: k })
|
||||||
if (!queryData) {
|
if (!queryData) {
|
||||||
const data = await getIso36112JsonData(iso36112[k])
|
const data = await getIso36112JsonData(iso36112[k])
|
||||||
if (data) {
|
if (data) {
|
||||||
db[dbGeoDataTableName].add({
|
indexedDBUtils.selectTable(dbGeoDataTableName).add({
|
||||||
name: k,
|
name: k,
|
||||||
geo: data
|
geo: data
|
||||||
})
|
})
|
||||||
@@ -505,14 +504,14 @@ export function loadGeoData () {
|
|||||||
* 使用indexedDB缓存地图数据
|
* 使用indexedDB缓存地图数据
|
||||||
* */
|
* */
|
||||||
export async function getGeoData (key) {
|
export async function getGeoData (key) {
|
||||||
const data = await db[dbGeoDataTableName].get({ name: key })
|
const data = await indexedDBUtils.selectTable(dbGeoDataTableName).get({ name: key })
|
||||||
if (data) {
|
if (data) {
|
||||||
return data.geo
|
return data.geo
|
||||||
} else {
|
} else {
|
||||||
if (iso36112[key]) {
|
if (iso36112[key]) {
|
||||||
const d = await getIso36112JsonData(iso36112[key])
|
const d = await getIso36112JsonData(iso36112[key])
|
||||||
if (d) {
|
if (d) {
|
||||||
db[dbGeoDataTableName].add({
|
indexedDBUtils.selectTable(dbGeoDataTableName).add({
|
||||||
name: key,
|
name: key,
|
||||||
geo: d
|
geo: d
|
||||||
})
|
})
|
||||||
@@ -937,7 +936,7 @@ export async function getDefaultCurTab (tableType, metric, columnName) {
|
|||||||
export async function readDrilldownTableConfigByUser () {
|
export async function readDrilldownTableConfigByUser () {
|
||||||
// 获取用户定制的自定义配置
|
// 获取用户定制的自定义配置
|
||||||
const userId = localStorage.getItem(storageKey.userId)
|
const userId = localStorage.getItem(storageKey.userId)
|
||||||
const userLocalConfig = await db[dbDrilldownTableConfig].get({ id: userId })
|
const userLocalConfig = await indexedDBUtils.selectTable(dbDrilldownTableConfig).get({ id: userId })
|
||||||
let defaultDrillDownTableConfigs = []
|
let defaultDrillDownTableConfigs = []
|
||||||
if (userLocalConfig) {
|
if (userLocalConfig) {
|
||||||
defaultDrillDownTableConfigs = userLocalConfig.config
|
defaultDrillDownTableConfigs = userLocalConfig.config
|
||||||
@@ -946,15 +945,15 @@ export async function readDrilldownTableConfigByUser () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getConfigVersion (id) {
|
export async function getConfigVersion (id) {
|
||||||
let defaultConfigInDb = await db[dbDrilldownTableConfig].get({ id: id })
|
let defaultConfigInDb = await indexedDBUtils.selectTable(dbDrilldownTableConfig).get({ id: id })
|
||||||
if (!defaultConfigInDb) {
|
if (!defaultConfigInDb) {
|
||||||
defaultConfigInDb = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
defaultConfigInDb = await indexedDBUtils.selectTable(dbDrilldownTableConfig).get({ id: 'default' })
|
||||||
}
|
}
|
||||||
return defaultConfigInDb.version || ''
|
return defaultConfigInDb.version || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function combineDrilldownTableWithUserConfig () {
|
export async function combineDrilldownTableWithUserConfig () {
|
||||||
const defaultConfigInDb = await db[dbDrilldownTableConfig].get({ id: 'default' })
|
const defaultConfigInDb = await indexedDBUtils.selectTable(dbDrilldownTableConfig).get({ id: 'default' })
|
||||||
const defaultConfigGroup = defaultConfigInDb ? defaultConfigInDb.config : []
|
const defaultConfigGroup = defaultConfigInDb ? defaultConfigInDb.config : []
|
||||||
const currentUserConfigGroup = await readDrilldownTableConfigByUser()
|
const currentUserConfigGroup = await readDrilldownTableConfigByUser()
|
||||||
if (defaultConfigGroup && currentUserConfigGroup && currentUserConfigGroup.length > 0) {
|
if (defaultConfigGroup && currentUserConfigGroup && currentUserConfigGroup.length > 0) {
|
||||||
@@ -1086,3 +1085,64 @@ export function colorGradientCalculation (startColor, endColor, values) {
|
|||||||
export function colorHexToRgbArr (hex) {
|
export function colorHexToRgbArr (hex) {
|
||||||
return [1, 3, 5].map((h) => parseInt(hex.substring(h, h + 2), 16))
|
return [1, 3, 5].map((h) => parseInt(hex.substring(h, h + 2), 16))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过事件类型eventType转换对应名称
|
||||||
|
* @param type
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export function getNameByEventType (type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'http error': {
|
||||||
|
return 'http error ratio'
|
||||||
|
}
|
||||||
|
case 'dns error': {
|
||||||
|
return 'dns error ratio'
|
||||||
|
}
|
||||||
|
case 'high dns response time': {
|
||||||
|
return 'dns response time'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
折线图通过事件类型 type 转换对应名称
|
||||||
|
*/
|
||||||
|
export function getLineType (type) {
|
||||||
|
switch (type) {
|
||||||
|
case 'bytes': {
|
||||||
|
return 'Bits/s'
|
||||||
|
}
|
||||||
|
case 'packets': {
|
||||||
|
return 'Packets/s'
|
||||||
|
}
|
||||||
|
case 'sessions': {
|
||||||
|
return 'Sessions/s'
|
||||||
|
}
|
||||||
|
case 'queries': {
|
||||||
|
return 'Queries/s'
|
||||||
|
}
|
||||||
|
default: return type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
npm折线图通过事件类型 type 转换对应 index 以及 unit
|
||||||
|
*/
|
||||||
|
export function getLineIndexUnit (type, show) {
|
||||||
|
switch (type) {
|
||||||
|
case 'establishLatencyMs': {
|
||||||
|
return show ? '(ms)' : 0
|
||||||
|
}
|
||||||
|
case 'tcpLostlenPercent': {
|
||||||
|
return show ? '(%)' : 3
|
||||||
|
}
|
||||||
|
case 'pktRetransPercent': {
|
||||||
|
return show ? '(%)' : 4
|
||||||
|
}
|
||||||
|
case 'httpResponseLatency': {
|
||||||
|
return show ? '(ms)' : 1
|
||||||
|
}
|
||||||
|
case 'sslConLatency': {
|
||||||
|
return show ? '(ms)' : 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ function asciiCompute (num, ascii = 1000, units, dot = 2) {
|
|||||||
return ['', '']
|
return ['', '']
|
||||||
}
|
}
|
||||||
num = Number(num)
|
num = Number(num)
|
||||||
|
if (num === 0) {
|
||||||
|
return [0, '']
|
||||||
|
}
|
||||||
let carry = 0
|
let carry = 0
|
||||||
if (num > 1) {
|
if (num > 1) {
|
||||||
const log = Math.log(num) / Math.log(ascii)
|
const log = Math.log(num) / Math.log(ascii)
|
||||||
|
|||||||
@@ -38,21 +38,6 @@ export default {
|
|||||||
i18n: 'overall.operationLog',
|
i18n: 'overall.operationLog',
|
||||||
path: '/administration/operationLog',
|
path: '/administration/operationLog',
|
||||||
icon: 'cn-icon cn-icon-operation-log'
|
icon: 'cn-icon cn-icon-operation-log'
|
||||||
},
|
|
||||||
{
|
|
||||||
i18n: 'I18n',
|
|
||||||
path: '/administration/i18n',
|
|
||||||
icon: 'cn-icon cn-icon-i18n'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
i18n: 'galaxyProxy.galaxyProxy',
|
|
||||||
path: '/administration/galaxyProxy',
|
|
||||||
icon: 'cn-icon cn-icon-proxy'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
i18n: 'overall.chart',
|
|
||||||
path: '/administration/chart',
|
|
||||||
icon: 'cn-icon cn-icon-chart'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export default {
|
|||||||
const boxDom = document.getElementById('frame-box')
|
const boxDom = document.getElementById('frame-box')
|
||||||
const dom = document.getElementById('frame')
|
const dom = document.getElementById('frame')
|
||||||
const height = boxDom.offsetHeight
|
const height = boxDom.offsetHeight
|
||||||
dom.src = `http://192.168.44.114:8088/superset/explore/?r=15&standalone=1&height=${height || 800}`
|
dom.src = BASE_CONFIG.logUrl + '&height=' + (height + 100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ export default {
|
|||||||
},
|
},
|
||||||
reload () {
|
reload () {
|
||||||
this.copyDataList.forEach(item => {
|
this.copyDataList.forEach(item => {
|
||||||
if (this.$refs['chart' + item.id]) {
|
if (this.$refs['chart' + item.id] && this.$refs['chart' + item.id][0]) {
|
||||||
this.$refs['chart' + item.id].reload()
|
this.$refs['chart' + item.id][0].reload()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,20 +11,40 @@
|
|||||||
<div class="domain-detail-list__content">{{ $_.get(chartData, "org") || '-'}}</div>
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "org") || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="domain-detail-list__row">
|
<div class="domain-detail-list__row">
|
||||||
<div class="domain-detail-list__label">Email</div>
|
<div class="domain-detail-list__label">注册机构邮箱</div>
|
||||||
<div class="domain-detail-list__content">{{ $_.get(chartData, "email") || '-'}}</div>
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "email") || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="domain-detail-list__row">
|
<div class="domain-detail-list__row">
|
||||||
<div class="domain-detail-list__label">{{$t('overall.country')}}</div>
|
<div class="domain-detail-list__label">注册机构电话</div>
|
||||||
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "domainWhoisPhone") || '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="domain-detail-list__row">
|
||||||
|
<div class="domain-detail-list__label">注册国家</div>
|
||||||
<div class="domain-detail-list__content">{{ $_.get(chartData, "country") || '-'}}</div>
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "country") || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="domain-detail-list__row">
|
<div class="domain-detail-list__row">
|
||||||
<div class="domain-detail-list__label">{{$t('entities.creationDate')}}</div>
|
<div class="domain-detail-list__label">注册地邮编</div>
|
||||||
<div class="domain-detail-list__content">{{ dateFormatByAppearance($_.get(chartData, "createTime") * 1) || '-'}}</div>
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "domainWhoisPostcode") || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="domain-detail-list__row">
|
<div class="domain-detail-list__row">
|
||||||
<div class="domain-detail-list__label">{{$t('entities.expirationDate')}}</div>
|
<div class="domain-detail-list__label">{{$t('entities.creationDate')}}</div>
|
||||||
<div class="domain-detail-list__content">{{ dateFormatByAppearance($_.get(chartData, "expirationTime") * 1) || '-'}}</div>
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "createTime") ? dateFormatByAppearance($_.get(chartData, "createTime") * 1) : '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="domain-detail-list__row">
|
||||||
|
<div class="domain-detail-list__label">过期时间</div>
|
||||||
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "expirationTime") ? dateFormatByAppearance($_.get(chartData, "expirationTime") * 1) : '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="domain-detail-list__row">
|
||||||
|
<div class="domain-detail-list__label">主办单位名称</div>
|
||||||
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "domainIcpCompanyName") || '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="domain-detail-list__row">
|
||||||
|
<div class="domain-detail-list__label">主办单位性质</div>
|
||||||
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "domainIcpCompanyType") || '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="domain-detail-list__row">
|
||||||
|
<div class="domain-detail-list__label">网站备案号</div>
|
||||||
|
<div class="domain-detail-list__content">{{ $_.get(chartData, "domainIcpSiteLicense") || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export default {
|
|||||||
? legendMapping[
|
? legendMapping[
|
||||||
`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`
|
`${this.entity && this.entity.ip ? 'ip_' : ''}${r.legend}`
|
||||||
]
|
]
|
||||||
: (legendMapping[r.legend] ? legendMapping[r.legend] : humpToSpace(r.legend)),
|
: (legendMapping[r.legend] ? legendMapping[r.legend] : r.legend),
|
||||||
data: r.values.map((v) => [
|
data: r.values.map((v) => [
|
||||||
Number(v[0]) * 1000,
|
Number(v[0]) * 1000,
|
||||||
Number(v[1]),
|
Number(v[1]),
|
||||||
|
|||||||
@@ -35,10 +35,12 @@ export default {
|
|||||||
initEcharts (id) {
|
initEcharts (id) {
|
||||||
this.initDom(id, 2)
|
this.initDom(id, 2)
|
||||||
const chartParams = this.chartInfo.params
|
const chartParams = this.chartInfo.params
|
||||||
const domains = this.chartData.map(function (item, i) {
|
let domains = this.chartData.map(function (item, i) {
|
||||||
return item.domain
|
return item.domain
|
||||||
}).join(',')
|
}).join(',')
|
||||||
|
// 参数字符串限制长度在4300以内。经测试,超过4600左右会报错
|
||||||
|
domains = domains.substring(0, 4300)
|
||||||
|
domains = domains.substring(0, domains.lastIndexOf(','))
|
||||||
const byType = new Promise(resolve => {
|
const byType = new Promise(resolve => {
|
||||||
get(replaceUrlPlaceholder(chartParams.byCategoryUrl, { domains: domains })).then(response => {
|
get(replaceUrlPlaceholder(chartParams.byCategoryUrl, { domains: domains })).then(response => {
|
||||||
if (response.code === 200) {
|
if (response.code === 200) {
|
||||||
@@ -47,7 +49,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
// this.noData0 = false
|
// this.noData0 = false
|
||||||
// chartOption = this.$_.cloneDeep(this.chartOption)
|
// chartOption = this.$_.cloneDeep(this.chartOption)
|
||||||
const data = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
const originalData = response.data.result.sort(reverseSortBy('uniqDomains')).map(d => {
|
||||||
return {
|
return {
|
||||||
data: d,
|
data: d,
|
||||||
name: d.categoryName,
|
name: d.categoryName,
|
||||||
@@ -55,6 +57,22 @@ export default {
|
|||||||
unitType: chartParams.unitType
|
unitType: chartParams.unitType
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const data = originalData.filter((d, i) => i < 5)
|
||||||
|
let otherValue = 0
|
||||||
|
originalData.forEach((d, i) => {
|
||||||
|
if (i > 4) {
|
||||||
|
otherValue += parseInt(d.uniqDomains)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
data.push({
|
||||||
|
data: {
|
||||||
|
uniqDomains: otherValue,
|
||||||
|
categoryName: 'other'
|
||||||
|
},
|
||||||
|
name: 'other',
|
||||||
|
value: otherValue,
|
||||||
|
unitType: chartParams.unitType
|
||||||
|
})
|
||||||
this.chartOption.series[0].data = data
|
this.chartOption.series[0].data = data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,10 +202,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data-protocol-value">
|
<div class="content__data-protocol-value">
|
||||||
<div class="content__data-protocol-value-title">{{$t('protocol.requestVolume')}}</div>
|
<div class="content__data-protocol-value-title">{{$t('protocol.totalFlow')}}</div>
|
||||||
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'bytes'), chartInfo.params.unitType).join('')}}</div>
|
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'count'), chartInfo.params.unitType).join('')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'bytesPercent'), unitTypes.percent).join('')}}</span></div>
|
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'countPercent'), unitTypes.percent).join('')}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data-protocol">
|
<div class="content__data-protocol">
|
||||||
<div class="content__data-protocol-all">
|
<div class="content__data-protocol-all">
|
||||||
@@ -214,10 +214,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data-protocol-value">
|
<div class="content__data-protocol-value">
|
||||||
<div class="content__data-protocol-value-title">{{$t('protocol.totalFlow')}}</div>
|
<div class="content__data-protocol-value-title">{{$t('protocol.requestVolume')}}</div>
|
||||||
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'count'), chartInfo.params.unitType).join('')}}</div>
|
<div class="content__data-protocol-value-num">{{unitConvert($_.get(chartData, 'bytes'), unitTypes.byte).join('')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'countPercent'), unitTypes.percent).join('')}}</span></div>
|
<div class="content__data-protocol-percent"><span>{{$t('protocol.proportion')}}</span> <span>{{unitConvert($_.get(chartData, 'bytesPercent'), unitTypes.percent).join('')}}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -64,11 +64,11 @@ export const legendMapping = {
|
|||||||
ip_packets_sent_rate: i18n.global.t('trafficSummary.packetsPerSecondS2c'),
|
ip_packets_sent_rate: i18n.global.t('trafficSummary.packetsPerSecondS2c'),
|
||||||
dnsLatency: i18n.global.t('dns.latency'),
|
dnsLatency: i18n.global.t('dns.latency'),
|
||||||
queryRate: i18n.global.t('dns.query.rate'),
|
queryRate: i18n.global.t('dns.query.rate'),
|
||||||
formatErrorRate: i18n.global.t('dns.formatErrorRate'),
|
formatErrorRate: 'FormErr',
|
||||||
serverFailureRate: i18n.global.t('dns.serverFailureRate'),
|
serverFailureRate: 'ServFail',
|
||||||
nonExistentDomainRate: i18n.global.t('dns.nonExistentDomainRate'),
|
nonExistentDomainRate: 'NXDomain',
|
||||||
notImplementedRate: i18n.global.t('dns.notImplementedRate'),
|
notImplementedRate: 'NotImp',
|
||||||
queryRefusedRate: i18n.global.t('dns.queryRefusedRate'),
|
queryRefusedRate: 'Refused',
|
||||||
sequenceGapLossPercent: i18n.global.t('entity.ip.sequenceGapLossPercent'),
|
sequenceGapLossPercent: i18n.global.t('entity.ip.sequenceGapLossPercent'),
|
||||||
establishLatency: i18n.global.t('entity.ip.establishLatency'),
|
establishLatency: i18n.global.t('entity.ip.establishLatency'),
|
||||||
httpResponseLatency: i18n.global.t('entity.ip.httpResponseLatency'),
|
httpResponseLatency: i18n.global.t('entity.ip.httpResponseLatency'),
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ export const line = {
|
|||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
type: 'value',
|
type: 'value',
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
formatter: function (value) {
|
formatter: function (value) {
|
||||||
return unitConvert(value, unitTypes.number, null, null, 0).join(' ')
|
return unitConvert(value, unitTypes.number, null, null, 0).join(' ')
|
||||||
@@ -30,7 +33,7 @@ export const line = {
|
|||||||
},
|
},
|
||||||
animation: false,
|
animation: false,
|
||||||
grid: {
|
grid: {
|
||||||
left: 55,
|
left: 60,
|
||||||
bottom: 30,
|
bottom: 30,
|
||||||
top: 20,
|
top: 20,
|
||||||
right: 25
|
right: 25
|
||||||
@@ -62,7 +65,7 @@ export const line = {
|
|||||||
{
|
{
|
||||||
name: '',
|
name: '',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: false,
|
smooth: true,
|
||||||
symbol: 'none',
|
symbol: 'none',
|
||||||
data: [],
|
data: [],
|
||||||
markLine: {}
|
markLine: {}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
reload () {
|
reload () {
|
||||||
this.dnsScreenDataList.forEach(item => {
|
this.dnsScreenDataList.forEach(item => {
|
||||||
if (this.$refs['chart' + item.id]) {
|
if (this.$refs['chart' + item.id] && this.$refs['chart' + item.id][0]) {
|
||||||
this.$refs['chart' + item.id].getChartData()
|
this.$refs['chart' + item.id][0].getChartData()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -334,6 +334,8 @@ export default {
|
|||||||
if (!this.$refs.dateTimeRange.isCustom) {
|
if (!this.$refs.dateTimeRange.isCustom) {
|
||||||
const value = this.timeFilter.dateRangeValue
|
const value = this.timeFilter.dateRangeValue
|
||||||
this.$refs.dateTimeRange.quickChange(value)
|
this.$refs.dateTimeRange.quickChange(value)
|
||||||
|
} else {
|
||||||
|
this.timeFilter = JSON.parse(JSON.stringify(this.timeFilter))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.timeFilter = JSON.parse(JSON.stringify(this.timeFilter))
|
this.timeFilter = JSON.parse(JSON.stringify(this.timeFilter))
|
||||||
|
|||||||
@@ -123,11 +123,8 @@ export default {
|
|||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(api.dnsInsight.activeMaliciousDomain, params).then(res => {
|
get(api.dnsInsight.activeMaliciousDomain, params).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
const data = res.data.result
|
this.isNoData = res.data.result.length === 0
|
||||||
if (!data || data.length === 0) {
|
this.tableData = res.data.result
|
||||||
this.isNoData = true
|
|
||||||
}
|
|
||||||
this.tableData = data
|
|
||||||
} else {
|
} else {
|
||||||
this.isNoData = true
|
this.isNoData = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,9 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -208,9 +208,7 @@ export default {
|
|||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(api.dnsInsight.recentEvents, params).then(res => {
|
get(api.dnsInsight.recentEvents, params).then(res => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
if (!res.data.result || res.data.result.length === 0) {
|
this.isNoData = res.data.result.length === 0
|
||||||
this.isNoData = true
|
|
||||||
}
|
|
||||||
this.tableData = res.data.result
|
this.tableData = res.data.result
|
||||||
this.tableData.forEach((t, index) => {
|
this.tableData.forEach((t, index) => {
|
||||||
if (index > 5) {
|
if (index > 5) {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ import { getSecond } from '@/utils/date-util'
|
|||||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { getLineType, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
export default {
|
export default {
|
||||||
name: 'DnsTrafficLine',
|
name: 'DnsTrafficLine',
|
||||||
components: {
|
components: {
|
||||||
@@ -207,63 +207,9 @@ export default {
|
|||||||
{ analysis: {}, name: 'network.inbound', class: 'inbound', show: true, invertTab: true, positioning: 1, 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.outbound', class: 'outbound', show: true, invertTab: true, positioning: 2, data: [], unitType: '' }
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
this.initData(res.data.result, val, active, show)
|
||||||
}
|
}
|
||||||
res.data.result.forEach((t) => {
|
|
||||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
|
||||||
const mpackets = _.cloneDeep(this.mpackets)
|
|
||||||
mpackets[0].analysis = t.totalBitsRate.analysis
|
|
||||||
mpackets[1].analysis = t.inboundBitsRate.analysis
|
|
||||||
mpackets[2].analysis = t.outboundBitsRate.analysis
|
|
||||||
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' && parseFloat(e.analysis.avg) === 0) {
|
|
||||||
e.show = false
|
|
||||||
num += 1
|
|
||||||
} else {
|
|
||||||
e.show = true
|
|
||||||
if (!active && show !== this.lineRefer) {
|
|
||||||
this.legendSelectChange(e, 'index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.lineTab === e.class) {
|
|
||||||
if (parseFloat(e.analysis.avg) <= 0) {
|
|
||||||
this.lineTab = ''
|
|
||||||
this.lineRefer = ''
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mpackets = mpackets
|
|
||||||
if (num === 3) {
|
|
||||||
mpackets[0].invertTab = false
|
|
||||||
this.lineTab = 'total'
|
|
||||||
this.legendSelectChange(mpackets[0], 0)
|
|
||||||
this.echartsInit(this.mpackets)
|
|
||||||
} else {
|
|
||||||
this.echartsInit(this.mpackets, show)
|
|
||||||
if (!this.lineRefer) this.lineRefer = 'Average'
|
|
||||||
}
|
|
||||||
} else if (t.type === 'queries' && val === 'Queries/s') {
|
|
||||||
const mpackets = _.cloneDeep(this.mpackets)
|
|
||||||
mpackets[0].analysis = t.totalQueryRate.analysis
|
|
||||||
mpackets[0].data = t.totalQueryRate.values ? t.totalQueryRate.values : []
|
|
||||||
mpackets.forEach((e, i) => {
|
|
||||||
if (i !== 0) {
|
|
||||||
e.show = false
|
|
||||||
}
|
|
||||||
e.unitType = 'queries/s'
|
|
||||||
e.invertTab = false
|
|
||||||
this.lineTab = 'total'
|
|
||||||
this.legendSelectChange(e, 0)
|
|
||||||
})
|
|
||||||
this.mpackets = mpackets
|
|
||||||
this.echartsInit(this.mpackets, true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
this.showError = true
|
this.showError = true
|
||||||
@@ -526,6 +472,79 @@ export default {
|
|||||||
dataIntegrationArray.sort((a, b) => { return a[1] - b[1] })
|
dataIntegrationArray.sort((a, b) => { return a[1] - b[1] })
|
||||||
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
||||||
return this.sizes[sortIndex]
|
return this.sizes[sortIndex]
|
||||||
|
},
|
||||||
|
initData (data, val, active, show) {
|
||||||
|
let lineData = []
|
||||||
|
if (data !== undefined && data.length > 0) {
|
||||||
|
data.forEach((item) => {
|
||||||
|
item.type = getLineType(item.type)
|
||||||
|
if (item.type === val) {
|
||||||
|
lineData = Object.keys(item).map(t => {
|
||||||
|
return {
|
||||||
|
...item[t]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
lineData.splice(0, 1)
|
||||||
|
const mpackets = _.cloneDeep(this.mpackets)
|
||||||
|
if (val === 'Queries/s') {
|
||||||
|
lineData.forEach((d, i) => {
|
||||||
|
mpackets[i].data = d.values
|
||||||
|
mpackets[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
mpackets.forEach((e, i) => {
|
||||||
|
if (i !== 0) {
|
||||||
|
e.show = false
|
||||||
|
}
|
||||||
|
e.unitType = 'queries/s'
|
||||||
|
e.invertTab = false
|
||||||
|
this.lineTab = 'total'
|
||||||
|
this.legendSelectChange(e, 0)
|
||||||
|
})
|
||||||
|
this.mpackets = mpackets
|
||||||
|
this.echartsInit(this.mpackets, true)
|
||||||
|
} else {
|
||||||
|
const unit = 'bps'
|
||||||
|
this.legendInit(lineData, active, show, unit, mpackets)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legendInit (data, active, show, type, dnsData) {
|
||||||
|
data.forEach((d, i) => {
|
||||||
|
dnsData[i].data = d.values
|
||||||
|
dnsData[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
let num = 0
|
||||||
|
dnsData.forEach(e => {
|
||||||
|
e.unitType = type
|
||||||
|
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
||||||
|
e.show = false
|
||||||
|
num += 1
|
||||||
|
} else {
|
||||||
|
e.show = true
|
||||||
|
if (!active && show !== this.lineRefer) {
|
||||||
|
this.legendSelectChange(e, 'index')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.lineTab === e.class) {
|
||||||
|
if (parseFloat(e.analysis.avg) <= 0) {
|
||||||
|
this.lineTab = ''
|
||||||
|
this.lineRefer = ''
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.mpackets = dnsData
|
||||||
|
if (num === 3) {
|
||||||
|
dnsData[0].invertTab = false
|
||||||
|
this.lineTab = 'total'
|
||||||
|
this.legendSelectChange(dnsData[0], 0)
|
||||||
|
this.echartsInit(this.mpackets)
|
||||||
|
} else {
|
||||||
|
this.echartsInit(this.mpackets, show)
|
||||||
|
if (!this.lineRefer) this.lineRefer = 'Average'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -542,7 +561,9 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.chartOption = null
|
this.chartOption = null
|
||||||
this.unitConvert = null
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="link-statistical-dimension" style="position: relative">
|
<div class="link-statistical-dimension" style="position: relative">
|
||||||
<div class="dimension-title">{{ $t('linkMonitor.egressLink') }} & {{ $t('linkMonitor.ingressLink') }}
|
<div class="dimension-title" v-if="gridData.length>3">{{ $t('linkMonitor.egressLink') }} & {{ $t('linkMonitor.ingressLink') }}</div>
|
||||||
</div>
|
<div class="dimension-title" v-else>{{ $t('linkMonitor.nextHopInternetOfGrid') }}</div>
|
||||||
|
|
||||||
<chart-no-data v-if="isNoData"></chart-no-data>
|
<chart-no-data v-if="isNoData"></chart-no-data>
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ import { useRoute } from 'vue-router'
|
|||||||
import { ref, shallowRef } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
import { chartColor3, chartColor4, unitTypes } from '@/utils/constants'
|
import { chartColor3, chartColor4, unitTypes } from '@/utils/constants'
|
||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { getLineType, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { get } from '@/utils/http'
|
import { get } from '@/utils/http'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
@@ -187,94 +187,9 @@ export default {
|
|||||||
{ analysis: {}, name: 'linkMonitor.ingress', class: 'ingress', show: true, invertTab: true, positioning: 1, 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: '' }
|
{ analysis: {}, name: 'linkMonitor.egress', class: 'egress', show: true, invertTab: true, positioning: 2, data: [], unitType: '' }
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
this.initData(res.data.result, val, active, show)
|
||||||
}
|
}
|
||||||
res.data.result.forEach((t) => {
|
|
||||||
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 : []
|
|
||||||
let num = 0
|
|
||||||
mpackets.forEach(e => {
|
|
||||||
e.unitType = 'bps'
|
|
||||||
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
|
||||||
e.show = false
|
|
||||||
num += 1
|
|
||||||
} else {
|
|
||||||
e.show = true
|
|
||||||
if (!active && !show) {
|
|
||||||
this.legendSelectChange(e, 'index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.lineTab === e.class) {
|
|
||||||
if (parseFloat(e.analysis.avg) <= 0) {
|
|
||||||
this.lineTab = ''
|
|
||||||
this.lineRefer = ''
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mpackets = 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)
|
|
||||||
if (!this.lineRefer) this.lineRefer = 'Average'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} 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 : []
|
|
||||||
let num = 0
|
|
||||||
mpackets.forEach(e => {
|
|
||||||
e.unitType = 'packets/s'
|
|
||||||
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
|
||||||
e.show = false
|
|
||||||
num += 1
|
|
||||||
} else {
|
|
||||||
e.show = true
|
|
||||||
if (!active && !show) {
|
|
||||||
this.legendSelectChange(e, 'index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.lineTab === e.class) {
|
|
||||||
if (parseFloat(e.analysis.avg) <= 0) {
|
|
||||||
this.lineTab = ''
|
|
||||||
this.lineRefer = ''
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mpackets = 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)
|
|
||||||
if (!this.lineRefer) this.lineRefer = 'Average'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.showError = true
|
this.showError = true
|
||||||
this.errorMsg = res.message
|
this.errorMsg = res.message
|
||||||
@@ -457,6 +372,65 @@ export default {
|
|||||||
dataIntegrationArray.sort((a, b) => { return a[1] - b[1] })
|
dataIntegrationArray.sort((a, b) => { return a[1] - b[1] })
|
||||||
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
||||||
return this.sizes[sortIndex]
|
return this.sizes[sortIndex]
|
||||||
|
},
|
||||||
|
initData (data, val, active, show) {
|
||||||
|
let lineData = []
|
||||||
|
if (data !== undefined && data.length > 0) {
|
||||||
|
data.forEach((item) => {
|
||||||
|
item.type = getLineType(item.type)
|
||||||
|
if (item.type === val) {
|
||||||
|
lineData = Object.keys(item).map(t => {
|
||||||
|
return {
|
||||||
|
...item[t]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
lineData.splice(0, 1)
|
||||||
|
const mpackets = _.cloneDeep(this.mpackets)
|
||||||
|
const unit = val === 'Bits/s' ? 'bps' : 'packets/s'
|
||||||
|
this.legendInit(lineData, active, show, unit, mpackets)
|
||||||
|
},
|
||||||
|
legendInit (data, active, show, type, linkData) {
|
||||||
|
data.forEach((d, i) => {
|
||||||
|
linkData[i].data = d.values
|
||||||
|
linkData[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
let num = 0
|
||||||
|
linkData.forEach(e => {
|
||||||
|
e.unitType = type
|
||||||
|
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
||||||
|
e.show = false
|
||||||
|
num += 1
|
||||||
|
} else {
|
||||||
|
e.show = true
|
||||||
|
if (!active && !show) {
|
||||||
|
this.legendSelectChange(e, 'index')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.lineTab === e.class) {
|
||||||
|
if (parseFloat(e.analysis.avg) <= 0) {
|
||||||
|
this.lineTab = ''
|
||||||
|
this.lineRefer = ''
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.mpackets = linkData
|
||||||
|
if (num === 3) {
|
||||||
|
linkData[0].invertTab = false
|
||||||
|
this.lineTab = 'total'
|
||||||
|
this.legendSelectChange(linkData[0], 0)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.echartsInit(this.mpackets)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.echartsInit(this.mpackets)
|
||||||
|
if (!this.lineRefer) this.lineRefer = 'Average'
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -473,7 +447,9 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.chartOption = null
|
this.chartOption = null
|
||||||
this.unitConvert = null
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,15 +102,12 @@ export default {
|
|||||||
if (condition.length > 1) {
|
if (condition.length > 1) {
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
params.q = condition.find(c => c.indexOf('common_ingress_link_id') > -1 || c.indexOf('ingress_link_direction') > -1)
|
params.q = condition.find(c => c.indexOf('common_ingress_link_id') > -1 || c.indexOf('ingress_link_direction') > -1)
|
||||||
|
url = api.linkMonitor.drilldownQuadrupleIngressAnalysis // 入口
|
||||||
} else {
|
} else {
|
||||||
params.q = condition.find(c => c.indexOf('common_egress_link_id') > -1 || c.indexOf('egress_link_direction') > -1)
|
params.q = condition.find(c => c.indexOf('common_egress_link_id') > -1 || c.indexOf('egress_link_direction') > -1)
|
||||||
|
url = api.linkMonitor.drilldownQquadrupleEgressAnalysis // 出口
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (n === 0) {
|
|
||||||
url = api.linkMonitor.drilldownQuadrupleIngressAnalysis // 入口
|
|
||||||
} else {
|
|
||||||
url = api.linkMonitor.drilldownQquadrupleEgressAnalysis // 出口
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (n === 0) {
|
if (n === 0) {
|
||||||
url = api.linkMonitor.quadrupleIngressAnalysis // 入口
|
url = api.linkMonitor.quadrupleIngressAnalysis // 入口
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ export default {
|
|||||||
searcherApp: '',
|
searcherApp: '',
|
||||||
// 选中的app,不区分app和provider
|
// 选中的app,不区分app和provider
|
||||||
toSaveApp: [],
|
toSaveApp: [],
|
||||||
appShowType: 'bytes',
|
|
||||||
pageObj: { // 分页对象
|
pageObj: { // 分页对象
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 24,
|
pageSize: 24,
|
||||||
@@ -248,7 +247,7 @@ export default {
|
|||||||
handleData (prevRequest, request, _t) {
|
handleData (prevRequest, request, _t) {
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
Promise.all([prevRequest, request]).then(res => {
|
Promise.all([prevRequest, request]).then(res => {
|
||||||
this.isNoData = (res[0].data.result.length && res[1].data.result.length) === 0
|
this.isNoData = res[0].data.result.length === 0 && res[1].data.result.length === 0
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
this.appData = this.appData.map(t => {
|
this.appData = this.appData.map(t => {
|
||||||
return {
|
return {
|
||||||
@@ -298,16 +297,6 @@ export default {
|
|||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
metricChange (value) {
|
|
||||||
if (value === 'Bits/s') {
|
|
||||||
this.appShowType = 'bytes'
|
|
||||||
} else if (value === 'Packets/s') {
|
|
||||||
this.appShowType = 'packets'
|
|
||||||
} else if (value === 'Sessions/s') {
|
|
||||||
this.appShowType = 'sessions'
|
|
||||||
}
|
|
||||||
this.init()
|
|
||||||
},
|
|
||||||
getUrlParam (param, defaultValue, isNumber) {
|
getUrlParam (param, defaultValue, isNumber) {
|
||||||
if (isNumber) {
|
if (isNumber) {
|
||||||
return this.$route.query[param] ? Number(this.$route.query[param]) : defaultValue
|
return this.$route.query[param] ? Number(this.$route.query[param]) : defaultValue
|
||||||
@@ -675,13 +664,6 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// moreChange (app) {
|
|
||||||
// this.appData.forEach(t => {
|
|
||||||
// if (t.name === app.name && t.type === app.type) {
|
|
||||||
// t.moreOptions = !t.moreOptions
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// },
|
|
||||||
resize () {
|
resize () {
|
||||||
this.myChart.forEach(t => {
|
this.myChart.forEach(t => {
|
||||||
t.resize()
|
t.resize()
|
||||||
@@ -734,7 +716,9 @@ export default {
|
|||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
clearTimeout(this.timerScroll)
|
clearTimeout(this.timerScroll)
|
||||||
clearTimeout(this.timerSearch)
|
clearTimeout(this.timerSearch)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.unitConvert = null
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,15 +11,15 @@
|
|||||||
<div class="ddos-detection-type">
|
<div class="ddos-detection-type">
|
||||||
<div class="ddos-detection-type-value">
|
<div class="ddos-detection-type-value">
|
||||||
<div class="ddos-detection-type-value-name">{{$t('network.numberOfAttacks')}}</div>
|
<div class="ddos-detection-type-value-name">{{$t('network.numberOfAttacks')}}</div>
|
||||||
<div class="ddos-detection-type-value-number">{{$_.get(ddosData, 'attackerCount') || 0}}</div>
|
<div class="ddos-detection-type-value-number" test-id="attackerCount">{{unitConvert($_.get(ddosData, 'attackerCount'), unitTypes.number).join(' ')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ddos-detection-type-value">
|
<div class="ddos-detection-type-value">
|
||||||
<div class="ddos-detection-type-value-name">{{$t('network.number0fVictims')}}</div>
|
<div class="ddos-detection-type-value-name">{{$t('network.number0fVictims')}}</div>
|
||||||
<div class="ddos-detection-type-value-number">{{$_.get(ddosData, 'victimCount') || 0}}</div>
|
<div class="ddos-detection-type-value-number" test-id="victimCount">{{unitConvert($_.get(ddosData, 'victimCount'), unitTypes.number).join(' ')}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ddos-detection-type-value">
|
<div class="ddos-detection-type-value">
|
||||||
<div class="ddos-detection-type-value-name">{{$t('network.number0fDetectedAttackEvents')}}</div>
|
<div class="ddos-detection-type-value-name">{{$t('network.number0fDetectedAttackEvents')}}</div>
|
||||||
<div class="ddos-detection-type-value-number ddos-event">{{$_.get(ddosData, 'attackEventCount') || 0}}</div>
|
<div class="ddos-detection-type-value-number ddos-event" test-id="attackEventCount">{{unitConvert($_.get(ddosData, 'attackEventCount'), unitTypes.number).join(' ')}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-button size="small">{{$t('network.ddosDetection')}}<i class="cn-icon cn-icon-arrow-right"></i></el-button>
|
<el-button size="small">{{$t('network.ddosDetection')}}<i class="cn-icon cn-icon-arrow-right"></i></el-button>
|
||||||
@@ -29,11 +29,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { get } from '@/utils/http'
|
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
|
import unitConvert from '@/utils/unit-convert'
|
||||||
|
import { unitTypes } from '@/utils/constants'
|
||||||
|
import axios from 'axios'
|
||||||
export default {
|
export default {
|
||||||
name: 'NetworkOverviewDdosDetection',
|
name: 'NetworkOverviewDdosDetection',
|
||||||
components: {
|
components: {
|
||||||
@@ -44,6 +46,8 @@ export default {
|
|||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
ddosData: {},
|
ddosData: {},
|
||||||
|
unitConvert,
|
||||||
|
unitTypes,
|
||||||
isNoData: false,
|
isNoData: false,
|
||||||
showError: false,
|
showError: false,
|
||||||
errorMsg: ''
|
errorMsg: ''
|
||||||
@@ -59,19 +63,16 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
ddosDetectDataRequests () {
|
ddosDetectDataRequests () {
|
||||||
const params = {
|
const params = {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: this.timeFilter && this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : '',
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: this.timeFilter && this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : ''
|
||||||
}
|
}
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(api.netWorkOverview.ddosEventAnalysis, params).then(res => {
|
axios.get(api.netWorkOverview.ddosEventAnalysis, { params: params }).then(res => {
|
||||||
|
res = res.data
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
if (res.data.result.length === 0) {
|
this.isNoData = res.data.result.length === 0
|
||||||
this.isNoData = true
|
this.ddosData = res.data.result[0]
|
||||||
} else {
|
|
||||||
this.ddosData = res.data.result[0]
|
|
||||||
this.isNoData = false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
this.showError = true
|
this.showError = true
|
||||||
@@ -87,7 +88,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.ddosDetectDataRequests()
|
this.$nextTick(() => {
|
||||||
|
this.ddosDetectDataRequests()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -12,15 +12,18 @@
|
|||||||
:key="index"
|
:key="index"
|
||||||
@mouseenter="mouseenter(item)"
|
@mouseenter="mouseenter(item)"
|
||||||
@mouseleave="mouseleave(item)"
|
@mouseleave="mouseleave(item)"
|
||||||
@click="activeChange(item, index)">
|
@click="activeChange(item, index)"
|
||||||
|
:test-id="`tab${index}`"
|
||||||
|
>
|
||||||
<div class="line-value-mpackets-name">
|
<div class="line-value-mpackets-name">
|
||||||
<div :class="item.class"></div>
|
<div :class="item.class"></div>
|
||||||
<div class="mpackets-name">{{$t(item.name)}}</div>
|
<div class="mpackets-name">{{$t(item.name)}}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="line-value-unit">
|
<div class="line-value-unit" :test-id="`tabContent${index}`">
|
||||||
<span class="line-value-unit-number">{{unitConvert(item.analysis.avg, unitTypes.number)[0]}}</span>
|
<span class="line-value-unit-number">{{unitConvert(item.analysis.avg, unitTypes.number)[0]}}</span>
|
||||||
<span class="line-value-unit-number2">
|
<span class="line-value-unit-number2">
|
||||||
<span>{{unitConvert(item.analysis.avg, unitTypes.number)[1]}}</span><span v-if="item.unitType">{{item.unitType}}</span>
|
<span>{{unitConvert(item.analysis.avg, unitTypes.number)[1]}}</span>
|
||||||
|
<span v-if="item.unitType">{{item.unitType}}</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -46,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div style="height: calc(100% - 74px); position: relative">
|
<div style="height: calc(100% - 74px); position: relative">
|
||||||
<chart-no-data v-if="isNoData && !showError"></chart-no-data>
|
<chart-no-data v-if="isNoData && !showError"></chart-no-data>
|
||||||
<div class="chart-drawing" v-show="showMarkLine && !isNoData && !showError" id="overviewLineChart"></div>
|
<div class="chart-drawing" v-show="showMarkLine && !isNoData && !showError" ref="overviewLineChart"></div>
|
||||||
<!-- todo 后续改动,此处为框选返回-->
|
<!-- todo 后续改动,此处为框选返回-->
|
||||||
<!-- <div id="brushBtn" style="position: absolute;left: 0;top: 0;" v-show="mouseDownFlag">-->
|
<!-- <div id="brushBtn" style="position: absolute;left: 0;top: 0;" v-show="mouseDownFlag">-->
|
||||||
<!-- <el-button @click.stop="backBrushHistory">返回</el-button>-->
|
<!-- <el-button @click.stop="backBrushHistory">返回</el-button>-->
|
||||||
@@ -63,13 +66,13 @@ import { unitTypes, chartColor3, chartColor4 } from '@/utils/constants.js'
|
|||||||
import { ref, shallowRef } from 'vue'
|
import { ref, shallowRef } from 'vue'
|
||||||
import { stackedLineTooltipFormatter } from '@/views/charts/charts/tools'
|
import { stackedLineTooltipFormatter } from '@/views/charts/charts/tools'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { get } from '@/utils/http'
|
import axios from 'axios'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { getLineType, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
export default {
|
export default {
|
||||||
name: 'NetworkOverviewLine',
|
name: 'NetworkOverviewLine',
|
||||||
@@ -186,32 +189,16 @@ export default {
|
|||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: getSecond(this.timeFilter.endTime)
|
||||||
}
|
}
|
||||||
let condition = ''
|
if (this.queryCondition) {
|
||||||
if (this.queryCondition && this.tabOperationType !== '3') {
|
|
||||||
params.q = this.queryCondition
|
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)
|
this.toggleLoading(true)
|
||||||
|
axios.get(api.netWorkOverview.totalTrafficAnalysis, { params: params }).then(response => {
|
||||||
get(api.netWorkOverview.totalTrafficAnalysis, params).then((res) => {
|
const res = response.data
|
||||||
this.errorMsg = res.message
|
this.errorMsg = res.message
|
||||||
|
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.isNoData = res.data.result.length === 0
|
this.isNoData = res.data.result.length === 0
|
||||||
this.showError = false
|
this.showError = false
|
||||||
|
|
||||||
if (this.isNoData) {
|
if (this.isNoData) {
|
||||||
this.lineTab = ''
|
this.lineTab = ''
|
||||||
this.mpackets = [
|
this.mpackets = [
|
||||||
@@ -222,125 +209,9 @@ export default {
|
|||||||
{ analysis: {}, name: 'network.through', class: 'through', show: true, invertTab: true, positioning: 4, 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: '' }
|
{ analysis: {}, name: 'network.other', class: 'other', show: true, invertTab: true, positioning: 5, data: [], unitType: '' }
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
this.initData(res.data.result, val, active, show, n)
|
||||||
}
|
}
|
||||||
res.data.result.forEach((t) => {
|
|
||||||
if (t.type === 'bytes' && val === 'Bits/s') {
|
|
||||||
const mpackets = _.cloneDeep(this.mpackets)
|
|
||||||
mpackets[0].analysis = t.totalBitsRate.analysis
|
|
||||||
mpackets[1].analysis = t.inboundBitsRate.analysis
|
|
||||||
mpackets[2].analysis = t.outboundBitsRate.analysis
|
|
||||||
mpackets[3].analysis = t.internalBitsRate.analysis
|
|
||||||
mpackets[4].analysis = t.throughBitsRate.analysis
|
|
||||||
mpackets[5].analysis = t.other.analysis
|
|
||||||
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 : []
|
|
||||||
let num = 0
|
|
||||||
mpackets.forEach(e => {
|
|
||||||
e.unitType = 'bps'
|
|
||||||
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
|
||||||
e.show = false
|
|
||||||
num += 1
|
|
||||||
} else {
|
|
||||||
e.show = true
|
|
||||||
if (!active && show !== this.lineRefer) {
|
|
||||||
this.legendSelectChange(e, 'index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.lineTab === e.class) {
|
|
||||||
if (parseFloat(e.analysis.avg) <= 0) {
|
|
||||||
this.lineTab = ''
|
|
||||||
this.lineRefer = ''
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mpackets = mpackets
|
|
||||||
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)
|
|
||||||
if (!this.lineRefer) this.lineRefer = 'Average'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else if (t.type === 'packets' && val === 'Packets/s') {
|
|
||||||
const mpackets = _.cloneDeep(this.mpackets)
|
|
||||||
mpackets[0].analysis = t.totalPacketsRate.analysis
|
|
||||||
mpackets[1].analysis = t.inboundPacketsRate.analysis
|
|
||||||
mpackets[2].analysis = t.outboundPacketsRate.analysis
|
|
||||||
mpackets[3].analysis = t.internalPacketsRate.analysis
|
|
||||||
mpackets[4].analysis = t.throughPacketsRate.analysis
|
|
||||||
mpackets[5].analysis = t.other.analysis
|
|
||||||
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 : []
|
|
||||||
let num = 0
|
|
||||||
mpackets.forEach(e => {
|
|
||||||
e.unitType = 'packets/s'
|
|
||||||
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
|
||||||
e.show = false
|
|
||||||
num += 1
|
|
||||||
} else {
|
|
||||||
e.show = true
|
|
||||||
if (!active && show !== this.lineRefer) {
|
|
||||||
this.legendSelectChange(e, 'index')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.lineTab === e.class) {
|
|
||||||
if (parseFloat(e.analysis.avg) <= 0) {
|
|
||||||
this.lineTab = ''
|
|
||||||
this.lineRefer = ''
|
|
||||||
this.init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.mpackets = mpackets
|
|
||||||
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)
|
|
||||||
if (!this.lineRefer) this.lineRefer = 'Average'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else if (t.type === 'sessions' && val === 'Sessions/s') {
|
|
||||||
const mpackets = _.cloneDeep(this.mpackets)
|
|
||||||
mpackets[0].analysis = t.totalSessionsRate.analysis
|
|
||||||
mpackets[0].data = t.totalSessionsRate.values ? t.totalSessionsRate.values : []
|
|
||||||
mpackets.forEach((e, i) => {
|
|
||||||
if (i !== 0) {
|
|
||||||
e.show = false
|
|
||||||
}
|
|
||||||
e.unitType = 'sessions/s'
|
|
||||||
e.invertTab = false
|
|
||||||
this.lineTab = 'total'
|
|
||||||
this.legendSelectChange(e, 0)
|
|
||||||
})
|
|
||||||
this.mpackets = mpackets
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.echartsInit(this.mpackets, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.showError = true
|
this.showError = true
|
||||||
this.errorMsg = res.message
|
this.errorMsg = res.message
|
||||||
@@ -377,163 +248,163 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
echartsInit (echartsData, show) {
|
echartsInit (echartsData, show) {
|
||||||
if (this.lineTab) {
|
// echarts内容在单元测试时不执行
|
||||||
this.handleActiveBar()
|
if (!this.isUnitTesting) {
|
||||||
echartsData = echartsData.filter(t => t.show === true && t.invertTab === false)
|
if (this.lineTab) {
|
||||||
} else {
|
this.handleActiveBar()
|
||||||
echartsData = echartsData.filter(t => t.show === true)
|
echartsData = echartsData.filter(t => t.show === true && t.invertTab === false)
|
||||||
}
|
} else {
|
||||||
const _this = this
|
echartsData = echartsData.filter(t => t.show === true)
|
||||||
// !this.myChart && (this.myChart = echarts.init(dom))
|
|
||||||
// 此处为验证是否因dom未销毁,导致图表出错,后续可能会改
|
|
||||||
let dom = null
|
|
||||||
dom = document.getElementById('overviewLineChart')
|
|
||||||
|
|
||||||
this.chartOption = stackedLineChartOption
|
|
||||||
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) {
|
|
||||||
return _this.symbolSizeSortChange(i, value[0])
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
itemStyle: {
|
|
||||||
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']),
|
|
||||||
markLine: {
|
|
||||||
silent: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: '#B4B1A8'
|
|
||||||
},
|
|
||||||
symbol: 'none',
|
|
||||||
label: {
|
|
||||||
formatter (params) {
|
|
||||||
const arr = unitConvert(params.value, unitTypes.number).join('')
|
|
||||||
return _this.lineRefer + '(' + arr + echartsData[0].unitType + ')'
|
|
||||||
},
|
|
||||||
position: 'insideStartTop',
|
|
||||||
color: '#717171',
|
|
||||||
fontFamily: 'NotoSansSChineseRegular'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
const _this = this
|
||||||
if (!show) {
|
// !this.myChart && (this.myChart = echarts.init(dom))
|
||||||
this.chartOption.series.forEach((t) => {
|
// 此处为验证是否因dom未销毁,导致图表出错,后续可能会改
|
||||||
t.markLine.label.show = false
|
this.chartOption = stackedLineChartOption
|
||||||
t.markLine = []
|
const chartOption = this.chartOption.series[0]
|
||||||
})
|
this.chartOption.series = echartsData.map((t, i) => {
|
||||||
}
|
return {
|
||||||
if (this.lineRefer === 'Average' && show) {
|
...chartOption,
|
||||||
this.chartOption.series.forEach((t, i) => {
|
name: t.name,
|
||||||
t.markLine.label.show = true
|
lineStyle: {
|
||||||
t.markLine.data = [
|
color: chartColor3[t.positioning],
|
||||||
{
|
width: 1
|
||||||
yAxis: echartsData[i].analysis.avg
|
},
|
||||||
}
|
stack: t.name !== 'network.total' ? 'network.total' : '',
|
||||||
]
|
symbolSize: function (value) {
|
||||||
})
|
return _this.symbolSizeSortChange(i, value[0])
|
||||||
} else if (this.lineRefer === '95th Percentile' && show) {
|
},
|
||||||
this.chartOption.series.forEach((t, i) => {
|
emphasis: {
|
||||||
t.markLine.label.show = true
|
itemStyle: {
|
||||||
t.markLine.data = [
|
borderColor: chartColor4[t.positioning],
|
||||||
{ yAxis: echartsData[i].analysis.p95 }
|
borderWidth: 2,
|
||||||
]
|
shadowColor: chartColor4[t.positioning],
|
||||||
})
|
shadowBlur: this.sizes[t.positioning] + 2
|
||||||
} else if (this.lineRefer === 'Maximum' && show) {
|
|
||||||
this.chartOption.series.forEach((t, i) => {
|
|
||||||
t.markLine.label.show = true
|
|
||||||
t.markLine.data = [
|
|
||||||
{ yAxis: echartsData[i].analysis.max }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
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]
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
return stackedLineTooltipFormatter(params)
|
|
||||||
}
|
|
||||||
this.showMarkLine = true
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.myChart = echarts.init(dom)
|
|
||||||
this.myChart.setOption(this.chartOption)
|
|
||||||
// 设置参见官网:https://echarts.apache.org/zh/api.html#action.brush.brush
|
|
||||||
this.myChart.dispatchAction({
|
|
||||||
// 刷选模式的开关。使用此 action 可将当前鼠标变为可刷选状态。事实上,点击 toolbox 中的 brush 按钮时,就是通过这个 action,将当前普通鼠标变为刷选器的。
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
|
|
||||||
key: 'brush',
|
|
||||||
brushOption: {
|
|
||||||
// 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
|
|
||||||
brushType: 'lineX',
|
|
||||||
xAxisIndex: 'all',
|
|
||||||
// 单击清除选框
|
|
||||||
brushMode: 'single',
|
|
||||||
// 选择完毕再返回所选数据
|
|
||||||
throttleType: 'debounce'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const self = this
|
|
||||||
|
|
||||||
this.myChart.on('brushEnd', function (params) {
|
|
||||||
self.myChart.dispatchAction({
|
|
||||||
type: 'brush',
|
|
||||||
areas: [] // 删除选框
|
|
||||||
})
|
|
||||||
if (!self.mouseDownFlag) {
|
|
||||||
// 避免点击空白区域报错
|
|
||||||
if (params.areas !== undefined && params.areas.length > 0) {
|
|
||||||
self.brushHistory.unshift({
|
|
||||||
startTime: _.cloneDeep(self.timeFilter.startTime) * 1000,
|
|
||||||
endTime: _.cloneDeep(self.timeFilter.endTime) * 1000
|
|
||||||
})
|
|
||||||
|
|
||||||
const rangeObj = {
|
|
||||||
startTime: Math.ceil(params.areas[0].coordRange[0]),
|
|
||||||
endTime: Math.ceil(params.areas[0].coordRange[1])
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
// todo 目前暂定框选最小范围为5分钟,后续可能会变动
|
areaStyle: {
|
||||||
if (rangeObj.endTime - rangeObj.startTime < 5 * 60 * 1000) {
|
opacity: 0.1,
|
||||||
rangeObj.startTime = rangeObj.endTime - 5 * 60 * 1000
|
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']),
|
||||||
|
markLine: {
|
||||||
|
silent: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#B4B1A8'
|
||||||
|
},
|
||||||
|
symbol: 'none',
|
||||||
|
label: {
|
||||||
|
formatter (params) {
|
||||||
|
const arr = unitConvert(params.value, unitTypes.number).join('')
|
||||||
|
return _this.lineRefer + '(' + arr + echartsData[0].unitType + ')'
|
||||||
|
},
|
||||||
|
position: 'insideStartTop',
|
||||||
|
color: '#717171',
|
||||||
|
fontFamily: 'NotoSansSChineseRegular'
|
||||||
}
|
}
|
||||||
_this.$store.commit('setRangeEchartsData', rangeObj)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
if (!show) {
|
||||||
|
this.chartOption.series.forEach((t) => {
|
||||||
|
t.markLine.label.show = false
|
||||||
|
t.markLine = []
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (this.lineRefer === 'Average' && show) {
|
||||||
|
this.chartOption.series.forEach((t, i) => {
|
||||||
|
t.markLine.label.show = true
|
||||||
|
t.markLine.data = [
|
||||||
|
{
|
||||||
|
yAxis: echartsData[i].analysis.avg
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
} else if (this.lineRefer === '95th Percentile' && show) {
|
||||||
|
this.chartOption.series.forEach((t, i) => {
|
||||||
|
t.markLine.label.show = true
|
||||||
|
t.markLine.data = [
|
||||||
|
{ yAxis: echartsData[i].analysis.p95 }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
} else if (this.lineRefer === 'Maximum' && show) {
|
||||||
|
this.chartOption.series.forEach((t, i) => {
|
||||||
|
t.markLine.label.show = true
|
||||||
|
t.markLine.data = [
|
||||||
|
{ yAxis: echartsData[i].analysis.max }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return stackedLineTooltipFormatter(params)
|
||||||
|
}
|
||||||
|
this.showMarkLine = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.myChart = echarts.init(this.$refs.overviewLineChart)
|
||||||
|
this.myChart.setOption(this.chartOption)
|
||||||
|
// 设置参见官网:https://echarts.apache.org/zh/api.html#action.brush.brush
|
||||||
|
this.myChart.dispatchAction({
|
||||||
|
// 刷选模式的开关。使用此 action 可将当前鼠标变为可刷选状态。事实上,点击 toolbox 中的 brush 按钮时,就是通过这个 action,将当前普通鼠标变为刷选器的。
|
||||||
|
type: 'takeGlobalCursor',
|
||||||
|
// 如果想变为“可刷选状态”,必须设置。不设置则会关闭“可刷选状态”。
|
||||||
|
key: 'brush',
|
||||||
|
brushOption: {
|
||||||
|
// 参见 brush 组件的 brushType。如果设置为 false 则关闭“可刷选状态”。
|
||||||
|
brushType: 'lineX',
|
||||||
|
xAxisIndex: 'all',
|
||||||
|
// 单击清除选框
|
||||||
|
brushMode: 'single',
|
||||||
|
// 选择完毕再返回所选数据
|
||||||
|
throttleType: 'debounce'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const self = this
|
||||||
|
|
||||||
|
this.myChart.on('brushEnd', function (params) {
|
||||||
|
self.myChart.dispatchAction({
|
||||||
|
type: 'brush',
|
||||||
|
areas: [] // 删除选框
|
||||||
|
})
|
||||||
|
if (!self.mouseDownFlag) {
|
||||||
|
// 避免点击空白区域报错
|
||||||
|
if (params.areas !== undefined && params.areas.length > 0) {
|
||||||
|
self.brushHistory.unshift({
|
||||||
|
startTime: _.cloneDeep(self.timeFilter.startTime) * 1000,
|
||||||
|
endTime: _.cloneDeep(self.timeFilter.endTime) * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
const rangeObj = {
|
||||||
|
startTime: Math.ceil(params.areas[0].coordRange[0]),
|
||||||
|
endTime: Math.ceil(params.areas[0].coordRange[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo 目前暂定框选最小范围为5分钟,后续可能会变动
|
||||||
|
if (rangeObj.endTime - rangeObj.startTime < 5 * 60 * 1000) {
|
||||||
|
rangeObj.startTime = rangeObj.endTime - 5 * 60 * 1000
|
||||||
|
}
|
||||||
|
_this.$store.commit('setRangeEchartsData', rangeObj)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
activeChange (item, index) {
|
activeChange (item, index) {
|
||||||
if (this.isNoData) return
|
if (this.isNoData) return
|
||||||
@@ -606,32 +477,34 @@ export default {
|
|||||||
referenceSelectChange (val) {
|
referenceSelectChange (val) {
|
||||||
this.lineRefer = val
|
this.lineRefer = val
|
||||||
let echartsData
|
let echartsData
|
||||||
const chartOption = this.myChart.getOption()
|
|
||||||
if (this.lineTab) {
|
if (this.lineTab) {
|
||||||
echartsData = this.mpackets.filter(t => t.show === true && t.invertTab === false)
|
echartsData = this.mpackets.filter(t => t.show === true && t.invertTab === false)
|
||||||
} else {
|
} else {
|
||||||
echartsData = this.mpackets.filter(t => t.show === true)
|
echartsData = this.mpackets.filter(t => t.show === true)
|
||||||
}
|
}
|
||||||
if (this.lineRefer === 'Average' && this.showMarkLine) {
|
if (!this.isUnitTesting) {
|
||||||
chartOption.series.forEach((t, i) => {
|
const chartOption = this.myChart.getOption()
|
||||||
if (t.name === echartsData[0].name) {
|
if (this.lineRefer === 'Average' && this.showMarkLine) {
|
||||||
t.markLine.data = [{ yAxis: echartsData[0].analysis.avg }]
|
chartOption.series.forEach((t, i) => {
|
||||||
}
|
if (t.name === echartsData[0].name) {
|
||||||
})
|
t.markLine.data = [{ yAxis: echartsData[0].analysis.avg }]
|
||||||
} else if (this.lineRefer === '95th Percentile' && this.showMarkLine) {
|
}
|
||||||
chartOption.series.forEach((t, i) => {
|
})
|
||||||
if (t.name === echartsData[0].name) {
|
} else if (this.lineRefer === '95th Percentile' && this.showMarkLine) {
|
||||||
t.markLine.data = [{ yAxis: echartsData[0].analysis.p95 }]
|
chartOption.series.forEach((t, i) => {
|
||||||
}
|
if (t.name === echartsData[0].name) {
|
||||||
})
|
t.markLine.data = [{ yAxis: echartsData[0].analysis.p95 }]
|
||||||
} else if (this.lineRefer === 'Maximum' && this.showMarkLine) {
|
}
|
||||||
chartOption.series.forEach((t, i) => {
|
})
|
||||||
if (t.name === echartsData[0].name) {
|
} else if (this.lineRefer === 'Maximum' && this.showMarkLine) {
|
||||||
t.markLine.data = [{ yAxis: echartsData[0].analysis.max }]
|
chartOption.series.forEach((t, i) => {
|
||||||
}
|
if (t.name === echartsData[0].name) {
|
||||||
})
|
t.markLine.data = [{ yAxis: echartsData[0].analysis.max }]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.myChart.setOption(chartOption)
|
||||||
}
|
}
|
||||||
this.myChart.setOption(chartOption)
|
|
||||||
},
|
},
|
||||||
symbolSizeSortChange (index, time) {
|
symbolSizeSortChange (index, time) {
|
||||||
const dataIntegrationArray = []
|
const dataIntegrationArray = []
|
||||||
@@ -681,6 +554,87 @@ export default {
|
|||||||
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
const sortIndex = dataIntegrationArray.findIndex(a => a[2] === index)
|
||||||
return this.sizes[sortIndex]
|
return this.sizes[sortIndex]
|
||||||
},
|
},
|
||||||
|
initData (data, val, active, show, n) {
|
||||||
|
let lineData = []
|
||||||
|
if (data !== undefined && data.length > 0) {
|
||||||
|
data.forEach((item) => {
|
||||||
|
item.type = getLineType(item.type)
|
||||||
|
if (item.type === val) {
|
||||||
|
lineData = Object.keys(item).map(t => {
|
||||||
|
return {
|
||||||
|
...item[t]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
lineData.splice(0, 1)
|
||||||
|
if (val === 'Sessions/s') {
|
||||||
|
const mpackets = _.cloneDeep(this.mpackets)
|
||||||
|
lineData.forEach((d, i) => {
|
||||||
|
mpackets[i].data = d.values
|
||||||
|
mpackets[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
mpackets.forEach((e, i) => {
|
||||||
|
if (i !== 0) {
|
||||||
|
e.show = false
|
||||||
|
}
|
||||||
|
e.unitType = 'sessions/s'
|
||||||
|
e.invertTab = false
|
||||||
|
this.lineTab = 'total'
|
||||||
|
this.legendSelectChange(e, 0)
|
||||||
|
})
|
||||||
|
this.mpackets = mpackets
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.echartsInit(this.mpackets, true)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const unit = val === 'Bits/s' ? 'bps' : 'packets/s'
|
||||||
|
this.legendInit(lineData, active, show, unit, n)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legendInit (data, active, show, type, n) {
|
||||||
|
const mpackets = _.cloneDeep(this.mpackets)
|
||||||
|
data.forEach((d, i) => {
|
||||||
|
mpackets[i].data = d.values
|
||||||
|
mpackets[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
let num = 0
|
||||||
|
mpackets.forEach(e => {
|
||||||
|
e.unitType = type
|
||||||
|
if (e.name !== 'network.total' && parseFloat(e.analysis.avg) === 0) {
|
||||||
|
e.show = false
|
||||||
|
num += 1
|
||||||
|
} else {
|
||||||
|
e.show = true
|
||||||
|
if (!active && show !== this.lineRefer) {
|
||||||
|
this.legendSelectChange(e, 'index')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.lineTab === e.class) {
|
||||||
|
if (parseFloat(e.analysis.avg) <= 0) {
|
||||||
|
this.lineTab = ''
|
||||||
|
this.lineRefer = ''
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.mpackets = mpackets
|
||||||
|
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)
|
||||||
|
if (!this.lineRefer) this.lineRefer = 'Average'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 鼠标右键返回框选的时间范围
|
* 鼠标右键返回框选的时间范围
|
||||||
*/
|
*/
|
||||||
@@ -702,11 +656,9 @@ export default {
|
|||||||
this.myChart = null
|
this.myChart = null
|
||||||
this.chartOption = null
|
this.chartOption = null
|
||||||
this.timer = setTimeout(() => {
|
this.timer = setTimeout(() => {
|
||||||
if (this.lineTab) {
|
if (this.lineTab && this.metric !== 'Sessions/s') {
|
||||||
const data = this.mpackets.find(t => t.class === this.lineTab)
|
const data = this.mpackets.find(t => t.class === this.lineTab)
|
||||||
if (data && data.positioning) {
|
this.activeChange(data, data.positioning)
|
||||||
this.activeChange(data, data.positioning)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
this.init()
|
this.init()
|
||||||
}
|
}
|
||||||
@@ -717,11 +669,13 @@ export default {
|
|||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
|
|
||||||
let myChart = echarts.getInstanceByDom(document.getElementById('overviewLineChart'))
|
let myChart = echarts.getInstanceByDom(this.$refs.overviewLineChart)
|
||||||
if (myChart) {
|
if (myChart) {
|
||||||
echarts.dispose(myChart)
|
echarts.dispose(myChart)
|
||||||
}
|
}
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
// 检测时发现该方法占用较大内存,且未被释放
|
// 检测时发现该方法占用较大内存,且未被释放
|
||||||
this.unitConvert = null
|
this.unitConvert = null
|
||||||
myChart = null
|
myChart = null
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
init () {
|
init () {
|
||||||
const params = {
|
const params = {
|
||||||
// startTime: true,
|
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: getSecond(this.timeFilter.startTime),
|
||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: getSecond(this.timeFilter.endTime)
|
||||||
}
|
}
|
||||||
@@ -193,6 +192,14 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
|
const dom = document.getElementById('chart1')
|
||||||
|
const dom2 = document.getElementById('chart2')
|
||||||
|
if (dom) {
|
||||||
|
echarts.dispose(dom)
|
||||||
|
}
|
||||||
|
if (dom2) {
|
||||||
|
echarts.dispose(dom2)
|
||||||
|
}
|
||||||
this.myChart = null
|
this.myChart = null
|
||||||
this.myChart2 = null
|
this.myChart2 = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,8 +215,8 @@ import unitConvert from '@/utils/unit-convert'
|
|||||||
import { getChainRatio, computeScore, urlParamsHandler, overwriteUrl, readDrilldownTableConfigByUser, combineDrilldownTableWithUserConfig, getDnsMapData, handleSpecialValue, getConfigVersion } from '@/utils/tools'
|
import { getChainRatio, computeScore, urlParamsHandler, overwriteUrl, readDrilldownTableConfigByUser, combineDrilldownTableWithUserConfig, getDnsMapData, handleSpecialValue, getConfigVersion } from '@/utils/tools'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { db } from '@/indexedDB'
|
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
import indexedDBUtils from '@/indexedDB'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NetworkOverviewTabs',
|
name: 'NetworkOverviewTabs',
|
||||||
@@ -1729,7 +1729,7 @@ export default {
|
|||||||
version = await getConfigVersion('default')
|
version = await getConfigVersion('default')
|
||||||
}
|
}
|
||||||
// 更新缓存中的配置
|
// 更新缓存中的配置
|
||||||
await db[dbDrilldownTableConfig].put({
|
await indexedDBUtils.selectTable(dbDrilldownTableConfig).put({
|
||||||
id: this.userId,
|
id: this.userId,
|
||||||
version: version,
|
version: version,
|
||||||
config: this.$_.cloneDeep(curUserConfigGroup)
|
config: this.$_.cloneDeep(curUserConfigGroup)
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
<chart-no-data v-if="isNoData"></chart-no-data>
|
<chart-no-data v-if="isNoData"></chart-no-data>
|
||||||
<div class="npm-app-body" v-else>
|
<div class="npm-app-body" v-else>
|
||||||
<div class="npm-app-body-patch" v-for="(data, index) in tableData" :key="index">
|
<div class="npm-app-body-patch" v-for="(data, index) in tableData" :key="index">
|
||||||
<div class="npm-app-body-icon"><span><i :class="data.icon"></i></span></div>
|
<div class="npm-app-body-icon"><span><i :class="data.icon" :test-id="`iconContent${index}`"></i></span></div>
|
||||||
<div class="npm-app-body-color" v-for="(item, index) in 6" :key="index" :class="{'score-color': data.score >= index + 1}"></div>
|
<div class="npm-app-body-color" v-for="index2 in 6" :key="index2" :class="{'score-color': data.score >= index2}"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
<div v-else-if="scope.row.bytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
<div v-else-if="scope.row.bytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
||||||
<i class="cn-icon-decline cn-icon"></i>
|
<i class="cn-icon-decline cn-icon"></i>
|
||||||
<span v-if="scope.row.bytesRateChainRatio >= -5">
|
<span v-if="scope.row.bytesRateChainRatio >= -5">
|
||||||
{{unitConvert(scope.row.bytesRateChainRatio, unitTypes.percent).join('').replaceAll('-', '')}}
|
{{unitConvert(scope.row.bytesRateChainRatio, unitTypes.percent).join('').replace(/-/g, '')}}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>>500.00%</span>
|
<span v-else>>500.00%</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
<div v-else-if="scope.row.outboundBytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
<div v-else-if="scope.row.outboundBytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
||||||
<i class="cn-icon-decline cn-icon"></i>
|
<i class="cn-icon-decline cn-icon"></i>
|
||||||
<span v-if="scope.row.outboundBytesRateChainRatio >= -5">
|
<span v-if="scope.row.outboundBytesRateChainRatio >= -5">
|
||||||
{{unitConvert(scope.row.outboundBytesRateChainRatio, unitTypes.percent).join('').replaceAll('-', '')}}
|
{{unitConvert(scope.row.outboundBytesRateChainRatio, unitTypes.percent).join('').replace(/-/g, '')}}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>>500.00%</span>
|
<span v-else>>500.00%</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -86,35 +86,35 @@
|
|||||||
<div class="data-trend">
|
<div class="data-trend">
|
||||||
<div v-if="scope.row.inboundBytesRateChainRatio > 0" class="data-total-trend data-total-trend-red">
|
<div v-if="scope.row.inboundBytesRateChainRatio > 0" class="data-total-trend data-total-trend-red">
|
||||||
<i class="cn-icon-rise1 cn-icon"></i>
|
<i class="cn-icon-rise1 cn-icon"></i>
|
||||||
<span v-if="scope.row.inboundBytesRateChainRatio <= 5">
|
<span v-if="scope.row.inboundBytesRateChainRatio <= 5" :test-id="`inbound-${scope.row.appSubcategory}`">
|
||||||
{{unitConvert(scope.row.inboundBytesRateChainRatio, unitTypes.percent).join('')}}
|
{{unitConvert(scope.row.inboundBytesRateChainRatio, unitTypes.percent).join('')}}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>>500.00%</span>
|
<span v-else :test-id="`inbound-${scope.row.appSubcategory}`">>500.00%</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.inboundBytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
<div v-else-if="scope.row.inboundBytesRateChainRatio < 0" class="data-total-trend data-total-trend-green">
|
||||||
<i class="cn-icon-decline cn-icon"></i>
|
<i class="cn-icon-decline cn-icon"></i>
|
||||||
<span v-if="scope.row.inboundBytesRateChainRatio >= -5">
|
<span v-if="scope.row.inboundBytesRateChainRatio >= -5" :test-id="`inbound-${scope.row.appSubcategory}`">
|
||||||
{{unitConvert(scope.row.inboundBytesRateChainRatio, unitTypes.percent).join('').replaceAll('-', '')}}
|
{{unitConvert(scope.row.inboundBytesRateChainRatio, unitTypes.percent).join('').replace(/-/g, '')}}
|
||||||
</span>
|
</span>
|
||||||
<span v-else>>500.00%</span>
|
<span v-else :test-id="`inbound-${scope.row.appSubcategory}`">>500.00%</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.inboundBytesRateChainRatio === 0" class="data-total-trend data-total-trend-black">
|
<div v-else-if="scope.row.inboundBytesRateChainRatio === 0" :test-id="`inbound-${scope.row.appSubcategory}`" class="data-total-trend data-total-trend-black">
|
||||||
<i class="cn-icon-constant cn-icon"></i>
|
<i class="cn-icon-constant cn-icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<div v-else></div>
|
<div v-else></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'score'">
|
<template v-else-if="item.prop === 'score'">
|
||||||
<div v-if="scope.row.score <= 2" :class="{'data-score-red': scope.row.score <= 2}" class="data-score">
|
<div v-if="scope.row.score <= 2" :test-id="`score-${scope.row.appSubcategory}`" class="data-score data-score-red">
|
||||||
{{scope.row.score}}
|
{{scope.row.score}}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.score <= 4" :class="{'data-score-yellow': scope.row.score <= 4}" class="data-score">
|
<div v-else-if="scope.row.score <= 4" :test-id="`score-${scope.row.appSubcategory}`" class="data-score data-score-yellow">
|
||||||
{{scope.row.score}}
|
{{scope.row.score}}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.score <= 6" :class="{'data-score-green': scope.row.score <= 6}" class="data-score">
|
<div v-else-if="scope.row.score <= 6" :test-id="`score-${scope.row.appSubcategory}`" class="data-score data-score-green">
|
||||||
{{scope.row.score}}
|
{{scope.row.score}}
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="scope.row.score === '-'" class="data-score-no-data">
|
<div v-else-if="scope.row.score === '-'" :test-id="`score-${scope.row.appSubcategory}`" class="data-score-no-data">
|
||||||
-
|
-
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -138,17 +138,12 @@ import { unitTypes, npmCategoryInfoMapping, networkTable, operationType, npmCate
|
|||||||
import unitConvert from '@/utils/unit-convert'
|
import unitConvert from '@/utils/unit-convert'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { get } from '@/utils/http'
|
import { computeScore, getChainRatio, getUserDrilldownTableConfig, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import {
|
|
||||||
getChainRatio,
|
|
||||||
computeScore,
|
|
||||||
urlParamsHandler,
|
|
||||||
overwriteUrl,
|
|
||||||
getUserDrilldownTableConfig
|
|
||||||
} from '@/utils/tools'
|
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
import ChartNoData from '@/views/charts/charts/ChartNoData'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NpmAppCategoryScore',
|
name: 'NpmAppCategoryScore',
|
||||||
data () {
|
data () {
|
||||||
@@ -198,15 +193,16 @@ export default {
|
|||||||
endTime: getSecond(this.timeFilter.endTime)
|
endTime: getSecond(this.timeFilter.endTime)
|
||||||
}
|
}
|
||||||
// 获取table后三列内容
|
// 获取table后三列内容
|
||||||
const currentTrafficRequest = get(api.npm.overview.appTrafficAnalysis, { ...params, cycle: 0 })
|
const currentTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 0 } })
|
||||||
const lastCycleTrafficRequest = get(api.npm.overview.appTrafficAnalysis, { ...params, cycle: 1 })
|
const lastCycleTrafficRequest = axios.get(api.npm.overview.appTrafficAnalysis, { params: { ...params, cycle: 1 } })
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
Promise.all([currentTrafficRequest, lastCycleTrafficRequest]).then(res => {
|
Promise.all([currentTrafficRequest, lastCycleTrafficRequest]).then(res => {
|
||||||
if (res[0].code === 200 && res[1].code === 200) {
|
// console.log('打印数据=====', res)
|
||||||
|
if (res[0].data.code === 200 && res[1].data.code === 200) {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
this.errorMsg = ''
|
this.errorMsg = ''
|
||||||
const prevData = res[1].data.result
|
const prevData = res[1].data.data.result
|
||||||
const data = res[0].data.result
|
const data = res[0].data.data.result
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
const tableData = data.map(d => {
|
const tableData = data.map(d => {
|
||||||
@@ -228,24 +224,23 @@ export default {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
// 计算分数
|
// 计算分数
|
||||||
const tcpRequest = get(api.npm.overview.appTcpSessionDelay, params)
|
const tcpRequest = axios.get(api.npm.overview.appTcpSessionDelay, { params: params })
|
||||||
const httpRequest = get(api.npm.overview.appHttpResponseDelay, params)
|
const httpRequest = axios.get(api.npm.overview.appHttpResponseDelay, { params: params })
|
||||||
const sslRequest = get(api.npm.overview.appSslConDelay, params)
|
const sslRequest = axios.get(api.npm.overview.appSslConDelay, { params: params })
|
||||||
const tcpLostRequest = get(api.npm.overview.appTcpLostlenPercent, params)
|
const tcpLostRequest = axios.get(api.npm.overview.appTcpLostlenPercent, { params: params })
|
||||||
const packetRetransRequest = get(api.npm.overview.appPacketRetransPercent, params)
|
const packetRetransRequest = axios.get(api.npm.overview.appPacketRetransPercent, { params: params })
|
||||||
Promise.all([tcpRequest, httpRequest, sslRequest, tcpLostRequest, packetRetransRequest]).then(res => {
|
Promise.all([tcpRequest, httpRequest, sslRequest, tcpLostRequest, packetRetransRequest]).then(res => {
|
||||||
const keyPre = ['tcp', 'http', 'ssl', 'tcpLost', 'packetRetrans']
|
const keyPre = ['tcp', 'http', 'ssl', 'tcpLost', 'packetRetrans']
|
||||||
let msg = ''
|
let msg = ''
|
||||||
|
|
||||||
res.forEach((r, i) => {
|
res.forEach((r, i) => {
|
||||||
if (r.code === 200) {
|
if (r.data.code === 200) {
|
||||||
tableData.forEach(t => {
|
tableData.forEach(t => {
|
||||||
const find = r.data.result.find(d => d.appSubcategory === t.appSubcategory)
|
t[keyPre[i] + 'Score'] = r.data.data.result.find(d => d.appSubcategory === t.appSubcategory)
|
||||||
t[keyPre[i] + 'Score'] = find
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.showError = true
|
this.showError = true
|
||||||
msg = msg + ',' + r.message
|
msg = msg + ',' + r.data.data.message
|
||||||
if (msg.indexOf(',') === 0) {
|
if (msg.indexOf(',') === 0) {
|
||||||
msg = msg.substring(1, msg.length)
|
msg = msg.substring(1, msg.length)
|
||||||
}
|
}
|
||||||
@@ -348,7 +343,7 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
let toPanel = null
|
let toPanel = null
|
||||||
list.forEach((item, index) => {
|
list.forEach(item => {
|
||||||
if (item.label === tabType) {
|
if (item.label === tabType) {
|
||||||
item.checked = false
|
item.checked = false
|
||||||
toPanel = item.panelId
|
toPanel = item.panelId
|
||||||
@@ -360,8 +355,7 @@ export default {
|
|||||||
this.$store.commit('setNetworkOverviewTabList', list)
|
this.$store.commit('setNetworkOverviewTabList', list)
|
||||||
const tabObjGroup = list.filter(item => item.checked)
|
const tabObjGroup = list.filter(item => item.checked)
|
||||||
if (tabObjGroup && tabObjGroup.length > 0) {
|
if (tabObjGroup && tabObjGroup.length > 0) {
|
||||||
const curTab = tabObjGroup[0]
|
this.urlChangeParams[this.curTabState.curTab] = tabObjGroup[0]
|
||||||
this.urlChangeParams[this.curTabState.curTab] = curTab
|
|
||||||
}
|
}
|
||||||
this.changeUrlTabState()
|
this.changeUrlTabState()
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
@@ -384,6 +378,9 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.init()
|
this.init()
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ export default {
|
|||||||
},
|
},
|
||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.chartOption = null
|
this.chartOption = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,21 @@
|
|||||||
<div class="npm-header">
|
<div class="npm-header">
|
||||||
<div class="npm-header-body" v-for="(item, index) in chartData" :key=index>
|
<div class="npm-header-body" v-for="(item, index) in chartData" :key=index>
|
||||||
<div class="npm-header-body-severity">
|
<div class="npm-header-body-severity">
|
||||||
<div class="npm-header-body-severity-icon" :class="item.eventSeverity"></div>
|
<div class="npm-header-body-severity-icon" :class="item.eventSeverity" :test-id="`icon${index}`"></div>
|
||||||
<div class="npm-header-body-severity-value">{{item.eventSeverity}}</div>
|
<div class="npm-header-body-severity-value" :test-id="`severity${index}`">{{item.eventSeverity}}</div>
|
||||||
</div>
|
</div>
|
||||||
<chart-error v-if="showError" tooltip :content="errorMsg" />
|
<chart-error v-if="showError" tooltip :content="errorMsg" />
|
||||||
<div v-else class="npm-header-body-total">{{item.count}}</div>
|
<div v-else class="npm-header-body-total" :test-id="`total${index}`">{{item.count}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { get } from '@/utils/http'
|
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
|
import axios from 'axios'
|
||||||
export default {
|
export default {
|
||||||
name: 'NpmEventsHeader',
|
name: 'NpmEventsHeader',
|
||||||
components: { ChartError },
|
components: { ChartError },
|
||||||
@@ -65,12 +65,13 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
recentEventsListData () {
|
recentEventsListData () {
|
||||||
const params = {
|
const params = {
|
||||||
startTime: getSecond(this.timeFilter.startTime),
|
startTime: this.timeFilter && this.timeFilter.startTime ? getSecond(this.timeFilter.startTime) : '',
|
||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: this.timeFilter && this.timeFilter.endTime ? getSecond(this.timeFilter.endTime) : '',
|
||||||
type: this.type
|
type: this.type
|
||||||
}
|
}
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(api.npm.events.list, params).then(res => {
|
axios.get(api.npm.events.list, { params: params }).then(res => {
|
||||||
|
res = res.data
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
if (res.data.result.length === 0) {
|
if (res.data.result.length === 0) {
|
||||||
@@ -96,7 +97,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.recentEventsListData()
|
this.$nextTick(() => {
|
||||||
|
this.recentEventsListData()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -336,7 +336,9 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.chartOption = null
|
this.chartOption = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="npm-network-quantity">
|
<div class="npm-network-quantity">
|
||||||
<single-value
|
<div class="single-value" v-for="(npm, index) in newNpmNetworkData" :key="index">
|
||||||
v-if="npmNetworkData.length>0"
|
<div class="single-value__title" style="display: flex">
|
||||||
:npm-network-name="npmNetworkName"
|
{{ $t(npmNetworkName[index].name) }}
|
||||||
:npm-network-data="npmNetworkData"
|
<chart-error v-if="npm.message" tooltip :content="npm.message"></chart-error>
|
||||||
></single-value>
|
</div>
|
||||||
|
|
||||||
|
<div class="single-value__content" >
|
||||||
|
<div class="single-value__content-number" v-if="index ===0 || index ===1 || index ===2" :test-id="`singleValueContent${index}`">
|
||||||
|
{{ unitConvert(npm.Avg, unitTypes.time).join(' ') }}
|
||||||
|
</div>
|
||||||
|
<div class="single-value__content-number" v-else :test-id="`singleValueContent${index}`">
|
||||||
|
{{unitConvert(npm.Avg, unitTypes.percent).join(' ')}}
|
||||||
|
</div>
|
||||||
|
<div v-if="npm.value > 0" class="single-value__content-trend single-value__content-trend-red" >
|
||||||
|
<i class="cn-icon-rise1 cn-icon" :test-id="`singleValueTrendIcon${index}`"></i>
|
||||||
|
<span v-if="npm.value <= 5" :test-id="`singleValueTrendValue${index}`">
|
||||||
|
{{ unitConvert(npm.value, unitTypes.percent).join('') }}
|
||||||
|
</span>
|
||||||
|
<span v-else :test-id="`singleValueTrendValue${index}`">>500.00%</span>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="npm.value < 0" class="single-value__content-trend single-value__content-trend-green" >
|
||||||
|
<i class="cn-icon-decline cn-icon" :test-id="`singleValueTrendIcon${index}`"></i>
|
||||||
|
<span v-if="npm.value >= -5" :test-id="`singleValueTrendValue${index}`">
|
||||||
|
{{ unitConvert(npm.value, unitTypes.percent).join('') }}
|
||||||
|
</span>
|
||||||
|
<span v-else :test-id="`singleValueTrendValue${index}`">>500.00%</span>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="npm.value === 0" class="single-value__content-trend single-value__content-trend-black">
|
||||||
|
<i class="cn-icon-constant cn-icon" :test-id="`singleValueTrendIcon${index}`"></i>
|
||||||
|
</div>
|
||||||
|
<div v-else></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="single-value__circle">
|
||||||
|
<div class="single-value__circle-p95" :test-id="`singleValueP95${index}`">
|
||||||
|
<span v-if="index ===0 || index ===1 || index ===2">
|
||||||
|
P95:{{ unitConvert(npm.P95, unitTypes.time).join(' ') }}</span>
|
||||||
|
<span v-else>
|
||||||
|
P95:{{ unitConvert(npm.P95, unitTypes.percent).join(' ') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="single-value__circle-p99" :test-id="`singleValueP99${index}`">
|
||||||
|
<span v-if="index ===0 || index ===1 || index ===2">
|
||||||
|
P99:{{ unitConvert(npm.P99, unitTypes.time).join(' ') }}
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
P99:{{ unitConvert(npm.P99, unitTypes.percent).join(' ') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SingleValue from '@/views/charts2/charts/npm/localComponents/SingleValue'
|
|
||||||
import { get } from '@/utils/http'
|
|
||||||
import { getSecond } from '@/utils/date-util'
|
import { getSecond } from '@/utils/date-util'
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
@@ -18,9 +62,11 @@ import _ from 'lodash'
|
|||||||
import { getChainRatio } from '@/utils/tools'
|
import { getChainRatio } from '@/utils/tools'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { unitTypes } from '@/utils/constants'
|
||||||
|
import unitConvert from '@/utils/unit-convert'
|
||||||
|
import axios from 'axios'
|
||||||
export default {
|
export default {
|
||||||
name: 'NpmNetworkQuantity',
|
name: 'NpmNetworkQuantity',
|
||||||
components: { SingleValue },
|
|
||||||
mixins: [chartMixin],
|
mixins: [chartMixin],
|
||||||
setup () {
|
setup () {
|
||||||
const { query } = useRoute()
|
const { query } = useRoute()
|
||||||
@@ -39,6 +85,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
unitTypes,
|
||||||
|
unitConvert,
|
||||||
npmNetworkName: [
|
npmNetworkName: [
|
||||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency' },
|
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency' },
|
||||||
{ name: 'networkAppPerformance.httpResponse' },
|
{ name: 'networkAppPerformance.httpResponse' },
|
||||||
@@ -48,6 +96,7 @@ export default {
|
|||||||
],
|
],
|
||||||
npmNetworkCycleData: [],
|
npmNetworkCycleData: [],
|
||||||
npmNetworkLastCycleData: [],
|
npmNetworkLastCycleData: [],
|
||||||
|
newNpmNetworkData: [],
|
||||||
npmNetworkData: [],
|
npmNetworkData: [],
|
||||||
side: '',
|
side: '',
|
||||||
chartData: {},
|
chartData: {},
|
||||||
@@ -68,7 +117,7 @@ export default {
|
|||||||
npmNetworkCycleQuery () {
|
npmNetworkCycleQuery () {
|
||||||
let condition = ''
|
let condition = ''
|
||||||
let url = ''
|
let url = ''
|
||||||
if (this.queryCondition.indexOf(' OR ') > -1) {
|
if (this.queryCondition && this.queryCondition.indexOf(' OR ') > -1) {
|
||||||
condition = this.queryCondition.split(/["|'](.*?)["|']/)
|
condition = this.queryCondition.split(/["|'](.*?)["|']/)
|
||||||
} else {
|
} else {
|
||||||
condition = this.queryCondition
|
condition = this.queryCondition
|
||||||
@@ -84,37 +133,38 @@ export default {
|
|||||||
} else if (parseFloat(this.tabIndex) === 1) {
|
} else if (parseFloat(this.tabIndex) === 1) {
|
||||||
this.side = 'server'
|
this.side = 'server'
|
||||||
}
|
}
|
||||||
if (condition && (typeof condition !== 'object') && type) {
|
if (condition && (typeof condition !== 'object') && type) { // 判断 condition 不为空并且不为对象 type 不为空
|
||||||
if (type === 'clientIp' || type === 'serverIp') {
|
if (type === 'clientIp' || type === 'serverIp') { // type = clientIp || serverIp
|
||||||
if (parseFloat(this.tabIndex) === 0) {
|
if (parseFloat(this.tabIndex) === 0) { // npm 下钻 tabIndex 为 0
|
||||||
type = 'clientIp'
|
type = 'clientIp'
|
||||||
} else if (parseFloat(this.tabIndex) === 1) {
|
} else if (parseFloat(this.tabIndex) === 1) { // npm 下钻 tabIndex 为 1
|
||||||
type = 'serverIp'
|
type = 'serverIp'
|
||||||
}
|
}
|
||||||
params.q = `ip='${condition.split(/'(.*?)'/)[1]}'`
|
params.q = `ip='${condition.split(/'(.*?)'/)[1]}'` // 拼接字段作为参数
|
||||||
} else if (type === 'clientCity') {
|
} else if (type === 'clientCity') {
|
||||||
params.q = `client_city='${condition.split(/'(.*?)'/)[1]}'`
|
params.q = `client_city='${condition.split(/'(.*?)'/)[1]}'` // 拼接字段作为参数
|
||||||
} else if (type === 'serverCity') {
|
} else if (type === 'serverCity') {
|
||||||
params.q = `server_city='${condition.split(/'(.*?)'/)[1]}'`
|
params.q = `server_city='${condition.split(/'(.*?)'/)[1]}'` // 拼接字段作为参数
|
||||||
} else {
|
} else {
|
||||||
params.q = condition
|
params.q = condition // 默认参数
|
||||||
}
|
}
|
||||||
params.type = type
|
params.type = type
|
||||||
} else if (condition.length > 1 && type && type === 'ip') {
|
} else if (condition.length > 1 && type && type === 'ip') { // condition 为数组时数组长度不为 0 | type 不为空 | type为ip
|
||||||
params.q = `${type}='${condition[1]}' and side='${this.side}'`
|
params.q = `${type}='${condition[1]}' and side='${this.side}'` // 拼接字段作为参数
|
||||||
params.type = type
|
params.type = type
|
||||||
} else if (condition.length > 1 && type && type !== 'ip') {
|
} else if (condition.length > 1 && type && type !== 'ip') { // condition 为数组时数组长度不为 0 | type 不为空 | type不为ip
|
||||||
if (type === 'country' || type === 'asn' || type === 'province' || type === 'city' || type === 'isp') {
|
if (type === 'country' || type === 'asn' || type === 'province' || type === 'city' || type === 'isp') { // 根据接口所需,调整参数
|
||||||
params.q = `${type}='${condition[1]}'`
|
params.q = `${type}='${condition[1]}'` // 拼接字段作为参数
|
||||||
params.type = type
|
params.type = type
|
||||||
} else if (type === 'idcRenter') {
|
} else if (type === 'idcRenter') {
|
||||||
params.q = `idc_renter='${condition[1]}'`
|
params.q = `idc_renter='${condition[1]}'` // 拼接字段作为参数
|
||||||
params.type = type
|
params.type = type
|
||||||
} else {
|
} else {
|
||||||
params.q = `${condition[0]}'${condition[1]}'`
|
params.q = `${condition[0]}'${condition[1]}'` // 拼接字段作为参数
|
||||||
params.type = type
|
params.type = type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 区分 3 级菜单和 2 级菜单使用不同的 url
|
||||||
if (parseFloat(this.tabOperationType) === 3) {
|
if (parseFloat(this.tabOperationType) === 3) {
|
||||||
url = api.npm.overview.allNetworkAnalysis
|
url = api.npm.overview.allNetworkAnalysis
|
||||||
} else {
|
} else {
|
||||||
@@ -123,7 +173,8 @@ export default {
|
|||||||
if ((type && condition) || type) {
|
if ((type && condition) || type) {
|
||||||
params.type = params.type || type
|
params.type = params.type || type
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(url, params).then(res => {
|
axios.get(url, { params: params }).then(res => {
|
||||||
|
res = res.data
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.npmNetworkCycleData = res.data.result
|
this.npmNetworkCycleData = res.data.result
|
||||||
}
|
}
|
||||||
@@ -133,21 +184,21 @@ export default {
|
|||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const tcp = get(api.npm.overview.tcpSessionDelay, params)
|
const tcp = axios.get(api.npm.overview.tcpSessionDelay, { params: params })
|
||||||
const http = get(api.npm.overview.httpResponseDelay, params)
|
const http = axios.get(api.npm.overview.httpResponseDelay, { params: params })
|
||||||
const ssl = get(api.npm.overview.sslConDelay, params)
|
const ssl = axios.get(api.npm.overview.sslConDelay, { params: params })
|
||||||
const tcpPercent = get(api.npm.overview.tcpLostlenPercent, params)
|
const tcpPercent = axios.get(api.npm.overview.tcpLostlenPercent, { params: params })
|
||||||
const packetPercent = get(api.npm.overview.packetRetransPercent, params)
|
const packetPercent = axios.get(api.npm.overview.packetRetransPercent, { params: params })
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
|
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
|
||||||
// 状态为200的,赋值接口数据,不为200的传入报错提示message,
|
// 状态为200的,赋值接口数据,不为200的传入报错提示message,
|
||||||
// 传给子组件SingleValue,再进行error处理,注:error处理不在此处处理
|
// 传给子组件SingleValue,再进行error处理,注:error处理不在此处处理
|
||||||
this.npmNetworkCycleData = []
|
this.npmNetworkCycleData = []
|
||||||
res.forEach(t => {
|
res.forEach(t => {
|
||||||
if (t.code === 200) {
|
if (t.data.code === 200) {
|
||||||
this.npmNetworkCycleData.push(t.data.result)
|
this.npmNetworkCycleData.push(t.data.data.result)
|
||||||
} else {
|
} else {
|
||||||
this.npmNetworkCycleData.push(t)
|
this.npmNetworkCycleData.push(t.data)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
this.npmNetworkLastCycleQuery()
|
this.npmNetworkLastCycleQuery()
|
||||||
@@ -177,7 +228,8 @@ export default {
|
|||||||
if ((params.type && params.q) || (param && param.type)) {
|
if ((params.type && params.q) || (param && param.type)) {
|
||||||
params.type = params.type || param.type
|
params.type = params.type || param.type
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(url, params).then(res => {
|
axios.get(url, { params: params }).then(res => {
|
||||||
|
res = res.data
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.npmNetworkLastCycleData = res.data.result
|
this.npmNetworkLastCycleData = res.data.result
|
||||||
} else {
|
} else {
|
||||||
@@ -195,20 +247,20 @@ export default {
|
|||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const tcp = get(api.npm.overview.tcpSessionDelay, params)
|
const tcp = axios.get(api.npm.overview.tcpSessionDelay, { params: params })
|
||||||
const http = get(api.npm.overview.httpResponseDelay, params)
|
const http = axios.get(api.npm.overview.httpResponseDelay, { params: params })
|
||||||
const ssl = get(api.npm.overview.sslConDelay, params)
|
const ssl = axios.get(api.npm.overview.sslConDelay, { params: params })
|
||||||
const tcpPercent = get(api.npm.overview.tcpLostlenPercent, params)
|
const tcpPercent = axios.get(api.npm.overview.tcpLostlenPercent, { params: params })
|
||||||
const packetPercent = get(api.npm.overview.packetRetransPercent, params)
|
const packetPercent = axios.get(api.npm.overview.packetRetransPercent, { params: params })
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
|
Promise.all([tcp, http, ssl, tcpPercent, packetPercent]).then(res => {
|
||||||
// 状态为200的,赋值接口数据,不为200的保留报错提示message,
|
// 状态为200的,赋值接口数据,不为200的保留报错提示message,
|
||||||
// 传给子组件SingleValue,再进行error处理,注:error处理不在此处处理
|
// 传给子组件SingleValue,再进行error处理,注:error处理不在此处处理
|
||||||
res.forEach(t => {
|
res.forEach(t => {
|
||||||
if (t.code === 200) {
|
if (t.data.code === 200) {
|
||||||
this.npmNetworkLastCycleData.push(t.data.result)
|
this.npmNetworkLastCycleData.push(t.data.data.result)
|
||||||
} else {
|
} else {
|
||||||
this.npmNetworkLastCycleData.push(t)
|
this.npmNetworkLastCycleData.push(t.data)
|
||||||
}
|
}
|
||||||
this.npmNetworkQuantity(this.npmNetworkCycleData, this.npmNetworkLastCycleData, 1)
|
this.npmNetworkQuantity(this.npmNetworkCycleData, this.npmNetworkLastCycleData, 1)
|
||||||
})
|
})
|
||||||
@@ -271,6 +323,39 @@ export default {
|
|||||||
})
|
})
|
||||||
this.npmNetworkData = cycle
|
this.npmNetworkData = cycle
|
||||||
}
|
}
|
||||||
|
this.initData(this.npmNetworkData)
|
||||||
|
},
|
||||||
|
initData (data) {
|
||||||
|
// 处理数据后的数组
|
||||||
|
const dealList = []
|
||||||
|
|
||||||
|
if (data !== undefined && data.length > 0) {
|
||||||
|
data.forEach((item) => {
|
||||||
|
const tempObj = {}
|
||||||
|
for (const i in item) {
|
||||||
|
if (item.msg || item.message) {
|
||||||
|
// 为了兼容字段为msg的情况
|
||||||
|
tempObj.message = item.msg ? item.msg : item.message
|
||||||
|
} else {
|
||||||
|
// 将含有avg、p90等关键字使用avg、p90来代替,形成统一属性
|
||||||
|
if (i.indexOf('Avg') > -1) {
|
||||||
|
tempObj.Avg = item[i]
|
||||||
|
} else if (i.indexOf('P50') > -1) {
|
||||||
|
tempObj.P50 = item[i]
|
||||||
|
} else if (i.indexOf('P90') > -1) {
|
||||||
|
tempObj.P90 = item[i]
|
||||||
|
} else if (i.indexOf('P95') > -1) {
|
||||||
|
tempObj.P95 = item[i]
|
||||||
|
} else if (i.indexOf('P99') > -1) {
|
||||||
|
tempObj.P99 = item[i]
|
||||||
|
}
|
||||||
|
tempObj.value = item.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dealList.push(tempObj)
|
||||||
|
})
|
||||||
|
this.newNpmNetworkData = dealList
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -282,6 +367,7 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer1)
|
clearTimeout(this.timer1)
|
||||||
clearTimeout(this.timer2)
|
clearTimeout(this.timer2)
|
||||||
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -21,15 +21,15 @@
|
|||||||
<template #default="scope" :column="item">
|
<template #default="scope" :column="item">
|
||||||
<div class="data-recent-table">
|
<div class="data-recent-table">
|
||||||
<template v-if="item.prop === 'eventSeverity'">
|
<template v-if="item.prop === 'eventSeverity'">
|
||||||
<span class="data-recent-table-severity" :class="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
|
<span class="data-recent-table-severity" :class="scope.row[item.prop]" :test-id="`eventSeverity-${scope.row.eventSeverity}-${scope.$index}`">{{scope.row[item.prop]}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'eventKey'">
|
<template v-else-if="item.prop === 'eventKey'">
|
||||||
<span class="data-recent-table-entity click-active" @click="jumpPage(scope.row)">{{splitEventKey(scope.row[item.prop])}}</span>
|
<span class="data-recent-table-entity click-active" @click="jumpPage(scope.row)" :test-id="`eventKey-${splitEventKey(scope.row.eventKey)}-${scope.$index}`">{{splitEventKey(scope.row[item.prop])}}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="item.prop === 'eventType'">
|
<template v-else-if="item.prop === 'eventType'">
|
||||||
<span class="data-recent-table-eventType">{{scope.row[item.prop]}}</span>
|
<span class="data-recent-table-eventType" :test-id="`eventType-${scope.row.eventType}-${scope.$index}`">{{scope.row[item.prop]}}</span>
|
||||||
</template>
|
</template>
|
||||||
<span v-else-if="scope.row[item.prop]">{{scope.row[item.prop]}}</span>
|
<span v-else-if="scope.row[item.prop]" :test-id="`startTime-${scope.row.startTime}-${scope.$index}`">{{scope.row[item.prop]}}</span>
|
||||||
<span v-else>-</span>
|
<span v-else>-</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -48,13 +48,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { get } from '@/utils/http'
|
|
||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { getSecond, dateFormatByAppearance } from '@/utils/date-util'
|
import { getSecond, dateFormatByAppearance } from '@/utils/date-util'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NpmRecentEvents',
|
name: 'NpmRecentEvents',
|
||||||
@@ -99,7 +99,7 @@ export default {
|
|||||||
endTime: getSecond(this.timeFilter.endTime),
|
endTime: getSecond(this.timeFilter.endTime),
|
||||||
limit: 8
|
limit: 8
|
||||||
}
|
}
|
||||||
if (condition.length > 1 && this.dimensionType) {
|
if (condition && condition.length > 1 && this.dimensionType) {
|
||||||
params.param = condition[1]
|
params.param = condition[1]
|
||||||
params.type = this.dimensionType
|
params.type = this.dimensionType
|
||||||
if (params.type === 'serverIp' || params.type === 'clientIp') params.type = 'ip'
|
if (params.type === 'serverIp' || params.type === 'clientIp') params.type = 'ip'
|
||||||
@@ -114,7 +114,8 @@ export default {
|
|||||||
url = api.npm.events.recentEvents
|
url = api.npm.events.recentEvents
|
||||||
}
|
}
|
||||||
this.toggleLoading(true)
|
this.toggleLoading(true)
|
||||||
get(url, params).then(res => {
|
axios.get(url, { params: params }).then(res => {
|
||||||
|
res = res.data
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
this.showError = false
|
this.showError = false
|
||||||
this.isNoData = res.data.result.length === 0
|
this.isNoData = res.data.result.length === 0
|
||||||
@@ -151,6 +152,7 @@ export default {
|
|||||||
return name
|
return name
|
||||||
},
|
},
|
||||||
jumpPage (item) {
|
jumpPage (item) {
|
||||||
|
this.beforeRouterPush()
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
path: '/detection/performanceEvent',
|
path: '/detection/performanceEvent',
|
||||||
query: {
|
query: {
|
||||||
@@ -158,6 +160,36 @@ export default {
|
|||||||
eventId: item.eventId
|
eventId: item.eventId
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 在路由跳转前,即下钻前将路由数据保存起来,确保回退和前进保留当时状态
|
||||||
|
*/
|
||||||
|
beforeRouterPush () {
|
||||||
|
const currentRouter = this.$_.cloneDeep(this.$route.query)
|
||||||
|
const historyList = this.$_.cloneDeep(this.$store.getters.getRouterHistoryList)
|
||||||
|
|
||||||
|
const tempObj = {
|
||||||
|
t: currentRouter.t,
|
||||||
|
query: currentRouter,
|
||||||
|
path: this.$_.cloneDeep(this.$route.path),
|
||||||
|
params: this.$_.cloneDeep(this.$route.params)
|
||||||
|
}
|
||||||
|
if (historyList.length > 0) {
|
||||||
|
let flag = true
|
||||||
|
historyList.forEach((item, index) => {
|
||||||
|
if (item.t === currentRouter.t) {
|
||||||
|
historyList[index] = tempObj
|
||||||
|
flag = false
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (flag) historyList.push(tempObj)
|
||||||
|
} else {
|
||||||
|
historyList.push(tempObj)
|
||||||
|
}
|
||||||
|
this.$store.commit('setRouterHistoryList', historyList)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import { get } from '@/utils/http'
|
|||||||
import { api } from '@/utils/api'
|
import { api } from '@/utils/api'
|
||||||
import { drillDownPanelTypeMapping } from '@/utils/constants'
|
import { drillDownPanelTypeMapping } from '@/utils/constants'
|
||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import { useRoute } from 'vue-router'
|
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
export default {
|
export default {
|
||||||
name: 'NpmTabs',
|
name: 'NpmTabs',
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ import ChartNoData from '@/views/charts/charts/ChartNoData'
|
|||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import chartMixin from '@/views/charts2/chart-mixin'
|
import chartMixin from '@/views/charts2/chart-mixin'
|
||||||
import { useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
import { getLineType, getLineIndexUnit, overwriteUrl, urlParamsHandler } from '@/utils/tools'
|
||||||
import ChartError from '@/components/common/Error'
|
import ChartError from '@/components/common/Error'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -80,11 +80,11 @@ export default {
|
|||||||
{ name: this.$t('network.other'), show: true, positioning: 5, data: [], unitType: 'number' }
|
{ name: this.$t('network.other'), show: true, positioning: 5, data: [], unitType: 'number' }
|
||||||
],
|
],
|
||||||
npmQuantity: [
|
npmQuantity: [
|
||||||
{ name: this.$t('networkAppPerformance.tcpConnectionEstablishLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.tcpConnectionEstablishLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 0 },
|
||||||
{ name: this.$t('networkAppPerformance.httpResponse'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.httpResponse'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 1 },
|
||||||
{ name: this.$t('networkAppPerformance.sslResponseLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.sslResponseLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 2 },
|
||||||
{ name: this.$t('networkAppPerformance.packetLoss'), show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
{ name: this.$t('networkAppPerformance.packetLoss'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 3 },
|
||||||
{ name: this.$t('overall.packetRetrans'), show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
{ name: this.$t('overall.packetRetrans'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 4 }
|
||||||
],
|
],
|
||||||
chartData: {},
|
chartData: {},
|
||||||
metricOptions: [
|
metricOptions: [
|
||||||
@@ -144,7 +144,6 @@ export default {
|
|||||||
if (!val) {
|
if (!val) {
|
||||||
val = this.metricFilter
|
val = this.metricFilter
|
||||||
}
|
}
|
||||||
// const conditionStr = this.$route.query.queryCondition ? this.$route.query.queryCondition : ''
|
|
||||||
let condition = ''
|
let condition = ''
|
||||||
let type = this.dimensionType
|
let type = this.dimensionType
|
||||||
if (this.queryCondition.indexOf(' OR ') > -1) {
|
if (this.queryCondition.indexOf(' OR ') > -1) {
|
||||||
@@ -209,92 +208,15 @@ export default {
|
|||||||
{ name: this.$t('network.other'), show: true, positioning: 5, data: [], unitType: 'number' }
|
{ name: this.$t('network.other'), show: true, positioning: 5, data: [], unitType: 'number' }
|
||||||
]
|
]
|
||||||
this.npmQuantity = [
|
this.npmQuantity = [
|
||||||
{ name: this.$t('networkAppPerformance.tcpConnectionEstablishLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.tcpConnectionEstablishLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 0 },
|
||||||
{ name: this.$t('networkAppPerformance.httpResponse'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.httpResponse'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 1 },
|
||||||
{ name: this.$t('networkAppPerformance.sslResponseLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('networkAppPerformance.sslResponseLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 2 },
|
||||||
{ name: this.$t('networkAppPerformance.packetLoss'), show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
{ name: this.$t('networkAppPerformance.packetLoss'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 3 },
|
||||||
{ name: this.$t('overall.packetRetrans'), show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
{ name: this.$t('overall.packetRetrans'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 4 }
|
||||||
]
|
]
|
||||||
|
} else {
|
||||||
|
this.initData(res.data.result, val)
|
||||||
}
|
}
|
||||||
res.data.result.forEach((t) => {
|
|
||||||
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) => {
|
|
||||||
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) => {
|
|
||||||
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) => {
|
|
||||||
e.show = i === 0
|
|
||||||
})
|
|
||||||
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) => {
|
|
||||||
e.show = i === 1
|
|
||||||
})
|
|
||||||
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) => {
|
|
||||||
e.show = i === 2
|
|
||||||
})
|
|
||||||
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) => {
|
|
||||||
e.show = i === 3
|
|
||||||
})
|
|
||||||
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) => {
|
|
||||||
e.show = i === 4
|
|
||||||
})
|
|
||||||
this.npmQuantity = npmQuantity
|
|
||||||
this.echartsInit(this.npmQuantity, '(%)')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
this.showError = true
|
this.showError = true
|
||||||
@@ -308,204 +230,50 @@ export default {
|
|||||||
this.toggleLoading(false)
|
this.toggleLoading(false)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if (val === 'Bits/s' || val === 'Packets/s' || val === 'Sessions/s') {
|
this.toggleLoading(true)
|
||||||
this.toggleLoading(true)
|
const totalTrafficAnalysis = get(api.npm.overview.totalTrafficAnalysis, params)
|
||||||
get(api.npm.overview.totalTrafficAnalysis, params).then(res => {
|
const totalNetworkAnalysis = get(api.npm.overview.totalNetworkAnalysis, params)
|
||||||
if (res.code === 200) {
|
const totalHttpResponseDelay = get(api.npm.overview.totalHttpResponseDelay, params)
|
||||||
this.showError = false
|
const totalSslConDelay = get(api.npm.overview.totalSslConDelay, params)
|
||||||
this.isNoData = res.data.result.length === 0
|
const npmLineData = []
|
||||||
if (this.isNoData) {
|
Promise.all([totalNetworkAnalysis, totalTrafficAnalysis, totalHttpResponseDelay, totalSslConDelay]).then(res => {
|
||||||
this.mpackets = [
|
res.forEach(item => {
|
||||||
{ name: 'network.total', show: true, positioning: 0, data: [], unitType: 'number' },
|
if (item.code === 200) {
|
||||||
{ name: 'network.inbound', show: true, positioning: 1, data: [], unitType: 'number' },
|
npmLineData.push(...item.data.result)
|
||||||
{ 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) => {
|
|
||||||
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) => {
|
|
||||||
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) => {
|
|
||||||
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 {
|
} else {
|
||||||
this.isNoData = false
|
this.isNoData = false
|
||||||
this.showError = true
|
this.showError = true
|
||||||
this.errorMsg = res.message
|
this.errorMsg = res.message
|
||||||
}
|
}
|
||||||
}).catch(e => {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = e.message
|
|
||||||
}).finally(() => {
|
|
||||||
this.toggleLoading(false)
|
|
||||||
})
|
})
|
||||||
} else if (val === 'establishLatencyMs' || val === 'tcpLostlenPercent' || val === 'pktRetransPercent') {
|
this.showError = false
|
||||||
this.toggleLoading(true)
|
this.isNoData = npmLineData.length === 0
|
||||||
get(api.npm.overview.totalNetworkAnalysis, params).then(res => {
|
if (this.isNoData) {
|
||||||
if (res.code === 200) {
|
this.mpackets = [
|
||||||
this.showError = false
|
{ name: this.$t('network.total'), show: true, positioning: 0, data: [], unitType: 'number' },
|
||||||
this.isNoData = res.data.result.length === 0
|
{ name: this.$t('network.inbound'), show: true, positioning: 1, data: [], unitType: 'number' },
|
||||||
if (this.isNoData) {
|
{ name: this.$t('network.outbound'), show: true, positioning: 2, data: [], unitType: 'number' },
|
||||||
this.npmQuantity = [
|
{ name: this.$t('network.internal'), show: true, positioning: 3, data: [], unitType: 'number' },
|
||||||
{ name: 'networkAppPerformance.tcpConnectionEstablishLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('network.through'), show: true, positioning: 4, data: [], unitType: 'number' },
|
||||||
{ name: 'networkAppPerformance.httpResponse', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
{ name: this.$t('network.other'), show: true, positioning: 5, data: [], unitType: 'number' }
|
||||||
{ name: 'networkAppPerformance.sslResponseLatency', show: true, positioning: 0, data: [], unitType: unitTypes.time },
|
]
|
||||||
{ name: 'networkAppPerformance.packetLoss', show: true, positioning: 0, data: [], unitType: unitTypes.percent },
|
this.npmQuantity = [
|
||||||
{ name: 'overall.packetRetrans', show: true, positioning: 0, data: [], unitType: unitTypes.percent }
|
{ name: this.$t('networkAppPerformance.tcpConnectionEstablishLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 0 },
|
||||||
]
|
{ name: this.$t('networkAppPerformance.httpResponse'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 1 },
|
||||||
}
|
{ name: this.$t('networkAppPerformance.sslResponseLatency'), show: true, positioning: 0, data: [], unitType: unitTypes.time, index: 2 },
|
||||||
res.data.result.forEach((t) => {
|
{ name: this.$t('networkAppPerformance.packetLoss'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 3 },
|
||||||
if (t.type === 'establishLatencyMs' && val === 'establishLatencyMs') {
|
{ name: this.$t('overall.packetRetrans'), show: true, positioning: 0, data: [], unitType: unitTypes.percent, index: 4 }
|
||||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
]
|
||||||
npmQuantity[0].data = t.establishLatencyMs.values ? t.establishLatencyMs.values : []
|
} else {
|
||||||
npmQuantity.forEach((e, i) => {
|
this.initData(npmLineData, val)
|
||||||
e.show = i === 0
|
}
|
||||||
})
|
}).catch(e => {
|
||||||
this.npmQuantity = npmQuantity
|
this.isNoData = false
|
||||||
this.echartsInit(this.npmQuantity, '(ms)')
|
this.showError = true
|
||||||
} else if (t.type === 'tcpLostlenPercent' && val === 'tcpLostlenPercent') {
|
this.errorMsg = e.message
|
||||||
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
}).finally(() => {
|
||||||
npmQuantity[3].data = t.tcpLostlenPercent.values ? t.tcpLostlenPercent.values : []
|
this.toggleLoading(false)
|
||||||
npmQuantity.forEach((e, i) => {
|
})
|
||||||
e.show = i === 3
|
|
||||||
})
|
|
||||||
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) => {
|
|
||||||
e.show = i === 4
|
|
||||||
})
|
|
||||||
this.npmQuantity = npmQuantity
|
|
||||||
this.echartsInit(this.npmQuantity, '(%)')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = res.message
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = e.message
|
|
||||||
}).finally(() => {
|
|
||||||
this.toggleLoading(false)
|
|
||||||
})
|
|
||||||
} else if (val === 'httpResponseLatency') {
|
|
||||||
this.toggleLoading(true)
|
|
||||||
get(api.npm.overview.totalHttpResponseDelay, params).then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
this.showError = false
|
|
||||||
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) => {
|
|
||||||
e.show = i === 1
|
|
||||||
})
|
|
||||||
this.npmQuantity = npmQuantity
|
|
||||||
this.echartsInit(this.npmQuantity, '(ms)')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = res.message
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = e.message
|
|
||||||
}).finally(() => {
|
|
||||||
this.toggleLoading(false)
|
|
||||||
})
|
|
||||||
} else if (val === 'sslConLatency') {
|
|
||||||
this.toggleLoading(true)
|
|
||||||
get(api.npm.overview.totalSslConDelay, params).then(res => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
this.showError = false
|
|
||||||
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) => {
|
|
||||||
e.show = i === 2
|
|
||||||
})
|
|
||||||
this.npmQuantity = npmQuantity
|
|
||||||
this.echartsInit(this.npmQuantity, '(ms)')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = res.message
|
|
||||||
}
|
|
||||||
}).catch(e => {
|
|
||||||
this.isNoData = false
|
|
||||||
this.showError = true
|
|
||||||
this.errorMsg = e.message
|
|
||||||
}).finally(() => {
|
|
||||||
this.toggleLoading(false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
echartsInit (echartsData, legendUnit) {
|
echartsInit (echartsData, legendUnit) {
|
||||||
@@ -619,6 +387,67 @@ export default {
|
|||||||
},
|
},
|
||||||
resize () {
|
resize () {
|
||||||
this.myChart.resize()
|
this.myChart.resize()
|
||||||
|
},
|
||||||
|
initData (data, val) {
|
||||||
|
let lineData = []
|
||||||
|
if (data !== undefined && data.length > 0) {
|
||||||
|
data.forEach(item => {
|
||||||
|
item.type = getLineType(item.type)
|
||||||
|
if (item.type === val) {
|
||||||
|
lineData = Object.keys((item)).map(t => {
|
||||||
|
return {
|
||||||
|
...item[t],
|
||||||
|
index: getLineIndexUnit(item.type, false),
|
||||||
|
unit: getLineIndexUnit(item.type, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
lineData.splice(0, 1)
|
||||||
|
const mpackets = _.cloneDeep(this.mpackets)
|
||||||
|
const npmQuantity = _.cloneDeep(this.npmQuantity)
|
||||||
|
if (val === 'Sessions/s') {
|
||||||
|
lineData.forEach((d, i) => {
|
||||||
|
mpackets[i].data = d.values
|
||||||
|
mpackets[i].analysis = d.analysis
|
||||||
|
})
|
||||||
|
mpackets.forEach((e, i) => {
|
||||||
|
if (i !== 0) {
|
||||||
|
e.show = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.mpackets = mpackets
|
||||||
|
this.echartsInit(this.mpackets)
|
||||||
|
} else if (val !== 'Bits/s' && val !== 'Packets/s' && val !== 'Sessions/s') {
|
||||||
|
this.legendInit(lineData, npmQuantity, true)
|
||||||
|
} else {
|
||||||
|
this.legendInit(lineData, mpackets, false)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legendInit (data, npmData, show) {
|
||||||
|
data.forEach((d, i) => {
|
||||||
|
if (show) {
|
||||||
|
npmData[d.index].data = d.values
|
||||||
|
npmData[d.index].analysis = d.analysis
|
||||||
|
} else {
|
||||||
|
npmData[i].data = d.values
|
||||||
|
npmData[i].analysis = d.analysis
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (show) {
|
||||||
|
npmData.forEach((e, i) => {
|
||||||
|
e.show = i === data[0].index
|
||||||
|
})
|
||||||
|
this.npmQuantity = npmData
|
||||||
|
this.echartsInit(this.npmQuantity, data[0].unit)
|
||||||
|
} else {
|
||||||
|
npmData.forEach((e) => {
|
||||||
|
e.show = true
|
||||||
|
})
|
||||||
|
this.mpackets = npmData
|
||||||
|
this.echartsInit(this.mpackets)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@@ -633,8 +462,9 @@ export default {
|
|||||||
beforeUnmount () {
|
beforeUnmount () {
|
||||||
clearTimeout(this.timer)
|
clearTimeout(this.timer)
|
||||||
window.removeEventListener('resize', this.resize)
|
window.removeEventListener('resize', this.resize)
|
||||||
this.myChart = null
|
if (this.myChart) {
|
||||||
this.myChart = null
|
echarts.dispose(this.myChart)
|
||||||
|
}
|
||||||
this.unitConvert = null
|
this.unitConvert = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="single-value" v-for="(npm, index) in newNpmNetworkData" :key="index">
|
|
||||||
<div class="single-value__title" style="display: flex">
|
|
||||||
{{ $t(npmNetworkName[index].name) }}
|
|
||||||
<chart-error v-if="npm.message" tooltip :content="npm.message"></chart-error>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="single-value__content">
|
|
||||||
<div class="single-value__content-number" v-if="index ===0 || index ===1 || index ===2">
|
|
||||||
{{ unitConvert(npm.Avg, unitTypes.time).join(' ') }}
|
|
||||||
</div>
|
|
||||||
<div class="single-value__content-number" v-else>
|
|
||||||
{{unitConvert(npm.Avg, unitTypes.percent).join(' ')}}
|
|
||||||
</div>
|
|
||||||
<div v-if="npm.value > 0" class="single-value__content-trend single-value__content-trend-red">
|
|
||||||
<i class="cn-icon-rise1 cn-icon"></i>
|
|
||||||
<span v-if="npm.value <= 5">
|
|
||||||
{{ unitConvert(npm.value, unitTypes.percent).join('') }}
|
|
||||||
</span>
|
|
||||||
<span v-else>>500.00%</span>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="npm.value < 0" class="single-value__content-trend single-value__content-trend-green">
|
|
||||||
<i class="cn-icon-decline cn-icon"></i>
|
|
||||||
<span v-if="npm.value >= -5">
|
|
||||||
{{ unitConvert(npm.value, unitTypes.percent).join('').replaceAll('-', '') }}
|
|
||||||
</span>
|
|
||||||
<span v-else>>500.00%</span>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="npm.value === 0" class="single-value__content-trend single-value__content-trend-black">
|
|
||||||
<i class="cn-icon-constant cn-icon"></i>
|
|
||||||
</div>
|
|
||||||
<div v-else></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="single-value__circle">
|
|
||||||
<div class="single-value__circle-p95">
|
|
||||||
<span v-if="index ===0 || index ===1 || index ===2">
|
|
||||||
P95:{{ unitConvert(npm.P95, unitTypes.time).join(' ') }}</span>
|
|
||||||
<span v-else>
|
|
||||||
P95:{{ unitConvert(npm.P95, unitTypes.percent).join(' ') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="single-value__circle-p99">
|
|
||||||
<span v-if="index ===0 || index ===1 || index ===2">
|
|
||||||
P99:{{ unitConvert(npm.P99, unitTypes.time).join(' ') }}
|
|
||||||
</span>
|
|
||||||
<span v-else>
|
|
||||||
P99:{{ unitConvert(npm.P99, unitTypes.percent).join(' ') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { unitTypes } from '@/utils/constants'
|
|
||||||
import unitConvert from '@/utils/unit-convert'
|
|
||||||
import ChartError from '@/components/common/Error'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SingleValue',
|
|
||||||
components: { ChartError },
|
|
||||||
props: {
|
|
||||||
npmNetworkName: Array,
|
|
||||||
npmNetworkData: Array
|
|
||||||
},
|
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
unitTypes,
|
|
||||||
unitConvert,
|
|
||||||
newNpmNetworkData: [] // 整合处理传过来的数据列表
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
npmNetworkData: {
|
|
||||||
deep: true,
|
|
||||||
handler () {
|
|
||||||
this.initData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted () {
|
|
||||||
this.initData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/**
|
|
||||||
* 初始化数据
|
|
||||||
*/
|
|
||||||
initData () {
|
|
||||||
// 传过来的数据
|
|
||||||
const npmNetworkData = this.npmNetworkData
|
|
||||||
// 处理数据后的数组
|
|
||||||
const dealList = []
|
|
||||||
|
|
||||||
if (npmNetworkData !== undefined && npmNetworkData.length > 0) {
|
|
||||||
npmNetworkData.forEach((item) => {
|
|
||||||
const tempObj = {}
|
|
||||||
for (const i in item) {
|
|
||||||
if (item.msg || item.message) {
|
|
||||||
// 为了兼容字段为msg的情况
|
|
||||||
tempObj.message = item.msg ? item.msg : item.message
|
|
||||||
} else {
|
|
||||||
// 将含有avg、p90等关键字使用avg、p90来代替,形成统一属性
|
|
||||||
if (i.indexOf('Avg') > -1) {
|
|
||||||
tempObj.Avg = item[i]
|
|
||||||
} else if (i.indexOf('P50') > -1) {
|
|
||||||
tempObj.P50 = item[i]
|
|
||||||
} else if (i.indexOf('P90') > -1) {
|
|
||||||
tempObj.P90 = item[i]
|
|
||||||
} else if (i.indexOf('P95') > -1) {
|
|
||||||
tempObj.P95 = item[i]
|
|
||||||
} else if (i.indexOf('P99') > -1) {
|
|
||||||
tempObj.P99 = item[i]
|
|
||||||
}
|
|
||||||
tempObj.value = item.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dealList.push(tempObj)
|
|
||||||
})
|
|
||||||
this.newNpmNetworkData = dealList
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -134,15 +134,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.$route.query.eventId) {
|
this.initExpendTab()
|
||||||
if (parseFloat(this.$route.query.eventId) === this.detection.eventId) {
|
|
||||||
const container = document.getElementById('cnContainer')
|
|
||||||
container.scrollTop = 555 + this.index * 97
|
|
||||||
|
|
||||||
this.isCollapse = false
|
|
||||||
this.$emit('switchCollapse', this.isCollapse, this.index)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
iconClass () {
|
iconClass () {
|
||||||
@@ -186,7 +178,7 @@ export default {
|
|||||||
this.$emit('switchCollapse', this.isCollapse, this.index)
|
this.$emit('switchCollapse', this.isCollapse, this.index)
|
||||||
|
|
||||||
if (this.isCollapse) {
|
if (this.isCollapse) {
|
||||||
const newQuery = this.$route.query // 深拷贝路由数据
|
const newQuery = this.$route.query
|
||||||
delete newQuery.eventId
|
delete newQuery.eventId
|
||||||
this.reloadUrl(newQuery, 'cleanOldParams')
|
this.reloadUrl(newQuery, 'cleanOldParams')
|
||||||
} else {
|
} else {
|
||||||
@@ -207,6 +199,33 @@ export default {
|
|||||||
newUrl = urlParamsHandler(window.location.href, query, newParam, clean)
|
newUrl = urlParamsHandler(window.location.href, query, newParam, clean)
|
||||||
}
|
}
|
||||||
overwriteUrl(newUrl)
|
overwriteUrl(newUrl)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 初始化从npm跳转过来的id,并展开tab
|
||||||
|
*/
|
||||||
|
initExpendTab () {
|
||||||
|
if (this.$route.query.eventId) {
|
||||||
|
if (this.$route.query.eventId === this.detection.eventId) {
|
||||||
|
const container = document.getElementById('cnContainer')
|
||||||
|
const dom = document.getElementsByClassName('cn-detection__case')
|
||||||
|
// 未展开的item折叠块,高度67+下边距10+底部线高度1,兼容不同分辨率下的tab高度
|
||||||
|
let itemHeight = 78
|
||||||
|
if (dom && this.index > 0) {
|
||||||
|
itemHeight = dom[0].clientHeight + 11
|
||||||
|
}
|
||||||
|
|
||||||
|
let topHeight = 554 + this.index * itemHeight
|
||||||
|
// 经过测试对比,第7个以后的tab会往上移动,但是手动展开和自动展开tab的滚动条高度一致,为解决该问题,自动加上误差值
|
||||||
|
if (this.index > 6) {
|
||||||
|
topHeight = topHeight + 6
|
||||||
|
}
|
||||||
|
|
||||||
|
container.scrollTop = topHeight
|
||||||
|
|
||||||
|
this.isCollapse = false
|
||||||
|
this.$emit('switchCollapse', this.isCollapse, this.index)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ export default {
|
|||||||
const chartDom = document.getElementById(`eventSeverityTrendBar${this.pageType}`)
|
const chartDom = document.getElementById(`eventSeverityTrendBar${this.pageType}`)
|
||||||
const eventSeverityTrendOption = this.$_.cloneDeep(multipleBarOption)
|
const eventSeverityTrendOption = this.$_.cloneDeep(multipleBarOption)
|
||||||
|
|
||||||
const xData = []
|
let xData = []
|
||||||
dataMap.forEach(function (value) {
|
dataMap.forEach(function (value) {
|
||||||
// eventSeverityTrendOption.series[Number(getSeriesIndex(key))].data = value.map(v => Number(v[1]))
|
// eventSeverityTrendOption.series[Number(getSeriesIndex(key))].data = value.map(v => Number(v[1]))
|
||||||
value.forEach(item => {
|
value.forEach(item => {
|
||||||
@@ -303,6 +303,9 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
xData = xData.sort((a, b) => {
|
||||||
|
return new Date(a) - new Date(b)
|
||||||
|
})
|
||||||
eventSeverityTrendOption.series.forEach(serie => {
|
eventSeverityTrendOption.series.forEach(serie => {
|
||||||
const seriesData = []
|
const seriesData = []
|
||||||
xData.forEach(item => {
|
xData.forEach(item => {
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
<div class="overview__title">{{$t('detections.metric')}}</div>
|
<div class="overview__title">{{$t('detections.metric')}}</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__content--metric ">{{detection.eventType || '-'}}</div>
|
<div class="row__content--metric ">{{getNameByEventType(detection.eventType) || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
@@ -95,7 +95,7 @@ import { get } from '@/utils/http'
|
|||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { markRaw } from 'vue'
|
import { markRaw } from 'vue'
|
||||||
import { metricOption } from '@/views/detections/options/detectionOptions'
|
import { metricOption } from '@/views/detections/options/detectionOptions'
|
||||||
import { sortBy, reverseSortBy } from '@/utils/tools'
|
import { sortBy, reverseSortBy, getNameByEventType } from '@/utils/tools'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
export default {
|
export default {
|
||||||
name: 'DetectionPerformanceEventAppOverview',
|
name: 'DetectionPerformanceEventAppOverview',
|
||||||
@@ -134,6 +134,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getNameByEventType,
|
||||||
query () {
|
query () {
|
||||||
this.queryBasic().then(responses => {
|
this.queryBasic().then(responses => {
|
||||||
responses && (this.basicInfo = responses)
|
responses && (this.basicInfo = responses)
|
||||||
@@ -180,6 +181,10 @@ export default {
|
|||||||
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.chartOptionMetric.series.forEach(item => {
|
||||||
|
item.name = this.getNameByEventType(this.detection.eventType)
|
||||||
|
})
|
||||||
|
|
||||||
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
<div class="overview__title">{{$t('detections.metric')}}</div>
|
<div class="overview__title">{{$t('detections.metric')}}</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__content--metric ">{{detection.eventType || '-'}}</div>
|
<div class="row__content--metric ">{{getNameByEventType(detection.eventType) || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
@@ -98,7 +98,7 @@ import { get } from '@/utils/http'
|
|||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { markRaw } from 'vue'
|
import { markRaw } from 'vue'
|
||||||
import { metricOption } from '@/views/detections/options/detectionOptions'
|
import { metricOption } from '@/views/detections/options/detectionOptions'
|
||||||
import { sortBy, reverseSortBy } from '@/utils/tools'
|
import { sortBy, reverseSortBy, getNameByEventType } from '@/utils/tools'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
export default {
|
export default {
|
||||||
name: 'DetectionPerformanceEventDomainOverview',
|
name: 'DetectionPerformanceEventDomainOverview',
|
||||||
@@ -165,6 +165,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getNameByEventType,
|
||||||
query () {
|
query () {
|
||||||
this.queryBasic().then(responses => {
|
this.queryBasic().then(responses => {
|
||||||
responses && (this.basicInfo = responses)
|
responses && (this.basicInfo = responses)
|
||||||
@@ -212,6 +213,10 @@ export default {
|
|||||||
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.chartOptionMetric.series.forEach(item => {
|
||||||
|
item.name = this.getNameByEventType(this.detection.eventType)
|
||||||
|
})
|
||||||
|
|
||||||
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
<div class="overview__title">{{$t('detections.metric')}}</div>
|
<div class="overview__title">{{$t('detections.metric')}}</div>
|
||||||
<div class="overview__row">
|
<div class="overview__row">
|
||||||
<div class="row__content--metric ">{{getNameByType(detection.eventType) || '-'}}</div>
|
<div class="row__content--metric ">{{getNameByEventType(detection.eventType) || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="metric__column">
|
<div class="metric__column">
|
||||||
@@ -88,7 +88,7 @@ import { get } from '@/utils/http'
|
|||||||
import * as echarts from 'echarts'
|
import * as echarts from 'echarts'
|
||||||
import { markRaw } from 'vue'
|
import { markRaw } from 'vue'
|
||||||
import { metricOption } from '@/views/detections/options/detectionOptions'
|
import { metricOption } from '@/views/detections/options/detectionOptions'
|
||||||
import { sortBy, reverseSortBy } from '@/utils/tools'
|
import { sortBy, reverseSortBy, getNameByEventType } from '@/utils/tools'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -129,6 +129,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getNameByEventType,
|
||||||
query () {
|
query () {
|
||||||
this.queryBasic().then(responses => {
|
this.queryBasic().then(responses => {
|
||||||
responses && (this.basicInfo = responses)
|
responses && (this.basicInfo = responses)
|
||||||
@@ -173,9 +174,11 @@ export default {
|
|||||||
this.chartOptionMetric.series[1].data = this.metricList.slice(startIndex - 1, endIndex).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
this.chartOptionMetric.series[1].data = this.metricList.slice(startIndex - 1, endIndex).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
||||||
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
this.chartOptionMetric.series[2].data = this.metricList.slice(endIndex - 1, this.metricList.length).map(v => [Number(v[0]) * 1000, Number(v[1]), unitTypes.number])
|
||||||
}
|
}
|
||||||
|
|
||||||
this.chartOptionMetric.series.forEach(item => {
|
this.chartOptionMetric.series.forEach(item => {
|
||||||
item.name = this.getNameByType(this.detection.eventType)
|
item.name = this.getNameByEventType(this.detection.eventType)
|
||||||
})
|
})
|
||||||
|
|
||||||
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
this.chartOptionMetric && this.metricChart.setOption(this.chartOptionMetric)
|
||||||
},
|
},
|
||||||
queryMetric () {
|
queryMetric () {
|
||||||
@@ -236,29 +239,6 @@ export default {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
window.open(href, '_blank')
|
window.open(href, '_blank')
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 通过事件类型转换对应名称
|
|
||||||
* @param type
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
getNameByType (type) {
|
|
||||||
switch (type) {
|
|
||||||
case 'http error': {
|
|
||||||
return 'http error ratio'
|
|
||||||
}
|
|
||||||
case 'dns error': {
|
|
||||||
return 'dns error ratio'
|
|
||||||
}
|
|
||||||
case 'high dns response time': {
|
|
||||||
return 'dns response time'
|
|
||||||
}
|
|
||||||
// 目前ui并未找到此类型,添加以防不测
|
|
||||||
case 'high http resopnse time':
|
|
||||||
default: {
|
|
||||||
return 'http response time'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
|||||||
@@ -324,8 +324,8 @@ export default {
|
|||||||
getMillisecond,
|
getMillisecond,
|
||||||
query () {
|
query () {
|
||||||
Promise.all([this.queryBasic(), this.queryEvent()]).then((responses) => {
|
Promise.all([this.queryBasic(), this.queryEvent()]).then((responses) => {
|
||||||
responses[0].malwareTechniques = responses[0].malwareTechniques.length > 2 ? responses[0].malwareTechniques.replace('[', '').split(',', 5).join(', ') : ''
|
responses[0].malwareTechniques = responses[0].malwareTechniques.length > 2 ? responses[0].malwareTechniques.replace('[', '').replace(']', '').split(',', 5).join(', ') : ''
|
||||||
responses[0].malwareGroups = responses[0].malwareGroups.length > 2 ? responses[0].malwareGroups.replace('[', '').split(',', 5).join(', ') : ''
|
responses[0].malwareGroups = responses[0].malwareGroups.length > 2 ? responses[0].malwareGroups.replace('[', '').replace(']', '').split(',', 5).join(', ') : ''
|
||||||
responses[0].malwarePlatforms = responses[0].malwarePlatforms.length > 1 ? responses[0].malwarePlatforms : ''
|
responses[0].malwarePlatforms = responses[0].malwarePlatforms.length > 1 ? responses[0].malwarePlatforms : ''
|
||||||
responses[0].malwareDescription = responses[0].malwareDescription.length > 1 ? responses[0].malwareDescription : ''
|
responses[0].malwareDescription = responses[0].malwareDescription.length > 1 ? responses[0].malwareDescription : ''
|
||||||
responses[0] && (this.basicInfo = responses[0])
|
responses[0] && (this.basicInfo = responses[0])
|
||||||
|
|||||||
@@ -22,6 +22,14 @@
|
|||||||
<div class="row__label row__label--width130">{{$t('entities.org')}}</div>
|
<div class="row__label row__label--width130">{{$t('entities.org')}}</div>
|
||||||
<div class="row__content">{{entityData.domainWhoisOrg || '-'}}</div>
|
<div class="row__content">{{entityData.domainWhoisOrg || '-'}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.icpCompanyName')}}</div>
|
||||||
|
<div class="row__content">{{entityData.domainIcpCompanyName || '-'}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="overview__row">
|
||||||
|
<div class="row__label row__label--width130">{{$t('entities.icpLicense')}}</div>
|
||||||
|
<div class="row__content">{{entityData.domainIcpSiteLicense || '-'}}</div>
|
||||||
|
</div>
|
||||||
<!-- <div class="overview__row">
|
<!-- <div class="overview__row">
|
||||||
<div class="row__label row__label--width130">{{$t('overall.remark')}}</div>
|
<div class="row__label row__label--width130">{{$t('overall.remark')}}</div>
|
||||||
<div class="row__content">{{entityData.domainDescription || '-'}}</div>
|
<div class="row__content">{{entityData.domainDescription || '-'}}</div>
|
||||||
@@ -352,7 +360,9 @@ export default {
|
|||||||
domainDescription: response.data.result.domainDescription,
|
domainDescription: response.data.result.domainDescription,
|
||||||
domainReputationScore: response.data.result.domainReputationScore,
|
domainReputationScore: response.data.result.domainReputationScore,
|
||||||
domainWhoisAddress: response.data.result.domainWhoisAddress,
|
domainWhoisAddress: response.data.result.domainWhoisAddress,
|
||||||
domainWhoisOrg: response.data.result.domainWhoisOrg
|
domainWhoisOrg: response.data.result.domainWhoisOrg,
|
||||||
|
domainIcpCompanyName: response.data.result.domainIcpCompanyName,
|
||||||
|
domainIcpSiteLicense: response.data.result.domainIcpSiteLicense
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,34 +1,215 @@
|
|||||||
|
/**
|
||||||
|
* jest: https://jestjs.io/docs/getting-started
|
||||||
|
* vue-jest: https://test-utils.vuejs.org/guide/
|
||||||
|
* */
|
||||||
|
|
||||||
import Test from '../src/Test'
|
import Test from '../src/Test'
|
||||||
import { mount } from '@vue/test-utils'
|
import { mount } from '@vue/test-utils'
|
||||||
|
import { getNameByEventType } from '@/utils/tools'
|
||||||
|
import axios from 'axios'
|
||||||
|
import indexedDBUtils from '@/indexedDB'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
|
||||||
// 模拟vue-router库,否则组件中引用vue-router的代码报错
|
// 模拟的axios返回数据
|
||||||
jest.mock('vue-router', () => {
|
const mockId = { data: 2 }
|
||||||
return {
|
const mockTitle = { data: 'title2' }
|
||||||
useRouter: function () { return { currentRoute: '/' } }
|
const mockCount = { data: 999 }
|
||||||
}
|
const mockDifferentParam0 = { data: 0 }
|
||||||
})
|
const mockDifferentParam1 = { data: 1 }
|
||||||
test('点击按钮后count的值+1', async () => {
|
const mergeRequestParam0 = { data: 0 }
|
||||||
// 加载vue组件,获得实例
|
const mergeRequestParam1 = { data: 1 }
|
||||||
const wrapper = mount(Test)
|
const mergeRequestChildParam0 = { data: 0 }
|
||||||
|
const mergeRequestChildParam1 = { data: 1 }
|
||||||
// 取到文本和按钮的dom
|
|
||||||
const textNode = await wrapper.get('[data-test="count"]')
|
describe('单元测试demo', () => {
|
||||||
const button = await wrapper.get('[data-test="button"]')
|
test('Vue组件--点击按钮后count的值+1', async () => {
|
||||||
// 断言文本dom的内容是否是'0'
|
// 若组件中使用了vue-router,需要细化模拟相关内容
|
||||||
expect(textNode.text()).toContain('0')
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
// 模拟按钮dom点击,执行click()方法
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
await button.trigger('click')
|
// 加载vue组件,获得实例
|
||||||
// 断言点击按钮后文本dom的内容是否是'1'
|
const wrapper = mount(Test, {
|
||||||
expect(textNode.text()).toContain('1')
|
global: {
|
||||||
// 再次点击
|
plugins: [ElementPlus]
|
||||||
await button.trigger('click')
|
}
|
||||||
// 断言点击按钮后文本dom的内容是否是'2'
|
})
|
||||||
expect(textNode.text()).toContain('2')
|
// 取到文本和按钮的dom
|
||||||
|
const textNode = await wrapper.get('[test-id="count"]')
|
||||||
// 通过wrapper.vm.xxx直接执行click方法、获取data的数据
|
const button = await wrapper.get('[test-id="button"]')
|
||||||
expect(wrapper.vm.count).toEqual(2)
|
// 断言文本dom的内容是否是'0'
|
||||||
await wrapper.vm.click()
|
expect(textNode.text()).toBe('0')
|
||||||
expect(wrapper.vm.count).toEqual(3)
|
// 模拟按钮dom点击,执行click()方法
|
||||||
|
await button.trigger('click')
|
||||||
// 更多断言类型:https://jestjs.io/zh-Hans/docs/expect
|
// 断言点击按钮后文本dom的内容是否是'1'
|
||||||
|
expect(textNode.text()).toBe('1')
|
||||||
|
// 再次点击
|
||||||
|
await button.trigger('click')
|
||||||
|
// 断言点击按钮后文本dom的内容是否是'2'
|
||||||
|
expect(textNode.text()).toBe('2')
|
||||||
|
/* 更多断言类型:https://jestjs.io/docs/expect */
|
||||||
|
})
|
||||||
|
test('Vue组件--获取路由中的参数', async () => {
|
||||||
|
// query中带上lineTab参数
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: { lineTab: 'total' } })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 取到文本和按钮的dom
|
||||||
|
const textNode = await wrapper.get('[test-id="tab"]')
|
||||||
|
expect(textNode.text()).toBe('total')
|
||||||
|
})
|
||||||
|
test('Vue组件--模拟获取localstorage/sessionStorage的内容', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 模拟localStorage的getItem
|
||||||
|
jest.spyOn(localStorage.__proto__, 'getItem').mockImplementation(key => key)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(wrapper.vm.localstorageValue).toBe('key')
|
||||||
|
})
|
||||||
|
test('Vue组件--直接获取vue实例中的data和method', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
// 测试内容只有一个axios请求的时候
|
||||||
|
axios.get.mockResolvedValue(mockCount)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
mocks: {
|
||||||
|
$t: key => key
|
||||||
|
},
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const textNode = await wrapper.get('[test-id="count"]')
|
||||||
|
// 通过wrapper.vm.xxx直接执行click方法、获取data的数据
|
||||||
|
expect(wrapper.vm.count).toBe(0)
|
||||||
|
await wrapper.vm.click()
|
||||||
|
expect(wrapper.vm.count).toBe(1)
|
||||||
|
await wrapper.vm.getCount()
|
||||||
|
await wrapper.vm.$nextTick(() => {
|
||||||
|
expect(textNode.text()).toBe('999')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
test('Vue组件--多个axios请求', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
// 测试内容有多个url不同的axios请求的话,需分开写
|
||||||
|
axios.get.mockImplementation(url => {
|
||||||
|
switch (url) {
|
||||||
|
case '/api/getObjId':
|
||||||
|
return Promise.resolve(mockId)
|
||||||
|
case '/api/getObjTitle':
|
||||||
|
return Promise.resolve(mockTitle)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const textNode = await wrapper.get('[test-id="id"]')
|
||||||
|
const textNode2 = await wrapper.get('[test-id="title"]')
|
||||||
|
expect(textNode2.text()).toBe('title')
|
||||||
|
await wrapper.vm.getObj()
|
||||||
|
await wrapper.vm.$nextTick(() => {
|
||||||
|
expect(textNode.text()).toBe('2')
|
||||||
|
expect(textNode2.text()).toBe('title2')
|
||||||
|
// 匹配整个对象
|
||||||
|
expect(wrapper.vm.obj).toEqual({ id: 2, title: 'title2' })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
test('Vue组件--多个同url不同参数的axios请求', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
axios.get.mockResolvedValueOnce(mockDifferentParam0)
|
||||||
|
axios.get.mockResolvedValueOnce(mockDifferentParam1)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await wrapper.vm.differentRequestParam()
|
||||||
|
expect(wrapper.vm.differentParamData0).toBe(0)
|
||||||
|
expect(wrapper.vm.differentParamData1).toBe(1)
|
||||||
|
})
|
||||||
|
test('Vue组件--axios请求内包含多个不同url的组合请求', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
axios.get.mockResolvedValueOnce(mergeRequestParam0)
|
||||||
|
axios.get.mockResolvedValueOnce(mergeRequestParam1)
|
||||||
|
|
||||||
|
axios.get.mockImplementation(url => {
|
||||||
|
switch (url) {
|
||||||
|
case '/api/getChildId':
|
||||||
|
return Promise.resolve(mergeRequestChildParam0)
|
||||||
|
case '/api/getChildTitle':
|
||||||
|
return Promise.resolve(mergeRequestChildParam1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await wrapper.vm.mergeRequest()
|
||||||
|
await wrapper.vm.$nextTick(() => {
|
||||||
|
expect(wrapper.vm.mergeRequestData0).toBe(0)
|
||||||
|
expect(wrapper.vm.mergeRequestData1).toBe(1)
|
||||||
|
expect(wrapper.vm.mergeRequestChildData0).toBe(0)
|
||||||
|
expect(wrapper.vm.mergeRequestChildData1).toBe(1)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
test('Vue组件--模拟indexedDB操作', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 模拟indexedDB的内容
|
||||||
|
indexedDBUtils.selectTable.mockReturnValue({
|
||||||
|
put: jest.fn(),
|
||||||
|
get: jest.fn().mockResolvedValue({ a: 1 })
|
||||||
|
})
|
||||||
|
await wrapper.vm.setIndexedDBValue()
|
||||||
|
await wrapper.vm.getIndexedDBValue()
|
||||||
|
expect(wrapper.vm.indexedDBValue).toEqual({ a: 1 })
|
||||||
|
})
|
||||||
|
test('Vue组件--使用第三方组件的情况(以el-table为例)', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
require('vue-router').useRouter.mockReturnValue({ currentRoute: { value: { path: '/' } } })
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(Test, {
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 执行nextTick等待el-table渲染完成
|
||||||
|
await wrapper.vm.$nextTick()
|
||||||
|
const textNode = await wrapper.get('[test-id="name0"]')
|
||||||
|
const textNode2 = await wrapper.get('[test-id="age1"]')
|
||||||
|
expect(textNode.text()).toBe('a')
|
||||||
|
expect(textNode2.text()).toBe('11')
|
||||||
|
})
|
||||||
|
test('js方法--getNameByEventType', async () => {
|
||||||
|
expect(getNameByEventType('http error')).toBe('http error ratio')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
41
test/init.js
Normal file
41
test/init.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { config } from '@vue/test-utils'
|
||||||
|
|
||||||
|
/* 开启测试 */
|
||||||
|
config.global.mocks.isUnitTesting = true
|
||||||
|
/* 初始化dayjs */
|
||||||
|
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
|
||||||
|
// 引入 lodash 工具 模拟 lodash
|
||||||
|
const _ = require('lodash') // lodash工具
|
||||||
|
|
||||||
|
/* 模拟vue-router库,否则组件中引用vue-router的代码报错 */
|
||||||
|
jest.mock('vue-router', () => {
|
||||||
|
return {
|
||||||
|
useRouter: jest.fn(),
|
||||||
|
useRoute: jest.fn(),
|
||||||
|
createWebHashHistory: jest.fn(),
|
||||||
|
createRouter: jest.fn().mockReturnValue({
|
||||||
|
beforeEach: jest.fn()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
/* 模拟axios */
|
||||||
|
jest.mock('axios')
|
||||||
|
/* 模拟indexedDB工具 */
|
||||||
|
jest.mock('@/indexedDB')
|
||||||
|
/* 模拟$t */
|
||||||
|
config.global.mocks.$t = key => key
|
||||||
|
/* 模拟$route,具体用例中需要不同值时重写覆盖即可 */
|
||||||
|
config.global.mocks.$route = { query: '' }
|
||||||
|
/* 模拟 lodash */
|
||||||
|
config.global.mocks.$_ = _
|
||||||
|
/* 消除warn */
|
||||||
|
jest.spyOn(console, 'warn').mockImplementation(() => {})
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import NetworkOverviewDdosDetection from '@/views/charts2/charts/networkOverview/NetworkOverviewDdosDetection'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const mockGet = {
|
||||||
|
data: {"status":200,"code":200,"queryKey":"dec6723e173e8fa2b00917dc597bfb27","success":true,"message":null,"statistics":{"elapsed":0,"rows_read":2,"result_size":58,"result_rows":1},"job":null,"formatType":"json","meta":[{"name":"attack_event_count","type":"long","category":"Metric"},{"name":"attacker_count","type":"long","category":"Metric"},{"name":"victim_count","type":"long","category":"Metric"}],"data":{"resultType":"object","result":[{"attackEventCount":1200000,"attackerCount":2687878,"victimCount":36676767}]},"originalUrl":"http://192.168.44.55:9999?query=SELECT%20COUNT%28*%29%20AS%20attack_event_count%2C%20COUNT%28DISTINCT%28offender_ip%29%29%20AS%20attacker_count%2C%20COUNT%28DISTINCT%28victim_ip%29%29%20AS%20victim_count%20FROM%20security_event%20WHERE%20start_time%20%3E%3D%201675043912%20AND%20start_time%20%3C%201675047512%20AND%20security_type%20%3D%20%27ddos%27&format=json&option=real-time","msg":"OK"}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeFilter = {
|
||||||
|
dateRangeValue: -1,
|
||||||
|
startTime: 1675043912,
|
||||||
|
endTime: 1675047512
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('views/charts2/charts/networkOverview/NetworkOverviewDdosDetection.vue测试', () => {
|
||||||
|
test('攻击、受害、攻击数事件:ddos检测图', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟 axios 返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(NetworkOverviewDdosDetection, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const attackEventCount = wrapper.get('[test-id="attackEventCount"]')
|
||||||
|
const attackerCount = wrapper.get('[test-id="attackerCount"]')
|
||||||
|
const victimCount = wrapper.get('[test-id="victimCount"]')
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
expect(attackEventCount.text()).toEqual('1.20 M')
|
||||||
|
expect(attackerCount.text()).toEqual('2.69 M')
|
||||||
|
expect(victimCount.text()).toEqual('36.68 M')
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
import NetworkOverviewLine from '@/views/charts2/charts/networkOverview/NetworkOverviewLine'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
const mockGet = {
|
||||||
|
data: {"status":200,"code":200,"success":true,"message":null,"formatType":"json","data":{"resultType":"object","result":[{"type":"bytes","totalBitsRate":{"values":[[1673247564,"96801019.52"]],"analysis":{"avg":"112042808.24","max":"301842105.76","min":"52096324","p95":"168089003.35199997"}},"inboundBitsRate":{"values":[[1673247564,"11814508.48"]],"analysis":{"avg":"18587597.36","max":"137528138.88","min":"3181142.88","p95":"49561521.447999954"}},"outboundBitsRate":{"values":[[1673247564,"84282965.52"]],"analysis":{"avg":"87557861.44","max":"290402258","min":"45337684.48","p95":"121041718.81199999"}},"internalBitsRate":{"values":[[1673247564,"9125.12"]],"analysis":{"avg":"278114.32","max":"2215460.48","min":"0","p95":"923494.5719999998"}},"throughBitsRate":{"values":[[1673247564,"694420.48"]],"analysis":{"avg":"5619235.12","max":"42455480.24","min":"262607.76","p95":"13559588.195999999"}},"other":{"values":[[1673247564,"0.00"]],"analysis":{"avg":"0.01","max":"0.08","min":"0.00","p95":"0.08"}}},{"type":"packets","totalPacketsRate":{"values":[[1673247564,"12077.53"]],"analysis":{"avg":"14062.37","max":"32840.42","min":"6564.17","p95":"20923.167999999987"}},"inboundPacketsRate":{"values":[[1673247564,"3865.58"]],"analysis":{"avg":"4241.61","max":"15460.03","min":"1918.22","p95":"8549.799999999997"}},"outboundPacketsRate":{"values":[[1673247564,"8118.89"]],"analysis":{"avg":"9170.98","max":"27134.58","min":"4510.25","p95":"13690.540999999996"}},"internalPacketsRate":{"values":[[1673247564,"15.89"]],"analysis":{"avg":"35.95","max":"276.47","min":"0.00","p95":"122.49749999999999"}},"throughPacketsRate":{"values":[[1673247564,"77.17"]],"analysis":{"avg":"613.82","max":"3768.56","min":"42.92","p95":"1279.757499999999"}},"other":{"values":[[1673247564,"0.00"]],"analysis":{"avg":"0","max":"0.01","min":"0.00","p95":"0.01"}}},{"type":"sessions","totalSessionsRate":{"values":[[1673247564,"29.92"]],"analysis":{"avg":"29.89","max":"29.92","min":"29.67","p95":"29.92"}}}]},"msg":"OK"}
|
||||||
|
}
|
||||||
|
const timeFilter = {
|
||||||
|
dateRangeValue: -1,
|
||||||
|
startTime: 1673244000000,
|
||||||
|
endTime: 1673247600000
|
||||||
|
}
|
||||||
|
const chart = {"id":1,"name":"network overview line","i18n":"","panelId":1,"pid":0,"type":102,"x":0,"y":0,"w":19,"h":6,"params":{},"cby":1,"ctime":"2022-07-06 16:59:22","uby":1,"utime":"2022-07-06 16:59:22","remark":"","state":1,"system":0,"buildIn":0,"uuser":{"id":1,"name":null,"username":"admin","salt":null,"lang":null,"theme":null,"lastLoginIp":null,"lastLoginTime":null,"ctime":null,"cby":null,"email":null,"mobile":null,"status":null,"source":null,"buildIn":null,"roleIds":null,"usergroupIds":null,"roles":null,"apiKeyId":null},"cuser":{"id":1,"name":null,"username":"admin","salt":null,"lang":null,"theme":null,"lastLoginIp":null,"lastLoginTime":null,"ctime":null,"cby":null,"email":null,"mobile":null,"status":null,"source":null,"buildIn":null,"roleIds":null,"usergroupIds":null,"roles":null,"apiKeyId":null},"children":[],"parent":null,"panel":{"id":1,"name":"Network Overview","i18n":null,"type":null,"params":null,"cby":null,"ctime":null,"uby":null,"utime":null,"remark":null,"state":null,"buildIn":null,"uuser":null,"cuser":null},"i":1,"category":"echarts","firstShow":false,"moved":false}
|
||||||
|
|
||||||
|
describe('views/charts2/charts/networkOverview/NetworkOverviewLine.vue测试', () => {
|
||||||
|
test('Metric=Bits/s,点击第三个tab', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(NetworkOverviewLine, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter,
|
||||||
|
chart
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const textNode0 = await wrapper.get('[test-id="tabContent0"]')
|
||||||
|
const textNode1 = await wrapper.get('[test-id="tabContent1"]')
|
||||||
|
const textNode2 = await wrapper.get('[test-id="tabContent2"]')
|
||||||
|
// 延迟等待渲染。使用wrapper.vm.$nextTick有时不管用(例如组件中使用了setTimeout的时候)
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
expect(textNode0.text()).toEqual('112.04Mbps')
|
||||||
|
expect(textNode1.text()).toEqual('18.59Mbps')
|
||||||
|
expect(textNode2.text()).toEqual('87.56Mbps')
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
|
||||||
|
// 点击tab后,是否切换高亮状态
|
||||||
|
const textNode3 = await wrapper.get('[test-id="tab2"]')
|
||||||
|
await textNode3.trigger('click')
|
||||||
|
expect(textNode3.classes()).toContain('is-active')
|
||||||
|
})
|
||||||
|
test('Metric=Packets/s', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(NetworkOverviewLine, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter,
|
||||||
|
chart,
|
||||||
|
metric: 'Packets/s'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const textNode0 = await wrapper.get('[test-id="tabContent0"]')
|
||||||
|
const textNode1 = await wrapper.get('[test-id="tabContent1"]')
|
||||||
|
const textNode2 = await wrapper.get('[test-id="tabContent2"]')
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
expect(textNode0.text()).toEqual('14.06Kpackets/s')
|
||||||
|
expect(textNode1.text()).toEqual('4.24Kpackets/s')
|
||||||
|
expect(textNode2.text()).toEqual('9.17Kpackets/s')
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
})
|
||||||
|
test('Metric=Sessions/s', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟axios返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(NetworkOverviewLine, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter,
|
||||||
|
chart,
|
||||||
|
metric: 'Sessions/s'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const textNode0 = await wrapper.get('[test-id="tabContent0"]')
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
expect(textNode0.text()).toEqual('29.89sessions/s')
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
})
|
||||||
|
})
|
||||||
148
test/views/charts2/charts/npm/NpmAppCategoryScore.test.js
Normal file
148
test/views/charts2/charts/npm/NpmAppCategoryScore.test.js
Normal file
File diff suppressed because one or more lines are too long
54
test/views/charts2/charts/npm/NpmEventsHeader.test.js
Normal file
54
test/views/charts2/charts/npm/NpmEventsHeader.test.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import NpmEventsHeader from '@/views/charts2/charts/npm/NpmEventsHeader'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
// 模拟数据
|
||||||
|
const chartData = {
|
||||||
|
data: {"status":200,"code":200,"queryKey":"6480498979f7501d822572ebeb9e9665","success":true,"message":null,"statistics":{"elapsed":0,"rows_read":3,"result_size":167,"result_rows":5},"job":null,"formatType":"json","meta":[{"name":"event_severity","type":"string","category":"Dimension"},{"name":"count","type":"long","category":"Metric"}],"data":{"resultType":"table","result":[{"eventSeverity":"critical","count":322334},{"eventSeverity":"high","count":1111},{"eventSeverity":"info","count":122222},{"eventSeverity":"low","count":14456678},{"eventSeverity":"medium","count":2000000}]},"originalUrl":"http://192.168.44.55:9999?query=SELECT%20event_severity%20AS%20event_severity%2C%20COUNT%28*%29%20AS%20count%20FROM%20performance_event%20WHERE%20start_time%20%3E%3D%201675026686%20AND%20end_time%20%3C%201675048286%20GROUP%20BY%20event_severity&format=json&option=real-time","msg":"OK"}
|
||||||
|
}
|
||||||
|
// type
|
||||||
|
const type = 'severity'
|
||||||
|
|
||||||
|
describe('views/charts2/charts/npm/NpmEventsHeader.vue测试', () => {
|
||||||
|
test('严重等级各等级个数:npm event 严重等级单值', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟 axios 返回数据
|
||||||
|
axios.get.mockResolvedValue(chartData)
|
||||||
|
// 加载vue组件,获得实例
|
||||||
|
const wrapper = mount(NpmEventsHeader, {
|
||||||
|
propsData: {
|
||||||
|
type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 严重等级
|
||||||
|
const severity0 = wrapper.get('[test-id="severity0"]')
|
||||||
|
const severity1 = wrapper.get('[test-id="severity1"]')
|
||||||
|
const severity2 = wrapper.get('[test-id="severity2"]')
|
||||||
|
const severity3 = wrapper.get('[test-id="severity3"]')
|
||||||
|
const severity4 = wrapper.get('[test-id="severity4"]')
|
||||||
|
// 各等级个数
|
||||||
|
const total0 = wrapper.get('[test-id="total0"]')
|
||||||
|
const total1 = wrapper.get('[test-id="total1"]')
|
||||||
|
const total2 = wrapper.get('[test-id="total2"]')
|
||||||
|
const total3 = wrapper.get('[test-id="total3"]')
|
||||||
|
const total4 = wrapper.get('[test-id="total4"]')
|
||||||
|
|
||||||
|
// type
|
||||||
|
expect(wrapper.vm.type).toEqual('severity')
|
||||||
|
|
||||||
|
expect(severity0.text()).toEqual('critical')
|
||||||
|
expect(severity1.text()).toEqual('high')
|
||||||
|
expect(severity2.text()).toEqual('medium')
|
||||||
|
expect(severity3.text()).toEqual('low')
|
||||||
|
expect(severity4.text()).toEqual('info')
|
||||||
|
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
expect(total0.text()).toEqual('322,334')
|
||||||
|
expect(total1.text()).toEqual('1,111')
|
||||||
|
expect(total2.text()).toEqual('2,000,000')
|
||||||
|
expect(total3.text()).toEqual('14,456,678')
|
||||||
|
expect(total4.text()).toEqual('122,222')
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
})
|
||||||
|
})
|
||||||
248
test/views/charts2/charts/npm/NpmNetworkQuantity.test.js
Normal file
248
test/views/charts2/charts/npm/NpmNetworkQuantity.test.js
Normal file
File diff suppressed because one or more lines are too long
162
test/views/charts2/charts/npm/NpmRecentEvents.test.js
Normal file
162
test/views/charts2/charts/npm/NpmRecentEvents.test.js
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
import NpmRecentEvents from '@/views/charts2/charts/npm/NpmRecentEvents'
|
||||||
|
import { mount } from '@vue/test-utils'
|
||||||
|
import axios from 'axios'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
// 未下钻
|
||||||
|
const mockGet = {
|
||||||
|
data: {"status":200,"code":200,"queryKey":"68d8aa5867b08b926b5bd38c36add9e5","success":true,"message":null,"statistics":{"elapsed":0,"rows_read":2,"result_size":550,"result_rows":5},"job":null,"formatType":"json","meta":[{"name":"event_id","type":"long","category":"Metric"},{"name":"event_severity","type":"string","category":"Metric"},{"name":"event_key","type":"string","category":"Metric"},{"name":"event_type","type":"string","category":"Metric"}],"data":{"resultType":"table","result":[{"eventId":1173511643475208192,"eventSeverity":"critical","eventKey":"114.114.114.114 dns error","eventType":"dns error"},{"eventId":1173504415263352832,"eventSeverity":"high","eventKey":"116.178.78.241 http error","eventType":"http error"},{"eventId":1173492761289025537,"eventSeverity":"medium","eventKey":"223.6.6.6 dns error","eventType":"dns error"},{"eventId":1173489002890651648,"eventSeverity":"low","eventKey":"114.114.114.114 dns error","eventType":"dns error"},{"eventId":1173482380537620480,"eventSeverity":"info","eventKey":"1.1.1.2 dns error","eventType":"http error"},{"eventId":1173482380537620481,"eventSeverity":"critical","eventKey":"1.1.1.2 dns error","eventType":"dns error"}]},"originalUrl":"http://192.168.44.55:9999?query=SELECT%20event_id%20AS%20event_id%2Cevent_severity%20AS%20event_severity%2C%20event_key%20AS%20event_key%2C%20event_type%20AS%20event_type%20FROM%20performance_event%20WHERE%20start_time%20%3E%3D%201675227528%20AND%20end_time%20%3C%201675231128%20ORDER%20BY%20start_time%20DESC%20%20LIMIT%208%20&format=json&option=real-time","msg":"OK"}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下钻
|
||||||
|
const mockGet1 = {
|
||||||
|
data: {"status":200,"code":200,"queryKey":"fc0bd92bf3b48a37310d5c004d8b7a7b","success":true,"message":null,"statistics":{"elapsed":0,"rows_read":2,"result_size":689,"result_rows":7},"job":null,"formatType":"json","meta":[{"name":"event_id","type":"long","category":"Metric"},{"name":"event_severity","type":"string","category":"Metric"},{"name":"event_type","type":"string","category":"Metric"},{"name":"start_time","type":"long","category":"Metric"}],"data":{"resultType":"table","result":[{"eventId":1132790825086844928,"eventSeverity":"critical","eventType":"http error","startTime":1672802700},{"eventId":1132132403379142657,"eventSeverity":"high","eventType":"dns error","startTime":1672763400},{"eventId":1131441760155688960,"eventSeverity":"low","eventType":"dns error","startTime":1672722300},{"eventId":1131411523384598528,"eventSeverity":"medium","eventType":"http error","startTime":1672720500},{"eventId":1131390214323789824,"eventSeverity":"info","eventType":"dns error","startTime":1672719300},{"eventId":1131306200132968450,"eventSeverity":"critical","eventType":"http error","startTime":1672714200}]},"originalUrl":"http://192.168.44.55:9999?query=SELECT%20event_id%20AS%20event_id%2Cevent_severity%20AS%20event_severity%2C%20event_type%20AS%20event_type%2C%20start_time%20AS%20start_time%20FROM%20performance_event%20WHERE%20start_time%20%3E%3D%201672675200%20AND%20start_time%20%3C%201677513600%20AND%20server_ip%20%3D%20%27116.178.236.216%27%20ORDER%20BY%20start_time%20DESC&format=json&option=real-time","msg":"OK"}
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
curTab: "country",
|
||||||
|
dimensionType: "ip",
|
||||||
|
fourthMenu: "116.178.214.84",
|
||||||
|
fourthPanel: "8",
|
||||||
|
networkOverviewBeforeTab: "ip",
|
||||||
|
panelName: "116.178.214.84",
|
||||||
|
queryCondition: "common_client_ip='116.178.214.84' OR common_server_ip='116.178.214.84'",
|
||||||
|
t: "1675236779453",
|
||||||
|
tabIndex: "1",
|
||||||
|
tabOperationBeforeType: "",
|
||||||
|
tabOperationType: "4",
|
||||||
|
thirdMenu: "network.ips",
|
||||||
|
thirdPanel: "12"
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeFilter = {
|
||||||
|
dateRangeValue: -1,
|
||||||
|
startTime: 1675043912,
|
||||||
|
endTime: 1675047512
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('views/charts2/charts/npm/NpmRecentEvents.vue测试', () => {
|
||||||
|
test('npm events 近期事件表格 未下钻', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: {} })
|
||||||
|
// 模拟 axios 返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet)
|
||||||
|
|
||||||
|
const wrapper = mount(NpmRecentEvents, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
const severity0 = wrapper.get('[test-id="eventSeverity-critical-0"]')
|
||||||
|
const severity1 = wrapper.get('[test-id="eventSeverity-high-1"]')
|
||||||
|
const severity2 = wrapper.get('[test-id="eventSeverity-medium-2"]')
|
||||||
|
const severity3 = wrapper.get('[test-id="eventSeverity-low-3"]')
|
||||||
|
const severity4 = wrapper.get('[test-id="eventSeverity-info-4"]')
|
||||||
|
const severity5 = wrapper.get('[test-id="eventSeverity-critical-5"]')
|
||||||
|
|
||||||
|
expect(severity0.text()).toEqual('critical')
|
||||||
|
expect(severity1.text()).toEqual('high')
|
||||||
|
expect(severity2.text()).toEqual('medium')
|
||||||
|
expect(severity3.text()).toEqual('low')
|
||||||
|
expect(severity4.text()).toEqual('info')
|
||||||
|
expect(severity5.text()).toEqual('critical')
|
||||||
|
|
||||||
|
expect(severity0.classes()).toContain('critical')
|
||||||
|
expect(severity1.classes()).toContain('high')
|
||||||
|
expect(severity2.classes()).toContain('medium')
|
||||||
|
expect(severity3.classes()).toContain('low')
|
||||||
|
expect(severity4.classes()).toContain('info')
|
||||||
|
expect(severity5.classes()).toContain('critical')
|
||||||
|
|
||||||
|
const eventKey0 = wrapper.get('[test-id="eventKey-114.114.114.114-0"]')
|
||||||
|
const eventKey1 = wrapper.get('[test-id="eventKey-116.178.78.241-1"]')
|
||||||
|
const eventKey2 = wrapper.get('[test-id="eventKey-223.6.6.6-2"]')
|
||||||
|
const eventKey3 = wrapper.get('[test-id="eventKey-114.114.114.114-3"]')
|
||||||
|
const eventKey4 = wrapper.get('[test-id="eventKey-1.1.1.2-4"]')
|
||||||
|
|
||||||
|
expect(eventKey0.text()).toEqual('114.114.114.114')
|
||||||
|
expect(eventKey1.text()).toEqual('116.178.78.241')
|
||||||
|
expect(eventKey2.text()).toEqual('223.6.6.6')
|
||||||
|
expect(eventKey3.text()).toEqual('114.114.114.114')
|
||||||
|
expect(eventKey4.text()).toEqual('1.1.1.2')
|
||||||
|
|
||||||
|
const eventType0 = wrapper.get('[test-id="eventType-dns error-0"]')
|
||||||
|
const eventType1 = wrapper.get('[test-id="eventType-http error-1"]')
|
||||||
|
const eventType2 = wrapper.get('[test-id="eventType-dns error-2"]')
|
||||||
|
const eventType3 = wrapper.get('[test-id="eventType-dns error-3"]')
|
||||||
|
const eventType4 = wrapper.get('[test-id="eventType-http error-4"]')
|
||||||
|
|
||||||
|
expect(eventType0.text()).toEqual('dns error')
|
||||||
|
expect(eventType1.text()).toEqual('http error')
|
||||||
|
expect(eventType2.text()).toEqual('dns error')
|
||||||
|
expect(eventType3.text()).toEqual('dns error')
|
||||||
|
expect(eventType4.text()).toEqual('http error')
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
}, 200))
|
||||||
|
})
|
||||||
|
test('npm events 近期事件表格 下钻', async () => {
|
||||||
|
require('vue-router').useRoute.mockReturnValue({ query: query })
|
||||||
|
// 模拟 axios 返回数据
|
||||||
|
axios.get.mockResolvedValue(mockGet1)
|
||||||
|
|
||||||
|
const wrapper = mount(NpmRecentEvents, {
|
||||||
|
propsData: {
|
||||||
|
timeFilter
|
||||||
|
},
|
||||||
|
global: {
|
||||||
|
plugins: [ElementPlus]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await new Promise(resolve => setTimeout(() => {
|
||||||
|
const severity0 = wrapper.get('[test-id="eventSeverity-critical-0"]')
|
||||||
|
const severity1 = wrapper.get('[test-id="eventSeverity-high-1"]')
|
||||||
|
const severity2 = wrapper.get('[test-id="eventSeverity-low-2"]')
|
||||||
|
const severity3 = wrapper.get('[test-id="eventSeverity-medium-3"]')
|
||||||
|
const severity4 = wrapper.get('[test-id="eventSeverity-info-4"]')
|
||||||
|
const severity5 = wrapper.get('[test-id="eventSeverity-critical-5"]')
|
||||||
|
|
||||||
|
expect(severity0.text()).toEqual('critical')
|
||||||
|
expect(severity1.text()).toEqual('high')
|
||||||
|
expect(severity2.text()).toEqual('low')
|
||||||
|
expect(severity3.text()).toEqual('medium')
|
||||||
|
expect(severity4.text()).toEqual('info')
|
||||||
|
expect(severity5.text()).toEqual('critical')
|
||||||
|
|
||||||
|
expect(severity0.classes()).toContain('critical')
|
||||||
|
expect(severity1.classes()).toContain('high')
|
||||||
|
expect(severity2.classes()).toContain('low')
|
||||||
|
expect(severity3.classes()).toContain('medium')
|
||||||
|
expect(severity4.classes()).toContain('info')
|
||||||
|
expect(severity5.classes()).toContain('critical')
|
||||||
|
|
||||||
|
const eventType0 = wrapper.get('[test-id="eventType-http error-0"]')
|
||||||
|
const eventType1 = wrapper.get('[test-id="eventType-dns error-1"]')
|
||||||
|
const eventType2 = wrapper.get('[test-id="eventType-dns error-2"]')
|
||||||
|
const eventType3 = wrapper.get('[test-id="eventType-http error-3"]')
|
||||||
|
const eventType4 = wrapper.get('[test-id="eventType-dns error-4"]')
|
||||||
|
|
||||||
|
expect(eventType0.text()).toEqual('http error')
|
||||||
|
expect(eventType1.text()).toEqual('dns error')
|
||||||
|
expect(eventType2.text()).toEqual('dns error')
|
||||||
|
expect(eventType3.text()).toEqual('http error')
|
||||||
|
expect(eventType4.text()).toEqual('dns error')
|
||||||
|
|
||||||
|
const startTime0 = wrapper.get('[test-id="startTime-2023-01-04T11:25:00+08:00-0"]')
|
||||||
|
const startTime1 = wrapper.get('[test-id="startTime-2023-01-04T00:30:00+08:00-1"]')
|
||||||
|
const startTime2 = wrapper.get('[test-id="startTime-2023-01-03T13:05:00+08:00-2"]')
|
||||||
|
const startTime3 = wrapper.get('[test-id="startTime-2023-01-03T12:35:00+08:00-3"]')
|
||||||
|
const startTime4 = wrapper.get('[test-id="startTime-2023-01-03T12:15:00+08:00-4"]')
|
||||||
|
|
||||||
|
expect(startTime0.text()).toEqual('2023-01-04T11:25:00+08:00')
|
||||||
|
expect(startTime1.text()).toEqual('2023-01-04T00:30:00+08:00')
|
||||||
|
expect(startTime2.text()).toEqual('2023-01-03T13:05:00+08:00')
|
||||||
|
expect(startTime3.text()).toEqual('2023-01-03T12:35:00+08:00')
|
||||||
|
expect(startTime4.text()).toEqual('2023-01-03T12:15:00+08:00')
|
||||||
|
|
||||||
|
resolve()
|
||||||
|
}, 300))
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user