CN-643 Dashboard - network overview - 表格点击事件开发:交互等内容开发

This commit is contained in:
hanyuxia
2022-08-05 15:46:31 +08:00
parent e7fcd2f4e2
commit 9b59060ce6
14 changed files with 1379 additions and 253 deletions

View File

@@ -57,6 +57,98 @@
font-size: 17px; font-size: 17px;
color: #046ECA; color: #046ECA;
} }
.header__left-breadcrumb{
display:flex;
align-items:center;
.route-menu:hover{
cursor: pointer;
color: #2C72C6;
}
.header__left-breadcrumb-item-select{
display:flex;
align-items: center;
.search-input{
width:100%;
padding: 4px 4px 0px 4px;
.el-input__inner{
padding:0px 4px;
background: #FFFFFF;
border: 1px solid #C5C5C5;
box-shadow: -1px 1px 10px -1px rgba(205,205,205,0.85);
border-radius: 2px;
font-size: 12px;
/*color: rgba(87,87,87,0.60);*/
letter-spacing: 0;
font-weight: 400;
}
}
.breadcrumb-button{
align-items: center;
width: 100%;
height: 24px;
justify-content: center;
line-height: 24px;
padding: 0px 6px;
span {
margin-right: 6px;
}
}
.breadcrumb-button:hover,.breadcrumb-button__active {
cursor:pointer;
background: rgba(113,113,113,0.10);
box-shadow: 0 2px 4px 0 rgba(51,51,51,0.02);
border-radius: 2px;
}
.breadcrumb__popper{
top: -7px !important;
width:auto !important;
max-height:206px;
overflow:hidden;
padding: 0px !important;
background: #FFFFFF;
border:1px solid #C5C5C5 !important;
box-shadow: -1px 1px 10px -1px rgba(205,205,205,0.85)!important;
border-radius: 2px !important;
.selected {
color: #0091ff;
font-weight: bold;
}
.el-popper {
max-height: 405px;
}
.select-dropdown {
max-height:172px;
width:100%;
margin: 1px 0px;
overflow:auto;
list-style: none;
padding:4px 0px;
box-sizing: border-box;
.select-dropdown__item:hover{
background-color: #F5F7FA !important;
}
.select-dropdown__item{
width:100%;
height:30px;
padding:0px 11px;
line-height:30px;
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: #666665;
display: list-item;
text-align: -webkit-match-parent;
box-sizing: border-box;
cursor: pointer;
font-family: Helvetica;
font-size: 12px;
font-weight: 400;
}
}
}
}
}
} }
.cn-menu-modal { .cn-menu-modal {
top: 60px; top: 60px;
@@ -184,3 +276,16 @@
.vue-grid-item{ .vue-grid-item{
transition: none; transition: none;
} }
#breadcrumbSelectDropdown::-webkit-scrollbar {
width:10px;
}
#breadcrumbSelectDropdown::-webkit-scrollbar-track-piece {
background: #ECECEC;
border-radius: 0 0 2px 0;
}
#breadcrumbSelectDropdown::-webkit-scrollbar-thumb {
background-clip: content-box !important;
background: #C5C5C5;
border-radius: 4px;
border: 2px solid transparent;
}

View File

@@ -3,6 +3,9 @@
$grey:#353636; $grey:#353636;
height:100%; height:100%;
font-size:12px; font-size:12px;
.tab-hide{
margin-top:40px;
}
.cn-chart__tabs { .cn-chart__tabs {
height:100%; height:100%;
.tab-pane { .tab-pane {
@@ -12,6 +15,9 @@
border-radius: 4px; border-radius: 4px;
.tab-table { .tab-table {
border:0px; border:0px;
.data-click:hover{
cursor: pointer;
}
} }
.data-total{ .data-total{
display: flex !important; display: flex !important;
@@ -84,6 +90,9 @@
.el-tabs__content { .el-tabs__content {
height: calc(100% - 40px); height: calc(100% - 40px);
border:none; border:none;
.el-table__body-wrapper {
height: calc(100% - 32px) !important;
}
} }
} }
.tab-search { .tab-search {

View File

@@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "cn-icon"; /* Project id 2614877 */ font-family: "cn-icon"; /* Project id 2614877 */
src: url('iconfont.woff2?t=1658134544266') format('woff2'), src: url('iconfont.woff2?t=1659663639076') format('woff2'),
url('iconfont.woff?t=1658134544266') format('woff'), url('iconfont.woff?t=1659663639076') format('woff'),
url('iconfont.ttf?t=1658134544266') format('truetype'); url('iconfont.ttf?t=1659663639076') format('truetype');
} }
.cn-icon { .cn-icon {
@@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.cn-icon-xiala:before {
content: "\e7a3";
}
.cn-icon-Provider:before {
content: "\e7a1";
}
.cn-icon-APP1:before {
content: "\e7a2";
}
.cn-icon-social-network:before { .cn-icon-social-network:before {
content: "\e79b"; content: "\e79b";
} }

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -38,8 +38,49 @@
<div class="cn-header__nav"> <div class="cn-header__nav">
<i class="cn-icon cn-icon-a-NetworkAnalytics"></i> <i class="cn-icon cn-icon-a-NetworkAnalytics"></i>
<el-breadcrumb class="header__left-breadcrumb" separator=">"> <el-breadcrumb class="header__left-breadcrumb" separator=">">
<el-breadcrumb-item class="header__left-breadcrumb-item" :title="item" v-for="item in breadcrumb" :key="item"> <el-breadcrumb-item class="header__left-breadcrumb-item" :id="`breadcrumb${item}`" :title="item" v-for="(item,index) in breadcrumb" :key="item">
{{item}} <template v-if="index===3">
<div class="header__left-breadcrumb-item-select">
<el-popover placement="bottom-start"
ref="breadcrumbPopover"
:show-arrow="false"
:append-to-body="false"
:hide-after="0"
:show-after="0"
popper-class="breadcrumb__popper"
@show="showBreadcrumbPopover(item)"
@hide="hideBreadcrumbPopover()"
trigger="click">
<template #reference>
<div class="breadcrumb-button" id="breadcrumbButton" :class="showBackground?'breadcrumb-button__active':''" >
<span id="breadcrumbValue"> {{item}}</span><i class="cn-icon-xiala cn-icon"></i>
</div>
</template>
<el-row type="flex" justify="center" style="width: fit-content;flex-direction: column;">
<div class="search-input">
<el-input placeholder="Filter options"
size="mini"
v-model="dropDownValue"
@input="dropDownSearch"></el-input>
</div>
<ul class="select-dropdown" id="breadcrumbSelectDropdown" @scroll="scrollList()">
<li v-for="item in breadcrumbColumnValueListShow" title='' :key="item" :id="item" class="select-dropdown__item" @click="changeValue(item)" :class="selected?'':''">
<span>{{item}}</span>
</li>
</ul>
</el-row>
</el-popover>
</div>
</template>
<template v-else-if="index===2">
<span class="route-menu" @click="jump(path,item,'',3)">{{item}}</span>
</template>
<template v-else-if="index===1">
<span class="route-menu" @click="jump(path,'','',2)">{{item}}</span>
</template>
<template v-else>
<span>{{item}}</span>
</template>
</el-breadcrumb-item> </el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
</div> </div>
@@ -108,8 +149,10 @@
<script> <script>
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { get, put } from '@/utils/http' import { get, put } from '@/utils/http'
import { entityType, storageKey } from '@/utils/constants' import { entityType, storageKey, networkOverviewTabList, operationType, networkOverviewSearchUrl } from '@/utils/constants'
import { api } from '@/utils/api' import { api } from '@/utils/api'
import { ref } from 'vue'
import { getNowTime, getSecond } from '@/utils/date-util'
export default { export default {
name: 'Header', name: 'Header',
@@ -136,7 +179,14 @@ export default {
newPwd: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }], newPwd: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
newPwd2: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: passwordComparison, trigger: 'blur' }] newPwd2: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: passwordComparison, trigger: 'blur' }]
}, },
showMenu: false showMenu: false,
dropDownValue: '',
breadcrumbColumnValueListShow: [],
valueMeta: [],
showBackground: false,
selected: false,
valueMenuId: '',
curPageNum: 1
} }
}, },
computed: { computed: {
@@ -163,15 +213,22 @@ export default {
const breadcrumbMap = [] const breadcrumbMap = []
this.$store.getters.menuList.forEach(menu => { this.$store.getters.menuList.forEach(menu => {
if (this.$_.isEmpty(menu.children) && menu.route) { if (this.$_.isEmpty(menu.children) && menu.route) {
breadcrumbMap.push({ name: this.$t(menu.i18n), path: menu.route }) breadcrumbMap.push({ name: this.$t(menu.i18n), path: menu.route, columnName: menu.columnName, columnValue: menu.columnValue })
} else if (!this.$_.isEmpty(menu.children)) { } else if (!this.$_.isEmpty(menu.children)) {
menu.children.forEach(child => { menu.children.forEach(child => {
breadcrumbMap.push({ name: child.i18n ? this.$t(child.i18n) : child.name, parentName: menu.i18n ? this.$t(menu.i18n) : menu.name, path: child.route }) breadcrumbMap.push({ name: child.i18n ? this.$t(child.i18n) : child.name, parentName: menu.i18n ? this.$t(menu.i18n) : menu.name, path: child.route, columnName: child.columnName, columnValue: child.columnValue })
}) })
} }
}) })
const breadcrumb = breadcrumbMap.find(b => this.path === b.path) const breadcrumb = breadcrumbMap.find(b => this.path === b.path)
if (breadcrumb.columnValue) {
return breadcrumb ? [breadcrumb.parentName, breadcrumb.name, this.$t(breadcrumb.columnName), breadcrumb.columnValue] : []
} else if (breadcrumb.columnName) {
return breadcrumb ? [breadcrumb.parentName, breadcrumb.name, this.$t(breadcrumb.columnName)] : []
} else {
return breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : [] return breadcrumb ? [breadcrumb.parentName, breadcrumb.name] : []
}
}, },
path () { path () {
const { path } = useRoute() const { path } = useRoute()
@@ -183,6 +240,9 @@ export default {
storeFrom () { storeFrom () {
return this.$store.getters.from return this.$store.getters.from
}, },
breadcrumbColumnValueListAll () {
return this.$store.getters.getBreadcrumbColumnValueList
},
route () { route () {
return this.$route.path return this.$route.path
} }
@@ -201,7 +261,11 @@ export default {
this.from = Object.keys(this.entityType)[0] this.from = Object.keys(this.entityType)[0]
}, },
setup () { setup () {
const dateRangeValue = 60
const { startTime, endTime } = getNowTime(dateRangeValue)
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
return { return {
chartTimeFilter,
entityType // 所有entity类型用于header下拉框选择 entityType // 所有entity类型用于header下拉框选择
} }
}, },
@@ -230,6 +294,77 @@ export default {
window.location.reload() window.location.reload()
}) })
}, },
initDropdownList (currentValue) {
const columnName = this.$store.getters.getBreadcrumbColumnName
let type = 'ip'
const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
if (tabObjGroup && tabObjGroup.length > 0) {
const curTab = tabObjGroup[0]
if (curTab) {
type = curTab.prop
}
}
const params = {
startTime: getSecond(this.chartTimeFilter.startTime),
endTime: getSecond(this.chartTimeFilter.endTime),
limit: 10 * this.curPageNum++,
type: type,
name: this.dropDownValue ? this.dropDownValue : ''
}
get(networkOverviewSearchUrl.drilldownList, params).then(response => {
if (response.code === 200) {
this.breadcrumbColumnValueListShow = response.data.result
this.$nextTick(() => {
setTimeout(() => {
this.breadcrumbColumnValueListShow.forEach(item => {
const selectedDom = document.getElementById(item)
if (selectedDom) {
if (item === currentValue) {
selectedDom.style.cssText = 'color:#0091ff;font-weight: bold;'
} else {
selectedDom.style.cssText = ''
}
}
})
}, 250)
})
}
})
},
showBreadcrumbPopover (valueMenuId) {
this.curPageNum = 1
this.showBackground = true
this.dropDownValue = ''
const currentValue = document.getElementById('breadcrumbValue').innerText
this.initDropdownList(currentValue)
this.valueMenuId = 'breadcrumb' + valueMenuId
},
hideBreadcrumbPopover () {
this.showBackground = false
},
changeValue (value) {
// 设置面包屑显示的内容及hover时的title
document.getElementById('breadcrumbValue').innerText = value
document.getElementById('breadcrumbButton').setAttribute('title', value)
document.getElementById(this.valueMenuId).setAttribute('title', value)
this.$refs.breadcrumbPopover.hide()
const columnName = this.$store.getters.getBreadcrumbColumnName
const tabObjGroup = networkOverviewTabList.filter(item => item.label == columnName)
if (tabObjGroup && tabObjGroup.length > 0) {
const curTab = tabObjGroup[0]
if (curTab) {
const queryCondition = []
const searchProps = curTab.dillDownProp
searchProps.forEach(item => {
queryCondition.push(item + "='" + value + "'")
})
this.$store.commit('setQueryCondition', queryCondition.join(' OR '))
}
}
this.jump(this.path, columnName, value, operationType.fourthMenu)
},
shrink () { shrink () {
this.showMenu = !this.showMenu this.showMenu = !this.showMenu
}, },
@@ -249,7 +384,53 @@ export default {
} }
}) })
}, },
jump (route) { jump (route, columnName, columnValue, opeType) {
if (opeType) {
this.$store.commit('setTabOperationBeforeType', this.$store.getters.getTabOperationType)
this.$store.commit('setTabOperationType', opeType)
} else {
this.$store.commit('setTabOperationType', operationType.mainMenu)
}
if (!columnName) { // 点击第二级菜单
this.$store.commit('setNetworkOverviewTabList', [])
}
// 清空网络概况的特殊面包屑
this.$store.getters.menuList.forEach(menu => {
if (!this.$_.isEmpty(menu.children)) {
menu.children.forEach(child => {
if (this.$route.path === child.route) {
if (columnValue) { // 点击的为值
child.columnValue = columnValue
child.columnName = columnName
this.$store.commit('setBreadcrumbColumnValue', columnValue)
this.$store.commit('setBreadcrumbColumnName', columnName)
this.$store.commit('setPanelName', columnValue)
} else if (columnName) { // 点击的为列名
child.columnValue = ''
child.columnName = columnName
this.$store.commit('setBreadcrumbColumnValue', '')
this.$store.commit('setBreadcrumbColumnName', columnName)
this.$store.commit('setPanelName', columnName)
const tabList = this.$store.getters.getNetworkOverviewTabList
const curTab = tabList.filter(item => this.$t(item.label) === columnName)[0]
this.$store.commit('setNetworkOverviewCurrentTab', curTab)
this.$store.commit('setQueryCondition', '')
this.$store.commit('setNetworkOverviewBeforeTab', null)
} else {
child.columnName = ''
child.columnValue = ''
this.$store.commit('setBreadcrumbColumnValue', '')
this.$store.commit('setBreadcrumbColumnName', '')
this.$store.commit('setPanelName', '')
this.$store.commit('setBreadcrumbColumnValueList', [])
this.$store.commit('setNetworkOverviewCurrentTab', null)
this.$store.commit('setQueryCondition', '')
this.$store.commit('setNetworkOverviewBeforeTab', null)
}
}
})
}
})
if (route === this.route) { if (route === this.route) {
this.refresh() this.refresh()
return return
@@ -262,8 +443,24 @@ export default {
}) })
this.showMenu = false this.showMenu = false
}, },
dropDownSearch () {
this.curPageNum = 1
this.initDropdownList()
},
refresh () { refresh () {
this.$emit('refresh') this.$emit('refresh')
},
refreshPanel (menu) {
if (this.breadcrumb.length >= 4) {
const breadList = this.breadcrumb.splice(3, this.breadcrumb.length - 3)
this.breadcrumb = ref(breadList)
}
},
scrollList () {
const obj = document.getElementById('breadcrumbSelectDropdown')
if (obj.scrollTop + obj.clientHeight === obj.scrollHeight) {
this.initDropdownList()
}
} }
} }
} }

View File

@@ -18,7 +18,37 @@ const panel = {
y: 0 y: 0
}, },
chartList: [], chartList: [],
currentMap: dnsServerRole.RTDNSM currentMap: dnsServerRole.RTDNSM,
/*
点击tab会修改networkOverviewCurrentTab
点击value
panelName、
breadcrumbColumnName、
breadcrumbColumnValue、
breadcrumbColumnValueList、
networkOverviewCurrentTab、
queryCondition
点击顶部第二级菜单:与点击菜单相同
点击顶部第三级菜单:
panelName、
breadcrumbColumnValue、
queryCondition
点击顶部第四级菜单切换value
panelName、
breadcrumbColumnValue、
queryCondition
*/
panelName: '', // 网络概况的Panel的名称
breadcrumbColumnName: '', // 点击tab里的value都会修改此值,为面包屑的菜单
breadcrumbColumnValue: '', // 点击tab里的value都会修改此值,为面包屑的菜单
breadcrumbColumnValueList: [], // 第四级面包屑的下拉列表
networkOverviewCurrentTab: null, // 只代表选中的tab有时会与面包屑中显示的值不同
networkOverviewBeforeTab: null, // 点击表格的值时使用记录点击当前tab表格的值之前点击的表格值所属的tab
queryCondition: '', // 数据查询的条件
networkOverviewTabList: [], // 存储tab列表的一些状态如是否选中
tabOperationType: 0, // 操作类型:2-二级菜单3-三级菜单4-四级菜单5-切换tab6-切换metric7-操作Customize
tabOperationBeforeType: 0// 记录上次的操作类型
}, },
mutations: { mutations: {
setShowRightBox (state, flag) { setShowRightBox (state, flag) {
@@ -68,6 +98,36 @@ const panel = {
}, },
setCurrentMap (state, currentMap) { setCurrentMap (state, currentMap) {
state.currentMap = currentMap state.currentMap = currentMap
},
setPanelName (state, panelName) {
state.panelName = panelName
},
setBreadcrumbColumnName (state, breadcrumbColumnName) {
state.breadcrumbColumnName = breadcrumbColumnName
},
setBreadcrumbColumnValue (state, breadcrumbColumnValue) {
state.breadcrumbColumnValue = breadcrumbColumnValue
},
setBreadcrumbColumnValueList (state, breadcrumbColumnValueList) {
state.breadcrumbColumnValueList = breadcrumbColumnValueList
},
setNetworkOverviewCurrentTab (state, networkOverviewCurrentTab) {
state.networkOverviewCurrentTab = networkOverviewCurrentTab
},
setQueryCondition (state, queryCondition) {
state.queryCondition = queryCondition
},
setNetworkOverviewTabList (state, networkOverviewTabList) {
state.networkOverviewTabList = networkOverviewTabList
},
setTabOperationType (state, tabOperationType) {
state.tabOperationType = tabOperationType
},
setNetworkOverviewBeforeTab (state, networkOverviewBeforeTab) {
state.networkOverviewBeforeTab = networkOverviewBeforeTab
},
setTabOperationBeforeType (state, tabOperationBeforeType) {
state.tabOperationBeforeType = tabOperationBeforeType
} }
}, },
getters: { getters: {
@@ -112,6 +172,36 @@ const panel = {
}, },
getCurrentMap (state) { getCurrentMap (state) {
return state.currentMap return state.currentMap
},
getPanelName (state) {
return state.panelName
},
getBreadcrumbColumnName (state) {
return state.breadcrumbColumnName
},
getBreadcrumbColumnValue (state) {
return state.breadcrumbColumnValue
},
getBreadcrumbColumnValueList (state) {
return state.breadcrumbColumnValueList
},
getNetworkOverviewCurrentTab (state) {
return state.networkOverviewCurrentTab
},
getQueryCondition (state) {
return state.queryCondition
},
getNetworkOverviewTabList (state) {
return state.networkOverviewTabList
},
getTabOperationType (state) {
return state.tabOperationType
},
getNetworkOverviewBeforeTab (state) {
return state.networkOverviewBeforeTab
},
getTabOperationBeforeType (state) {
return state.tabOperationBeforeType
} }
}, },
actions: { actions: {

View File

@@ -174,6 +174,192 @@ export const networkOverviewTabs = [
'network.protocolPorts' 'network.protocolPorts'
] ]
export const operationType = {
mainMenu: 0, // 菜单
secondMenu: 1, // 二级菜单
thirdMenu: 3, // 三级菜单
fourthMenu: 4, // 四级菜单
changeTab: 5, // 切换tab
changeMetric: 6, // 切换metric
customize: 7// 操作Customize
}
export const networkOverviewTableUrlName = {
ips: 'ips',
countries: 'countries',
asns: 'asns',
applications: 'applications',
providers: 'providers',
domains: 'domains',
protocols: 'protocols',
idcTenants: 'idcTenants',
provinces: 'provinces',
cities: 'cities',
isps: 'isps',
applicationCategories: 'applicationCategories',
domainCategories: 'domainCategories',
hosts: 'hosts',
snis: 'snis',
protocolPorts: 'protocolPorts'
}
export const networkOverviewSearchUrl = {
curUrl: '/interface/overview/dimensionTrafficAnalysis',
cycleUrl: '/interface/overview/dimensionCycleTrafficAnalysis',
drilldownCurUrl: '/interface/overview/drilldown/dimensionTrafficAnalysis',
drilldownCycleUrl: '/interface/overview/drilldown/dimensionCycleTrafficAnalysis',
drilldownList: '/interface/overview/drilldown/list'
}
export const networkOverviewTabList = [
{
label: 'network.ips',
prop: 'ip',
queryCycleTotalProp: 'ips',
dillDownProp: ['common_client_ip', 'common_server_ip'],
checked: true,
url: '/interface/overview/ipsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/ipsCycleTrafficTotal',
disabled: false
}, {
label: 'network.countries',
prop: 'country',
queryCycleTotalProp: 'countries',
dillDownProp: ['client_country', 'server_country'],
checked: true,
url: '/interface/overview/countriesTrafficAnalysis',
cycleTotalUrl: '/interface/overview/countriesCycleTrafficTotal',
disabled: false
}, {
label: 'network.asns',
prop: 'asn',
queryCycleTotalProp: 'asns',
dillDownProp: ['client_asn', 'server_asn'],
checked: true,
url: '/interface/overview/asnsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/asnsCycleTrafficTotal',
disabled: false
}, {
label: 'network.applications',
prop: 'appLabel',
queryCycleTotalProp: 'applications',
dillDownProp: ['common_app_label'],
checked: true,
url: '/interface/overview/applicationsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/applicationsCycleTrafficTotal',
disabled: false
}, {
label: 'network.providers',
prop: 'appCompany',
queryCycleTotalProp: 'providers',
dillDownProp: ['app_company'],
checked: true,
url: '/interface/overview/providersTrafficAnalysis',
cycleTotalUrl: '/interface/overview/providersCycleTrafficTotal',
disabled: false
}, {
label: 'network.domains',
prop: 'domain',
queryCycleTotalProp: 'domains',
dillDownProp: ['domain'],
checked: true,
url: '/interface/overview/domainsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/domainsCycleTrafficTotal',
disabled: false
}, {
label: 'network.protocols',
prop: 'l7Protocol',
queryCycleTotalProp: 'protocols',
dillDownProp: ['common_l7_protocol'],
checked: true,
url: '/interface/overview/protocolsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/protocolsCycleTrafficTotal',
disabled: false
}, {
label: 'network.idcTenants',
prop: 'idcRenter',
queryCycleTotalProp: 'idcTenants',
dillDownProp: ['client_idc_renter', 'server_idc_renter'],
checked: true,
url: '/interface/overview/idcTenantsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/idcTenantsCycleTrafficTotal',
disabled: false
}, {
label: 'network.provinces',
prop: 'province',
queryCycleTotalProp: 'provinces',
dillDownProp: ['client_province', 'server_province'],
checked: false,
url: '/interface/overview/provincesTrafficAnalysis',
cycleTotalUrl: '/interface/overview/provincesCycleTrafficTotal',
disabled: false
}, {
label: 'network.cities',
prop: 'city',
queryCycleTotalProp: 'cities',
dillDownProp: ['client_region', 'server_region'],
checked: false,
url: '/interface/overview/citiesTrafficAnalysis',
cycleTotalUrl: '/interface/overview/citiesCycleTrafficTotal',
disabled: false
}, {
label: 'network.isps',
prop: 'isp',
queryCycleTotalProp: 'isps',
dillDownProp: ['client_isp', 'server_isp'],
checked: false,
url: '/interface/overview/ispsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/ispsCycleTrafficTotal',
disabled: false
}, {
label: 'network.applicationCategories',
prop: 'appSubcategory',
queryCycleTotalProp: 'applicationCategories',
dillDownProp: ['app_subcategory'],
checked: false,
url: '/interface/overview/applicationCategoriesTrafficAnalysis',
cycleTotalUrl: '/interface/overview/applicationCategoriesCycleTrafficTotal',
disabled: false
}, {
label: 'network.domainCategories',
prop: 'domainCategoryName',
queryCycleTotalProp: 'domainCategories',
dillDownProp: ['domain_category_name'],
checked: false,
url: '/interface/overview/domainCategoriesTrafficAnalysis',
cycleTotalUrl: '/interface/overview/domainCategoriesCycleTrafficTotal',
disabled: false
}, {
label: 'network.hosts',
prop: 'httpHost',
queryCycleTotalProp: 'hosts',
dillDownProp: ['http_host'],
checked: false,
url: '/interface/overview/hostsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/hostsCycleTrafficTotal',
disabled: false
}, {
label: 'network.snis',
prop: 'sslSni',
queryCycleTotalProp: 'snis',
dillDownProp: ['ssl_sni'],
checked: false,
url: '/interface/overview/snisTrafficAnalysis',
cycleTotalUrl: '/interface/overview/snisCycleTrafficTotal',
disabled: false
}, {
label: 'network.protocolPorts',
prop: 'protocolPort',
queryCycleTotalProp: 'protocolports',
dillDownProp: ['common_l7_protocol', 'common_server_port '],
checked: false,
url: '/interface/overview/protocolPortsTrafficAnalysis',
cycleTotalUrl: '/interface/overview/protocolPortsCycleTrafficTotal',
disabled: false
}
]
export const dnsServerRole = { export const dnsServerRole = {
RTDNS: 'RTDNS', RTDNS: 'RTDNS',
TLDNS: 'TLDNS', TLDNS: 'TLDNS',

View File

@@ -6,6 +6,7 @@
v-if="chart.type === typeMapping.networkOverview.line" v-if="chart.type === typeMapping.networkOverview.line"
:chart="chart" :chart="chart"
:time-filter="timeFilter" :time-filter="timeFilter"
ref="networkLine"
></network-overview-line> ></network-overview-line>
<network-overview-ddos-detection <network-overview-ddos-detection
v-else-if="chart.type === typeMapping.networkOverview.ddosDetection" v-else-if="chart.type === typeMapping.networkOverview.ddosDetection"
@@ -17,9 +18,12 @@
:chart="chart" :chart="chart"
:time-filter="timeFilter" :time-filter="timeFilter"
></network-overview-performance-event> ></network-overview-performance-event>
<network-overview-tabs <network-overview-tabs @getChartData="getChartData"
v-else-if="chart.type === typeMapping.networkOverview.table" v-else-if="chart.type === typeMapping.networkOverview.table"
:time-filter="timeFilter" :time-filter="timeFilter"
:chart="chart"
:chartData="chartData"
:ref="`tab${chart.id}`"
></network-overview-tabs> ></network-overview-tabs>
<network-overview-apps <network-overview-apps
v-else-if="chart.type === typeMapping.networkOverview.appList" v-else-if="chart.type === typeMapping.networkOverview.appList"
@@ -87,6 +91,9 @@ import NpmLine from '@/views/charts2/charts/NpmLine'
import NpmEventsByType from '@/views/charts2/charts/NpmEventsByType' import NpmEventsByType from '@/views/charts2/charts/NpmEventsByType'
import NpmRecentEvents from '@/views/charts2/charts/NpmRecentEvents' import NpmRecentEvents from '@/views/charts2/charts/NpmRecentEvents'
import NpmEventsHeader from '@/views/charts2/charts/NpmEventsHeader' import NpmEventsHeader from '@/views/charts2/charts/NpmEventsHeader'
import { get } from '@/utils/http'
import { getNowTime, getSecond } from '@/utils/date-util'
import { ref } from 'vue'
export default { export default {
name: 'Chart', name: 'Chart',
components: { components: {
@@ -115,12 +122,91 @@ export default {
return { return {
typeMapping, typeMapping,
loading: false, loading: false,
isNoData: false isNoData: false,
chartData: null,
queryParams: {}
}
},
mounted () {
this.getChartData()
},
setup (props) {
const dateRangeValue = 60
const { startTime, endTime } = getNowTime(dateRangeValue)
const chartTimeFilter = ref({ startTime, endTime, dateRangeValue })
const table = ref({})
return {
table,
chartTimeFilter
} }
}, },
methods: { methods: {
npmTabChange (index) { npmTabChange (index) {
this.$emit('npmTabChange', index) this.$emit('npmTabChange', index)
},
reload () {
this.getChartData()
},
/* 参数 extraParams 额外请求参数 */
getChartData (url, extraParams = {}, chartTimeFilter) {
try {
if (chartTimeFilter) {
// 图表自带timeFilter刷新时
this.queryTimeRange = {
startTime: getSecond(chartTimeFilter.startTime),
endTime: getSecond(chartTimeFilter.endTime)
}
} else if (this.timeFilter) {
this.queryTimeRange = {
startTime: getSecond(this.timeFilter.startTime),
endTime: getSecond(this.timeFilter.endTime)
}
} else {
this.queryTimeRange = {
startTime: getSecond(this.chartTimeFilter.startTime),
endTime: getSecond(this.chartTimeFilter.endTime)
}
}
const chartParams = this.chart.params
// 接口查询参数
this.queryParams = {
...this.queryTimeRange,
...extraParams
}
let requestUrl = url
if (this.chart.type === 601) {
const chartObj = this.$refs['tab' + this.chart.id]
requestUrl = url || chartObj.getCurUrl()
this.queryParams = {
...chartObj.handleQueryParams(extraParams),
...this.queryTimeRange
}
}
if (requestUrl) {
get(requestUrl, this.queryParams).then(response => {
if (response.code === 200) {
this.chartData = response.data.result
} else {
if (this.chart.type === 601) {
this.$refs['tab' + this.chart.id].loading = false
}
}
})
}
} catch (e) {
console.error(e)
}
},
resizeLine () {
this.$nextTick(function () {
setTimeout(() => {
console.log(this.$refs)
if (this.$refs.networkLine) {
this.$refs.networkLine.resize()
}
}, 250)
})
} }
} }
} }

View File

@@ -23,6 +23,7 @@
:time-filter="timeFilter" :time-filter="timeFilter"
:extra-params="extraParams" :extra-params="extraParams"
:id="item.id" :id="item.id"
ref="chartGrid"
@npmTabChange="npmTabChange" @npmTabChange="npmTabChange"
:chart="item" :chart="item"
></chart> ></chart>
@@ -35,7 +36,7 @@
import VueGridLayout from 'vue-grid-layout' import VueGridLayout from 'vue-grid-layout'
import _ from 'lodash' import _ from 'lodash'
import Chart from '@/views/charts2/Chart' import Chart from '@/views/charts2/Chart'
import {panelTypeAndRouteMapping, storageKey} from '@/utils/constants' import { panelTypeAndRouteMapping, storageKey } from '@/utils/constants'
import { typeMapping } from '@/views/charts2/chart-tools' import { typeMapping } from '@/views/charts2/chart-tools'
export default { export default {
name: 'ChartList', name: 'ChartList',
@@ -90,6 +91,10 @@ export default {
methods: { methods: {
npmTabChange (index) { npmTabChange (index) {
this.npmTabIndex = parseInt(index) this.npmTabIndex = parseInt(index)
},
resizeLine () {
console.log(this.$refs)
this.$refs.chartGrid.resizeLine()
} }
} }
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="panel-box"> <div class="panel-box">
<div class="panel__header"> <div class="panel__header">
<div class="panel__title">{{panel.i18n ? $t(panel.i18n) : panel.name}}</div> <div class="panel__title">{{panelName?panelName:(panel.i18n ? $t(panel.i18n) : panel.name)}}</div>
<div class="panel__time"> <div class="panel__time">
<date-time-range <date-time-range
class="date-time-range" class="date-time-range"
@@ -38,7 +38,6 @@ import { getPanelList, getChartList } from '@/utils/api'
import { getNowTime } from '@/utils/date-util' import { getNowTime } from '@/utils/date-util'
import { getTypeCategory } from '@/views/charts/charts/tools' import { getTypeCategory } from '@/views/charts/charts/tools'
import ChartList from '@/views/charts2/ChartList' import ChartList from '@/views/charts2/ChartList'
import { typeMapping } from '@/views/charts2/chart-tools'
export default { export default {
name: 'Panel', name: 'Panel',
@@ -53,10 +52,12 @@ export default {
return { return {
chartList: [], // 普通panel的chart chartList: [], // 普通panel的chart
panelLock: true, panelLock: true,
extraParams: {} extraParams: {},
panelName: ''
} }
}, },
async mounted () { async mounted () {
this.panelName = this.$store.getters.getPanelName
await this.init() await this.init()
const vm = this const vm = this
this.emitter.on('reloadChartList', async function () { this.emitter.on('reloadChartList', async function () {
@@ -107,6 +108,16 @@ export default {
this.initChartAttr(chart) this.initChartAttr(chart)
return chart return chart
}) })
if (this.$store.getters.getBreadcrumbColumnName || this.$store.getters.getBreadcrumbColumnValue) { // networkOverview页面
const list = this.chartList.filter(item => {
return (item.type === 102 || item.type === 601)
})
list.forEach(item => {
item.w = 24
})
this.chartList = ref(list)
}
} }
}, },
initChartAttr (chart) { initChartAttr (chart) {

File diff suppressed because it is too large Load Diff