NEZ-1592 feat:asset等列表页面增加 最近告警趋势 图表(70%)
This commit is contained in:
@@ -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';
|
||||||
|
|||||||
78
nezha-fronted/src/assets/css/common/loading.scss
Normal file
78
nezha-fronted/src/assets/css/common/loading.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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';
|
||||||
|
|||||||
75
nezha-fronted/src/components/common/alert/alertDaysInfo.vue
Normal file
75
nezha-fronted/src/components/common/alert/alertDaysInfo.vue
Normal 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>
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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: {
|
||||||
|
|||||||
@@ -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 = ''
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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')
|
||||||
|
|||||||
Reference in New Issue
Block a user