This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nezha-nezha-fronted/nezha-fronted/src/components/common/js/tools.js

836 lines
30 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { getChart } from './common'
import MessageBox from 'element-ui/packages/message-box/src/main'
import i18n from '../i18n'
import bus from '@/libs/bus'
import moment from 'moment-timezone'
/* 弹窗点击外部后关闭 */
const exceptClassName = ['prevent-clickoutside', 'config-dropdown', 'nz-pop', 'el-picker', 'chart-box-dropdown', 'metric-dropdown', 'el-cascader__dropdown', 'no-style-class', 'el-message-box', 'nz-dashboard-dropdown', 'el-autocomplete-suggestion', 'nz-temp-box', 'el-time-panel', 'el-dropdown-menu', 'el-select-dropdown'] // clickoutside排除的class(白名单) no-style-class没有任何样式的class
export const clickoutside = {
// 初始化指令
bind (el, binding, vnode) {
if (!binding.expression) return
const unsavedChange = localStorage.getItem('nz-unnsaved-change')
let oldValue
try {
oldValue = JSON.parse(JSON.stringify(binding.value.obj))
} catch (e) {
}
function documentHandler (e) {
if (el.contains(e.target)) {
return false
} else {
let flag = true
const path = e.path || (e.composedPath && e.composedPath())
// eslint-disable-next-line no-labels
top: for (let i = 0; i < path.length; i++) {
for (let j = 0; j < exceptClassName.length; j++) {
if (path[i].className && path[i].className.indexOf && path[i].className.indexOf(exceptClassName[j]) !== -1) {
flag = false
// eslint-disable-next-line no-labels
break top
}
}
}
if (!flag) {
return false
}
if (oldValue) {
const newValue = JSON.parse(JSON.stringify(binding.value.obj))
if (unsavedChange == 'on' && !isEqual(oldValue, newValue)) {
MessageBox.confirm(i18n.t('tip.confirmCancel'), {
confirmButtonText: i18n.t('tip.yes'),
cancelButtonText: i18n.t('tip.no'),
type: 'warning'
}).then(() => {
if (binding.value.func) {
binding.value.func()
}
})
} else {
binding.value.func()
}
} else {
if (binding.arg) {
binding.value(e, binding.arg)
} else {
if (binding.value) {
binding.value(e)
}
}
}
}
}
// 给当前元素绑定个私有变量方便在unbind中可以解除事件监听
el.__vueClickOutside__ = documentHandler
document.addEventListener('mousedown', documentHandler)
},
unbind (el, binding) {
// 解除事件监听
document.removeEventListener('mousedown', el.__vueClickOutside__)
delete el.__vueClickOutside__
}
}
function isEqual (o1, o2) {
var isEqualForInner = function (obj1, obj2) {
const o1 = obj1 instanceof Object
const o2 = obj2 instanceof Object
if (!o1 || !o2) {
return obj1 === obj2
}
if (Object.keys(obj1).length !== Object.keys(obj2).length) {
return false
}
for (const attr of Object.keys(obj1)) {
const t1 = obj1[attr] instanceof Object
const t2 = obj2[attr] instanceof Object
if (t1 && t2) {
if (!isEqualForInner(obj1[attr], obj2[attr])) {
return false
}
} else if (obj1[attr] !== obj2[attr]) {
return false
}
}
return true
}
return isEqualForInner(o1, o2)
}
export const cancelWithChange = {
bind: function (el, binding) {
if (!binding.value || !binding.value.obj) return
const unsavedChange = localStorage.getItem('nz-unnsaved-change')
const oldValue = JSON.parse(JSON.stringify(binding.value.obj))
function domClick (e) {
const newValue = JSON.parse(JSON.stringify(binding.value.obj))
if (unsavedChange == 'on' && !isEqual(oldValue, newValue)) {
MessageBox.confirm(i18n.t('tip.confirmCancel'), {
confirmButtonText: i18n.t('tip.yes'),
cancelButtonText: i18n.t('tip.no'),
type: 'warning'
}).then(() => {
if (binding.value.func) {
binding.value.func()
}
})
} else {
binding.value.func()
}
}
el.__vueDomClick__ = domClick
el.addEventListener('click', domClick)
},
unbind: function (el, binding) {
// 解除事件监听
document.removeEventListener('click', el.__vueDomClick__)
delete el.__vueDomClick__
}
}
// 底部上滑框窗口控制
export const bottomBoxWindow = {
// 鼠标拖动二级列表
listResize (vm, e) {
window.resizing = true
const mainListDom = document.querySelector('.main-list') // 主列表
const subBoxDom = document.querySelector('.sub-box') // 副列表
const subListDom = document.querySelector('.sub-list') // 副列表
const contentRightDom = document.querySelector('.list-page') // 右侧内容区
const resizeBarHeight = 9 // resize横条高度
const minHeight = 15 // 主、副列表最小高度限制为15
const contentHideHeight = 100 // 主、副列表高度低于100时隐藏内容
const mainModalDom = document.querySelector('.main-modal') // 主列表遮罩
const resizeModalDom = document.querySelector('.resize-modal') // 副列表遮罩
const resizeBarDom = document.querySelector('.sub-list-resize') // 拖动条
const contentRightHeight = contentRightDom.offsetHeight// 可视高度
// 点击时俩dom的初始高度
const subInitialHeight = subListDom.offsetHeight + resizeBarHeight
mainModalDom.style.display = 'block'
resizeModalDom.style.cssText = `height: ${subInitialHeight}px; display: block;`
resizeBarDom.style.display = 'none'
let resizeModalEndHeight
// 点击时鼠标的Y轴位置
const mouseInitialY = e.clientY
document.onmousemove = (e) => {
window.resizing = true
e.preventDefault()
// 得到鼠标拖动的距离
const mouseMoveY = e.clientY - mouseInitialY
resizeModalEndHeight = subInitialHeight - mouseMoveY
// 主、副列表高度限制
if (resizeModalEndHeight > contentRightHeight - minHeight) {
resizeModalEndHeight = contentRightHeight - minHeight
}
if (resizeModalEndHeight < minHeight) {
resizeModalEndHeight = minHeight
}
resizeModalDom.style.height = `${resizeModalEndHeight}px`
}
document.onmouseup = () => {
window.resizing = false
mainListDom.style.height = `${contentRightHeight - resizeModalEndHeight}px`
subBoxDom.style.height = `${resizeModalEndHeight}px`
subListDom.style.height = `${resizeModalEndHeight - resizeBarHeight}px`
resizeModalDom.style.display = 'none'
mainModalDom.style.display = 'none'
resizeBarDom.style.display = ''
// 当主副列表可视区域小于一定值时,不展示内容
if (contentRightHeight - resizeModalEndHeight <= contentHideHeight) {
if (vm.bottomBox.mainResizeShow) {
vm.bottomBox.mainResizeShow = false
}
} else {
if (!vm.bottomBox.mainResizeShow) {
vm.bottomBox.mainResizeShow = true
}
}
if (resizeModalEndHeight < contentHideHeight) {
if (vm.bottomBox.subResizeShow) {
vm.bottomBox.subResizeShow = false
}
} else {
if (!vm.bottomBox.subResizeShow) {
vm.bottomBox.subResizeShow = true
}
}
document.onmousemove = null
document.onmouseup = null
}
},
exitFullScreen (vm) {
window.resizing = true
const contentRightDom = document.querySelector('.list-page') // 右侧内容区
const contentRightHeight = contentRightDom.offsetHeight// 可视高度
// 主列表
document.querySelector('.main-list-with-sub').style.height = vm.bottomBox.mainListHeight ? vm.bottomBox.mainListHeight + 'px' : 'calc(50% - 4px)'
// 副列表
document.querySelector('.sub-list').style.height = vm.bottomBox.mainListHeight ? contentRightHeight - vm.bottomBox.mainListHeight - 9 + 'px' : 'calc(50% - 4px)'
setTimeout(() => {
if (document.querySelector('.main-list-with-sub').offsetHeight >= 100) {
vm.bottomBox.mainResizeShow = true
}
if (document.querySelector('.sub-list').offsetHeight >= 100) {
vm.bottomBox.subResizeShow = true
}
vm.bottomBox.isFullScreen = false
window.resizing = false
vm.$nextTick(() => {
const table = vm.$refs.dataTable || vm.$parent.$refs.dataTable
table.$refs.dataTable.doLayout()
})
}, 210)
},
fullScreen (vm) {
window.resizing = true
const contentRightDom = document.querySelector('.list-page') // 右侧内容区
const contentRightHeight = contentRightDom.offsetHeight - 9// 可视高度
vm.bottomBox.isFullScreen = true
// 主列表
vm.bottomBox.mainListHeight = document.querySelector('.main-list-with-sub').offsetHeight // 记录全屏前主列表的高度
document.querySelector('.main-list-with-sub').style.height = '0'
vm.bottomBox.mainResizeShow = false
// 副列表
document.querySelector('.sub-list').style.height = contentRightHeight + 'px'
window.resizing = false
},
showSubListWatch (vm, n) {
vm.bottomBox.inTransform = n
if (!n) {
vm.mainTableHeight = vm.$tableHeight.normal // 重置table的高度
vm.tools.toTopBtnTop = vm.$tableHeight.toTopBtnTop
vm.bottomBox.isFullScreen = false
// 移动分页组件的位置
/* const paginationTop = document.querySelector('.pagination-top')
const paginationBottom = document.querySelector('.pagination-bottom')
paginationTop.classList.remove('display-none')
if (paginationTop.classList.contains('pagination-top-show')) {
paginationTop.classList.remove('pagination-top-show')
}
if (!paginationTop.classList.contains('pagination-top-hide')) {
paginationTop.classList.add('pagination-top-hide')
}
setTimeout(() => {
paginationTop.classList.add('display-none')
paginationBottom.appendChild(paginationTop.removeChild(document.querySelector('.pagination')))
}, 210) */
// 主列表恢复全屏
vm.bottomBox.mainResizeShow = vm.bottomBox.subResizeShow = true
document.querySelector('.main-list').style.height = ''
// 副列表高度清空
document.querySelector('.sub-list').style.height = ''
} else {
vm.mainTableHeight = vm.$tableHeight.openSubList.mainList // 重置table高度
vm.tools.toTopBtnTop = vm.$tableHeight.openSubList.toTopBtnTop
// 移动分页组件的位置
/* const paginationTop = document.querySelector('.pagination-top')
paginationTop.appendChild(document.querySelector('.pagination-bottom').removeChild(document.querySelector('.pagination')))
paginationTop.classList.remove('display-none')
setTimeout(() => {
if (paginationTop.classList.contains('pagination-top-hide')) {
paginationTop.classList.remove('pagination-top-hide')
}
if (!paginationTop.classList.contains('pagination-top-show')) {
paginationTop.classList.add('pagination-top-show')
}
}, 210) */
}
}
}
export function stringTimeParseToUnix (stringTime) {
let time = new Date(stringTime).getTime()
let offset = localStorage.getItem('nz-sys-timezone')
offset = moment.tz(offset).format('Z')
offset = Number.parseInt(offset)
const localOffset = new Date().getTimezoneOffset() * 60 * 1000 * -1 // 默认 一分钟显示时区偏移的结果
time = time + localOffset - offset * 60 * 60 * 1000
return parseInt(time / 1000)
}
export function getTime (size, unit) { // 计算时间
const now = new Date(bus.computeTimezone(new Date().getTime()))
if (unit) {
switch (unit) {
case 'y':
now.setFullYear(now.getFullYear() + size)
break
case 'M':
now.setMonth(now.getMonth() + size)
break
case 'd':
now.setDate(now.getDate() + size)
break
case 'h':
now.setHours(now.getHours() + size)
break
case 'm':
now.setMinutes(now.getMinutes() + size)
break
case 's':
now.setSeconds(now.getSeconds() + size)
break
default:
console.error('unit error')
}
} else {
now.setSeconds(now.getSeconds() + size)
}
const year = now.getFullYear()
let month = now.getMonth() + 1
month = month < 10 ? '0' + month : month
let day = now.getDate()
day = day < 10 ? '0' + day : day
let hour = now.getHours()
hour = hour < 10 ? '0' + hour : hour
let minute = now.getMinutes()
minute = minute < 10 ? '0' + minute : minute
let second = now.getSeconds()
second = second < 10 ? '0' + second : second
return year + '-' + month + '-' + day + ' ' + hour + ':' + minute + ':' + second
}
export function calcDurationByStringTime (startTime, endTime) {
const durationSecond = stringTimeParseToUnix(endTime) - stringTimeParseToUnix(startTime)
let result = `${durationSecond % 60}s`
if (durationSecond > 60) {
result = `${(Math.floor(durationSecond / 60)) % 60}m ${result}`
}
if (durationSecond > 60 * 60) {
result = `${Math.floor(durationSecond / (60 * 60))}h ${result}`
}
return result
}
export function calcDurationByStringTimeB (startTime, endTime) {
const durationSecond = stringTimeParseToUnix(endTime) - stringTimeParseToUnix(startTime)
let result = `${durationSecond % 60}s`
if (durationSecond >= 60 * 60 * 24) {
result = `${(Math.floor(durationSecond / 3600)) % 24}h`
result = `${Math.floor(durationSecond / (60 * 60 * 24))}d ${result}`
} else if (durationSecond >= 60 * 60) {
result = `${(Math.floor(durationSecond / 60)) % 60}m`
result = `${Math.floor(durationSecond / (60 * 60))}h ${result}`
} else if (durationSecond >= 60) {
result = `${(Math.floor(durationSecond / 60)) % 60}m ${result}`
}
return result
}
export function unixTimeParseToString (unixTime, fmt = 'yyyy-MM-dd hh:mm:ss') {
const date = new Date(unixTime * 1000)
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
S: date.getMilliseconds() // 毫秒
}
if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)) }
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) }
}
return fmt
}
// chart-resize工具
export const chartResizeTool = {
minHeight: 200, // 图表最小高度
chartBlankHeight: 10, // 图表空白占位高度(padding-bottom + border)
chartTableBlankHeight: 6, // 表格型图表额外空白占位高度
chartBlankWidth: 10, // 图表空白占位宽度(padding-right)
containerBlankWidth: 30, // 容器空白占位宽度(#listContainer的padding
titleHeight: 40, // 标题dom高度
timeouter: null,
stepWidth (containerWidth) { // 单元宽度,参数为容器总宽度
return Math.floor((containerWidth - this.containerBlankWidth) / 12)
},
start (vm, originalData, event, chartIndexs) {
const $self = this
const data = JSON.parse(JSON.stringify(originalData)) // 将初始对象复制,后续操作使用复制对象
const shadow = vm.$refs.resizeShadow ? vm.$refs.resizeShadow : vm.$refs[0].resizeShadow // 缩放时底部阴影dom
const box = vm.$refs.resizeBox ? vm.$refs.resizeBox : vm.$refs[0].resizeBox // 图表内容dom
const chartBlankWidth = this.chartBlankWidth
const chartBlankHeight = this.chartBlankHeight
const titleHeight = this.titleHeight
const containerWidth = data.groupId ? document.getElementById('listContainer' + data.groupId).offsetWidth + 40 : document.getElementById('listContainer').offsetWidth
const step = this.stepWidth(containerWidth)
const mouseOriginalX = event.clientX // 鼠标初始坐标
const mouseOriginalY = event.clientY
const originalWidth = step * data.span // 图表、阴影初始宽高
let shadowNewWidth = originalWidth
const originalHeight = step * data.height
let shadowNewHeight = originalHeight
// 1.激活背景阴影
shadow.classList.add('resize-shadow-active')
// 2.鼠标移动时调整resize-box的宽高同时监听宽高的变化变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容
document.addEventListener('mousemove', moveListener)
// 3.鼠标松开将resize-box宽高改为resize-shadow宽高结束
document.addEventListener('mouseup', mouseupListener)
function moveListener (e) {
const mouseX = e.clientX
const mouseY = e.clientY
const w = `${Math.floor(originalWidth + (mouseX - mouseOriginalX) - chartBlankWidth)}px`
const h = `${Math.floor(originalHeight + (mouseY - mouseOriginalY) - chartBlankHeight)}px`
box.style.width = w
box.style.height = h
// 调整resize-box的宽高。减去chartBlankWidth、chartBlankHeight是为了对齐
// box.style.width = `${Math.floor(originalWidth + (mouseX - mouseOriginalX) - chartBlankWidth)}px`
// box.style.height = `${Math.floor(originalHeight + (mouseY - mouseOriginalY) - chartBlankHeight)}px`
// 监听宽高的变化变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容
const remainderWidth = (box.offsetWidth + chartBlankWidth - shadowNewWidth) % step // 宽的余数
const remainderHeight = (box.offsetHeight + chartBlankHeight - shadowNewHeight) % step // 高的余数
boxStepHandler(remainderWidth, remainderHeight)
}
function mouseupListener (e) {
data.span = Math.round((shadow.offsetWidth + chartBlankWidth) / step)
data.height = Math.round((shadow.offsetHeight + chartBlankHeight) / step)
box.style.width = `${Math.floor(data.span * step) - chartBlankWidth}px`
box.style.height = `${Math.floor(data.height * step) - chartBlankHeight}px`
// 请求后台,保存变更
if (data.height != originalData.height || data.span != originalData.span) {
originalData.height = data.height
originalData.span = data.span
vm.$put('/visual/panel/chart/modify', originalData)
}
// 关闭背景阴影
shadow.classList.remove('resize-shadow-active')
document.removeEventListener('mousemove', moveListener)
document.removeEventListener('mouseup', mouseupListener)
}
function boxStepHandler (width, height, chartIndex) { // param: 宽高变化量大于0放大小于0缩小
let widthChange = false
let heightChange = false
if (width > step / 2) { // 放大shadow宽
widthChange = true
// 判断是否因为百分数计算的宽度有小数的原因导致宽度超过当前行,使图表错误换行
const currentWidth = shadow.offsetWidth + step // 增大一阶后的宽度
const currentSpan = Math.round((currentWidth + chartBlankWidth) / step) // 根据width计算span
const calcWidth = currentSpan * step - chartBlankWidth // 不会换行的宽度
shadow.style.width = `${calcWidth}px`
} else if (width <= 0 - (step / 2)) { // 缩小shadow宽
widthChange = true
const currentWidth = shadow.offsetWidth - step // 减小一阶
const currentSpan = Math.round((currentWidth + chartBlankWidth) / step) // 根据width计算span
const calcWidth = currentSpan * step - chartBlankWidth // 不会换行的宽度
shadow.style.width = `${calcWidth}px`
}
if (widthChange) {
shadowNewWidth = shadow.offsetWidth
}
if (height > step / 2) { // 放大shadow高
heightChange = true
const currentHeight = shadow.offsetHeight + step // 增大一阶后的宽度
const currentHeightSpan = Math.round((currentHeight + chartBlankHeight) / step) // 根据width计算span
const calcHeight = currentHeightSpan * step - chartBlankHeight // 不会换行的宽度
shadow.style.height = `${calcHeight}px`
} else if (height <= 0 - (step / 2)) { // 缩小shadow高
heightChange = true
const currentHeight = shadow.offsetHeight - step // 增大一阶后的宽度
const currentHeightSpan = Math.round((currentHeight + chartBlankHeight) / step) // 根据width计算span
const calcHeight = currentHeightSpan * step - chartBlankHeight // 不会换行的宽度
shadow.style.height = `${calcHeight}px`
}
if (heightChange) {
shadowNewHeight = shadow.offsetHeight
}
if (widthChange || heightChange) {
clearTimeout($self.timeouter)
$self.timeouter = setTimeout(() => {
// step时chart重绘
if (box.classList.contains('resize-box-echarts')) { // echarts类型
getChart(chartIndexs).resize({ width: shadow.offsetWidth - 16, height: shadow.offsetHeight - titleHeight - vm.$refs.legendArea.offsetHeight })
}
}, 500)
// chart外层宽高调整
const outerBox = document.getElementById(`chart-${data.id}`)
outerBox.style.height = `${shadow.offsetHeight + chartBlankHeight}px`
outerBox.style.width = `${parseFloat(shadow.style.width.split('px')[0]) + chartBlankWidth}px`
}
}
}
}
// table 方法
export const tableSet = {
// 是否需要排序
sortableShow (prop, from) {
switch (prop) {
case 'state': {
if (from === 'operationlog' || from === 'alertSilence') {
return false
}
break
}
case 'startAt': {
if (from === 'alertSilence') {
return false
}
break
}
case 'id':
case 'alertRule':
case 'severity':
case 'endAt':
case 'ID':
case 'HOST':
case 'SN':
case 'assetType':
case 'purchaseDate':
case 'pingStatus':
case 'dataCenter':
case 'cabinet':
case 'model':
case 'principal':
case 'asset':
case 'port':
case 'project':
case 'module':
case 'type':
case 'name':
case 'area':
case 'vendor':
case 'filename':
case 'updateAt':
case 'username':
case 'ip':
case 'operation':
case 'createDate':
case 'time':
case 'host':
case 'protocol':
case 'user':
case 'cmd':
case 'alertName':
case 'threshold':
case 'idc':
case 'alertNum':
case 'gname':
return 'custom'
default : return false
}
},
// prop字段
propTitle (prop, from) {
switch (from) {
case 'asset':
switch (prop) {
case 'ID': return 'ass.id'
case 'HOST': return 'ass.host'
case 'SN': return 'ass.sn'
case 'assetType': return 'sdtt.value'
case 'purchaseDate': return 'ass.purchase_date'
case 'state': return 'ass.state'
case 'pingStatus': return 'assp.rtt'
case 'dataCenter': return 'idc.name'
case 'cabinet': return 'cab.name'
case 'model': return 'mo.name'
case 'vendor': return 'sdt.value'
case 'principal': return 'su.username'
default : return prop
}
case 'alertMessage':
switch (prop) {
case 'id': return 'am.id'
case 'state': return 'am.state'
case 'alertRule': return 'ar.alert_name'
case 'severity': return 'am.severity'
case 'startAt': return 'am.start_at'
case 'endAt': return 'am.end_at'
default : return prop
}
case 'project':
switch (prop) {
case 'id': return 'e.id'
case 'asset': return 'a.host'
case 'port': return 'e.port'
case 'project': return 'p.name'
case 'module': return 'm.name'
case 'type': return 'm.type'
case 'state' :return 'es.state'
// case 'path': return'e.path';
default : return prop
}
case 'dc':
switch (prop) {
case 'id': return 'i.id'
case 'name': return 'i.name'
case 'area': return 'sa.name'
default : return prop
}
case 'endpointTab':
switch (prop) {
case 'id': return 'e.id'
case 'asset': return 'a.host'
case 'port': return 'e.port'
case 'project': return 'p.name'
case 'module': return 'm.name'
case 'type': return 'm.type'
case 'state' :return 'es.state'
// case 'path': return'e.path';
default : return prop
}
case 'model':
switch (prop) {
case 'id': return 'mo.id'
case 'name': return 'mo.name'
case 'type': return 'dictt.value'
case 'vendor': return 'dict.value'
default : return prop
}
case 'promServer':
switch (prop) {
case 'id': return 'id'
case 'idc': return 'idc_id'
case 'host': return 'host'
case 'port': return 'port'
case 'type': return 'type'
default : return prop
}
case 'mib':
switch (prop) {
case 'id': return 'sm.id'
case 'name': return 'sm.name'
case 'filename': return 'sm.file_name'
case 'updateAt': return 'sm.update_at'
default : return prop
}
case 'operationlog':
switch (prop) {
case 'id': return 'sl.id'
case 'username': return 'su.username'
case 'ip': return 'sl.ip'
case 'operation': return 'sl.operation'
case 'type': return 'sl.type'
case 'createDate': return 'sl.create_date'
case 'time': return 'sl.time'
default : return prop
}
case 'temrminallog':
switch (prop) {
case 'protocol': return 'protocol'
case 'startTime': return 'startTime'
default : return prop
}
case 'alertRules':
switch (prop) {
case 'id': return 'ar.id'
case 'alertName': return 'ar.alert_name'
case 'threshold': return 'ar.threshold'
case 'severity': return 'ar.severity'
default : return prop
}
case 'exprTemp':
switch (prop) {
case 'id': return 'id'
case 'name': return 'name'
case 'gname': return 'gname'
default : return prop
}
default: return prop
}
},
// 本地正序
asce (prop) {
return function (obj1, obj2) {
let val1 = obj1[prop]
let val2 = obj2[prop]
if (!isNaN(val1) && !isNaN(val2) && prop === 'value') {
val1 = Number(val1)
val2 = Number(val2)
}
if (prop === 'time') {
val1 = tableSet.strTodate(val1)
val2 = tableSet.strTodate(val2)
}
if (prop === 'element') {
if (val1.alias) {
val1 = JSON.stringify(obj1[prop].alias).replace(/\s*/g, '')
} else {
val1 = JSON.stringify(obj1[prop].element).replace(/\s*/g, '')
}
if (val2.alias) {
val2 = JSON.stringify(obj2[prop].alias).replace(/\s*/g, '')
} else {
val2 = JSON.stringify(obj2[prop].element).replace(/\s*/g, '')
}
}
if (val1 < val2) {
return -1
} else if (val1 > val2) {
return 1
} else {
return 0
}
}
},
// 本地倒序
desc (prop) {
return function (obj1, obj2) {
let val1 = obj1[prop]
let val2 = obj2[prop]
if (!isNaN(Number(val1)) && !isNaN(Number(val2)) && prop !== 'time') {
val1 = Number(val1)
val2 = Number(val2)
}
if (prop === 'time') {
val1 = tableSet.strTodate(val1)
val2 = tableSet.strTodate(val2)
}
if (prop === 'element') {
if (val1.alias) {
val1 = JSON.stringify(obj1[prop].alias).replace(/\s*/g, '')
} else {
val1 = JSON.stringify(obj1[prop].element).replace(/\s*/g, '')
}
if (val2.alias) {
val2 = JSON.stringify(obj2[prop].alias).replace(/\s*/g, '')
} else {
val2 = JSON.stringify(obj2[prop].element).replace(/\s*/g, '')
}
}
if (val1 < val2) {
return 1
} else if (val1 > val2) {
return -1
} else {
return 0
}
}
},
// 转化时间字符串为时间戳
strTodate (str) {
let date = str.trim()
date = date.substring(0, 19)
date = date.replace(/-/g, '/') // 必须把日期'-'转为'/'
return new Date(date).getTime()
}
}
export function getMetricTypeValue (queryItem, type) {
let copy = JSON.parse(JSON.stringify(queryItem))
switch (type) {
case 'min': {
const min = copy.sort((x, y) => { return parseFloat(x[1]) - parseFloat(y[1]) })[0][1]
return min
}
case 'max': {
const max = copy.sort((x, y) => { return parseFloat(y[1]) - parseFloat(x[1]) })[0][1]
return max
}
case 'avg': {
copy = copy.map(t => parseFloat(t[1]))
const sum = eval(copy.join('+'))
const avg = sum / copy.length
return avg
}
case 'last': {
const last = copy.sort((x, y) => { return parseFloat(y[0]) - parseFloat(x[0]) })[0][1]
return last
}
case 'first': {
const first = copy.sort((x, y) => { return parseFloat(y[0]) - parseFloat(x[0]) })[copy.length - 1][1]
return first
}
case 'total': {
copy = copy.map(t => parseFloat(t[1]))
const total = eval(copy.join('+'))
return total
}
}
}
export function blankPromise () {
return new Promise(resolve => { resolve() })
}
export function clickLegend (echart, legendName, index) {
if (echart) {
//
}
}
export function showTableTooltip (content, show = true, e) {
if (show) {
const dom = document.querySelector('.table-tooltip')
dom.innerHTML = content
dom.setAttribute('style', `visibility: visible; top: ${e.clientY - e.offsetY + e.target.offsetHeight * 0.5 - dom.offsetHeight * 0.5}px; left: ${e.clientX - e.offsetX + e.target.offsetWidth}px`)
}
}
export function hideTableTooltip () {
const dom = document.querySelector('.table-tooltip')
dom.setAttribute('style', 'visibility: hidden;')
dom.innerHTML = ''
}
/* 数字转换保留小数,数字很小时转为科学计数法, dot为保留几位小数 */
export function formatScientificNotation (value, dot = 2) {
let val = value ? parseFloat(Number(value).toFixed(dot)) : 0
if (val === 0) {
val = Number(value).toPrecision(dot + 1)
}
return val
}
/* function getTdDom(dom) {
let tagName = dom.tagName;
if (tagName.toLowerCase() === 'td') {
return dom;
} else {
return getTdDom(dom.parentElement);
}
} */