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

488 lines
19 KiB
JavaScript
Raw Normal View History

import PerfectScrollbar from "perfect-scrollbar";
//top置顶按钮公共方法
export function toTop(type, wrap) {
if (type == 'el') {
let currentTop = wrap.scrollTop;
let interval = currentTop/10;
let intervalFunc = setInterval(function(){ //花200ms分10次回到顶部模拟动画效果
if (currentTop == 0) {
clearInterval(intervalFunc);
} else {
currentTop = (currentTop - interval) < interval*0.5 ? 0 : currentTop - interval;
wrap.scrollTop = currentTop;
}
}, 20);
} else {
let els = document.querySelectorAll(".el-table__body-wrapper");
if (wrap || wrap == 0) { //指定index的table__body
let currentTop = els[wrap].scrollTop;
let interval = currentTop/10;
let intervalFunc = setInterval(function(){ //花200ms分10次回到顶部模拟动画效果
if (currentTop == 0) {
clearInterval(intervalFunc);
} else {
currentTop = (currentTop - interval) < interval*0.5 ? 0 : currentTop - interval;
els[wrap].scrollTop = currentTop;
}
}, 20);
} else { //所有table__body
for (let i = 0; i < els.length; i++) {
let currentTop = els[i].scrollTop;
let interval = currentTop/10;
let intervalFunc = setInterval(function(){ //花200ms分10次回到顶部模拟动画效果
if (currentTop == 0) {
clearInterval(intervalFunc);
} else {
currentTop = (currentTop - interval) < interval*0.5 ? 0 : currentTop - interval;
els[i].scrollTop = currentTop;
}
}, 20);
}
}
}
}
/*弹窗点击外部后关闭*/
const exceptClassName = ["config-dropdown", "nz-pop", "el-picker", "chart-box-dropdown", 'metric-dropdown', 'el-cascader__dropdown', "asset-dropdown", "no-style-class", 'el-message-box','nz-dashboard-dropdown']; //clickoutside排除的class(白名单) no-style-class没有任何样式的class
export const clickoutside = {
// 初始化指令
bind(el, binding, vnode) {
function documentHandler(e) {
if (el.contains(e.target)) {
return false;
} else {
let flag = true;
let path = e.path || (e.composedPath && e.composedPath());
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(exceptClassName[j]) != -1) {
flag = false;
break top;
}
}
}
if (!flag) {
return false;
}
}
// 判断指令中是否绑定了函数
if (binding.expression) {
// 如果绑定了函数 则调用那个函数此处binding.value就是handleClose方法
if (binding.arg) {
binding.value(e, binding.arg);
} else {
binding.value(e);
}
}
}
// 给当前元素绑定个私有变量方便在unbind中可以解除事件监听
el.__vueClickOutside__ = documentHandler;
document.addEventListener('mousedown', documentHandler);
},
unbind(el, binding) {
// 解除事件监听
document.removeEventListener('mousedown', el.__vueClickOutside__);
delete el.__vueClickOutside__;
},
};
/*el-table自定义滚动条*/
const el_scrollBar = el => {
if (el._ps_ instanceof PerfectScrollbar) {
el._ps_.update();
} else {
//el上挂一份属性
el._ps_ = new PerfectScrollbar(el, {minScrollbarLength: 25});
}
};
export const scrollBar = {
inserted(el, binding, vnode) {
const { arg } = binding;
if (arg === "el-table") {
el = el.querySelector(".el-table__body-wrapper");
!el && console.warn("未发现className为el-table__body-wrapper的dom");
} else if (arg === "el-dropdown") {
el = document.querySelector(".el-dropdown-menu");
!el && console.warn("未发现className为el-dropdown-menu的dom");
} else if (arg == "legend") {
el = el.querySelector(".legend-container");
!el && console.warn("未发现className为legend-container的dom");
}
// 启用x轴后不让原生滚动条出来作乱
if (el) {
vnode.context.$nextTick(() => {
if (arg === "xterm") {
el = el.querySelector(".xterm-viewport");
!el && console.warn("未发现className为xterm-viewport的dom");
}
if(arg==="metric-label-cascader"){
el = el.querySelector(".el-cascader__tags");
!el && console.warn("未发现className为el-cascader__tags的dom");
}
el.classList.add("ps");
2020-04-17 16:39:08 +08:00
el.addEventListener("ps-scroll-y", () => {
el.classList.add("ps");
});
el.addEventListener("ps-scroll-x", () => {
el.classList.add("ps");
});
//el上挂一份属性
el_scrollBar(el);
});
const rules = ["fixed", "absolute", "relative"];
if (!rules.includes(window.getComputedStyle(el, null).position)) {
console.error(
`perfect-scrollbar所在的容器的position属性必须是以下之一${rules.join(
"、"
)}`
);
}
}
},
componentUpdated(el, binding, vnode, oldVnode) {
2020-04-17 16:39:08 +08:00
const { arg, value } = binding;
if (arg === "el-table") {
el = el.querySelector(".el-table__body-wrapper");
!el && console.warn("未发现className为el-table__body-wrapper的dom");
} else if (arg === "el-dropdown") {
el = document.querySelector(".el-dropdown-menu");
!el && console.warn("未发现className为el-dropdown-menu的dom");
}else if (arg === "xterm") {
el = el.querySelector(".xterm-viewport");
!el && console.warn("未发现className为xterm-viewport的dom");
}else if(arg==="metric-label-cascader"){
el = el.querySelector(".el-cascader__tags");
!el && console.warn("未发现className为el-cascader__tags的dom");
}
setTimeout(() => {
el.classList.add("ps");
el.classList.add("ps--active-y");
el._ps_.update();
}, 1500)
try {
vnode.context.$nextTick(() => {
el_scrollBar(el);
2020-04-17 16:49:28 +08:00
if (value) {
el.querySelector(".ps__rail-x").classList.add("ps-scroll-" + value);
el.querySelector(".ps__rail-y").classList.add("ps-scroll-" + value);
}
});
} catch (error) {
console.error(error);
el_scrollBar(el);
}
},
};
// 底部上滑框窗口控制
export const bottomBoxWindow = {
// 鼠标拖动二级列表
listResize(vm, e) {
window.resizing = true;
let mainListDom = document.querySelector(".main-list-with-sub"); //主列表
let subListDom = document.querySelector(".sub-list"); //副列表
let contentRightDom = document.querySelector(".content-right"); //右侧内容区
let contentRightHeight = contentRightDom.offsetHeight;//可视高度
//得到点击时俩dom的初始高度
let mainInitialHeight = mainListDom.offsetHeight;
let subInitialHeight = subListDom.offsetHeight;
//点击时鼠标的Y轴位置
let mouseInitialY = e.clientY;
document.onmousemove = (e) => {
window.resizing = true;
mainListDom.classList.remove('main-and-sub-transition');
subListDom.classList.remove('main-and-sub-transition');
e.preventDefault();
//得到鼠标拖动的距离
let mouseMoveY = Math.abs(e.clientY - mouseInitialY);
//往上方拖动:
if (e.clientY < mouseInitialY) {
vm.toTopBtnTop = mainInitialHeight-mouseMoveY+20+'px';
mainListDom.style.height = mainInitialHeight-mouseMoveY+'px';
subListDom.style.height = subInitialHeight+mouseMoveY+'px';
}
//往下方拖动:
if (e.clientY > mouseInitialY) {
vm.toTopBtnTop = mainInitialHeight+mouseMoveY+20+'px';
mainListDom.style.height = mainInitialHeight+mouseMoveY+'px';
subListDom.style.height = subInitialHeight-mouseMoveY+'px';
}
// 主、副列表最小高度限制为15px; 23是因为拖动区域有8的高度
if(parseInt(mainListDom.style.height) > contentRightHeight-23){
vm.toTopBtnTop = contentRightHeight+5+'px';
mainListDom.style.height = contentRightHeight-23+'px';
}
if(parseInt(mainListDom.style.height) <= 15){
vm.toTopBtnTop = '35px';
mainListDom.style.height = '15px';
}
if(parseInt(subListDom.style.height) > contentRightHeight-23){
subListDom.style.height = contentRightHeight-23+'px';
}
if(parseInt(subListDom.style.height) <= 15){
subListDom.style.height = '15px';
}
//当主副列表可视区域小于一定值时,不展示内容
if(parseInt(mainListDom.style.height) <= 100){
if (vm.mainResizeShow) {
vm.mainResizeShow = false;
}
} else {
if (!vm.mainResizeShow) {
vm.mainResizeShow = true;
}
}
if(parseInt(subListDom.style.height) <= 100){
if (vm.subResizeShow) {
vm.subResizeShow = false;
}
} else {
if (!vm.subResizeShow) {
vm.subResizeShow = true;
}
}
};
document.onmouseup = () => {
window.resizing = false;
mainListDom.classList.add('main-and-sub-transition');
subListDom.classList.add('main-and-sub-transition');
document.onmousemove = null;
}
},
exitFullScreen(vm) {
2020-05-12 14:56:43 +08:00
window.resizing = true;
let contentRightDom = document.querySelector(".content-right"); //右侧内容区
let contentRightHeight = contentRightDom.offsetHeight;//可视高度
//主列表
document.querySelector(".main-list-with-sub").style.height = vm.mainListHeight ? vm.mainListHeight + 'px' : 'calc(50% - 4px)';
//副列表
document.querySelector(".sub-list").style.height = vm.mainListHeight ? contentRightHeight-vm.mainListHeight-9 + 'px' : 'calc(50% - 4px)';
setTimeout(() => {
vm.isFullScreen = false;
if (document.querySelector(".main-list-with-sub").offsetHeight >= 100) {
vm.mainResizeShow = true;
}
if (document.querySelector(".sub-list").offsetHeight >= 100) {
vm.subResizeShow = true;
}
2020-05-12 14:56:43 +08:00
window.resizing = false;
}, 210);
},
fullScreen(vm) {
2020-05-12 14:56:43 +08:00
window.resizing = true;
let contentRightDom = document.querySelector(".content-right"); //右侧内容区
let contentRightHeight = contentRightDom.offsetHeight;//可视高度
vm.isFullScreen = true;
//主列表
vm.mainListHeight = document.querySelector(".main-list-with-sub").offsetHeight; //记录全屏前主列表的高度
document.querySelector(".main-list-with-sub").style.height = '0';
vm.mainResizeShow = false;
//副列表
document.querySelector(".sub-list").style.height = contentRightHeight + 'px';
2020-05-12 14:56:43 +08:00
window.resizing = false;
},
showSubListWatch(vm, n) {
vm.inTransform = n;
if (!n) {
vm.mainTableHeight = vm.$tableHeight.normal; //重置table的高度
vm.toTopBtnTop = vm.$tableHeight.toTopBtnTop;
vm.isFullScreen = false;
//移动分页组件的位置
let paginationTop = document.querySelector(".pagination-top");
let 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.mainResizeShow = vm.subResizeShow = true;
document.querySelector('.main-list').style.height = "";
//副列表高度清空
document.querySelector(".sub-list").style.height = '';
} else {
vm.mainTableHeight = vm.$tableHeight.openSubList.mainList; //重置table高度
vm.toTopBtnTop = vm.$tableHeight.openSubList.toTopBtnTop;
//移动分页组件的位置
let 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();
return time/1000;
}
2020-05-15 15:03:42 +08:00
2020-05-15 15:12:18 +08:00
export function unixTimeParseToString(unixTime,fmt='yyyy-MM-dd hh:mm:ss'){
2020-05-15 15:03:42 +08:00
let date=new Date(unixTime * 1000);
var 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(var 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;
}
2020-05-29 21:06:55 +08:00
//chart-resize工具
export const chartResizeTool = {
minHeight: 200, //图表最小高度
chartPaddingTop: 20, //图表padding-top
chartBlankHeight: 22, //图表空白占位高度(padding-top + border)
2020-05-31 13:44:47 +08:00
chartTableBlankHeight: 6, //表格型图表额外空白占位高度
2020-05-29 21:06:55 +08:00
chartBlankWidth: 20, //图表空白占位宽度
containerBlankWidth: 25, //容器空白占位宽度(#listContainer的padding
titleHeight: 28, //标题dom高度
stepHeight: 50, //单元高度
stepWidth(containerWidth) { //单元宽度,参数为容器总宽度
return (containerWidth-this.containerBlankWidth)/12;
},
calculateHeight(original) {
let height = Math.floor(original/this.stepHeight)*this.stepHeight;
2020-05-29 21:06:55 +08:00
if (height < this.minHeight) {
height = this.minHeight;
}
2020-05-31 13:44:47 +08:00
return height-this.chartBlankHeight;
2020-05-29 21:06:55 +08:00
},
2020-05-31 13:44:47 +08:00
start(vm, originalData, event) {
let data = JSON.parse(JSON.stringify(originalData)); //将初始对象复制,后续操作使用复制对象
let shadow = vm.$refs.resizeShadow; //缩放时底部阴影dom
if (!shadow) {
2020-05-29 21:06:55 +08:00
shadow = vm.$refs[0].resizeShadow;
}
let box = vm.$refs.resizeBox; //图表内容dom
if (!box) {
2020-05-29 21:06:55 +08:00
box = vm.$refs[0].resizeBox;
}
let chartPaddingTop = this.chartPaddingTop;
2020-05-29 21:06:55 +08:00
let chartBlankWidth = this.chartBlankWidth;
let chartBlankHeight = this.chartBlankHeight;
2020-05-31 13:44:47 +08:00
let titleHeight = this.titleHeight;
2020-05-29 21:06:55 +08:00
let stepWidth = this.stepWidth(document.getElementById('listContainer').offsetWidth);
let stepHeight = this.stepHeight;
let mouseOriginalX = event.clientX; //鼠标初始坐标
let mouseOriginalY = event.clientY;
2020-05-31 13:44:47 +08:00
let originalWidth = stepWidth*data.span; //图表、阴影初始宽高
let shadowNewWidth = originalWidth;
let originalHeight = data.height;
let shadowNewHeight = originalHeight;
2020-05-29 21:06:55 +08:00
//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) {
let mouseX = e.clientX;
let mouseY = e.clientY;
//调整resize-box的宽高
box.style.width = `${originalWidth+(mouseX-mouseOriginalX)-chartBlankWidth}px`;
2020-05-31 13:44:47 +08:00
box.style.height = `${originalHeight+(mouseY-mouseOriginalY)-chartBlankHeight}px`;
2020-05-29 21:06:55 +08:00
//监听宽高的变化变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容
2020-05-31 13:44:47 +08:00
let remainderWidth = (box.offsetWidth+chartBlankWidth-shadowNewWidth)%stepWidth; //宽的余数
let remainderHeight = (box.offsetHeight+chartBlankHeight-shadowNewHeight)%stepHeight; //高的余数
boxStepHandler(remainderWidth, remainderHeight);
2020-05-29 21:06:55 +08:00
}
function mouseupListener(e) {
2020-05-31 13:44:47 +08:00
//将resize-box的宽高设为resize-shadow的宽高
box.style.width = `${shadow.offsetWidth}px`;
box.style.height = `${Math.round(shadow.offsetHeight/10)*10}px`;
data.height = Math.round((box.offsetHeight+chartPaddingTop)/stepHeight)*stepHeight;
data.span = Math.round((box.offsetWidth+chartBlankWidth)/stepWidth);
2020-05-31 13:44:47 +08:00
//请求后台,保存变更
if (data.height != originalData.height || data.span != originalData.span) {
2020-05-31 13:44:47 +08:00
originalData.height = data.height;
originalData.span = data.span;
vm.$put("panel/" + vm.panelIdInner + "/charts/modify", originalData);
}
2020-05-29 21:06:55 +08:00
//关闭背景阴影
shadow.classList.remove("resize-shadow-active");
2020-05-31 13:44:47 +08:00
2020-05-29 21:06:55 +08:00
document.removeEventListener("mousemove", moveListener);
document.removeEventListener("mouseup", mouseupListener);
}
function boxStepHandler(width, height) { //param: 宽高变化量大于0放大小于0缩小
2020-05-31 13:44:47 +08:00
let widthChange = false;
let heightChange = false;
if (width > stepWidth/2) { //放大shadow宽
widthChange = true;
//判断是否因为百分数计算的宽度有小数的原因导致宽度超过当前行,使图表错误换行
let currentWidth = shadow.offsetWidth+stepWidth;
let currentSpan = Math.round((currentWidth+chartBlankWidth)/stepWidth);
let calcWidth = currentSpan*stepWidth-chartBlankWidth; //不会换行的宽度
shadow.style.width = `${calcWidth}px`;
2020-05-31 13:44:47 +08:00
} else if (width <= 0-(stepWidth/2)) { //缩小shadow宽
widthChange = true;
let currentWidth = shadow.offsetWidth-stepWidth;
let currentSpan = Math.round(currentWidth/stepWidth);
let calcWidth = currentSpan*stepWidth-chartBlankWidth; //不会换行的宽度
shadow.style.width = `${calcWidth}px`;
2020-05-31 13:44:47 +08:00
}
if (widthChange) {
shadowNewWidth = shadow.offsetWidth;
}
if (height > stepHeight/2) { //放大shadow高
2020-05-31 13:44:47 +08:00
heightChange = true;
shadow.style.height = `${Math.round(shadow.offsetHeight/10)*10+stepHeight}px`;
} else if (height <= 0-(stepHeight/2)) { //缩小shadow高
2020-05-31 13:44:47 +08:00
heightChange = true;
shadow.style.height = `${Math.round(shadow.offsetHeight/10)*10-stepHeight}px`;
2020-05-31 13:44:47 +08:00
}
if (heightChange) {
shadowNewHeight = shadow.offsetHeight+chartBlankHeight;
2020-05-31 13:44:47 +08:00
}
2020-05-29 21:06:55 +08:00
2020-05-31 13:44:47 +08:00
if (widthChange || heightChange) {
2020-05-31 17:40:55 +08:00
//step时chart重绘
2020-05-31 13:44:47 +08:00
if (box.classList.contains("resize-box-echarts")) { //echarts类型
vm.echartStore.resize({width: shadow.offsetWidth-16, height: shadow.offsetHeight-titleHeight-vm.$refs.legendArea.offsetHeight});
}
//chart外层宽高调整
let outerBox = document.getElementById(`chart-${data.id}`);
outerBox.style.height = `${shadow.offsetHeight+chartPaddingTop}px`;
outerBox.style.width = `${parseFloat(shadow.style.width.split("px")[0])+chartBlankWidth}px`;
2020-05-31 13:44:47 +08:00
}
2020-05-29 21:06:55 +08:00
}
}
}