cloud-ui/src/views/quest/node/components/node-item.vue

260 lines
6.3 KiB
Vue

<template>
<div class="node-item" ref="node"
:class="[(isActive || isSelected) ? 'active' : '']"
:style="flowNodeContainer"
v-click-outside="setNotActive"
@click="setActive"
@mouseenter="showAnchor"
@mouseleave="hideAnchor"
@dblclick.prevent="editNode"
@contextmenu.prevent="onContextmenu">
<div class="log-wrap">
<img :src="node.logImg" alt="">
</div>
<div class="nodeName">{{node.nodeName}}</div>
<!--连线用--//触发连线的区域-->
<div class="node-anchor anchor-top" v-show="mouseEnter"></div>
<div class="node-anchor anchor-right" v-show="mouseEnter"></div>
<div class="node-anchor anchor-bottom" v-show="mouseEnter"></div>
<div class="node-anchor anchor-left" v-show="mouseEnter"></div>
<!-- <el-dialog :visible.sync="updNameFlag" width="30%">-->
<!-- <el-form v-model="node">-->
<!-- <el-form-item label="节点名称">-->
<!-- <el-input v-model="newNodeName" placeholder="请输入内容" />-->
<!-- </el-form-item>-->
<!-- <el-form-item>-->
<!-- <el-button type="primary" @click="doUpdName"> </el-button>-->
<!-- </el-form-item>-->
<!-- </el-form>-->
<!-- </el-dialog>-->
</div>
</template>
<script>
import ClickOutside from 'vue-click-outside'
export default {
name: "nodeItem",
props: {
node: Object
},
directives: {
ClickOutside
},
computed: {
// 节点容器样式
flowNodeContainer: {
get() {
return {
top: this.node.top,
left: this.node.left
};
}
}
},
data() {
return {
// updNameFlag: false,
// newNodeName: '',
mouseEnter: false,
isActive: false,
isSelected: false
};
},
methods: {
showAnchor() {
this.mouseEnter = true
},
hideAnchor() {
this.mouseEnter = false
},
onContextmenu() {
this.$contextmenu({
items: [{
label: '修改名称',
disabled: false,
icon: "",
onClick: () => {
// this.toUpdName();
this.newNodeName = prompt("请输入新名称:");
if (this.newNodeName !== null) {
this.$emit('setNodeName', this.node.id, this.newNodeName)
} else {
alert("操作取消!");
}
}
},{
label: '删除节点',
disabled: false,
icon: "",
onClick: () => {
this.deleteNode()
}
}],
event,
customClass: 'custom-class',
zIndex: 9999,
minWidth: 180
})
},
setActive() {
if (window.event.ctrlKey) {
this.isSelected = !this.isSelected
return false
}
this.isActive = true
this.isSelected = false
setTimeout(() => {
this.$emit("changeLineState", this.node.id, true)
}, 0)
},
setNotActive() {
if (!window.event.ctrlKey) {
this.isSelected = false
}
if (!this.isActive) {
return
}
this.$emit("changeLineState", this.node.id, false)
this.isActive = false
},
editNode() {
this.newNodeName = prompt("请输入新名称:");
if (this.newNodeName !== null) {
this.$emit('setNodeName', this.node.id, this.newNodeName)
} else {
alert("操作取消!");
}
},
deleteNode() {
this.$emit("deleteNode", this.node)
},
// toUpdName() {
// this.updNameFlag = true
// },
// doUpdName() {
// this.$emit('setNodeName', this.node.id, this.newNodeName)
// this.updNameFlag = false
// },
/** jsPlumb节点类型 --> 数据库节点类型 */
toMysqlNode(node,preLine,nextLine){
return {
id: node.authId,
nodeType: node.type,
nodeCode: node.id,
nodeName: node.nodeName,
nodePositionTop: node.top,
nodePositionLeft: node.left,
nodePreCode: preLine,
nodeNextCode: nextLine,
state: 'Y'
}
},
/** 数据库节点类型 --> jsPlumb节点类型 */
toJsPlumbNode(nodeInfo){
const node = {
authId: nodeInfo.id,
id: nodeInfo.nodeCode,
type: nodeInfo.nodeType,
nodeName: nodeInfo.nodeName,
top: nodeInfo.nodePositionTop,
left: nodeInfo.nodePositionLeft
}
const line = []
// 节点有后继节点
if (nodeInfo.nodeNextCode){
const nextLine = {
from: nodeInfo.nodeCode,
to: nodeInfo.nodeNextCode
}
line.push(nextLine)
}
// 节点有前驱节点
if (nodeInfo.nodePreCode){
const perLine = {
from: nodeInfo.nodePreCode,
to: nodeInfo.nodeCode
}
line.push(perLine)
}
return {
node: node,
line: line
}
}
}
};
</script>
<style lang="less" scoped>
@labelColor: #409eff;
@nodeSize: 20px;
@viewSize: 10px;
.node-item {
position: absolute;
display: flex;
height: 40px;
width: 120px;
justify-content: center;
align-items: center;
border: 1px solid #b7b6b6;
border-radius: 4px;
cursor: move;
box-sizing: content-box;
z-index: 9995;
&:hover {
z-index: 9998;
.delete-btn{
display: block;
}
}
.log-wrap{
width: 40px;
height: 40px;
border-right: 1px solid #b7b6b6;
}
.nodeName {
flex-grow: 1;
width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.node-anchor {
display: flex;
position: absolute;
width: @nodeSize;
height: @nodeSize;
align-items: center;
justify-content: center;
border-radius: 10px;
cursor: crosshair;
z-index: 9999;
background: -webkit-radial-gradient(sandybrown 10%, white 30%, #9a54ff 60%);
}
.anchor-top{
top: calc((@nodeSize / 2)*-1);
left: 50%;
margin-left: calc((@nodeSize/2)*-1);
}
.anchor-right{
top: 50%;
right: calc((@nodeSize / 2)*-1);
margin-top: calc((@nodeSize / 2)*-1);
}
.anchor-bottom{
bottom: calc((@nodeSize / 2)*-1);
left: 50%;
margin-left: calc((@nodeSize / 2)*-1);
}
.anchor-left{
top: 50%;
left: calc((@nodeSize / 2)*-1);
margin-top: calc((@nodeSize / 2)*-1);
}
}
.active{
border: 1px dashed @labelColor;
box-shadow: 0px 5px 9px 0px rgba(0,0,0,0.5);
}
</style>