NEZ-1592 feat:asset等列表页面增加 最近告警趋势 图表(70%)

This commit is contained in:
zhangyu
2022-02-24 13:43:20 +08:00
parent 4639a1d359
commit 0c6dab781d
11 changed files with 301 additions and 7 deletions

View File

@@ -3,3 +3,4 @@
@import './tableCommon.scss'; @import './tableCommon.scss';
@import './rightBoxCommon.scss'; @import './rightBoxCommon.scss';
@import './tooltip.scss'; @import './tooltip.scss';
@import './loading.scss';

View File

@@ -0,0 +1,78 @@
// https://github.com/loadingio/css-spinner/tree/master/dist 从当前链接现在在 在tools.js 的myLoading 进行判断处理
// 高度 宽度 等细节 记得处理
// 1
.lds-dual-ring,
.lds-dual-ring:after {
box-sizing: border-box;
}
.lds-dual-ring {
display: inline-block;
width: 80px;
height: 80px;
}
.lds-dual-ring:after {
content: " ";
display: block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
border: 6.4px solid currentColor;
border-color: currentColor transparent currentColor transparent;
animation: lds-dual-ring 1.2s linear infinite;
}
@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
// 2
.ldsFacebook,
.ldsFacebook div {
box-sizing: border-box;
}
.ldsFacebook {
display: inline-block;
position: relative;
width: 40px;
height: 32px;
}
.ldsFacebook div {
display: inline-block;
position: absolute;
left: 8px;
width: 8px;
background: $--background-color-empty;
animation: ldsFacebook 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
}
.ldsFacebook div:nth-child(1) {
left: 8px;
background: $--background-color-empty;
filter: invert(50%);
animation-delay: -0.24s;
}
.ldsFacebook div:nth-child(2) {
left: 20px;
background: $--background-color-empty;
filter: invert(50%);
animation-delay: -0.12s;
}
.ldsFacebook div:nth-child(3) {
left: 32px;
background: $--background-color-empty;
filter: invert(50%);
animation-delay: 0s;
}
@keyframes ldsFacebook {
0% {
top: 8px;
height: 32px;
}
50%, 100% {
top: 12px;
height: 16px;
}
}

View File

@@ -0,0 +1,13 @@
.alert-days-info{
display: flex;
height: 100%;
width: 100%;
> div{
width: 14px;
height: 24px;
margin-right: 5px;
border-radius: 2px;
background-color:$--color-success;
cursor: pointer;
}
}

View File

@@ -5,6 +5,7 @@
@import './common/alert/alertLabel.scss'; @import './common/alert/alertLabel.scss';
@import './common/alert/alertRuleInfo.scss'; @import './common/alert/alertRuleInfo.scss';
@import './common/alert/selectAlertSilence.scss'; @import './common/alert/selectAlertSilence.scss';
@import './common/alert/alertDaysInfo.scss';
@import './common/bottomBox/bottomBox.scss'; @import './common/bottomBox/bottomBox.scss';
@import './common/bottomBox/panelTabNew.scss'; @import './common/bottomBox/panelTabNew.scss';
@import './common/bottomBox/terminalLogCMDTab.scss'; @import './common/bottomBox/terminalLogCMDTab.scss';

View File

@@ -0,0 +1,75 @@
<template>
<div class="alert-days-info">
<!-- {{timestampStr(item.time, 'YYYY-MM-DD')}} {{item.P1+' '+item.P2+' '+item.P3}}-->
<div v-for="item in daysData" :key="item.time" :style="showPriority(item)">
</div>
</div>
</template>
<script>
export default {
name: 'alertDaysInfo',
props: {
alertDaysData: Array
},
data () {
return {
daysData: [],
severityData: this.$store.getters.severityData,
severityDataWeight: this.$store.getters.severityDataWeight
}
},
watch: {
alertDaysData: {
immediate: true,
handler () {
this.getWeeksTime()
}
}
},
methods: {
getWeeksTime () {
const localOffset = new Date().getTimezoneOffset() // 默认 显示时区偏移的结果 单位分钟
const now = new Date(new Date().toLocaleDateString()).getTime() - localOffset * 60 * 1000
const arr = []
for (let i = 0; i < 7; i++) {
const obj = {
time: now - i * 24 * 60 * 60 * 1000
}
this.severityDataWeight.forEach(item => {
obj[item.name] = 0
})
console.log(obj)
arr.unshift(obj)
}
this.alertDaysData.forEach(item => {
item.values.forEach(time => {
const findItem = arr.find(days => days.time == time[0])
// console.log(item)
if (findItem) {
findItem[item.metric.priority] = time[1]
}
})
})
this.daysData = arr
},
showPriority (daysData) {
let style = ''
this.severityDataWeight.forEach(item => {
if (daysData[item.name] && !style) {
style = {
background: item.color
}
}
})
console.log(daysData,style)
return style
}
}
}
</script>
<style scoped>
</style>

View File

@@ -98,6 +98,61 @@ function isEqual (o1, o2) {
} }
return isEqualForInner(o1, o2) return isEqualForInner(o1, o2)
} }
export const myLoading = {
bind: myLoadingFunction,
update: myLoadingFunction,
unbind: function (el, binding) {
const className = binding.arg || 'el-loading-mask'
const ds = el.getElementsByClassName(className)[0]
if (ds) {
el.removeChild(ds)
}
}
}
function myLoadingFunction (el, binding, vnode) {
const className = binding.arg || 'el-loading-mask'
const ds = el.getElementsByClassName(className)[0]
if (binding.value) {
if (ds) {
return
}
// 若果是true创建一个div
const div = document.createElement('div')
div.style.textAlign = 'center'
if (binding.modifiers.scaleMin) {
div.style.transform = 'scale(0.5)'
}
if (binding.modifiers.scaleMax) {
div.style.transform = 'scale(2)'
}
if (className === 'ldsFacebook') {
const newDiv1 = document.createElement('div')
const newDiv2 = document.createElement('div')
const newDiv3 = document.createElement('div')
div.appendChild(newDiv1)
div.appendChild(newDiv2)
div.appendChild(newDiv3)
}
if (className === 'el-loading-mask') {
const newDiv1 = document.createElement('div')
newDiv1.setAttribute('class', 'el-loading-spinner')
div.appendChild(newDiv1)
}
// 插入到被绑定的元素内部
el.appendChild(div)
// div内部加入内容
// div.innerHTML = '加载中...'
// el 元素设置相对定位 div设置绝对定位
el.setAttribute('class', 'elrelative')
// 设置绝对定位
div.setAttribute('class', className)
} else {
// 去掉div 去掉样式 去掉定位
if (ds) {
el.removeChild(ds)
}
}
}
export const cancelWithChange = { export const cancelWithChange = {
bind: function (el, binding) { bind: function (el, binding) {
if (!binding.value || !binding.value.obj) return if (!binding.value || !binding.value.obj) return

View File

@@ -43,7 +43,13 @@
<span style="cursor: pointer" @click="$emit('showBottomBox', 'endpointTab', scope.row)"><i class="nz-icon nz-icon-overview-endpoint monitorColor"></i> <span>{{scope.row.endpointNum ? scope.row.endpointNum : 0}}</span></span> <span style="cursor: pointer" @click="$emit('showBottomBox', 'endpointTab', scope.row)"><i class="nz-icon nz-icon-overview-endpoint monitorColor"></i> <span>{{scope.row.endpointNum ? scope.row.endpointNum : 0}}</span></span>
</template> </template>
<template v-else-if="item.prop === 'alertNum'"> <template v-else-if="item.prop === 'alertNum'">
<span style="cursor: pointer" @click="$emit('showBottomBox', 'alertMessageTab', scope.row)"><i :class="scope.row.alertNum ? 'red' : 'green'" class="nz-icon nz-icon-overview-alert"></i> <span>{{scope.row.alertNum ? scope.row.alertNum : 0}}</span></span> <span style="cursor: pointer" @click="$emit('showBottomBox', 'alertMessageTab', scope.row)" v-myLoading:ldsFacebook="scope.row.trendLoading">
<!-- <i :class="scope.row.alertNum ? 'red' : 'green'" class="nz-icon nz-icon-overview-alert"></i> <span>{{scope.row.alertNum ? scope.row.alertNum : 0}}</span>-->
<alertDaysInfo
v-if="scope.row.alertDaysData"
:alertDaysData="scope.row.alertDaysData"
/>
</span>
</template> </template>
<template v-else-if="item.prop === 'dc'">{{scope.row.dc ? scope.row.dc.name : '-'}}</template> <template v-else-if="item.prop === 'dc'">{{scope.row.dc ? scope.row.dc.name : '-'}}</template>
<template v-else-if="item.prop === 'cabinet'"> <template v-else-if="item.prop === 'cabinet'">
@@ -154,11 +160,13 @@ import table from '@/components/common/mixin/table'
import { showTableTooltip, hideTableTooltip } from '@/components/common/js/tools' import { showTableTooltip, hideTableTooltip } from '@/components/common/js/tools'
// import bus from '@/libs/bus' // import bus from '@/libs/bus'
import alertLabel from '@/components/common/alert/alertLabel' import alertLabel from '@/components/common/alert/alertLabel'
import alertDaysInfo from '@/components/common/alert/alertDaysInfo'
export default { export default {
name: 'assetTable', name: 'assetTable',
mixins: [table], mixins: [table],
components: { components: {
alertLabel: alertLabel alertLabel: alertLabel,
alertDaysInfo
}, },
props: { props: {
showOption: { showOption: {

View File

@@ -432,7 +432,9 @@ export default {
index: -1 index: -1
} }
}, },
timer: '' timer: '',
needAlertDaysData: true,
trendKey: 'assetId'
} }
}, },
methods: { methods: {
@@ -713,6 +715,27 @@ export default {
for (let i = 0; i < response.data.list.length; i++) { for (let i = 0; i < response.data.list.length; i++) {
response.data.list[i].status = response.data.list[i].status + '' response.data.list[i].status = response.data.list[i].status + ''
} }
if (this.needAlertDaysData) {
console.log(123123123123)
const arr = []
response.data.list.forEach(item => {
item.trendLoading = true
const params = {
type: 'total',
dimension: 'priority',
step: 'd'
}
params[this.trendKey] = item.id
arr.push(this.$get('/stat/alertMessage/trend', params))
})
Promise.all(arr).then(res => {
response.data.list.forEach((item, index) => {
item.trendLoading = false
item.alertDaysData = res[index].data.result ? res[index].data.result[0].values : []
})
this.tableData = response.data.list
})
}
this.tableData = response.data.list this.tableData = response.data.list
const globalSearchId = this.$store.getters.getGlobalSearchId const globalSearchId = this.$store.getters.getGlobalSearchId
let detailViewRightObj = '' let detailViewRightObj = ''

View File

@@ -19,7 +19,7 @@ import plTable from 'pl-table'
import 'pl-table/themes/index.css' import 'pl-table/themes/index.css'
import { post, get, put, del } from './http.js' import { post, get, put, del } from './http.js'
import { clickoutside, bottomBoxWindow, stringTimeParseToUnix, unixTimeParseToString, chartResizeTool, tableSet, cancelWithChange } from './components/common/js/tools.js' import { clickoutside, bottomBoxWindow, stringTimeParseToUnix, unixTimeParseToString, chartResizeTool, tableSet, cancelWithChange, myLoading } from './components/common/js/tools.js'
import * as tools from './components/common/js/tools.js' import * as tools from './components/common/js/tools.js'
import * as constants from './components/common/js/constants.js' import * as constants from './components/common/js/constants.js'
@@ -122,12 +122,15 @@ Vue.mixin({
return bus.timeFormate(this.timezoneToUtcTime(time), fmt) return bus.timeFormate(this.timezoneToUtcTime(time), fmt)
} }
}, },
timestampStr: function (time) { timestampStr: function (time, fmt) {
const date = new Date(time) const date = new Date(time)
const localOffset = date.getTimezoneOffset() * 60 * 1000 // 默认 一分钟显示时区偏移的结果 const localOffset = date.getTimezoneOffset() * 60 * 1000 // 默认 一分钟显示时区偏移的结果
const dateStr = new Date(time).getTime() + localOffset const dateStr = new Date(time).getTime() + localOffset
if (!fmt) {
fmt = localStorage.getItem('nz-default-dateFormat') || 'YYYY-MM-DD HH:mm:ss'
}
if (time) { if (time) {
return bus.timeFormate(bus.UTCTimeToConfigTimezone(dateStr), localStorage.getItem('nz-default-dateFormat') ? localStorage.getItem('nz-default-dateFormat') : 'YYYY-MM-DD HH:mm:ss') return bus.timeFormate(bus.UTCTimeToConfigTimezone(dateStr), fmt)
} else { } else {
return '-' return '-'
} }
@@ -238,6 +241,7 @@ Vue.use(hasPermission)
/* 指令 */ /* 指令 */
Vue.directive('cancel', cancelWithChange) Vue.directive('cancel', cancelWithChange)
Vue.directive('clickoutside', clickoutside) Vue.directive('clickoutside', clickoutside)
Vue.directive('myLoading', myLoading)
window.resizing = false window.resizing = false
window.vm = new Vue({ window.vm = new Vue({
el: '#app', el: '#app',

View File

@@ -144,6 +144,13 @@ router.beforeEach((to, from, next) => {
resolve() resolve()
} }
}) })
Vue.http.get(configUrl).then(config => {
get(config.body.baseUrl + 'alert/severity', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code == 200) {
store.commit('setSeverityData', response.data.list)
}
})
})
Promise.all([i18nRequest, permissionRequest]).then(response => { Promise.all([i18nRequest, permissionRequest]).then(response => {
if (to.path) { if (to.path) {
if (permissionWhiteList.indexOf(to.path) !== -1) { if (permissionWhiteList.indexOf(to.path) !== -1) {

View File

@@ -10,7 +10,9 @@ const user = {
menuList: [], menuList: [],
buttonList: [], buttonList: [],
roleList: [], roleList: [],
language: localStorage.getItem('nz-language') language: localStorage.getItem('nz-language'),
severityData: [],
severityDataWeight: []
}, },
mutations: { mutations: {
setLanguage (state, language) { setLanguage (state, language) {
@@ -25,6 +27,22 @@ const user = {
setRoleList (state, roleList) { setRoleList (state, roleList) {
state.roleList = [...roleList] state.roleList = [...roleList]
}, },
setSeverityData (state, severityData) {
state.severityData = [...severityData]
console.log(severityData)
const arr = JSON.parse(JSON.stringify(severityData.reverse()))
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length; j++) {
if (arr[i].weight < arr[j].weight) {
const temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
state.severityDataWeight = arr
console.log(arr)
},
clean (state) { clean (state) {
state.menuList = [] state.menuList = []
state.buttonList = [] state.buttonList = []
@@ -43,6 +61,12 @@ const user = {
}, },
roleList (state) { roleList (state) {
return state.roleList return state.roleList
},
severityData (state) {
return state.severityData
},
severityDataWeight (state) {
return state.severityDataWeight
} }
}, },
actions: { actions: {
@@ -126,6 +150,11 @@ const user = {
localStorage.setItem('nz-user-name', user.name) localStorage.setItem('nz-user-name', user.name)
} }
}) })
get('alert/severity', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code == 200) {
store.commit('setSeverityData', response.data.list)
}
})
}, },
logoutSuccess (store, res) { logoutSuccess (store, res) {
localStorage.removeItem('nz-username') localStorage.removeItem('nz-username')