260 lines
6.3 KiB
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>
|