Commit 30755b06 by 李耀琨

已换 mxgraph 画布

parent d5bf3460
English | [简体中文](./customToolbar_design_zh_cn.md)
## Overview
This article is about how to use **vue** and **mxGraph** to implement a custom toolbox.
Mainly complete the following functions:
- Customize the contents of the toolbox.
- Drag a tool item from the toolbox to the drawing area and generate the corresponding cell.
- Double click the generated cell to view the cell data.
This example can be seen on [github] (https://github.com/lanniu/vue-mxgraph-example).
## Basic layout
![image](http://picture.lanniu.top/20200107090258.png)
The basic layout we envision is shown in the figure above. The entire interface is divided into two parts, the left is the toolbox, and the right is our drawing area.
Since style is not our focus this time, we will show the tool items in a list. Of course you can also use some third-party component libraries such as [element-ui](https://element.eleme.cn/), [ant design vue](https://www.antdv.com/docs/vue), [vuetify](https://vuetifyjs.com/) to achieve some cool display effects.
## Defining the model
First we need to define the data structure of the toolbox:
```
[
{
icon: String || Object, // Path or object of the tool item icon
title: String, // The name of the tool item
width: Number, // Tool item default width
height: Number, // Tool item default height
style: {
... // Cell style generated by the tool item
}
}
]
```
It can be seen that the toolbox is an array, which stores multiple tool item objects, and each tool item contains multiple attributes.
It should be noted that the **style** attribute. The information contained in this attribute is used to describe the style of the cell generated by this tool item after dragging. For the value range, please refer to [official api] (https: // jgraph .github.io / mxgraph / docs / js-api / files / util / mxConstants-js.html # mxConstants).
After understanding the data structure, we began to define the specific data:
```
const outputIcon = './icon/output.png'
const inputIcon = './icon/input.png'
export const toolbarItems = [
{
icon: outputIcon,
title: '输出',
width: 50,
height: 50,
style: {
fillColor: 'transparent',
strokeColor: '#000000',
strokeWidth: '1',
shape: MxConstants.SHAPE_LABEL,
align: MxConstants.ALIGN_CENTER,
verticalAlign: MxConstants.ALIGN_BOTTOM,
imageAlign: MxConstants.ALIGN_CENTER,
imageVerticalAlign: MxConstants.ALIGN_TOP,
image: outputIcon
}
},
{
icon: inputIcon,
title: '输入',
width: 50,
height: 50,
style: {
fillColor: 'transparent', // fillColor
strokeColor: '#000000', // strokeColor
strokeWidth: '1', // strokeWidth
shape: MxConstants.SHAPE_LABEL, // shape
align: MxConstants.ALIGN_CENTER, // align
verticalAlign: MxConstants.ALIGN_BOTTOM, // vertical align
imageAlign: MxConstants.ALIGN_CENTER, // image align
imageVerticalAlign: MxConstants.ALIGN_TOP, // image vertical align
image: inputIcon // image
}
}
]
```
(All pictures in this example are placed in the /public directory)
For the convenience of maintenance, we put the above content into the toolbar.js file. Then import it in the vue component and save it as a calculated property called toolbarItems.
```
import {toolbarItems} from './customToolbar/toolbar'
export default {
computed: {
toolbarItems: () => toolbarItems
}
}
```
## Writing templates
With the data defined, we started writing template code.
First we need a large container for the toolbox and drawing area.
```
<div class="customToolbarContainer">
</div>
```
Then we add the toolbox code:
```
<div class="customToolbarContainer">
<div class="toolbarContainer">
<ul>
<li v-for="item in toolbarItems" :key="item['title']" ref="toolItem">
<img :src="item['icon']" :alt="item['title']">
<span>{{item['title']}}</span>
</li>
</ul>
</div>
</div>
```
Then we add the drawing area code:
```
<div class="customToolbarContainer">
<div class="toolbarContainer">
<ul>
<li v-for="item in toolbarItems" :key="item['title']" ref="toolItem">
<img :src="item['icon']" :alt="item['title']">
<span>{{item['title']}}</span>
</li>
</ul>
</div>
<div class="graphContainer" ref="container"></div>
</div>
```
Finally we need a bit of css (I used scss):
```
.customToolbarContainer {
width: 100%;
height: 100%;
display: flex;
position: relative;
.toolbarContainer {
flex: 1;
font-size: 20px;
background: #efefef;
text-align: center;
padding-top: 20px;
ul {
padding: 0;
margin: 0;
li {
list-style: none;
margin-bottom: 10px;
cursor: pointer;
img {
width: 15px;
height: 15px;
}
span {
margin-left: 15px;
}
}
}
}
.graphContainer {
position: relative;
flex: 7;
}
}
```
Now when we launch the webpage, we should see the following effect:
![image](http://picture.lanniu.top/20200107100229.png)
## Writing business code
Now that everything is ready, we start writing specific code.
First we need to declare a graph object in vue's data to hold the mxGraph instance.
```
data(){
return {
graph: null
}
}
```
First define a method named **createGraph** to instantiate the mxGraph object:
```
createGraph() {
this.graph = new MxGraph(this.$refs.container)
}
```
Then define a method named **initGraph** to initiate some attribute and event:
```
initGraph() {
if (this.R.isNil(this.graph)) {
return
}
this.graph.setConnectable(true) // Allow connection
this.graph.setCellsEditable(false) // Unchangeable
this.graph.convertValueToString = (cell) => { // Generate display labels based on cell
return this.R.prop('title', cell)
}
this.graph.addListener(MxEvent.DOUBLE_CLICK, (graph, evt) => { // Listen for double-click events
const cell = this.R.pathOr([], ['properties', 'cell'], evt)
console.info(cell) // Output double-clicked cell in the console
})
}
```
In the above code, several graph instance methods are used, and the following are introduced one by one:
- [setConnectable](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.setConnectable) The setting is to allow new connections.
- [setCellsEditable](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.setCellsEditable) Set whether to allow double-clicking to modify the label of the cell directly.
- [convertValueToString](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.convertValueToString) This is a function that receives a cell and returns the label that the cell uses for display. Here is a rewrite of the default method.
- [addListener](https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxEvent-js.html#mxEvent.addListener) Add a double-click listener for the graph.
Then define a method named **addCell** to add cells to the drawing area:
```
addCell(toolItem, x, y) {
const {width, height} = toolItem
const styleObj = toolItem['style']
const style = Object.keys(styleObj).map((attr) => `${attr}=${styleObj[attr]}`).join(';')
const parent = this.graph.getDefaultParent()
this.graph.getModel().beginUpdate()
try {
let vertex = this.graph.insertVertex(parent, null, null, x, y, width, height, style)
vertex.title = toolItem['title']
} finally {
this.graph.getModel().endUpdate()
}
}
```
**addCell** receives three parameters: tool item object, X coordinate of Cell, and y coordinate of Cell.
The following steps were performed in the method:
- Get the default width and height information of the cell.
- Splice style into the form "xxx = xxx; xxx = xxx;".
- Call the model's beginUpdate method to start a transaction.
- Invoke the [insertVertex](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.insertVertex) method to add a cell.
- Call the model's endUpdate method to end a transaction.
The next step is to implement the core code of the toolbox. Let's create a new method called ** initToolbar **:
```
initToolbar() {
const domArray = this.$refs.toolItem
if (!(domArray instanceof Array) || domArray.length <= 0) {
return
}
domArray.forEach((dom, domIndex) => {
const toolItem = this.toolbarItems[domIndex]
const {width, height} = toolItem
const dropHandler = (graph, evt, cell, x, y) => {
this.addCell(toolItem, x, y)
}
const createDragPreview = () => {
const elt = document.createElement('div')
elt.style.border = '2px dotted black'
elt.style.width = `${width}px`
elt.style.height = `${height}px`
return elt
}
MxUtils.makeDraggable(dom, this.graph, dropHandler, createDragPreview(), 0, 0, false, true)
})
}
```
The purpose of the method is to allow the tool item to be dragged and trigger a custom callback event when letting go. The following steps were performed in the method:
1. Get all tool items dom.
2. Iterate through all doms.
1. Gets the tool item object corresponding to the dom.
2. Gets the default width and height of the tool item.
3. Define a callback function for drop and execute the **addCell** method in the callback function.
4. Defines a method for generating a preview. This method returns a div as a preview graphic.
5. Call the [makeDraggable](https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxUtils-js.html#mxUtils.makeDraggable) method.
It should be noted that the **makeDraggable** method, makeDraggable receives multiple parameters, we now need to pay attention to the first four:
1. **dom** The dom element that needs to be dragged。
2. **graph** The bound graph object.
3. **dropHandler** Callback function when drop.
4. **preview** Preview graphics while dragging.
Finally, let's add the following code to the mounted:
```
mounted() {
this.createGraph()
this.initGraph()
this.initToolbar()
this.$refs.container.style.background = 'url("./mxgraph/images/grid.gif")'
}
```
When we open the webpage, we can see the following effects:
![](http://picture.lanniu.top/20200107111924.png)
When you double-click the cell, you can see the output information in the console:
![](http://picture.lanniu.top/20200107112010.png)
We can make some extensions to this Demo in the actual project. For example, in addCell function, you can instantiate different objects for different tool items and save them in the value property of the cell. When you double-click the cell, you can pop up the dialog box and modify the value of the cell's value attribute.
end.
[English](./customToolbar_design_en_us.md) | 简体中文
## 概述
本篇的内容是围绕如何使用 **vue****mxGraph** 实现一个自定义的工具箱。
主要完成以下功能:
- 自定义工具箱的内容。
- 从工具箱中拖拽一个工具项到绘画区并生成对应的cell。
- 双击生成的cell可以查看cell的数据。
本例可以在 [github](https://github.com/lanniu/vue-mxgraph-example) 上看到源码。
## 基本布局
![image](http://picture.lanniu.top/20200107090258.png)
我们设想的基本布局如上图所示,整个界面分为左右两部分,左侧为工具箱,右侧为我们的绘图区。
由于样式不是我们此次的重点,所以我们将以列表的形式展示工具项,当然你也可以使用一些第三方组件库如 [element-ui](https://element.eleme.cn/)[ant design vue](https://www.antdv.com/docs/vue)[vuetify](https://vuetifyjs.com/) 等来实现一些很酷炫的展示效果。
## 定义模型
首先我们需要定义工具箱的数据结构:
```
[
{
icon: String || Object, // 工具项图标的路径或对象
title: String, // 工具项的名称
width: Number, // 工具项的默认宽度
height: Number, // 工具项的默认高度
style: {
... // 工具项生成的 cell 样式
}
}
]
```
可以看出来工具箱是一个数组,其中存放了多个工具项对象,每个工具项中包含了多个属性。
需要注意的是 **style** 这个属性,这个属性里包含的信息是用于描述此工具项在拖拽后生成的 cell 的样式,取值范围请参考[官方api](https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxConstants-js.html#mxConstants)
了解了数据结构后,我们开始定义具体的数据:
```
const outputIcon = './icon/output.png'
const inputIcon = './icon/input.png'
export const toolbarItems = [
{
icon: outputIcon,
title: '输出',
width: 50,
height: 50,
style: {
fillColor: 'transparent',
strokeColor: '#000000',
strokeWidth: '1',
shape: MxConstants.SHAPE_LABEL,
align: MxConstants.ALIGN_CENTER,
verticalAlign: MxConstants.ALIGN_BOTTOM,
imageAlign: MxConstants.ALIGN_CENTER,
imageVerticalAlign: MxConstants.ALIGN_TOP,
image: outputIcon
}
},
{
icon: inputIcon,
title: '输入',
width: 50,
height: 50,
style: {
fillColor: 'transparent', // 填充色
strokeColor: '#000000', // 线条颜色
strokeWidth: '1', // 线条粗细
shape: MxConstants.SHAPE_LABEL, // 形状
align: MxConstants.ALIGN_CENTER, // 水平方向对齐方式
verticalAlign: MxConstants.ALIGN_BOTTOM, // 垂直方向对齐方式
imageAlign: MxConstants.ALIGN_CENTER, // 图形水平方向对齐方式
imageVerticalAlign: MxConstants.ALIGN_TOP, // 图形垂直方向对齐方式
image: inputIcon // 图形
}
}
]
```
(本例中所有的图片都放在 public 目录下)
为了方便维护我们把以上内容放到 toolbar.js 文件中。然后在 vue 组件中导入,并保存为一个名为 toolbarItems 的计算属性。
```
import {toolbarItems} from './customToolbar/toolbar'
export default {
computed: {
toolbarItems: () => toolbarItems
}
}
```
## 编写模板
定义好数据后,我们开始编写模板代码。
首先我们需要一个大的容器,用于存放工具箱和画布。
```
<div class="customToolbarContainer">
</div>
```
接着我们加上工具箱代码:
```
<div class="customToolbarContainer">
<div class="toolbarContainer">
<ul>
<li v-for="item in toolbarItems" :key="item['title']" ref="toolItem">
<img :src="item['icon']" :alt="item['title']">
<span>{{item['title']}}</span>
</li>
</ul>
</div>
</div>
```
然后我们加上工具箱的代码:
```
<div class="customToolbarContainer">
<div class="toolbarContainer">
<ul>
<li v-for="item in toolbarItems" :key="item['title']" ref="toolItem">
<img :src="item['icon']" :alt="item['title']">
<span>{{item['title']}}</span>
</li>
</ul>
</div>
<div class="graphContainer" ref="container"></div>
</div>
```
最后我们还需要一点 css(我使用了scss):
```
.customToolbarContainer {
width: 100%;
height: 100%;
display: flex;
position: relative;
.toolbarContainer {
flex: 1;
font-size: 20px;
background: #efefef;
text-align: center;
padding-top: 20px;
ul {
padding: 0;
margin: 0;
li {
list-style: none;
margin-bottom: 10px;
cursor: pointer;
img {
width: 15px;
height: 15px;
}
span {
margin-left: 15px;
}
}
}
}
.graphContainer {
position: relative;
flex: 7;
}
}
```
现在我们开打网页,应该可以看到如下的效果了:
![image](http://picture.lanniu.top/20200107100229.png)
## 编写业务代码
现在万事俱备,我们开始编写具体的代码。
首先我们需要在 vue 的 data 中声明一个 graph 对象,用于保存 mxGraph 实例。
```
data(){
return {
graph: null
}
}
```
首先定义一个 **createGraph** 方法用于生成mxGraph对象:
```
createGraph() {
this.graph = new MxGraph(this.$refs.container)
}
```
接着我们定义一个 **initGraph** 方法用于初始化一些属性和事件:
```
initGraph() {
if (this.R.isNil(this.graph)) {
return
}
this.graph.setConnectable(true) // 允许连线
this.graph.setCellsEditable(false) // 不可修改
this.graph.convertValueToString = (cell) => { // 根据cell生成显示的标签
return this.R.prop('title', cell)
}
this.graph.addListener(MxEvent.DOUBLE_CLICK, (graph, evt) => { // 监听双击事件
const cell = this.R.pathOr([], ['properties', 'cell'], evt)
console.info(cell) // 在控制台输出双击的cell
})
}
```
上面的代码中,用到了几个 graph 实例的方法,下面一一介绍一下:
- [setConnectable](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.setConnectable) 设置是否允许新建连线。
- [setCellsEditable](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.setCellsEditable) 设置是否允许直接双击修改 cell 的标签。
- [convertValueToString](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.convertValueToString) 这是一个函数,接收一个 cell,并返回该 cell 用于显示的 label,这里是复写了默认的方法。
- [addListener](https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxEvent-js.html#mxEvent.addListener) 为 graph 添加一个双击的监听事件。
然后我们定义一个方法 **addCell** 用于向画布中添加 cell:
```
addCell(toolItem, x, y) {
const {width, height} = toolItem
const styleObj = toolItem['style']
const style = Object.keys(styleObj).map((attr) => `${attr}=${styleObj[attr]}`).join(';')
const parent = this.graph.getDefaultParent()
this.graph.getModel().beginUpdate()
try {
let vertex = this.graph.insertVertex(parent, null, null, x, y, width, height, style)
vertex.title = toolItem['title']
} finally {
this.graph.getModel().endUpdate()
}
}
```
**addCell** 接收三个参数,分别为:工具项对象,X轴坐标,y轴坐标。
方法中分别执行了如下的步骤:
- 获取了cell默认的宽高信息。
- 把style拼接为“xxx=xxx;xxx=xxx;”的形式。
- 调用 model 的 beginUpdate 方法开始一个事务。
- 调用 [insertVertex](https://jgraph.github.io/mxgraph/docs/js-api/files/view/mxGraph-js.html#mxGraph.insertVertex) 方法,添加一个 cell。
- 调用 model 的 endUpdate 方法结束一个事务。
接着就是实现工具箱的核心代码,我们新建一个叫 **initToolbar** 的方法:
```
initToolbar() {
const domArray = this.$refs.toolItem
if (!(domArray instanceof Array) || domArray.length <= 0) {
return
}
domArray.forEach((dom, domIndex) => {
const toolItem = this.toolbarItems[domIndex]
const {width, height} = toolItem
const dropHandler = (graph, evt, cell, x, y) => {
this.addCell(toolItem, x, y)
}
const createDragPreview = () => {
const elt = document.createElement('div')
elt.style.border = '2px dotted black'
elt.style.width = `${width}px`
elt.style.height = `${height}px`
return elt
}
MxUtils.makeDraggable(dom, this.graph, dropHandler, createDragPreview(), 0, 0, false, true)
})
}
```
方法的目的是让工具项可以被拖拽,且在放手时会触发自定义的回调事件。方法中分别执行了如下的步骤:
1. 获取所有的工具项 dom。
2. 遍历所有的 dom。
1. 获取 dom 对应的工具项对象。
2. 获取工具项的默认宽高。
3. 定义 drop 的回调函数,在函数中执行 **addCell** 方法。
4. 定义生成预览的方法,该方法返回一个 div,作为预览的图形。
5. 调用[makeDraggable](https://jgraph.github.io/mxgraph/docs/js-api/files/util/mxUtils-js.html#mxUtils.makeDraggable)方法。
需要注意的是 **makeDraggable** 方法,makeDraggable 接收多个参数,我们现在需要在意的是前四个:
1. dom 需要允许被拖拽的 dom 元素。
2. graph 绑定的 graph 对象。
3. dropHandler drop 时的回调函数。
4. preview 拖拽时的预览图形。
最后让我们在 mounted 生命周期函数中添加如下代码:
```
mounted() {
this.createGraph()
this.initGraph()
this.initToolbar()
this.$refs.container.style.background = 'url("./mxgraph/images/grid.gif")'
}
```
我们打开网页可以看到如下的效果:
![](http://picture.lanniu.top/20200107111924.png)
双击cell时,可以在控制台看到输出的信息:
![](http://picture.lanniu.top/20200107112010.png)
我们在实际的项目中可以对这个 Demo 进行一些扩充,比如在 addCell 时可以针对不同的工具项实例化得到不同的对象,并保存在 cell 的 value 属性中,双击 cell 时可以在弹出的对话框中修改 value 的属性值。
至此。
......@@ -52,11 +52,14 @@
"mavon-editor": "^2.9.0",
"moment": "^2.29.1",
"mxgraph": "^4.2.2",
"mxgraph-js": "^1.0.1",
"node-sass": "^5.0.0",
"normalize.css": "7.0.0",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
"prop-types": "^15.7.2",
"qs": "^6.9.1",
"ramda": "^0.27.1",
"screenfull": "4.2.0",
"scss": "^0.2.4",
"scss-loader": "0.0.1",
......
......@@ -213,9 +213,9 @@ export function randomValueFunc(data){
//数据库表路径
export function explorer(data){
export function explorer2(data){
return request({
url: 'etlweb/database/explorer',
url: 'etlweb/database/explorer2',
data,
method: 'post'
})
......@@ -276,6 +276,18 @@ export function save(data){
}
//文件绝对路径
export function fileexplorer(data){
return request({
url: 'etlweb/system/fileexplorer',
data,
method: 'post'
})
}
......
......@@ -31,6 +31,8 @@ import './router/index' // permission control
import 'echarts-gl'
import moment from 'moment'
import jsPlump from 'jsplumb'
Vue.use(jsPlump);
// 引入自定义指令
......@@ -65,3 +67,17 @@ new Vue({
render: h => h(App)
})
import * as R from 'ramda'
Vue.prototype.R = R
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
<template>
<div>
<el-tree
:data="browsingData"
:props="defaultProps"
@node-click="handleNodeClick"
lazy
ref="tree"
:load="loadDataTree"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span style="display: flex; align: center">
<div
:class="data.iconCls"
style="
display: inline-block;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center;
"
width=""
alt=""
></div>
{{ node.label }}
</span>
</span>
</el-tree>
</div>
</template>
<script>
import { fileexplorer } from "@/api/kettle/link";
export default {
props: [""], //从父组件传过来的值
data() {
return {
defaultProps: {
children: "children",
label: "text",
},
browsingData: [],
absolutePath: "",
};
},
created() {},
methods: {
loadDataTree(node, resolve) {
if (node.level === 0) {
let pamq = new FormData(); // 创建form对象
pamq.append("path", "");
pamq.append("extension", "32");
pamq.append("node", "xnode-2092");
fileexplorer(pamq).then((res) => {
this.browsingData = res;
console.log(this.browsingData, "------------");
});
return resolve(this.browsingData);
} else {
let pam = new FormData(); // 创建form对象
pam.append("path", node.data.id);
pam.append("extension", "32");
pam.append("node", node.data.id);
fileexplorer(pam).then((res) => {
if (res) {
if (res.length > 0) {
resolve(res);
} else if (res.length === 0) {
let empty = null;
resolve(empty);
} else {
this.$message.error(res.errMsg);
}
}
});
}
// if (node.level > this.PopupFrom.length) return resolve([]);
},
handleNodeClick(data, node) {
console.log("点击当前节点node===", node);
console.log("点击当前节点data===", data);
this.absolutePath = node.data.id;
console.log(this.absolutePath, "绝对路径");
this.$emit("route", {
name: node.data.id,
});
},
},
};
</script>
<style>
.type-checked {
background-color: #8888ff;
color: #fff;
}
.mybox ul {
margin: 0;
padding: 0;
}
.mybox ul li {
list-style: none;
height: 30px;
line-height: 30px;
padding: 0 10px;
white-space: nowrap;
}
</style>
\ No newline at end of file
<template>
<div class="tableInput">
<el-form ref="stepName" :model="stepName" label-width="120px">
<el-form-item label="步骤名称:">
<el-input v-model="stepName.name"></el-input>
</el-form-item>
</el-form>
<el-form-item label="步骤名称:">
<el-input v-model="stepName.name" @change="tableInputName"></el-input>
</el-form-item>
</el-form>
<el-form ref="form" :model="form" label-width="0px">
<el-form-item>
<el-row :gutter="10">
......@@ -34,16 +32,20 @@
</el-select> -->
</el-col>
<el-col class="line" :span="2">
<el-button size="mini" @click="dialogVisibleFourth = true">编辑</el-button></el-col
<el-button size="mini" @click="dialogVisibleFourth = true"
>编辑</el-button
></el-col
>
<el-col class="line" :span="2">
<el-button size="mini" @click="dialogVisibleFourth = true">新建</el-button></el-col
<el-button size="mini" @click="dialogVisibleFourth = true"
>新建</el-button
></el-col
>
<el-col class="line" :span="2">
<el-button size="mini">向导</el-button></el-col
>
<el-col class="line" :span="5">
<el-button size="mini" @click="scanTree('')"
<el-button size="mini" @click="SQLPopup"
>获取SQL查询语句</el-button
></el-col
>
......@@ -82,8 +84,7 @@
<el-input v-model="form.limit"></el-input>
</el-form-item>
</el-form>
<!--
<el-dialog
title="数据库浏览"
:visible.sync="browsing"
......@@ -95,39 +96,59 @@
:data="browsingData"
:props="defaultProps"
@node-click="handleNodeClick"
></el-tree>
lazy
:load="loadDataTree"
v-if="scanFlag"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span style="display: flex; align: center">
<div
:class="data.iconCls"
style="
display: inline-block;
width: 20px;
height: 20px;
background-repeat: no-repeat;
background-position: center;
"
width=""
alt=""
></div>
{{ node.label }}
</span>
</span>
</el-tree>
<span slot="footer" class="dialog-footer">
<el-button @click="browsing = false">取 消</el-button>
<el-button type="primary" @click="browsing = false">确 定</el-button>
<el-button type="primary" @click="addBrowsing">确 定</el-button>
</span>
</el-dialog> -->
</el-dialog>
<estab-dialog ref="establishDia" :dialogVisibleFourth.sync='dialogVisibleFourth' @getSonValue="getSonValue" :listNames="listNames" :scanDialogVisible.sync='scanDialogVisible'  :form="newForm" :chooseType="chooseType" :chooseFlag.sync="chooseFlag"></estab-dialog>
</div>
</template>
<script>
import main from '../../../mykettle/main'
import { tableFields, explorer, listDatabases,listNames } from "@/api/kettle/link";
import main from "../../../mykettle/main";
import {
tableFields,
explorer2,
listDatabases,
listNames,
} from "@/api/kettle/link";
export default {
props: ["connectionNode","stepName"], //从父组件传过来的值
components: {
main
},
props: ["connectionNode", "stepName"], //从父组件传过来的值
components: {
main,
},
data() {
return {
browsing: false,
dialogVisibleFourth:false,
scanDialogVisible:false,
newForm:{},
dialogVisibleFourth: false,
scanDialogVisible: false,
newForm: {},
form: {
wLazyConversion: false,
wVariables: false,
......@@ -135,99 +156,98 @@ newForm:{},
},
ComboBox: [],
library: [],
PopupFrom:{},
PopupFrom: {},
scanFlag: false,
browsingData: [],
defaultProps: {
children: "children",
label: "text",
},
dataBaseName:"",
curNode:{},
chooseType:"",
chooseFlag:false,
dataBaseName: "",
curNode: {},
chooseType: "表",
chooseFlag: false,
};
},
created() {
this.listDatabasesFun();
}, // 监听编号好后获取选择的数据库的树形里列表
watch: {
dataBaseName: {
handler(newValue, oldValue) {
console.log("obj changed");
if (newValue) {
this.$refs.establishDia.scanDialogOpen();
this.chooseFlag = true;
}
},
deep: true,
}, // form(newValue, oldValue){ //   this.form=newValue; // }
},
 // 监听编号好后获取选择的数据库的树形里列表
  watch: {
    dataBaseName:{
       handler (newValue, oldValue) {
        console.log('obj changed');
        if(newValue){
          this.$refs.establishDia.scanDialogOpen();
          this.chooseFlag=true;
        }
      },
      deep: true
    },
    // form(newValue, oldValue){
    //   this.form=newValue;
    // }
  },
methods: {
tableInputName(){
this.stepName
},
//  //获取新建弹窗返回来的值
getSonValue(res){
      if(typeof(res)=='string'){
        this.dataBaseName = res
         console.log('接收子组件的值1111111----',this.dataBaseName);
      }else if(typeof(res)=='object'){
        console.log('接收子组件的值55555----',res);
        this.curNode=res;
         // DOM 更新后
        // this.$nextTick(() => {
        //   this.form.text=this.curNode.data.text;
        //   // this.$refs.goal.values=this.curNode.data.text;
        //   // this.$refs.goal.refreshData(this.from)
        // })
//         this.$set(this.newForm,'text',this.curNode.data.text)
//         this.$forceUpdate()
        // this.form.text=this.curNode.data.text;
        console.log('chuanhuo=====', this.newForm);
      }else if(typeof(res)=='boolean'){
         this.dialogVisibleFourth=res;
         console.log('接收子组件的值2222222----',this.dialogVisibleFourth);
      }
    },
//    //浏览
scanTree(type){
      if(this.form.connection){
        this.$refs.establishDia.database(this.form.connection);
        console.log('当前选中数据库***************',this.form.connection);
        if(this.form.connection){
          this.$refs.establishDia.scanDialogOpen();
          this.chooseFlag=true;
          this.chooseType=type;
        }
      }else{
        this.$message.error('请选择数据库')
      }
    },
 //获取新建弹窗返回来的值
    getSonValue(res){
      if(typeof(res)=='string'){
        this.dataBaseName = res
         console.log('接收子组件的值1111111----',this.dataBaseName);
      }else if(typeof(res)=='object'){
        console.log('接收子组件的值55555----',res);
        this.curNode=res;
         // DOM 更新后
        // this.$nextTick(() => {
        //   this.form.text=this.curNode.data.text;
        //   // this.$refs.goal.values=this.curNode.data.text;
        //   // this.$refs.goal.refreshData(this.from)
        // })
//         this.$set(this.newForm,'text',this.curNode.data.text)
//         this.$forceUpdate()
        // this.form.text=this.curNode.data.text;
        console.log('chuanhuo=====', this.newForm);
      }else if(typeof(res)=='boolean'){
         this.dialogVisibleFourth=res;
         console.log('接收子组件的值2222222----',this.dialogVisibleFourth);
      }    
    },
   //浏览
scanTree(type){
      if(this.form.connection){       
        this.$refs.establishDia.database(this.form.connection);
        console.log('当前选中数据库***************',this.form.connection);
        if(this.form.connection){
          this.$refs.establishDia.scanDialogOpen();
          this.chooseFlag=true;
          this.chooseType=type;
        }         
      }else{
        this.$message.error('请选择数据库')
      }
      
    },
//获取新建弹窗返回来的值
// getSonValue(res){
// this.dialogVisibleFourth=res;
// this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择oracle数据
// this.methodHoverIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// this.methodCheckedIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// // this.addFlag=true;//增减变量改为编辑变量
// },
 //获取新建弹窗返回来的值
//查询已经建立的所有数据库列表
//获取新建弹窗返回来的值
// getSonValue(res){
// this.dialogVisibleFourth=res;
// this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择oracle数据
// this.methodHoverIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// this.methodCheckedIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// // this.addFlag=true;//增减变量改为编辑变量
// },
//获取新建弹窗返回来的值
// 查询已经建立的所有数据库列表
listNames(){
listNames().then(res=>{
if (res) {
if (res) {
console.log('获取所有已经创建的数据库列表:',res);
this.namesList=res;
}else {
......@@ -236,99 +256,150 @@ newForm:{},
})
},
getField(val) {
this.library = this.ComboBox.find((e) => {
return e.name == val;
});
console.log(this.library);
},
SQLPopup() {
if (this.form.connection) {
this.browsing = !this.browsing;
let pamq = new FormData(); // 创建form对象
pamq.append("databaseInfo", JSON.stringify(this.library));
pamq.append("nodeId", "");
pamq.append("text", "");
pamq.append("includeElement", "15");
pamq.append("node","");
explorer(pamq).then((res) => {
console.log(res,'------------');
this.PopupFrom = res
// this.browsingData = res
let pam = new FormData(); // 创建form对象
pam.append("databaseInfo", JSON.stringify(this.library));
pam.append("nodeId", JSON.stringify(this.PopupFrom[0].nodeId).replace("\"", "").replace("\"",""));
pam.append("text", JSON.stringify(this.library.name).replace("\"", "").replace("\"",""));
pam.append("includeElement", "15");
explorer(pam).then((res) => {
console.log(res,'++++++++++++++++++');
this.browsingData = this.PopupFrom
this.browsingData[0].children = res
let itemData = this.browsingData[0]
console.log('======',itemData,res)
itemData.children = res
this.$set(this.browsingData,0,itemData)
// this.browsingData = this.PopupFrom
// this.browsingData[0].children = res
});
});
addBrowsing(){
} else {
this.$message.error("请选择数据库");
console.log(this.stepName);
}
},
// loadNode(node, resolve) {
// if (node.level === 0) {
// return resolve([{ name: 'region' }]);
// }
// if (node.level > this.PopupFrom.length) return resolve([]);
this.browsing = false
const that = this;
let flowObj = Object.assign({}, that.flowData);
var xml2js = require('xml2js');
//xml->json
//xml2js默认会把子子节点的值变为一个数组, explicitArray设置为false
var xmlParser = new xml2js.Parser({explicitArray : false, ignoreAttrs : true})
//json->xml
var jsonBuilder = new xml2js.Builder();
// setTimeout(() => {
//测试用例
var xml = "<root>flowObj xml2js!</root>";
var obj = flowObj
// const data = [{
// name: 'leaf',
// leaf: true
// }, {
// name: 'zone'
// }];
console.log('----------');
// xml -> json
xmlParser.parseString(xml, function (err, result) {
//将返回的结果再次格式化
console.log(JSON.stringify(result));
});
console.log('----------');
// resolve(data);
// }, 500);
// },
//json --> xml
var builder = new xml2js.Builder();
var jsonxml = builder.buildObject(obj);
console.log(jsonxml);
// handleNodeClick(data) {
// console.log(data);
// let pam = new FormData(); // 创建form对象
// pam.append("databaseInfo", JSON.stringify(this.library));
// pam.append("nodeId", JSON.stringify(data.nodeId).replace("\"", "").replace("\"",""));
// pam.append("text", JSON.stringify(data.text).replace("\"", "").replace("\"",""));
// pam.append("includeElement", "15");
// explorer(pam).then(res=>{
// console.log(res,'..........');
console.log('----------');
// })
// },
let mps = new FormData(); // 创建form对象
mps.append("graphXml", flowObj);
mps.append("databaseName", "127");
mps.append("schema", "test");
mps.append("table", "R_CLUSTER");
tableFields(mps).then(res=>{
console.log(res);
})
},
SQLPopup() {
if (this.form.connection) {
this.browsing = !this.browsing;
this.scanFlag = true;
// let pamq = new FormData(); // 创建form对象
// pamq.append("databaseInfo", JSON.stringify(this.library));
// pamq.append("nodeId", "");
// pamq.append("text", "");
// pamq.append("includeElement", "15");
// pamq.append("node","");
// explorer2(pamq).then((res) => {
// console.log(res,'------------');
// this.PopupFrom = res
// // this.browsingData = res
// let pam = new FormData(); // 创建form对象
// pam.append("databaseInfo", JSON.stringify(this.library));
// pam.append("nodeId", JSON.stringify(this.PopupFrom[0].nodeId).replace("\"", "").replace("\"",""));
// pam.append("text", JSON.stringify(this.library.name).replace("\"", "").replace("\"",""));
// pam.append("includeElement", "15");
// explorer2(pam).then((res) => {
// console.log(res,'++++++++++++++++++');
// this.browsingData = this.PopupFrom
// this.browsingData[0].children = res
// let itemData = this.browsingData[0]
// console.log('======',itemData,res)
// itemData.children = res
// this.$set(this.browsingData,0,itemData)
// // this.browsingData = this.PopupFrom
// // this.browsingData[0].children = res
// });
// });
} else {
this.$message.error("请选择数据库");
console.log(this.stepName);
}
},
loadDataTree(node, resolve) {
if (node.level === 0) {
let pamq = new FormData(); // 创建form对象
pamq.append("databaseInfo", JSON.stringify(this.library));
pamq.append("nodeId", "");
pamq.append("text", "root");
pamq.append("includeElement", "15");
pamq.append("node", "xnode-4528");
explorer2(pamq).then((res) => {
this.browsingData = res;
console.log(this.browsingData, "------------");
});
return resolve(this.browsingData);
} else {
let pam = new FormData(); // 创建form对象
pam.append("databaseInfo", JSON.stringify(this.library));
pam.append("nodeId", node.data.nodeId);
pam.append("text", node.data.text);
pam.append("node", node.data.id);
pam.append("includeElement", "15");
explorer2(pam).then((res) => {
if (res) {
if (res.length > 0) {
resolve(res);
} else if (res.length === 0) {
let empty = null;
resolve(empty);
} else {
this.$message.error(res.errMsg);
}
}
});
}
// if (node.level > this.PopupFrom.length) return resolve([]);
},
handleNodeClick(data,node) {
console.log('点击当前节点node===',node);
console.log('点击当前节点data===',data);
},
handleClose(done) {
this.scanFlag = false;
this.$confirm("确认关闭?")
.then((_) => {
done();
......
......@@ -8,40 +8,32 @@
<el-tabs type="border-card">
<el-tab-pane label="文件">
<el-form ref="form" :model="form" label-width="150px">
<el-form ref="form" :model="fileSelection" label-width="150px">
<el-form-item label="文件名称:">
<el-row :gutter="10">
<el-col :span="17">
<el-input v-model="form.fileName"></el-input>
<el-input v-model="fileSelection.fileName" :disabled="form.acceptingFilenames == 'Y' "></el-input>
</el-col>
<el-col class="line" :span="3">
<el-button size="mini">增加</el-button></el-col
<el-button size="mini" @click="addFile" :disabled="form.acceptingFilenames == 'Y' ">增加</el-button></el-col
>
<el-col class="line" :span="3">
<el-button size="mini">浏览</el-button></el-col
<el-button size="mini" @click="selectFilePath(1)" :disabled="form.acceptingFilenames == 'Y' ">浏览</el-button></el-col
>
</el-row>
</el-form-item>
<el-form-item label="规则表达式:">
<el-input v-model="form.fileMask"></el-input>
<el-input v-model="fileSelection.filemask" :disabled="form.acceptingFilenames == 'Y' "></el-input>
</el-form-item>
<el-form-item label="正则表达式(排除):">
<el-input v-model="form.excludeFileMask"></el-input>
<el-input v-model="fileSelection.excludeFileMask" :disabled="form.acceptingFilenames == 'Y' "></el-input>
</el-form-item>
<el-form-item label="选中的文件:">
<!-- <input type="file" placeholder="上传" @change="fileChnageInput" /> -->
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-change="handleChange"
:show-file-list="false"
:auto-upload="false"
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-card class="box-card">
<el-table :data="fileData" style="width: 100%">
......@@ -64,14 +56,14 @@
@click="handleClick(scope.row)"
type="text"
size="small"
:disabled="form.acceptingFilenames"
:disabled="form.acceptingFilenames == 'Y'"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deleteRow(scope.$index, fileData)"
:disabled="form.acceptingFilenames"
:disabled="form.acceptingFilenames == 'Y'"
>删除</el-button
>
</template>
......@@ -83,27 +75,32 @@
<el-form ref="form" :model="form" label-width="200px">
<el-card class="box-card">
<el-form-item label="从以前步骤接受文件名:">
<el-checkbox v-model="form.acceptingFilenames"></el-checkbox>
<el-checkbox v-model="form.acceptingFilenames" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
<el-form-item label="从以前步骤接受字段名:">
<el-checkbox
v-model="form.passingThruFields"
:disabled="!form.acceptingFilenames"
:disabled="form.acceptingFilenames == 'N' || !form.acceptingFilenames"
true-label="Y" false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="步骤读取的文件名来自:">
<el-input
v-model="form.acceptingField"
:disabled="!form.acceptingFilenames"
></el-input>
<el-select v-model="form.acceptingField" style="width: 100%" :disabled="form.acceptingFilenames == 'N' || !form.acceptingFilenames">
<el-option
v-for="item in connectionNode"
:key="item.id"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-form-item label="在输入里的字段被当做文件名:">
<el-input
v-model="form.acceptingStepName"
:disabled="!form.acceptingFilenames"
:disabled="form.acceptingFilenames == 'N' || !form.acceptingFilenames"
></el-input>
</el-form-item>
</el-card>
......@@ -119,8 +116,6 @@
</el-select>
</el-form-item>
<el-form-item label="分割符:">
<el-row :gutter="10">
<el-col :span="20">
......@@ -137,7 +132,7 @@
</el-form-item>
<el-form-item label="在文本里允许换行:">
<el-checkbox v-model="form.breakInEnclosureAllowed"></el-checkbox>
<el-checkbox v-model="form.breakInEnclosureAllowed" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
<el-form-item label="逃逸字符:">
......@@ -147,13 +142,13 @@
<el-form-item label="头部:">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.header"></el-checkbox>
<el-checkbox v-model="form.header" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="4">头部行数:</el-col>
<el-col :span="17">
<el-input
v-model="form.nrHeaderLines"
:disabled="!form.header"
:disabled="form.header == 'N' || !form.header"
></el-input>
</el-col>
</el-row>
......@@ -162,13 +157,13 @@
<el-form-item label="尾部:">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.footer"></el-checkbox>
<el-checkbox v-model="form.footer" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="4">尾部行数:</el-col>
<el-col :span="17">
<el-input
v-model="form.nrFooterLines"
:disabled="!form.footer"
:disabled="form.footer == 'N' || !form.footer"
></el-input>
</el-col>
</el-row>
......@@ -177,13 +172,13 @@
<el-form-item label="包装行:">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.lineWrapped"></el-checkbox>
<el-checkbox v-model="form.lineWrapped" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="6">以时间包装的行数:</el-col>
<el-col :span="15">
<el-input
v-model="form.nrWraps"
:disabled="!form.lineWrapped"
:disabled="form.lineWrapped == 'N' || !form.lineWrapped"
></el-input>
</el-col>
</el-row>
......@@ -192,13 +187,13 @@
<el-form-item label="分页布局(pointout):">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.layoutPaged"></el-checkbox>
<el-checkbox v-model="form.layoutPaged" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="5">每页记录行数:</el-col>
<el-col :span="16">
<el-input
v-model="form.nrLinesPerPage"
:disabled="!form.layoutPaged"
:disabled="form.layoutPaged == 'N' || !form.layoutPaged"
></el-input>
</el-col>
</el-row>
......@@ -207,14 +202,14 @@
<el-col :span="17">
<el-input
v-model="form.nrLinesDocHeader"
:disabled="!form.layoutPaged"
:disabled="form.layoutPaged == 'N' || !form.layoutPaged"
></el-input>
</el-col>
</el-row>
</el-form-item>
<el-form-item label="压缩:">
<el-select v-model="form.fileCompression" style="width: 100%">
<el-option
v-for="item in fieldCompress"
......@@ -227,19 +222,19 @@
</el-form-item>
<el-form-item label="没有空行:">
<el-checkbox v-model="form.noEmptyLines"></el-checkbox>
<el-checkbox v-model="form.noEmptyLines" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
<el-form-item label="在输出包括字段名:">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.includeFilename"></el-checkbox>
<el-checkbox v-model="form.includeFilename" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="5">包含字段名名称:</el-col>
<el-col :span="16">
<el-input
v-model="form.filenameField"
:disabled="!form.includeFilename"
:disabled="form.includeFilename == 'N' || !form.includeFilename"
></el-input>
</el-col>
</el-row>
......@@ -248,13 +243,13 @@
<el-form-item label="输出包含行数:">
<el-row :gutter="10">
<el-col :span="2">
<el-checkbox v-model="form.includeRowNumber"></el-checkbox>
<el-checkbox v-model="form.includeRowNumber" true-label="Y" false-label="N"></el-checkbox>
</el-col>
<el-col class="line" :span="5">行数字段名称:</el-col>
<el-col :span="16">
<el-input
v-model="form.rowNumberField"
:disabled="!form.includeRowNumber"
:disabled="form.includeRowNumber == 'N' || !form.includeFilename"
></el-input>
</el-col>
</el-row>
......@@ -263,7 +258,8 @@
<el-col :span="1">
<el-checkbox
v-model="form.rowNumberByFile"
:disabled="!form.includeRowNumber"
:disabled="form.includeRowNumber == 'N' || !form.includeFilename"
true-label="Y" false-label="N"
></el-checkbox>
</el-col>
</el-row>
......@@ -299,70 +295,72 @@
</el-form-item>
<el-form-item label="解析日期的时候是否严格要求:">
<el-checkbox v-model="form.dateFormatLenient"></el-checkbox>
<el-checkbox v-model="form.dateFormatLenient" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
<el-form-item label="本地日期格式:">
<el-input v-model="form.dateFormatLocale"></el-input>
<el-input v-model="form.dateFormatLocale" true-label="Y" false-label="N"></el-input>
</el-form-item>
<el-form-item label="添加文件名:">
<el-checkbox v-model="form.addresult"></el-checkbox>
<el-checkbox v-model="form.addresult" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="错误处理">
<el-form ref="form" :model="form" label-width="160px">
<el-form-item label="忽略错误:">
<el-checkbox v-model="form.errorIgnored"></el-checkbox>
<el-checkbox v-model="form.errorIgnored" true-label="Y" false-label="N"></el-checkbox>
</el-form-item>
<el-form-item label="忽略错误文件:">
<el-checkbox
v-model="form.skipBadFiles"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
true-label="Y" false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="错误文件字段名:">
<el-input
v-model="form.fileErrorField"
:disabled="!this.form.errorIgnored || !this.form.skipBadFiles"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored "
></el-input>
</el-form-item>
<el-form-item label="文件错误信息字段名:">
<el-input
v-model="form.fileErrorMessageField"
:disabled="!this.form.errorIgnored || !this.form.skipBadFiles"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-form-item>
<el-form-item label="跳过错误行:">
<el-checkbox
v-model="form.errorLineSkipped"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
true-label="Y" false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="错误计数制度:">
<el-input
v-model="form.errorCountField"
:disabled="!this.form.errorIgnored"
v-model="form.errorCountField "
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-form-item>
<el-form-item label="错误字段文件名:">
<el-input
v-model="form.errorFieldsField"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-form-item>
<el-form-item label="错误文本字段:">
<el-input
v-model="form.errorTextField"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-form-item>
......@@ -371,19 +369,19 @@
<el-col :span="10">
<el-input
v-model="form.warningFilesDestinationDirectory"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-col>
<el-col class="line" :span="3">扩展名:</el-col>
<el-col :span="8">
<el-input
v-model="form.warningFilesExtension"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-col>
<el-col class="line" :span="2">
<el-button size="mini">浏览</el-button></el-col
<el-button :disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored" size="mini" @click="selectFilePath(2)">浏览</el-button></el-col
>
</el-row>
</el-form-item>
......@@ -393,19 +391,19 @@
<el-col :span="10">
<el-input
v-model="form.errorFilesDestinationDirectory"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-col>
<el-col class="line" :span="3">扩展名:</el-col>
<el-col :span="8">
<el-input
v-model="form.errorFilesExtension"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-col>
<el-col class="line" :span="2">
<el-button size="mini">浏览</el-button></el-col
<el-button :disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored" size="mini" @click="selectFilePath(3)">浏览</el-button></el-col
>
</el-row>
</el-form-item>
......@@ -415,19 +413,19 @@
<el-col :span="10">
<el-input
v-model="form.lineNumberFilesDestinationDirectory"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored"
></el-input>
</el-col>
<el-col class="line" :span="3">扩展名:</el-col>
<el-col :span="8">
<el-input
v-model="form.lineNumberFilesExtension"
:disabled="!this.form.errorIgnored"
:disabled="this.form.errorIgnored == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2">
<el-button size="mini">浏览</el-button></el-col
<el-button :disabled="this.form.errorIgnored == 'N' || !this.form.errorIgnored" size="mini" @click="selectFilePath(4)">浏览</el-button></el-col
>
</el-row>
</el-form-item>
......@@ -554,6 +552,51 @@
</el-tab-pane>
</el-tabs>
<el-dialog
title="修改文件内容"
:visible.sync="fileBox"
width="500px"
:before-close="handleClose"
:modal="false"
>
<el-form ref="form" :model="fielForm" label-width="160px">
<el-form-item label="文件/目录:">
<el-input v-model="fielForm.name" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="通配符:">
<el-input v-model="fielForm.filemask"></el-input>
</el-form-item>
<el-form-item label="通配符号(排除):">
<el-input v-model="fielForm.excludeFileMask"></el-input>
</el-form-item>
<el-form-item label="要求:">
<el-select v-model="fielForm.fileRequired" style="width: 100%">
<el-option label="是" value="1"></el-option>
<el-option label="否" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="包含子目录:">
<el-select v-model="fielForm.includeSubFolders" style="width: 100%">
<el-option label="是" value="1"></el-option>
<el-option label="否" value="0"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="fileBox = false">取 消</el-button>
<el-button type="primary" @click="fileBox">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="添加字段"
:visible.sync="fieldBox"
......@@ -680,16 +723,64 @@
<el-button type="primary" @click="addFilterBox">确 定</el-button>
</span>
</el-dialog>
<!-- 文件浏览器-->
<el-dialog
title="文件浏览器"
:visible.sync="filePathSelection"
width="500px"
:before-close="handleClose"
:modal="false"
>
<browseFiles :disabed="true" v-on:route="route"></browseFiles>
<span slot="footer" class="dialog-footer">
<el-button @click="filePathSelection = false">取 消</el-button>
<el-button type="primary" @click="addFilePathSelection"
>确 定</el-button
>
</span>
</el-dialog>
</div>
</template>
<script>
import browseFiles from "../appBulletFrame/browseFiles";
import { valueFormat, valueMeta,formatMapperLineTerminator,availableCharsets,compressionProviderNames } from "@/api/kettle/link";
export default {
props: [""],
props: ["connectionNode"], //从父组件传过来的值
components: {
browseFiles,
},
data() {
return {
form:{
acceptingFilenames:"Y",
passingThruFields:"Y",
breakInEnclosureAllowed:"Y",
header:"Y",
footer:"Y",
lineWrapped:"Y",
layoutPaged:"Y",
noEmptyLines:"Y",
includeFilename:"Y",
includeRowNumber:"Y",
includeRowNumber:"Y",
dateFormatLenient:"Y",
dateFormatLocale:"Y",
addresult:"Y",
errorIgnored:"Y",
skipBadFiles:"Y",
errorLineSkipped:"Y",
},
fileBox:false,
filterBox: false,
fieldBox: false,
form: {},
......@@ -718,6 +809,12 @@ export default {
dataState: false,
fileType:[],
codingType:[],
routeState:0,
filePathSelection:false,
localPath:{},
fileSelection:{},
fielForm:{},
};
......@@ -733,6 +830,39 @@ export default {
methods: {
addFile(){
this.fileData.push(this.fileSelection)
this.fileSelection = {}
},
addFilePathSelection(){
this.filePathSelection = !this.filePathSelection
if (this.routeState == 1 ) {
this.fileSelection.fileName = this.localPath.fileName
}else if (this.routeState == 2 ) {
this.form.warningFilesDestinationDirectory = this.localPath.fileName
}else if (this.routeState == 3) {
this.form.errorFilesDestinationDirectory = this.localPath.fileName
}else if (this.routeState == 4) {
this.form.lineNumberFilesDestinationDirectory = this.localPath.fileName
}
},
route(flowData){
this.localPath.fileName = flowData.name
console.log(this.localPath);
},
selectFilePath(tsate){
this.routeState = tsate
this.filePathSelection = !this.filePathSelection
},
compressionProviderNamesFun(){
compressionProviderNames().then(res=>{
this.fieldCompress = res
......@@ -765,10 +895,7 @@ export default {
handleChange(file, fileList) {
this.fileList = fileList.slice(-3);
this.fileData.push({ fileName: file.name });
},
addFilterBox() {
this.filterBox = !this.filterBox;
......@@ -778,6 +905,15 @@ export default {
}
},
handleClick(val){
this.fileBox = !this.fileBox
this.fielForm = val
},
deleteRow(index, rows) {
rows.splice(index, 1);
},
filterClick(state, val) {
this.filterBox = !this.filterBox;
this.dataState = state;
......
......@@ -176,17 +176,9 @@
</el-select>
</el-form-item>
<el-form-item label="选中的文件:">
<!-- <input type="file" placeholder="上传" @change="fileChnageInput" /> -->
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:on-change="handleChange"
:show-file-list="false"
:auto-upload="false"
<el-button size="small" type="primary" @click="selectFilePath(1)"
>选择文件</el-button
>
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
<el-card class="box-card">
<el-table :data="ileListData" style="width: 100%">
<el-table-column prop="name" label="文件/目录" width="120">
......@@ -227,18 +219,24 @@
<el-card class="box-card">
<el-form ref="form" :model="form" label-width="200px">
<el-form-item label="从前面的步骤获取文件名:">
<el-checkbox v-model="form.checked"></el-checkbox>
<el-checkbox
v-model="form.checked"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="从哪个步骤读文件名:">
<el-select
v-model="form.wAccStep"
style="width: 100%"
:disabled="!form.checked"
:disabled="!form.checked || form.checked == 'N'"
>
<el-option v-for="item in connectionNode"
:key="item.id"
:label="item.name"
:value="item.name"></el-option>
<el-option
v-for="item in connectionNode"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
......@@ -246,7 +244,7 @@
<el-select
v-model="form.wAccField"
style="width: 100%"
:disabled="!form.checked"
:disabled="!form.checked || form.checked == 'N'"
>
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
......@@ -258,48 +256,61 @@
<el-tab-pane label="工作表" name="worksheet">
<h3>要读取的工作表列表</h3>
<el-button type="primary" @click="workClick(true)">添加工作表</el-button>
<br>
<el-card class="box-card">
<el-table :data="worksheetList" style="width: 100%">
<el-table-column prop="name" label="工作表名称" width="120">
</el-table-column>
<el-table-column prop="startrow" label="起始行">
</el-table-column>
<el-table-column prop="startcol" label="起始列">
</el-table-column>
<el-button type="primary" @click="workClick(true)"
>添加工作表</el-button
>
<br />
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="workClick(false,scope.row)"
type="text"
size="small"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deleteRow(scope.$index,worksheetList)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
<el-card class="box-card">
<el-table :data="worksheetList" style="width: 100%">
<el-table-column prop="name" label="工作表名称" width="120">
</el-table-column>
<el-table-column prop="startrow" label="起始行">
</el-table-column>
<el-table-column prop="startcol" label="起始列">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="workClick(false, scope.row)"
type="text"
size="small"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deleteRow(scope.$index, worksheetList)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="内容" name="content">
<el-form ref="form" :model="form" label-width="200px">
<el-form-item label="头部:">
<el-checkbox v-model="form.header"></el-checkbox>
<el-checkbox
v-model="form.header"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="没有空行:">
<el-checkbox v-model="form.noempty"></el-checkbox>
<el-checkbox
v-model="form.noempty"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="停在空白记录:">
<el-checkbox v-model="form.stoponempty"></el-checkbox>
<el-checkbox
v-model="form.stoponempty"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="限制:">
......@@ -308,19 +319,21 @@
<el-form-item label="编码:">
<el-select v-model="form.encoding" filterable style="width: 100%">
<el-option
v-for="item in codingType"
<el-option
v-for="item in codingType"
:key="item.index"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="添加文件名">
<el-checkbox v-model="form.add_to_result_filenames"></el-checkbox>
<el-checkbox
v-model="form.add_to_result_filenames"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
</el-form>
</el-tab-pane>
......@@ -328,15 +341,25 @@
<el-tab-pane label="错误处理" name="handling">
<el-form ref="form" :model="form" label-width="130px">
<el-form-item label="严格类型:">
<el-checkbox v-model="form.strict_types"></el-checkbox>
<el-checkbox
v-model="form.strict_types"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="忽略错误:">
<el-checkbox v-model="form.ignore"></el-checkbox>
<el-checkbox
v-model="form.ignore"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="跳过错误行:">
<el-checkbox
v-model="form.errorLineSkipped"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
......@@ -345,21 +368,30 @@
<el-col :span="8">
<el-input
v-model="form.bad_line_files_destination_directory"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.warningFilesExtension"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button size="mini">变量</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button size="mini">浏览</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(2)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
......@@ -369,21 +401,30 @@
<el-col :span="8">
<el-input
v-model="form.errorFilesDestinationDirectory"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.errorFilesExtension"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button size="mini">变量</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button size="mini">浏览</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(3)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
......@@ -393,21 +434,30 @@
<el-col :span="8">
<el-input
v-model="form.lineNumberFilesDestinationDirectory"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.lineNumberFilesExtension"
:disabled="!this.form.ignore"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button size="mini">变量</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button size="mini">浏览</el-button></el-col
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(4)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
......@@ -415,7 +465,9 @@
</el-tab-pane>
<el-tab-pane label="字段" name="field">
<el-button type="primary" @click="fieldClick(true)">添加字段</el-button>
<el-button type="primary" @click="fieldClick(true)"
>添加字段</el-button
>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="名称"> </el-table-column>
......@@ -442,7 +494,7 @@
<el-table-column label="操作" width="100px">
<template slot-scope="scope">
<el-button
@click="fieldClick(false,scope.row)"
@click="fieldClick(false, scope.row)"
type="text"
size="small"
>编辑</el-button
......@@ -665,9 +717,12 @@
width="800px"
:before-close="handleClose"
>
<tableInput :disabled="true" :connectionNode="connectionNode" :stepName="stepName"> </tableInput>
<tableInput
:disabled="true"
:connectionNode="connectionNode"
:stepName="stepName"
>
</tableInput>
<span slot="footer" class="dialog-footer">
<el-button @click="TableInputDialog = false">取 消</el-button>
......@@ -684,8 +739,6 @@
width="800px"
:before-close="handleClose"
>
<getSystemInformation :disabled="true"> </getSystemInformation>
<span slot="footer" class="dialog-footer">
......@@ -703,7 +756,6 @@
width="800px"
:before-close="handleClose"
>
<customConstant :disabled="true"> </customConstant>
<span slot="footer" class="dialog-footer">
......@@ -721,7 +773,6 @@
width="800px"
:before-close="handleClose"
>
<randomNumber :disabled="true"> </randomNumber>
<span slot="footer" class="dialog-footer">
......@@ -732,8 +783,6 @@
</span>
</el-dialog>
<!-- 生成记录-->
<el-dialog
title="生成记录"
......@@ -741,7 +790,6 @@
width="800px"
:before-close="handleClose"
>
<generatingRecords :disabed="true"></generatingRecords>
<span slot="footer" class="dialog-footer">
......@@ -752,7 +800,6 @@
</span>
</el-dialog>
<!-- 文本文件输入-->
<el-dialog
title="文本文件输入"
......@@ -760,8 +807,10 @@
width="800px"
:before-close="handleClose"
>
<textFileInput :disabed="true"></textFileInput>
<textFileInput
:disabed="true"
:connectionNode="connectionNode"
></textFileInput>
<span slot="footer" class="dialog-footer">
<el-button @click="TextFileInputDialog = false">取 消</el-button>
......@@ -771,25 +820,51 @@
</span>
</el-dialog>
<!-- 文件浏览器-->
<el-dialog
title="文件浏览器"
:visible.sync="filePathSelection"
width="500px"
:before-close="handleClose"
>
<browseFiles :disabed="true" v-on:route="route"></browseFiles>
<span slot="footer" class="dialog-footer">
<el-button @click="filePathSelection = false">取 消</el-button>
<el-button type="primary" @click="addFilePathSelection"
>确 定</el-button
>
</span>
</el-dialog>
<!-- 输出弹窗start=============== -->
<outDialog ref="tableOutPut" :tableOutPutVisible.sync="tableOutPutVisible" @fathertrans="fathertrans"></outDialog>
<insertOrUpdate ref="insertOrdate" :InsertOrUpdateVisible.sync="InsertOrUpdateVisible"></insertOrUpdate>
<excelOutPutDialog ref="excelOut" :excelOutPutVisible.sync="excelOutPutVisible"></excelOutPutDialog>
<updateDialog ref="update" :updateVisible.sync="updateVisible"></updateDialog>
<outDialog
ref="tableOutPut"
:tableOutPutVisible.sync="tableOutPutVisible"
@fathertrans="fathertrans"
></outDialog>
<insertOrUpdate
ref="insertOrdate"
:InsertOrUpdateVisible.sync="InsertOrUpdateVisible"
></insertOrUpdate>
<excelOutPutDialog
ref="excelOut"
:excelOutPutVisible.sync="excelOutPutVisible"
></excelOutPutDialog>
<updateDialog
ref="update"
:updateVisible.sync="updateVisible"
></updateDialog>
<synDialog ref="syn" :synVisible.sync="synVisible"></synDialog>
<delDialog ref="del" :deleteVisible.sync="deleteVisible"></delDialog>
<sqlDialog ref="sql" :sqlVisible.sync="sqlVisible"></sqlDialog>
<textFileDialog ref="textFile" :fileVisible.sync="fileVisible"></textFileDialog>
<textFileDialog
ref="textFile"
:fileVisible.sync="fileVisible"
></textFileDialog>
<microDialog ref="mic" :microVisible.sync="microVisible"></microDialog>
<!-- 输出弹窗end================== -->
</div>
</template>
......@@ -810,7 +885,7 @@ import {
availableCharsets,
valueFormat,
valueMeta,
save
save,
} from "@/api/kettle/link";
// 输入弹窗
import tableInput from "../appBulletFrame/tableInput";
......@@ -819,75 +894,91 @@ import customConstant from "../appBulletFrame/customConstant";
import randomNumber from "../appBulletFrame/randomNumber";
import generatingRecords from "../appBulletFrame/generatingRecords";
import textFileInput from "../appBulletFrame/textFileInput";
import browseFiles from "../appBulletFrame/browseFiles";
// 输出弹窗start******************************************
import outDialog from '../../../output-dialog/table-out'
import insertOrUpdate from '../../../output-dialog/insertOrUpdate'
import excelOutPutDialog from '../../../output-dialog/Excel-output'
import updateDialog from '../../../output-dialog/update'
import synDialog from '../../../output-dialog/synchronize'
import delDialog from '../../../output-dialog/delete'
import sqlDialog from '../../../output-dialog/sqlFileOutput'
import textFileDialog from '../../../output-dialog/text-file-output'
import microDialog from '../../../output-dialog/micro-excel'
import outDialog from "../../../output-dialog/table-out";
import insertOrUpdate from "../../../output-dialog/insertOrUpdate";
import excelOutPutDialog from "../../../output-dialog/Excel-output";
import updateDialog from "../../../output-dialog/update";
import synDialog from "../../../output-dialog/synchronize";
import delDialog from "../../../output-dialog/delete";
import sqlDialog from "../../../output-dialog/sqlFileOutput";
import textFileDialog from "../../../output-dialog/text-file-output";
import microDialog from "../../../output-dialog/micro-excel";
// 输出弹窗end********************************************
// XML
import {
mxUtils as MxUtils,
mxGraph as MxGraph,
// mxEvent as MxEvent,
// mxKeyHandler as MxKeyHandler,
// mxRubberband as MxRubberBand,
// mxConstants as MxConstants,
// mxStencilRegistry as MxStencilRegistry,
// mxStencil as MxStencil,
mxCodec as MxCodec,
mxGraphModel as MxGraphModel,
mxGeometry as MxGeometry,
} from "mxgraph/javascript/mxClient";
// import { mxGraph } from 'mxgraph-js';
export default {
props: {
dialogVisibleFourth: {
type: Boolean,
default: false
}
dialogVisibleFourth: {
type: Boolean,
default: false,
},
},
data() {
return {
// 转xml
graph: null,
graphXml: "",
// mxl=================================
InsertOrUpdateVisible:false,
tableOutPutVisible:false,
excelOutPutVisible:false,
updateVisible:false,
synVisible:false,
deleteVisible:false,
sqlVisible:false,
fileVisible:false,
microVisible:false,
InsertOrUpdateVisible: false,
tableOutPutVisible: false,
excelOutPutVisible: false,
updateVisible: false,
synVisible: false,
deleteVisible: false,
sqlVisible: false,
fileVisible: false,
microVisible: false,
// mxl=================================
// 输入模块
ileListData:[],
worksheetList:[],
publicData: [], //全部连接
connectionNode:{},
codingType:[],
TextFileInputDialog:false,
RowGeneratorDialog:false,
TableInputDialog:false,
SystemInfoDialog:false,
ConstantDialog:false,
RandomValueDialog:false,
excelLnput:false,
dataState:false,
ileListData: [],
worksheetList: [],
publicData: [], //全部连接
connectionNode: {},
codingType: [],
routeState: 0,
filePathSelection: false,
TextFileInputDialog: false,
RowGeneratorDialog: false,
TableInputDialog: false,
SystemInfoDialog: false,
ConstantDialog: false,
RandomValueDialog: false,
excelLnput: false,
dataState: false,
edit: false,
work: false,
field: false,
form: {},
formFile:{},
formFile: {},
activeName: "file",
fieldType:[],
fieldFormat:[],
stepName:{},
fieldType: [],
fieldFormat: [],
stepName: {},
tableData: [
{
filemask: "",
......@@ -899,7 +990,6 @@ export default {
],
engine: [],
// 画布模块
isShowIcon: false,
isLeftMenu: true,
......@@ -924,10 +1014,8 @@ export default {
},
zoom: 0.5,
workForm:{},
fieldForm:{},
workForm: {},
fieldForm: {},
};
},
// 一些基础配置移动该文件中
......@@ -942,19 +1030,19 @@ export default {
customConstant,
randomNumber,
textFileInput,
browseFiles,
// FlowNodeForm
// 弹窗组件start***********************
outDialog,//表输出
insertOrUpdate,//插入或更新
excelOutPutDialog,
updateDialog,
synDialog,
delDialog,
sqlDialog,
textFileDialog,
microDialog
// 弹窗组件end***********************
// 弹窗组件start***********************
outDialog, //表输出
insertOrUpdate, //插入或更新
excelOutPutDialog,
updateDialog,
synDialog,
delDialog,
sqlDialog,
textFileDialog,
microDialog,
// 弹窗组件end***********************
},
//自定义指令 https://www.jb51.net/article/108047.htm
directives: {
......@@ -1061,28 +1149,42 @@ export default {
console.log("初始化流程数据", new Function("return " + data_test)());
this.dataReload(new Function("return " + data_test)());
});
this.createGraph();
},
methods: {
addFilePathSelection() {
this.filePathSelection = !this.filePathSelection;
if (this.routeState == 1) {
this.ileListData.push(this.localPath);
} else if (this.routeState == 2) {
this.form.bad_line_files_destination_directory = this.localPath.name;
} else if (this.routeState == 3) {
this.form.errorFilesDestinationDirectory = this.localPath.name;
} else if (this.routeState == 4) {
this.form.lineNumberFilesDestinationDirectory = this.localPath.name;
}
},
route(flowData) {
this.localPath = flowData;
console.log(this.localPath);
},
selectFilePath(tsate) {
this.routeState = tsate;
this.filePathSelection = !this.filePathSelection;
},
// 子组件发射回来的弹窗变量变为true
fathertrans(res){
fathertrans(res) {
// this.dialogVisibleFourth=res;
this.$emit("update:dialogVisibleFourth", res);
console.log('发射回父组件====');
this.$emit("update:dialogVisibleFourth", res);
console.log("发射回父组件====");
},
fileChnageInput(e) {
console.log(e);
},
// 上传
handleChange(file, fileList) {
// console.log(file);
this.fileList = fileList.slice(-3);
this.ileListData.push({ name: file.name });
// console.log(this.tableData);
// this.getObjectURL(file.raw)
// console.log(this.getObjectURL(file.raw));
},
getObjectURL(file) {
let url = null;
......@@ -1099,12 +1201,12 @@ export default {
rows.splice(index, 1);
},
deletefield(index, rows){
rows.splice(index, 1);
deletefield(index, rows) {
rows.splice(index, 1);
},
deleteFile(index, rows){
rows.splice(index, 1);
deleteFile(index, rows) {
rows.splice(index, 1);
},
tapClick() {},
// 文件
......@@ -1112,44 +1214,40 @@ rows.splice(index, 1);
this.edit = !this.edit;
this.formFile = val;
},
// 字段
addField(){
this.field = !this.field
// 字段
addField() {
this.field = !this.field;
if (this.dataState) {
this.tableData.push(this.fieldForm)
}else{
this.tableData.push(this.fieldForm);
} else {
}
},
fieldClick(state,val) {
fieldClick(state, val) {
this.field = !this.field;
this.dataState = state
this.dataState = state;
if (state) {
this.fieldForm = {}
}else{
this.fieldForm = {};
} else {
this.fieldForm = val;
}
},
// 工作表
workClick(state,val) {
// 工作表
workClick(state, val) {
this.work = !this.work;
this.dataState = state
this.dataState = state;
if (state) {
this.workForm = {}
}else{
this.workForm = {};
} else {
this.workForm = val;
}
},
addWork(){
this.work = !this.work
addWork() {
this.work = !this.work;
if (this.dataState) {
this.worksheetList.push(this.workForm)
}else{
this.worksheetList.push(this.workForm);
} else {
}
},
// 关闭弹框
......@@ -1242,13 +1340,12 @@ rows.splice(index, 1);
}); //获取连接节点
if (this.publicData[to]) {
this.publicData[to].push(obj);
this.publicData[to].push(obj);
} else {
this.publicData[to] = [obj];
}
console.log(this.publicData)
console.log(this.publicData);
return true;
});
......@@ -1358,16 +1455,13 @@ rows.splice(index, 1);
},
// 删除线
deleteLine(from, to) {
delete this.publicData[to]
delete this.publicData[to];
this.flowData.lineList = this.flowData.lineList.filter(function (line) {
if (line.from == from && line.to == to) {
return false;
}
return true;
});
},
// 改变连线
......@@ -1407,6 +1501,7 @@ rows.splice(index, 1);
this.$message.error("请把节点拖入到画布中");
return;
}
left = left - containerRect.x + efContainer.scrollLeft;
top = top - containerRect.y + efContainer.scrollTop;
// 居中
......@@ -1432,7 +1527,9 @@ rows.splice(index, 1);
}
break;
}
console.log("-------003", nodeMenu.type);
var node = {
id: nodeId, //节点id--前端唯一的
name: nodeName, //节点名称
......@@ -1563,8 +1660,8 @@ rows.splice(index, 1);
console.log("点击节点操作", node);
// this.$emit("dialogVisibleFourth",true);
// this.$emit('updata:dialogVisibleFourth',true); //触发showbox方法,true为向父组件传递的数据
this.stepName = node
this.connectionNode = this.publicData[node.id]
this.stepName = node;
this.connectionNode = this.publicData[node.id];
console.log(this.connectionNode);
this.isShowR = true;
this.activeElement.type = "node";
......@@ -1607,14 +1704,14 @@ rows.splice(index, 1);
} else if (node.ids == "step5") {
this.ConstantDialog = !this.ConstantDialog;
return;
}else if (node.ids == "step4") {
} else if (node.ids == "step4") {
this.RandomValueDialog = !this.RandomValueDialog;
return;
}else if (node.ids == "step3") {
this.RowGeneratorDialog = !this.RowGeneratorDialog
} else if (node.ids == "step3") {
this.RowGeneratorDialog = !this.RowGeneratorDialog;
return;
}else if (node.ids == "step2") {
this.TextFileInputDialog = !this.TextFileInputDialog
} else if (node.ids == "step2") {
this.TextFileInputDialog = !this.TextFileInputDialog;
return;
}
if (node.ids == "step16") {
......@@ -1670,46 +1767,78 @@ rows.splice(index, 1);
let flowObj = Object.assign({}, that.flowData);
// localStorage.setItem("data_test", JSON.stringify(flowObj))
console.log("保存流程图", flowObj);
console.log(this.jsPlumb.getAllConnections())
// this.graphXml = this.encode(this.graph);
// console.log(this.graphXml,'8888888888888888');
// if (!that.checkFlow()) return;
// that.$message.success("保存流程成功!暂时请查先看控制台。");
var xml2js = require('xml2js');
//xml->json
//xml2js默认会把子子节点的值变为一个数组, explicitArray设置为false
var xmlParser = new xml2js.Parser({explicitArray : false, ignoreAttrs : true})
//json->xml
var jsonBuilder = new xml2js.Builder();
//测试用例
var xml = "<root>flowObj xml2js!</root>";
var obj = flowObj
console.log('----------');
// xml -> json
xmlParser.parseString(xml, function (err, result) {
//将返回的结果再次格式化
console.log(JSON.stringify(result));
});
console.log('----------');
//json --> xml
var builder = new xml2js.Builder();
var jsonxml = builder.buildObject(obj);
console.log(jsonxml);
console.log('----------');
// 保存
let pamers = new FormData(); // 创建form对象
// var xml2js = require('xml2js');
// //xml->json
// //xml2js默认会把子子节点的值变为一个数组, explicitArray设置为false
// var xmlParser = new xml2js.Parser({explicitArray : false, ignoreAttrs : true})
// //json->xml
// var jsonBuilder = new xml2js.Builder();
// //测试用例
// var xml = "<root>flowObj xml2js!</root>";
// var obj = flowObj
// console.log('----------');
// // xml -> json
// xmlParser.parseString(xml, function (err, result) {
// //将返回的结果再次格式化
// console.log(JSON.stringify(result));
// });
// console.log('----------');
// //json --> xml
// var builder = new xml2js.Builder();
// var jsonxml = builder.buildObject(obj);
// console.log(jsonxml);
// console.log('----------');
// 保存
let pamers = new FormData(); // 创建form对象
pamers.append("graphXml", jsonxml);
save(pamers).then(res=>{
console.log(res);
save(pamers).then((res) => {
console.log(res);
if (res.success) {
that.$message.success("保存流程成功!暂时请查先看控制台。");
} else {
that.$message.error(res.errMsg);
}
});
},
})
// 转xml
createGraph() {
this.graph = new MxGraph(this.$refs.efContainer);
},
encode(graph) {
const encoder = new MxCodec();
const result = encoder.encode(graph.getModel());
return MxUtils.getPrettyXml(result);
},
decode(graphXml, graph) {
window["mxGraphModel"] = MxGraphModel;
window["mxGeometry"] = MxGeometry;
const xmlDocument = MxUtils.parseXml(graphXml);
const decoder = new MxCodec(xmlDocument);
const node = xmlDocument.documentElement;
decoder.decode(node, graph.getModel());
},
//重绘流程图
clearFlow() {
let that = this;
......
<template>
<div class="menu" ref="">
<el-tree
class="trees"
:data="data"
:props="defaultProps"
:render-after-expand="false"
>
<div class="custom-tree-node" slot-scope="{ node, data }">
<div
class="custom-tree-node"
:key-id="data.children ? '' : 123"
:id="data.id"
:icon="data.icon"
>
{{ data.text }}
</div>
</div>
</el-tree>
</div>
</template>
<script>
import { steps } from "@/api/kettle/link";
export default {
name: "nodeMenu2",
data() {
return {
defaultProps: {
children: "children",
label: "text",
id: "id",
},
data: [],
};
},
components: {},
created() {
this.stepsFun()
},
mounted() {
},
beforeUpdate(){
this.$emit('shooStatus',true)
},
methods: {
stepsFun() {
let pamer = new FormData(); // 创建form对象
pamer.append("node", "xnode-12");
this.$forceUpdate();
steps(pamer).then((res) => {
this.data = res;
});
},
},
};
</script>
<template>
<div class="ef-flow-box" v-if="easyFlowVisible">
<div class="ef-flow-header">
<el-row>
<!--顶部工具菜单-->
<el-col :span="24">
<div class="ef-tooltar">
<el-link type="primary" :underline="false">{{
flowData.name
}}</el-link>
<el-divider direction="vertical"></el-divider>
<el-tooltip
class="item"
effect="dark"
:open-delay="300"
content="保存流程图"
placement="bottom"
>
<el-button
type="text"
icon="el-icon-receiving"
size="large"
></el-button>
</el-tooltip>
<el-divider direction="vertical"></el-divider>
<el-tooltip
class="item"
effect="dark"
:open-delay="300"
content="生产流程图片"
placement="bottom"
>
<el-button
type="text"
icon="el-icon-picture"
size="large"
></el-button>
</el-tooltip>
<el-divider direction="vertical"></el-divider>
<el-tooltip
class="item"
effect="dark"
content="重新绘制"
placement="bottom"
>
<el-button
type="text"
icon="el-icon-refresh"
size="large"
></el-button>
</el-tooltip>
<el-divider direction="vertical"></el-divider>
<el-tooltip
class="item"
effect="dark"
content="点击删除"
placement="bottom"
>
<el-button
type="text"
icon="el-icon-delete"
size="large"
@click="deleteFlow"
></el-button>
</el-tooltip>
<el-divider direction="vertical"></el-divider>
<el-tooltip
class="item"
effect="dark"
content="设置"
placement="bottom"
>
<el-button
type="text"
icon="el-icon-setting"
size="large"
></el-button>
</el-tooltip>
</div>
</el-col>
</el-row>
</div>
<div class="ef-flow-main">
<!-- 画布start -->
<div class="mxgraphClass">
<div id="mxgraph" ref="container"></div>
</div>
</div>
<!-- 输入工具弹框 -->
<!--
<el-dialog
title="Excelt输入"
:visible.sync="excelLnput"
width="800px"
:before-close="handleClose"
>
<div id="ExcelInputDialog"></div>
<el-form ref="stepName" :model="stepName" label-width="120px">
<el-form-item label="步骤名称:">
<el-input v-model="stepName.name"></el-input>
</el-form-item>
</el-form>
<el-tabs v-model="activeName" type="border-card" @tab-click="tapClick">
<el-tab-pane label="文件" name="file">
<el-form ref="form" :model="form" label-width="120px">
<el-form-item label="表格类(引擎):">
<el-select v-model="form.engine" style="width: 100%">
<el-option
v-for="item in engine"
:key="item.code"
:label="item.desc"
:value="item.code"
/>
</el-select>
</el-form-item>
<el-form-item label="选中的文件:">
<el-button size="small" type="primary" @click="selectFilePath(1)"
>选择文件</el-button
>
<el-card class="box-card">
<el-table :data="ileListData" style="width: 100%">
<el-table-column prop="name" label="文件/目录" width="120">
</el-table-column>
<el-table-column prop="filemask" label="通配符">
</el-table-column>
<el-table-column
prop="exclude_filemask"
label="通配符号(排除)"
width="120"
>
</el-table-column>
<el-table-column prop="file_required" label="要求">
</el-table-column>
<el-table-column prop="include_subfolders" label="包含子目录">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="handleClick(scope.row)"
type="text"
size="small"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deleteFile(scope.$index, ileListData)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
</el-form-item>
</el-form>
<el-card class="box-card">
<el-form ref="form" :model="form" label-width="200px">
<el-form-item label="从前面的步骤获取文件名:">
<el-checkbox
v-model="form.checked"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="从哪个步骤读文件名:">
<el-select
v-model="form.wAccStep"
style="width: 100%"
:disabled="!form.checked || form.checked == 'N'"
>
<el-option
v-for="item in connectionNode"
:key="item.id"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="保存文件的字段:">
<el-select
v-model="form.wAccField"
style="width: 100%"
:disabled="!form.checked || form.checked == 'N'"
>
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
</el-form>
</el-card>
</el-tab-pane>
<el-tab-pane label="工作表" name="worksheet">
<h3>要读取的工作表列表</h3>
<el-button type="primary" @click="workClick(true)"
>添加工作表</el-button
>
<br />
<el-card class="box-card">
<el-table :data="worksheetList" style="width: 100%">
<el-table-column prop="name" label="工作表名称" width="120">
</el-table-column>
<el-table-column prop="startrow" label="起始行">
</el-table-column>
<el-table-column prop="startcol" label="起始列">
</el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
@click="workClick(false, scope.row)"
type="text"
size="small"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deleteRow(scope.$index, worksheetList)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-card>
</el-tab-pane>
<el-tab-pane label="内容" name="content">
<el-form ref="form" :model="form" label-width="200px">
<el-form-item label="头部:">
<el-checkbox
v-model="form.header"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="没有空行:">
<el-checkbox
v-model="form.noempty"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="停在空白记录:">
<el-checkbox
v-model="form.stoponempty"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="限制:">
<el-input v-model="form.limit"></el-input>
</el-form-item>
<el-form-item label="编码:">
<el-select v-model="form.encoding" filterable style="width: 100%">
<el-option
v-for="item in codingType"
:key="item.index"
:label="item.name"
:value="item.name"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="添加文件名">
<el-checkbox
v-model="form.add_to_result_filenames"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="错误处理" name="handling">
<el-form ref="form" :model="form" label-width="130px">
<el-form-item label="严格类型:">
<el-checkbox
v-model="form.strict_types"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="忽略错误:">
<el-checkbox
v-model="form.ignore"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="跳过错误行:">
<el-checkbox
v-model="form.errorLineSkipped"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
true-label="Y"
false-label="N"
></el-checkbox>
</el-form-item>
<el-form-item label="告警文件目录:">
<el-row :gutter="10">
<el-col :span="8">
<el-input
v-model="form.bad_line_files_destination_directory"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.warningFilesExtension"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(2)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
<el-form-item label="错误件目录:">
<el-row :gutter="10">
<el-col :span="8">
<el-input
v-model="form.errorFilesDestinationDirectory"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.errorFilesExtension"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(3)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
<el-form-item label="失败行数文件目录:">
<el-row :gutter="10">
<el-col :span="8">
<el-input
v-model="form.lineNumberFilesDestinationDirectory"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">扩展名</el-col>
<el-col :span="8">
<el-input
v-model="form.lineNumberFilesExtension"
:disabled="!this.form.ignore || this.form.ignore == 'N'"
></el-input>
</el-col>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
>变量</el-button
></el-col
>
<el-col class="line" :span="2.5">
<el-button
:disabled="!this.form.ignore || this.form.ignore == 'N'"
size="mini"
@click="selectFilePath(4)"
>浏览</el-button
></el-col
>
</el-row>
</el-form-item>
</el-form>
</el-tab-pane>
<el-tab-pane label="字段" name="field">
<el-button type="primary" @click="fieldClick(true)"
>添加字段</el-button
>
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="name" label="名称"> </el-table-column>
<el-table-column prop="type" label="类型"> </el-table-column>
<el-table-column prop="length" label="长度"> </el-table-column>
<el-table-column prop="precision" label="精度"> </el-table-column>
<el-table-column prop="trim_type" label="去除空格类型">
</el-table-column>
<el-table-column prop="repeat" label="重复"> </el-table-column>
<el-table-column prop="format" label="格式"> </el-table-column>
<el-table-column prop="currency" label="货币"> </el-table-column>
<el-table-column prop="decimal" label="小数"> </el-table-column>
<el-table-column prop="group" label="分组"> </el-table-column>
<el-table-column label="操作" width="100px">
<template slot-scope="scope">
<el-button
@click="fieldClick(false, scope.row)"
type="text"
size="small"
>编辑</el-button
>
<el-button
type="text"
size="small"
@click="deletefield(scope.$index, tableData)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="其他输出字段" name="oher ">
<el-form ref="form" :model="form" label-width="150px">
<el-form-item label="文件名称字段:">
<el-input v-model="form.filefield"></el-input>
</el-form-item>
<el-form-item label="Sheet名称字段:">
<el-input v-model="form.sheetfield"></el-input>
</el-form-item>
<el-form-item label="Sheet的行号列:">
<el-input v-model="form.sheetrownumfield"></el-input>
</el-form-item>
<el-form-item label="行号列:">
<el-input v-model="form.rownumfield"></el-input>
</el-form-item>
<el-form-item label="文件名字段:">
<el-input v-model="form.shortFileFieldName"></el-input>
</el-form-item>
<el-form-item label="扩展名字段:">
<el-input v-model="form.extensionFieldName"></el-input>
</el-form-item>
<el-form-item label="路径字段:">
<el-input v-model="form.pathFieldName"></el-input>
</el-form-item>
<el-form-item label="文件大小字段:">
<el-input v-model="form.sizeFieldName"></el-input>
</el-form-item>
<el-form-item label="是否为隐藏文件字段:">
<el-input v-model="form.hiddenFieldName"></el-input>
</el-form-item>
<el-form-item label="最后修改时间字段:">
<el-input v-model="form.lastModificationTimeFieldName"></el-input>
</el-form-item>
<el-form-item label="Uri字段:">
<el-input v-model="form.uriNameFieldName"></el-input>
</el-form-item>
<el-form-item label="Root uri字段:">
<el-input v-model="form.rootUriNameFieldName"></el-input>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<el-button @click="excelLnput = false">取 消</el-button>
<el-button type="primary" @click="excelLnput = false">确 定</el-button>
</span>
</el-dialog> -->
<!-- 修改-->
<!-- <el-dialog
title="编辑"
:visible.sync="edit"
width="500px"
:before-close="handleClose"
>
<el-form ref="form" :model="formFile" label-width="150px">
<el-form-item label="文件/目录:">
<el-input v-model="formFile.name" :disabled="true"></el-input>
</el-form-item>
<el-form-item label="通配符:">
<el-input v-model="formFile.filemask"></el-input>
</el-form-item>
<el-form-item label="通配符号(排除):">
<el-input v-model="formFile.exclude_filemask"></el-input>
</el-form-item>
<el-form-item label="要求:">
<el-select v-model="formFile.file_required" style="width: 100%">
<el-option label="是" value="1"></el-option>
<el-option label="否" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="包含子目录:">
<el-select v-model="formFile.include_subfolders" style="width: 100%">
<el-option label="是" value="1"></el-option>
<el-option label="否" value="0"></el-option>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="edit = false">取 消</el-button>
<el-button type="primary" @click="edit = false">确 定</el-button>
</span>
</el-dialog> -->
<!-- 工作添加/修改-->
<!-- <el-dialog
title="编辑"
:visible.sync="work"
width="500px"
:before-close="handleClose"
>
<el-form ref="form" :model="workForm" label-width="150px">
<el-form-item label="工作表名称:">
<el-input v-model="workForm.name"></el-input>
</el-form-item>
<el-form-item label="起始行:">
<el-input v-model="workForm.startLine"></el-input>
</el-form-item>
<el-form-item label="起始列:">
<el-input v-model="workForm.startColumn"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="work = false">取 消</el-button>
<el-button type="primary" @click="addWork">确 定</el-button>
</span>
</el-dialog> -->
<!-- 字段添加/修改-->
<!-- <el-dialog
title="编辑"
:visible.sync="field"
width="500px"
:before-close="handleClose"
>
<el-form ref="form" :model="fieldForm" label-width="120px">
<el-form-item label="名称:">
<el-input v-model="fieldForm.name"></el-input>
</el-form-item>
<el-form-item label="类型:">
<el-select v-model="fieldForm.type" style="width: 100%">
<el-option
v-for="item in fieldType"
:key="item.id"
:label="item.name"
:value="item.name"
/>
</el-select>
</el-form-item>
<el-form-item label="长度:">
<el-input v-model="fieldForm.length"></el-input>
</el-form-item>
<el-form-item label="精度:">
<el-input v-model="fieldForm.accuracy"></el-input>
</el-form-item>
<el-form-item label="去除空格类型:">
<el-select v-model="fieldForm.space" style="width: 100%">
<el-option label="不去掉空格" value="none"></el-option>
<el-option label="去掉左空格" value="left"></el-option>
<el-option label="去掉右空格" value="right"></el-option>
<el-option label="去掉左右两端空格" value="both"></el-option>
</el-select>
</el-form-item>
<el-form-item label="重复:">
<el-input v-model="fieldForm.repeat"></el-input>
</el-form-item>
<el-form-item label="格式:">
<el-select v-model="fieldForm.format" style="width: 100%">
<el-option
v-for="item in fieldFormat"
:key="item.index"
:label="item.name"
:value="item.name"
/></el-select>
</el-form-item>
<el-form-item label="货币:">
<el-input v-model="fieldForm.currency"></el-input>
</el-form-item>
<el-form-item label="小数:">
<el-input v-model="fieldForm.decimal"></el-input>
</el-form-item>
<el-form-item label="分组:">
<el-input v-model="fieldForm.grouping"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="field = false">取 消</el-button>
<el-button type="primary" @click="addField">确 定</el-button>
</span>
</el-dialog> -->
<!-- 表输入-->
<!-- <el-dialog
title="表输入"
:visible.sync="TableInputDialog"
width="800px"
:before-close="handleClose"
>
<tableInput
:disabled="true"
:connectionNode="connectionNode"
:stepName="stepName"
>
</tableInput>
<span slot="footer" class="dialog-footer">
<el-button @click="TableInputDialog = false">取 消</el-button>
<el-button type="primary" @click="TableInputDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 获取系统信息-->
<!-- <el-dialog
title="获取系统信息"
:visible.sync="SystemInfoDialog"
width="800px"
:before-close="handleClose"
>
<getSystemInformation :disabled="true"> </getSystemInformation>
<span slot="footer" class="dialog-footer">
<el-button @click="SystemInfoDialog = false">取 消</el-button>
<el-button type="primary" @click="SystemInfoDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 自定义常量数据-->
<!-- <el-dialog
title="自定义常量数据"
:visible.sync="ConstantDialog"
width="800px"
:before-close="handleClose"
>
<customConstant :disabled="true"> </customConstant>
<span slot="footer" class="dialog-footer">
<el-button @click="ConstantDialog = false">取 消</el-button>
<el-button type="primary" @click="ConstantDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 生成随机数-->
<!-- <el-dialog
title="生成随机数"
:visible.sync="RandomValueDialog"
width="800px"
:before-close="handleClose"
>
<randomNumber :disabled="true"> </randomNumber>
<span slot="footer" class="dialog-footer">
<el-button @click="RandomValueDialog = false">取 消</el-button>
<el-button type="primary" @click="RandomValueDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 生成记录-->
<!-- <el-dialog
title="生成记录"
:visible.sync="RowGeneratorDialog"
width="800px"
:before-close="handleClose"
>
<generatingRecords :disabed="true"></generatingRecords>
<span slot="footer" class="dialog-footer">
<el-button @click="RowGeneratorDialog = false">取 消</el-button>
<el-button type="primary" @click="RowGeneratorDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 文本文件输入-->
<!-- <el-dialog
title="文本文件输入"
:visible.sync="TextFileInputDialog"
width="800px"
:before-close="handleClose"
>
<textFileInput
:disabed="true"
:connectionNode="connectionNode"
></textFileInput>
<span slot="footer" class="dialog-footer">
<el-button @click="TextFileInputDialog = false">取 消</el-button>
<el-button type="primary" @click="TextFileInputDialog = false"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 文件浏览器-->
<!-- <el-dialog
title="文件浏览器"
:visible.sync="filePathSelection"
width="500px"
:before-close="handleClose"
>
<browseFiles :disabed="true" v-on:route="route"></browseFiles>
<span slot="footer" class="dialog-footer">
<el-button @click="filePathSelection = false">取 消</el-button>
<el-button type="primary" @click="addFilePathSelection"
>确 定</el-button
>
</span>
</el-dialog> -->
<!-- 输出弹窗start=============== -->
<!-- <outDialog
ref="tableOutPut"
:tableOutPutVisible.sync="tableOutPutVisible"
@fathertrans="fathertrans"
></outDialog>
<insertOrUpdate
ref="insertOrdate"
:InsertOrUpdateVisible.sync="InsertOrUpdateVisible"
></insertOrUpdate>
<excelOutPutDialog
ref="excelOut"
:excelOutPutVisible.sync="excelOutPutVisible"
></excelOutPutDialog>
<updateDialog
ref="update"
:updateVisible.sync="updateVisible"
></updateDialog>
<synDialog ref="syn" :synVisible.sync="synVisible"></synDialog>
<delDialog ref="del" :deleteVisible.sync="deleteVisible"></delDialog>
<sqlDialog ref="sql" :sqlVisible.sync="sqlVisible"></sqlDialog>
<textFileDialog
ref="textFile"
:fileVisible.sync="fileVisible"
></textFileDialog>
<microDialog ref="mic" :microVisible.sync="microVisible"></microDialog> -->
<!-- 输出弹窗end================== -->
</div>
</template>
<script>
import draggable from "vuedraggable";
// 使用修改后的jsplumb
import lodash from "lodash"; //JavaScript 实用工具库
import {
excelSheetType,
previousSteps,
inputOutputFields,
availableCharsets,
valueFormat,
valueMeta,
save,
} from "@/api/kettle/link";
// 输入弹窗
import tableInput from "../appBulletFrame/tableInput";
import getSystemInformation from "../appBulletFrame/getSystemInformation";
import customConstant from "../appBulletFrame/customConstant";
import randomNumber from "../appBulletFrame/randomNumber";
import generatingRecords from "../appBulletFrame/generatingRecords";
import textFileInput from "../appBulletFrame/textFileInput";
import browseFiles from "../appBulletFrame/browseFiles";
// 输出弹窗start******************************************
import outDialog from "../../../output-dialog/table-out";
import insertOrUpdate from "../../../output-dialog/insertOrUpdate";
import excelOutPutDialog from "../../../output-dialog/Excel-output";
import updateDialog from "../../../output-dialog/update";
import synDialog from "../../../output-dialog/synchronize";
import delDialog from "../../../output-dialog/delete";
import sqlDialog from "../../../output-dialog/sqlFileOutput";
import textFileDialog from "../../../output-dialog/text-file-output";
import microDialog from "../../../output-dialog/micro-excel";
// 输出弹窗end********************************************
import {
mxGraph,
mxUtils,
mxEvent,
mxCell,
mxKeyHandler,
mxRubberband,
mxConstants,
mxStencilRegistry,
mxStencil,
mxCodec,
mxGraphModel,
mxGeometry,
} from "mxgraph-js";
// XML
// import {
// mxUtils as mxUtils,
// mxGraph as mxGraph,
// mxEvent as mxEvent,
// mxKeyHandler as mxKeyHandler,
// mxRubberband as mxRubberband,
// mxConstants as mxConstants,
// mxStencilRegistry as mxStencilRegistry,
// mxStencil as mxStencil,
// mxCodec as mxCodec,
// mxGraphModel as mxGraphModel,
// mxGeometry as mxGeometry,
// } from "mxgraph/javascript/mxClient";
export default {
props: {
dialogVisibleFourth: {
type: Boolean,
default: false,
},
},
data() {
return {
keyHandler: null,
palettes: {},
graphXml: "",
// mxl=================================
InsertOrUpdateVisible: false,
tableOutPutVisible: false,
excelOutPutVisible: false,
updateVisible: false,
synVisible: false,
deleteVisible: false,
sqlVisible: false,
fileVisible: false,
microVisible: false,
// mxl=================================
// 输入模块
ileListData: [],
worksheetList: [],
publicData: [], //全部连接
connectionNode: {},
codingType: [],
routeState: 0,
filePathSelection: false,
TextFileInputDialog: false,
RowGeneratorDialog: false,
TableInputDialog: false,
SystemInfoDialog: false,
ConstantDialog: false,
RandomValueDialog: false,
excelLnput: false,
dataState: false,
edit: false,
work: false,
field: false,
form: {},
formFile: {},
activeName: "file",
fieldType: [],
fieldFormat: [],
stepName: {},
tableData: [
{
filemask: "",
name: "王小虎",
exclude_filemask: "",
file_required: "0",
include_subfolders: "1",
},
],
engine: [],
// 画布模块
isShowIcon: false,
isLeftMenu: true,
isShowR: false,
// graph 实例
graph: null,
// 控制画布销毁
easyFlowVisible: true,
// 是否加载完毕标志位
loadEasyFlowFinish: false,
// 数据
flowData: {},
// 激活的元素、可能是节点、可能是连线
activeElement: {
// 可选值 node 、line
type: undefined,
// 节点ID
nodeId: undefined,
// 连线ID
sourceId: undefined,
targetId: undefined,
},
zoom: 0.5,
workForm: {},
fieldForm: {},
};
},
// 一些基础配置移动该文件中
// mixins: [easyFlowMixin],
components: {
tableInput,
draggable,
getSystemInformation,
generatingRecords,
customConstant,
randomNumber,
textFileInput,
browseFiles,
// FlowNodeForm
// 弹窗组件start***********************
outDialog, //表输出
insertOrUpdate, //插入或更新
excelOutPutDialog,
updateDialog,
synDialog,
delDialog,
sqlDialog,
textFileDialog,
microDialog,
// 弹窗组件end***********************
},
//自定义指令 https://www.jb51.net/article/108047.htm
directives: {
flowDrag: {
// bind(el, binding, vnode, oldNode) {
// if (!binding) {
// return;
// }
// el.onmousedown = (e) => {
// if (e.button == 2) {
// // 右键不管
// return;
// }
// // 鼠标按下,计算当前原始距离可视区的高度
// let disX = e.clientX;
// let disY = e.clientY;
// el.style.cursor = "move";
// document.onmousemove = function (e) {
// // 移动时禁止默认事件
// e.preventDefault();
// const left = e.clientX - disX;
// disX = e.clientX;
// el.scrollLeft += -left;
// const top = e.clientY - disY;
// disY = e.clientY;
// el.scrollTop += -top;
// };
// document.onmouseup = function (e) {
// el.style.cursor = "auto";
// document.onmousemove = null;
// document.onmouseup = null;
// };
// };
// },
},
},
mounted() {
this.createGraph();
this.initToolbar();
this.initGraph();
this.$refs.container.style.background = 'url("./mxgraph/images/grid.gif")';
},
methods: {
task() {
let domArr = document.querySelectorAll('[key-id="123"]');
this.createGraph();
this.initToolbar();
},
handleNodeClick(e, node, i) {
this.$forceUpdate();
},
//生成画布
createGraph() {
this.graph = new mxGraph(this.$refs.container);
},
//初始化画布
initGraph() {
if (this.R.isNil(this.graph)) {
return;
}
this.graph.setConnectable(true); // 允许连线
      this.graph.setCellsEditable(false); // 不可修改
      this.graph.setTooltips(true);
      this.graph.setPanning(true);
      this.graph.setDropEnabled(true);
      this.graph.setAllowDanglingEdges(false);
      this.graph.setDisconnectOnMove(false);
this.graph.convertValueToString = (cell) => {
// 根据cell生成显示的标签
return this.R.prop("title", cell);
};
this.graph.addListener(mxEvent.DOUBLE_CLICK, (graph, evt) => {
console.log(evt);
// 监听双击事件
const cell = this.R.pathOr([], ["properties", "cell"], evt);
console.info(cell); // 在控制台输出双击的cell
});
this.graph.addListener(mxEvent.CLICK, (graph, evt) => {
console.log(evt);
// 监听单击事件
const cell = this.R.pathOr([], ["properties", "cell"], evt);
console.info(cell); // 在控制台输出单击的cell
});
},
addCell(toolItem, x, y) {
const { width, height } = toolItem;
const parent = this.graph.getDefaultParent();
this.graph.getModel().beginUpdate();
try {
let vertex = this.graph.insertVertex(
parent,
null,
null,
x,
y,
width,
height
);
vertex.title = toolItem["title"];
} finally {
this.graph.getModel().endUpdate();
}
},
//选择
initToolbar() {
let domArr = document.querySelectorAll('[key-id="123"]');
console.log(domArr);
domArr.forEach((dom, index) => {
// console.log(dom);
let toolItemObj = {
title: dom.innerHTML,
id:dom.id,
width: 60,
height: 60,
};
const { width, height } = toolItemObj;
const dropHandler = (graph, evt, cell, x, y) => {
this.addCell(toolItemObj, x, y);
};
const createDragPreview = () => {
const elt = document.createElement("div");
elt.style.border = "1px dotted black";
elt.style.width = `${width}px`;
elt.style.height = `${height}px`;
return elt;
};
mxUtils.makeDraggable(
dom,
this.graph,
dropHandler,
createDragPreview(),
0,
0,
false,
true
);
});
},
// //设置
settingFlow() {
// console.log("按钮给我测试其他的功能--1", );
},
// // 删除激活的元素
deleteFlow() {
this.graph.removeCells(this.graph.getSelectionCells(), false); //删除选中节点
// if (this.activeElement.type === "node") {
// this.deleteNode(this.activeElement.nodeId);
// } else if (this.activeElement.type === "line") {
// this.$confirm("确定删除所点击的线吗?", "提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning",
// })
// .then(() => {
// var conn = this.graph.getConnections({
// source: this.activeElement.sourceId,
// target: this.activeElement.targetId,
// })[0];
// this.graph.deleteConnection(conn);
// })
// .catch(() => {});
// }
},
// // 删除线
// deleteLine(from, to) {
// delete this.publicData[to];
// this.flowData.lineList = this.flowData.lineList.filter(function (line) {
// if (line.from == from && line.to == to) {
// return false;
// }
// return true;
// });
// },
// // 改变连线
// changeLine(oldFrom, oldTo) {
// this.deleteLine(oldFrom, oldTo);
// },
// // 改变节点的位置
// changeNodeSite(flowData) {
// for (var i = 0; i < this.flowData.nodeList.length; i++) {
// let node = this.flowData.nodeList[i];
// if (node.id === flowData.nodeId) {
// node.left = flowData.left;
// node.top = flowData.top;
// }
// }
// },
// /**
// * 删除节点
// * @param nodeId 被删除节点的ID
// */
// deleteNode(nodeId) {
// this.$confirm("确定要删除节点" + nodeId + "?", "提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning",
// closeOnClickModal: false,
// })
// .then(() => {
// /**
// * 这里需要进行业务判断,是否可以删除
// */
// this.flowData.nodeList = this.flowData.nodeList.filter(function (
// node
// ) {
// if (node.id === nodeId) {
// // 伪删除,将节点隐藏,否则会导致位置错位
// // node.show = false
// return false;
// }
// return true;
// });
// this.$nextTick(function () {
// this.graph.removeAllEndpoints(nodeId);
// });
// })
// .catch(() => {});
// return true;
// },
// console.log("点击节点操作", node);
// // this.$emit("dialogVisibleFourth",true);
// // this.$emit('updata:dialogVisibleFourth',true); //触发showbox方法,true为向父组件传递的数据
// this.stepName = node;
// this.connectionNode = this.publicData[node.id];
// console.log(this.connectionNode);
// this.isShowR = true;
// this.activeElement.type = "node";
// this.activeElement.nodeId = node.id;
// // this.$refs.nodeForm.nodeInit(this.flowData, nodeId)
// let pamer = new FormData(); // 创建form对象
// pamer.append("query", "");
// excelSheetType(pamer).then((res) => {
// this.engine = res;
// });
// availableCharsets(pamer).then((res) => {
// this.codingType = res;
// });
// let pamer2 = new FormData(); // 创建form对象
// pamer2.append("valueType", "all");
// valueFormat(pamer2).then((res) => {
// this.fieldFormat = res;
// });
// valueMeta().then((res) => {
// this.fieldType = res;
// });
// previousSteps().then((res) => {});
// inputOutputFields().then((res) => {});
// if (node.ids == "step1") {
// this.excelLnput = !this.excelLnput;
// return;
// } else if (node.ids == "step7") {
// this.TableInputDialog = !this.TableInputDialog;
// return;
// } else if (node.ids == "step6") {
// this.SystemInfoDialog = !this.SystemInfoDialog;
// return;
// } else if (node.ids == "step5") {
// this.ConstantDialog = !this.ConstantDialog;
// return;
// } else if (node.ids == "step4") {
// this.RandomValueDialog = !this.RandomValueDialog;
// return;
// } else if (node.ids == "step3") {
// this.RowGeneratorDialog = !this.RowGeneratorDialog;
// return;
// } else if (node.ids == "step2") {
// this.TextFileInputDialog = !this.TextFileInputDialog;
// return;
// }
// if (node.ids == "step16") {
// this.tableOutPutVisible = !this.tableOutPutVisible;
// return;
// }
// // 是否具有该线
// hasLine(from, to) {
// for (var i = 0; i < this.flowData.lineList.length; i++) {
// var line = this.flowData.lineList[i];
// if (line.from === from && line.to === to) {
// return true;
// }
// }
// return false;
// },
// // 是否含有相反的线
// hashOppositeLine(from, to) {
// return this.hasLine(to, from);
// },
// nodeRightMenu(nodeId, evt) {
// console.log(88);
// this.menu.show = true;
// this.menu.curNodeId = nodeId;
// this.menu.left = evt.x + "px";
// this.menu.top = evt.y + "px";
// },
// repaintEverything() {
// this.graph.repaint();
// },
// // 加载流程图-不能删
// dataReload(flowData) {
// this.easyFlowVisible = false;
// this.flowData.nodeList = [];
// this.flowData.lineList = [];
// this.$nextTick(() => {
// flowData = lodash.cloneDeep(flowData);
// this.easyFlowVisible = true;
// this.flowData = flowData;
// // console.log(flowData, '渲染数据');
// this.$nextTick(() => {
// this.graph = graph.getInstance();
// this.$nextTick(() => {
// this.jsPlumbInit();
// });
// });
// });
// },
// // 保存流程图
saveFlow() {
// this.graphXml = this.encode(this.graph);
// console.log(this.graphXml);
// const that = this;
// let flowObj = Object.assign({}, that.flowData);
// // localStorage.setItem("data_test", JSON.stringify(flowObj))
// console.log("保存流程图", flowObj);
// // 保存
// let pamers = new FormData(); // 创建form对象
// pamers.append("graphXml", jsonxml);
// save(pamers).then((res) => {
// console.log(res);
// if (res.success) {
// that.$message.success("保存流程成功!暂时请查先看控制台。");
// } else {
// that.$message.error(res.errMsg);
// }
// });
// },
// // 转xml
// createGraph() {
// this.graph = new mxGraph(this.$refs.efContainer);
// },
// encode(graph) {
// const encoder = new mxCodec();
// const result = encoder.encode(graph.getModel());
// return mxUtils.getPrettyXml(result);
// },
// decode(graphXml, graph) {
// window["mxGraphModel"] = mxGraphModel;
// window["mxGeometry"] = mxGeometry;
// const xmlDocument = mxUtils.parseXml(graphXml);
// const decoder = new mxCodec(xmlDocument);
// const node = xmlDocument.documentElement;
// decoder.decode(node, graph.getModel());
},
// //重绘流程图
clearFlow() {
// let that = this;
// console.log("重绘流程图--1", that.flowData);
// that
// .$confirm("确定要重新绘制流程图吗?", "提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning",
// closeOnClickModal: false,
// })
// .then(() => {
// if (that.flowData.nodeList.length !== 0) {
// that.flowData.nodeList.forEach(function (node, index) {
// that.graph.remove(node.id);
// });
// that.flowData.nodeList = [];
// that.flowData.linkList = [];
// that.$message.success("设置成功");
// console.log("重绘流程图--002", that.flowData);
// }
// })
// .catch(() => {
// console.log("取消重绘流程图--1");
// that.$message.error("取消重制");
// });
// },
// //放小
// zoomSub() {
// let that = this;
// if (that.zoom <= 0) {
// return;
// }
// // setInterval(() => {
// that.zoom = that.zoom - 0.1;
// that.$refs.efContainer.style.transform = `scale(${that.zoom})`;
// that.graph.setZoom(that.zoom);
// // }, 1000)
// },
// //放大
// zoomAdd() {
// let that = this;
// if (that.zoom >= 1) {
// return;
// }
// // setInterval(() => {
// that.zoom = that.zoom + 0.1;
// // that.$refs.efContainer.style.transform = `scale(${that.zoom})`
// console.log(that.zoom);
// that.$refs.efContainer.style.transform = `scale(${that.zoom})`;
// that.graph.setZoom(that.zoom);
// // }, 1000)
},
// // 下载数据
downloadData() {
// this.$confirm("确定要下载该流程数据吗?", "提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning",
// closeOnClickModal: false,
// })
// .then(() => {
// var datastr =
// "data:text/json;charset=utf-8," +
// encodeURIComponent(JSON.stringify(this.flowData, null, "\t"));
// console.log(this.flowData);
// var downloadAnchorNode = document.createElement("a");
// downloadAnchorNode.setAttribute("href", datastr);
// downloadAnchorNode.setAttribute("download", "flowData.json");
// downloadAnchorNode.click();
// downloadAnchorNode.remove();
// this.$message.success("正在下载中,请稍后...");
// })
// .catch(() => {});
},
}
};
</script>
<style lang="scss" type="text/scss" scoped>
.mxgraphClass,
#mxgraph {
height: 100vh;
width: 100%;
}
.moveR-enter-active,
.moveR-leave-active {
transition: all 0.3s linear;
transform: translateX(0);
}
.moveR-enter,
.moveR-leave {
transform: translateX(100%);
}
.moveR-leave-to {
transform: translateX(100%);
}
.moveL-enter-active,
.moveL-leave-active {
transition: all 0.3s linear;
transform: translateX(0%);
}
.moveL-enter,
.moveL-leave {
transform: translateX(-100%);
}
.moveL-leave-to {
transform: translateX(-100%);
}
</style>
......@@ -34,7 +34,7 @@
/*left: 225px;*/
margin-top: -9px;
width: 18px;
height: 36px;
height: 100%;
line-height: 36px;
background-color: #F1F3F4;
z-index: 999;
......
import { mxConstants } from 'mxgraph-js'
// const outputIcon = './icon/output.png'
// const inputIcon = './icon/input.png'
export const toolbarItems = [
{
// icon: outputIcon,
title: '输出',
width: 50,
height: 50,
style: {
fillColor: 'transparent',
strokeColor: '#000000',
strokeWidth: '1',
shape: mxConstants.SHAPE_LABEL,
align: mxConstants.ALIGN_CENTER,
verticalAlign: mxConstants.ALIGN_BOTTOM,
imageAlign: mxConstants.ALIGN_CENTER,
imageVerticalAlign: mxConstants.ALIGN_TOP,
// image: outputIcon
}
},
{
// icon: inputIcon,
title: '输入',
width: 50,
height: 50,
style: {
fillColor: 'transparent', // 填充色
strokeColor: '#000000', // 线条颜色
strokeWidth: '1', // 线条粗细
shape: mxConstants.SHAPE_LABEL, // 形状
align: mxConstants.ALIGN_CENTER, // 水平方向对其方式
verticalAlign: mxConstants.ALIGN_BOTTOM, // 垂直方向对其方式
imageAlign: mxConstants.ALIGN_CENTER, // 图形水平方向对其方式
imageVerticalAlign: mxConstants.ALIGN_TOP, // 图形方向对其方式
// image: inputIcon // 图形
}
}
]
......@@ -85,7 +85,7 @@
<el-tab-pane label="核心对象" name="second" v-if="tabShowFlag">
<div class="sel-content">
<!-- 核心对象 -->
<node-menu @addNode="addNode" ref="nodeMenu"></node-menu>
<node-menu @addNode="addNode" ref="nodeMenu" ></node-menu>
</div>
</el-tab-pane>
</el-tabs>
......@@ -94,7 +94,7 @@
<div class="mid">
<el-tabs v-if="tabShowFlag" style="margin-top:-5vh;margin-bottom:0;" v-model="picName" type="card" closable @tab-remove="removeTab">
<el-tab-pane label="数据库名称" >
<flow-designer ref="pic" :dialogVisibleFourth.sync="dialogVisibleFourth"></flow-designer>
<flow-designer ref="pic" :dialogVisibleFourth.sync="dialogVisibleFourth" ></flow-designer>
</el-tab-pane>
</el-tabs>
......@@ -373,8 +373,13 @@ export default {
// Establish,//新建转换,新建作业,新建目录弹窗
},
data() {
return {
flowData:{},
exportDialogVisible:false,//导出资源库弹窗
curDataBase:null,//当前选择的资源库
nodePath:'',//当前选中文件夹
......@@ -664,8 +669,6 @@ export default {
//文件夹列表
explorer(path){
var formData = new FormData();
......@@ -988,6 +991,7 @@ export default {
/**
* 拖拽结束后添加新的节点
* @param evt
......@@ -997,9 +1001,10 @@ export default {
//addNode(evt, nodeMenu, mousePosition) {
addNode(evt, draggingNode, mousePosition) {
console.log('天加evt==',evt);
// draggingNode.data.text = draggingNode.data.text
console.log('天加nodeMenu==',draggingNode.data);
var nodeMenu=draggingNode.data;
// var screenX = evt.originalEvent.clientX, screenY = evt.originalEvent.clientY
// let efContainer = this.$refs.efContainer
var screenX = evt.clientX, screenY = evt.clientY
......@@ -1025,8 +1030,9 @@ export default {
// var origName = nodeMenu.name
var origName = nodeMenu.path
var nodeName = origName
console.log('-------003',nodeMenu.type);
var node = {
var node = {
id: nodeId, //节点id--前端唯一的
name: nodeMenu.text, //节点名称
type: nodeMenu.type, //节点类型
......@@ -1035,6 +1041,10 @@ export default {
ico: nodeMenu.icon, //图标
ids: nodeMenu.id //工具固定类型id
}
console.log(this.flowData,'++++++++++++++++++');
console.log(node);
/**
......
<template>
<div class="box">
<div class="left">
<!-- <el-tabs v-model="activeName" type="card" @tab-click="handleClick"> -->
<el-tabs v-model="activeName" type="card" >
<el-tab-pane label="资源库" name="first">
<div class="sel-content">
<div class="sel-menu-bar">
<el-dropdown
size="small"
placement="bottom"
>
<span class="sel-btn">
新建
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="password" @click.native="createTrans()">
<template>
<i style="color:red;font-weight:bold;font-size:15px;" class="el-icon-refresh"></i>
新建转换
</template>
</el-dropdown-item>
<el-dropdown-item command="logout" @click.native="createJob()">
<template>
<i style="color:#F99C1C;font-weight:bold;font-size:15px;" class="el-icon-refresh-left"></i>
新建任务
</template>
</el-dropdown-item>
<el-dropdown-item style="text-align:right" @click.native="createFile()">新建目录</el-dropdown-item>
<el-dropdown-item class="text-center">打开</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown
size="small"
placement="bottom">
<span class="sel-btn">
资源库管理
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="showModalOne()">连接资源库</el-dropdown-item>
<el-dropdown-item >管理资源库</el-dropdown-item>
<el-dropdown-item >断开资源库</el-dropdown-item>
<el-dropdown-item @click.native="exportTreeDialog()">导出资源库</el-dropdown-item>
<el-dropdown-item>导入资源库</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown
size="small"
placement="bottom">
<span class="sel-btn">
帮组
<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item> 语言切换</el-dropdown-item>
<el-dropdown-item >关于</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<!-- 文件夹存放区域start-->
<el-tree
:data="fileTreeList"
:auto-expand-parent="true"
:check-strictly="true"
:default-expand-all="false"
node-key="id"
ref="tree"
:props="defaultProps"
:highlight-current="true"
@node-click="handleNodeClick"
>
<span class="custom-tree-node" slot-scope="{ node, data }">
<span style="display:flex;align:center;">
<div v-if="data.iconCls" :class="data.iconCls" style="display:inline-block;width:20px;height:20px;background-repeat:no-repeat;background-position:center;" width="" alt=""></div>
{{ node.label }}
</span>
</span>
</el-tree>
<!-- 文件夹存放区域end -->
</div>
</el-tab-pane>
<el-tab-pane label="核心对象" name="second" v-if="tabShowFlag">
<div class="sel-content">
<!-- 核心对象 -->
<nodeMenu2 @shooStatus="shooStatus"></nodeMenu2>
</div>
</el-tab-pane>
</el-tabs>
</div>
<div class="resize" title="收缩侧边栏">...</div>
<div class="mid">
<el-tabs v-if="tabShowFlag" style="margin-top:-5vh;margin-bottom:0;" v-model="picName" type="card" closable @tab-remove="removeTab">
<el-tab-pane label="数据库名称" >
<mxgraph-designer ref="pic" v-if="mxGraphShow"></mxgraph-designer>
</el-tab-pane>
</el-tabs>
</div>
<!-- 弹窗1start -->
<el-dialog
title="资源库连接"
:visible.sync="dialogVisibleOne"
width="500px"
:before-close="handleCloseOne">
<div>
<el-link @click.native="showModalTwo" class="btn-pointer" :underline="false">新增资源库</el-link>
<el-link class="btn-pointer" @click.native="editDataBase">修改资源库</el-link>
<el-link @click.native="deleteLinkRes" class="btn-pointer" :underline="false">删除资源库</el-link>
</div>
<div class="table-container">
<!-- <ul >
<li v-for="(item,index) in count" :key="index" class="infinite-list-item">{{ item }}</li>
</ul> -->
<ul >
<li class="btn" @mouseenter="listHoverIdx = idx" @mouseleave="listHoverIdx = -1" @click="chooselink(item,idx)" :class="{'hover': listHoverIdx == idx,'checked': listCheckedIdx == idx}" v-for="(item,idx) in linkList" :key="idx" >
{{ item.name }}
</li>
</ul>
</div>
<el-form style="margin-top:15px;" label-position="left" :rules="loginRules" :model="loginModel" status-icon ref="loginForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="用户名" prop="username">
<el-input v-model="loginModel.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="loginModel.password" ></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleCloseOne">取 消</el-button>
<el-button type="primary" @click.native="loginRepository('loginForm')">确 定</el-button>
</span>
<!-- </el-form> -->
</el-dialog>
<!-- 弹窗1end -->
<!--弹窗2start -->
<el-dialog
title="选择仓库类型"
:visible.sync="dialogVisibleTwo"
width="650px"
top="15%"
:before-close="handleCloseTwo">
<div class="table-container table-container-repos">
<ul>
<!-- <li :class="typeFlag==index?'type-checked':''" @click="chooseLinkType(index)" ref="acp" v-for="(item,index) in typesList" :key="index" >
{{ item.type }}:{{ item.name }}
</li> -->
<li class="btn" @mouseenter="typeHoverIdx = idx" @mouseleave="typeHoverIdx = -1" @click="typeCheckedIdx=idx" :class="{'hover': typeHoverIdx == idx,'checked': typeCheckedIdx == idx}" v-for="(item,idx) in typesList" :key="idx" >
{{ item.type }}:{{ item.name }}
</li>
</ul>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="FileModal = true">取 消</el-button>
<el-button type="primary" @click="showModalThree(typeCheckedIdx)">确 定</el-button>
</span>
</el-dialog>
<!-- 弹窗2end -->
<!-- 弹窗3start -->
<el-dialog
title="资源库信息"
:visible.sync="dialogVisibleThree"
width="600px"
top="19%"
:before-close="handleCloseThree">
<el-form style="margin-top:15px;" :model="repositoryInfoModel" status-icon ref="repositoryInfoForm" label-width="150px" class="demo-ruleForm">
<el-form-item label="选择数据库连接">
<!-- <el-select v-model="ruleForm.region" placeholder="请选择选择数据库连接">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select> -->
<el-select v-model="selectName" placeholder="请选择选择数据库连接" @focus="clickFunc" @change="selectNameFunc">
<el-option v-for="(item,index) in namesList" :key="index" :label="item.name" :value="item.name"></el-option>
</el-select>
<span style="margin-left:15px;">
<el-button @click="editDataBaseModal()">编辑</el-button>
<el-button @click="showModalFourth()">新建</el-button>
<el-button @click="deleteLink(selectName)">删除</el-button>
</span>
</el-form-item>
<el-form-item label="资源库标识" prop="name">
<el-input v-model="repositoryInfoModel.name"></el-input>
</el-form-item>
<el-form-item label="资源库名称" prop="description">
<el-input v-model="repositoryInfoModel.description"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="repositoryInfoConfirm('repositoryInfoForm')">确 定</el-button>
<el-button @click="createOrUpdate">创建或更新</el-button>
<el-button @click="dialogVisibleRemind = true">删 除</el-button>
<el-button @click="dialogVisibleThree = false">取 消</el-button>
<!-- <el-button type="primary" @click="dialogVisibleTwo = false">确 定</el-button> -->
</span>
</el-dialog>
<!-- 弹窗3end -->
<!-- 弹窗4start -->
<estab-dialog ref="establishDia" :dialogVisibleFourth.sync='dialogVisibleFourth' @getSonValue="getSonValue" :listNames="listNames"></estab-dialog>
<!-- 弹窗5start -->
<el-dialog
title="文件资源库设置"
:visible.sync="FileModal"
width="600px"
top="19%"
:before-close="closeFileModal">
<el-form style="margin-top:15px;" :model="ruleForm" status-icon ref="ruleForm" label-width="150px" class="demo-ruleForm">
<el-form-item label="根目录" prop="pass">
<div style="display:flex;">
<el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
<span style="margin-left:15px;">
<el-button @click="FileModalScan = true">浏览</el-button>
</span>
</div>
</el-form-item>
<el-form-item label="只读资源库?:" prop="checkPass">
<el-checkbox ></el-checkbox>
</el-form-item>
<el-form-item label="不显示隐藏文件:" prop="checkPass">
<el-checkbox ></el-checkbox>
</el-form-item>
<el-form-item label="资源库标志" prop="checkPass">
<el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="名称" prop="checkPass">
<el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeFileModal()">取 消</el-button>
<el-button type="primary" @click="FileModal = false">确 定</el-button>
</span>
</el-dialog>
<!-- 弹窗5end -->
<!-- 弹窗6start -->
<el-dialog
title="文件浏览器"
:visible.sync="FileModalScan"
width="450px"
top="19%"
:before-close="closeFileModalScan">
<div class="file-container">
<!-- 文件夹存放区域start-->
<!-- <el-tree
:data="jobTreeList"
:auto-expand-parent="true"
:check-strictly="true"
:default-expand-all="false"
node-key="id"
ref="tree"
:props="defaultProps"
:highlight-current="true"> -->
<!-- el-icon-folder -->
<!-- <span class="custom-tree-node" slot-scope="{node,data}">
<span>
<i :class="data.icon"></i>{{ node.label }}
</span>
</span> -->
<!-- <span class="custom-tree-node" slot-scope="{node,data}">
<span>
<i class="el-icon-folder"></i>{{ node.label }}
</span>
</span>
</el-tree> -->
<!-- 文件夹存放区域end -->
</div>
<span slot="footer" class="dialog-footer" style="display:flex;">
<el-select style="flex:1;margin-right:25px;" v-model="ruleForm.region" placeholder="请选择选择数据库连接">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
<el-button @click="FileModalScan = false">取 消</el-button>
<el-button type="primary" @click="FileModalScan = false">确 定</el-button>
</span>
</el-dialog>
<!-- 弹窗6end -->
<testDialogue ref="testDialogue" :dialogVisible.sync='testDialogueFlag'></testDialogue>
<dialogRemind ref="testDialogueRemind" @getValue="getValueFromChild" :dialogVisibleOne.sync='dialogVisibleRemind' :repositoryInfoModel="repositoryInfoModel" :selectName='selectName'></dialogRemind>
<scanDialog ref="scanDialog" :scanDialogVisible.sync="scanDialogVisible" :createModel="createModel"></scanDialog>
<feature ref="feature" :featureDialogVisible.sync="featureDialogVisible"></feature>
<establishDialog ref="establishDialog" :estabDialogVisible.sync="estabDialogVisible" :title="estabTitle" :nodePath="nodePath" :explorer="explorer"></establishDialog>
<export-tree ref="exDialog" :exportDialogVisible.sync="exportDialogVisible"></export-tree>
</div>
</template>
<script>
// import '@/utils/dialog.js';
// import {jsPlumb} from 'jsplumb'
import mxgraphDesigner from '../dashboard-kettle/components/designer/mxgraphDesigner'
import nodeMenu2 from '../dashboard-kettle/components/designer/modules/node_menu2'//左边tab
import { mxGraph, mxUtils, mxEvent, mxKeyHandler, mxRubberband,mxConstants,mxStencilRegistry,mxStencil,mxCodec,mxGraphModel,mxGeometry } from 'mxgraph-js'
// 弹窗组件start==================
import testDialogue from '../dialogs-components/test'
import scanDialog from '../dialogs-components/scan'
import feature from '../dialogs-components/feature'
import establishDialog from '../dialogs-components/establish'
// 弹窗组件end====================
// 删除
import {deleteLink} from '../dialogs-components/dialog'//左边tab
import dialogRemind from '../dialogs-components/dialog-remind'//删除提示弹窗
import {explorer,features,remove,checkInit} from "@/api/kettle/file";
import {
types,
getLinkList,
accessMethod,//获取连接方式列表
accessData,//获取连接类型
create,
listNames,//获取已经创建的数据库列表
database,//编辑数据库信息
check,//编辑数据库
loginRepository,//连接数据库
addRepository,//资源库信息
} from "@/api/kettle/link";
// import Establish from '../dialogs-components/establish.vue'
// import Scan from '../dialogs-components/scan.vue'
export default {
components: {
mxgraphDesigner,
nodeMenu2,
testDialogue,//测试连接弹窗
dialogRemind,////删除提示弹窗
scanDialog,
feature,//特征列表
establishDialog,
// Establish,//新建转换,新建作业,新建目录弹窗
},
props: ["dragItem"],
data() {
return {
graph:null,
flowData:[],
exportDialogVisible:false,//导出资源库弹窗
curDataBase:null,//当前选择的资源库
nodePath:'',//当前选中文件夹
curNodeIconCls:'',//当前选中节点
estabDialogVisible:false,//新建转换,新建作业,新建目录弹窗
estabTitle:'转换',//新建转换弹窗提示
featureDialogVisible:false,//特征列表弹窗
scanDialogVisible:false,//浏览弹窗
prefix:'http://192.168.0.2:9700/etlweb/',
inputValue:'',// 密码
// dropFunction,//删除数据库表
deleteLink,//删除资源库模块的方法
dialogVisibleRemind:false,//资源库信息删除提示弹窗
testDialogueFlag:false,//测试弹弹窗
tabShowFlag:true,//控制选项卡的显示和隐藏
picName:'',//画板的标签明名称
accessDataList:[],//连接类型
typesList:[],//资源库连接类型
typeHoverIdx: -1,
typeCheckedIdx: -2 ,
linkList:[],//获取历史连接的资源库列表
listHoverIdx: -1,//鼠标移动到历史创建数据库列表
listCheckedIdx: -2 ,//当前选择历史创建数据库列表
accessMethods:[],//连接方式列表
// linkHoverIdx: -1,//鼠标移动到连接类型
// linkCheckedIdx: -2 ,//当前选择连接类型列表
// methodHoverIdx:0,//鼠标移动到连接方式
// methodCheckedIdx: 0,//当前选择连接方式列表
initlinkTypeIdx:0,//初始化默认选择oracle
namesList:[],//已经创建的数据库列表
createModel:{
name:'',
type:'',
access:'',
hostname:'',
databaseName:'',
port:'',
username:'',
password:'',
stramingReasults:'',
supportBooleanDataType:'',
supportTimestampDataType:'',
preserveReservedCaseCheck:'',
extraOptions:[],
usingConnectionPool:'N',
initialPoolSize:'5',
maximumPoolSize:'10',
partitioned:'N',
partitionInfo:[]
},//创建数据库
selectName:'',//当前选中的下拉框的数据
dataBaseDetail:{},//数据库详情
addFlag:true,//新增还是编辑数据库判断
loginModel:{},//数据库连接
loginRules:{
username:[
{required:true,message:'请输入用户名',trigger:'blur'}
],
password:[
{required:true,message:'请输入密码',trigger:'blur'}
],
},//连接验证
repositoryInfoModel:{
name:'',
description:''
},//资源库信息
// methodCheckedText:'Native (JDBC)',//当前选择的连接方式test
rulesOne:{
name:[
{required:true,message:'请输入名称',trigger:'blur'}
],
hostname:[
{required:true,message:'请输入主机名称',trigger:'blur'}
],
databaseName:[
{required:true,message:'请输入数据库名称',trigger:'blur'}
],
port:[
{required:true,message:'请输入端口号',trigger:'blur'}
],
username:[
{required:true,message:'请输入用户名',trigger:'blur'}
],
password:[
{required:true,message:'请输入密码',trigger:'blur'}
],
// logLevel:[
// {required:true,message:'请选择日志级别',trigger:'change'}
// ],
},
checkModel:[],
visible:true,
dialogDrag:false,
dialog: {// dialog显示隐藏
dialogVisible: false,
dialogDrag: true, // 可拖拽
dialogChange: true, // 可拉伸
title: '详情'
},
activeName: 'first',//当前选择的标签
// jobTreeList:[
// {
// path: 'f0',
// id: '1',
// parent: '0',
// lasted: false,
// },
// {
// path: 'f01',
// id: '2',
// parent: '1',
// lasted: true,
// },
// {
// path: 'f02',
// id: '3',
// parent: '1',
// lasted: true,
// },
// {
// path: 'f021',
// id: '6',
// parent: '3',
// lasted: false,
// },
// {
// path: 'f021',
// id: '7',
// parent: '6',
// lasted: false,
// },
// {
// path: 'f40',
// id: '4',
// parent: '0',
// lasted: false,
// },
// {
// path: 'f41',
// id: '5',
// parent: '4',
// lasted: true,
// }
// ],
fileTreeList:[
{ iconCls:"imageFolder",
path:"/",
childen:[]},
// {
// "id":"f1e1928d205b49a8b4ceda97d51074c1",
// "text":"45",
// "iconCls":"imageFolder",
// "expanded":false,
// "leaf":false,
// "path":"/45",
// "type":null
// },
// {
// "id":"6da65d6179e34f2cb1376cd50303f0cd",
// "text":"testLi",
// "iconCls":"imageFolder",
// "expanded":false,
// "leaf":false,
// "path":"/testLi",
// "type":null,
// 'children':[{"id":"f821fad4deee413388611d81c9c75405","text":"test","iconCls":"trans","expanded":false,"leaf":true,"path":"/testLi/test","type":"transformation"},{"id":"8f67bffb2d29494da31eb36ccdb1a9d2","text":"转换 1","iconCls":"trans","expanded":false,"leaf":true,"path":"/testLi/转换 1","type":"transformation"}]
// },
// {
// "id":"bd5309795a7e4679aaca71f4ac7aa9b8",
// "text":"ee",
// "iconCls":"trans",
// "expanded":false,
// "leaf":true,
// "path":"/ee",
// "type":"transformation"
// },
// {
// "id":"ecb4080a382148e19f76ebb4feca6d7d",
// "text":"test",
// "iconCls":"trans",
// "expanded":false,
// "leaf":true,
// "path":"/test",
// "type":"transformation"
// },
// {
// "id":"3d093451b4564403b2060ba43a6a7008",
// "text":"tran303",
// "iconCls":"trans",
// "expanded":false,
// "leaf":true,
// "path":"/tran303",
// "type":"transformation"
// },
// {
// "id":"e5287b8341534d12bfafd3185f70f913",
// "text":"asdsa",
// "iconCls":"trans",
// "expanded":false,
// "leaf":true,
// "path":"/asdsa",
// "type":"transformation"
// },
// {
// "id":"7fc1e4aa582e48258595eb29972c05e5",
// "text":"sf",
// "iconCls":"trans",
// "expanded":false,
// "leaf":true,
// "path":"/sf",
// "type":"transformation"
// },
// {
// "id":"56e6cc94b8fe4804b9859b042243021a",
// "text":"作业1",
// "iconCls":"job",
// "expanded":false,
// "leaf":true,
// "path":"/作业1",
// "type":"job"
// }
],
childenTreeList:[],
// defaultProps: {
// label: 'path',
// children: 'children',
// },
defaultProps: {
label: "text",
children: "children",
},
dialogVisibleOne:false,//链接资源库弹窗
ruleForm: {
pass: '',
checkPass: '',
age: ''
},
dialogVisibleTwo:false,//新增资源库弹窗
count:[
'1111111111111111',
'2222222222222222'
],
dialogVisibleThree:false,//资源库信息弹窗
dialogVisibleFourth:false,
// linkType:[
// {value: 0, text: '一般'},
// {value: 1, text: '高级'},
// {value: 2, text: '选项'},
// {value: 3, text: '连接池'},
// {value: 4, text: '集群'}
// ],
// nowTypeIndex:0,//当前选中数据库类型
FileModal:false,//文件资源库弹窗
FileModalScan:false,//浏览弹窗
//画布
mxGraphShow:false
};
},
mounted () {
this.dragControllerDiv();//左右窗体调整宽度
// this.treeRevert(this.jobTreeList);
// this.accessData();//页面一加载就获取连接类型
this.explorer('');//获取文件夹列表
// console.log(this.$refs.establishDia.linkType,'55555555555555555')
// this.$nextTick(function () {
// console.log(this.$refs.establishDia,'========')
// // this.$refs.establishDia.accessData();//页面一加载就获取连接类型
// this.$refs.establishDia.accessData();//页面一加载就获取连接类型
// })
// this.dialogVisibleFourth=true
// this.$refs.scanDialog.dataBaseScan(formData);
},
methods: {
//接收子组件显示画布
shooStatus(e){
console.log(e,'接收子组件显示画布')
this.$nextTick(()=>{
this.mxGraphShow = e
})
},
//文件夹列表
explorer(path){
var formData = new FormData();
formData.append('loadElement', 3);
formData.append('path', path);
formData.append('node', 'xnode-14');
this.$forceUpdate();
explorer(formData).then(res=>{
if (res) {
if(path==''){
console.log('点击当前path==',path);
this.fileTreeList=res;
// this.fileTreeList=JSON.stringify(this.fileTreeList);
}else{
console.log('点击当前2222222222222path==',path);
this.childenTreeList=res;
console.log('子节点2path==',this.childenTreeList);
}
}else {
this.$message.error(res.errMsg)
}
})
},
// 左边文件夹和右边画布的宽度可以拖拽调整
dragControllerDiv: function () {
var resize = document.getElementsByClassName('resize');
var left = document.getElementsByClassName('left');
var mid = document.getElementsByClassName('mid');
var box = document.getElementsByClassName('box');
for (let i = 0; i < resize.length; i++) {
// 鼠标按下事件
resize[i].onmousedown = function (e) {
//颜色改变提醒
// resize[i].style.background = '#818181';
var startX = e.clientX;
resize[i].left = resize[i].offsetLeft;
// 鼠标拖动事件
document.onmousemove = function (e) {
var endX = e.clientX;
var moveLen = resize[i].left + (endX - startX); // (endx-startx)=移动的距离。resize[i].left+移动的距离=左边区域最后的宽度
var maxT = box[i].clientWidth - resize[i].offsetWidth; // 容器宽度 - 左边区域的宽度 = 右边区域的宽度
if (moveLen < 32) moveLen = 32; // 左边区域的最小宽度为32px
if (moveLen > maxT - 150) moveLen = maxT - 150; //右边区域最小宽度为150px
resize[i].style.left = moveLen; // 设置左侧区域的宽度
for (let j = 0; j < left.length; j++) {
left[j].style.width = moveLen + 'px';
mid[j].style.width = (box[i].clientWidth - moveLen - 10) + 'px';
}
};
// 鼠标松开事件
document.onmouseup = function (evt) {
//颜色恢复
// resize[i].style.background = '#d6d6d6';
document.onmousemove = null;
document.onmouseup = null;
resize[i].releaseCapture && resize[i].releaseCapture(); //当你不在需要继续获得鼠标消息就要应该调用ReleaseCapture()释放掉
};
resize[i].setCapture && resize[i].setCapture(); //该函数在属于当前线程的指定窗口里设置鼠标捕获
return false;
};
}
},
//文件夹数据转换
treeRevert(arrayList){
console.log('传入数据=============',arrayList);
let formatObj = arrayList.reduce((pre, cur) => {
return {...pre, [cur['id']]: cur}
}, {});
console.log(formatObj);
let formatArray = arrayList.reduce((arr, cur) => {
// let pid = cur.pid ? cur.pid : 0;
let pid = cur.parent ? cur.parent : 0;
let parent = formatObj[pid];
cur.disabled = !cur.lasted;
if (parent) {
parent.children ? parent.children.push(cur) : parent.children=[cur];
} else {
arr.push(cur)
}
return arr;
}, []);
console.log('树形数据=============',formatArray);
// this.jobTreeList=formatArray;
},
// 打开关闭弹窗
showModalOne(){
console.log('打卡资源库连接:');
this.getLinkList();//打开资源库连接弹窗同时获取历史连接记录
this.dialogVisibleOne=true;
},
handleCloseOne(){
this.dialogVisibleOne=false;
this.listHoverIdx=-1;//清空当前鼠标移动到的数据
this.listCheckedIdx=-2;//清空当前鼠标选中的数据
},
showModalTwo(){
this.dialogVisibleTwo=true;
this.types();
},
handleCloseTwo(){
this.dialogVisibleTwo=false;
},
showModalThree(typeCheckedIdx){
console.log('当前点击---',typeCheckedIdx);
if(typeCheckedIdx==0){
this.dialogVisibleThree=true;
}
if(typeCheckedIdx==1){
this.FileModal=true;
}
},
handleCloseThree(){
this.dialogVisibleThree=false;
},
// 新增数据库
showModalFourth(){
this.dialogVisibleFourth=true;
this.$refs.establishDia.database();
// this.accessData();//获取连接类型
this.$refs.establishDia.accessMethod();//获取连接方式
// console.log('this.methodHoverIdx==',this.methodHoverIdx);
// console.log('this.methodCheckedIdx==',this.methodCheckedIdx);
},
//获取新建弹窗返回来的值
getSonValue(res){
if(typeof(res)=='boolean'){
this.dialogVisibleFourth=res;
}
this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择oracle数据
this.methodHoverIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
this.methodCheckedIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// this.addFlag=true;//增减变量改为编辑变量
},
// handleCloseFourth(){
// this.dialogVisibleFourth=false;
// this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择oracle数据
// this.methodHoverIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// this.methodCheckedIdx=0;//关闭弹窗后初始化选择oracle数据对应第一条
// this.addFlag=true;//增减变量改为编辑变量
// },
closeFileModal(){
this.FileModal=false;
},
closeFileModalScan(){
this.FileModalScan=false;
},
// chooseType(index){
// this.nowTypeIndex=index;
// },
// 获取资源库连接类型
types(){
types().then(res=>{
if (res) {
console.log('获取类型成功!');
this.typesList=res;
}else {
this.$message.error(res.errMsg)
}
})
},
// 获取历史建立的连接资源库列表
getLinkList(){
getLinkList().then(res=>{
if (res) {
console.log('获取历史连接资源库列表:');
this.linkList=res;
}else {
this.$message.error(res.errMsg)
}
})
},
// 编辑数据
comfirmCreate(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
// JSON对象转成formData对象
var params=this.createModel;
// 由于高级选项连接池集群页面没有画完,保存默认参数
params.supportBooleanDataType=true;
params.supportTimestampDataType=true;
params.preserveReservedCaseCheck=true;
params.extraOptions = [];
params.usingConnectionPool='N';
params.initialPoolSize='5';
params.maximumPoolSize='10';
params.partitioned='N';
params.partitionInfo=[];
var formData = new FormData();
formData.append('databaseInfo', JSON.stringify(params));
console.log('表单提交参数==',params);
console.log('编辑表单提交参数==',formData);
check(formData).then(res=>{
console.log('提交数据:',res);
if (res.success) {
create(formData).then(res=>{
console.log('提交数据:',res);
if (res.success) {
this.$message.success('成功!');
this.dialogVisibleFourth=false;//关闭弹窗
this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择的数据
this.listNames();//刷新已经创建的数据库列表
}else {
this.$message.error(res.message)
}
})
}else {
this.$message.error(res.message)
}
})
}
});
},
//查询已经建立的所有数据库列表
listNames(){
listNames().then(res=>{
if (res) {
console.log('获取所有已经创建的数据库列表:',res);
this.namesList=res;
}else {
this.$message.error(res.errMsg)
}
})
},
//选择数据库编辑
selectNameFunc(e){
console.log('当前选中的数',e);
console.log('当前选中的数-===',this.selectName);
},
//点击选择获取已经创建的数据库列表
clickFunc(){
this.listNames();
},
editDataBaseModal(){
if(this.selectName){
this.dialogVisibleFourth=true;
// this.addFlag=false;//增减变量改为编辑变量
}
this.$refs.establishDia.database(this.selectName);
this.$refs.establishDia.accessMethod();//获取连接方式
// console.log('this.methodHoverIdx==',this.methodHoverIdx);
// console.log('this.methodCheckedIdx==',this.methodCheckedIdx);
},
// 资源库连接
loginRepository(formName){
console.log('进入登录==========');
this.$refs[formName].validate((valid) => {
if (valid) {
// JSON对象转成formData对象
var params=this.loginModel;
params.atStartupShown=false;//在启动时显示此对话框默认为 false
console.log('登录提交参数==',params);
var formData = new FormData();
formData.append('loginInfo', JSON.stringify(params));
console.log('提交转换数据:',formData);
loginRepository(formData).then(res=>{
console.log('返回数据:',res);
if (res.success) {
this.$message.success('连接成功!');
this.explorer('');
this.handleCloseOne();//关闭弹窗
// this.linkCheckedIdx=this.initlinkTypeIdx;//关闭弹窗后初始化选择的数据
}else {
this.$message.error(res.errMsg)
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
// 选择资源库
chooselink(item,index){
this.listCheckedIdx=index;
this.loginModel.reposityId=item.name;
console.log('当前选择的资源库=====',item);
this.curDataBase=item;
console.log('当前选择连接的数据库reposityId==',this.loginModel.reposityId);
},
removeTab(){},
//选出要传给后台的参数集合便于编辑方法 check
// chooseParams(objParams){
// var newObject={};
// for(var key in this.createModel){
// console.log(key,this.createModel[key])
// newObject[key]=objParams[key];
// }
// console.log('新的对象====',newObject);
// this.createModel=newObject;
// console.log('编辑赋值当前对象====',this.createModel);
// this.accessData();//获取连接类型
// },
// 资源库信息确定新建
repositoryInfoConfirm(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
// JSON对象转成formData对象
var params=this.repositoryInfoModel;
params.type='KettleDatabaseRepository';//写死
var extraOptions={database:this.selectName}
params.extraOptions=extraOptions;
var formData = new FormData();
formData.append('reposityInfo', JSON.stringify(params));
formData.append('add', true);
console.log('资源库信息确认提交参数==',params);
addRepository(formData).then(res=>{
console.log('提交数据:',res);
if (res.success) {
this.$message.success('成功!');
this.handleCloseThree();// 关闭弹窗1
this.handleCloseTwo();//关闭弹窗2
this.getLinkList();//刷新列表
this.listCheckedIdx=-2;//清空当前选择的资源库
this.curDataBase=null;
this.selectName='';
}else {
this.$message.error(res.errMsg)
}
})
} else {
console.log('error submit!!');
return false;
}
});
},
testDialogueOpen(){
// JSON对象转成formData对象
var params=this.createModel;
// 由于高级选项连接池集群页面没有画完,保存默认参数
params.supportBooleanDataType=true;
params.supportTimestampDataType=true;
params.preserveReservedCaseCheck=true;
params.extraOptions = [];
params.usingConnectionPool='N';
params.initialPoolSize='5';
params.maximumPoolSize='10';
params.partitioned='N';
params.partitionInfo=[];
var formData = new FormData();
formData.append('databaseInfo', JSON.stringify(params));
console.log('表单提交参数==',params);
this.$refs.testDialogue.test(formData);
this.testDialogueFlag = true;
},
getValueFromChild(input){
this.inputValue = input; //接收子组件的值,然后赋予自己的变量
// this.showChild = false; //关闭子组件dialog
},
featureDialogOpen(){
// JSON对象转成formData对象
var params=this.createModel;
// 由于高级选项连接池集群页面没有画完,保存默认参数
params.supportBooleanDataType=true;
params.supportTimestampDataType=true;
params.preserveReservedCaseCheck=true;
params.extraOptions = [];
params.usingConnectionPool='N';
params.initialPoolSize='5';
params.maximumPoolSize='10';
params.partitioned='N';
params.partitionInfo=[];
var formData = new FormData();
formData.append('databaseInfo', JSON.stringify(params));
console.log('表单提交参数==',params);
this.$refs.feature.feature(formData);
this.featureDialogVisible = true;
},
// 资源库浏览
scanDialogOpen(){
var params=this.createModel;
// 由于高级选项连接池集群页面没有画完,保存默认参数
params.supportBooleanDataType=true;
params.supportTimestampDataType=true;
params.preserveReservedCaseCheck=true;
params.extraOptions = [];
params.usingConnectionPool='N';
params.initialPoolSize='5';
params.maximumPoolSize='10';
params.partitioned='N';
params.partitionInfo=[];
var formData = new FormData();
formData.append('databaseInfo', JSON.stringify(params));
formData.append('includeElement', 15);
var node={
text: 'root',
iconCls: 'imageFolder',
}
formData.append('node', 'xnode-3620');
formData.append('nodeId', '');
formData.append('text', 'root');
// 当前编辑的项目的id
// formData.append('node', 'xnode-3620');
// formData.append('nodeId', 'root');
// formData.append('text', '');
// formData.append('nodeId', '');
// formData.append('text', 'root');
// formData.append('node', 'xnode-2984');
this.$refs.scanDialog.dataBaseScan(formData);
this.scanDialogVisible = true;
},
// 删除资源库
deleteLinkRes(){
var formData = new FormData();
formData.append('repositoryName', this.loginModel.reposityId);
console.log('参数==',formData);
remove(formData).then(res=>{
if (res) {
this.$message.success('成功!');
this.getLinkList();//打开资源库连接弹窗同时获取历史连接记录
}else {
this.$message.error(res.errMsg)
}
})
},
//新建转换
createTrans(){
if(this.curNodeIconCls =='imageFolder'){
this.estabDialogVisible=true;
this.estabTitle='转换';
}else{
this.$message.error('请选择资源库中的一个目录');
}
},
// 新建任务
createJob(){
if(this.curNodeIconCls =='imageFolder'){
this.estabDialogVisible=true;
this.estabTitle='任务';
}else{
this.$message.error('请选择资源库中的一个目录');
}
},
// 新建目录
createFile(){
if(this.curNodeIconCls =='imageFolder'){
this.estabDialogVisible=true;
this.estabTitle='目录';
}else{
this.$message.error('请选择资源库中的一个目录');
}
},
handleNodeClick(data,node){
console.log('点击当前节点===',node);
this.nodePath=data.path;//当前选择数
this.curNodeIconCls=data.iconCls;//当前选中节点
console.log('当前节点的文件夹路径:',this.nodePath);
// console.log(data,'当前节点的父节点:',node.parent.data);
},
//修改资源库
editDataBase(){
if(this.curDataBase){
this.repositoryInfoModel.name=this.curDataBase.name;
this.repositoryInfoModel.description=this.curDataBase.description;
this.selectName=this.curDataBase.extraOptions.database;
this.dialogVisibleThree=true;
}else{
this.$message.error('请选择一个资源库');
}
},
//创建或者更新
createOrUpdate(){
var formData = new FormData();
formData.append('connection', this.selectName);
console.log('参数==',formData);
checkInit(formData).then(res=>{
if (res) {
this.$message.success('成功!');
// this.getLinkList();//打开资源库连接弹窗同时获取历史连接记录
}else {
this.$message.error(res.errMsg)
}
})
},
// 导出资源库弹窗
exportTreeDialog(){
console.log('导出资源库====');
this.exportDialogVisible=true;
}
}
};
</script>
<style>
@import url(./kettle.css);
</style>
\ No newline at end of file
<template>
<div class="customToolbarContainer">
<div class="toolbarContainer">
<ul>
<li v-for="item in toolbarItems" :key="item['title']" ref="toolItem">
<img :src="item['icon']" :alt="item['title']">
<span>{{item['title']}}</span>
</li>
</ul>
</div>
<div class="graphContainer" ref="container"></div>
</div>
</template>
<script>
// import { steps } from "@/api/kettle/link";
import {toolbarItems} from './toolbar'
// import {
// mxEvent as mxEvent,
// mxGraph as mxGraph, mxUtils as mxUtils
// } from 'mxgraph/javascript/mxClient'
import { mxGraph, mxUtils, mxEvent, mxKeyHandler, mxRubberband,mxConstants,mxStencilRegistry,mxStencil,mxCodec,mxGraphModel,mxGeometry } from 'mxgraph-js'
export default {
name: 'index2',
computed: {
toolbarItems: () => toolbarItems
},
data() {
return {
data() {
return {
graph: null
}
}
}
},
methods: {
// stepsFun() {
// let pamer = new FormData(); // 创建form对象
// pamer.append("node", "xnode-12");
// this.$forceUpdate();
// steps(pamer).then((res) => {
// this.toolbarItems = res
// console.log(this.menuList,res[0]);
// });
// },
createGraph() {
this.graph = new mxGraph(this.$refs.container)
},
initGraph() {
if (this.R.isNil(this.graph)) {
return
}
this.graph.setConnectable(true) // 允许连线
this.graph.setCellsEditable(false) // 不可修改
this.graph.convertValueToString = (cell) => { // 从value中获取显示的内容
return this.R.prop('title', cell)
}
this.graph.addListener(mxEvent.DOUBLE_CLICK, (graph, evt) => { // 监听双击事件
const cell = this.R.pathOr([], ['properties', 'cell'], evt)
console.info(cell) // 在控制台输出双击的cell
})
},
addCell(toolItem, x, y) {
console.log(JSON.stringify(toolItem))
const {width, height} = toolItem
const styleObj = toolItem['style']
const style = Object.keys(styleObj).map((attr) => `${attr}=${styleObj[attr]}`).join(';')
const parent = this.graph.getDefaultParent()
this.graph.getModel().beginUpdate()
try {
let vertex = this.graph.insertVertex(parent, null, null, x, y, width, height, style)
console.log(x,y);
vertex.title = toolItem['title']
} finally {
this.graph.getModel().endUpdate()
}
},
initToolbar() {
console.log(this.$refs.toolItem,"********************");
const domArray = this.$refs.toolItem
console.log(domArray[0])
if (!(domArray instanceof Array) || domArray.length <= 0) {
return
}
domArray.forEach((dom, domIndex) => {
const toolItem = this.toolbarItems[domIndex]
console.log(this.toolbarItems);
const {width, height} = toolItem
const dropHandler = (graph, evt, cell, x, y) => {
this.addCell(toolItem, x, y)
}
const createDragPreview = () => {
const elt = document.createElement('div')
elt.style.border = '1px dotted black'
elt.style.width = `${width}px`
elt.style.height = `${height}px`
return elt
}
mxUtils.makeDraggable(dom, this.graph, dropHandler, createDragPreview(), 0, 0, false, true)
})
}
},
mounted() {
this.createGraph()
this.initGraph()
this.initToolbar()
this.$refs.container.style.background = 'url("./mxgraph/images/grid.gif")'
}
}
</script>
<style lang="scss">
.customToolbarContainer {
// width: 100%;
// height: 100%;
display: flex;
position: relative;
.toolbarContainer {
flex: 1;
font-size: 20px;
background: #efefef;
text-align: center;
padding-top: 20px;
ul {
padding: 0;
margin: 0;
li {
list-style: none;
margin-bottom: 10px;
cursor: pointer;
img {
width: 15px;
height: 15px;
}
span {
margin-left: 15px;
}
}
}
}
.graphContainer {
position: relative;
height: 800px;
flex: 7;
}
}
</style>
import {
mxConstants
} from 'mxgraph-js'
const outputIcon = './icon/output.png'
const inputIcon = './icon/input.png'
export const toolbarItems = [
{
// icon: outputIcon,
title: '输出',
width: 50,
height: 50,
style: {
fillColor: 'transparent',
strokeColor: '#000000',
strokeWidth: '1',
shape: mxConstants.SHAPE_LABEL,
align: mxConstants.ALIGN_CENTER,
verticalAlign: mxConstants.ALIGN_BOTTOM,
imageAlign: mxConstants.ALIGN_CENTER,
imageVerticalAlign: mxConstants.ALIGN_TOP,
// image: outputIcon
}
},
{
// icon: inputIcon,
title: '输入',
width: 50,
height: 50,
style: {
fillColor: 'transparent', // 填充色
strokeColor: '#000000', // 线条颜色
strokeWidth: '1', // 线条粗细
shape: mxConstants.SHAPE_LABEL, // 形状
align: mxConstants.ALIGN_CENTER, // 水平方向对其方式
verticalAlign: mxConstants.ALIGN_BOTTOM, // 垂直方向对其方式
imageAlign: mxConstants.ALIGN_CENTER, // 图形水平方向对其方式
imageVerticalAlign: mxConstants.ALIGN_TOP, // 图形方向对其方式
// image: inputIcon // 图形
}
}
]
......@@ -18,6 +18,18 @@ module.exports = {
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
chainWebpack: (config) => {
config.module
.rule('')
.test(/mxClient\.js$/)
.use('exports-loader')
.loader('exports-loader?mxClient,mxGraphModel,mxActor,mxShape,mxEventObject,mxGraph,mxPrintPreview,mxEventSource,mxRectangle,mxVertexHandler,mxMouseEvent,mxGraphView,mxImage,mxGeometry,mxRubberband,mxKeyHandler,mxDragSource,mxGraphModel,mxEvent,mxUtils,mxWindow,mxEvent,mxCodec,mxCell,mxConstants,mxPoint,mxGraphHandler,mxCylinder,mxCellRenderer,mxEvent,mxUndoManager')
.end();
config.resolve.alias
.set('@', resolve('src'))
.set('@assets', resolve('src/assets'));
// 按这种格式.set('', resolve('')) 自己添加
},
devServer: {
port: port,
open: true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment