/** * Description 过滤函数 * Input :* * Output :isValueExsit, substringUUID, splitIP, isChineseEngNum, * NAT, SLB, SWITCH, ROUTE, VM, DNAT_SNAT, setIconProperty, filter, * simulateHoverClick, canvasTips, SCALE, stringTypeNum, getRectWidth, scaleCanvas * other : 无 * author : lsb */ let NAT = { width: 70, height: 44, imgUrl: 'https://static.eflycloud.com/V5/pc/image/nat.png' }; // nat图片的地址和原始大小 let SLB = { width: 70, height: 44, imgUrl: 'https://static.eflycloud.com/V5/pc/image/SLB.png' }; // SLB图片的地址和原始大小 let SWITCH = { width: 71, height: 65, imgUrl: 'https://static.eflycloud.com/V5/pc/image/switch.png' }; // 交换机图片的地址和原始大小 let ROUTE = { width: 53, height: 82, imgUrl: 'https://static.eflycloud.com/V5/pc/image/route.png' }; // 路由器图片的地址和原始大小 let VM = { width: 71, height: 81, imgUrl: 'https://static.eflycloud.com/V5/pc/image/VM.png' }; // 云主机图片的地址和原始大小 let RDS = { width: 71, height: 81, imgUrl: 'https://static.eflycloud.com/V5/pc/image/RDS1.png' }; // RDS图片的地址和原始大小 let DNAT_SNAT = 'DNAT/SNAT查看'; // 图标缩放比例 let SCALE = 0.7; let LEFT_SCLAE = 0; let TIPS_LEFT = 0; /** * 判断值是否存在 * @param {any} value:值 * @param {string} name: 名字 * @return {any} boolean || string */ function isValueExsit(value: any, name: string): any { switch (value) { case null: return false; case 'undefined': return false; case 'slb': if (value.length < 0) { return false; } break; default: return name; } } /** * 拼接uuid * @param {string} value:uuid * @return {string} uuidSplit:拼接后的uuid */ function substringUUID(uuid: string): string { let subString = uuid?.substring(uuid.length - 12, uuid.length); let uuidSplit = '...' + subString; return uuidSplit; } /** * 裁剪ip * @param {string} ip:ip * @return {string} ip地址的最后一段 */ function splitIP(ip: string): string { let arr = ip.split(':'); return arr[arr.length - 1]; } /** * 判断字符是中文还是英文、数字 * @param {string} param:字符串 * @return {string} 中文 || 英文 || 数字 || 其他字符 */ function isChineseEngNum(param: string): string { let regExp1 = /[\u4e00-\u9fa5]+/; let regExp2 = /[a-zA-Z]+/; let regExp3 = /[0-9]+/; if (regExp1.test(param)) { return '中文'; } else if (regExp2.test(param)) { return '英文'; } else if (regExp3.test(param)) { return '数字'; } else { return '其他字符'; } } /** * 查找出一个字符串中的数字的个数,英文的个数,中文的个数,和其他的个数 * @param {any} params:一段字符或者其他类型 * @return {object} 返回数字的个数,英文的个数,中文的个数,和其他的个数 */ function stringTypeNum(params: any): object { let str = params.toString(); let strLength = str.length; let regExp1 = /[\u4e00-\u9fa5]+/g; let regExp2 = /\w+/g; let numberAndEngNum = 0, chineseNum = 0, otherNum = 0; // 英文和数字的个数 if (str.match(regExp2)) { let arr = str.match(regExp2); arr.forEach(function (element: any, index: number) { numberAndEngNum += arr[index].length; }); } else { numberAndEngNum = 0; } // 中文的个数 if (str.match(regExp1)) { let arr = str.match(regExp1); arr.forEach(function (element: any, index: number) { chineseNum += arr[index].length; }); } else { chineseNum = 0; } // 其他的个数 otherNum = strLength - chineseNum - numberAndEngNum; let obj = { numberAndEngNum: numberAndEngNum, chineseNum: chineseNum, otherNum: otherNum }; return obj; } /** * 往接口返回的数据增加相对应height和width,imgUrl * @param {string} name:名字 * @param {any} icon:往接口返回的数据 */ function setIconProperty(name: string, icon: any): void { switch (name) { case 'natData': // 往接口返回的nat网关数据增加相对应height和width,imgUrl { icon['height'] = NAT.height * SCALE; icon['width'] = NAT.width * SCALE; icon['imgUrl'] = NAT.imgUrl; icon['type'] = 'nat'; } break; case 'routeTableData': // 往接口返回的默认路由数据增加相对应height和width,imgUrl icon['height'] = ROUTE.height * SCALE; icon['width'] = ROUTE.width * SCALE; icon['imgUrl'] = ROUTE.imgUrl; icon['type'] = 'route'; break; case 'noMountSlb': // 往接口返回的默认路由数据增加相对应height和width,imgUrl icon['height'] = SLB.height * SCALE; icon['width'] = SLB.width * SCALE; icon['imgUrl'] = SLB.imgUrl; icon['type'] = 'slb'; break; case 'slb': // 往接口返回的slb由数据增加相对应height和width,imgUrl if (icon.length > 0) { icon[0][0].slb.height = SLB.height * SCALE; icon[0][0].slb.width = SLB.width * SCALE; icon[0][0].slb.imgUrl = SLB.imgUrl; icon[0][0].slb.type = 'slb'; } break; case 'vswitchData': // 往接口返回的交换机数据增加相对应height和width,imgUrl if (icon.length > 0) { icon.forEach(function (current: any) { current.height = SWITCH.height * SCALE; current.width = SWITCH.width * SCALE; current.imgUrl = SWITCH.imgUrl; current.type = 'switch'; // 往接口返回的云主机数据增加相对应height和width,imgUrl if (current.vmArray && current.vmArray.length > 0) { current.vmArray.forEach(function (vmCurrent: any) { vmCurrent.height = VM.height * SCALE; vmCurrent.width = VM.width * SCALE; vmCurrent.imgUrl = VM.imgUrl; vmCurrent.type = 'vm'; }); } if (current.rdsArray && current.rdsArray.length > 0) { current.rdsArray.forEach(function (rdsCurrent: any) { rdsCurrent.height = RDS.height * SCALE; rdsCurrent.width = RDS.width * SCALE; rdsCurrent.imgUrl = RDS.imgUrl; rdsCurrent.type = 'rds'; }); } }); } break; default: break; } } /** * 找出数组对象中的相同对象,把相同的对象选出来做成一个数组,再用一个大数组包含起来变成二位数组 * @param {Array} vmList * @return {any} 返回一个数组 */ function filter(vmList: Array): any { let slbArr = []; let obj: any = {}; vmList.forEach(function (n: any, index) { if (n['slb'] && n['slb']['id']) { if (obj.hasOwnProperty(n['slb']['id'])) { obj[n['slb']['id']].push(n); } else { obj[n['slb']['id']] = [n]; } } else { return; } }); for (let index in obj) { slbArr.push(obj[index]); } return slbArr; } /** * 模拟hover悬浮出弹框 * @param {any} canvasDom dom * @param {Array} allIconCoorArr 所有图标的坐标 * @param {object} DNAT_SNAT_Coor DNAT/SNAT的坐标 * @param {object} natData natData数据 * @param {string} platform pc || admin * @return void */ function simulateHoverClick(canvasDom: any, allIconCoorArr: Array, DNAT_SNAT_Coor: any, natData: any, platform: string): void { // 模拟hover悬浮出弹框 canvasDom.onmousemove = function (e: any) { // 给canvas添加点击事件 e = e || event; // 获取事件对象 // 获取事件在canvas中发生的位置 let x = e.offsetX; let y = e.offsetY; // 如果事件位置在图标区域中,悬浮弹框 if (allIconCoorArr.length > 0) { for (let i = 0; i < allIconCoorArr.length; i++) { // tslint:disable-next-line:max-line-length if (x >= allIconCoorArr[i]['leftCoordinate'].leftX && x <= allIconCoorArr[i]['rightCoordinate'].rightX && y >= allIconCoorArr[i]['leftCoordinate'].leftY - allIconCoorArr[i]['icon'].height / 2 && y <= allIconCoorArr[i]['leftCoordinate'].leftY + allIconCoorArr[i]['icon'].height / 2) { // tslint:disable-next-line:max-line-length x > 740 ? canvasTips('show', { cursorX: x - 230, cursorY: y + 20, icon: allIconCoorArr[i]['icon'] }) : canvasTips('show', { cursorX: x + 15, cursorY: y, icon: allIconCoorArr[i]['icon'] }); canvasDom.onmousedown = function () { return; }; break; // tslint:disable-next-line:max-line-length } else if (natData && x >= DNAT_SNAT_Coor['minX'] && x <= DNAT_SNAT_Coor['maxX'] && y >= DNAT_SNAT_Coor['minY'] && y <= DNAT_SNAT_Coor['maxY']) { canvasDom.onmousedown = function () { if (natData) { goNatDetail(natData['resourceUUID'], platform); } }; canvasDom.style.cursor = 'pointer'; } else { canvasTips('hidden'); canvasDom.onmousedown = function () { return; }; } } } }; } /** * 跳转到nat详情 * @param {string} uuid * @param {string} platform pc || admin */ function goNatDetail(uuid: string, platform: string) { switch (platform) { case 'pc': window.location.href = window.location.protocol + '//' + window.location.host + '/resource/nat/detail/' + uuid; break; case 'admin': window.location.href = window.location.protocol + '//' + window.location.host + '/resource/nat/detail/' + uuid; break; default: break; } } /** * 显示弹框的内容 * @param {any} parentId dom * @param {any} textNode 显示弹框的内容 */ function showTextNode(parentId: any, textNode: any): void { let parent: any = document.getElementById(parentId); parent.innerHTML = textNode; parent.style.display = 'block'; } /** * 往公网加入空格 * @param publicIP */ function publicIPAddSpace(publicIP: any) { let publicIPArr = publicIP.split(','); let text = ''; publicIPArr.forEach((element: any) => { text = text + element + '   '; }); return text; } /** * 显示悬浮框的数据 * @param {any} data */ function tipsBoxDataFun(data: any): void { // 显示别名和编号 data.about ? showTextNode('about-js', '别名:' + data.about) : showTextNode('about-js', '别名:-'); // tslint:disable-next-line:max-line-length data.resourceUUID ? showTextNode('uuid-js', '编号:' + data.resourceUUID) : (data.vmResourceUUID? data.vmResourceUUID : data.rdsResourceUUID) ? showTextNode('uuid-js', '编号:' + (data.vmResourceUUID? data.vmResourceUUID : data.rdsResourceUUID)) : showTextNode('uuid-js', '编号:-'); switch (data.type) { case 'switch': // 显示目标网段 // tslint:disable-next-line:max-line-length data.network && data.iMaskLength ? showTextNode('privateIP-js', '目标网段:' + data.network + '/' + data.iMaskLength) : showTextNode('privateIP-js', '目标网段:-'); showTextNode('publicIP-js', ''); break; case 'route': showTextNode('privateIP-js', ''); showTextNode('publicIP-js', ''); break; case 'nat': { showTextNode('privateIP-js', ''); let publicIP = publicIPAddSpace(data.publicIP); data.publicIP ? showTextNode('publicIP-js', '公网:' + publicIP) : showTextNode('publicIP-js', '公网:-'); } break; default: { // 显示公网和私网 let publicIP = publicIPAddSpace(data.publicIP); data.privateIP ? showTextNode('privateIP-js', '私网:' + data.privateIP) : showTextNode('privateIP-js', '私网:-'); data.publicIP ? showTextNode('publicIP-js', '公网:' + publicIP) : showTextNode('publicIP-js', '公网:-'); } break; } } /** * 显示或隐藏canvas的悬浮框 * @param {string} isShow 有两个值。show:显示,hidden:隐藏 * @param {object} info 数据 * @return void */ function canvasTips(isShow: string, info?: any): void { let tips: any = document.getElementById('canvas-tips-js'); let myCanvas: any = document.getElementById('myCanvas'); switch (isShow) { case 'show': { myCanvas.style.cursor = 'pointer'; tips.style.display = 'block'; tips.style.left = info['cursorX'] + 'px'; tips.style.top = info['cursorY'] + 'px'; tipsBoxDataFun(info['icon']); } break; case 'hidden': { myCanvas.style.cursor = 'default'; tips.style.display = 'none'; } break; default: break; } } /** * 动态获取图标右下角的矩形的宽 * @param {string} type 类型 * @param {number} nameWidth 名称字符串的长度 * @param {string} name 名称 * @return {object} {rectContent: 矩形里的内容,rectWidth: 矩形的宽度} */ function getRectWidth(type: string, nameWidth: number, name: string): object { let rectContent, rectWidth: any; let regChinese = /[\u4e00-\u9fa5]+/; let regExp = /...+/; if (type) { switch (type) { case 'nat': if (nameWidth > 85) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 6) + '...' : regExp.test(name) ? rectContent = name : rectContent = name.substring(0, 11) + '...'; rectWidth = 85; } else { rectContent = name; rectWidth = nameWidth; } break; case 'route': if (nameWidth > 85) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 6) + '...' : regExp.test(name) ? rectContent = name : rectContent = name.substring(0, 11) + '...'; rectWidth = 85; } else { rectContent = name; rectWidth = nameWidth; } break; case 'slb': if (nameWidth > 85) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 6) + '...' : regExp.test(name) ? rectContent = name : rectContent = name.substring(0, 11) + '...'; rectWidth = 85; } else { rectContent = name; rectWidth = nameWidth; } break; case 'switch': if (nameWidth > 60) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 4) + '...' : regExp.test(name) ? rectContent = '...' + name.substring(name.length - 6, name.length) : rectContent = name.substring(0, 7) + '...'; rectWidth = 60; } else { rectContent = name; rectWidth = nameWidth; } break; case 'vm': if (nameWidth > 85) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 6) + '...' : regExp.test(name) ? rectContent = name : rectContent = name.substring(0, 11) + '...'; rectWidth = 85; } else { rectContent = name; rectWidth = nameWidth; } break; case 'rds': if (nameWidth > 85) { // tslint:disable-next-line:max-line-length regChinese.test(name) ? rectContent = name.substring(0, 6) + '...' : regExp.test(name) ? rectContent = name : rectContent = name.substring(0, 11) + '...'; rectWidth = 85; } else { rectContent = name; rectWidth = nameWidth; } break; default: break; } } let obj = { rectContent: rectContent, rectWidth: rectWidth + 10 }; return obj; } /** * 拓扑图实现缩小方法功能 * @param {*} void *@return {*} void */ function scaleCanvas(): void { let addCanvas: any = document.getElementById('canvas-add-js'); let reduceCanva: any = document.getElementById('canvas-reduce-js'); let canvasContainer: any = document.getElementById('canvas-container-js'); let scaleDefault: any = document.getElementById('scale-default-js'); let scalePercentage: any = document.getElementById('scale-percentage-js'); // 缩放的比例 let canvasScale = 1; addMouseWheelEvent(canvasContainer, mousewheel); // 点击加号放大拓扑图 addCanvas.onclick = function () { canvasScale = canvasScale + 0.05; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; }; // 点击减号缩小拓扑图 reduceCanva.onclick = function () { canvasScale = canvasScale > 0.15 ? canvasScale - 0.05 : 0.1; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; }; /** * 使用鼠标的滚轮实现canvas方法或者缩小拓扑图 * @param {*} e */ function mousewheel(e: any) { // 取消默认事件 e.preventDefault(); // 处理兼容问题 谷歌浏览器、ie浏览器 if (('wheelDelta' in e) && e.wheelDelta < 0) { canvasScale = canvasScale > 0.15 ? canvasScale - 0.05 : 0.1; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; } else if (('wheelDelta' in e) && e.wheelDelta > 0) { canvasScale = canvasScale + 0.05; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; } // 兼容火狐浏览器 if (('detail' in e) && e.detail > 0) { canvasScale = canvasScale > 0.15 ? canvasScale - 0.05 : 0.1; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; } else if (('detail' in e) && e.detail < 0) { canvasScale = canvasScale + 0.05; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; } } // 还原缩放比例 scaleDefault.onclick = function () { canvasScale = 1; canvasContainer.style.transform = 'scale(' + canvasScale + ',' + canvasScale + ')'; scalePercentage.innerHTML = '缩放 ' + Math.round(canvasScale * 100) + '%'; let canvasDiv: any = document.getElementById('canvas-container-js'); canvasDiv.style.left = '0px'; canvasDiv.style.top = '0px'; }; } /** * 兼容火狐和其他浏览器 * @param {*} element dom * @param {*} func 方法 * @return {*} void */ function addMouseWheelEvent(element: any, func: any): void { // 其他浏览器 if (typeof element.onmousewheel === 'object') { element.onmousewheel = function (e: any) { func(e); }; } // 火狐 if (typeof element.onmousewheel === 'undefined') { element.addEventListener('DOMMouseScroll', func, false); } } /** * 实现拖拉 * @param myCanvas */ function dragCanvas(myCanvas: any) { let canvasDivParent: any = document.querySelector('#canvas-container-parent-js'); let canvasDiv: any = document.querySelector('#canvas-container-js'); let divX = 0, divY = 0, mbuttonType = false, divLeft = canvasDiv.offsetLeft, divTop = canvasDiv.offsetTop; canvasDivParent.addEventListener('mousedown', function (e: any) { divX = e.clientX; divY = e.clientY; mbuttonType = true; myCanvas.style.cursor = 'move'; }); canvasDivParent.addEventListener('mousemove', function (e: any) { e.preventDefault(); if (mbuttonType) { myCanvas.style.cursor = 'move'; let diffx = e.clientX - divX; let diffy = e.clientY - divY; divLeft += diffx; divTop += diffy; canvasDiv.style.left = divLeft + 'px'; canvasDiv.style.top = divTop + 'px'; divX = e.clientX; divY = e.clientY; } }); canvasDivParent.addEventListener('mouseup', function (e: any) { mbuttonType = false; myCanvas.style.cursor = 'default'; }); canvasDivParent.addEventListener('mouseleave', function (e: any) { mbuttonType = false; myCanvas.style.cursor = 'default'; }); } function canvasHeight(dom: any, res: any) { // heightIndex:计算画布的高,云主机和rds的个数加上没有连接云主机的交换机个数 let heightIndex: number = 0; if (res.data.vswitchData && res.data.vswitchData.length > 0) { // res.data.vswitchData.forEach(function (current, index) { // if (current.vmArray && current.vmArray.length > 0) { // heightIndex += current.vmArray.length; // } else { // heightIndex++; // } // if (current.rdsArray && current.rdsArray.length > 0) { // heightIndex += current.rdsArray.length; // } else { // heightIndex++; // } res.data.vswitchData.forEach(function (current: any, index: number) { // vm和rds图在同一列的位置,所以高度计算应该叠加 if (current.vmArray && current.vmArray.length > 0 || current.rdsArray && current.rdsArray.length > 0) { heightIndex += (current.vmArray.length + current.rdsArray.length); } else { heightIndex++; } }); let lastSwitch = res.data.vswitchData[res.data.vswitchData.length - 1]; let switchLength = res.data.vswitchData.length; if (switchLength === 1 && (lastSwitch.vmArray.length + lastSwitch.rdsArray.length) < 2) { dom.height = 500; return; } // 主机和rds的高度是一样的,这里直接用主机的高度做计算即可 if (switchLength > 1 && (lastSwitch.vmArray.length + lastSwitch.rdsArray.length) < 2) { dom.height = heightIndex * 2 * (VM.height * SCALE) + VM.height; } else { dom.height = heightIndex * 2 * (VM.height * SCALE) + res.data.vswitchData.length * (VM.height * SCALE / 2) - VM.height * SCALE / 2; } // if (switchLength === 1 && (lastSwitch.rdsArray.length === 0 || lastSwitch.rdsArray.length === 1)) { // dom.height = 500; // return; // } // // tslint:disable-next-line:max-line-length // if (switchLength > 1 && (lastSwitch.vmArray.length === 0 || lastSwitch.vmArray.length === 1)) { // dom.height = heightIndex * 2 * (VM.height * SCALE) + VM.height; // } else { // dom.height = heightIndex * 2 * (VM.height * SCALE) + res.data.vswitchData.length * (VM.height * SCALE / 2) - VM.height * SCALE / 2; // } // if (switchLength > 1 && (lastSwitch.rdsArray.length === 0 || lastSwitch.rdsArray.length === 1)) { // dom.height = heightIndex * 2 * (RDS.height * SCALE) + RDS.height; // } else { // dom.height = heightIndex * 2 * (RDS.height * SCALE) + res.data.vswitchData.length * (RDS.height * SCALE / 2) - RDS.height * SCALE / 2; // } } else { dom.height = 500; } } // tslint:disable-next-line:max-line-length export { isValueExsit, substringUUID, splitIP, isChineseEngNum, NAT, SLB, SWITCH, ROUTE, VM, RDS, DNAT_SNAT, setIconProperty, filter, simulateHoverClick, canvasTips, SCALE, stringTypeNum, getRectWidth, scaleCanvas, dragCanvas, canvasHeight };