feat:告警信息页面添加时间过滤&修复导出bug

This commit is contained in:
wangwenrui
2020-10-12 18:15:24 +08:00
parent 5fdcd89e2d
commit 76f47b76be
9 changed files with 102 additions and 180 deletions

View File

@@ -13,6 +13,7 @@
<div v-if="from == 'endpoint'" class="sub-list-tab" @click="changeTab('endpointQuery')">{{$t("overall.query")}}</div>
</div>
<div class="top-tool-right">
<pick-time :refresh-data-func="getAlertList" v-model="searchTime" :use-chart-unit="false" :use-refresh="false" :default-pick="defaultPick" :show-empty="true"></pick-time>
<div class="top-tool-search">
<search-input :default-item="'alertMessageState'" :default-value="defaultSearchValue" :searchMsg="searchMsg" @search="search"></search-input>
</div>
@@ -102,7 +103,7 @@
chartDatas: [],
legend: [],
sameLabels: ['instance','module','project','asset','endpoint','datacenter'],
searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()],
searchTime:[],
currentMsg: {},
chartUnit: 5,
requestIndex:0,
@@ -226,6 +227,7 @@
tablelable: [],
dropCol: [],
tableData: [],
defaultPick:12,
}
},
computed: {
@@ -294,7 +296,6 @@
this.$emit('changeTab', tab);
},
deleteMessage(deleteBox,cb) {
console.log(deleteBox)
this.$put("alert/message", deleteBox).then(res => {
if (res.code === 200) {
this.$message({duration: 2000, type: 'success', message: this.$t("tip.deleteSuccess")});
@@ -470,6 +471,14 @@
this.loading = true;
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
if(this.searchTime&& this.searchTime.length>1){
this.$set(this.searchLabel, "startAt", bus.timeFormate(this.searchTime[0], 'yyyy-MM-dd hh:mm:ss'));
this.$set(this.searchLabel, "endAt", bus.timeFormate(this.searchTime[1], 'yyyy-MM-dd hh:mm:ss'));
}else{
delete this.searchLabel.startAt
delete this.searchLabel.endAt
}
setTimeout(() => {
this.$get('alert/message', this.searchLabel).then(response => {
if (response.code == 200) {
@@ -584,6 +593,11 @@
immediate: true,
deep: true,
handler(n) {
if(n.alertNum==0){
this.defaultPick=8
}else{
this.defaultPick=12;
}
if (this.from == "alertRule") {
this.searchMsg.searchLabelList = this.searchMsg.searchLabelList.filter((item, index) => {
return item.label != "alertName" && item.label != "severity"

View File

@@ -104,7 +104,6 @@
params:{type:Object},
exportFileName:{type:String},
importUrl: {type:String,required:true},
link:{type:Object},
},
data:function(){
return {
@@ -159,9 +158,6 @@
form.append('excelFile',this.importFile.raw);
if(this.paramsType){
form.append('type',this.paramsType);
if(this.paramsType==='asset' || this.paramsType==='model'){
form.append('linkId',this.link.id);
}
}
this.$post(this.importUrl,form,{'Content-Type': 'multipart/form-data'}).then(response=>{
if(response.code==200 && response.msg=='success'){

View File

@@ -208,6 +208,7 @@ const cn = {
curMonth: "本月",
lastMonth: "上月",
customTimeRange: "Custom time range",
noDate:'无',
lastFiveMin: "最近5分钟",
lastFifteenMin: "最近15分钟",
lastThirtyMin: "最近30分钟",

View File

@@ -214,6 +214,7 @@ const en = {
curMonth:'This month',//'本月'
lastMonth:'Last month',//'上月'
customTimeRange:'Custom time range',
noDate:'Empty',
lastFiveMin:'Last 5 minutes',
lastFifteenMin:'Last 15 minutes',
lastThirtyMin:'Last 30 minutes',

View File

@@ -1,6 +1,6 @@
<template>
<div class="interval-refresh ">
<time-picker v-if="showTimePicker" ref="timePicker" class="time-picker" @change="dateChange"></time-picker>
<time-picker v-if="showTimePicker" ref="timePicker" class="time-picker" @change="dateChange" :default-pick="defaultPick" :show-empty="showEmpty"></time-picker>
<chart-unit v-model="unit" v-if="useChartUnit"></chart-unit>
<div class="nz-btn-group nz-btn-group-size-normal nz-btn-group-light margin-r-20" v-show="useRefresh" style="height: 24px;line-height: 24px;vertical-align: middle;">
<button style="border-right: 1px solid rgba(162,162,162,0.50);" type="button" class="nz-btn nz-btn-size-normal nz-btn-style-light" @click="refreshDataFunc">
@@ -55,7 +55,9 @@
showTimePicker:{
type:Boolean,
default:true,
}
},
defaultPick:Number,
showEmpty:{type:Boolean,default:false}
},
data(){
return{
@@ -107,6 +109,9 @@
this.refreshDataFunc();
},
timeFormate(timeRange){
if(timeRange&&timeRange.length<2){
return []
}
const startTime = bus.timeFormate(timeRange[0], 'yyyy-MM-dd hh:mm:ss');
const endTime = bus.timeFormate(timeRange[1], 'yyyy-MM-dd hh:mm:ss');
return [startTime, endTime];

View File

@@ -17,6 +17,7 @@
<!-- begin搜素框-->
<div class="top-tools">
<div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': false}">
<pick-time :refresh-data-func="getAlertList" v-model="searchTime" :use-chart-unit="false" :use-refresh="false" :default-pick="12" :show-empty="true"></pick-time>
<div class="top-tool-search">
<search-input :searchMsg="searchMsg" @search="search" :bottomBox.inTransform="true"></search-input>
</div>
@@ -267,6 +268,7 @@
width: 150
},
],
searchTime: [],
searchMsg: { //给搜索框子组件传递的信息
zheze_none: true,
searchLabelList: [{
@@ -337,6 +339,13 @@
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
this.$set(this.searchLabel, "moduleId", this.moduleId);
if(this.searchTime&& this.searchTime.length>1){
this.$set(this.searchLabel, "startAt", bus.timeFormate(this.searchTime[0], 'yyyy-MM-dd hh:mm:ss'));
this.$set(this.searchLabel, "endAt", bus.timeFormate(this.searchTime[1], 'yyyy-MM-dd hh:mm:ss'));
}else{
delete this.searchLabel.startAt
delete this.searchLabel.endAt
}
this.$get('alert/message', {...this.searchLabel}).then(response => {
this.loading=false;
if (response.code == 200) {

View File

@@ -87,6 +87,7 @@
:disabled="isPopoverDisabled"
trigger="hover"
id="panel-calender-popover">
<template v-if="this.searchTime&&this.searchTime.length>1">
<el-row :gutter="10" class="calendar-popover">
<el-col :span="24" class="calendar-popover-text">{{searchTime[0]}}</el-col>
</el-row>
@@ -96,6 +97,10 @@
<el-row :gutter="10" class="calendar-popover">
<el-col :span="24" class="calendar-popover-text">{{searchTime[1]}}</el-col>
</el-row>
</template>
<template v-else>
<div style="text-align: center;width: 100%;color: #909399;font-family: NotoSans !important;font-size: 12px !important;">{{$t("dashboard.panel.noDate")}}</div>
</template>
<div class="el-dropdown-link" slot="reference">
<i class="nz-icon nz-icon-time" style="width:20px;"></i>
<span class="panel-list-title" id="timePickerContent">{{showTime.text}}</span>
@@ -104,10 +109,12 @@
</el-popover>
<el-dropdown-menu class="nz-dashboard-dropdown" slot="dropdown">
<!-- <el-dropdown-item >{{$t('dashboard.panel.customTimeRange')}}</el-dropdown-item> -->
<el-dropdown-item v-for="item in timeData" :key="item.id+1"
:class="showTime.id==item.id?'nz-dashboard-dropdown-bg':''" :command="item">
<template v-for="item in timeData" >
<el-dropdown-item :class="showTime.id==item.id?'nz-dashboard-dropdown-bg':''" :command="item" v-if="item.id != 12 || showEmpty">
{{item.text}}
</el-dropdown-item>
</template>
</el-dropdown-menu>
</el-dropdown>
<!--
@@ -124,6 +131,8 @@ import bus from '../../libs/bus';
export default {
name: "timePicker",
props: {
defaultPick:Number,
showEmpty:{default:false,type:Boolean}
},
data() {
return {
@@ -142,6 +151,11 @@ export default {
id:0,
text:this.$t("dashboard.panel.customTimeRange"),
},
{
id:12,
text:this.$t("dashboard.panel.noDate"),
},
{
id:1,
text:this.$t("dashboard.panel.lastFiveMin"),
@@ -269,7 +283,11 @@ export default {
this.$refs.calendar.focus();
}else {
this.isCustom = false;
if(this.showEmpty&& id === 12){
this.searchTime=[]
}
this.$emit('change', this.searchTime);
}
}
},
@@ -320,6 +338,24 @@ export default {
}
},
},
created() {
},
watch:{
defaultPick:{
immediate:true,
handler(n,o){
if(n&&Number.isInteger(n)){
let showTime=this.timeData.find(item=>item.id == n);
if(showTime){
this.showTime = Object.assign({},showTime);
}
if(this.showEmpty&& this.defaultPick === 12){
this.searchTime=[]
}
}
}
}
},
mounted: function () {
/*
if(this.isCustom){

View File

@@ -21,6 +21,7 @@
<div class="main-list main-and-sub-transition" :class="{'main-list-with-sub': bottomBox.showSubList}">
<div class="top-tools" v-show="bottomBox.mainResizeShow">
<div class="top-tool-main-right" :class="{'top-tool-main-right-to-left': bottomBox.showSubList}">
<pick-time :refresh-data-func="getAlertList" v-model="searchTime" :use-chart-unit="false" :use-refresh="false" :default-pick="12" :show-empty="true"></pick-time>
<div class="top-tool-search">
<search-input :searchMsg="searchMsg" @search="search" :bottomBox.inTransform="bottomBox.inTransform"></search-input>
</div>
@@ -96,6 +97,7 @@
import axios from 'axios';
import nzAlertTag from './nzAlertTag';
import chart from '../../page/dashboard/overview/chart'
import pickTime from "../../common/pickTime";
import chartDataFormat from "../../charts/chartDataFormat";
import alertRuleInfo from '../../common/alert/alertRuleInfo'
import alertLabel from '../../common/alert/alertLabel'
@@ -108,6 +110,7 @@
'alertRuleInfo':alertRuleInfo,
'alertLabel':alertLabel,
'alertMessageTable':alertMessageTable,
'pick-time':pickTime,
},
data() {
return {
@@ -143,7 +146,7 @@
chartDatas: [],
sameLabels: ['instance','module','project','asset','endpoint','datacenter'],
legend: [],
searchTime: [new Date().setHours(new Date().getHours() - 1), new Date()],
searchTime: [],
currentMsg: {},
chartUnit: 5,
@@ -325,161 +328,17 @@
})
return result;
},
chartUnitChange:function(unit){
this.chartUnit=unit;
this.$nextTick(()=>{
this.queryChartDate()
})
},
formatThreshold:function(value,unit){
let unitMethod=chartDataFormat.getUnit(unit)
if(unitMethod&&value){
return unitMethod.compute(value,null,2);
}else{
return value
}
},
queryChartDate() {
let $temp=this;
let start = this.searchTime[0]?this.searchTime[0]:this.getTime(-1, 'h');
let end = this.searchTime[1]?this.searchTime[1]:this.getTime(0, 'h')
this.searchTime = [start, end];
let timeDiff = (new Date(end).getTime()-new Date(start).getTime())/1000/(24*60*60);
let step = '15s';
if(timeDiff< 1){
step='15s';
}else if(timeDiff < 7){
step='5m';
}else if(timeDiff<30){
step='10m';
}else{
step='30m';
}
this.$refs.messageChart.startLoading();
let axiosArr=[];
let paramStr = JSON.stringify(this.promQueryParamConvert(this.currentMsg));
axiosArr.push(axios.get("/prom/api/v1/query_range?query="+paramStr.substring(1, paramStr.length-1).replace(/\+/g, "%2B").replace(/ /g, "%20").replace(/\\/g, "")+"&start="+this.$stringTimeParseToUnix(start)+"&end="+this.$stringTimeParseToUnix(end)+"&step="+step));
this.legend = [];
this.chartDatas = [];
axios.all(axiosArr).then(res =>{
try {
res.forEach((response, promIndex) => {
if (response.status == 200) {
if (response.data.status == 'success') {
let queryData = response.data.data.result[0];
if (queryData) {
let chartData = {
type: "line",
symbol: 'none', //去掉点
smooth: 0.2, //曲线变平滑
name: '',
lineStyle: {
width: 1,
opacity: 0.9
},
markLine: {
silent: true,
symbol: ['circle', 'circle'],
label: {
distance: this.computeDistance(chartDataFormat.getUnit(this.currentMsg.alertRule.unit ? this.currentMsg.alertRule.unit : 2).compute(this.currentMsg.alertRule.threshold)),
formatter: function (params) {
return chartDataFormat.getUnit($temp.currentMsg.alertRule.unit ? $temp.currentMsg.alertRule.unit : 2).compute(params.value)
}
},
lineStyle: {
color:'#d64f40',
width:2,
type:'dotted'
},
data: [{
yAxis: Number(this.currentMsg.alertRule.threshold)
}, ]
},
markArea:{
itemStyle:{
color:'#d64f40',
opacity:0.1
},
data:[this.returnMarkArea()]
}
};
if(this.currentMsg.alertRule.operator=='=='||this.currentMsg.alertRule.operator=='!='){
delete chartData.markArea;
}
chartData.name += "{";
alias += "{";
Object.keys(queryData.metric).forEach((item, index) => {
let label = item;
let value = queryData.metric[label];
chartData.name += label + "='" + value + "',";
});
chartData.name = chartData.name.charAt(chartData.name.length - 1) == "," ? chartData.name.substr(0, chartData.name.length - 1) : chartData.name;
chartData.name += "}";
let alias = chartData.name;
let legend = {
name: chartData.name,
alias: alias,
isGray: false
}
this.legend.push(legend);
chartData.data = queryData.values.map((dpsItem, dpsIndex) => {
return [bus.computeTimezone(dpsItem[0]) * 1000, parseFloat(dpsItem[1]).toFixed(2)];
});
this.chartDatas.push(chartData);
}
} else {
this.$message.error(response.data.error)
console.error(response.data)
}
}
});
this.$nextTick(() => {
this.$refs.messageChart.setRandomColors(this.chartDatas.length);
this.$refs.messageChart.setLegend(this.legend);
this.$refs.messageChart.setSeries(this.chartDatas);
this.$refs.messageChart.endLoading();
});
} catch(err) {
this.$message.error(err);
this.$refs.messageChart.endLoading();
}
})
},
computeDistance:function(str){
var width = 0;
var html = document.createElement('span');
html.innerText = str;
html.className = 'getTextWidth';
document.querySelector('body').appendChild(html);
width = document.querySelector('.getTextWidth').offsetWidth;
document.querySelector('.getTextWidth').remove();
return Number('-'+(width+5));
},
returnMarkArea:function(){
if(this.currentMsg){
if(this.currentMsg.alertRule.operator=='>'||this.currentMsg.alertRule.operator=='>='){
return[{yAxis:this.currentMsg.alertRule.threshold},{}]
}else{
return[{},{yAxis:this.currentMsg.alertRule.threshold}]
}
}
},
detail(obj) {
this.chartDatas = [];
this.legend = [];
this.graphShow = true;
this.currentMsg = obj;
this.chartUnit=obj.alertRule.unit?obj.alertRule.unit:5;
this.$nextTick(() => {
this.queryChartDate();
});
},
dialogClose() {
this.graphShow = false;
},
getAlertList: function () {
this.$set(this.searchLabel, "pageNo", this.pageObj.pageNo);
this.$set(this.searchLabel, "pageSize", this.pageObj.pageSize);
if(this.searchTime&& this.searchTime.length>1){
this.$set(this.searchLabel, "startAt", bus.timeFormate(this.searchTime[0], 'yyyy-MM-dd hh:mm:ss'));
this.$set(this.searchLabel, "endAt", bus.timeFormate(this.searchTime[1], 'yyyy-MM-dd hh:mm:ss'));
}else{
delete this.searchLabel.startAt
delete this.searchLabel.endAt
}
this.tools.loading = true;
this.$get('alert/message', this.searchLabel).then(response => {
this.tools.loading = false;

View File

@@ -85,7 +85,7 @@
clearTimeout(this.filterTimer)
this.filterTimer=setTimeout(()=>{
this.filterItems(newContent);
},300)
},200)
},
dealSpecilChar:function(char,operation){//控制括号的成对添加和删除
// console.log('specil char',char)
@@ -832,19 +832,20 @@
let promise=$temp.storeCursor(char);
if(source == 'user'){
//console.log(delta,oldDelta,oldContent)
clearTimeout($temp.userChangeTimer)
$temp.userChangeTimer=setTimeout(()=>{
// clearTimeout($temp.userChangeTimer)
// $temp.userChangeTimer=setTimeout(()=>{
let newContent=$temp.getContent()
promise.then(()=>{ //存储完光标后再进行后面的操作
$temp.userChange(char,operation,newContent,oldContent)
})
},100)
// },100)
}
$temp.content=$temp.getContent();
//console.log('current content-->',$temp.content)
$temp.getPosition();
clearTimeout($temp.formatTimer)
$temp.formatTimer=setTimeout($temp.formatContent,100)
/*clearTimeout($temp.formatTimer)
$temp.formatTimer=setTimeout($temp.formatContent,100)*/
$temp.formatContent()
}
//监听文本区域的高度
let lineHeight = 16;