fix:修复dashboard内存泄漏

This commit is contained in:
zyh
2022-04-27 17:03:06 +08:00
28 changed files with 1481 additions and 206 deletions

View File

@@ -55,6 +55,7 @@ const devWebpackConfig = merge(baseWebpackConfig, {
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
favicon: path.resolve(__dirname, '../src/assets/img/favicon.ico'),
filename: 'index.html',
template: 'index.html',
inject: true

View File

@@ -91,6 +91,7 @@ const webpackConfig = merge(baseWebpackConfig, {
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
favicon: path.resolve(__dirname, '../src/assets/img/favicon.ico'),
filename: config.build.index,
template: 'index.html',
hash: false,

View File

@@ -22,7 +22,7 @@ module.exports = {
// host: '0.0.0.0', // can be overwritten by process.env.HOST
host: 'localhost', // can be overwritten by process.env.HOST
port: 80, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
autoOpenBrowser: true,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: true,
poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

View File

@@ -5,8 +5,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="data:;base64,=">
<link href="./static/explore-tab-logo.png" rel="icon" type="image/x-icon"/>
<link href="./favicon.ico" rel="icon" type="image/x-icon"/>
<title>Network Zodiac</title>
<style>

View File

@@ -15,7 +15,8 @@
width: 100%;
position: absolute;
z-index: 2000;
background-color: rgba(255,255,255,0.9);
background-color: $--background-color-empty;
opacity: 0.8;
margin: 0;
top: 0;
right: 0;

View File

@@ -11,6 +11,7 @@
align-items: center;
font-weight: 600;
font-family: PingFangSC-Medium;
color: $--color-text-primary;
.alert-message-state {
display: block;
@@ -18,10 +19,9 @@
margin-right: 15px;
font-size: 14px;
font-weight: normal;
color: $--color-text-label;
padding: 2px 8px;
border-radius: 4px;
color: $--color-text-label;
}
}
@@ -51,10 +51,10 @@
}
.alert-message-info-tab {
height: 63%;
height: 61.8%;
flex: 1;
.alert-label-header-title {
.alert-label-header-title3 {
display: none;
}
@@ -97,6 +97,8 @@
}
.el-tabs__content {
// box-sizing:content-box;
// height: 100%;
padding: 25px 30px;
flex: 1;
border: 1px solid $--border-color-light;
@@ -235,7 +237,7 @@
.time-line-item-header {
font-size: 14px;
color: #333333;
color: $--color-text-primary;
font-weight: 400;
}
}
@@ -274,7 +276,8 @@
.info-box-content {
font-size: 14px;
color: #666666;
// color: #666666;
color: $--color-text-regular;
font-weight: 400;
width: 100%;
margin-bottom: 40px;
@@ -307,12 +310,12 @@
padding-left: 5px;
span:nth-of-type(n) {
color: #999999;
color: $--color-text-secondary;
margin-right: 5px;
}
span:nth-of-type(2n) {
color: #666666;
color: $--color-text-regular;
margin-right: 15px;
}
}
@@ -417,6 +420,7 @@
.nz-alert-tag__content {
padding-left: 6px;
padding-right: 6px;
color: $--color-text-primary;
display: flex;
align-items: center;
justify-content: center;

View File

@@ -8,7 +8,7 @@
line-height: 40px;
height: 40px;
box-sizing: border-box;
border: 1px solid $--border-color-base;
border: 1px solid $--border-color-light;
border-radius: $--border-radius-small;
}
.calendar.calendar--small {
@@ -81,13 +81,14 @@
display: flex;
justify-content: space-between;
font-size: 14px;
color: $--color-text-regular;
.utc-str {
line-height: 44px;
text-align: right;
span{
font-size: 12px;
background: $--background-color-2;
padding: 6px 8px;
}
}
}
@@ -113,6 +114,7 @@
}
.date-range-text {
color: $--color-text-regular;
font-size: 14px;
// min-width: 150px;
flex-direction: row;
@@ -120,12 +122,12 @@
padding: 0 10px;
display: flex;
justify-content: space-around;
height: 26px;
background: #FFFFFF;
// border: 1px solid #E7EAED;
height: 30px;
background: $--background-color-empty;
//border: 1px solid $--border-color-light;
box-shadow: 0 2px 4px 0 rgba(51, 51, 51, 0.02);
border-radius: 2px;
line-height: 26px;
line-height: 30px;
transition: width .3s;
.cn-icon {
@@ -144,7 +146,7 @@
.date-range-title {
font-size: 14px;
color: #666666;
color: $--color-text-regular;
font-weight: 600;
padding: 14px 0 7px 8px;
}
@@ -166,7 +168,7 @@
.date-range-panel {
// height: 460px;
width: 500px;
background: #FFFFFF;
background: $--background-color-empty;
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
position: absolute;
right: 4%;
@@ -179,26 +181,67 @@
flex-direction: column;
.content-title {
font-size: 14px;
color: #666666;
color: $--color-text-regular;
font-weight: 400;
}
.content-input {
width: 230px;
display: flex;
position: relative;
align-items: center;
margin-bottom: 12px;
.el-input{
width: auto;
flex: 1;
.el-input__inner{
border: 1px solid #E7EAED;
border: 1px solid $--border-color-light;
border-radius: 2px;
width: 230px;
padding: 0 8px;
height: 30px;
line-height: 30px;
margin-bottom: 12px;
outline: #169AFF;
//height: 30px;
//line-height: 30px;
//outline: #169AFF;
}
}
.input-hint{
display: none;
}
.nz-icon-box{
height: 28px;
box-sizing: border-box;
background: $--background-color-2;
padding: 0 8px;
line-height: 25px;
border-radius: 2px;
color: $--color-text-regular;
border: 1px solid $--border-color-base;
margin-left: 4px;
.nz-icon{
font-size: 14px;
}
&:hover{
border-color: $--color-primary;
color: $--color-primary;
}
}
&.input-error{
.el-input{
.el-input__inner{
border: 1px solid $--color-danger;
//outline: $--color-danger;
}
}
.input-hint{
display: block;
color: $--color-danger;
position: absolute;
left: 0;
font-size: 14px;
bottom: -25px;
}
}
}
.date-range-history {
@@ -236,22 +279,22 @@
display: flex;
flex-direction: column;
justify-content: center;
color: #333333;
color: $--color-text-primary;
font-weight: 400;
padding: 0 10px;
cursor: pointer;
}
li:hover {
background: #F5F5F5;
color: #333333;
background: $--alert-rule-background-color;
color: $--color-text-primary;
}
li.activeLi :hover {
background: #F5F5F5;
background: $--alert-rule-background-color;
color: $--color-primary !important;
}
li.activeLi {
background: #F5F5F5;
background: $--alert-rule-background-color;
color: $--color-primary !important;
font-weight: 400;
@@ -265,3 +308,9 @@
}
}
}
.el-date-range-picker.el-picker-panel__body__only {
width: 324px;
}
.el-date-range-picker__content.el-date-range-picker__content__only{
width: 100%;
}

View File

@@ -32,9 +32,9 @@ $--left-menu-background-color-hover: $--left-menu-background-color-active;
/* 3.字色 */
// 标题字色(覆盖element-ui内置变量)
$--color-text-primary: #333332;
$--color-text-primary: #333333;
// 普通字色(覆盖element-ui内置变量)
$--color-text-regular: #666665;
$--color-text-regular: #666666;
// 次要字色(覆盖element-ui内置变量)
$--color-text-secondary: #999998;
// 链接字色
@@ -221,7 +221,7 @@ $--switch-background-color: #dcdfe6;
$--project-input-background-color: $--color-text-disabled;
/* alert rule */
$--alert-rule-background-color: #f4f4f5;
$--alert-rule-background-color: #f5f5f5;
$--alert-rule-color: $--overview-icon-color;
/* webSSH */

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -28,6 +28,7 @@ import { formatScientificNotation, getMetricTypeValue } from '@/components/commo
import chartDataFormat from '@/components/chart/chartDataFormat'
import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash'
import bus from "@/libs/bus";
export default {
name: 'chart-bar',
@@ -107,6 +108,13 @@ export default {
}
}
}
chartOption.yAxis.axisLabel.formatter = function (val, index) {
const value = formatScientificNotation(val, 6)
let chartUnit = self.chartInfo.unit
chartUnit = chartUnit || 2
const unit = chartDataFormat.getUnit(chartUnit)
return unit.compute(value, index, -1, 2)
}
chartOption.tooltip.formatter = this.formatterFunc
chartOption.tooltip.position = this.tooltipPosition
/* 使用setTimeout延迟渲染图表避免样式错乱 */

View File

@@ -43,7 +43,12 @@ const chartBarOption = {
}
},
yAxis: {
type: 'value'
type: 'value',
axisLabel: {
show: true,
fontSize: 10
// formatter: 动态生成
}
},
series: [
{

View File

@@ -117,7 +117,7 @@ export default {
// 处理legend别名
alias = alias + this.handleLegendAlias(legend, chartInfo.elements[expressionIndex].legend)
if (!alias) {
alias = chartInfo.elements[expressionIndex].expression
alias = chartInfo.elements[expressionIndex].expression || ''
}
if (alias == 'Previous ') {
alias += chartInfo.elements[expressionIndex].expression
@@ -148,9 +148,9 @@ export default {
if (/\{\{.+\}\}/.test(aliasExpression)) {
const labelValue = aliasExpression.replace(/(\{\{.+?\}\})/g, function (i) {
const label = i.substr(i.indexOf('{{') + 2, i.indexOf('}}') - i.indexOf('{{') - 2)
// if (!legend) {
// return label
// }
if (!legend) {
return label
}
const reg = new RegExp(label + '=".+?"')
let value = null
if (reg.test(legend)) {

View File

@@ -27,12 +27,16 @@
{{ alertLabelData && alertLabelData.id ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.name ? alertLabelData.name : '--'}}</div>
</div>
<!-- <div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div>
</div> -->
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.manageIp") }}</div>
<div class="alert-label-value">
@@ -43,10 +47,6 @@
}}
</div>
</div>
<div class="alert-label-box name-label">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.name ? alertLabelData.name : '--'}}</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.type") }}</div>
<div class="alert-label-value">
@@ -188,7 +188,7 @@
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.Name ? alertLabelData.Name : "--" }}
</div>
@@ -281,7 +281,7 @@
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
@@ -376,7 +376,7 @@
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
@@ -508,7 +508,7 @@
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>

View File

@@ -0,0 +1,874 @@
<template>
<div
:class="calcHeight(that.position, that)"
:style="calcPosition(that.position, that)"
class="alert-label__border"
ref="alertLabels"
>
<div class="alert-label-header-title3">
<div
class="alert-label-header-circle"
:style="`background: ${alertColor}`"
>
<i class="nz-icon" :class="selectIcon(type)"></i>
</div>
<div class="alert-label-header-name">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div>
<div
class="alert-label-info"
v-if="type === 'asset'"
v-my-loading="loading"
>
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.id ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">{{alertLabelData && alertLabelData.name ? alertLabelData.name : '--'}}</div>
</div>
<!-- <div class="alert-label-box name-labe">
<div class="alert-label-title">Name</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div> -->
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.manageIp") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.manageIp
? alertLabelData.manageIp
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.type") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.type && alertLabelData.type.name
? alertLabelData.type.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.state") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.state && alertLabelData.state.name
? alertLabelData.state.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Ping</div>
<div class="alert-label-value">
<div
v-if="alertLabelData"
:class="{
'green-bg':
alertLabelData &&
alertLabelData.pingInfo &&
alertLabelData.pingInfo.status === 1,
'red-bg':
alertLabelData &&
alertLabelData.pingInfo &&
alertLabelData.pingInfo.status === 0,
}"
class="active-icon"
></div>
<span v-if="alertLabelData">{{
alertLabelData &&
alertLabelData.pingInfo &&
alertLabelData.pingInfo.rtt
? alertLabelData.pingInfo.rtt + "ms"
: ""
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.dc") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.dc && alertLabelData.dc.name
? alertLabelData.dc.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.cabinet") }}</div>
<div class="alert-label-value">
{{
alertLabelData &&
alertLabelData.cabinet &&
alertLabelData.cabinet.name
? alertLabelData.cabinet.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.brand") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.brand && alertLabelData.brand.name
? alertLabelData.brand.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.model") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.model && alertLabelData.model.name
? alertLabelData.model.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.alert") }}</div>
<div class="alert-label-value" v-if="alertLabelData">
<i
:class="alertLabelData.alertNum ? 'red' : 'green'"
class="nz-icon nz-icon-overview-alert vertical-align-top;"
@mouseenter="tooltipHover('', true, $event)"
@mouseleave="tooltipHover('', false, $event)"
></i>
<div
v-if="alertNumtooltipShow"
class="alert-days-info-tooltip"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<div class="tooltip-title">
{{ $t("project.topology.alert") }}({{ $t("asset.pingActive") }})
</div>
<div class="severity-info" style="justify-content: space-between">
<div class="severity-name">{{ $t("overall.result.total") }}</div>
<div class="severity-value">{{ alertLabelData.alertNum }}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("asset.endpoint") }}</div>
<div class="alert-label-value">
<i class="nz-icon nz-icon-overview-endpoint monitorColor"></i>&nbsp;
<span>{{
alertLabelData && alertLabelData.endpointNum
? alertLabelData.endpointNum
: 0
}}</span>
</div>
</div>
</div>
<div
class="alert-label-info"
v-if="type === 'module'"
v-my-loading="loading"
>
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.id ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.Name ? alertLabelData.Name : "--" }}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.project") }}</div>
<div class="alert-label-value">
{{
alertLabelData &&
alertLabelData.project &&
alertLabelData.project.name
? alertLabelData.project.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("asset.endpoint") }}</div>
<div class="alert-label-value">
<i class="nz-icon nz-icon-overview-endpoint monitorColor"></i>&nbsp;
<span>{{
alertLabelData && alertLabelData.endpointNum
? alertLabelData.endpointNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.asset") }}</div>
<div class="alert-label-value">
<i
class="nz-icon nz-icon-overview-project monitorColor color23BF9A"
/>&nbsp;
<span>{{
alertLabelData && alertLabelData.assetNum
? alertLabelData.assetNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.alert") }}</div>
<div class="alert-label-value" v-if="alertLabelData">
<i
:class="alertLabelData.alertNum ? 'red' : 'green'"
class="nz-icon nz-icon-overview-alert vertical-align-top;"
@mouseenter="tooltipHover('', true, $event)"
@mouseleave="tooltipHover('', false, $event)"
></i>
<div
v-if="alertNumtooltipShow"
class="alert-days-info-tooltip"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<div class="tooltip-title">
{{ $t("project.topology.alert") }}({{ $t("asset.pingActive") }})
</div>
<div class="severity-info" style="justify-content: space-between">
<div class="severity-name">{{ $t("overall.result.total") }}</div>
<div class="severity-value">{{ alertLabelData.alertNum }}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.remark") }}</div>
<div class="alert-label-value alert-label-remark">
{{
alertLabelData && alertLabelData.remark
? alertLabelData.remark
: "--"
}}
</div>
</div>
</div>
<div
class="alert-label-info"
v-if="type === 'project'"
v-my-loading="loading"
>
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.module") }}</div>
<div class="alert-label-value">
<i
style="cursor: pointer"
class="nz-icon nz-icon-overview-module monitorColor"
/>&nbsp;
<span>{{
alertLabelData && alertLabelData.moduleNum
? alertLabelData.moduleNum
: "--"
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">Endpoint</div>
<div class="alert-label-value">
<i class="nz-icon nz-icon-overview-endpoint monitorColor"></i>&nbsp;
<span>{{
alertLabelData && alertLabelData.endpointNum
? alertLabelData.endpointNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.asset") }}</div>
<div class="alert-label-value">
<i
class="nz-icon nz-icon-overview-project monitorColor color23BF9A"
/>
<span>{{
alertLabelData && alertLabelData.assetNum
? alertLabelData.assetNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.alert") }}</div>
<div class="alert-label-value" v-if="alertLabelData">
<i
:class="alertLabelData.alertNum ? 'red' : 'green'"
class="nz-icon nz-icon-overview-alert vertical-align-top;"
@mouseenter="tooltipHover('', true, $event)"
@mouseleave="tooltipHover('', false, $event)"
></i>
<div
v-if="alertNumtooltipShow"
class="alert-days-info-tooltip"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<div class="tooltip-title">
{{ $t("project.topology.alert") }}({{ $t("asset.pingActive") }})
</div>
<div class="severity-info" style="justify-content: space-between">
<div class="severity-name">{{ $t("overall.result.total") }}</div>
<div class="severity-value">{{ alertLabelData.alertNum }}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.remark") }}</div>
<div class="alert-label-value alert-label-remark">
{{
alertLabelData && alertLabelData.remark
? alertLabelData.remark
: "--"
}}
</div>
</div>
</div>
<div
class="alert-label-info"
v-if="type === 'endpoint'"
v-my-loading="loading"
>
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.id ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.project") }}</div>
<div class="alert-label-value">
{{
alertLabelData &&
alertLabelData.project &&
alertLabelData.project.name
? alertLabelData.project.name
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.module") }}</div>
<div class="alert-label-value">
<i
style="cursor: pointer"
class="nz-icon nz-icon-overview-module monitorColor"
/>&nbsp;
<span>{{
alertLabelData &&
alertLabelData.module &&
alertLabelData.module.name
? alertLabelData.module.name
: "--"
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.asset") }}</div>
<div class="alert-label-value">
<i
class="nz-icon nz-icon-overview-project monitorColor color23BF9A"
></i
>&nbsp;
<span>{{
alertLabelData && alertLabelData.asset.name
? alertLabelData.asset.name
: "--"
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.alert") }}</div>
<div class="alert-label-value" v-if="alertLabelData">
<i
:class="alertLabelData.alertNum ? 'red' : 'green'"
class="nz-icon nz-icon-overview-alert vertical-align-top;"
@mouseenter="tooltipHover('', true, $event)"
@mouseleave="tooltipHover('', false, $event)"
></i>
<div
v-if="alertNumtooltipShow"
class="alert-days-info-tooltip"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<div class="tooltip-title">
{{ $t("project.topology.alert") }}({{ $t("asset.pingActive") }})
</div>
<div class="severity-info" style="justify-content: space-between">
<div class="severity-name">{{ $t("overall.result.total") }}</div>
<div class="severity-value">{{ alertLabelData.alertNum }}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.state") }}</div>
<div class="alert-label-value">
<span style="width: auto">
<span class="endpoint-cell-left"
><i class="nz-icon nz-icon-Metrics active" />
{{ $t("project.endpoint.metrics") }}
</span>
<span
v-if="alertLabelData && alertLabelData.configs[0].state === 0"
>
<span class="active-icon red-bg inline-block"></span>
</span>
<span
v-else-if="
alertLabelData && alertLabelData.configs[0].state === 1
"
>
<span class="active-icon green-bg inline-block"></span>
</span>
<span v-else-if="alertLabelData && alertLabelData.configs[0].state">
<span class="active-icon gray-bg inline-block"></span>
</span>
</span>
<span style="width: auto">
<span class="endpoint-cell-left" style="margin-left: 10px"
><i class="nz-icon nz-icon-logs active" />
{{ $t("project.endpoint.logs") }}
</span>
<span
v-if="alertLabelData && alertLabelData.configs[1].state === 0"
>
<span class="active-icon red-bg inline-block"></span>
</span>
<span
v-else-if="
alertLabelData && alertLabelData.configs[1].state === 1
"
>
<span class="active-icon green-bg inline-block"></span>
</span>
<span v-else-if="alertLabelData && alertLabelData.configs[1].state">
<span class="active-icon gray-bg inline-block"></span>
</span>
</span>
</div>
</div>
</div>
<div class="alert-label-info" v-if="type === 'dc'" v-my-loading="loading">
<div class="alert-label-box">
<div class="alert-label-title">ID</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.id ? alertLabelData.id : "--" }}
</div>
</div>
<div class="alert-label-box name-labe">
<div class="alert-label-title">{{$t('overall.name')}}</div>
<div class="alert-label-value">
{{ alertLabelData && alertLabelData.name ? alertLabelData.name : "--" }}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.location") }}</div>
<div class="alert-label-value">
{{
alertLabelData && alertLabelData.location && alertLabelData.location
? alertLabelData.location
: "--"
}}
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.cabinet") }}</div>
<div class="alert-label-value">
<i
v-if="alertLabelData"
class="nz-icon nz-icon-cabinet monitorColor"
:class="
alertLabelData && alertLabelData.cabinetNum > 0
? 'color23BF9A'
: 'colorEF7458'
"
/>&nbsp;
<span>{{
alertLabelData && alertLabelData.cabinetNum
? alertLabelData.cabinetNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.asset") }}</div>
<div class="alert-label-value">
<i
class="nz-icon nz-icon-overview-project monitorColor color23BF9A"
/>&nbsp;
<span>{{
alertLabelData && alertLabelData.assetNum && alertLabelData.assetNum
? alertLabelData.assetNum
: 0
}}</span>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.alert") }}</div>
<div class="alert-label-value" v-if="alertLabelData">
<i
:class="alertLabelData.alertNum ? 'red' : 'green'"
class="nz-icon nz-icon-overview-alert vertical-align-top;"
@mouseenter="tooltipHover('', true, $event)"
@mouseleave="tooltipHover('', false, $event)"
></i>
<div
v-if="alertNumtooltipShow"
class="alert-days-info-tooltip"
:style="{ left: position.left + 'px', top: position.top + 'px' }"
>
<div class="tooltip-title">
{{ $t("project.topology.alert") }}({{ $t("asset.pingActive") }})
</div>
<div class="severity-info" style="justify-content: space-between">
<div class="severity-name">{{ $t("overall.result.total") }}</div>
<div class="severity-value">{{ alertLabelData.alertNum }}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-label-box">
<div class="alert-label-title">{{ $t("overall.state") }}</div>
<div class="alert-label-value" style="margin-left: 3px">
<div
v-if="alertLabelData"
:class="{
'green-bg': alertLabelData && alertLabelData.state === 'ON',
'red-bg': alertLabelData && alertLabelData.state === 'OFF',
}"
class="active-icon"
></div>
<span v-if="alertLabelData && alertLabelData.state === 'ON'">{{
$t("overall.enabled")
}}</span>
<span v-if="alertLabelData && alertLabelData.state === 'OFF'">{{
$t("overall.disabled")
}}</span>
</div>
</div>
</div>
</div>
</template>
<script>
import trendMixin from './trendMixins'
export default {
name: 'alertLabel',
mixins: [trendMixin],
props: {
id: {},
type: {},
// labelLoading:{},
that: {},
detailList: Boolean,
alertTableDialog: Boolean
},
data () {
return {
alertLabelData: null,
loading: true,
heightList: 0,
boxWidth: 0,
severityDataWeight: this.$store.getters.severityDataWeight,
alertColor: '#23bf9a'
}
},
watch: {
id: {
immediate: true,
deep: true,
handler (n) {
this.init()
}
},
that: {
immediate: true,
deep: true,
handler (n) {}
},
LRTriangle: {
immediate: true,
deep: true,
handler (n) {}
}
},
computed: {
calcPosition () {
return function (position) {
const clientHeight =
document.body.clientHeight < document.documentElement.clientHeight
? document.body.clientHeight
: document.documentElement.clientHeight
const clientWidth =
document.body.clientWidth < document.documentElement.clientWidth
? document.body.clientWidth
: document.documentElement.clientWidth
let leftOffSetView = 0
let leftOffSet = this.detailList ? -80 : 10
let topOffSet = this.detailList ? 60 : 22
let topOffSetView = 0
let labelPosition = {
top: 0,
left: 0,
right: 0
}
if (this.alertTableDialog) {
let dialog = document.querySelector(
'#dialog-alert-massage .el-dialog'
)
if (!dialog) {
dialog = document.querySelector('#viewGraphDialog .el-dialog')
}
const dialogHeight = dialog.getBoundingClientRect()
leftOffSet = leftOffSet - 3 * dialogHeight.x
leftOffSetView = dialogHeight.x
topOffSet = topOffSet - dialogHeight.y
topOffSetView = topOffSet
}
if (position.top > clientHeight / 2) {
labelPosition = {
left: `${position.left + position.width + leftOffSet}px`,
top: `${position.top - this.heightList - topOffSetView}px`
}
} else {
labelPosition = {
left: `${position.left + position.width + leftOffSet}px`,
top: `${position.top + topOffSet}px`
}
}
if (position.left > clientWidth / 2) {
delete labelPosition.left
labelPosition.right =
clientWidth - position.left - leftOffSetView + 'px'
}
return labelPosition
}
},
calcHeight () {
const self = this
return function (position) {
const clientHeight =
document.body.clientHeight < document.documentElement.clientHeight
? document.body.clientHeight
: document.documentElement.clientHeight
const elHeight =
self.type === 'asset' ? 318 : self.type === 'project' ? 70 : 70
if (position.top + elHeight > clientHeight) {
return 'alert-labelUp'
} else {
return 'alert-label'
}
}
}
},
methods: {
init () {
this.loading = true
if (this.type === 'asset') {
this.$get('asset/asset/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data
this.alertColor = this.returnColor(res.data.alert)
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'project') {
this.$get('monitor/project/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data
this.alertColor = this.returnColor(res.data.alert)
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'module') {
this.$get('monitor/module/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data
this.alertColor = this.returnColor(res.data.alert)
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'endpoint') {
this.$get('monitor/endpoint/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data
this.alertColor = this.returnColor(res.data.alert)
} else {
this.$message.error(res.msg)
}
})
}
if (this.type === 'dc') {
this.$get('dc/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertLabelData = res.data
this.alertColor = this.returnColor(res.data.alert)
} else {
this.$message.error(res.msg)
}
})
}
const weekDays = this.getWeeksTime()
if (this.trendTimer) {
clearTimeout(this.trendTimer)
this.trendTimer = null
}
this.trendTimer = setTimeout(() => {
this.trendLoading = true
const params = {
type: 'total',
dimension: 'priority',
step: 'd'
}
params[this.type + 'Id'] = this.id
this.$get('/stat/alertMessage/trend', params).then((res) => {
if (!res.data) {
return
}
const alertDaysData = res.data.result
? res.data.result[0].values
: []
const newWeekDays = JSON.parse(JSON.stringify(weekDays))
alertDaysData.forEach((item) => {
item.values.forEach((time) => {
const findItem = newWeekDays.find((days) => days.time == time[0])
if (findItem) {
findItem[item.metric.priority] = time[1]
}
})
})
setTimeout(() => {
this.alertDaysData = newWeekDays
this.trendLoading = false
})
})
})
},
alertActiveStr () {
return this.$t('overall.active')
},
alertStateStr (num) {
if (num == 1) {
return this.$t('asset.inStock')
} else {
return this.$t('asset.notInStock')
}
},
selectIcon (type) {
switch (type) {
case 'asset':
return 'nz-icon-overview-project'
case 'dc':
return 'nz-icon-Datacenter2'
case 'project':
return 'nz-icon-project'
case 'module':
return 'nz-icon-overview-module'
case 'endpoint':
return 'nz-icon-overview-endpoint'
case 'alertrule':
return 'nz-icon-Alertrule'
}
return 'nz-icon-module5'
},
returnColor (obj) {
let color = ''
if (!obj) {
return '#23bf9a'
} else {
this.severityDataWeight.forEach((severity) => {
const num = obj.find((alert) => alert.priority === severity.name)
if (num && !color && num.num > 0) {
color = severity.color
}
})
if (!color) {
color = '#23bf9a'
}
return color
}
}
},
mounted () {
if (this.$refs.alertLabels) {
this.heightList = this.$refs.alertLabels.getBoundingClientRect().height
this.boxWidth = this.$refs.alertLabels.getBoundingClientRect().width
} else {
this.heightList = 0
this.boxWidth = 0
}
},
beforeDestroy () {}
}
</script>
<style>
</style>

View File

@@ -40,8 +40,8 @@
<script>
import alertMessageInfoDetail from '@/components/common/alert/alertMessageInfoDetail'
import searchItemInfo from '@/components/common/globalSearch/searchItemInfo'
import alertLabel from '@/components/common/alert/alertLabel'
import alertRuleInfo from '@/components/common/alert/alertRuleInfo'
import alertLabel from '@/components/common/alert/alertLabel3'
import alertRuleInfo from '@/components/common/alert/alertRuleInfo2'
// import alertLabelMixin from '@/components/common/mixin/alertLabelMixin'
export default {
name: 'alertMessageInfoTab',

View File

@@ -14,7 +14,7 @@
<div class="alert-rule-value">{{alertRuleData.id ? alertRuleData.id : '--'}}</div>
</div>
<div class="alert-rule-box name-labe">
<div class="alert-rule-title">Name</div>
<div class="alert-rule-title">{{$t('overall.name')}}</div>
<div class="alert-rule-value">{{alertRuleData.name ? alertRuleData.name : '--'}}</div>
</div>
<!-- <div class="alert-rule-box">-->

View File

@@ -0,0 +1,221 @@
<template>
<div :style="calcPosition(that.position,that)" class="alert-label__border alert-label" v-my-loading="loading" ref="alertLabels">
<div class="alert-label-header-title3">
<div class="alert-label-header-circle" :style="`background: ${alertColor}`">
<i class="nz-icon nz-icon-Alertrule"></i>
</div>
<div class="alert-label-header-name">
{{alertRuleData && alertRuleData.name ? alertRuleData.name : '--'}}
</div>
</div>
<div class="alert-rule-nfo" >
<div class="alert-rule-box">
<div class="alert-rule-title">ID</div>
<div class="alert-rule-value">{{alertRuleData.id ? alertRuleData.id : '--'}}</div>
</div>
<div class="alert-rule-box name-labe">
<div class="alert-rule-title">{{$t('overall.name')}}</div>
<div class="alert-rule-value">{{alertRuleData.name ? alertRuleData.name : '--'}}</div>
</div>
<!-- <div class="alert-rule-box">-->
<!-- <div class="alert-rule-title">{{$t('alert.name')}}</div>-->
<!-- <div class="alert-rule-value">{{alertRuleData.name ? alertRuleData.name : '&#45;&#45;'}}</div>-->
<!-- </div>-->
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.type')}}</div>
<div class="alert-rule-value">
<span v-if="alertRuleData.type === 1">
{{$t('project.metrics.metrics')}}
</span>
<span v-else-if="alertRuleData.type === 2">
{{$t('overall.logs')}}
</span>
<span v-else-if="alertRuleData.type === 3">SNMP trap</span>
<span v-else>--</span>
</div>
</div>
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.severity')}}</div>
<div class="alert-rule-value"><i class="nz-icon nz-icon-circle" :style="{color:severityColor,'font-size':'12px','margin-right':'5px'}"></i>{{alertRuleData.severityId ? severityData.find(s => alertRuleData.severityId === s.id).name : '--'}}</div>
</div>
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.config.expr')}}</div>
<div class="alert-rule-value">{{alertRuleData.expr ? (alertRuleData.expr + alertRuleData.operator + formatThreshold(alertRuleData.threshold,alertRuleData.unit)) : '--'}}</div>
</div>
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.alertNum')}}</div>
<div class="alert-rule-value" v-if="alertRuleData">
<i :class="alertRuleData.alertNum ? 'red' : 'green'" class="nz-icon nz-icon-overview-alert vertical-align-top;" @mouseenter="tooltipHover('',true, $event)" @mouseleave="tooltipHover('',false, $event)"></i>
<div v-if="alertNumtooltipShow" class="alert-days-info-tooltip" :style="{left: position.left + 'px',top:position.top + 'px'}">
<div class="tooltip-title">{{$t('project.topology.alert')}}({{$t('asset.pingActive')}})</div>
<div class="severity-info" style='justify-content: space-between'>
<div class="severity-name">{{$t('overall.result.total')}}</div>
<div class="severity-value">{{alertRuleData.alertNum}}</div>
</div>
</div>
<alertDaysInfo
v-show="!trendLoading"
:alertDaysData="alertDaysData"
/>
</div>
</div>
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.config.trbShot')}}</div>
<div class="alert-rule-value" @click="trbShotShow"><i class="nz-icon nz-icon-guzhangshuju"></i></div>
</div>
<div class="alert-rule-box">
<div class="alert-rule-title">{{$t('alert.state')}}</div>
<div class="alert-rule-value" style="margin-left: 3px">
<div v-if="alertRuleData.state === 1">
<i class="active-icon green-bg inline-block"></i>
{{ $t('overall.enabled') }}
</div>
<div v-else-if="alertRuleData.state === 0">
<i class="active-icon gray-bg inline-block"></i>
{{ $t('overall.disabled') }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import chartDataFormat from '../../chart/chartDataFormat'
import trendMixins from '@/components/common/alert/trendMixins'
export default {
name: 'alert-rule-info',
mixins: [trendMixins],
props: {
id: {},
messageLoad: {},
detailList: Boolean,
that: {},
severityData: Array
},
data () {
return {
loading: true,
alertRuleData: '',
severityColor: '',
severityDataWeight: this.$store.getters.severityDataWeight,
alertColor: '#23bf9a'
}
},
components: {
},
computed: {
calcPosition () {
return function (position) {
if (!position) {
return {
left: '0px',
top: '0px'
}
}
const clientHeight = (document.body.clientHeight < document.documentElement.clientHeight) ? document.body.clientHeight : document.documentElement.clientHeight
// const windowWidth = window.innerWidth
const boxHeight = this.$refs.alertLabels ? this.$refs.alertLabels.offsetHeight : 231
const windowHeight = window.innerHeight
const leftOffSetView = this.detailList ? -80 : 10
if (position.top > windowHeight / 2) {
return {
left: `${position.left + position.width + leftOffSetView}px`,
top: `${position.top - boxHeight}px`
}
} else {
return {
left: `${position.left + position.width + leftOffSetView}px`,
top: `${position.top}px`
}
}
}
}
},
methods: {
formatThreshold (value, unit) {
const unitMethod = chartDataFormat.getUnit(unit)
if (unitMethod && value) {
return unitMethod.compute(value, null, 2)
} else {
return value
}
},
trbShotShow () {
this.$emit('showText')
},
severityDataColor () {
this.severityData.forEach(item => {
if (this.alertRuleData.severityId === item.id) {
this.severityColor = item.color
}
})
},
returnColor (obj) {
let color = ''
if (!obj) {
color = '#23bf9a'
return color
} else {
this.severityDataWeight.forEach(severity => {
const num = obj.find(alert => alert.priority === severity.name)
if (num && !color && num.num > 0) {
color = severity.color
}
})
if (!color) {
color = '#23bf9a'
}
return color
}
}
},
mounted () {
this.$get('/alert/rule/' + this.id).then((res) => {
if (res.msg === 'success') {
this.loading = false
this.alertRuleData = res.data
this.severityDataColor()
this.alertColor = this.returnColor(res.data.alert)
const weekDays = this.getWeeksTime()
if (this.trendTimer) {
clearTimeout(this.trendTimer)
this.trendTimer = null
}
this.trendTimer = setTimeout(() => {
this.trendLoading = true
const params = {
type: 'total',
dimension: 'priority',
step: 'd'
}
params['rule' + 'Id'] = this.id
this.$get('/stat/alertMessage/trend', params).then((res) => {
if (!res.data) {
return
}
const alertDaysData = res.data.result ? res.data.result[0].values : []
const newWeekDays = JSON.parse(JSON.stringify(weekDays))
alertDaysData.forEach(item => {
item.values.forEach(time => {
const findItem = newWeekDays.find(days => days.time == time[0])
if (findItem) {
findItem[item.metric.priority] = time[1]
}
})
})
setTimeout(() => {
this.alertDaysData = newWeekDays
this.trendLoading = false
})
})
})
} else {
this.$message.error(res.msg)
}
})
}
}
</script>

View File

@@ -494,7 +494,6 @@ export default {
if (this.$refs.pickTime) {
const nowTimeType = this.$refs.pickTime.$refs.timePicker.nowTimeType
this.nowTimeType = this.$refs.pickTime.$refs.timePicker.nowTimeType
console.log(nowTimeType, this.nowTimeType)
this.setSearchTime(nowTimeType.type, nowTimeType.value)
this.filter.start_time = bus.timeFormate(this.searchTime[0])
this.filter.end_time = bus.timeFormate(this.searchTime[1])
@@ -520,7 +519,6 @@ export default {
this.$set(this.searchTime, 0, startTime)
this.$set(this.searchTime, 1, endTime)
this.$set(this.searchTime, 2, val + 'h')
console.log(this.searchTime)
} else if (type === 'date') {
const startTime = bus.timeFormate(new Date(bus.computeTimezone(new Date().getTime())).setDate(new Date(bus.computeTimezone(new Date().getTime())).getDate() - val))
const endTime = bus.timeFormate(new Date(bus.computeTimezone(new Date().getTime())))

View File

@@ -221,3 +221,10 @@ export function sysObjectIdInput (rule, value, callback) {
export function longAndLat (rule, value, callback) { // 校验经纬度
}
export function dataValidate () {
// const time = '([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$'
// const YMD = '/((([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[48]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-29))'
// const DMY = '/((^(3[01]|[12][0-9]|0[1-9])(\\/)(10|12|0[13578])(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(30|[12][0-9]|0[1-9])(\\/)(11|0[469])(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(2[0-8]|1[0-9]|0[1-9])(\\/)(02)(\\/)((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(29)(\\/)(02)(\\/)([2468][048]00)$)|(^(29)(\\/)(02)(\\/)([3579][26]00)$)|(^(29)(\\/)(02)(\\/)([1][89][0][48])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][0][48])$)|(^(29)(\\/)(02)(\\/)([1][89][2468][048])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][2468][048])$)|(^(29)(\\/)(02)(\\/)([1][89][13579][26])$)|(^(29)(\\/)(02)(\\/)([2-9][0-9][13579][26])$))/'
// const MDY =
}

View File

@@ -5,7 +5,8 @@
class="el-picker-panel el-date-range-picker el-popper time-picker-popover__select-top"
:class="[{
'has-sidebar': $slots.sidebar || shortcuts,
'has-time': showTime
'has-time': showTime,
'el-picker-panel__body__only': isOnly
}, popperClass]">
<div class="el-picker-panel__body-wrapper">
<slot name="sidebar" class="el-picker-panel__sidebar"></slot>
@@ -17,7 +18,7 @@
:key="key"
@click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
</div>
<div class="el-picker-panel__body">
<div class="el-picker-panel__body" style="min-width: auto">
<div class="el-date-range-picker__time-header" v-if="showTime">
<span class="el-date-range-picker__editors-wrap">
<span class="el-date-range-picker__time-picker-wrap">
@@ -84,7 +85,9 @@
</span>
</span>
</div>
<div class="el-picker-panel__content el-date-range-picker__content is-left">
<div class="el-picker-panel__content el-date-range-picker__content is-left" :class="{
'el-date-range-picker__content__only': isOnly
}">
<div class="el-date-range-picker__header">
<button
type="button"
@@ -108,7 +111,32 @@
:disabled="!enableMonthArrow"
:class="{ 'is-disabled': !enableMonthArrow }"
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
<button
type="button"
@click="rightPrevYear"
v-if="unlinkPanels&&isOnly"
:disabled="!enableYearArrow"
:class="{ 'is-disabled': !enableYearArrow }"
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
<button
type="button"
@click="rightPrevMonth"
v-if="unlinkPanels&&isOnly"
:disabled="!enableMonthArrow"
:class="{ 'is-disabled': !enableMonthArrow }"
class="el-picker-panel__icon-btn el-icon-arrow-left"></button>
<button
type="button"
v-if="isOnly"
@click="rightNextYear"
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
<button
type="button"
v-if="isOnly"
@click="rightNextMonth"
class="el-picker-panel__icon-btn el-icon-arrow-right"></button>
<div>{{ leftLabel }}</div>
<!-- <div>{{ rightLabel }}</div>-->
</div>
<date-table
:timezone="timezone"
@@ -125,7 +153,7 @@
@pick="handleRangePick">
</date-table>
</div>
<div class="el-picker-panel__content el-date-range-picker__content is-right">
<div class="el-picker-panel__content el-date-range-picker__content is-right" v-if="!isOnly">
<div class="el-date-range-picker__header">
<button
type="button"
@@ -321,6 +349,7 @@ export default {
return {
popperClass: '',
value: [],
isOnly: false,
defaultValue: null,
defaultTime: null,
minDate: '',
@@ -440,6 +469,12 @@ export default {
? right
: nextMonth(this.leftDate)
}
},
isOnly: {
immediate: true,
handler (n) {
console.log(n,'isOnly')
}
}
},

View File

@@ -392,6 +392,10 @@ export default {
validateEvent: {
type: Boolean,
default: true
},
isOnly: {
type: Boolean,
default: false
}
},
@@ -444,6 +448,9 @@ export default {
if (!valueEquals(val, oldVal) && !this.pickerVisible && this.validateEvent) {
this.dispatch('ElFormItem', 'el.form.change', val)
}
},
isOnly:{
immediate: true
}
},
@@ -840,6 +847,7 @@ export default {
this.popperElm = this.picker.$el
this.picker.width = this.reference.getBoundingClientRect().width
this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange'
this.picker.isOnly = this.isOnly
this.picker.selectionMode = this.selectionMode
this.picker.unlinkPanels = this.unlinkPanels
this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false

View File

@@ -51,7 +51,11 @@
<el-input maxlength="128" show-word-limit v-model="editAsset.number" size="small"/>
</el-form-item>
<el-form-item :label="$t('asset.brandAndModel')" class="placeholder-emphasize" prop="brandAndModel">
<el-cascader
<div @click="judgeType">
<el-cascader
ref="cascader"
:clearable="true"
:disabled="judgeTypes"
v-model="editAsset.brandAndModel"
:placeholder="lockModelInputValue"
:options="options.brandAndModelOptions"
@@ -60,6 +64,7 @@
size="small"
style="width: 100%;"
></el-cascader>
</div>
</el-form-item>
<el-form-item :label="$t('asset.location')" prop="location" class="is-required">
<location-cascader v-if="!vmLock" ref="locationCascader" :dc-option="options.dcOptions" :default-model-u-size="1" @change="setLocationData"></location-cascader>
@@ -327,6 +332,7 @@ export default {
const vm = this
return {
assetConstants,
judgeTypes: true,
showAllTalonOption: false,
showAddressOption: true,
talonShowTow: true,
@@ -546,6 +552,14 @@ export default {
this.getFieldGroupData()
},
methods: {
judgeType () {
if (!this.editAsset.type.name) {
this.$message.error(this.$t('asset.assetBox.message.type'))
return false
} else {
this.judgeTypes = false
}
},
clickOutside () {
this.esc(false)
},
@@ -629,6 +643,10 @@ export default {
})
},
selectType (type) {
this.$refs.cascader.$refs.panel.clearCheckedNodes()
this.$refs.cascader.$refs.panel.activePath = []
this.editAsset.brandAndModel = ''
this.lockModelInputValue = ''
this.editAsset.type = { ...type }
this.editAsset.typeId = type.id ? type.id : ''
this.editAsset.authType = ''
@@ -639,6 +657,7 @@ export default {
this.editAsset.snmpCredentialId = ''
this.editAsset.authProtocolPort = ''
this.editAsset.pid = ''
this.getModelData()
},
addLabel ([groupId, metaId]) {
const label = this.options.metaOptions.find(m => m.id === metaId)
@@ -798,7 +817,7 @@ export default {
},
getModelData () {
return new Promise(resolve => {
this.$get('asset/model?pageSize=-1').then(response => {
this.$get('asset/model?pageSize=-1&typeIds=' + this.editAsset.typeId).then(response => {
if (response.code === 200) {
this.options.modelOptions = response.data.list
const titleSearchData = {}
@@ -810,6 +829,11 @@ export default {
}
})
this.options.brandAndModelOptions = Object.keys(titleSearchData).map(b => titleSearchData[b])
if (!this.editAsset.type.name) {
this.judgeTypes = true
} else {
this.judgeTypes = false
}
}
resolve()
})

View File

@@ -46,22 +46,32 @@
size="mini"
ref="calendar"
:format="timeFormatStrToDatePickFormat(timeFormatMain)"
@change="dateChange(whoChoose)"
v-model="searchTimeValue"
type="date"
:value-format="timeFormatStrToDatePickFormat(timeFormatMain)"
@change="dateChange"
:default-time="['00:00:00', '23:59:59']"
v-model="oldSearchTime"
:isOnly="true"
type="daterange"
popper-class="panel-time-picker-popper time-picker-popover__select-top"
align="right"
>
</my-date-picker>
<!-- @change="dateChange(whoChoose)"-->
<div class="content-title">{{$t('dashboard.panel.chartForm.valMapping.from')}}</div>
<div @click="myDatePickerShow('start')" tabindex="1" class="content-input">
<el-input v-model="searchTime[0]" @change="dateChange('start',searchTime[0])"> </el-input>
<div tabindex="1" class="content-input" :class="oldSearchTimeError[0] ? 'input-error' : ''">
<el-input @focus="searchTimeValue = oldSearchTime[0]" v-model="oldSearchTime[0]" @change="dateInputChange('start',oldSearchTime[0])" size="mini"> </el-input>
<div @click="myDatePickerShow()" class="nz-icon-box">
<i class="nz-icon nz-icon-date"/>
</div>
<div class="input-hint">{{inputError}}</div>
</div>
<div class="content-title">{{$t('dashboard.panel.chartForm.valMapping.to')}}</div>
<div @click="myDatePickerShow('end')" tabindex="2" class="content-input">
<el-input v-model="searchTime[1]" @change="dateChange('end',searchTime[1])"> </el-input>
<div tabindex="2" class="content-input" :class="oldSearchTimeError[1] ? 'input-error' : ''">
<el-input @focus="searchTimeValue = oldSearchTime[1]" v-model="oldSearchTime[1]" @change="dateInputChange('end',oldSearchTime[1])" size="mini"> </el-input>
<div @click="myDatePickerShow()" class="nz-icon-box">
<i class="nz-icon nz-icon-date"/>
</div>
<div class="input-hint">{{$t('date.formatError')}}</div>
</div>
<div>
<el-button
@@ -132,6 +142,7 @@
<script>
import bus from '@/libs/bus'
import moment from 'moment-timezone'
export default {
name: 'timePicker',
@@ -159,6 +170,13 @@ export default {
bus.timeFormate(bus.getOffsetTimezoneData(-1)),
bus.timeFormate(bus.getOffsetTimezoneData())
],
oldSearchTime: [bus.timeFormate(bus.getOffsetTimezoneData(-1)),
bus.timeFormate(bus.getOffsetTimezoneData())],
oldSearchTimeError: {
0: false,
1: false
},
inputError: this.$t('date.formatError'),
showTime: {
id: 4,
text: this.$t('dashboard.panel.lastOneHour')
@@ -253,6 +271,9 @@ export default {
this.getItem()
this.getUtcStr()
this.getRangeHistoryArr()
const timeTemp = this.$loadsh.cloneDeep(this.searchTime)
this.oldSearchTime[0] = timeTemp[0]
this.oldSearchTime[1] = timeTemp[1]
},
methods: {
changeDropdownFlag () {
@@ -268,8 +289,8 @@ export default {
this.utc = localStorage.getItem('timezoneOffset')
},
myDatePickerShow (item) {
this.whoChoose = item
this.isCustom = true
// this.whoChoose = item
// this.isCustom = true
this.$refs.calendar.focus()
this.$refs.calendar.pickerVisible = true
if (document.getElementById('viewGraphDialog')) {
@@ -308,9 +329,13 @@ export default {
this.utcStr = str + this.utc
},
timeRange (item) {
if (this.oldSearchTimeError[0] || this.oldSearchTimeError[1]) {
return
}
this.searchTime = this.$loadsh.cloneDeep(this.oldSearchTime)
this.showTime = this.nowTimeType = {
id: 0,
text: this.$t('dashboard.panel.customTimeRange'),
text: this.searchTime[0] + ' ' + this.$t('dashboard.panel.to') + ' ' + this.searchTime[1],
value: -1
}
this.isCustom = true
@@ -329,49 +354,42 @@ export default {
this.$emit('change', this.searchTime)
},
showDropdown () {
const timeTemp = this.$loadsh.cloneDeep(this.searchTime)
this.oldSearchTime[0] = timeTemp[0]
this.oldSearchTime[1] = timeTemp[1]
this.oldSearchTimeError[0] = false
this.oldSearchTimeError[1] = false
this.dropdownFlag = !this.dropdownFlag
},
dateChange (type, v) {
dateInputChange (type, v) {
if (type == 'start') {
if (!v) {
const startTime = bus.timeFormate(this.searchTimeValue).trim().split(' ')[0] + ' '
this.$set(this.searchTime, 0, startTime)
const dateValidate = moment(this.oldSearchTime[0], this.timeFormatMain).isValid()
if (!dateValidate) {
this.inputError = this.$t('date.formatError')
this.oldSearchTimeError[0] = true
} else {
const str = v.trim().split(' ')[1]
const reg = /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/
if (reg.test(str)) {
const startTime = bus.timeFormate(v)
this.$set(this.searchTime, 0, startTime)
} else {
this.$set(this.searchTime, 0, '')
}
this.oldSearchTimeError[0] = false
this.oldSearchTime[0] = bus.timeFormate(this.oldSearchTime[0])
}
} else if (type == 'end') {
if (!v) {
const endTime = bus.timeFormate(this.searchTimeValue).trim().split(' ')[0] + ' '
this.$set(this.searchTime, 1, endTime)
const dateValidate = moment(this.oldSearchTime[1], this.timeFormatMain).isValid()
if (!dateValidate) {
this.oldSearchTimeError[1] = true
} else {
const str = v.trim().split(' ')[1]
const reg = /^([01]\d|2[0-3]):[0-5]\d:[0-5]\d$/
if (reg.test(str)) {
const endTime = bus.timeFormate(v)
this.$set(this.searchTime, 1, endTime)
} else {
this.$set(this.searchTime, 1, '')
}
this.oldSearchTimeError[1] = false
// this.$set(this.oldSearchTime, 1, bus.timeFormate(this.oldSearchTime[1]))
this.oldSearchTime[1] = bus.timeFormate(this.oldSearchTime[1])
}
}
this.searchTime[2] = ''
this.$set(this.showTime, 'id', 0)
this.$set(
this.showTime,
'text',
this.searchTime[0] +
' ' +
this.$t('dashboard.panel.to') +
' ' +
this.searchTime[1]
)
console.log(moment(this.oldSearchTime[0], this.timeFormatMain).isValid(), moment(this.oldSearchTime[1], this.timeFormatMain).isValid(), !moment(this.oldSearchTimeError[0]).isBefore(this.oldSearchTime[1]))
if (moment(this.oldSearchTime[0], this.timeFormatMain).isValid() && moment(this.oldSearchTime[1], this.timeFormatMain).isValid() && !moment(this.oldSearchTimeError[0]).isBefore(this.oldSearchTime[1])) {
this.oldSearchTimeError[0] = true
this.inputError = this.$t('date.fromGreaterTo')
}
},
dateChange () {
this.oldSearchTimeError[0] = false
this.oldSearchTimeError[1] = false
},
setCustomTime (timeGroup, timeRange) {
if (timeGroup) {
@@ -560,6 +578,13 @@ export default {
}
}
}
},
sign (n) {
if (n) {
this.rangeHistory = localStorage.getItem('date-range-history' + this.sign)
? JSON.parse(localStorage.getItem('date-range-history' + this.sign))
: []
}
}
}
}

View File

@@ -120,15 +120,15 @@ export const baseTheme = EditorView.theme({
lineHeight: '1',
marginRight: '10px',
verticalAlign: 'top',
'&:after': { content: "'\\ea88'" },
fontFamily: 'codicon',
'&:after': { content: "'\\e76f'" },
fontFamily: 'nz-icon',
paddingRight: '0',
opacity: '1',
color: '#007acc',
},
'.cm-completionIcon-function, .cm-completionIcon-method': {
'&:after': { content: "'\\ea8c'" },
'&:after': { content: "'\\e76f'" },
color: '#652d90',
},
'.cm-completionIcon-class': {
@@ -141,7 +141,7 @@ export const baseTheme = EditorView.theme({
'&:after': { content: "'𝑥'" },
},
'.cm-completionIcon-constant': {
'&:after': { content: "'\\eb5f'" },
'&:after': { content: "'\\e76f'" },
color: '#007acc',
},
'.cm-completionIcon-type': {
@@ -154,14 +154,14 @@ export const baseTheme = EditorView.theme({
'&:after': { content: "'□'" },
},
'.cm-completionIcon-keyword': {
'&:after': { content: "'\\eb62'" },
'&:after': { content: "'\\e76f'" },
color: '#616161',
},
'.cm-completionIcon-namespace': {
'&:after': { content: "'▢'" },
},
'.cm-completionIcon-text': {
'&:after': { content: "'\\ea95'" },
'&:after': { content: "'\\e76f'" },
color: '#ee9d28',
},
});

View File

@@ -76,15 +76,18 @@
class="input-box"
@click="dropDownVisible = false"
>
<div :id="'editor'+index"
class="not-fixed-height no-resize no-close"
<div
:id="'editor'+index"
v-if="type !== 'log'"
class="not-fixed-height no-resize no-close"
>
</div>
<!-- <div id='editor'
class="not-fixed-height no-resize no-close"
>
</div> -->
<!-- <el-input
<el-input
v-if="type == 'log'"
:id="inputId"
v-model="expressionList[index]"
:autosize="{ minRows: 1, maxRows: 6 }"
@@ -93,7 +96,7 @@
@input="metricKeyDown"
@keyup.enter.native="expressionChange"
ref="elInput"
></el-input> -->
></el-input>
<div v-if="errorMsg" class="append-msg error">
<span>{{ errorMsg }}</span>
@@ -231,8 +234,10 @@
@click="dropDownVisible = false"
v-if="plugins.indexOf('metric-input') > -1"
>
<div :id="'editor'+index"
class="not-fixed-height no-resize no-close"
<div
:id="'editor'+index"
v-if="type !== 'log'"
class="not-fixed-height no-resize no-close"
>
</div>
<!-- <div id="editor"
@@ -240,8 +245,9 @@
ref="elInput"
></div> -->
<!-- <el-input
<el-input
v-model="expressionList[index]"
v-if="type === 'log'"
@input="metricKeyDown"
type="textarea"
:maxlength="styleType === 3 ? 512 : 4096"
@@ -249,7 +255,7 @@
:autosize="{ minRows: 1, maxRows: 6 }"
class="not-fixed-height no-resize"
ref="elInput"
></el-input> -->
></el-input>
<div class="append-msg error" v-if="errorMsg">
<span>{{ errorMsg }}</span>
</div>
@@ -420,6 +426,7 @@ import { lintKeymap } from '@codemirror/lint'
import { baseTheme, promqlHighlighter } from './CMTheme.tsx'
import { closeBrackets, closeBracketsKeymap } from '@codemirror/closebrackets'
import { autocompletion, completionKeymap, CompletionContext, CompletionResult } from '@codemirror/autocomplete'
import { newCompleteStrategy } from 'codemirror-promql/dist/esm/complete'
export default {
name: 'promqlInput',
@@ -459,7 +466,7 @@ export default {
},
data () {
return {
oldcCodeLength:'',
oldcCodeLength: '',
newView: null,
codeMirrorValue: [],
dropDownVisible: false,
@@ -527,8 +534,7 @@ export default {
}
},
mounted () {
this.initCodeMirror()
if (!this.fromFatherData && this.type !== 'logs') {
if (!this.fromFatherData && this.type !== 'log') {
this.queryMetrics()
}
},
@@ -537,22 +543,48 @@ export default {
const self = this
const promQL = new PromQLExtension().setComplete(
{
remote: {
url: 'http://192.168.40.42:8080/prom',
fetchFn: this.fetchFn,
cache: {
initialMetricList: [
'ALERTS',
'ALERTS_FOR_STATE',
'alertmanager_alerts',
'alertmanager_alerts_invalid_total',
'alertmanager_alerts_received_total',
'nz-agent'
]
completeStrategy: query(newCompleteStrategy({
remote: {
url: 'http://192.168.40.42:8080/prom',
fetchFn: this.fetchFn
}
}
}))
}
)
function query (CompleteStrategy) {
const obj = {}
obj.complete = CompleteStrategy
obj.queryHistory = []
obj.promQL = function (context) {
return Promise.resolve(this.complete.promQL(context)).then((res) => {
const { state, pos } = context
const tree = syntaxTree(state).resolve(pos, -1)
const start = res != null ? res.from : tree.from
if (start !== 0) {
return res
}
const historyItems = {
from: start,
to: pos,
options: this.queryHistory.map((q) => ({
label: q.length < 80 ? q : q.slice(0, 76).concat('...'),
detail: 'past query',
apply: q,
info: q.length < 80 ? undefined : q
})),
span: /^[a-zA-Z0-9_:]+$/
}
if (res !== null) {
historyItems.options = historyItems.options.concat(res.options)
}
// console.log(historyItems)
return historyItems
})
}
return obj
}
const dynamicConfigCompartment = new Compartment()
const dynamicConfig = [
promqlHighlighter,
@@ -622,92 +654,63 @@ export default {
const view = new EditorView({
state: EditorViewstate,
// parent: document.getElementById('editor')
parent: document.getElementById('editor'+self.index)
parent: document.getElementById('editor' + self.index)
})
self.newView = view
} else {
console.log('viewIsOk')
// console.log('viewIsOk')
// const { from} = self.newView.state.selection.ranges[0]
// const to = self.codeMirrorValue.length
const to = self.oldcCodeLength
const from = self.oldcCodeLength
console.log(from,to);
// console.log(from, to)
self.newView.dispatch(
self.newView.state.update({
effects: dynamicConfigCompartment.reconfigure(dynamicConfig),
changes:{from,to,insert:self.codeMirrorValue[self.index]}
changes: { from, to, insert: self.codeMirrorValue[self.index] }
})
)
}
},
newChange (val) {
console.log('newchange', val)
if(val){
// console.log('newchange', val)
if (val) {
this.oldcCodeLength = val.length
console.log(this.oldcCodeLength);
// console.log(this.oldcCodeLength)
this.codeMirrorValue[this.index] = val
this.expressionList[this.index] = val
console.log(this.codeMirrorValue);
// console.log(this.codeMirrorValue)
this.metricKeyDown(val)
}else{
this.oldcCodeLength = 0;
} else {
this.oldcCodeLength = 0
this.codeMirrorValue[this.index] = ''
}
},
newDoc (val) {
console.log('doc', val)
},
getHint (val, params, b, c, d) {
if (params) {
console.log(val, params, b, c, d, 123123123)
console.log(JSON.stringify(params.body))
return this.sendAjax('', params)
} else {
return this.sendAjax('http://192.168.44.61:10091/api/v1/series', {})
}
// this.$post('api/v1/series')
// console.log('doc', val)
},
fetchFn (a, b) {
const params = {}
if (b) {
const form = new FormData()
console.log(b.body)
form.append('match[]', b.body.getAll('match[]'))
return this.$post(a, form)
} else {
return this.$get(a)
}
},
sendAjax (url, body) {
// 构造表单数据
return new Promise(resolve => {
const nowUrl = url
const formData = new FormData()
formData.append('username', 'johndoe')
formData.append('id', 123456)
// 创建xhr对象
const xhr = {
...new XMLHttpRequest(),
...body
}
// 设置xhr请求的超时时间
xhr.timeout = 3000
// 设置响应返回的数据格式
xhr.responseType = ''
// 创建一个 post 请求,采用异步
xhr.open('post', nowUrl, true)
xhr.setRequestHeader('Authorization', localStorage.getItem('nz-token'))
// 注册相关事件回调处理函数
xhr.onload = function (e) {
if (this.status == 200 || this.status == 304) {
// alert(this.responseText)
resolve(JSON.parse(this.responseText))
params['match[]'] = b.body.get('match[]')
params.start = b.body.get('start')
params.end = b.body.get('end')
a += '?match[]=' + b.body.get('match[]')
return fetch(a, {
...b,
// body: JSON.stringify(params),
redirect: 'follow',
headers: {
Authorization: localStorage.getItem('nz-token'),
'content-type': 'application/x-www-form-urlencoded'
}
})
}
return fetch(a, {
...b,
headers: {
Authorization: localStorage.getItem('nz-token')
}
xhr.onerror = function (e) { console.log(e) }
// 发送数据
xhr.send()
})
},
closeDropdown () {
@@ -792,7 +795,7 @@ export default {
this.cascaderValue = ''
},
metricChangeNew (value) {
console.log(value);
// console.log(value)
if (!value) return
this.insertText(value)
this.dropDownVisible = false
@@ -1063,7 +1066,6 @@ export default {
// elInput.selectionEnd = startPos + insertTxt.length
this.expressionList[this.index] = insertTxt
this.codeMirrorValue[this.index] = insertTxt
console.log('inserttext', this.codeMirrorValue[this.index])
this.initCodeMirror()
}
/* setMsg:function(){
@@ -1088,13 +1090,12 @@ export default {
}
}
},
expressionList:{
expressionList: {
deep: true,
immediate: true,
handler (n, o) {
console.log(n,n[this.index]);
this.codeMirrorValue[this.index] = n[this.index];
// console.log(n, n[this.index])
this.codeMirrorValue[this.index] = n[this.index]
}
},
@@ -1107,6 +1108,17 @@ export default {
// }
// }
// }
type: {
deep: true,
immediate: true,
handler (n) {
if (n !== 'log') {
this.$nextTick(() => {
this.initCodeMirror()
})
}
}
}
}
}
</script>

View File

@@ -40,7 +40,7 @@
<!-- </el-input>-->
<!-- </div>-->
<pick-time id="panel" ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false" class="margin-r-10" :sign="panelId"></pick-time>
<pick-time id="panel" ref="pickTime" v-model="searchTime" :refresh-data-func="dateChange" :use-chart-unit="false" class="margin-r-10" :sign="showPanel.id"></pick-time>
<button id="panel-add-chart" v-has="'main_add'" :title="$t('overall.createChart')" class="top-tool-btn margin-r-10"
type="button" @click="addChartBefore">

View File

@@ -143,6 +143,8 @@ router.beforeEach((to, from, next) => {
})
})
} else {
const theme = localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`) || 'light'
document.getElementsByTagName('body')[0].setAttribute('class', 'theme-' + theme)
resolve()
}
})

View File

@@ -1 +1,2 @@
{"baseUrl":"http://192.168.40.42:8080/", "version": "21.04"}
{"baseUrl":"/", "version": "21.04"}