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

# Conflicts:
#	nezha-fronted/src/components/chart/chart/chartGauge.vue
#	nezha-fronted/src/components/chart/chart/chartHexagonD3.vue
This commit is contained in:
zhangyu
2022-03-24 13:40:37 +08:00
29 changed files with 154 additions and 52 deletions

View File

@@ -263,6 +263,16 @@ export default {
chartChildrenData: false
}
},
watch: {
chartData: {
deep: true,
handler (n) {
if (n) {
this.chartChildrenData = false
}
}
}
},
computed: {
isNoData () {
return lodash.isEmpty(this.chartData) && ['text', 'url', 'clock'].indexOf(this.chartInfo.type) === -1

View File

@@ -78,9 +78,9 @@ export default {
bus.$emit('clear-asset-filter') // 清除leftMenu左侧菜单过滤条件
// if(this.$store.getters.getIdcArr.length===0){return}//如果不存在idc 则不跳转
}
if (data === 'project' || data === 'module' || data === 'endpoint') {
data = 'monitor/' + data
}
// if (data === 'project' || data === 'module' || data === 'endpoint') {
// data = data
// }
if (data === 'alertList') {
data = 'alertMessage'
}

View File

@@ -63,6 +63,7 @@ export default {
this.gaugeData = []
this.isInit = false
const decimals = this.chartInfo.param.decimals || 2
this.isNoData = true
return new Promise(resolve => {
let colorIndex = 0
originalDatas.forEach((originalData, expressionIndex) => {

View File

@@ -68,6 +68,7 @@ export default {
this.HexagonData = []
this.isInit = false
const decimals = this.chartInfo.param.decimals || 2
this.isNoData = true
return new Promise(resolve => {
let colorIndex = 0
originalDatas.forEach((originalData, expressionIndex) => {

View File

@@ -102,6 +102,7 @@ export default {
const decimals = this.chartInfo.param.decimals || 2
const s = lodash.cloneDeep(seriesTemplate)
s.data = []
this.isNoData = true
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
this.isNoData = false

View File

@@ -93,6 +93,7 @@ export default {
const decimals = this.chartInfo.param.decimals || 2
return new Promise(resolve => {
let colorIndex = 0
this.isNoData = true
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
this.isNoData = false

View File

@@ -28,6 +28,7 @@ import { randomcolor } from '@/components/common/js/radomcolor/randomcolor'
import { chartLegendPlacement } from '@/components/common/js/constants'
import { getChart, setChart } from '@/components/common/js/common'
import { initColor } from '@/components/chart/chart/tools'
import lodash from 'lodash'
export default {
name: 'chart-time-series', // x轴是时间的图包括折线、柱状、堆叠、散点
@@ -69,9 +70,14 @@ export default {
}
},
methods: {
initChart (chartOption = this.chartOption) {
initChart (chartOptions = this.chartOption) {
const chartOption = lodash.cloneDeep(chartOptions)
this.legends = []
this.series = chartOption.series = this.handleTimeSeries(this.chartInfo, chartOption.series[0], this.chartData) // 生成series和legends
if (!this.series.length) {
this.isNoData = true
this.$emit('chartIsNoData', this.isNoData)
}
if (this.isNoData) {
return
}
@@ -190,7 +196,7 @@ export default {
let flag = true
params.forEach((item, i) => {
const seriesName = item.seriesName.split('-')[0]
if (i === 0) {
if (i === 0 && item.seriesName.indexOf('Previous') === -1) {
const value = bus.computeTimezone(item.data[0] * 1000)
const tData = new Date(value)
str += '<div class="tooltip-title" style="margin-bottom: 5px">'

View File

@@ -100,6 +100,7 @@ export default {
const decimals = this.chartInfo.param.decimals || 2
const s = lodash.cloneDeep(seriesTemplate)
s.data = []
this.isNoData = true
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
this.isNoData = false

View File

@@ -65,9 +65,16 @@
</div>
<div class="basic-info-table-list">
<div class="basic-info-table-title">{{ $t('overall.alert') }}</div>
<div class="basic-info-table-value">
<i :class="chartDetail && chartDetail.alertNum > 0 ? 'red' : 'green'" class="nz-icon nz-icon-overview-alert"></i>&nbsp;
<span>{{chartDetail ? chartDetail.alertNum : 0}}</span>
<div class="basic-info-table-value" v-if="chartDetail">
<i :class="chartDetail.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">Alert message (active)</div>
<div class="severity-info" style='justify-content: space-between'>
<div class="severity-name">{{$t('overall.result.total')}}</div>
<div class="severity-value">{{chartDetail.alertNum}}</div>
</div>
</div>
<alertDaysInfo v-show="!trendLoading" :alertDaysData="alertDaysData"/>
</div>
</div>
<div class="basic-info-table-list">
@@ -108,9 +115,16 @@
</div>
<div class="basic-info-table-list">
<div class="basic-info-table-title">{{$t('overall.alert')}}</div>
<div class="basic-info-table-value">
<i :class="chartDetail && chartDetail.alertNum > 0 ? 'red' : 'green'" class="nz-icon nz-icon-overview-alert"></i>&nbsp;
<span>{{chartDetail && chartDetail.alertNum ? chartDetail.alertNum : 0}}</span>
<div class="basic-info-table-value" v-if="chartDetail">
<i :class="chartDetail.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">Alert message (active)</div>
<div class="severity-info" style='justify-content: space-between'>
<div class="severity-name">{{$t('overall.result.total')}}</div>
<div class="severity-value">{{chartDetail.alertNum}}</div>
</div>
</div>
<alertDaysInfo v-show="!trendLoading" :alertDaysData="alertDaysData"/>
</div>
</div>
<div class="basic-info-table-list">
@@ -150,6 +164,7 @@
<script>
import bus from '@/libs/bus'
import trendMixin from '../common/alert/trendMixins'
export default {
name: 'chartDetail',
@@ -157,6 +172,7 @@ export default {
chartDetail: Object,
chartInfo: Object
},
mixins: [trendMixin],
watch: {
chartDetail: {
immediate: true,
@@ -174,16 +190,64 @@ export default {
})
}
}
},
'chartDetail.id': {
immediate: true,
deep: true,
handler (n) {
this.init()
}
}
},
data () {
return {
showBasicInfo: false
showBasicInfo: false,
chartDetailList: null
}
},
methods: {
hideElement () {
this.showBasicInfo = !this.showBasicInfo
},
init () {
this.loading = true
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'
}
if (this.chartInfo.type === 'assetInfo') {
params.assetId = this.chartDetail.id
} else if (this.chartInfo.type === 'endpointInfo') {
params.endpointId = this.chartDetail.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
})
})
})
}
}
}

View File

@@ -43,6 +43,7 @@ export default {
handleTimeSeries (chartInfo, seriesTemplate, originalDatas) {
const series = []
let colorIndex = 0
this.isNoData = true
originalDatas.forEach((originalData, expressionIndex) => {
originalData.forEach((data, dataIndex) => {
if (colorIndex >= 20 && !this.showAllData) {
@@ -266,6 +267,8 @@ export default {
if (!this.isInit && this.chartOption.color) {
this.colorList = this.colorList.slice(0, 20)
this.chartOption.color = this.chartOption.color.slice(0, 20)
}
if (!this.isInit) {
this.initChart(this.chartOption)
}
}

View File

@@ -120,11 +120,15 @@ export default {
})
axios.all(requestArr).then(res => {
this.logData = res.map(r => r.data)
if (this.logData[0]) {
if (this.logData[0].result.length > 0) {
this.endpointLoading = false
} else {
this.endpointLoading = true
}
} else {
this.endpointLoading = true
}
}).finally(() => {
this.loading = false
})

View File

@@ -147,6 +147,7 @@ export default {
fileShow: false,
fileContent: '',
recoveryCode: [],
userInfo: {},
bgImg: '' // 背景图
}
},
@@ -165,6 +166,7 @@ export default {
this.lang = res.data.user.lang || localStorage.getItem('nz-language')
this.$i18n.locale = this.lang
this.theme = res.data.user.theme
this.userInfo = res.data.user
// 获取可选语言
get('/sys/dict/all?type=lang').then(response => {
if (response.code === 200) {
@@ -221,8 +223,7 @@ export default {
localStorage.setItem('nz-prometheus-federation-enabled', res.data.prometheusFederationEnabled)
localStorage.setItem('nz-language', this.lang)
res.data.user = {
lang: this.lang,
theme: this.theme
...this.userInfo
}
this.loginSuccess(res)
} else {

View File

@@ -347,7 +347,10 @@ export default {
}
},
created () {
const path = this.$route.fullPath.match(/\/(\S*)\?/)[1]
let path = ''
if (this.$route.fullPath.match(/\/(\S*)\?/)) {
path = this.$route.fullPath.match(/\/(\S*)\?/)[1]
}
if (this.$route.query.orderBy && !this.isSubList) {
this.orderBy = this.$route.query.orderBy
}

View File

@@ -100,7 +100,7 @@ export default {
permissionCode: 'asset_view'
},
{
route: '/monitor/project',
route: '/project',
title: this.$t('overall.monitor'),
icon: 'nz-icon nz-icon-menu-project',
tip: this.$t('guide.monitorTip'),
@@ -238,7 +238,7 @@ export default {
}
this.$emit('close')
this.$router.push({
path: '/monitor/project',
path: '/project',
query: {
t: +new Date(),
add: 'project'
@@ -252,7 +252,7 @@ export default {
}
this.$emit('close')
this.$router.push({
path: '/monitor/module',
path: '/module',
query: {
t: +new Date(),
add: 'module'
@@ -266,7 +266,7 @@ export default {
}
this.$emit('close')
this.$router.push({
path: '/monitor/endpoint',
path: '/endpoint',
query: {
t: +new Date(),
add: 'endpoint'
@@ -280,7 +280,7 @@ export default {
}
this.$emit('close')
this.$router.push({
path: '/monitor/endpoint',
path: '/endpoint',
query: {
t: +new Date(),
importEndpoint: 'importEndpoint'

View File

@@ -21,6 +21,7 @@
<alert-message-table
ref="dataTable"
:api="url"
:orderByFa="orderBy"
:custom-table-title="tableTitle"
:height="mainTableHeight"
:now-time="nowTime"

View File

@@ -15,6 +15,7 @@
<template v-slot:default="slotProps">
<asset-table
ref="dataTable"
:orderByFa="orderBy"
v-loading="tools.loading"
:loading="tools.loading"
:api="url"

View File

@@ -16,6 +16,7 @@
<endpoint-table
style="height: calc(100% - 200px)"
ref="dataTable"
:orderByFa="orderBy"
v-loading="tools.loading"
:loading="tools.loading"
:api="url"

View File

@@ -298,9 +298,9 @@ export default {
}
},
getAssetData () {
this.$refs.transfer.startLoading()
this.$refs.transfer && this.$refs.transfer.startLoading()
this.$get('asset/asset', { ...this.transfer.searchLabel, ...this.transfer.pageObj }).then(response => {
this.$refs.transfer.endLoading()
this.$refs.transfer && this.$refs.transfer.endLoading()
if (response.code === 200) {
this.transfer.tableData = response.data.list
this.transfer.pageObj.total = response.data.total
@@ -309,13 +309,13 @@ export default {
})
},
getEndpointData () {
this.$refs.transfer.startLoading()
this.$refs.transfer && this.$refs.transfer.startLoading()
const idFilter = {}
if (this.from === fromRoute.asset) {
idFilter.assetIds = this.obj.varIds[0]
}
this.$get('monitor/endpoint', { ...this.transfer.searchLabel, ...this.transfer.pageObj, ...idFilter }).then(response => {
this.$refs.transfer.endLoading()
this.$refs.transfer && this.$refs.transfer.endLoading()
if (response.code === 200) {
this.transfer.tableData = response.data.list
this.transfer.pageObj.total = response.data.total

View File

@@ -664,7 +664,7 @@ export default {
})
},
getModuleData () {
this.$get('module', { pageNo: 1, pageSize: -1 }).then(response => {
this.$get('monitor/module', { pageNo: 1, pageSize: -1 }).then(response => {
if (response.code === 200) {
this.moduleSelect = response.data.list
this.moduleSelect.forEach((item, index) => {
@@ -1475,7 +1475,7 @@ export default {
if (this.$route.path === '/assetLabel') {
this.getGroupData()
}
if (this.$route.path === '/monitor/module') {
if (this.$route.path === '/module') {
this.getProjectData()
}
if (this.$route.path === '/alertRule') {

View File

@@ -161,7 +161,7 @@ export default {
},
jumpModule (row) {
localStorage.setItem('moduleProjectId', JSON.stringify([row.id, row.name]))
this.$router.push({ path: '/monitor/module' })
this.$router.push({ path: '/module' })
},
jumpAlertMessage (row) {
localStorage.setItem('alertMessageProjectId', row.id)
@@ -169,7 +169,7 @@ export default {
},
jumpEndpoint (row) {
localStorage.setItem('endpointProjectId', row.id)
this.$router.push({ path: '/monitor/endpoint' })
this.$router.push({ path: '/endpoint' })
}
},
computed: {

View File

@@ -50,7 +50,7 @@
</el-dropdown-menu>
</el-dropdown>
<el-dropdown trigger="click">
<div class="personal-avatar"><span>{{name.substr(0, 1)}}</span>&nbsp;<i class="nz-icon nz-icon-arrow-down"></i></div>
<div class="personal-avatar"><span>{{name ? name.substr(0, 1) : ''}}</span>&nbsp;<i class="nz-icon nz-icon-arrow-down"></i></div>
<el-dropdown-menu slot="dropdown" class="right-public-box-select-top right-public-box-dropdown-top" style="width: 142px; line-height: 36px;">
<div class="personal-dropdown">
<div class="personal-dropdown__username">{{name}}</div>
@@ -83,9 +83,9 @@ export default {
},
data () {
return {
username: localStorage.getItem('nz-username'),
name: localStorage.getItem('nz-user-name'),
language: localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en',
username: '',
name: '',
language: 'en',
// 顶部菜单相关
createMenu: [ // 新增按钮内容
{
@@ -119,7 +119,7 @@ export default {
permission: 'header_add_rule'
}
],
showGuide: false,
showGuide: false
// fontData: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ' ', '@', '$', '-']
}
},
@@ -212,6 +212,9 @@ export default {
this.initEvent()
this.getLinkData()
}
this.name = localStorage.getItem('nz-username')
this.username = localStorage.getItem('nz-username')
this.language = localStorage.getItem('nz-language') ? localStorage.getItem('nz-language') : 'en'
window.addEventListener('visibilitychange', this.testUser)
},
computed: {

View File

@@ -556,7 +556,6 @@ export default {
}
})
.catch(response => {
console.log(response)
this.$message.error(response.msg)
})
})
@@ -620,7 +619,6 @@ export default {
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.unit = this.currentMsg.alertRule.unit
console.log(chartInfo.unit)
this.showFullscreen(true, chartInfo)
} else if (this.currentMsg.alertRule.type === 2) {
const chartInfo = lodash.cloneDeep(logData)

View File

@@ -444,7 +444,7 @@ export default {
this.tableData = this.filterShowData(this.storedTableData, this.pageObj)
},
filterShowData (source, pageObj) {
return source.slice((pageObj.pageNo - 1) * pageObj.pageSize, pageObj.pageNo * pageObj.pageSize)
if (source) return source.slice((pageObj.pageNo - 1) * pageObj.pageSize, pageObj.pageNo * pageObj.pageSize)
},
chartUnitChange (unit) {
this.chartUnit = unit

View File

@@ -26,7 +26,7 @@
</div>
<div class="log-operation">
<span class="operation-label">{{$t('overall.limit')}}:</span>
<el-select v-model="limit" size="small" style="width: 100px;" popper-class="right-box-select-top ">
<el-select v-model="limit" size="small" style="width: 100px;" popper-class="right-box-select-top right-public-box-dropdown-top">
<el-option v-for="option in limitOptions" :key="option" :value="option"></el-option>
</el-select>
</div>

View File

@@ -989,9 +989,9 @@ export default {
bus.$emit('clear-asset-filter') // 清除leftMenu左侧菜单过滤条件
// if(this.$store.getters.getIdcArr.length===0){return}//如果不存在idc 则不跳转
}
if (data === 'project' || data === 'module' || data === 'endpoint') {
data = 'monitor/' + data
}
// if (data === 'project' || data === 'module' || data === 'endpoint') {
// data = 'monitor/' + data
// }
if (data === 'alertList') {
data = 'alertMessage'
}

View File

@@ -596,7 +596,7 @@ export default {
}
this.$set(this.searchLabel, 'pageNo', this.pageObj.pageNo)
this.$set(this.searchLabel, 'pageSize', this.pageObj.pageSize)
if (this.$route.path === '/monitor/endpoint') {
if (this.$route.path === '/endpoint') {
this.$set(this.searchLabel, 'statistics', 1)
}
const params = {
@@ -619,7 +619,7 @@ export default {
this.$get(this.url, params).then(response => {
this.tools.loading = false
if (response.code === 200) {
if (response.statistics && this.$route.path === '/monitor/endpoint') {
if (response.statistics && this.$route.path === '/endpoint') {
this.setSearchData(response.statistics)
}
for (let i = 0; i < response.data.list.length; i++) {

View File

@@ -11,7 +11,7 @@ Vue.use(VueResource)
const loginWhiteList = ['/setup', '/sys/license/upload', '/sys/license/state', '/sys/appearance'] // 免登陆白名单
const permissionWhiteList = ['/profile', '/menu', ...loginWhiteList] // 权限白名单
router.beforeEach((to, from, next) => {
if (store.getters.getNowPath !== to.path) {
if (store.getters.getNowPath !== to.path && store.getters.getNowPath !== '/login') {
requestsArr.forEach(xhr => xhr.cancel())
}
store.commit('setNowPath', to.path)
@@ -134,7 +134,8 @@ router.beforeEach((to, from, next) => {
returnMenuCode(res.data.menus, arr)
store.commit('setButtonList', arr)
store.commit('setRoleList', res.data.roles)
document.getElementsByTagName('body')[0].setAttribute('class', 'theme-' + localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`))
const theme = localStorage.getItem(`nz-user-${localStorage.getItem('nz-user-id')}-theme`) || 'light'
document.getElementsByTagName('body')[0].setAttribute('class', 'theme-' + theme)
resolve()
} else {
localStorage.removeItem('nz-token')

View File

@@ -34,16 +34,16 @@ export default new Router({
component: resolve => require(['../components/page/dashboard/overview/overview.vue'], resolve)
},
{
path: '/monitor/project',
path: '/project',
component: resolve => require(['../components/page/monitor/project/index.vue'], resolve)
},
{
path: '/monitor/module',
name: '/monitor/module',
path: '/module',
name: '/module',
component: resolve => require(['../components/page/monitor/module/moduleList.vue'], resolve)
},
{
path: '/monitor/endpoint',
path: '/endpoint',
component: resolve => require(['../components/page/monitor/endpoint/endpointList.vue'], resolve)
},
{

View File

@@ -71,6 +71,7 @@ const user = {
},
actions: {
loginSuccess (store, res) {
const defaultAppearance = {
system_name: localStorage.getItem('nz-sys-name'),
system_logo: localStorage.getItem('nz-sys-logo'),
@@ -147,7 +148,7 @@ const user = {
// 保存当前用户的 userId
localStorage.setItem('nz-user-id', user.id)
// 保存当前用户 name
localStorage.setItem('nz-user-name', user.name)
localStorage.setItem('nz-username', user.name)
}
})
get('alert/severity', { pageNo: 1, pageSize: -1 }).then(response => {