import PerfectScrollbar from "perfect-scrollbar"; import {getChart} from "./common"; //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', "el-autocomplete-suggestion"]; //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"); 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) { 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); 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"); //主列表 let subBoxDom = document.querySelector(".sub-box"); //副列表 let subListDom = document.querySelector(".sub-list"); //副列表 let contentRightDom = document.querySelector(".content-right"); //右侧内容区 let resizeBarHeight = 9; //resize横条高度 let minHeight = 15; //主、副列表最小高度限制为15 let contentHideHeight = 100; //主、副列表高度低于100时隐藏内容 let mainModalDom = document.querySelector(".main-modal"); //主列表遮罩 let resizeModalDom = document.querySelector(".resize-modal"); //副列表遮罩 let resizeBarDom = document.querySelector(".sub-list-resize"); //拖动条 let contentRightHeight = contentRightDom.offsetHeight;//可视高度 //点击时俩dom的初始高度: let subInitialHeight = subListDom.offsetHeight+resizeBarHeight; mainModalDom.style.display = "block"; resizeModalDom.style.cssText = `height: ${subInitialHeight}px; display: block;`; resizeBarDom.style.display = "none"; let resizeModalEndHeight; //点击时鼠标的Y轴位置 let mouseInitialY = e.clientY; document.onmousemove = (e) => { window.resizing = true; e.preventDefault(); //得到鼠标拖动的距离 let 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; let contentRightDom = document.querySelector(".content-right"); //右侧内容区 let 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; }, 210); }, fullScreen(vm) { window.resizing = true; let contentRightDom = document.querySelector(".content-right"); //右侧内容区 let contentRightHeight = contentRightDom.offsetHeight;//可视高度 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; //移动分页组件的位置 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.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; //移动分页组件的位置 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; } export function unixTimeParseToString(unixTime,fmt='yyyy-MM-dd hh:mm:ss'){ 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; } //chart-resize工具 export const chartResizeTool = { minHeight: 200, //图表最小高度 chartPaddingTop: 10, //图表padding-top chartBlankHeight: 12, //图表空白占位高度(padding-top + border) chartTableBlankHeight: 6, //表格型图表额外空白占位高度 chartBlankWidth: 10, //图表空白占位宽度 containerBlankWidth: 25, //容器空白占位宽度(#listContainer的padding) titleHeight: 28, //标题dom高度 stepHeight: 50, //单元高度 timeouter:null, stepWidth(containerWidth) { //单元宽度,参数为容器总宽度 return (containerWidth-this.containerBlankWidth)/12; }, calculateHeight(original) { let height = Math.floor(original/this.stepHeight)*this.stepHeight; if (height < this.minHeight) { height = this.minHeight; } return height-this.chartBlankHeight; }, start(vm, originalData, event, chartIndexs) { let $self=this; let data = JSON.parse(JSON.stringify(originalData)); //将初始对象复制,后续操作使用复制对象 let shadow = vm.$refs.resizeShadow; //缩放时底部阴影dom if (!shadow) { shadow = vm.$refs[0].resizeShadow; } let box = vm.$refs.resizeBox; //图表内容dom if (!box) { box = vm.$refs[0].resizeBox; } let chartPaddingTop = this.chartPaddingTop; let chartBlankWidth = this.chartBlankWidth; let chartBlankHeight = this.chartBlankHeight; let titleHeight = this.titleHeight; let stepWidth = this.stepWidth(document.getElementById('listContainer').offsetWidth); let stepHeight = this.stepHeight; let mouseOriginalX = event.clientX; //鼠标初始坐标 let mouseOriginalY = event.clientY; let originalWidth = stepWidth*data.span; //图表、阴影初始宽高 let shadowNewWidth = originalWidth; let originalHeight = 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) { let mouseX = e.clientX; let mouseY = e.clientY; //调整resize-box的宽高 box.style.width = `${originalWidth+(mouseX-mouseOriginalX)-chartBlankWidth}px`; box.style.height = `${originalHeight+(mouseY-mouseOriginalY)-chartBlankHeight}px`; //监听宽高的变化,变化量每达到step的50%时改变resize-shadow的尺寸并重绘resize-box内容 let remainderWidth = (box.offsetWidth+chartBlankWidth-shadowNewWidth)%stepWidth; //宽的余数 let remainderHeight = (box.offsetHeight+chartBlankHeight-shadowNewHeight)%stepHeight; //高的余数 boxStepHandler(remainderWidth, remainderHeight); } function mouseupListener(e) { //将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); //请求后台,保存变更 if (data.height != originalData.height || data.span != originalData.span) { originalData.height = data.height; originalData.span = data.span; vm.$put("panel/" + vm.panelIdInner + "/charts/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 > 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`; } 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`; } if (widthChange) { shadowNewWidth = shadow.offsetWidth; } if (height > stepHeight/2) { //放大shadow高 heightChange = true; shadow.style.height = `${Math.round(shadow.offsetHeight/10)*10+stepHeight}px`; } else if (height <= 0-(stepHeight/2)) { //缩小shadow高 heightChange = true; shadow.style.height = `${Math.round(shadow.offsetHeight/10)*10-stepHeight}px`; } if (heightChange) { shadowNewHeight = shadow.offsetHeight+chartBlankHeight; } 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外层宽高调整 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`; } } } }; //table 方法 export const tableSet = { //是否需要排序 sortableShow(prop,from){ switch(prop){ case 'id': case 'alertRule': case 'severity': case 'startAt': 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': return'custom'; case 'state': if( from === 'operationlog'){ return false }else{ 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 'id': return 'id'; case 'host': return 'host'; case 'port': return 'port'; case 'protocol': return 'protocol'; case 'user': return 'user'; case 'cmd': return 'cmd'; case 'time': return 'time'; 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; } default: break; } }, // 本地正序 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 blankPromise() { return new Promise(resolve => {resolve();}); }