NEZ-2649 fix: project topo 重构

This commit is contained in:
zhangyu
2023-03-09 15:20:09 +08:00
parent 582c3bcefa
commit 43ad9ef746
9 changed files with 581 additions and 23 deletions

View File

@@ -22,3 +22,308 @@
right: unset;
left: 0px;
}
.meta2d-box {
@keyframes model-error-animation {
0% {
transform: scale(0.7);
}
50% {
transform: scale(1);
}
100% {
transform: scale(0.7);
}
}
@keyframes model-icon-animation {
0% {
transform: scale(1.2) translateX(1px);
}
50% {
transform: scale(0.9) translateX(0px);
}
100% {
transform: scale(1.2) translateX(1px);
}
}
.nz-icon-shuidi {
position: absolute;
font-size: 48px;
color: rgba(190, 233, 222, 0.45);
border-radius: 50%;
height: 48px;
width: 48px;
line-height: 48px;
}
.el-collapse-item__arrow.el-icon-arrow-right{
display: none !important;
}
.el-collapse-item .is-active .nz-icon-arrow-right{
transform: rotate(90deg);
color: $--color-primary;
}
.el-collapse-item .title-delete{
display: none;
}
.el-collapse-item .nz-icon-arrow-right{
transition: transform .3s;
color: #BEBEBE;
margin-right: 5px;
}
.el-collapse-item:hover{
.el-collapse-item__header{
color: $--color-primary;
}
.nz-icon-arrow-right{
color: $--color-primary;
}
.title-delete{
display: block;
color: $--color-primary;
}
}
.edit-topologyLine{
//background: rgba(196,196,196,0.4) !important;
border-bottom: 1px solid $--explore-border-color-bottom;
}
.topology-scroll{
&.v{
display: none;
}
&.h{
display: none;
}
}
.model-error.nz-icon-shuidi {
color: #FADED7;
animation: model-error-animation .6s infinite ease-in-out;
animation-direction: normal;
}
.model-error-active.nz-icon-shuidi {
color: #FADED7;
}
.nz-icon-model {
color: #23BF9A;
position: absolute;
top: -4px;
left: 15px;
font-size: 18px;
line-height: 48px;
}
.model-error .nz-icon-model {
color: #EC7F66;
animation: model-icon-animation .6s infinite ease-in-out;
animation-direction: normal;
}
.model-error-active .nz-icon-model {
color: #EC7F66;
}
.scaleTool-enter-active {
animation: scaleTool-in .15s;
}
.scaleTool-leave-active {
animation: scaleTool-in .15s reverse;
}
@keyframes scaleTool-in {
from {
top: 0;
left: 0;
transform: scale(0.5);
}
}
.module-rect-top{
border-top: 4px dashed #ff8c0a;
position: absolute;
}
.module-rect-right{
border-right: 4px dashed #ff8c0a;
position: absolute;
}
.module-rect-bottom{
border-bottom: 4px dashed #ff8c0a;
position: absolute;
}
.module-rect-left{
border-left: 4px dashed #ff8c0a;
position: absolute;
}
.network-pop .nz-icon-hexagonBorder{
position: absolute;
font-size: 48px;
color: #84d5c2;
height: 48px;
width: 48px;
line-height: 48px;
}
.network-pop .nz-icon-hexagonBorder:hover {
transform: scale(1.1);
color: #4BB49B;
}
.network-pop .nz-icon-hexagonBorder.error-model-stat {
color: #F5BAAC;
}
.network-pop .nz-icon-hexagonBorder.error-model-stat:hover {
color: #EC7F66;
}
.network-pop .nz-icon-liubianxing {
color: #e2f3ef;
font-size: 44px;
position: absolute;
top: 0px;
left: 2px;
// transform: scale(1.1);
z-index: -1;
}
.network-pop .error-model-stat .nz-icon-liubianxing {
color: #FADED7;
}
.network-pop .nz-icon.noMove {
position: absolute;
left: 14px;
font-size: 20px;
color: #27c09c;
}
.network-pop .error-model-stat .nz-icon.noMove {
color: #EC7F66;
}
.network-pop .no-selPop {
color: $--color-text-secondary !important;
}
.network-pop .no-selPop .nz-icon-liubianxing {
color: rgb(218, 218, 218);
}
.network-pop .no-selPop .nz-icon-chart {
color: $--color-text-secondary;
}
.network-info {
position: absolute;
right: 0;
top: 50px;
z-index: 1;
}
.facade-top{
min-height: 138px;
display: flex;
margin: 4px 0;
height: calc(16% - 40px);
font-size: 12px;
z-index: 10;
padding-left: 15px;
}
.facade-top > div{
width: 18%;
min-width: 315px;
background: $--background-color-empty;
margin-right: 9px;
padding: 20px;
border: 1px solid $--background-color-empty;
box-shadow: 1px 2px 4px 0 rgba(0,0,0,0.12), -1px 1px 9px -1px rgba(205,205,205,0.77);
}
.facade-top-title{
font-size: 16px;
color: $--color-text-primary;
font-weight: bold;
padding: 5px 0;
}
.facade-top-left{
display: flex;
flex-direction: column;
justify-content: space-around;
}
.special.label{
margin-left: 30px;
}
.facade-top .facade-top-right{
width: auto;
min-width: 100px;
}
.facade-top-right-content{
display: flex;
justify-content: space-around;
justify-items: center;
flex-direction: column;
height: calc(100% - 30px);
align-items: flex-start;
}
.facade-top-right-content > div{
min-width: 84px;
height: 22px;
display: flex;
justify-content: space-between;
color: #fff;
text-align: center;
margin-bottom: 5px;
line-height: 22px;
}
.facade-top-right-content > div > div:last-child{
text-align: center;
border-radius: 0 4px 4px 0;
flex: 1;
height: calc(100% - 2px);
padding: 0 8px;
min-width: 40px;
}
.content-P1-title{
background: #F2866E;
border-radius: 4px 0 0 4px;
width: 40px;
height: 100%;
}
.content-P1-title + div{
border: 1px solid #F4907A;
font-size: 12px;
color: #F4907A;
}
.content-P2-title{
background: #F89984;
border-radius: 4px 0 0 4px;
width: 40px;
height: 100%;
}
.content-P2-title + div{
border: 1px solid #F9A28F;
font-size: 12px;
color: #F9A28F;
}
.content-P3-title{
background: #F7BA78;
border-radius: 4px 0 0 4px;
width: 40px;
height: 100%;
}
.content-P3-title + div{
border: 1px solid #F7BA78;
font-size: 12px;
color: #F7BA78;
}
.right-content-P1{
border: 1px solid ;
}
.align--center{
text-align: center;
}
}

View File

@@ -41,7 +41,44 @@ export default {
top: null,
bottom: null
},
setContextmenu: true
popDataShow: {
endpoint: false,
asset: false,
total: false,
other: false,
info: false,
alert: false,
main: false
},
projectInfo: {
title: '',
id: '',
remark: '',
alertStat: [1, 2, 3],
moduleMum: 6,
loading: true
},
setContextmenu: true,
modules: [],
allModules: [],
popData: [
{
top: '-41px',
left: '-23px',
className: 'nz-icon-endpoint',
id: 'endpoint',
title: this.$t('project.topology.endpoint')
},
{ top: '-41px', left: '22px', className: 'nz-icon-asset', id: 'asset', title: this.$t('asset.asset') },
{ top: '-2px', left: '45px', className: '', id: 'other', title: '' },
{ top: '37px', left: '22px', className: '', id: 'other', title: '' },
{ top: '37px', left: '-23px', className: 'nz-icon-info-normal', id: 'info', title: this.$t('project.topology.info') },
{ top: '-2px', left: '-45px', className: 'nz-icon-gaojing', id: 'alert', title: this.$t('project.topology.alert') }
],
nodesArr: [],
offsetX: 0,
offsetY: 0,
moduleId: ''
}
},
mixins: [topoUtil],
@@ -79,6 +116,7 @@ export default {
return true
}
meta2d.on('translate', this.topTranslate) // 平移·
meta2d.on('scale', this.topoScale) // 缩放·
meta2d.on('active', this.pensActive) // 选中·
// meta2d.on('translatePens', () => {}) // 移动画笔结束·
// meta2d.on('translatingPens', () => {}) // 移动画笔进行中·
@@ -94,10 +132,12 @@ export default {
const startTime = endTime - 60 * this.params.timeType * 1000
this.getQueryValues(this.querysArray, startTime, endTime).then((arr) => {
this.clacTopoData(this.topoData, arr).then((data) => {
this.getModule()
getTopology(this.meta2dId).resize()
getTopology(this.meta2dId).open(data)
getTopology(this.meta2dId).centerView()
getTopology(this.meta2dId).lock(1)
this.getNodesArr()
})
})
},
@@ -135,6 +175,7 @@ export default {
}
}
pen.nzName = name
pen.moduleId = ''
pen.disableInput = pen.disableInput || true
pen.background = pen.background || '#22222200'
pen.textAlign = pen.textAlign || 'center'
@@ -181,6 +222,7 @@ export default {
}
}
pen.nzName = name
pen.moduleId = ''
pen.disableInput = pen.disableInput || true
pen.lineAnimateType = pen.lineAnimateType || 0
pen.animateSpan = pen.animateSpan || 1
@@ -202,7 +244,7 @@ export default {
},
pensActive (pens, e) { // 选中节点
this.selectPens = pens
this.modulesDiff(pens[0])
setTimeout(() => {
this.$refs.meta2dProps && (this.$refs.meta2dProps.isUpdate = true)
})
@@ -212,9 +254,21 @@ export default {
this.$refs.meta2dProps.activeName = 'canvas'
this.selectPens = []
}
this.showNodeTools()
this.popDataShowUpdate('', true)
},
topTranslate () {
this.setContextmenu = false
this.offsetX = getTopology(this.meta2dId).store.data.x
this.offsetY = getTopology(this.meta2dId).store.data.y
this.showNodeTools()
this.popDataShowUpdate('', true)
},
topoScale () {
this.offsetX = getTopology(this.meta2dId).store.data.x
this.offsetY = getTopology(this.meta2dId).store.data.y
this.showNodeTools()
this.popDataShowUpdate('', true)
},
penEnter (pen, e) { // 移入节点
if (this.timer3) {
@@ -360,7 +414,120 @@ export default {
top: null,
bottom: null
}
}
},
// 获取module
getModule () {
this.projectInfo.loading = true
this.$get('/monitor/module?pageSize=-1&projectIds=' + this.project.id).then(response => {
if (response.code === 200) {
this.projectInfo.loading = false
this.allModules = JSON.parse(JSON.stringify(response.data.list))
// this.modulesDiff()
}
})
},
// 摘除已选择的module 置灰
modulesDiff (pen) {
this.modules = this.allModules
if (getTopology(this.meta2dId) && getTopology(this.meta2dId).store.data.pens) {
getTopology(this.meta2dId).store.data.pens.forEach(item => {
if (!item.type && item.moduleId) {
const findItem = this.modules.find(item1 => item.moduleId == item1.id)
if (findItem && pen && findItem.id !== pen.moduleId) {
findItem.disabled = true
} else {
findItem.disabled = false
}
}
})
}
},
// 显示module的工具
showNodeTools (index, pen) {
this.nodesArr.forEach((item, i) => {
item.moduleData.show = i == index
})
},
// 具体内容点击
nodeTools (node, tool) {
this.moduleId = node.moduleId
this.moduleName = node.moduleName
if (tool.id === 'total') {
this.popDataShowUpdate('', false, node)
return
}
const timer = setTimeout(() => {
this.popDataShowUpdate(tool.id, false, node)
clearTimeout(timer)
}, 100)
},
selpopIs (pen, state) { // 判断是否有图表
let flag = true
if (state.id === 'other') {
flag = false
}
if (state.id === 'total' && pen.data.expressArr.length === 0) {
flag = false
}
return flag
},
getNodesArr () {
if (!getTopology(this.meta2dId)) return
this.offsetX = getTopology(this.meta2dId).data().x
this.offsetY = getTopology(this.meta2dId).data().y
this.nodesArr = getTopology(this.meta2dId).store.data.pens.filter(item => {
item.moduleData = {
moduleId: '',
moduleName: '',
show: false,
error: false,
expressArr: [],
expressAllArr: [],
state: {
error: false,
asset: 0,
alert: 0,
endpoint: 0
}
}
if (!item.type && item.moduleId) {
this.$get('stat/module/abnormal', { moduleId: item.moduleId }).then(res=>{
if (res.code == 200) {
const module = res.data.list[0]
item.moduleData.state.error = item.moduleData.error = !module.state
item.moduleData.state.asset = !!module.asset
item.moduleData.state.alert = !!module.alert
item.moduleData.state.endpoint = !!module.endpoint
}
})
}
return !item.type && item.moduleId
})
},
popDataShowUpdate (key, flag, node) { // key 显示对应的弹窗 flag是否不显示工具栏
this.popDataShow = {
endpoint: false,
asset: false,
total: false,
other: false,
info: false,
alert: false,
main: false
}
if (key === 'total') {
this.chartDataInfo = { ...node.data, ...this.chartGetData.find(item => item.id === node.id) }
}
this.$nextTick(() => {
this.popDataShow[key] = true
})
if (flag) { // 处理关闭后 缩放后显示工具按钮的问题
this.moduleId = ''
this.showNodeTools()
}
if (key === 'asset' || key === 'alert' || key === 'endpoint') {
this.showNodeTools()
}
},
},
beforeDestroy () {
}

View File

@@ -7,6 +7,7 @@ export default {
methods: {
topoResize (id) {
getTopology(id).resize()
getTopology(id).centerView()
},
initEdit (id) {
bus.$emit('changeSelectPens', [])
@@ -18,7 +19,6 @@ export default {
this.calcNode(item)
})
}
getTopology(id).centerView()
getTopology(id).render()
},
calcNode (node) { // 处理节点数据
@@ -144,6 +144,9 @@ export default {
if (!pen.nzName) {
pen.nzName = ''
}
if (!pen.moduleId) {
pen.moduleId = ''
}
if (pen.isNz) {
if (pen.data.legend && pen.data.enable.valueMapping) {
const findItem = queryValues.find(query => query.name === pen.data.legend && query.parent === pen.data.parent)

View File

@@ -124,7 +124,9 @@ export default {
background: '#ffffff00',
bkImage: '',
bkImageId: '',
selectPenArr: {},
selectPenArr: {
active: []
},
nodesAlign: [// 对齐方式
{
value: 'left',
@@ -163,7 +165,7 @@ export default {
desc: '垂直等距分布',
icon: 'nz-icon-shuxiangfenbu'
}
]
],
}
},
mounted () {

View File

@@ -5,6 +5,15 @@
<!-- node-->
<div v-if="!pen.type">
<div class="form-row-box">
<!-- Module -->
<div class="form-row-title">
{{$t('overall.module')}}
</div>
<div v-show="elements.position" class="form-row-content">
<el-select v-model="pen.moduleId" @change="change('moduleId')" size="small">
<el-option v-for="item in modules" :value="item.id" :key="item.id" :label="item.name" :disabled="item.disabled"/>
</el-select>
</div>
<!-- Position -->
<div class="form-row-title">
{{$t('project.topology.position')}}
@@ -1022,7 +1031,8 @@ export default {
},
props: {
selectPens: {},
elements: {}
elements: {},
modules: {}
},
watch: {
selectPens: {

View File

@@ -95,9 +95,9 @@ export default {
editMeta2d () {
this.topoScreenState = JSON.parse(JSON.stringify(this.topoScreen))
this.$store.commit('setShowTopoScreen', true)
this.$emit('edit')
this.initEdit(this.meta2dId)
setTimeout(() => {
this.$emit('edit')
this.initEdit(this.meta2dId)
this.topoResize(this.meta2dId)
})
},
@@ -187,8 +187,10 @@ export default {
}
getTopology(this.meta2dId).render()
getTopology(this.meta2dId).centerView()
this.$emit('getNodesArr')
},
cancelTopology () {
this.isPreview = false
this.$store.commit('setShowTopoScreen', this.topoScreenState)
if (this.$refs.topTool.option.map) {
getTopology(this.meta2dId).hideMap()

View File

@@ -1,5 +1,5 @@
<template>
<div class="meta2d-box list-page" :class="editFlag ? 'topology-dialog' : ''" v-my-loading="meta2dLoading" ref="meta2dBox">
<div class="meta2d-box list-page" :class="editFlag ? 'topology-dialog' : ''" v-my-loading="meta2dLoading" ref="meta2dBox" v-clickoutside="showNodeTools">
<meta2dHeader
ref="header"
:meta2dId="meta2dId"
@@ -9,13 +9,44 @@
@edit="beforeEdit"
@exitEdit="exitEdit"
@reload="reload"
@getNodesArr="getNodesArr"
/>
<div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'" @contextmenu="onContextMenu($event)">
<div class="meta2d-main" :class="isChart ? 'meta2d-chart': 'meta2d-project'" @contextmenu="onContextMenu($event)" style="position: relative">
<div v-for="(item,index) in nodesArr" v-if="!editFlag&&!isPreview"
:key="index"
v-show="(item.y + offsetY - 48 > -20) && (item.x + item.width/2 + offsetX - 24 > - 20)"
:style="{position: 'absolute',top:item.y + offsetY - 48 + 'px',left:item.x + item.width/2 + offsetX - 24 +'px', 'z-index': 10}"
class="network-pop"
@click="showNodeTools(index,item)"
>
<i
:ref="'modelTopId'+index"
:class="{'nz-icon':true, 'nz-icon-shuidi':true,'model-error':item.moduleData.state&&item.moduleData.state.error&&!item.moduleData.show,'model-error-active':item.moduleData.state&&item.moduleData.state.error&&item.moduleData.show}"
>
<i style="cursor: pointer" class="nz-icon nz-icon-model"></i>
</i>
<!--'selpop':selpopIs(item),'no-selPop':!selpopIs(item),'error-model-stat':modelPopError(item) @click="popClick(item.id)" -->
<div v-for="(item1, index) in popData" :key="index">
<transition name="scaleTool">
<i v-if="item.moduleData.show"
:class="{'nz-icon':true,'nz-icon-hexagonBorder':true,'error-model-stat':item.moduleData.state[item1.id],'selpop':selpopIs(item,item1),'no-selPop':!selpopIs(item,item1),}"
:style="{top:item1.top,left:item1.left}"
:title="item1.title"
@click.stop="nodeTools(item,item1)"
>
<i class="nz-icon nz-icon-liubianxing"></i>
<i :class="[item1.className,{'nz-icon':item1.className},'noMove']"></i>
</i>
</transition>
</div>
</div>
<div :id="meta2dId" style="height: 100%;width: 100%"></div>
</div>
<meta2dProps
v-if="editFlag && !isPreview"
v-if="editFlag || isPreview"
ref="meta2dProps"
:modules="modules"
:selectPens.sync="selectPens"
:querysArray="querysArray"
:params="params"
@@ -40,6 +71,33 @@
:params="chartParams"
/>
</div>
<!--悬浮network部分-->
<div class="network-info">
<div v-if="popDataShow.main">
<popDataMain :moduleId="moduleId" :projectId="project.id"></popDataMain>
</div>
<div v-if="popDataShow.info">
<popDataInfo :moduleId="moduleId" :projectId="project.id"></popDataInfo>
</div>
</div>
<!--endpoint-->
<transition name="right-box">
<endpointTable v-if="popDataShow.endpoint" :moduleId="moduleId" :moduleName="moduleName" :projectId="project.id"
@close="popDataShowUpdate('',true)">
</endpointTable>
</transition>
<!--asset-->
<transition name="right-box">
<assetTable v-if="popDataShow.asset" :moduleId="moduleId" :moduleName="moduleName" :projectId="project.id"
@close="popDataShowUpdate('',true)">
</assetTable>
</transition>
<!--alert-->
<transition name="right-box">
<alertTable v-if="popDataShow.alert" :moduleId="moduleId" :moduleName="moduleName" :projectId="project.id"
@close="popDataShowUpdate('',true)">
</alertTable>
</transition>
</div>
</template>
@@ -49,6 +107,11 @@ import meta2dProps from '@/components/common/project/meta2d/meta2dProps'
import meta2dMain from '@/components/common/project/meta2d/js/meta2dMain'
import meta2dTooltip from '@/components/common/project/meta2d/meta2dTooltip'
import CanvasContextMenu from '@/components/common/project/meta2d/CanvasContextMenu'
import popDataMain from '@/components/common/project/popData/Main'
import popDataInfo from '@/components/common/project/popData/Info'
import alertTable from '@/components/common/project/popData/alertTable'
import assetTable from '@/components/common/project/popData/assetTable'
import endpointTable from '@/components/common/project/popData/endpointTable'
import { getTopology, setTopology } from '@/components/common/js/common'
import topoUtil from '@/components/common/project/meta2d/js/topoUtil'
import bus from '@/libs/bus'
@@ -64,18 +127,23 @@ export default {
},
querysArray: {},
params: {},
project: {}
project: {},
},
computed: {
isPreview () {
return this.$refs.header && this.$refs.header.isPreview
}
},
},
components: {
meta2dHeader,
meta2dProps,
meta2dTooltip,
CanvasContextMenu
CanvasContextMenu,
popDataMain,
popDataInfo,
alertTable,
assetTable,
endpointTable
},
watch: {
topoData: {

View File

@@ -2,7 +2,7 @@
<div class="props-box props" @keypress.stop="" @keydown.stop="" @keyup.stop="">
<el-tabs v-model="activeName" type="card" :before-leave="beforeLeave">
<el-tab-pane :label="$t('project.topology.element')" name="elements" v-if="selectPens.length === 1">
<meta2dElement :selectPens.sync="selectPens" @change="change" :elements="elements"/>
<meta2dElement :modules="modules" :selectPens.sync="selectPens" @change="change" :elements="elements"/>
</el-tab-pane>
<el-tab-pane :label="$t('project.topology.canvas')" name="canvas">
<meta2dCanvas :canvasProps="canvasProps" :params.sync="params" :meta2dId='meta2dId' @changeActiveName="changeActiveName" ref ='meta2dCanvas'/>
@@ -32,7 +32,8 @@ export default {
selectPens: {},
querysArray: {},
params: {},
meta2dId: {}
meta2dId: {},
modules: {}
},
components: {
meta2dElement,

View File

@@ -235,12 +235,6 @@
<div class="content">No data</div>
</div>
</div>
<!--endpoint-->
<transition name="right-box">
<endpointTable v-if="popDataShow.endpoint" :moduleId="moduleId" :moduleName="moduleName" :projectId="projectInfo.id"
@close="popDataShowUpdate('',true)">endpoint
</endpointTable>
</transition>
<div v-if="!fromOverView&&!editTopologyFlag&&!fromPrev" class="right-bottom-zoom">
<div class="zoom-option" style="border-bottom: 1px solid #c5c8cb;" @click="zoomMap(0.25)" :title="$t('overall.enlargement')"><span><i class="nz-icon nz-icon-enlarge"></i></span></div>
<div class="zoom-option" @click="zoomMap(-0.25)" :title="$t('overall.shrink')"><span><i class="nz-icon nz-icon-narrow"></i></span></div>
@@ -257,6 +251,12 @@
<!--<li>3.选中元素 按下Delete键或者Backspace可以删除元素</li>-->
<!--</ul>-->
<!--</div>-->
<!--endpoint-->
<transition name="right-box">
<endpointTable v-if="popDataShow.endpoint" :moduleId="moduleId" :moduleName="moduleName" :projectId="projectInfo.id"
@close="popDataShowUpdate('',true)">endpoint
</endpointTable>
</transition>
<!--asset-->
<transition name="right-box">
<assetTable v-if="popDataShow.asset" :moduleId="moduleId" :moduleName="moduleName" :projectId="projectInfo.id"