481 lines
14 KiB
Vue
481 lines
14 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="findDisposition()"
|
|
@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>
|
|
<!-- 节点配置-->
|
|
<div align="center">
|
|
<el-dialog :modal="false" title="配置" :visible.sync="disposition.findFlag" width="50%">
|
|
<span>数据库: {{ disposition.formData.dbName }}</span>
|
|
<span>数据表: {{ disposition.formData.table }}</span>
|
|
<span>
|
|
<el-table ref="table" :data="disposition.formData.fields" height="300px">
|
|
<el-table-column :show-overflow-tooltip="true" label="字段名称" prop="columnName" />
|
|
<el-table-column :show-overflow-tooltip="true" label="字段描述" prop="columnComment" />
|
|
<el-table-column :show-overflow-tooltip="true" label="字段类型" prop="columnType" />
|
|
</el-table>
|
|
</span>
|
|
<el-button @click="disposition.findFlag = false">确认</el-button>
|
|
<el-button type="primary" @click="editDisposition">修改配置</el-button>
|
|
</el-dialog>
|
|
<!-- 自定义表单对话框 -->
|
|
<el-drawer
|
|
style="padding-left: 20px; padding-right: 20px;"
|
|
:modal="false"
|
|
:visible.sync="disposition.updFlag"
|
|
direction="rtl"
|
|
title="节点配置"
|
|
append-to-body
|
|
size="60%">
|
|
<el-form ref="queryForm" :inline="true" :model="queryParams" size="small">
|
|
<el-form-item label="数据库名称" prop="dbName">
|
|
<el-select v-model="queryParams.dbName" placeholder="请选择数据库" clearable>
|
|
<el-option v-for="item in dbNameOptions" :key="item" :label="item" :value="item"/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="表名称" prop="tableName">
|
|
<el-input
|
|
v-model="queryParams.tableName"
|
|
clearable
|
|
placeholder="请输入表名称" />
|
|
</el-form-item>
|
|
<el-form-item label="表描述" prop="tableComment">
|
|
<el-input
|
|
v-model="queryParams.tableComment"
|
|
clearable
|
|
placeholder="请输入表描述" />
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button icon="el-icon-search" size="mini" type="primary" @click="handleQuery">查找</el-button>
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<el-table ref="table" :data="tableOptions" height="300px">
|
|
<el-table-column :show-overflow-tooltip="true" label="表名称" prop="tableName" />
|
|
<el-table-column :show-overflow-tooltip="true" label="表描述" prop="tableComment" />
|
|
<el-table-column label="操作">
|
|
<template slot-scope="scope">
|
|
<el-button type="text" @click="selectTable(scope.row)">选择</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
<el-divider />
|
|
<el-table ref="table" v-show="fieldsOptions" :data="fieldsOptions" height="300px"
|
|
@row-click="clickRow" @selection-change="handleSelectionChange">
|
|
<el-table-column type="selection" width="55" />
|
|
<el-table-column :show-overflow-tooltip="true" label="字段名称" prop="columnName" />
|
|
<el-table-column :show-overflow-tooltip="true" label="字段描述" prop="columnComment" />
|
|
<el-table-column :show-overflow-tooltip="true" label="字段类型" prop="columnType" />
|
|
</el-table>
|
|
<el-divider />
|
|
<div align="center">
|
|
<el-button type="primary" @click="saveDisposition">确 定</el-button>
|
|
<el-button @click="disposition.updFlag = false">取 消</el-button>
|
|
</div>
|
|
</el-drawer>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import ClickOutside from 'vue-click-outside'
|
|
import {listDbTableAll, selDbNameAll, selectDbTableColumnsByName} from "../../../../api/tool/gen";
|
|
export default {
|
|
name: "nodeItem",
|
|
props: {
|
|
node: Object
|
|
},
|
|
directives: {
|
|
ClickOutside
|
|
},
|
|
computed: {
|
|
// 节点容器样式
|
|
flowNodeContainer: {
|
|
get() {
|
|
return {
|
|
top: this.node.top,
|
|
left: this.node.left
|
|
};
|
|
}
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
mouseEnter: false,
|
|
isActive: false,
|
|
isSelected: false,
|
|
disposition: {
|
|
findFlag: false,
|
|
updFlag: false,
|
|
formData: {
|
|
nodeId: undefined,
|
|
dbName: undefined,
|
|
table: {},
|
|
fields: []
|
|
}
|
|
},
|
|
total: 0,
|
|
queryParams: {
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
dbName: undefined,
|
|
tableName: undefined,
|
|
tableComment: undefined
|
|
},
|
|
// 数据库列表
|
|
dbNameOptions: [],
|
|
// 展示数据表列表
|
|
tableOptions: [],
|
|
// 所有数据库列表
|
|
tableList: [],
|
|
// 字段列表
|
|
fieldsOptions: []
|
|
};
|
|
},
|
|
methods: {
|
|
showAnchor() {
|
|
this.mouseEnter = true
|
|
},
|
|
hideAnchor() {
|
|
this.mouseEnter = false
|
|
},
|
|
onContextmenu() {
|
|
this.$contextmenu({
|
|
items: [
|
|
{
|
|
label: '修改名称',
|
|
disabled: false,
|
|
icon: "",
|
|
onClick: () => {
|
|
this.toUpdName();
|
|
}
|
|
},{
|
|
label: '修改配置',
|
|
disabled: false,
|
|
icon: "",
|
|
onClick: () => {
|
|
this.disposition.updFlag = true;
|
|
}
|
|
},{
|
|
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
|
|
},
|
|
// 修改名称
|
|
toUpdName() {
|
|
this.$prompt('请输入新名称', '更改名称', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消'
|
|
}).then(({ value }) => {
|
|
this.$emit('setNodeName', this.node.id, value)
|
|
this.$message({
|
|
type: 'success',
|
|
message: '修改成功'
|
|
});
|
|
}).catch(() => {
|
|
this.$message({
|
|
type: 'info',
|
|
message: '操作取消'
|
|
});
|
|
});
|
|
},
|
|
// 选择删除节点
|
|
deleteNode() {
|
|
this.$confirm('确认删除该节点吗?', '删除提示', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.$emit("deleteNode", this.node)
|
|
this.$message({
|
|
type: 'success',
|
|
message: '删除成功'
|
|
});
|
|
}).catch(() => {
|
|
this.$message({
|
|
type: 'info',
|
|
message: '操作取消'
|
|
});
|
|
});
|
|
},
|
|
/** 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
|
|
}
|
|
},
|
|
// 双击触发-查看配置
|
|
findDisposition() {
|
|
// 查询节点配置信息
|
|
this.disposition.formData.nodeId = this.node.id
|
|
this.disposition.findFlag = true
|
|
},
|
|
// 编辑配置
|
|
editDisposition() {
|
|
this.selDbNameList()
|
|
this.getListAll()
|
|
this.disposition.updFlag = true
|
|
},
|
|
// 查询所有数据库名称
|
|
selDbNameList() {
|
|
selDbNameAll().then(res => {
|
|
this.dbNameOptions = res.data
|
|
})
|
|
},
|
|
// 查询表字段
|
|
getFields(dbName, tableName) {
|
|
selectDbTableColumnsByName(dbName, tableName).then(res => {
|
|
this.fieldsOptions = res.data
|
|
})
|
|
},
|
|
// 保存配置按钮
|
|
saveDisposition() {
|
|
console.log(this.disposition.formData)
|
|
const dispositionData = this.disposition.formData
|
|
const addData = []
|
|
/**
|
|
* {
|
|
* node_info_code: '',
|
|
* node_type: '',
|
|
* node_value: ''
|
|
* }
|
|
*/
|
|
// 处理数据库信息
|
|
addData.push({
|
|
nodeInfoCode: dispositionData.nodeId,
|
|
nodeType: 'dbName',
|
|
nodeValue: dispositionData.dbName
|
|
})
|
|
// 处理数据表信息
|
|
addData.push({
|
|
nodeInfoCode: dispositionData.nodeId,
|
|
nodeType: 'table',
|
|
nodeValue: dispositionData.table
|
|
})
|
|
// 处理数据字段信息
|
|
addData.push({
|
|
nodeInfoCode: dispositionData.nodeId,
|
|
nodeType: 'fields',
|
|
nodeValue: dispositionData.fields.toString()
|
|
})
|
|
console.log(addData)
|
|
this.disposition.updFlag = false
|
|
this.disposition.findFlag = false
|
|
},
|
|
// 重置配置信息
|
|
resetDisposition() {
|
|
this.disposition.formData = {
|
|
dbName: undefined,
|
|
table: {},
|
|
fields: []
|
|
}
|
|
},
|
|
getListAll() {
|
|
listDbTableAll().then(res => {
|
|
this.tableList = res.data;
|
|
this.tableOptions = res.data;
|
|
});
|
|
},
|
|
/** 搜索按钮操作 */
|
|
handleQuery() {
|
|
this.tableOptions = []
|
|
this.tableList.forEach(table => {
|
|
const params = this.queryParams
|
|
if ((table.dbName === params.dbName || !params.dbName) &&
|
|
(table.tableName.includes(params.tableName) || !params.tableName) &&
|
|
(table.tableComment.includes(params.tableComment) || !params.tableComment)){
|
|
this.tableOptions.push(table)
|
|
}
|
|
})
|
|
},
|
|
/** 重置按钮操作 */
|
|
resetQuery() {
|
|
this.resetForm("queryForm");
|
|
this.resetDisposition()
|
|
this.handleQuery();
|
|
},
|
|
/** 选择表信息*/
|
|
selectTable(row) {
|
|
this.disposition.formData.table = row.tableName
|
|
this.disposition.formData.dbName = row.dbName
|
|
this.getFields(row.dbName, row.tableName)
|
|
},
|
|
clickRow(row) {
|
|
this.$refs.table.toggleRowSelection(row);
|
|
},
|
|
// 多选框选中数据
|
|
handleSelectionChange(selection) {
|
|
this.disposition.formData.fields = selection.map(item => {
|
|
return {
|
|
fieldName: item.columnName,
|
|
fieldType: item.columnType,
|
|
fieldComment: item.columnComment
|
|
};
|
|
});
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
@labelColor: #409eff;
|
|
@nodeSize: 20px;
|
|
@viewSize: 10px;
|
|
.v-modal {
|
|
width: 50%;
|
|
display: none !important;
|
|
}
|
|
.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: 1006;
|
|
&:hover {
|
|
z-index: 1007;
|
|
.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: 1008;
|
|
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>
|