Merge branch 'dev-3.2' of https://git.mesalab.cn/nezha/nezha-fronted into dev-3.3

# Conflicts:
#	nezha-fronted/src/components/common/bottomBox/tabs/alertMessageTabNew.vue
This commit is contained in:
zhangyu
2022-03-23 15:18:55 +08:00
17 changed files with 506 additions and 27 deletions

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="overview"> <div class="overview">
<div class="content-col-content"> <div class="content-col-content">
<div :id="'map' + (isFullscreen ? '-screen-' : '' ) + chartInfo.id " style="height: 100%; width: 100%" :style="theme=='light'? '': ' filter: invert(1) hue-rotate(0.5turn);opacity: 0.75;'"></div> <div :id="'map' + (isFullscreen ? '-screen-' : '' ) + chartInfo.id " style="height: 100%; width: 100%" :style="theme=='dark'? 'filter: invert(1) hue-rotate(0.5turn);opacity: 0.75;': ''"></div>
</div> </div>
<!--自定义地图鼠标悬浮提示dom避免被overflowhidden裁剪--> <!--自定义地图鼠标悬浮提示dom避免被overflowhidden裁剪-->
<div :style="{'left': `${tooltip.x}px`, 'top': `${tooltip.y}px`}" class="my-pane" :class="'my-pane-' + chartId"></div> <div :style="{'left': `${tooltip.x}px`, 'top': `${tooltip.y}px`}" class="my-pane" :class="'my-pane-' + chartId"></div>

View File

@@ -53,7 +53,7 @@ import { getMetricTypeValue } from '@/components/common/js/tools'
import chartDataFormat from '@/components/charts/chartDataFormat' import chartDataFormat from '@/components/charts/chartDataFormat'
import { randomcolor } from '@/components/common/js/radomcolor/randomcolor' import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
import { initColor } from '@/components/chart/chart/tools' import { initColor } from '@/components/chart/chart/tools'
import fontWidth from '@/components/chart/chart/options/fontWidth' // import fontWidth from '@/components/chart/chart/options/fontWidth'
export default { export default {
name: 'chart-stat', name: 'chart-stat',

View File

@@ -83,7 +83,7 @@ export default {
chartOption.yAxis.axisLabel.formatter = this.yAxisLabelFormatter(minValue, maxValue, copies, unit, decimals) chartOption.yAxis.axisLabel.formatter = this.yAxisLabelFormatter(minValue, maxValue, copies, unit, decimals)
chartOption.yAxis.minInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'min') chartOption.yAxis.minInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'min')
chartOption.yAxis.maxInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(chartOption.series.length / 5) chartOption.yAxis.maxInterval = chartDataFormat.Interval(maxValue, copies, unit.type, 'max') * Math.ceil(chartOption.series.length / 5)
if (unit.type = 'Time') { if (unit.type === 'Time') {
delete chartOption.yAxis.minInterval delete chartOption.yAxis.minInterval
delete chartOption.yAxis.maxInterval delete chartOption.yAxis.maxInterval
} }

View File

@@ -216,7 +216,7 @@ export default {
getMaxValue (dataArg, chartInfo) { getMaxValue (dataArg, chartInfo) {
let maxValue = 0 let maxValue = 0
let minValue = 0 let minValue = 0
if (chartInfo.unit && dataArg.length > 0) { if (dataArg.length > 0) {
maxValue = 0 maxValue = 0
minValue = 0 minValue = 0
for (let j = 0; j < dataArg.length; j++) { for (let j = 0; j < dataArg.length; j++) {

View File

@@ -14,6 +14,30 @@ const chartBarOption = {
}, },
xAxis: { xAxis: {
type: 'category', type: 'category',
animation: false,
showAllSymbol: false,
axisLabel: {
interval: '0',
showMaxLabel: false,
rotate: 0,
show: false,
fontSize: 10
// formatter: 动态生成
},
axisPointer: { // y轴上显示指针对应的值
show: false
},
splitLine: {
show: false,
lineStyle: {
color: '#d9d9d9',
opacity: 0.8,
width: 1
}
},
axisLine: {
show: false
},
axisTick: { axisTick: {
show: false show: false
} }

View File

@@ -17,6 +17,8 @@ const chartPieOption = {
type: 'pie', type: 'pie',
radius: '55%', radius: '55%',
center: ['50%', '50%'], center: ['50%', '50%'],
avoidLabelOverlap: false,
zlevel: 1,
data: [], data: [],
label: { label: {
show: true, show: true,

View File

@@ -1,5 +1,20 @@
const fontWidth = { const fontWidth = {
0: 10, // 字号大小 12 13 14 15
A: 7.5 0: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719 0.656 0.046
1: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
2: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
3: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
4: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
5: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
6: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
7: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
8: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719
9: { defaultWidth: 7.781, addWidth: 0.6485 }, // 7.781 8.422 9.078 9.719,
space: { defaultWidth: 7.781, addWidth: 0.938 },
A: 7.5,
other: 3,
fontHeight: 1.5, // 字体大一px 高度加1.5
defaultHeight: 18,
numMinus: 0.0015
} }
export default fontWidth export default fontWidth

View File

@@ -421,7 +421,7 @@ function timeFormat34 (value) {
return bus.timeFormate(parseInt(value), 'YYYY-MM-DD HH:mm:ss') return bus.timeFormate(parseInt(value), 'YYYY-MM-DD HH:mm:ss')
} }
function timeFormat35 (value) { function timeFormat35 (value) {
return bus.timeFormate(parseInt(value), 'MM/dd/yyyy h:mm:ss a') return bus.timeFormate(parseInt(value), 'MM/DD/yyyy h:mm:ss a')
} }
// unit转化配置信息 // unit转化配置信息
/* /*

View File

@@ -3,7 +3,7 @@
<!-- {{timestampStr(item.time, 'YYYY-MM-DD')}} {{item.P1+' '+item.P2+' '+item.P3}}--> <!-- {{timestampStr(item.time, 'YYYY-MM-DD')}} {{item.P1+' '+item.P2+' '+item.P3}}-->
<div v-for="item in alertDaysData" :key="item.time" :style="showPriority(item)" @mouseenter="tooltipHover(item,true, $event)" @mouseleave="tooltipHover(item,false, $event)"> <div v-for="item in alertDaysData" :key="item.time" :style="showPriority(item)" @mouseenter="tooltipHover(item,true, $event)" @mouseleave="tooltipHover(item,false, $event)">
<div v-if="item.tooltipShow" class="alert-days-info-tooltip" :style="{left: item.position.left + 'px',top:item.position.top + 'px'}"> <div v-if="item.tooltipShow" class="alert-days-info-tooltip" :style="{left: item.position.left + 'px',top:item.position.top + 'px'}">
<div class="tooltip-title severity-time">{{timestampStr(item.time, 'YYYY-MM-DD')}}</div> <div class="tooltip-title severity-time">{{timestampStr(item.time, dateFormatStr)}}</div>
<div v-for="(severity,index) in severityDataWeight" :key="index" class="severity-info"> <div v-for="(severity,index) in severityDataWeight" :key="index" class="severity-info">
<div class="severity-block" :style="{background: severity.color}"></div> <div class="severity-block" :style="{background: severity.color}"></div>
<div class="severity-name">{{severity.name}}</div> <div class="severity-name">{{severity.name}}</div>
@@ -24,7 +24,8 @@ export default {
return { return {
daysData: [], daysData: [],
severityData: this.$store.getters.severityData, severityData: this.$store.getters.severityData,
severityDataWeight: this.$store.getters.severityDataWeight severityDataWeight: this.$store.getters.severityDataWeight,
dateFormatStr: localStorage.getItem('nz-default-dateFormat') ? localStorage.getItem('nz-default-dateFormat') : 'YYYY-MM-DD'
} }
}, },
// watch: { // watch: {
@@ -35,6 +36,14 @@ export default {
// } // }
// } // }
// }, // },
created () {
const dateFormatStr = localStorage.getItem('nz-default-dateFormat')
if (dateFormatStr) {
this.dateFormatStr = dateFormatStr.split(' ')[0]
} else {
this.dateFormatStr = 'YYYY-MM-DD'
}
},
methods: { methods: {
showPriority (daysData) { showPriority (daysData) {
let style = {} let style = {}

View File

@@ -297,6 +297,7 @@ export default {
url = this.url url = this.url
} }
this.$delete(url + '?ids=' + row.id + '&state=' + this.state).then(response => { this.$delete(url + '?ids=' + row.id + '&state=' + this.state).then(response => {
this.$delete(url + '?ids=' + row.id + '&state=' + row.state).then(response => {
if (response.code === 200) { if (response.code === 200) {
self.delFlag = true self.delFlag = true
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
@@ -646,7 +647,7 @@ export default {
} }
chartInfo.elements[0].expression = this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '') chartInfo.elements[0].expression = this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '')
chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels))) chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
chartInfo.unit = this.currentMsg.unit chartInfo.unit = this.currentMsg.alertRule.unit
this.showFullscreen(true, chartInfo) this.showFullscreen(true, chartInfo)
} else if (this.currentMsg.alertRule.type === 2) { } else if (this.currentMsg.alertRule.type === 2) {
const chartInfo = lodash.cloneDeep(logData) const chartInfo = lodash.cloneDeep(logData)
@@ -660,7 +661,7 @@ export default {
} }
chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '')) chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, ''))
chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels))) chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
chartInfo.unit = this.currentMsg.unit chartInfo.unit = this.currentMsg.alertRule.unit
this.showFullscreen(true, chartInfo) this.showFullscreen(true, chartInfo)
} }
}, },

View File

@@ -421,8 +421,11 @@ export default {
this.closeRightBox(true) this.closeRightBox(true)
} else { } else {
this.$message.error(response.msg) this.$message.error(response.msg)
this.$store.dispatch('clearPanel')
} }
}) })
}).catch(() => {
this.$store.dispatch('clearPanel')
}) })
}, },
addGroupItem (groupId) { addGroupItem (groupId) {

View File

@@ -1,7 +1,212 @@
import moment from 'moment-timezone' import moment from 'moment-timezone'
import bus from '@/libs/bus' import bus from '@/libs/bus'
import { hostPlus, latlng, port, positiveInteger, uSize } from '@/components/common/js/validate'
import routerPathParams from '@/components/common/mixin/routerPathParams'
export default { export default {
// mixins: [routerPathParams],
data () {
return {
imageFormatErr: false,
basic: {
// alert_api: '',
asset_ping_interval: '300', // 检查周期单位s
language: 'en',
session_timeout: '30',
storage_local_retention: 15 * 24,
system_name: '',
system_logo: '',
current_site_url: '',
timezone: '',
date_format: 'YYYY-MM-DD HH:mm:ss',
theme: 'Light',
default_cabinet_usize: '',
query_max_series: '',
unsaved_change: 'on',
default_scrape_interval: '60',
default_scrape_timeout: '30',
snmp_trap_listen_port: 162,
lnglat: '',
map_center_config: { longitude: 116.39, latitude: 39.9, zoom: 4, minZoom: 1, maxZoom: 10 },
pin_policy: {}
},
basicCopy: null,
basicRules: {
system_name: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
language: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
// alert_api: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: host, trigger: 'blur' }],
asset_ping_interval: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
default_scrape_interval: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
session_timeout: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
default_scrape_timeout: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
storage_local_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }],
snmp_trap_listen_port: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: port, trigger: 'blur' }],
timezone: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
default_cabinet_usize: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }, { validator: uSize, trigger: 'blur' }],
query_max_series: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
lnglat: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: latlng, trigger: 'blur' }
]
},
timezoneOption: [],
email: {
email_enable: 'on',
email_host: '',
email_port: 25,
email_timeout: 10,
email_auth_account: '',
email_auth_password: '',
email_send_account: '',
email_test_account: '',
email_security_type: 'NONE'
},
monitor: {
// alert_api: '',
asset_ping_from: '',
asset_ping_interval: '',
default_scrape_interval: '',
default_scrape_timeout: '',
logs_query_range_default_limit: '',
logs_storage_retention: '',
logs_storage_s3_access_key: '',
logs_storage_s3_bucket: '',
logs_storage_s3_endpoint: '',
logs_storage_s3_secret_access_key: '',
logs_storage_type: '',
metrics_query_max_series: '',
metrics_storage_retention: '',
metrics_storage_s3_access_key: '',
metrics_storage_s3_bucket: '',
metrics_storage_s3_endpoint: '',
metrics_storage_s3_secret_access_key: '',
metrics_storage_type: '',
prometheus_federation_enabled: ''
},
monitorRules: {
// alert_api: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
asset_ping_from: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
asset_ping_interval: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
default_scrape_interval: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
default_scrape_timeout: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
logs_query_range_default_limit: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
logs_storage_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
logs_storage_type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
metrics_query_max_series: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
metrics_storage_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
metrics_storage_type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
prometheus_federation_enabled: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
},
emailCopy: null,
emailRules: {
email_host: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: hostPlus, trigger: 'blur' }
],
email_port: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ validator: port, trigger: 'blur' }
],
email_auth_account: [
// { required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ type: 'email', message: this.$t('validate.email'), trigger: 'blur' }
],
email_send_account: [{ type: 'email', message: this.$t('validate.email'), trigger: 'blur' }],
email_test_account: [{ type: 'email', message: this.$t('validate.email'), trigger: 'blur' }]
},
terminal: {
terminal_timeout: 30,
terminal_telnet_user_tip: 'ogin:',
terminal_telnet_pin_tip: 'assword:',
terminal_record_local_retention: 365
},
terminalCopy: null,
terminalRules: {
terminal_timeout: [{ validator: positiveInteger, trigger: 'blur' }],
terminal_record_local_retention: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }]
},
ldap: {
ldap_address: '',
ldap_dn: '',
ldap_password: '',
ldap_ou: '',
ldap_user_filter: '',
ldap_mapping: '',
ldap_enable: 'off',
ldap_timeout: ''
},
ldapCopy: null,
ldapRules: {
ldap_address: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
ldap_user_filter: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
ldap_mapping: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
ldap_timeout: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: positiveInteger, trigger: 'blur' }]
},
reset: {
type: [],
pin: ''
},
linkTemp: {
name: '', url: ''
},
link: [],
linkReserved: [],
linkRules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ max: 64, message: this.$t('config.system.link.nameMaxLength'), trigger: 'blur' }
],
url: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
// { type: 'url', message: this.$t('config.system.link.uriRequired'), trigger: 'blur' } /*检验网址是否正确*/
]
},
notificationRules: {
name: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ max: 64, message: this.$t('config.system.link.nameMaxLength'), trigger: 'blur' }
],
filePath: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' },
{ pattern: /^\/(.*\.*.+\/?)+$/, message: this.$t('config.system.notification.filePathReg') }
// { type: 'url', message: this.$t('config.system.link.uriRequired'), trigger: 'blur' } /*检验网址是否正确*/
]
},
resetRules: {
type: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }],
pin: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }]
},
resetOptions: [
{
label: this.$t('config.system.reset.metric'),
value: 'metric'
},
{
label: this.$t('config.system.reset.alert'),
value: 'alert'
},
{
label: this.$t('config.system.reset.sysConfig'),
value: 'sysconfig'
}
],
switchTab: 'basic',
languageList: [
{ value: 'en', label: 'English' },
{ value: 'zh', label: '简体中文' }
],
themeList: [
{ value: 'light', label: 'Light' },
{ value: 'dark', label: 'Dark' }
],
dateFormatList: [
{ value: 'DD/MM/YYYY HH:mm:ss', label: 'DD/MM/YYYY HH:mm:ss', time: '' },
{ value: 'MM/DD/YYYY HH:mm:ss', label: 'MM/DD/YYYY HH:mm:ss', time: '' },
{ value: 'YYYY-MM-DD HH:mm:ss', label: 'YYYY-MM-DD HH:mm:ss', time: '' }
],
basicTimer: 0
}
},
methods: { methods: {
queryTimezone: function () { queryTimezone: function () {
this.$get('/sys/timezone').then(response => { this.$get('/sys/timezone').then(response => {
@@ -105,6 +310,175 @@ export default {
e.time = bus.timeFormate(bus.computeTimezone(milli), e.label) e.time = bus.timeFormate(bus.computeTimezone(milli), e.label)
} }
}) })
},
testSetInfo: function (type, formName) {
if (this.prevent_opt.save) { return } ;
this.prevent_opt.save = true
this.$refs[formName].validate((valid) => {
if (valid) {
const param = Object.assign({}, this[type])
param[type + '_test'] = true
const postParam = Object.assign({}, param)
this.$put('/sys/config/' + type, postParam).then(response => {
this.prevent_opt.save = false
if (response.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.testSuccess') })
} else {
this.$message.error(response.msg)
}
})
} else {
this.prevent_opt.save = false
return false
}
})
},
jumpTo (data, id) {
bus.$emit('menu-change', data)
this.$router.push({
path: '/' + data,
query: {
t: +new Date()
}
})
},
switchChange: function (formName) {
const $temp = this
$temp.$refs[formName].clearValidate()
setTimeout(() => {
$temp.$refs[formName].validate()
}, 100)
},
resetForm (formName, type) {
this.$refs[formName].resetFields()
this[type] = Object.assign({}, this[type + 'Copy'])
},
selectTab: function (tab) {
this.querySetInfo(tab.name)
},
lnglatChange (lnglat, zoom) {
const lnglatData = lnglat.split('.')
this.basic.map_center_config.longitude = lnglatData[0]
this.basic.map_center_config.latitude = lnglatData[1]
this.basic.map_center_config.zoom = zoom
this.basic.lnglat = lnglat
},
// link 移动
change: function (evt) {
// console.log(evt)
},
// start ,end ,add,update, sort, remove 得到的都差不多
start: function (evt) {
// console.log(evt)
},
notificationEnd: function (evt) {
const length = this.notification.length
if (evt.newIndex == evt.oldIndex) { // 如果没有移动返回
return
}
const parmas = {
id: this.notification[evt.newIndex].id,
prev: 0,
next: -1
}
if (evt.newIndex == length - 1) {
parmas.prev = this.notification[evt.newIndex - 1].id
} else if (evt.newIndex == 0) {
parmas.next = this.notification[evt.newIndex + 1].id
} else {
parmas.prev = this.notification[evt.newIndex - 1].id
parmas.next = this.notification[evt.newIndex + 1].id
}
this.$put('/alert/script/modify', parmas).then((response) => {
// this.$store.commit('setLinkData',this.link);
})
},
end: function (evt) {
const length = this.link.length
if (evt.newIndex == evt.oldIndex) { // 如果没有移动返回
return
}
const parmas = {
id: this.link[evt.newIndex].id,
prev: 0,
next: -1
}
if (evt.newIndex == length - 1) {
parmas.prev = this.link[evt.newIndex - 1].id
} else if (evt.newIndex == 0) {
parmas.next = this.link[evt.newIndex + 1].id
} else {
parmas.prev = this.link[evt.newIndex - 1].id
parmas.next = this.link[evt.newIndex + 1].id
}
this.$put('/link/modify', parmas).then((response) => {
this.$store.commit('setLinkData', this.link)
})
},
handleLogoChange (file, fileList) {
const imageTypes = ['image/jpeg', 'image/jpg', 'image/png']
const isImage = imageTypes.some(t => file.raw.type === t)
const isLt2M = file.raw.size / 1024 / 1024 < 2
this.imageFormatErr = (!isImage || !isLt2M)
if (isImage && isLt2M) {
const self = this
this.fileToBase64(file.raw).then(res => {
self.basic.system_logo = res
})
}
},
fileToBase64: function (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)// 转化二进制流,异步方法
let base64Str = ''
reader.onload = function () { // 完成后this.result为二进制流;
base64Str = this.result
resolve(base64Str)
}
})
},
timezoneOptionHandler: function (offset) {
const offsetHour = (offset / 1000 / 60 / 60).toFixed(0)
const offsetMinute = offset % (1000 * 60 * 60) / (1000 * 60)
const hour = offsetHour > 0 ? (offsetHour < 9 ? '+0' + offsetHour : '+' + offsetHour) : (offsetHour == 0 ? (offsetMinute == 0 ? '' : '+00') : (offsetHour > -10 ? '-0' + Math.abs(offsetHour) : offsetHour))
const minute = offsetHour == 0 && offsetMinute == 0 ? '' : (offsetMinute == 0 ? ':00' : (Math.abs(offsetMinute) > 9 ? ':' + Math.abs(offsetMinute) : ':0' + Math.abs(offsetMinute)))
return 'UTC' + hour + minute
},
resetSys () {
if (this.prevent_opt.save) { return } ;
this.prevent_opt.save = true
const resetParams = {
type: this.reset.type,
pin: this.reset.pin
}
if (resetParams.type && resetParams.pin) {
this.$confirm(this.$t('tip.resetPrompt'), {
confirmButtonText: this.$t('tip.yes'),
cancelButtonText: this.$t('tip.no'),
type: 'warning'
}).then(() => {
this.$put('/sys/config/reset', resetParams).then(response => {
if (response.code == 200) {
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.resetSuccess') })
this.reset.type = ''
this.reset.pin = ''
} else {
this.$message.error(response.msg)
}
this.prevent_opt.save = false
})
})
} else {
this.prevent_opt.save = false
return false
}
} }
} }
} }

View File

@@ -9,7 +9,6 @@
<el-dropdown-menu></el-dropdown-menu> <el-dropdown-menu></el-dropdown-menu>
<div id="header-open-global-search" @click="openGlobalSearch"> <div id="header-open-global-search" @click="openGlobalSearch">
<div class="header-menu__item"><i class="nz-icon nz-icon-search"></i></div> <div class="header-menu__item"><i class="nz-icon nz-icon-search"></i></div>
<span v-show="$store.state.consoleCount>0" class="right-tip">{{$store.state.consoleCount<=10?$store.state.consoleCount:'10+'}}</span>
</div> </div>
</el-dropdown> </el-dropdown>
<el-dropdown trigger="click"> <el-dropdown trigger="click">
@@ -67,6 +66,9 @@
</el-dropdown> </el-dropdown>
</div> </div>
<guide :show-dialog="showGuide" @dialogClosed="dialogClosed" @close="showGuide = false"></guide> <guide :show-dialog="showGuide" @dialogClosed="dialogClosed" @close="showGuide = false"></guide>
<!-- <span v-for="item in fontData" :key="item">-->
<!-- <span class="temp-dom" :class="`temp-dom&#45;&#45;${fontSzie}`" v-for="fontSzie in [12,13,14,15]" :key="fontSzie">{{item}}</span>-->
<!-- </span>-->
</div> </div>
</template> </template>
@@ -117,7 +119,8 @@ export default {
permission: 'header_add_rule' permission: 'header_add_rule'
} }
], ],
showGuide: false showGuide: false,
// fontData: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ' ', '@', '$', '-']
} }
}, },
methods: { methods: {
@@ -193,11 +196,17 @@ export default {
}, },
testUser () { testUser () {
if (this.username != localStorage.getItem('nz-username')) { if (this.username != localStorage.getItem('nz-username')) {
window.location.reload() this.$router.go(0)
} }
} }
}, },
mounted () { mounted () {
// for (let i = 65; i < 91; i++) {
// this.fontData.push(String.fromCharCode(i))
// }
// for (let i = 97; i < 123; i++) {
// this.fontData.push(String.fromCharCode(i))
// }
this.$i18n.locale = this.language this.$i18n.locale = this.language
if (localStorage.getItem('nz-token')) { if (localStorage.getItem('nz-token')) {
this.initEvent() this.initEvent()

View File

@@ -526,15 +526,39 @@ export default {
cancelButtonText: this.$t('tip.no'), cancelButtonText: this.$t('tip.no'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$delete(this.url + '?ids=' + this.batchDeleteObjs.map(m => m.id).join(',') + '&state=' + this.state).then(response => { const arrState = []
if (response.code === 200) { const promiseArr = []
this.batchDeleteObjs.forEach(item => {
if (arrState.indexOf(item.state) === -1) {
arrState.push(item.state)
}
})
arrState.forEach(state => {
const batchDeleteArr = this.batchDeleteObjs.filter(m => m.state === state)
promiseArr.push(this.$delete(this.url + '?ids=' + batchDeleteArr.map(m => m.id).join(',') + '&state=' + state))
})
Promise.all(promiseArr)
.then(res => {
let error = ''
let flag = false
for (let i = 0; i < res.length; i++) {
if (res[i].code !== 200 && !flag) {
error = res[i].msg
flag = true
}
}
if (!flag) {
this.delFlag = true this.delFlag = true
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
this.getTableData() this.getTableData()
} else { } else {
this.$message.error(response.msg) this.$message.error(error)
} }
}) })
.catch(response => {
console.log(response)
this.$message.error(response.msg)
})
}) })
}, },
del (row) { del (row) {
@@ -543,7 +567,7 @@ export default {
cancelButtonText: this.$t('tip.no'), cancelButtonText: this.$t('tip.no'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$delete(this.url + '?ids=' + row.id + '&state=' + this.state).then(response => { this.$delete(this.url + '?ids=' + row.id + '&state=' + row.state).then(response => {
if (response.code === 200) { if (response.code === 200) {
this.delFlag = true this.delFlag = true
this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') })
@@ -595,7 +619,8 @@ export default {
} }
chartInfo.elements[0].expression = this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '') chartInfo.elements[0].expression = this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '')
chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels))) chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
chartInfo.unit = this.currentMsg.unit chartInfo.unit = this.currentMsg.alertRule.unit
console.log(chartInfo.unit)
this.showFullscreen(true, chartInfo) this.showFullscreen(true, chartInfo)
} else if (this.currentMsg.alertRule.type === 2) { } else if (this.currentMsg.alertRule.type === 2) {
const chartInfo = lodash.cloneDeep(logData) const chartInfo = lodash.cloneDeep(logData)
@@ -609,7 +634,7 @@ export default {
} }
chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '')) chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, ''))
chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels))) chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
chartInfo.unit = this.currentMsg.unit chartInfo.unit = this.currentMsg.alertRule.unit
this.showFullscreen(true, chartInfo) this.showFullscreen(true, chartInfo)
} }
}, },

View File

@@ -343,8 +343,11 @@ export default {
this.getTableData(true) this.getTableData(true)
} else { } else {
this.$message.error(response.msg) this.$message.error(response.msg)
this.$store.dispatch('clearPanel')
} }
}) })
}).catch(() => {
this.$store.dispatch('clearPanel')
}) })
}, },
edit (u) { edit (u) {
@@ -512,6 +515,7 @@ export default {
// this.getTableData(); //删除相关图表后,刷新面板数据 // this.getTableData(); //删除相关图表后,刷新面板数据
} else { } else {
this.$message.error(response.msg) this.$message.error(response.msg)
this.$store.dispatch('clearPanel')
} }
}) })
}).catch(() => { }).catch(() => {

View File

@@ -11,7 +11,10 @@ Vue.use(VueResource)
const loginWhiteList = ['/setup', '/sys/license/upload', '/sys/license/state', '/sys/appearance'] // 免登陆白名单 const loginWhiteList = ['/setup', '/sys/license/upload', '/sys/license/state', '/sys/appearance'] // 免登陆白名单
const permissionWhiteList = ['/profile', '/menu', ...loginWhiteList] // 权限白名单 const permissionWhiteList = ['/profile', '/menu', ...loginWhiteList] // 权限白名单
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
if (store.getters.getNowPath !== to.path) {
requestsArr.forEach(xhr => xhr.cancel()) requestsArr.forEach(xhr => xhr.cancel())
}
store.commit('setNowPath', to.path)
const configUrl = 'static/config.json?Timestamp=' + new Date().getTime() const configUrl = 'static/config.json?Timestamp=' + new Date().getTime()
if (to.path === '/login') { // 拦截登录页面,现货区外观设置 再系统初始化检查 if (to.path === '/login') { // 拦截登录页面,现货区外观设置 再系统初始化检查
Vue.http.get(configUrl).then(config => { Vue.http.get(configUrl).then(config => {
@@ -81,7 +84,7 @@ router.beforeEach((to, from, next) => {
}) })
} else { } else {
localStorage.setItem('nz-token', '') localStorage.setItem('nz-token', '')
next({}) next()
} }
}) })
} else { } else {
@@ -165,6 +168,9 @@ router.beforeEach((to, from, next) => {
} }
} }
}) })
router.afterEach((to, from) => {
// store.commit('setNowPath', '')
})
// menuList中是否包含route权限 // menuList中是否包含route权限
export function hasMenu (menuList, route) { export function hasMenu (menuList, route) {

View File

@@ -43,7 +43,8 @@ const store = new Vuex.Store({
timeFormatMain: localStorage.getItem('nz-default-dateFormat') || 'YYYY-MM-DD HH:mm:ss', timeFormatMain: localStorage.getItem('nz-default-dateFormat') || 'YYYY-MM-DD HH:mm:ss',
globalShow: false, globalShow: false,
globalSearchId: '', globalSearchId: '',
isRouteLive: true isRouteLive: true,
nowPath: ''
}, },
getters: { getters: {
getGlobalSearchId (state) { getGlobalSearchId (state) {
@@ -94,6 +95,9 @@ const store = new Vuex.Store({
getIsRouteLive (state) { getIsRouteLive (state) {
return state.isRouteLive return state.isRouteLive
}, },
getNowPath (state) {
return state.nowPath
},
i18nIsReady (state) { i18nIsReady (state) {
return state.i18nReady return state.i18nReady
} }
@@ -197,6 +201,9 @@ const store = new Vuex.Store({
state.isRouteLive = true state.isRouteLive = true
}) })
}, },
setNowPath (state, path) {
state.nowPath = path
},
i18nReady (state, ready) { i18nReady (state, ready) {
state.i18nReady = ready state.i18nReady = ready
} }