├── .gitattributes ├── .gitignore ├── images ├── 1.png ├── 2.png ├── 3.png ├── 4.png └── 5.png ├── dist ├── favicon.ico ├── img │ ├── step-end.3898eb57.png │ ├── step-tag.5fb141f0.png │ ├── step-stop.cf2fb78e.png │ └── step-start2.206ef489.png ├── fonts │ ├── element-icons.732389de.ttf │ └── element-icons.535877f5.woff ├── index.html └── js │ └── app.ed3bd818.js ├── babel.config.js ├── public ├── favicon.ico └── index.html ├── src ├── assets │ ├── logo.png │ ├── step-if.png │ ├── icon-clear.png │ ├── icon-duiqi.png │ ├── icon-json.png │ ├── icon-redo.png │ ├── icon-undo.png │ ├── step-end.png │ ├── step-merge.png │ ├── step-start.png │ ├── step-stop.png │ ├── step-tag.png │ ├── step-wait.png │ ├── step-expand.png │ ├── step-start2.png │ ├── icon-undo-disable.png │ ├── icon-wangge-close.png │ ├── icon-wangge-open.png │ ├── icon-auto-sort-close.png │ └── icon-auto-sort-open.png ├── main.js ├── App.vue ├── utils │ ├── index.js │ └── dom.js ├── components │ ├── nodeNodeForm.vue │ ├── startNodeForm.vue │ ├── listForm.vue │ ├── ifNodeForm.vue │ ├── expandNodeForm.vue │ └── Draggable.js ├── constant │ └── index.js ├── styles │ ├── _step-imgs.scss │ ├── workflow.scss │ └── _jsplumbtoolkit-defaults.scss └── mock │ └── mock.js ├── vue.config.js ├── README.md ├── package.json └── LICENSE /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | node_modules 3 | .idea 4 | -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/images/1.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/images/5.png -------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/favicon.ico -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/cli-plugin-babel/preset' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/logo.png -------------------------------------------------------------------------------- /src/assets/step-if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-if.png -------------------------------------------------------------------------------- /src/assets/icon-clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-clear.png -------------------------------------------------------------------------------- /src/assets/icon-duiqi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-duiqi.png -------------------------------------------------------------------------------- /src/assets/icon-json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-json.png -------------------------------------------------------------------------------- /src/assets/icon-redo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-redo.png -------------------------------------------------------------------------------- /src/assets/icon-undo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-undo.png -------------------------------------------------------------------------------- /src/assets/step-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-end.png -------------------------------------------------------------------------------- /src/assets/step-merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-merge.png -------------------------------------------------------------------------------- /src/assets/step-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-start.png -------------------------------------------------------------------------------- /src/assets/step-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-stop.png -------------------------------------------------------------------------------- /src/assets/step-tag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-tag.png -------------------------------------------------------------------------------- /src/assets/step-wait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-wait.png -------------------------------------------------------------------------------- /src/assets/step-expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-expand.png -------------------------------------------------------------------------------- /src/assets/step-start2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/step-start2.png -------------------------------------------------------------------------------- /dist/img/step-end.3898eb57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/img/step-end.3898eb57.png -------------------------------------------------------------------------------- /dist/img/step-tag.5fb141f0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/img/step-tag.5fb141f0.png -------------------------------------------------------------------------------- /dist/img/step-stop.cf2fb78e.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/img/step-stop.cf2fb78e.png -------------------------------------------------------------------------------- /src/assets/icon-undo-disable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-undo-disable.png -------------------------------------------------------------------------------- /src/assets/icon-wangge-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-wangge-close.png -------------------------------------------------------------------------------- /src/assets/icon-wangge-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-wangge-open.png -------------------------------------------------------------------------------- /dist/img/step-start2.206ef489.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/img/step-start2.206ef489.png -------------------------------------------------------------------------------- /src/assets/icon-auto-sort-close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-auto-sort-close.png -------------------------------------------------------------------------------- /src/assets/icon-auto-sort-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/src/assets/icon-auto-sort-open.png -------------------------------------------------------------------------------- /dist/fonts/element-icons.732389de.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/fonts/element-icons.732389de.ttf -------------------------------------------------------------------------------- /dist/fonts/element-icons.535877f5.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bosscheng/vue-draggable-workflow/HEAD/dist/fonts/element-icons.535877f5.woff -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Date:2020/4/16 3 | * Desc: 4 | */ 5 | const pkg = require('./package'); 6 | 7 | module.exports = { 8 | publicPath: process.env.NODE_ENV === 'production' 9 | ? `/${pkg.name}/` 10 | : '/' 11 | }; 12 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import ElementUI from 'element-ui'; 4 | import 'element-ui/lib/theme-chalk/index.css'; 5 | 6 | Vue.config.productionTip = false; 7 | 8 | Vue.use(ElementUI); 9 | 10 | new Vue({ 11 | render: h => h(App), 12 | }).$mount('#app'); 13 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue draggable workflow 2 | 3 | 基于 sortablejs 和 jsplumb.js 实现的 workflow。 4 | 5 | - 支持页面布局缩放 6 | - 支持画布拖拽 7 | - 支持节点 8 | - 支持if else 9 | - 支持多分支 10 | - 支持节点拖拽 11 | 12 | 13 | ## 功能 14 | - [x] 撤销 15 | - [x] 初始化数据 16 | - [x] 网格线 hide/show 17 | - [x] 边界保护 18 | - [x] 自动排序 19 | - [x] 手动排列 20 | - [x] 清空数据 21 | - [x] 获取JSON数据 22 | - [x] 支持画布拖拽 23 | 24 | 25 | # 解惑文章 26 | 27 | [基于vue和jsplumb的工作流编辑器开发](https://juejin.cn/post/6844904144264773639) 28 | 29 | [基于vue和jsplumb的工作流编辑器开发(二)](https://juejin.cn/post/6948313872503832612) 30 | 31 | 32 | # 执行 33 | 34 | 35 | > 依赖 yarn 或者 npm 36 | 37 | ## step1 安装依赖 38 | 39 | ``` 40 | yarn install 41 | ``` 42 | ## step2 开发调试 43 | 44 | ``` 45 | yarn run dev 46 | ``` 47 | 48 | ## step3 编译部署 49 | 50 | ``` 51 | yarn run build 52 | ``` 53 | 54 | 55 | # 部分截图 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | vue-draggable-workflow
-------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Date:2020/4/15 3 | * Desc: 4 | */ 5 | 6 | // 7 | export function uuid() { 8 | // return (+new Date() * 1e6 + Math.floor(Math.random() * 1e6)).toString(36); 9 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { 10 | var r = Math.random() * 16 | 0; 11 | var v = c == 'x' ? r : (r & 0x3 | 0x8) 12 | return v.toString(16) 13 | }) 14 | } 15 | 16 | // 17 | export function clone(obj) { 18 | let result = ''; 19 | // 20 | if (typeof obj === 'object') { 21 | result = JSON.stringify(obj); 22 | result = JSON.parse(result); 23 | } else { 24 | result = obj; 25 | } 26 | 27 | return result; 28 | } 29 | 30 | export function getMousePosition(event){ 31 | let posX = 0; 32 | let posY = 0; 33 | const e = event || window.event; //标准化事件对象 34 | if (e.pageX || e.pageY) { //获取鼠标指针的当前坐标值 35 | posX = e.pageX; 36 | posY = e.pageY; 37 | } else if (e.clientX || e.clientY) { 38 | posX = event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft; 39 | posY = event.clientY + document.documentElement.scrollTop + document.body.scrollTop; 40 | } 41 | return { 42 | posX, 43 | posY 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-draggable-workflow", 3 | "version": "0.1.0", 4 | "private": true, 5 | "description": "vue draggable workflow by jsplumb", 6 | "bin": { 7 | "deploy": "build/deploy.sh" 8 | }, 9 | "scripts": { 10 | "serve": "vue-cli-service --open serve", 11 | "dev": "npm run serve", 12 | "build": "vue-cli-service build", 13 | "lint": "vue-cli-service lint" 14 | }, 15 | "dependencies": { 16 | "core-js": "^3.6.4", 17 | "vue": "^2.6.11", 18 | "element-ui": "^2.13.1", 19 | "sortablejs": "1.8.3", 20 | "jsplumb": "^2.13.1", 21 | "lodash": "^4.17.19", 22 | "json-formatter-js": "2.3.4" 23 | }, 24 | "devDependencies": { 25 | "@vue/cli-plugin-babel": "^4.3.0", 26 | "@vue/cli-service": "^4.3.0", 27 | "node-sass": "^4.9.0", 28 | "sass-loader": "^8.0.2", 29 | "vue-template-compiler": "^2.6.11" 30 | }, 31 | "eslintConfig": { 32 | "root": true, 33 | "env": { 34 | "node": true 35 | }, 36 | "extends": [ 37 | "plugin:vue/essential", 38 | "eslint:recommended" 39 | ], 40 | "parserOptions": { 41 | "parser": "babel-eslint" 42 | }, 43 | "rules": {} 44 | }, 45 | "browserslist": [ 46 | "> 1%", 47 | "last 2 versions", 48 | "not dead" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /src/components/nodeNodeForm.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 64 | 65 | 68 | -------------------------------------------------------------------------------- /src/components/startNodeForm.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 64 | 65 | 68 | -------------------------------------------------------------------------------- /src/components/listForm.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 49 | 50 | 69 | -------------------------------------------------------------------------------- /src/components/ifNodeForm.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 75 | 76 | 77 | 80 | -------------------------------------------------------------------------------- /src/constant/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * date: 2020-01-17 3 | * desc: 4 | */ 5 | 6 | 7 | export const FLOW_TYPE = { 8 | action: 'action', 9 | condition: 'condition', 10 | flow: 'flow', 11 | temp: 'temp', 12 | }; 13 | 14 | export const FLOW_ITEM_TYPE = { 15 | startNode: 'startNode', 16 | endNode: 'endNode', 17 | waitNode: 'waitNode', 18 | tempNode: 'tempNode', 19 | nodeNode: 'nodeNode', 20 | ifNode: 'ifNode', 21 | expandNode: 'expandNode', 22 | list: 'list' 23 | }; 24 | 25 | 26 | export const FLOW_LIST = { 27 | action: [ 28 | { 29 | id: 'nodeNode', 30 | type: 'nodeNode', 31 | className: 'step-tag', 32 | name: '节点', 33 | groupType: 'action', 34 | } 35 | ], 36 | // 条件控制 37 | condition: [ 38 | { 39 | id: 'conditionNode', 40 | type: 'ifNode', 41 | className: 'step-if', 42 | name: '条件判断', 43 | groupType: 'condition', 44 | }, 45 | { 46 | id: 'switchNode', 47 | type: 'expandNode', 48 | className: 'step-expand', 49 | name: '条件分组', 50 | groupType: 'condition', 51 | } 52 | ], 53 | // 流程控制 54 | flow: [ 55 | { 56 | id: 'startNode', 57 | type: 'startNode', 58 | className: 'step-start', 59 | name: 'start', 60 | groupType: 'flow', 61 | hidden: true 62 | }, 63 | { 64 | id: 'stopNode', 65 | type: 'endNode', 66 | className: 'step-end', 67 | name: '结束', 68 | groupType: 'flow', 69 | } 70 | ], 71 | // temp 72 | temp: [ 73 | { 74 | id: 'tempNode', 75 | type: 'tempNode', 76 | className: 'step-temp', 77 | name: 'temp', 78 | groupType: 'temp', 79 | }, 80 | ] 81 | }; 82 | 83 | export const FLOW_ALL_LIST = [ 84 | { 85 | type: FLOW_TYPE.action, 86 | ref: 'actionFlow', 87 | children: FLOW_LIST.action 88 | }, 89 | { 90 | type: FLOW_TYPE.flow, 91 | ref: 'flowFlow', 92 | children: FLOW_LIST.flow 93 | }, 94 | { 95 | type: FLOW_TYPE.condition, 96 | ref: 'conditionFlow', 97 | children: FLOW_LIST.condition 98 | }, 99 | ]; 100 | -------------------------------------------------------------------------------- /src/styles/_step-imgs.scss: -------------------------------------------------------------------------------- 1 | // step-icon 2 | 3 | @mixin stem-img($width:24px) { 4 | display: inline-block; 5 | background-size: 100% 100%; 6 | width: $width; 7 | height: $width; 8 | } 9 | 10 | 11 | .step-tag { 12 | background: url("../assets/step-tag.png") no-repeat center; 13 | @include stem-img; 14 | } 15 | 16 | .step-start { 17 | background: url("../assets/step-start.png") no-repeat center; 18 | @include stem-img; 19 | } 20 | 21 | .step-end { 22 | background: url("../assets/step-end.png") no-repeat center; 23 | @include stem-img; 24 | } 25 | 26 | 27 | .step-if { 28 | background: url("../assets/step-if.png") no-repeat center; 29 | @include stem-img(30px); 30 | } 31 | 32 | .step-expand { 33 | background: url("../assets/step-expand.png") no-repeat center; 34 | @include stem-img(30px); 35 | } 36 | 37 | .step-merge { 38 | background: url("../assets/step-merge.png") no-repeat center; 39 | @include stem-img(30px); 40 | } 41 | 42 | 43 | .step-start2 { 44 | background: url("../assets/step-start2.png") no-repeat center; 45 | @include stem-img(25px); 46 | } 47 | 48 | .step-stop { 49 | background: url("../assets/step-stop.png") no-repeat center; 50 | @include stem-img(25px); 51 | } 52 | 53 | .icon-duiqi { 54 | background: url("../assets/icon-duiqi.png") no-repeat center; 55 | @include stem-img(25px); 56 | } 57 | 58 | .icon-clear { 59 | background: url("../assets/icon-clear.png") no-repeat center; 60 | @include stem-img(25px); 61 | } 62 | 63 | .icon-redo { 64 | background: url("../assets/icon-redo.png") no-repeat center; 65 | @include stem-img(25px); 66 | } 67 | 68 | 69 | .icon-json { 70 | background: url("../assets/icon-json.png") no-repeat center; 71 | @include stem-img(25px); 72 | } 73 | 74 | .icon-wangge-open{ 75 | background: url("../assets/icon-wangge-open.png") no-repeat center; 76 | @include stem-img(25px); 77 | } 78 | 79 | .icon-wangge-close{ 80 | background: url("../assets/icon-wangge-close.png") no-repeat center; 81 | @include stem-img(25px); 82 | } 83 | 84 | .icon-undo{ 85 | background: url("../assets/icon-undo.png") no-repeat center; 86 | @include stem-img(25px); 87 | } 88 | 89 | .icon-undo-disabled{ 90 | background: url("../assets/icon-undo-disable.png") no-repeat center; 91 | @include stem-img(25px); 92 | } 93 | 94 | .icon-auto-sort-open{ 95 | background: url("../assets/icon-auto-sort-open.png") no-repeat center; 96 | @include stem-img(25px); 97 | } 98 | 99 | .icon-auto-sort-close{ 100 | background: url("../assets/icon-auto-sort-close.png") no-repeat center; 101 | @include stem-img(25px); 102 | } -------------------------------------------------------------------------------- /src/utils/dom.js: -------------------------------------------------------------------------------- 1 | /* 2 | * date: 2019-08-21 3 | * desc: 4 | */ 5 | 6 | var trim = function (str) { 7 | // 8 | var reExtraSpace = /^\s*(.*?)\s+$/; 9 | 10 | return str.replace(reExtraSpace, '$1'); 11 | }; 12 | 13 | /** 14 | * 15 | * @param element DOM 元素。 16 | * @param classNames String 用字符串分割开来。 17 | */ 18 | export function addClass(element, classNames) { 19 | 20 | if (!element || !classNames) { 21 | return; 22 | } 23 | 24 | var curClassNames = element.className; 25 | // 用空格分来 26 | var classes = (classNames || '').split(' '); 27 | 28 | for (var i = 0, len = classes.length; i < len; i++) { 29 | var classItem = classes[i]; 30 | if (!classItem) { 31 | continue; 32 | } 33 | 34 | if (element.classList) { 35 | element.classList.add(classItem); 36 | } else if (!hasClass(element, classItem)) { 37 | curClassNames += ' ' + classItem; 38 | } 39 | } 40 | 41 | if (!element.classList) { 42 | element.className = curClassNames; 43 | } 44 | } 45 | 46 | /** 47 | * 48 | * @param element 49 | * @param classNames 50 | */ 51 | export function removeClass(element, classNames) { 52 | if (!element || !classNames) { 53 | return; 54 | } 55 | 56 | var curClassNames = ' ' + element.className + ' '; 57 | // 用空格分来 58 | var classes = (classNames || '').split(' '); 59 | 60 | for (var i = 0, len = classes.length; i < len; i++) { 61 | var classItem = classes[i]; 62 | if (!classItem) { 63 | continue; 64 | } 65 | 66 | if (element.classList) { 67 | element.classList.remove(classItem); 68 | } else if (!hasClass(element, classItem)) { 69 | curClassNames = curClassNames.replace(' ' + classItem + ' ', ' '); 70 | } 71 | } 72 | 73 | if (!element.classList) { 74 | element.className = trim(curClassNames); 75 | } 76 | } 77 | 78 | 79 | /** 80 | * 81 | * @param element Element 元素 82 | * @param className 83 | * @returns {boolean} 84 | */ 85 | export function hasClass(element, className) { 86 | if (!element || !className) { 87 | return false; 88 | } 89 | 90 | // 91 | if (className.indexOf(' ') !== -1) { 92 | throw new Error('classNames should not contain space'); 93 | } 94 | 95 | 96 | if (element.classList) { 97 | return element.classList.contains(className); 98 | } else { 99 | return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1; 100 | } 101 | } 102 | 103 | 104 | // 依赖 getStyle 105 | function _getStyle(dom, name) { 106 | try { 107 | if (window.getComputedStyle) { 108 | return window.getComputedStyle(dom, null)[name]; 109 | } 110 | // 111 | return dom.currentStyle[name]; 112 | } catch (e) { 113 | return null; 114 | } 115 | } 116 | 117 | // 118 | export function getWidth(dom) { 119 | let width = _getStyle(dom, 'width'); 120 | if (width === 'auto') { 121 | width = dom.offsetWidth; 122 | } 123 | return parseFloat(width); 124 | } 125 | 126 | // 127 | export function getHeight(dom) { 128 | let height = _getStyle(dom, 'height'); 129 | if (height === 'auto') { 130 | height = dom.offsetHeight; 131 | } 132 | return parseFloat(height); 133 | } 134 | -------------------------------------------------------------------------------- /src/components/expandNodeForm.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 110 | 111 | 145 | -------------------------------------------------------------------------------- /src/styles/workflow.scss: -------------------------------------------------------------------------------- 1 | // jsPlumb样式优化 2 | @import "jsplumbtoolkit-defaults"; 3 | @import "step-imgs"; 4 | 5 | .flow-layout { 6 | display: flex; 7 | flex-direction: column; 8 | height: 100vh; 9 | } 10 | 11 | .flow-editor { 12 | position: relative; 13 | display: flex; 14 | flex-direction: row; 15 | flex: 1; 16 | overflow: hidden; 17 | height: 100%; 18 | } 19 | 20 | .flow-editor.draft { 21 | background: #fff; 22 | } 23 | 24 | 25 | .canvas-container { 26 | flex: 1; 27 | overflow: auto; 28 | z-index: 0; 29 | cursor: grab; 30 | transition: all 0.3s ease-out; 31 | } 32 | 33 | .canvas-container.show-grid[data-zoom="100"] { 34 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 35 | background-size: 75px 75px, 75px 75px, 15px 15px, 15px 15px; 36 | &:before{ 37 | background-size: 75px 10px, 5px 5px; 38 | } 39 | &:after { 40 | background-size: 10px 75px, 5px 5px; 41 | } 42 | } 43 | 44 | .canvas-container.show-grid[data-zoom="90"] { 45 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 46 | background-size: 70px 70px, 70px 70px, 14px 14px, 14px 14px; 47 | &:before{ 48 | background-size: 70px 10px, 5px 5px; 49 | } 50 | &:after { 51 | background-size: 10px 70px, 5px 5px; 52 | } 53 | } 54 | 55 | .canvas-container.show-grid[data-zoom="80"] { 56 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 57 | background-size: 60px 60px, 60px 60px, 12px 12px, 12px 12px; 58 | &:before{ 59 | background-size: 60px 10px, 5px 5px; 60 | } 61 | &:after { 62 | background-size: 10px 60px, 5px 5px; 63 | } 64 | } 65 | 66 | .canvas-container.show-grid[data-zoom="70"] { 67 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 68 | background-size: 55px 55px, 55px 55px, 11px 11px, 11px 11px; 69 | &:before{ 70 | background-size: 55px 10px, 5px 5px; 71 | } 72 | &:after { 73 | background-size: 10px 55px, 5px 5px; 74 | } 75 | } 76 | 77 | .canvas-container.show-grid[data-zoom="60"] { 78 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 79 | background-size: 45px 45px, 45px 45px, 9px 9px, 9px 9px; 80 | &:before{ 81 | background-size: 45px 10px, 5px 5px; 82 | } 83 | &:after { 84 | background-size: 10px 45px, 5px 5px; 85 | } 86 | } 87 | 88 | .canvas-container.show-grid[data-zoom="50"] { 89 | background-image: linear-gradient(#eee 1px, transparent 0), linear-gradient(90deg, #eee 1px, transparent 0), linear-gradient(#f5f5f5 1px, transparent 0), linear-gradient(90deg, #f5f5f5 1px, transparent 0); 90 | background-size: 40px 40px, 40px 40px, 8px 8px, 8px 8px; 91 | &:before{ 92 | background-size: 40px 10px, 5px 5px; 93 | } 94 | &:after { 95 | background-size: 10px 40px, 5px 5px; 96 | } 97 | } 98 | 99 | .canvas-container.show-grid:before { 100 | content: ""; 101 | height: 10px; 102 | width: 100%; 103 | display: block; 104 | background-repeat-y: no-repeat; 105 | position: absolute; 106 | background-image: linear-gradient(90deg, #ccc 1px, transparent 0), linear-gradient(90deg, #ddd 1px, transparent 0); 107 | background-size: 75px 10px, 5px 5px; 108 | } 109 | 110 | .canvas-container.show-grid:after { 111 | content: ""; 112 | height: 100%; 113 | width: 10px; 114 | display: block; 115 | background-repeat-x: no-repeat; 116 | position: absolute; 117 | top: 0; 118 | background-image: linear-gradient(#ccc 1px, transparent 0), linear-gradient(#ddd 1px, transparent 0); 119 | background-size: 10px 75px, 5px 5px; 120 | } 121 | 122 | #campaignCanvas { 123 | background-color: transparent; 124 | transform-origin: top; 125 | width: 100%; 126 | height: 100%; 127 | overflow: visible !important; 128 | position: relative; 129 | } 130 | 131 | 132 | .flow-editor { 133 | 134 | } 135 | 136 | .node { 137 | display: inline-block; 138 | vertical-align: bottom; 139 | background-color: #8db9d3; 140 | color: #fff; 141 | border-radius: 10px; 142 | margin: 0px 9px 15px; 143 | width: 50px; 144 | height: 50px; 145 | cursor: pointer; 146 | padding: 0; 147 | font-size: 0.9em; 148 | transition: 0.2s outline; 149 | } 150 | 151 | .node-circle { 152 | border-radius: 25px; 153 | 154 | .step-img { 155 | margin: 0 auto; 156 | margin-top: 10px; 157 | width: 30px; 158 | height: 30px; 159 | } 160 | } 161 | 162 | .node-square { 163 | display: inline-block; 164 | vertical-align: bottom; 165 | margin: 0px 9px 0; 166 | width: 50px; 167 | height: 50px; 168 | cursor: pointer; 169 | position: relative; 170 | 171 | .square { 172 | width: 50px; 173 | height: 50px; 174 | border-radius: 10px; 175 | background-color: #8db9d3; 176 | transform: rotate(45deg) scale(0.8); 177 | overflow: hidden; 178 | } 179 | 180 | .step-img { 181 | transform: rotate(-45deg); 182 | margin-top: 5px; 183 | margin-left: 5px; 184 | width: 40px; 185 | height: 40px; 186 | } 187 | 188 | .step-expand { 189 | margin-top: 2px; 190 | margin-left: 2px; 191 | } 192 | } 193 | 194 | 195 | .step-img { 196 | margin-top: 5px; 197 | margin-left: 13px; 198 | width: 24px; 199 | height: 24px; 200 | display: flex; 201 | flex-direction: column; 202 | justify-content: center; 203 | align-items: center; 204 | } 205 | 206 | .step-title { 207 | font-size: 10px; 208 | text-align: center; 209 | } 210 | 211 | // 右侧的editor 212 | .flow-editor-sidebar { 213 | position: relative; 214 | width: 287px; 215 | background-color: #616D74; 216 | color: #bababa; 217 | z-index: 1; 218 | overflow-y: auto; 219 | overflow-x: hidden; 220 | transition: all 0.3s; 221 | 222 | &.collapsed { 223 | transform: translateX(-100%); 224 | overflow: visible; 225 | width: 0; 226 | } 227 | 228 | .items-box { 229 | padding-top: 15px; 230 | padding-bottom: 5px; 231 | border-bottom: 1px solid #7f7f7f; 232 | 233 | &:last-child { 234 | border-bottom: none; 235 | } 236 | } 237 | 238 | } 239 | 240 | 241 | // editor 242 | .canvas-container { 243 | // 244 | .flow-item { 245 | height: 50px; 246 | width: 50px; 247 | } 248 | 249 | .flow-text { 250 | margin-left: 5px; 251 | padding-top: 8px; 252 | vertical-align: top; 253 | width: 62px; 254 | 255 | .text-line { 256 | color: #444; 257 | display: inline-block; 258 | } 259 | 260 | span { 261 | max-width: 50px; 262 | display: inline-block; 263 | } 264 | 265 | span.text-content{ 266 | white-space: pre; 267 | text-overflow: ellipsis; 268 | overflow: hidden; 269 | color: #8b9ea5; 270 | max-width: 90px; 271 | display: inline-block; 272 | position: absolute; 273 | word-break: break-all; 274 | word-break: break-word; 275 | 276 | &:hover{ 277 | overflow: visible; 278 | width: 90px; 279 | white-space: pre-wrap; 280 | z-index: 1; 281 | } 282 | } 283 | 284 | 285 | i { 286 | position: absolute; 287 | } 288 | } 289 | 290 | 291 | .node-content-wrap { 292 | position: absolute; 293 | width: 50px; 294 | height: 50px; 295 | cursor: pointer; 296 | display: flex; 297 | flex-shrink: 0; 298 | 299 | .node-square { 300 | margin: auto; 301 | } 302 | 303 | .node-content { 304 | display: flex; 305 | } 306 | 307 | .flow-item { 308 | flex-shrink: 0; 309 | } 310 | 311 | 312 | &:hover { 313 | .flow-delete { 314 | display: inline-block; 315 | text-align: center; 316 | font-size: 16px; 317 | } 318 | } 319 | } 320 | 321 | .node { 322 | margin: auto; 323 | } 324 | 325 | .node-temp.node-temp-img { 326 | position: relative; 327 | transform: scale(0.8) translateY(-5px); 328 | transition: all 0.5s; 329 | background: #fff; 330 | color: #ccc; 331 | border: 2px dashed; 332 | width: 50px; 333 | height: 50px; 334 | border-radius: 50%; 335 | display: flex; 336 | flex-direction: column; 337 | justify-content: center; 338 | flex-shrink: 0; 339 | align-items: center; 340 | font-size: 28px; 341 | cursor: pointer; 342 | 343 | &:before { 344 | content: "+"; 345 | font-size: 29px; 346 | margin-top: -2px; 347 | position: absolute; 348 | margin-left: 0.5px; 349 | color: #ccc; 350 | } 351 | 352 | &:after { 353 | content: ""; 354 | font-size: 14px; 355 | padding: 0 4px; 356 | opacity: 0; 357 | } 358 | 359 | 360 | &:hover { 361 | border-radius: 30px; 362 | width: 135px; 363 | transform: translateX(-45px); 364 | height: 100px; 365 | color: #72c6d0; 366 | z-index: 1; 367 | text-align: center; 368 | 369 | &:before { 370 | color: #72c6d0; 371 | content: ''; 372 | } 373 | 374 | &:after { 375 | opacity: 1; 376 | content: '\70B9\51FB\6216\62D6\52A8\5DE6\4FA7\8282\70B9\5230\6B64\5904'; 377 | } 378 | } 379 | 380 | 381 | 382 | &.is-active { 383 | position: relative; 384 | border-radius: 30px; 385 | width: 135px; 386 | transform: translateX(-45px); 387 | height: 100px; 388 | color: #72c6d0; 389 | z-index: 1; 390 | text-align: center; 391 | 392 | &:before { 393 | color: #72c6d0; 394 | content: ''; 395 | } 396 | 397 | &:after { 398 | opacity: 1; 399 | content: '\70B9\51FB\6216\62D6\52A8\5DE6\4FA7\8282\70B9\5230\6B64\5904'; 400 | } 401 | 402 | .sortable-ghost { 403 | display: none; 404 | } 405 | } 406 | } 407 | 408 | 409 | 410 | .flow-delete { 411 | cursor: pointer; 412 | display: none; 413 | color: #ff7373; 414 | } 415 | 416 | 417 | .node-temp-small { 418 | width: 22px; 419 | height: 22px; 420 | border-radius: 50%; 421 | border: 1.5px dashed; 422 | color: #ccc; 423 | text-align: center; 424 | background: #fff; 425 | cursor: pointer; 426 | transition: transform 0.3s, width 0.3s, height 0.3s, border-radius 0.3s; 427 | justify-content: center; 428 | display: none; 429 | 430 | &.is-active{ 431 | .sortable-ghost { 432 | display: none; 433 | } 434 | } 435 | 436 | &:before { 437 | width: 100px; 438 | height: 50px; 439 | position: absolute; 440 | left: 18px; 441 | display: flex; 442 | align-items: center; 443 | justify-content: center; 444 | } 445 | 446 | &:after { 447 | content: "+"; 448 | background: #fff; 449 | position: relative; 450 | top: 2px; 451 | } 452 | 453 | 454 | &.is-active, &:hover { 455 | color: #72c6d0; 456 | width: 135px; 457 | height: 50px; 458 | border-radius: 50px; 459 | z-index: 1; 460 | 461 | &:before { 462 | content: '\70B9\51FB\6216\62D6\52A8\5DE6\4FA7\8282\70B9\5230\6B64\5904'; 463 | } 464 | 465 | &:after { 466 | opacity: 0; 467 | } 468 | } 469 | } 470 | 471 | 472 | } 473 | 474 | 475 | // dialog 476 | .dialog-wrap { 477 | .el-dialog__header { 478 | padding: 15px 20px 10px; 479 | background-color: #81D3F8; 480 | color: #F2F2F2; 481 | } 482 | 483 | .el-dialog__body { 484 | padding: 15px 10px; 485 | } 486 | 487 | .dialog-title { 488 | } 489 | 490 | .el-icon-arrow-left { 491 | font-size: 14px; 492 | cursor: pointer; 493 | padding-right: 15px; 494 | border-right: 1px solid #ccc; 495 | } 496 | 497 | .desc { 498 | position: relative; 499 | line-height: 14px; 500 | } 501 | 502 | } 503 | 504 | 505 | .flow-tools { 506 | position: absolute; 507 | box-sizing: border-box; 508 | right: 297px; 509 | top: 10px; 510 | background: rgba(255, 255, 255, 1); 511 | border: 1px solid rgba(242, 242, 242, 1); 512 | height: 40px; 513 | border-radius: 3px; 514 | padding: 5px 0; 515 | z-index: 1; 516 | 517 | .tool-item { 518 | width: 25px; 519 | height: 25px; 520 | display: inline-block; 521 | cursor: pointer; 522 | color: #BFBFBF; 523 | margin: 0 5px; 524 | vertical-align: top; 525 | 526 | span { 527 | display: inline-block; 528 | } 529 | 530 | .fa{ 531 | font-size: 25px; 532 | } 533 | 534 | .fa-mail-forward{ 535 | font-size: 23px; 536 | } 537 | } 538 | } 539 | 540 | 541 | .flow-zoom { 542 | height: 96px; 543 | padding: 5px; 544 | top: 50px; 545 | left: 20px; 546 | position: absolute; 547 | display: flex; 548 | flex-direction: column; 549 | justify-content: space-between; 550 | z-index: 1; 551 | 552 | .zoom-btn { 553 | z-index: 2; 554 | 555 | .el-button--mini { 556 | width: 24px; 557 | height: 24px; 558 | 559 | &.is-circle { 560 | padding: 5px; 561 | } 562 | } 563 | } 564 | 565 | &:before { 566 | content: ""; 567 | position: absolute; 568 | border: 1px solid; 569 | width: 2px; 570 | height: 80px; 571 | left: 16px; 572 | box-shadow: 0px 0px 10px #ccc; 573 | } 574 | 575 | &:after { 576 | content: attr(data-zoom); 577 | top: 10px; 578 | left: 33px; 579 | position: absolute; 580 | } 581 | } 582 | 583 | 584 | .node-item-label { 585 | transform: translate(10px, -15px) !important; 586 | color: #bababa; 587 | width: 60px; 588 | 589 | .node-item-title { 590 | max-width: 60px; 591 | white-space: nowrap; 592 | overflow: hidden; 593 | text-overflow: ellipsis; 594 | display: block; 595 | } 596 | } 597 | 598 | .item-border { 599 | border: 1px solid #eee; 600 | border-radius: 4px; 601 | padding: 5px 10px; 602 | 603 | .item-title { 604 | font-size: 12px; 605 | } 606 | } 607 | 608 | .text-step-count{ 609 | color: #AA5C00; 610 | } 611 | 612 | .pre-show{ 613 | height: 500px; 614 | overflow: auto; 615 | } 616 | 617 | 618 | 619 | 620 | 621 | -------------------------------------------------------------------------------- /src/components/Draggable.js: -------------------------------------------------------------------------------- 1 | const Sortable = require("sortablejs"); 2 | 3 | function getConsole() { 4 | if (typeof window !== "undefined") { 5 | return window.console; 6 | } 7 | return global.console; 8 | } 9 | 10 | const console = getConsole(); 11 | 12 | function buildAttribute(object, propName, value) { 13 | if (value == undefined) { 14 | return object; 15 | } 16 | object = object == null ? {} : object; 17 | object[propName] = value; 18 | return object; 19 | } 20 | 21 | // remove node 22 | function removeNode(node) { 23 | if (node.parentElement !== null) { 24 | node.parentElement.removeChild(node); 25 | } 26 | } 27 | 28 | // insert node at 29 | function insertNodeAt(fatherNode, node, position) { 30 | const refNode = 31 | position === 0 32 | ? fatherNode.children[0] 33 | : fatherNode.children[position - 1].nextSibling; 34 | fatherNode.insertBefore(node, refNode); 35 | } 36 | 37 | // compute vm index 38 | function computeVmIndex(vnodes, element) { 39 | return vnodes.map(elt => elt.elm).indexOf(element); 40 | } 41 | 42 | function computeIndexes(slots, children, isTransition) { 43 | if (!slots) { 44 | return []; 45 | } 46 | 47 | const elmFromNodes = slots.map(elt => elt.elm); 48 | const rawIndexes = [...children].map(elt => elmFromNodes.indexOf(elt)); 49 | return isTransition ? rawIndexes.filter(ind => ind !== -1) : rawIndexes; 50 | } 51 | 52 | function emit(evtName, evtData) { 53 | this.$nextTick(() => this.$emit(evtName.toLowerCase(), evtData)); 54 | } 55 | 56 | function delegateAndEmit(evtName) { 57 | return evtData => { 58 | if (this.realList !== null) { 59 | this["onDrag" + evtName](evtData); 60 | } 61 | emit.call(this, evtName, evtData); 62 | }; 63 | } 64 | 65 | function groupIsClone(group) { 66 | if (!group) { 67 | return false; 68 | } 69 | const { pull } = group; 70 | if (typeof pull === "function") { 71 | return pull() === "clone"; 72 | } 73 | return pull === "clone"; 74 | } 75 | 76 | const eventsListened = ["Start", "Add", "Remove", "Update", "End"]; 77 | const eventsToEmit = ["Choose", "Sort", "Filter", "Clone"]; 78 | const readonlyProperties = ["Move", ...eventsListened, ...eventsToEmit].map( 79 | evt => "on" + evt 80 | ); 81 | var draggingElement = null; 82 | 83 | const props = { 84 | options: Object, 85 | list: { 86 | type: Array, 87 | required: false, 88 | default: null 89 | }, 90 | value: { 91 | type: Array, 92 | required: false, 93 | default: null 94 | }, 95 | noTransitionOnDrag: { 96 | type: Boolean, 97 | default: false 98 | }, 99 | clone: { 100 | type: Function, 101 | default: original => { 102 | return original; 103 | } 104 | }, 105 | element: { 106 | type: String, 107 | default: "div" 108 | }, 109 | tag: { 110 | type: String, 111 | default: null 112 | }, 113 | move: { 114 | type: Function, 115 | default: null 116 | }, 117 | componentData: { 118 | type: Object, 119 | required: false, 120 | default: null 121 | } 122 | }; 123 | 124 | const draggableComponent = { 125 | name: "draggable", 126 | 127 | inheritAttrs: true, 128 | 129 | props, 130 | 131 | data() { 132 | return { 133 | transitionMode: false, 134 | noneFunctionalComponentMode: false, 135 | init: false, 136 | isCloning: false 137 | }; 138 | }, 139 | 140 | render(h) { 141 | const slots = this.$slots.default; 142 | if (slots && slots.length === 1) { 143 | const child = slots[0]; 144 | if ( 145 | child.componentOptions && 146 | ["transition-group", "TransitionGroup"].includes( 147 | child.componentOptions.tag 148 | ) 149 | ) { 150 | this.transitionMode = true; 151 | } 152 | } 153 | let headerOffset = 0; 154 | let children = slots; 155 | const { header, footer } = this.$slots; 156 | if (header) { 157 | headerOffset = header.length; 158 | children = children ? [...header, ...children] : [...header]; 159 | } 160 | if (footer) { 161 | children = children ? [...children, ...footer] : [...footer]; 162 | } 163 | this.headerOffset = headerOffset; 164 | var attributes = null; 165 | const update = (name, value) => { 166 | attributes = buildAttribute(attributes, name, value); 167 | }; 168 | if (this.componentData) { 169 | const { on, props } = this.componentData; 170 | update("on", on); 171 | update("props", props); 172 | } 173 | return h(this.getTag(), attributes, children); 174 | }, 175 | 176 | created() { 177 | if (this.list !== null && this.value !== null) { 178 | console.error( 179 | "Value and list props are mutually exclusive! Please set one or another." 180 | ); 181 | } 182 | 183 | if (this.element !== "div") { 184 | console.warn( 185 | "Element props is deprecated please use tag props instead. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#element-props" 186 | ); 187 | } 188 | 189 | if (this.options !== undefined) { 190 | console.warn( 191 | "Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#options-props" 192 | ); 193 | } 194 | }, 195 | 196 | mounted() { 197 | this.noneFunctionalComponentMode = 198 | this.getTag().toLowerCase() !== this.$el.nodeName.toLowerCase(); 199 | if (this.noneFunctionalComponentMode && this.transitionMode) { 200 | throw new Error( 201 | `Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: ${this.getTag()}` 202 | ); 203 | } 204 | var optionsAdded = {}; 205 | eventsListened.forEach(elt => { 206 | optionsAdded["on" + elt] = delegateAndEmit.call(this, elt); 207 | }); 208 | 209 | eventsToEmit.forEach(elt => { 210 | optionsAdded["on" + elt] = emit.bind(this, elt); 211 | }); 212 | 213 | const options = Object.assign({}, this.options, this.$attrs, optionsAdded, { 214 | onMove: (evt, originalEvent) => { 215 | return this.onDragMove(evt, originalEvent); 216 | } 217 | }); 218 | !("draggable" in options) && (options.draggable = ">*"); 219 | this._sortable = new Sortable(this.rootContainer, options); 220 | this.computeIndexes(); 221 | }, 222 | 223 | beforeDestroy() { 224 | if (this._sortable !== undefined) this._sortable.destroy(); 225 | }, 226 | 227 | computed: { 228 | rootContainer() { 229 | return this.transitionMode ? this.$el.children[0] : this.$el; 230 | }, 231 | 232 | realList() { 233 | return this.list ? this.list : this.value; 234 | } 235 | }, 236 | 237 | watch: { 238 | options: { 239 | handler(newOptionValue) { 240 | this.updateOptions(newOptionValue); 241 | }, 242 | deep: true 243 | }, 244 | 245 | $attrs: { 246 | handler(newOptionValue) { 247 | this.updateOptions(newOptionValue); 248 | }, 249 | deep: true 250 | }, 251 | 252 | realList() { 253 | this.computeIndexes(); 254 | } 255 | }, 256 | 257 | methods: { 258 | getTag() { 259 | return this.tag || this.element; 260 | }, 261 | 262 | getIsCloning() { 263 | const { group } = this.$attrs; 264 | const groupConsideringOption = group || this.getOptionGroup(); 265 | return groupIsClone(groupConsideringOption); 266 | }, 267 | 268 | getOptionGroup() { 269 | const { options } = this; 270 | if (!options) { 271 | return undefined; 272 | } 273 | return options.group; 274 | }, 275 | 276 | updateOptions(newOptionValue) { 277 | for (var property in newOptionValue) { 278 | if (readonlyProperties.indexOf(property) == -1) { 279 | this._sortable.option(property, newOptionValue[property]); 280 | } 281 | } 282 | }, 283 | 284 | getChildrenNodes() { 285 | if (!this.init) { 286 | this.noneFunctionalComponentMode = 287 | this.noneFunctionalComponentMode && this.$children.length == 1; 288 | this.init = true; 289 | } 290 | 291 | if (this.noneFunctionalComponentMode) { 292 | return this.$children[0].$slots.default; 293 | } 294 | const rawNodes = this.$slots.default; 295 | return this.transitionMode ? rawNodes[0].child.$slots.default : rawNodes; 296 | }, 297 | 298 | computeIndexes() { 299 | this.$nextTick(() => { 300 | this.visibleIndexes = computeIndexes( 301 | this.getChildrenNodes(), 302 | this.rootContainer.children, 303 | this.transitionMode 304 | ); 305 | }); 306 | }, 307 | 308 | getUnderlyingVm(htmlElt) { 309 | const index = computeVmIndex(this.getChildrenNodes() || [], htmlElt); 310 | if (index === -1) { 311 | //Edge case during move callback: related element might be 312 | //an element different from collection 313 | return null; 314 | } 315 | const element = this.realList[index]; 316 | return { index, element }; 317 | }, 318 | 319 | getUnderlyingPotencialDraggableComponent({ __vue__ }) { 320 | if ( 321 | !__vue__ || 322 | !__vue__.$options || 323 | __vue__.$options._componentTag !== "transition-group" 324 | ) { 325 | return __vue__; 326 | } 327 | return __vue__.$parent; 328 | }, 329 | 330 | emitChanges(evt) { 331 | this.$nextTick(() => { 332 | this.$emit("change", evt); 333 | }); 334 | }, 335 | 336 | alterList(onList) { 337 | if (this.list) { 338 | onList(this.list); 339 | } else { 340 | const newList = [...this.value]; 341 | onList(newList); 342 | this.$emit("input", newList); 343 | } 344 | }, 345 | 346 | spliceList() { 347 | const spliceList = list => list.splice(...arguments); 348 | this.alterList(spliceList); 349 | }, 350 | 351 | updatePosition(oldIndex, newIndex) { 352 | const updatePosition = list => 353 | list.splice(newIndex, 0, list.splice(oldIndex, 1)[0]); 354 | this.alterList(updatePosition); 355 | }, 356 | 357 | getRelatedContextFromMoveEvent({ to, related }) { 358 | const component = this.getUnderlyingPotencialDraggableComponent(to); 359 | if (!component) { 360 | return { component }; 361 | } 362 | const list = component.realList; 363 | const context = { list, component }; 364 | if (to !== related && list && component.getUnderlyingVm) { 365 | const destination = component.getUnderlyingVm(related); 366 | if (destination) { 367 | return Object.assign(destination, context); 368 | } 369 | } 370 | 371 | return context; 372 | }, 373 | 374 | getVmIndex(domIndex) { 375 | const indexes = this.visibleIndexes; 376 | const numberIndexes = indexes.length; 377 | return domIndex > numberIndexes - 1 ? numberIndexes : indexes[domIndex]; 378 | }, 379 | 380 | getComponent() { 381 | return this.$slots.default[0].componentInstance; 382 | }, 383 | 384 | resetTransitionData(index) { 385 | if (!this.noTransitionOnDrag || !this.transitionMode) { 386 | return; 387 | } 388 | var nodes = this.getChildrenNodes(); 389 | nodes[index].data = null; 390 | const transitionContainer = this.getComponent(); 391 | transitionContainer.children = []; 392 | transitionContainer.kept = undefined; 393 | }, 394 | 395 | onDragStart(evt) { 396 | this.context = this.getUnderlyingVm(evt.item); 397 | this.isCloning = this.getIsCloning(); 398 | evt.item._underlying_vm_ = this.clone(this.context.element); 399 | draggingElement = evt.item; 400 | }, 401 | 402 | onDragAdd(evt) { 403 | const element = evt.item._underlying_vm_; 404 | if (element === undefined) { 405 | return; 406 | } 407 | removeNode(evt.item); 408 | const newIndex = this.getVmIndex(evt.newIndex); 409 | this.spliceList(newIndex, 0, element); 410 | this.computeIndexes(); 411 | const added = { element, newIndex }; 412 | this.emitChanges({ added }); 413 | }, 414 | 415 | onDragRemove(evt) { 416 | insertNodeAt(this.rootContainer, evt.item, evt.oldIndex); 417 | if (this.isCloning) { 418 | removeNode(evt.clone); 419 | return; 420 | } 421 | const oldIndex = this.context.index; 422 | this.spliceList(oldIndex, 1); 423 | const removed = { element: this.context.element, oldIndex }; 424 | this.resetTransitionData(oldIndex); 425 | this.emitChanges({ removed }); 426 | }, 427 | 428 | onDragUpdate(evt) { 429 | removeNode(evt.item); 430 | insertNodeAt(evt.from, evt.item, evt.oldIndex); 431 | const oldIndex = this.context.index; 432 | const newIndex = this.getVmIndex(evt.newIndex); 433 | this.updatePosition(oldIndex, newIndex); 434 | const moved = { element: this.context.element, oldIndex, newIndex }; 435 | this.emitChanges({ moved }); 436 | }, 437 | 438 | updateProperty(evt, propertyName) { 439 | evt.hasOwnProperty(propertyName) && 440 | (evt[propertyName] += this.headerOffset); 441 | }, 442 | 443 | computeFutureIndex(relatedContext, evt) { 444 | if (!relatedContext.element) { 445 | return 0; 446 | } 447 | const domChildren = [...evt.to.children].filter( 448 | el => el.style["display"] !== "none" 449 | ); 450 | const currentDOMIndex = domChildren.indexOf(evt.related); 451 | const currentIndex = relatedContext.component.getVmIndex(currentDOMIndex); 452 | const draggedInList = domChildren.indexOf(draggingElement) != -1; 453 | return draggedInList || !evt.willInsertAfter 454 | ? currentIndex 455 | : currentIndex + 1; 456 | }, 457 | 458 | onDragMove(evt, originalEvent) { 459 | const onMove = this.move; 460 | if (!onMove || !this.realList) { 461 | return true; 462 | } 463 | 464 | const relatedContext = this.getRelatedContextFromMoveEvent(evt); 465 | const draggedContext = this.context; 466 | const futureIndex = this.computeFutureIndex(relatedContext, evt); 467 | Object.assign(draggedContext, { futureIndex }); 468 | Object.assign(evt, { relatedContext, draggedContext }); 469 | return onMove(evt, originalEvent); 470 | }, 471 | 472 | onDragEnd() { 473 | this.computeIndexes(); 474 | draggingElement = null; 475 | } 476 | } 477 | }; 478 | 479 | 480 | export default draggableComponent; 481 | -------------------------------------------------------------------------------- /src/styles/_jsplumbtoolkit-defaults.scss: -------------------------------------------------------------------------------- 1 | /* 2 | Default styles for jsPlumb Toolkit 3 | 4 | Copyright 2018 https://jsplumbtoolkit.com 5 | */ 6 | 7 | /* --------------------------------------------------------------------------------------------- */ 8 | /* --- SURFACE WIDGET -------------------------------------------------------------------------- */ 9 | /* --------------------------------------------------------------------------------------------- */ 10 | 11 | /* 12 | Assigned to every Node managed by an instance of the Toolkit. They are required to be positioned absolute, to 13 | enable dragging to work properly. 14 | */ 15 | .jtk-node { 16 | position: absolute; 17 | } 18 | 19 | /* 20 | Assigned to every Group managed by an instance of the Toolkit. They are required to be positioned absolute, to 21 | enable dragging to work properly. We set overflow:visible on Group elements too, as a drag outside of the bounds 22 | is automatically reverted anyway, and without overflow:visible you cannot drag a node to some other element. You can 23 | also drag a node out of the element's viewport and if you drop it you can never get it back. 24 | */ 25 | .jtk-group { 26 | position: absolute; 27 | overflow: visible; 28 | } 29 | 30 | /* 31 | 32 | This is the attribute used to mark which part of a Group DOM element should contain the child Nodes. We mark it 33 | as having `position:relative` so that the absolute positioned Nodes are drawn correctly. 34 | */ 35 | [jtk-group-content] { 36 | position:relative; 37 | } 38 | 39 | /* 40 | This style was created in response to this Chrome bug: 41 | http://stackoverflow.com/questions/13758215/artifacts-when-css-scaled-in-chrome 42 | 43 | Basically it's about how sometimes there can be artefacts left on screen when the user drags an element. It seems 44 | the issue has been fixed in more recent versions of Chrome, but the style is left here in case you come across 45 | the problem. 46 | */ 47 | .jtk-node.jtk-drag { 48 | /*-webkit-backface-visibility: hidden;*/ 49 | } 50 | 51 | /* 52 | Suppresses the pointer events on an element that was created by Katavorio in response to a drag in which the element 53 | should first be cloned. Having this clone ignore pointer events means there is less chance that any other 54 | mouse activity (such as click) on the original element will not be consumed by katavorio. 55 | */ 56 | .katavorio-clone-drag { 57 | pointer-events:none; 58 | } 59 | 60 | /* 61 | Assigned to an element that is the `Container` in a `render` call. 62 | Elements that are acting as Surface widgets should have overflow:hidden set to prevent libs from 63 | scrolling them during drag (we don't want scrollbars; we have an infinite canvas). Position is set to 64 | `relative` as this is the parent for nodes, which are positioned absolute (and for absolute positioning 65 | to work, you need to ensure the parent node has `position:relative`). This style also sets some default 66 | values for the cursor - using a `grab` cursor where supported. 67 | */ 68 | .jtk-surface { 69 | overflow: hidden !important; 70 | position: relative; 71 | cursor: move; 72 | cursor: -moz-grab; 73 | cursor: -webkit-grab; 74 | 75 | /* 76 | For IE10+. As discussed on this page: 77 | 78 | https://msdn.microsoft.com/en-us/library/ie/jj583807(v=vs.85).aspx 79 | 80 | Microsoft have very helpfully implemented default behaviours for a bunch of touch events and 81 | then consumed the events so you don't have to be bothered by them. They've "done a lot of research" 82 | about this stuff and put together a really great default experience for everyone in the entire world. 83 | */ 84 | touch-action:none; 85 | 86 | /* 87 | Another Chrome issue that appears to have been fixed in later versions 88 | http://stackoverflow.com/questions/15464055/css-transition-effect-makes-image-blurry-moves-image-1px-in-chrome 89 | */ 90 | /* 91 | -webkit-backface-visibility: hidden; 92 | -webkit-transform: translateZ(0) scale(1.0, 1.0); 93 | */ 94 | } 95 | 96 | /* 97 | Assigned to the surface when it is being panned. The default is to change the cursor (in browsers that support 98 | a `grabbing` cursor), and to disable text selection. 99 | */ 100 | .jtk-surface-panning { 101 | cursor: -moz-grabbing; 102 | cursor: -webkit-grabbing; 103 | -webkit-touch-callout: none; 104 | -webkit-user-select: none; 105 | -khtml-user-select: none; 106 | -moz-user-select: none; 107 | -ms-user-select: none; 108 | user-select: none; 109 | } 110 | 111 | /* 112 | The work area in a surface renderer. 113 | */ 114 | .jtk-surface-canvas { 115 | overflow: visible !important; 116 | } 117 | 118 | /* 119 | For IE10+. Discussed above in the .jtk-surface styles. This one is specific to elements that are configured 120 | to be droppable on a Surface via its `registerDroppableNodes` method. 121 | */ 122 | .jtk-surface-droppable-node { 123 | touch-action:none; 124 | } 125 | 126 | /* 127 | Assigned to a Surface widget when panning is disabled (and therefore the app is relying on scrollbars when the content overflows). 128 | */ 129 | .jtk-surface-nopan { 130 | overflow: scroll !important; 131 | cursor:default; 132 | } 133 | 134 | /* 135 | Assigned to tile images in a tiled background 136 | */ 137 | .jtk-surface-tile { 138 | border:none; 139 | outline:none; 140 | margin:0; 141 | -webkit-transition: opacity .3s ease .15s; 142 | -moz-transition: opacity .3s ease .15s; 143 | -o-transition: opacity .3s ease .15s; 144 | -ms-transition: opacity .3s ease .15s; 145 | transition: opacity .3s ease .15s; 146 | } 147 | 148 | /* 149 | Assigned to the element used for node select with the mouse ("lasso"). 150 | */ 151 | .jtk-lasso { 152 | border: 2px solid rgb(49, 119, 184); 153 | background-color: WhiteSmoke; 154 | opacity: 0.5; 155 | display: none; 156 | z-index: 20000; 157 | position: absolute; 158 | } 159 | 160 | /* 161 | This class is added to the document body on lasso drag start and removed at the end of lasso dragging. Its purpose 162 | is to switch off text selection on all elements while the user is dragging the lasso. 163 | */ 164 | .jtk-lasso-select-defeat * { 165 | -webkit-touch-callout: none; 166 | -webkit-user-select: none; 167 | -khtml-user-select: none; 168 | -moz-user-select: none; 169 | -ms-user-select: none; 170 | user-select: none; 171 | } 172 | 173 | /** 174 | Added to the lasso mask when it is operating in 'inverted' mode, ie. the excluded parts of the UI are covered, rather 175 | than the normal mode in which the selected parts of the UI are covered. 176 | */ 177 | .jtk-lasso-mask { 178 | position:fixed; 179 | z-index:20000; 180 | display:none; 181 | opacity:0.5; 182 | background-color: #07234E; 183 | top:0; 184 | bottom:0; 185 | left:0; 186 | right:0; 187 | } 188 | 189 | /* 190 | Assigned to some element that has been selected (either via lasso or programmatically). 191 | */ 192 | .jtk-surface-selected-element { 193 | border: 2px dashed #f76258 !important; 194 | } 195 | 196 | /* 197 | Assigned to all pan buttons in a surface widget. 198 | */ 199 | .jtk-surface-pan { 200 | background-color: Azure; 201 | opacity: 0.4; 202 | text-align: center; 203 | cursor: pointer; 204 | z-index: 2; 205 | -webkit-transition: background-color 0.15s ease-in; 206 | -moz-transition: background-color 0.15s ease-in; 207 | -o-transition: background-color 0.15s ease-in; 208 | transition: background-color 0.15s ease-in; 209 | } 210 | 211 | /* 212 | Specific styles for the top and bottom pan buttons. 213 | Top/bottom are 100% width and 20px high by default 214 | */ 215 | .jtk-surface-pan-top, .jtk-surface-pan-bottom { 216 | width: 100%; 217 | height: 20px; 218 | } 219 | 220 | /* 221 | Hover styles for all pan buttons. 222 | On hover, change color, background color, font weight and opacity. 223 | */ 224 | .jtk-surface-pan-top:hover, .jtk-surface-pan-bottom:hover, .jtk-surface-pan-left:hover, .jtk-surface-pan-right:hover { 225 | opacity: 0.6; 226 | background-color: rgb(49, 119, 184); 227 | color: white; 228 | font-weight: bold; 229 | } 230 | 231 | /* 232 | Specific styles for the left and right pan buttons. 233 | Left/right pan buttons are 100% height and 20px wide 234 | */ 235 | .jtk-surface-pan-left, .jtk-surface-pan-right { 236 | width: 20px; 237 | height: 100%; 238 | line-height: 40; 239 | } 240 | 241 | 242 | /* 243 | Assigned to a pan button when the user is pressing it. 244 | */ 245 | .jtk-surface-pan-active, .jtk-surface-pan-active:hover { 246 | background-color: #f76258; 247 | } 248 | 249 | /* --------------------------------------------------------------------------------------------- */ 250 | /* --- MINIVIEW WIDGET ------------------------------------------------------------------------- */ 251 | /* --------------------------------------------------------------------------------------------- */ 252 | 253 | /* 254 | Assigned to an element that is acting as a Miniview. 255 | As with Surface, Miniview elements should have overflow:hidden set to prevent 256 | libs from scrolling them during drag. This style also provides a default width/height for a miniview, 257 | which you may wish to override. 258 | */ 259 | .jtk-miniview { 260 | overflow: hidden !important; 261 | width: 125px; 262 | height: 125px; 263 | position: relative; 264 | background-color: #B2C9CD; 265 | border: 1px solid #E2E6CD; 266 | border-radius: 4px; 267 | opacity: 0.8; 268 | } 269 | 270 | /* 271 | Assigned to the element that shows the size of the related viewport in a Miniview widget, and which can be dragged to 272 | move the surface. 273 | */ 274 | .jtk-miniview-panner { 275 | border: 5px dotted WhiteSmoke; 276 | opacity: 0.4; 277 | background-color: rgb(79, 111, 126); 278 | cursor: move; 279 | cursor: -moz-grab; 280 | cursor: -webkit-grab; 281 | } 282 | 283 | /* 284 | Assigned to the miniview's panner when it is being dragged. 285 | */ 286 | .jtk-miniview-panning { 287 | cursor: -moz-grabbing; 288 | cursor: -webkit-grabbing; 289 | } 290 | 291 | /* 292 | Added to all elements displayed in a miniview. 293 | */ 294 | .jtk-miniview-element { 295 | background-color: rgb(96, 122, 134); 296 | position: absolute; 297 | } 298 | 299 | /* 300 | Added to Group elements displayed in a miniview 301 | */ 302 | .jtk-miniview-group-element { 303 | background: transparent; 304 | border: 2px solid rgb(96,122,134); 305 | } 306 | 307 | /* 308 | Assigned to the collapse/expand miniview button 309 | */ 310 | .jtk-miniview-collapse { 311 | color: whiteSmoke; 312 | position: absolute; 313 | font-size: 18px; 314 | top: -1px; 315 | right: 3px; 316 | cursor: pointer; 317 | font-weight: bold; 318 | } 319 | 320 | /* 321 | The '-' symbol when the miniview is expanded 322 | */ 323 | .jtk-miniview-collapse:before { 324 | content: "\2012"; 325 | } 326 | 327 | /* 328 | Assigned to the miniview element when it is collapsed. 329 | */ 330 | .jtk-miniview-collapsed { 331 | background-color: #449ea6; 332 | border-radius: 4px; 333 | height: 22px; 334 | margin-right: 0; 335 | padding: 4px; 336 | width: 21px; 337 | } 338 | 339 | /* 340 | Hide all children of the miniview (except the expand button) when it is collapsed so you don't see anything 341 | poking through under the + icon. 342 | */ 343 | .jtk-miniview-collapsed .jtk-miniview-element, .jtk-miniview-collapsed .jtk-miniview-panner { 344 | visibility: hidden; 345 | } 346 | 347 | /* 348 | The '+' symbol when the miniview is collapsed. 349 | */ 350 | .jtk-miniview-collapsed .jtk-miniview-collapse:before { 351 | content: "+"; 352 | } 353 | 354 | /* 355 | Hover state for the collapse/expand icon. 356 | */ 357 | .jtk-miniview-collapse:hover { 358 | color: #E4F013; 359 | } 360 | 361 | /* ------------------------------------------------------------------------------------------- */ 362 | /* --- DIALOGS --------------------------------------------------------------------------------*/ 363 | /* ------------------------------------------------------------------------------------------- */ 364 | 365 | /* 366 | This is the element that acts as the dialog underlay - the modal "mask". Note the high z-index default 367 | set here (and note also the overlay style below has a z-index with a value higher by one). 368 | */ 369 | .jtk-dialog-underlay { 370 | left: 0; 371 | right: 0; 372 | top: 0; 373 | bottom: 0; 374 | position: fixed; 375 | z-index: 100000; 376 | opacity: 0.8; 377 | background-color: #CCC; 378 | display: none; 379 | } 380 | 381 | /* 382 | This is the element that acts as the parent for dialog content. 383 | */ 384 | .jtk-dialog-overlay { 385 | position: fixed; 386 | z-index: 100001; 387 | display: none; 388 | background-color: white; 389 | font-family: "Open Sans", sans-serif; 390 | padding: 7px; 391 | box-shadow: 0 0 5px gray; 392 | overflow: hidden; 393 | } 394 | 395 | .jtk-dialog-overlay-x { 396 | max-height:0; 397 | transition: max-height 0.5s ease-in; 398 | -moz-transition: max-height 0.5s ease-in; 399 | -ms-transition: max-height 0.5s ease-in; 400 | -o-transition: max-height 0.5s ease-in; 401 | -webkit-transition: max-height 0.5s ease-in; 402 | } 403 | 404 | .jtk-dialog-overlay-y { 405 | max-width:0; 406 | transition: max-width 0.5s ease-in; 407 | -moz-transition: max-width 0.5s ease-in; 408 | -ms-transition: max-width 0.5s ease-in; 409 | -o-transition: max-width 0.5s ease-in; 410 | -webkit-transition: max-width 0.5s ease-in; 411 | } 412 | 413 | .jtk-dialog-overlay-top { 414 | top:20px; 415 | } 416 | 417 | .jtk-dialog-overlay-bottom { 418 | bottom:20px; 419 | } 420 | 421 | .jtk-dialog-overlay-left { 422 | left:20px; 423 | } 424 | 425 | .jtk-dialog-overlay-right { 426 | right:20px; 427 | } 428 | 429 | .jtk-dialog-overlay-x.jtk-dialog-overlay-visible { 430 | max-height:1000px; 431 | } 432 | 433 | .jtk-dialog-overlay-y.jtk-dialog-overlay-visible { 434 | max-width:1000px; 435 | } 436 | 437 | /* 438 | The element containing buttons in a dialog. 439 | */ 440 | .jtk-dialog-buttons { 441 | text-align: right; 442 | margin-top: 5px; 443 | } 444 | 445 | /* 446 | An individual button in a dialog. 447 | */ 448 | .jtk-dialog-button { 449 | border: none; 450 | cursor: pointer; 451 | margin-right: 5px; 452 | min-width: 56px; 453 | background-color: white; 454 | outline: 1px solid #ccc; 455 | } 456 | 457 | /* 458 | Hover style for an individual button in a dialog. 459 | */ 460 | .jtk-dialog-button:hover { 461 | color: white; 462 | background-color: #234b5e; 463 | } 464 | 465 | /* 466 | The titlebar of a dialog. 467 | */ 468 | .jtk-dialog-title { 469 | text-align: left; 470 | font-size: 14px; 471 | margin-bottom: 9px; 472 | } 473 | 474 | .jtk-dialog-content { 475 | font-size:12px; 476 | text-align:left; 477 | min-width:250px; 478 | margin: 0 14px; 479 | } 480 | 481 | .jtk-dialog-content ul { 482 | width:100%; 483 | padding-left:0; 484 | } 485 | 486 | .jtk-dialog-content label { 487 | cursor: pointer; 488 | font-weight: inherit; 489 | } 490 | 491 | .jtk-dialog-overlay input, .jtk-dialog-overlay textarea { 492 | background-color: #FFF; 493 | border: 1px solid #CCC; 494 | color: #333; 495 | font-size: 14px; 496 | font-style: normal; 497 | outline: none; 498 | padding: 6px 4px; 499 | margin-right: 6px; 500 | } 501 | 502 | .jtk-dialog-overlay input:focus, .jtk-dialog-overlay textarea:focus { 503 | background-color: #cbeae1; 504 | border: 1px solid #83b8a8; 505 | color: #333; 506 | font-size: 14px; 507 | font-style: normal; 508 | outline: none; 509 | } 510 | 511 | /* -------------------------------------------------------------------------------------------- */ 512 | /* --- DRAWING TOOLS -------------------------------------------------------------------------- */ 513 | /* -------------------------------------------------------------------------------------------- */ 514 | 515 | /* 516 | Assigned to the element that is drawn around some other element when a drawing operation is taking place. 517 | */ 518 | .jtk-draw-skeleton { 519 | position: absolute; 520 | left: 0; 521 | right: 0; 522 | top: 0; 523 | bottom: 0; 524 | outline: 2px solid #84acb3; 525 | opacity: 0.8; 526 | } 527 | 528 | /* 529 | Assigned to every handle (top left, top right, bottom left, bottom right, center) in a draw skeleton. 530 | */ 531 | .jtk-draw-handle { 532 | position: absolute; 533 | width: 7px; 534 | height: 7px; 535 | background-color: #84acb3; 536 | } 537 | 538 | /* 539 | Assigned to the top left handle in a draw skeleton 540 | */ 541 | .jtk-draw-handle-tl { 542 | left: 0; 543 | top: 0; 544 | cursor: nw-resize; 545 | } 546 | 547 | /* 548 | Assigned to the top right handle in a draw skeleton 549 | */ 550 | .jtk-draw-handle-tr { 551 | right: 0; 552 | top: 0; 553 | cursor: ne-resize; 554 | } 555 | 556 | /* 557 | Assigned to the bottom left handle in a draw skeleton 558 | */ 559 | .jtk-draw-handle-bl { 560 | left: 0; 561 | bottom: 0; 562 | cursor: sw-resize; 563 | } 564 | 565 | /* 566 | Assigned to the bottom right handle in a draw skeleton 567 | */ 568 | .jtk-draw-handle-br { 569 | bottom: 0; 570 | right: 0; 571 | cursor: se-resize; 572 | } 573 | 574 | /* 575 | Assigned to the center handle in a draw skeleton (the handle by which the element may be dragged). This is 576 | not visible by defaut; enable if you need it. 577 | */ 578 | .jtk-draw-drag { 579 | display:none; 580 | position: absolute; 581 | left: 50%; 582 | top: 50%; 583 | margin-left: -10px; 584 | margin-top: -10px; 585 | width: 20px; 586 | height: 20px; 587 | background-color: #84acb3; 588 | cursor: move; 589 | } 590 | 591 | /* 592 | This class is added to the document body on drag resize start and removed at the end of resizing. Its purpose 593 | is to switch off text selection on all elements while the user is resizing an element. 594 | */ 595 | .jtk-drag-select-defeat * { 596 | -webkit-touch-callout: none; 597 | -webkit-user-select: none; 598 | -khtml-user-select: none; 599 | -moz-user-select: none; 600 | -ms-user-select: none; 601 | user-select: none; 602 | } 603 | -------------------------------------------------------------------------------- /src/mock/mock.js: -------------------------------------------------------------------------------- 1 | export const workflowItem = { 2 | positions: '{"e164f7f0-340f-4710-8e9d-90e538f95dc6":{"left":801,"top":30},"7edf6f19-50ab-4047-aba0-bff0f1112450":{"left":801,"top":150},"b4d84bc0-e1d2-41c4-bd97-c1f3cfbbbc15":{"left":801,"top":270},"aecc8389-0339-4791-ba16-86793c782cee":{"left":721,"top":390},"811f5778-334c-4426-bc7c-012409f0d031":{"left":911,"top":390},"fae270c9-a657-4859-94f3-fba25cf962b6":{"left":721,"top":510},"cfc5cb7c-3fd6-412d-898b-57021d1eb9a0":{"left":831,"top":510},"11d00d99-5a70-437d-b420-ead16a827438":{"left":991,"top":510},"51df605d-2c4b-4ada-b1eb-5328f01d18b6":{"left":400,"top":630},"16c0f389-1734-47bb-a278-e29b4b56d73b":{"left":561,"top":630},"f4029f13-b39a-4046-ae72-200acfe1df08":{"left":881,"top":630},"5538cdd8-fe07-4a57-a1cb-377fdac351f8":{"left":1041,"top":630},"643dc8d8-a538-42bf-9255-84dc20336aca":{"left":320,"top":750},"fbf644dd-c308-4fdb-b9f0-07be8bd95f66":{"left":480,"top":750},"37f1aade-de62-4b4d-a29b-7a4d80d289a9":{"left":561,"top":750},"0e9788bf-62bc-4da3-a701-861752602a05":{"left":721,"top":630},"d7b35346-a3d6-4474-88d4-34262b303e64":{"left":721,"top":750},"0e19a6e0-6ae6-4534-a0fe-d279c24673ae":{"left":881,"top":750},"06251e27-5d20-4fb2-989b-bdf64e625ff3":{"left":961,"top":750},"6b0cfcd2-ffb2-42ae-83fb-8ae21a950fa0":{"left":1121,"top":750},"cde5693d-1083-450c-a037-65ef5973747c":{"left":961,"top":870},"0183559b-c2ee-48bf-a718-3b2721e45a29":{"left":1121,"top":870}}', 3 | steps: [ 4 | { 5 | "elementId": "startNode", 6 | "stepId": "e164f7f0-340f-4710-8e9d-90e538f95dc6", 7 | "nextStep": "7edf6f19-50ab-4047-aba0-bff0f1112450" 8 | }, 9 | { 10 | "elementId": "nodeNode", 11 | "stepId": "7edf6f19-50ab-4047-aba0-bff0f1112450", 12 | "nextStep": "b4d84bc0-e1d2-41c4-bd97-c1f3cfbbbc15", 13 | "stepName": "节点" 14 | }, 15 | { 16 | "elementId": "conditionNode", 17 | "stepId": "b4d84bc0-e1d2-41c4-bd97-c1f3cfbbbc15", 18 | "nextSteps": [ 19 | { 20 | "nextStep": "aecc8389-0339-4791-ba16-86793c782cee", 21 | "name": "是", 22 | "isDefault": false, 23 | "ruleGroups": [] 24 | }, 25 | { 26 | "nextStep": "811f5778-334c-4426-bc7c-012409f0d031", 27 | "name": "否", 28 | "isDefault": true, 29 | "ruleGroups": [] 30 | } 31 | ], 32 | "stepName": "条件判断", 33 | "stepJson": "{}" 34 | }, 35 | { 36 | "elementId": "nodeNode", 37 | "stepId": "aecc8389-0339-4791-ba16-86793c782cee", 38 | "nextStep": "fae270c9-a657-4859-94f3-fba25cf962b6", 39 | "stepName": "节点" 40 | }, 41 | { 42 | "elementId": "conditionNode", 43 | "stepId": "811f5778-334c-4426-bc7c-012409f0d031", 44 | "nextSteps": [ 45 | { 46 | "nextStep": "cfc5cb7c-3fd6-412d-898b-57021d1eb9a0", 47 | "name": "是", 48 | "isDefault": false, 49 | "ruleGroups": [] 50 | }, 51 | { 52 | "nextStep": "11d00d99-5a70-437d-b420-ead16a827438", 53 | "name": "否", 54 | "isDefault": true, 55 | "ruleGroups": [] 56 | } 57 | ], 58 | "stepName": "条件判断", 59 | "stepJson": "{}" 60 | }, 61 | { 62 | "elementId": "switchNode", 63 | "stepId": "fae270c9-a657-4859-94f3-fba25cf962b6", 64 | "nextSteps": [ 65 | { 66 | "nextStep": "51df605d-2c4b-4ada-b1eb-5328f01d18b6", 67 | "name": "1", 68 | "isDefault": false 69 | }, 70 | { 71 | "nextStep": "16c0f389-1734-47bb-a278-e29b4b56d73b", 72 | "name": "2", 73 | "isDefault": false 74 | }, 75 | { 76 | "nextStep": "0e9788bf-62bc-4da3-a701-861752602a05", 77 | "name": "3", 78 | "isDefault": false 79 | }, 80 | { 81 | "nextStep": "f4029f13-b39a-4046-ae72-200acfe1df08", 82 | "name": "4", 83 | "isDefault": false 84 | }, 85 | { 86 | "nextStep": "5538cdd8-fe07-4a57-a1cb-377fdac351f8", 87 | "name": "5", 88 | "isDefault": false 89 | } 90 | ], 91 | "stepName": "条件分组" 92 | }, 93 | { 94 | "elementId": "stopNode", 95 | "stepId": "cfc5cb7c-3fd6-412d-898b-57021d1eb9a0", 96 | "nextStep": null 97 | }, 98 | { 99 | "elementId": "stopNode", 100 | "stepId": "11d00d99-5a70-437d-b420-ead16a827438", 101 | "nextStep": null 102 | }, 103 | { 104 | "elementId": "conditionNode", 105 | "stepId": "51df605d-2c4b-4ada-b1eb-5328f01d18b6", 106 | "nextSteps": [ 107 | { 108 | "nextStep": "643dc8d8-a538-42bf-9255-84dc20336aca", 109 | "name": "是", 110 | "isDefault": false, 111 | "ruleGroups": [] 112 | }, 113 | { 114 | "nextStep": "fbf644dd-c308-4fdb-b9f0-07be8bd95f66", 115 | "name": "否", 116 | "isDefault": true, 117 | "ruleGroups": [] 118 | } 119 | ], 120 | "stepName": "条件判断", 121 | "stepJson": "{}" 122 | }, 123 | { 124 | "elementId": "nodeNode", 125 | "stepId": "16c0f389-1734-47bb-a278-e29b4b56d73b", 126 | "nextStep": "37f1aade-de62-4b4d-a29b-7a4d80d289a9", 127 | "stepName": "节点" 128 | }, 129 | { 130 | "elementId": "nodeNode", 131 | "stepId": "f4029f13-b39a-4046-ae72-200acfe1df08", 132 | "nextStep": "0e19a6e0-6ae6-4534-a0fe-d279c24673ae", 133 | "stepName": "节点" 134 | }, 135 | { 136 | "elementId": "conditionNode", 137 | "stepId": "5538cdd8-fe07-4a57-a1cb-377fdac351f8", 138 | "nextSteps": [ 139 | { 140 | "nextStep": "06251e27-5d20-4fb2-989b-bdf64e625ff3", 141 | "name": "是", 142 | "isDefault": false, 143 | "ruleGroups": [] 144 | }, 145 | { 146 | "nextStep": "6b0cfcd2-ffb2-42ae-83fb-8ae21a950fa0", 147 | "name": "否", 148 | "isDefault": true, 149 | "ruleGroups": [] 150 | } 151 | ], 152 | "stepName": "条件判断", 153 | "stepJson": "{}" 154 | }, 155 | { 156 | "elementId": "stopNode", 157 | "stepId": "643dc8d8-a538-42bf-9255-84dc20336aca", 158 | "nextStep": null 159 | }, 160 | { 161 | "elementId": "stopNode", 162 | "stepId": "fbf644dd-c308-4fdb-b9f0-07be8bd95f66", 163 | "nextStep": null 164 | }, 165 | { 166 | "elementId": "stopNode", 167 | "stepId": "37f1aade-de62-4b4d-a29b-7a4d80d289a9", 168 | "nextStep": null 169 | }, 170 | { 171 | "elementId": "nodeNode", 172 | "stepId": "0e9788bf-62bc-4da3-a701-861752602a05", 173 | "nextStep": "d7b35346-a3d6-4474-88d4-34262b303e64", 174 | "stepName": "节点" 175 | }, 176 | { 177 | "elementId": "stopNode", 178 | "stepId": "d7b35346-a3d6-4474-88d4-34262b303e64", 179 | "nextStep": null 180 | }, 181 | { 182 | "elementId": "stopNode", 183 | "stepId": "0e19a6e0-6ae6-4534-a0fe-d279c24673ae", 184 | "nextStep": null 185 | }, 186 | { 187 | "elementId": "nodeNode", 188 | "stepId": "06251e27-5d20-4fb2-989b-bdf64e625ff3", 189 | "nextStep": "cde5693d-1083-450c-a037-65ef5973747c", 190 | "stepName": "节点" 191 | }, 192 | { 193 | "elementId": "nodeNode", 194 | "stepId": "6b0cfcd2-ffb2-42ae-83fb-8ae21a950fa0", 195 | "nextStep": "0183559b-c2ee-48bf-a718-3b2721e45a29", 196 | "stepName": "节点" 197 | }, 198 | { 199 | "elementId": "stopNode", 200 | "stepId": "cde5693d-1083-450c-a037-65ef5973747c", 201 | "nextStep": null 202 | }, 203 | { 204 | "elementId": "stopNode", 205 | "stepId": "0183559b-c2ee-48bf-a718-3b2721e45a29", 206 | "nextStep": null 207 | } 208 | ] 209 | }; 210 | 211 | export const workflowItem2 = { 212 | positions: '{"f4d316b7-b2d1-46bf-aeaa-42525c84726f":{"left":801,"top":30},"c89829f5-8595-458c-b040-4ff84d27befc":{"left":801,"top":150},"d611c32f-b6c0-4b97-80d9-47b783bd93ad":{"left":174,"top":270},"7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5":{"left":800,"top":271},"85c30556-75fa-441c-9a1d-0dced21755a5":{"left":1246,"top":261},"23220649-1dcd-4bdc-af43-a6f80800b80c":{"left":720,"top":391},"da100cd2-a2fd-4967-911f-3acb1036d249":{"left":880,"top":391},"4829e3d8-b45a-4719-abdb-518df7e383ea":{"left":1166,"top":381},"70712f8b-d164-4224-89fd-983a9a20f6b7":{"left":1326,"top":381},"9fa174ae-97b3-41b6-a9a5-9e6189561b85":{"left":720,"top":511},"996c2224-7ae3-43fe-ba3c-8b0c33f8a632":{"left":640,"top":631},"d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869":{"left":800,"top":631},"d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d":{"left":640,"top":751},"89bf2095-030f-4c5f-9d52-1f97cab2e295":{"left":720,"top":871},"83e1fce2-90d8-4edc-9d72-256e2e95425c":{"left":560,"top":871},"653742e5-ea18-4808-ae09-578a3b4667de":{"left":560,"top":991},"b8cb3a6f-4235-4b73-af09-3288f6bebe66":{"left":1166,"top":501},"43c74167-9906-454f-b3d4-4b0687c9cb94":{"left":1086,"top":621},"88e3aee3-d01c-432e-af05-d79d922c55df":{"left":1246,"top":621},"35a13fb1-916e-4717-9692-96a3262e5fd4":{"left":1086,"top":741},"d1c1e591-5b3e-4128-9609-080a30d8e414":{"left":1006,"top":861},"512f2bac-82ca-4ecc-8e71-a0171e8beb4a":{"left":1166,"top":861},"ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c":{"left":1006,"top":981}}', 213 | steps: [ 214 | { 215 | "elementId": "startNode", 216 | "stepId": "f4d316b7-b2d1-46bf-aeaa-42525c84726f", 217 | "nextStep": "c89829f5-8595-458c-b040-4ff84d27befc" 218 | }, 219 | { 220 | "elementId": "switchNode", 221 | "stepId": "c89829f5-8595-458c-b040-4ff84d27befc", 222 | "nextSteps": [ 223 | { 224 | "nextStep": "d611c32f-b6c0-4b97-80d9-47b783bd93ad", 225 | "name": "1", 226 | "isDefault": false 227 | }, 228 | { 229 | "nextStep": "7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5", 230 | "name": "2", 231 | "isDefault": false 232 | }, 233 | { 234 | "nextStep": "85c30556-75fa-441c-9a1d-0dced21755a5", 235 | "name": "3", 236 | "isDefault": false 237 | } 238 | ], 239 | "stepName": "条件分组" 240 | }, 241 | { 242 | "elementId": "stopNode", 243 | "stepId": "d611c32f-b6c0-4b97-80d9-47b783bd93ad", 244 | "nextStep": null 245 | }, 246 | { 247 | "elementId": "conditionNode", 248 | "stepId": "7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5", 249 | "nextSteps": [ 250 | { 251 | "nextStep": "23220649-1dcd-4bdc-af43-a6f80800b80c", 252 | "name": "是", 253 | "isDefault": false, 254 | "ruleGroups": [] 255 | }, 256 | { 257 | "nextStep": "da100cd2-a2fd-4967-911f-3acb1036d249", 258 | "name": "否", 259 | "isDefault": true, 260 | "ruleGroups": [] 261 | } 262 | ], 263 | "stepName": "条件判断", 264 | "stepJson": "{}" 265 | }, 266 | { 267 | "elementId": "conditionNode", 268 | "stepId": "85c30556-75fa-441c-9a1d-0dced21755a5", 269 | "nextSteps": [ 270 | { 271 | "nextStep": "4829e3d8-b45a-4719-abdb-518df7e383ea", 272 | "name": "是", 273 | "isDefault": false, 274 | "ruleGroups": [] 275 | }, 276 | { 277 | "nextStep": "70712f8b-d164-4224-89fd-983a9a20f6b7", 278 | "name": "否", 279 | "isDefault": true, 280 | "ruleGroups": [] 281 | } 282 | ], 283 | "stepName": "条件判断", 284 | "stepJson": "{}" 285 | }, 286 | { 287 | "elementId": "nodeNode", 288 | "stepId": "23220649-1dcd-4bdc-af43-a6f80800b80c", 289 | "nextStep": "9fa174ae-97b3-41b6-a9a5-9e6189561b85", 290 | "stepName": "节点" 291 | }, 292 | { 293 | "elementId": "stopNode", 294 | "stepId": "da100cd2-a2fd-4967-911f-3acb1036d249", 295 | "nextStep": null 296 | }, 297 | { 298 | "elementId": "nodeNode", 299 | "stepId": "4829e3d8-b45a-4719-abdb-518df7e383ea", 300 | "nextStep": "b8cb3a6f-4235-4b73-af09-3288f6bebe66", 301 | "stepName": "节点" 302 | }, 303 | { 304 | "elementId": "stopNode", 305 | "stepId": "70712f8b-d164-4224-89fd-983a9a20f6b7", 306 | "nextStep": null 307 | }, 308 | { 309 | "elementId": "conditionNode", 310 | "stepId": "9fa174ae-97b3-41b6-a9a5-9e6189561b85", 311 | "nextSteps": [ 312 | { 313 | "nextStep": "996c2224-7ae3-43fe-ba3c-8b0c33f8a632", 314 | "name": "是", 315 | "isDefault": false, 316 | "ruleGroups": [] 317 | }, 318 | { 319 | "nextStep": "d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869", 320 | "name": "否", 321 | "isDefault": true, 322 | "ruleGroups": [] 323 | } 324 | ], 325 | "stepName": "条件判断", 326 | "stepJson": "{}" 327 | }, 328 | { 329 | "elementId": "nodeNode", 330 | "stepId": "996c2224-7ae3-43fe-ba3c-8b0c33f8a632", 331 | "nextStep": "d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d", 332 | "stepName": "节点" 333 | }, 334 | { 335 | "elementId": "stopNode", 336 | "stepId": "d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869", 337 | "nextStep": null 338 | }, 339 | { 340 | "elementId": "conditionNode", 341 | "stepId": "d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d", 342 | "nextSteps": [ 343 | { 344 | "nextStep": "83e1fce2-90d8-4edc-9d72-256e2e95425c", 345 | "name": "是", 346 | "isDefault": false, 347 | "ruleGroups": [] 348 | }, 349 | { 350 | "nextStep": "89bf2095-030f-4c5f-9d52-1f97cab2e295", 351 | "name": "否", 352 | "isDefault": true, 353 | "ruleGroups": [] 354 | } 355 | ], 356 | "stepName": "条件判断", 357 | "stepJson": "{}" 358 | }, 359 | { 360 | "elementId": "stopNode", 361 | "stepId": "89bf2095-030f-4c5f-9d52-1f97cab2e295", 362 | "nextStep": null 363 | }, 364 | { 365 | "elementId": "nodeNode", 366 | "stepId": "83e1fce2-90d8-4edc-9d72-256e2e95425c", 367 | "nextStep": "653742e5-ea18-4808-ae09-578a3b4667de", 368 | "stepName": "节点" 369 | }, 370 | { 371 | "elementId": "stopNode", 372 | "stepId": "653742e5-ea18-4808-ae09-578a3b4667de", 373 | "nextStep": null 374 | }, 375 | { 376 | "elementId": "conditionNode", 377 | "stepId": "b8cb3a6f-4235-4b73-af09-3288f6bebe66", 378 | "nextSteps": [ 379 | { 380 | "nextStep": "43c74167-9906-454f-b3d4-4b0687c9cb94", 381 | "name": "是", 382 | "isDefault": false, 383 | "ruleGroups": [] 384 | }, 385 | { 386 | "nextStep": "88e3aee3-d01c-432e-af05-d79d922c55df", 387 | "name": "否", 388 | "isDefault": true, 389 | "ruleGroups": [] 390 | } 391 | ], 392 | "stepName": "条件判断", 393 | "stepJson": "{}" 394 | }, 395 | { 396 | "elementId": "nodeNode", 397 | "stepId": "43c74167-9906-454f-b3d4-4b0687c9cb94", 398 | "nextStep": "35a13fb1-916e-4717-9692-96a3262e5fd4", 399 | "stepName": "节点" 400 | }, 401 | { 402 | "elementId": "stopNode", 403 | "stepId": "88e3aee3-d01c-432e-af05-d79d922c55df", 404 | "nextStep": null 405 | }, 406 | { 407 | "elementId": "conditionNode", 408 | "stepId": "35a13fb1-916e-4717-9692-96a3262e5fd4", 409 | "nextSteps": [ 410 | { 411 | "nextStep": "d1c1e591-5b3e-4128-9609-080a30d8e414", 412 | "name": "是", 413 | "isDefault": false, 414 | "ruleGroups": [] 415 | }, 416 | { 417 | "nextStep": "512f2bac-82ca-4ecc-8e71-a0171e8beb4a", 418 | "name": "否", 419 | "isDefault": true, 420 | "ruleGroups": [] 421 | } 422 | ], 423 | "stepName": "条件判断", 424 | "stepJson": "{}" 425 | }, 426 | { 427 | "elementId": "nodeNode", 428 | "stepId": "d1c1e591-5b3e-4128-9609-080a30d8e414", 429 | "nextStep": "ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c", 430 | "stepName": "节点" 431 | }, 432 | { 433 | "elementId": "stopNode", 434 | "stepId": "512f2bac-82ca-4ecc-8e71-a0171e8beb4a", 435 | "nextStep": null 436 | }, 437 | { 438 | "elementId": "stopNode", 439 | "stepId": "ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c", 440 | "nextStep": null 441 | } 442 | ] 443 | } 444 | 445 | 446 | export const workflowItem3 = { 447 | positions: "{\"f4d316b7-b2d1-46bf-aeaa-42525c84726f\":{\"left\":801,\"top\":30},\"c89829f5-8595-458c-b040-4ff84d27befc\":{\"left\":801,\"top\":150},\"7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5\":{\"left\":800,\"top\":271},\"85c30556-75fa-441c-9a1d-0dced21755a5\":{\"left\":1246,\"top\":261},\"23220649-1dcd-4bdc-af43-a6f80800b80c\":{\"left\":720,\"top\":391},\"da100cd2-a2fd-4967-911f-3acb1036d249\":{\"left\":880,\"top\":391},\"4829e3d8-b45a-4719-abdb-518df7e383ea\":{\"left\":1166,\"top\":381},\"70712f8b-d164-4224-89fd-983a9a20f6b7\":{\"left\":1326,\"top\":381},\"9fa174ae-97b3-41b6-a9a5-9e6189561b85\":{\"left\":720,\"top\":511},\"996c2224-7ae3-43fe-ba3c-8b0c33f8a632\":{\"left\":640,\"top\":631},\"d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869\":{\"left\":800,\"top\":631},\"d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d\":{\"left\":640,\"top\":751},\"89bf2095-030f-4c5f-9d52-1f97cab2e295\":{\"left\":720,\"top\":871},\"83e1fce2-90d8-4edc-9d72-256e2e95425c\":{\"left\":560,\"top\":871},\"653742e5-ea18-4808-ae09-578a3b4667de\":{\"left\":560,\"top\":991},\"b8cb3a6f-4235-4b73-af09-3288f6bebe66\":{\"left\":1166,\"top\":501},\"43c74167-9906-454f-b3d4-4b0687c9cb94\":{\"left\":1086,\"top\":621},\"88e3aee3-d01c-432e-af05-d79d922c55df\":{\"left\":1246,\"top\":621},\"35a13fb1-916e-4717-9692-96a3262e5fd4\":{\"left\":1086,\"top\":741},\"d1c1e591-5b3e-4128-9609-080a30d8e414\":{\"left\":1006,\"top\":861},\"512f2bac-82ca-4ecc-8e71-a0171e8beb4a\":{\"left\":1166,\"top\":861},\"ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c\":{\"left\":1006,\"top\":981},\"bda7748f-f87d-4a04-880e-eca936d59a0e\":{\"left\":174,\"top\":270},\"ccd691fc-8301-404b-847a-0304a7ef7a45\":{\"left\":-146,\"top\":390},\"9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6\":{\"left\":14,\"top\":390},\"cedce24b-b0bb-4e3c-bc08-d0a63794c16c\":{\"left\":174,\"top\":390},\"9ac93355-d562-429c-b533-f80aa73771e0\":{\"left\":334,\"top\":390},\"b5b80616-46db-433a-856c-176b2e53f3bb\":{\"left\":494,\"top\":390}}", 448 | steps: [{ 449 | "elementId": "startNode", 450 | "stepId": "f4d316b7-b2d1-46bf-aeaa-42525c84726f", 451 | "nextStep": "c89829f5-8595-458c-b040-4ff84d27befc" 452 | }, { 453 | "elementId": "switchNode", 454 | "stepId": "c89829f5-8595-458c-b040-4ff84d27befc", 455 | "nextSteps": [{ 456 | "nextStep": "bda7748f-f87d-4a04-880e-eca936d59a0e", 457 | "name": "1", 458 | "isDefault": false 459 | }, { 460 | "nextStep": "7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5", 461 | "name": "2", 462 | "isDefault": false 463 | }, {"nextStep": "85c30556-75fa-441c-9a1d-0dced21755a5", "name": "3", "isDefault": false}], 464 | "stepName": "条件分组" 465 | }, { 466 | "elementId": "conditionNode", 467 | "stepId": "7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5", 468 | "nextSteps": [{ 469 | "nextStep": "23220649-1dcd-4bdc-af43-a6f80800b80c", 470 | "name": "是", 471 | "isDefault": false, 472 | "ruleGroups": [] 473 | }, {"nextStep": "da100cd2-a2fd-4967-911f-3acb1036d249", "name": "否", "isDefault": true, "ruleGroups": []}], 474 | "stepName": "条件判断", 475 | "stepJson": "{}" 476 | }, { 477 | "elementId": "conditionNode", 478 | "stepId": "85c30556-75fa-441c-9a1d-0dced21755a5", 479 | "nextSteps": [{ 480 | "nextStep": "4829e3d8-b45a-4719-abdb-518df7e383ea", 481 | "name": "是", 482 | "isDefault": false, 483 | "ruleGroups": [] 484 | }, {"nextStep": "70712f8b-d164-4224-89fd-983a9a20f6b7", "name": "否", "isDefault": true, "ruleGroups": []}], 485 | "stepName": "条件判断", 486 | "stepJson": "{}" 487 | }, { 488 | "elementId": "nodeNode", 489 | "stepId": "23220649-1dcd-4bdc-af43-a6f80800b80c", 490 | "nextStep": "9fa174ae-97b3-41b6-a9a5-9e6189561b85", 491 | "stepName": "节点" 492 | }, { 493 | "elementId": "stopNode", 494 | "stepId": "da100cd2-a2fd-4967-911f-3acb1036d249", 495 | "nextStep": null 496 | }, { 497 | "elementId": "nodeNode", 498 | "stepId": "4829e3d8-b45a-4719-abdb-518df7e383ea", 499 | "nextStep": "b8cb3a6f-4235-4b73-af09-3288f6bebe66", 500 | "stepName": "节点" 501 | }, { 502 | "elementId": "stopNode", 503 | "stepId": "70712f8b-d164-4224-89fd-983a9a20f6b7", 504 | "nextStep": null 505 | }, { 506 | "elementId": "conditionNode", 507 | "stepId": "9fa174ae-97b3-41b6-a9a5-9e6189561b85", 508 | "nextSteps": [{ 509 | "nextStep": "996c2224-7ae3-43fe-ba3c-8b0c33f8a632", 510 | "name": "是", 511 | "isDefault": false, 512 | "ruleGroups": [] 513 | }, {"nextStep": "d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869", "name": "否", "isDefault": true, "ruleGroups": []}], 514 | "stepName": "条件判断", 515 | "stepJson": "{}" 516 | }, { 517 | "elementId": "nodeNode", 518 | "stepId": "996c2224-7ae3-43fe-ba3c-8b0c33f8a632", 519 | "nextStep": "d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d", 520 | "stepName": "节点" 521 | }, { 522 | "elementId": "stopNode", 523 | "stepId": "d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869", 524 | "nextStep": null 525 | }, { 526 | "elementId": "conditionNode", 527 | "stepId": "d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d", 528 | "nextSteps": [{ 529 | "nextStep": "83e1fce2-90d8-4edc-9d72-256e2e95425c", 530 | "name": "是", 531 | "isDefault": false, 532 | "ruleGroups": [] 533 | }, {"nextStep": "89bf2095-030f-4c5f-9d52-1f97cab2e295", "name": "否", "isDefault": true, "ruleGroups": []}], 534 | "stepName": "条件判断", 535 | "stepJson": "{}" 536 | }, { 537 | "elementId": "stopNode", 538 | "stepId": "89bf2095-030f-4c5f-9d52-1f97cab2e295", 539 | "nextStep": null 540 | }, { 541 | "elementId": "nodeNode", 542 | "stepId": "83e1fce2-90d8-4edc-9d72-256e2e95425c", 543 | "nextStep": "653742e5-ea18-4808-ae09-578a3b4667de", 544 | "stepName": "节点" 545 | }, { 546 | "elementId": "stopNode", 547 | "stepId": "653742e5-ea18-4808-ae09-578a3b4667de", 548 | "nextStep": null 549 | }, { 550 | "elementId": "conditionNode", 551 | "stepId": "b8cb3a6f-4235-4b73-af09-3288f6bebe66", 552 | "nextSteps": [{ 553 | "nextStep": "43c74167-9906-454f-b3d4-4b0687c9cb94", 554 | "name": "是", 555 | "isDefault": false, 556 | "ruleGroups": [] 557 | }, {"nextStep": "88e3aee3-d01c-432e-af05-d79d922c55df", "name": "否", "isDefault": true, "ruleGroups": []}], 558 | "stepName": "条件判断", 559 | "stepJson": "{}" 560 | }, { 561 | "elementId": "nodeNode", 562 | "stepId": "43c74167-9906-454f-b3d4-4b0687c9cb94", 563 | "nextStep": "35a13fb1-916e-4717-9692-96a3262e5fd4", 564 | "stepName": "节点" 565 | }, { 566 | "elementId": "stopNode", 567 | "stepId": "88e3aee3-d01c-432e-af05-d79d922c55df", 568 | "nextStep": null 569 | }, { 570 | "elementId": "conditionNode", 571 | "stepId": "35a13fb1-916e-4717-9692-96a3262e5fd4", 572 | "nextSteps": [{ 573 | "nextStep": "d1c1e591-5b3e-4128-9609-080a30d8e414", 574 | "name": "是", 575 | "isDefault": false, 576 | "ruleGroups": [] 577 | }, {"nextStep": "512f2bac-82ca-4ecc-8e71-a0171e8beb4a", "name": "否", "isDefault": true, "ruleGroups": []}], 578 | "stepName": "条件判断", 579 | "stepJson": "{}" 580 | }, { 581 | "elementId": "nodeNode", 582 | "stepId": "d1c1e591-5b3e-4128-9609-080a30d8e414", 583 | "nextStep": "ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c", 584 | "stepName": "节点" 585 | }, { 586 | "elementId": "stopNode", 587 | "stepId": "512f2bac-82ca-4ecc-8e71-a0171e8beb4a", 588 | "nextStep": null 589 | }, { 590 | "elementId": "stopNode", 591 | "stepId": "ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c", 592 | "nextStep": null 593 | }, { 594 | "elementId": "switchNode", 595 | "stepId": "bda7748f-f87d-4a04-880e-eca936d59a0e", 596 | "nextSteps": [{ 597 | "nextStep": "ccd691fc-8301-404b-847a-0304a7ef7a45", 598 | "name": "1", 599 | "isDefault": false 600 | }, { 601 | "nextStep": "9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6", 602 | "name": "2", 603 | "isDefault": false 604 | }, { 605 | "nextStep": "cedce24b-b0bb-4e3c-bc08-d0a63794c16c", 606 | "name": "3", 607 | "isDefault": false 608 | }, { 609 | "nextStep": "9ac93355-d562-429c-b533-f80aa73771e0", 610 | "name": "4", 611 | "isDefault": false 612 | }, {"nextStep": "b5b80616-46db-433a-856c-176b2e53f3bb", "name": "5", "isDefault": false}], 613 | "stepName": "条件分组" 614 | }, { 615 | "elementId": "tempNode", 616 | "stepId": "ccd691fc-8301-404b-847a-0304a7ef7a45", 617 | "nextStep": null 618 | }, { 619 | "elementId": "tempNode", 620 | "stepId": "9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6", 621 | "nextStep": null 622 | }, { 623 | "elementId": "tempNode", 624 | "stepId": "cedce24b-b0bb-4e3c-bc08-d0a63794c16c", 625 | "nextStep": null 626 | }, { 627 | "elementId": "tempNode", 628 | "stepId": "9ac93355-d562-429c-b533-f80aa73771e0", 629 | "nextStep": null 630 | }, {"elementId": "tempNode", "stepId": "b5b80616-46db-433a-856c-176b2e53f3bb", "nextStep": null}] 631 | } 632 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . -------------------------------------------------------------------------------- /dist/js/app.ed3bd818.js: -------------------------------------------------------------------------------- 1 | (function(t){function e(e){for(var o,s,l=e[0],r=e[1],d=e[2],u=0,f=[];u-1}function y(t,e){try{return window.getComputedStyle?window.getComputedStyle(t,null)[e]:t.currentStyle[e]}catch(n){return null}}function N(t){var e=y(t,"width");return"auto"===e&&(e=t.offsetWidth),parseFloat(e)}var C=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[t._l(t.flowAllList,(function(e){return[n("div",{staticClass:"items-box"},[t._l(e.children,(function(o,i){return[e.type===t.flowTypeConstant.action?[o.hidden?t._e():n("div",{staticClass:"node",on:{click:function(e){return t.handleClick(o)}}},[n("div",{staticClass:"step-img",class:o.className}),n("div",{staticClass:"step-title"},[t._v(t._s(o.name))])])]:e.type===t.flowTypeConstant.flow?[o.hidden?t._e():n("div",{staticClass:"node node-circle",on:{click:function(e){return t.handleClick(o)}}},[n("div",{staticClass:"step-img",class:o.className})])]:e.type===t.flowTypeConstant.condition?[o.hidden?t._e():n("div",{staticClass:"node-square",on:{click:function(e){return t.handleClick(o)}}},[n("div",{staticClass:"square"},[n("div",{staticClass:"step-img",class:o.className})])])]:t._e()]}))],2)]}))],2)},T=[],S={name:"ListForm",data:function(){return{flowAllList:m,flowTypeConstant:u}},methods:{handleClick:function(t){this.$emit("handleCheck",t)}}},D=S,O=(n("6523"),n("2877")),$=Object(O["a"])(D,C,T,!1,null,"1b772e52",null),_=$.exports,E=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("el-form",{ref:"dataForm",attrs:{rules:t.rules,model:t.tempItem,"label-width":"80px"}},[n("el-form-item",{attrs:{label:"名称",prop:"stepName"}},[n("el-input",{staticStyle:{width:"200px"},attrs:{size:"small"},model:{value:t.tempItem.stepName,callback:function(e){t.$set(t.tempItem,"stepName",e)},expression:"tempItem.stepName"}})],1)],1)],1)},L=[];function j(){return{stepName:"新建"}}var k={name:"StartNodeForm",props:{editItem:{type:Object}},data:function(){return{tempItem:j(),rules:{stepName:[{required:!0,trigger:"blur",message:"请填写名称"}]}}},created:function(){this.editItem&&this.editItem.stepName&&(this.tempItem=w(this.editItem))},methods:{validateFormData:function(){var t=this;return new Promise((function(e,n){t.$refs["dataForm"].validate((function(t){t?e():n()}))}))},formData:function(){var t=w(this.tempItem);return t}}},M=k,P=Object(O["a"])(M,E,L,!1,null,"9a7d79b6",null),U=P.exports,G=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("el-form",{ref:"dataForm",attrs:{rules:t.rules,model:t.tempItem,"label-width":"80px"}},[n("el-form-item",{attrs:{label:"名称",prop:"stepName"}},[n("el-input",{staticStyle:{width:"200px"},attrs:{size:"small"},model:{value:t.tempItem.stepName,callback:function(e){t.$set(t.tempItem,"stepName",e)},expression:"tempItem.stepName"}})],1)],1)],1)},B=[];function A(){return{stepName:"节点"}}var R={name:"nodeNodeForm",props:{editItem:{type:Object}},data:function(){return{tempItem:A(),rules:{stepName:[{required:!0,trigger:"blur",message:"请填写名称"}]}}},created:function(){this.editItem&&this.editItem.stepName&&(this.tempItem=w(this.editItem))},methods:{validateFormData:function(){var t=this;return new Promise((function(e,n){t.$refs["dataForm"].validate((function(t){t?e():n()}))}))},formData:function(){var t=w(this.tempItem);return t}}},J=R,V=Object(O["a"])(J,G,B,!1,null,"f5f0e5f8",null),q=V.exports,z=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"if-node-form"},[n("el-form",{ref:"dataForm",attrs:{rules:t.rules,model:t.tempItem,"label-width":"80px"}},[n("el-form-item",{attrs:{label:"步骤名称",prop:"stepName"}},[n("el-input",{staticStyle:{width:"200px"},attrs:{size:"small"},model:{value:t.tempItem.stepName,callback:function(e){t.$set(t.tempItem,"stepName",e)},expression:"tempItem.stepName"}})],1)],1)],1)},H=[];function X(){return{stepName:"条件判断"}}var Y={name:"IfNodeForm",props:{editItem:{type:Object}},created:function(){if(this.editItem&&this.editItem.stepName){var t=w(this.editItem);this.updateData(t)}this.init()},data:function(){return{tempItem:X(),rules:{stepName:[{required:!0,trigger:"blur",message:"请填写名称"}]}}},methods:{init:function(){},updateData:function(t){this.tempItem.stepName=t.stepName},validateFormData:function(){var t=this;return new Promise((function(e,n){t.$refs["dataForm"].validate((function(t){t?e():n()}))}))},formData:function(){var t=w(this.tempItem);return t}}},W=Y,K=Object(O["a"])(W,z,H,!1,null,"783c604f",null),Q=K.exports,Z=function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",[n("el-form",{ref:"dataForm",attrs:{rules:t.rules,model:t.tempItem,"label-width":"80px"}},[n("el-form-item",{attrs:{label:"步骤名称",prop:"stepName"}},[n("el-input",{staticStyle:{width:"200px"},attrs:{size:"small"},model:{value:t.tempItem.stepName,callback:function(e){t.$set(t.tempItem,"stepName",e)},expression:"tempItem.stepName"}})],1),n("el-form-item",{attrs:{label:"分支",prop:"stepName"}},[t._l(t.tempItem.ruleGroupList,(function(e,o){return[n("div",{staticClass:"expand-item"},[n("span",{staticClass:"expand-title"},[t._v("分支"+t._s(o+1)+" ")]),n("span",{staticClass:"expand-content"},[n("el-input",{attrs:{size:"small",placeholder:"placeholder"},model:{value:e.name,callback:function(n){t.$set(e,"name",n)},expression:"ruleItem.name"}})],1),n("span",{staticClass:"el-icon-btn el-icon-remove",attrs:{title:"删除分支"},on:{click:function(e){return t.handleRemoveRuleGroup(o)}}})])]})),n("div",{staticClass:"el-icon-btn rule-content-tips el-icon-circle-plus",attrs:{title:"创建分支"},on:{click:t.handleCreateRuleGroup}})],2)],1)],1)},tt=[];function et(){return{stepName:"条件分组",ruleGroupList:[{name:""}]}}var nt={name:"ExpandNodeForm",props:{editItem:{type:Object}},data:function(){return{tempItem:et(),rules:{stepName:[{required:!0,trigger:"blur",message:"请填写名称"}]}}},created:function(){if(this.editItem&&this.editItem.stepName){var t=w(this.editItem);this.updateData(t)}},methods:{updateData:function(t){this.tempItem=t},validateFormData:function(){var t=this;return new Promise((function(e,n){t.$refs["dataForm"].validate((function(t){t?e():n()}))}))},formData:function(){var t=w(this.tempItem);return t},handleCreateRuleGroup:function(){this.tempItem.ruleGroupList.push({name:""})},handleRemoveRuleGroup:function(t){this.tempItem.ruleGroupList.splice(t,1),0===this.tempItem.ruleGroupList.length&&this.handleCreateRuleGroup()},_message:function(t,e){this.$message({type:e||"error",message:t})}}},ot=nt,it=(n("5052"),Object(O["a"])(ot,Z,tt,!1,null,"c2eb94a2",null)),at=it.exports,st={positions:'{"f4d316b7-b2d1-46bf-aeaa-42525c84726f":{"left":801,"top":30},"c89829f5-8595-458c-b040-4ff84d27befc":{"left":801,"top":150},"7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5":{"left":800,"top":271},"85c30556-75fa-441c-9a1d-0dced21755a5":{"left":1246,"top":261},"23220649-1dcd-4bdc-af43-a6f80800b80c":{"left":720,"top":391},"da100cd2-a2fd-4967-911f-3acb1036d249":{"left":880,"top":391},"4829e3d8-b45a-4719-abdb-518df7e383ea":{"left":1166,"top":381},"70712f8b-d164-4224-89fd-983a9a20f6b7":{"left":1326,"top":381},"9fa174ae-97b3-41b6-a9a5-9e6189561b85":{"left":720,"top":511},"996c2224-7ae3-43fe-ba3c-8b0c33f8a632":{"left":640,"top":631},"d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869":{"left":800,"top":631},"d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d":{"left":640,"top":751},"89bf2095-030f-4c5f-9d52-1f97cab2e295":{"left":720,"top":871},"83e1fce2-90d8-4edc-9d72-256e2e95425c":{"left":560,"top":871},"653742e5-ea18-4808-ae09-578a3b4667de":{"left":560,"top":991},"b8cb3a6f-4235-4b73-af09-3288f6bebe66":{"left":1166,"top":501},"43c74167-9906-454f-b3d4-4b0687c9cb94":{"left":1086,"top":621},"88e3aee3-d01c-432e-af05-d79d922c55df":{"left":1246,"top":621},"35a13fb1-916e-4717-9692-96a3262e5fd4":{"left":1086,"top":741},"d1c1e591-5b3e-4128-9609-080a30d8e414":{"left":1006,"top":861},"512f2bac-82ca-4ecc-8e71-a0171e8beb4a":{"left":1166,"top":861},"ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c":{"left":1006,"top":981},"bda7748f-f87d-4a04-880e-eca936d59a0e":{"left":174,"top":270},"ccd691fc-8301-404b-847a-0304a7ef7a45":{"left":-146,"top":390},"9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6":{"left":14,"top":390},"cedce24b-b0bb-4e3c-bc08-d0a63794c16c":{"left":174,"top":390},"9ac93355-d562-429c-b533-f80aa73771e0":{"left":334,"top":390},"b5b80616-46db-433a-856c-176b2e53f3bb":{"left":494,"top":390}}',steps:[{elementId:"startNode",stepId:"f4d316b7-b2d1-46bf-aeaa-42525c84726f",nextStep:"c89829f5-8595-458c-b040-4ff84d27befc"},{elementId:"switchNode",stepId:"c89829f5-8595-458c-b040-4ff84d27befc",nextSteps:[{nextStep:"bda7748f-f87d-4a04-880e-eca936d59a0e",name:"1",isDefault:!1},{nextStep:"7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5",name:"2",isDefault:!1},{nextStep:"85c30556-75fa-441c-9a1d-0dced21755a5",name:"3",isDefault:!1}],stepName:"条件分组"},{elementId:"conditionNode",stepId:"7bd4fc3d-c3b9-4b19-81dc-e49cd1e7b5c5",nextSteps:[{nextStep:"23220649-1dcd-4bdc-af43-a6f80800b80c",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"da100cd2-a2fd-4967-911f-3acb1036d249",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"conditionNode",stepId:"85c30556-75fa-441c-9a1d-0dced21755a5",nextSteps:[{nextStep:"4829e3d8-b45a-4719-abdb-518df7e383ea",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"70712f8b-d164-4224-89fd-983a9a20f6b7",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"nodeNode",stepId:"23220649-1dcd-4bdc-af43-a6f80800b80c",nextStep:"9fa174ae-97b3-41b6-a9a5-9e6189561b85",stepName:"节点"},{elementId:"stopNode",stepId:"da100cd2-a2fd-4967-911f-3acb1036d249",nextStep:null},{elementId:"nodeNode",stepId:"4829e3d8-b45a-4719-abdb-518df7e383ea",nextStep:"b8cb3a6f-4235-4b73-af09-3288f6bebe66",stepName:"节点"},{elementId:"stopNode",stepId:"70712f8b-d164-4224-89fd-983a9a20f6b7",nextStep:null},{elementId:"conditionNode",stepId:"9fa174ae-97b3-41b6-a9a5-9e6189561b85",nextSteps:[{nextStep:"996c2224-7ae3-43fe-ba3c-8b0c33f8a632",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"nodeNode",stepId:"996c2224-7ae3-43fe-ba3c-8b0c33f8a632",nextStep:"d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d",stepName:"节点"},{elementId:"stopNode",stepId:"d2a791f1-7bd7-4cde-ab7c-2e8fab3bb869",nextStep:null},{elementId:"conditionNode",stepId:"d5ba66cb-7ddb-4dbc-ad44-fe27570cc90d",nextSteps:[{nextStep:"83e1fce2-90d8-4edc-9d72-256e2e95425c",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"89bf2095-030f-4c5f-9d52-1f97cab2e295",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"stopNode",stepId:"89bf2095-030f-4c5f-9d52-1f97cab2e295",nextStep:null},{elementId:"nodeNode",stepId:"83e1fce2-90d8-4edc-9d72-256e2e95425c",nextStep:"653742e5-ea18-4808-ae09-578a3b4667de",stepName:"节点"},{elementId:"stopNode",stepId:"653742e5-ea18-4808-ae09-578a3b4667de",nextStep:null},{elementId:"conditionNode",stepId:"b8cb3a6f-4235-4b73-af09-3288f6bebe66",nextSteps:[{nextStep:"43c74167-9906-454f-b3d4-4b0687c9cb94",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"88e3aee3-d01c-432e-af05-d79d922c55df",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"nodeNode",stepId:"43c74167-9906-454f-b3d4-4b0687c9cb94",nextStep:"35a13fb1-916e-4717-9692-96a3262e5fd4",stepName:"节点"},{elementId:"stopNode",stepId:"88e3aee3-d01c-432e-af05-d79d922c55df",nextStep:null},{elementId:"conditionNode",stepId:"35a13fb1-916e-4717-9692-96a3262e5fd4",nextSteps:[{nextStep:"d1c1e591-5b3e-4128-9609-080a30d8e414",name:"是",isDefault:!1,ruleGroups:[]},{nextStep:"512f2bac-82ca-4ecc-8e71-a0171e8beb4a",name:"否",isDefault:!0,ruleGroups:[]}],stepName:"条件判断",stepJson:"{}"},{elementId:"nodeNode",stepId:"d1c1e591-5b3e-4128-9609-080a30d8e414",nextStep:"ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c",stepName:"节点"},{elementId:"stopNode",stepId:"512f2bac-82ca-4ecc-8e71-a0171e8beb4a",nextStep:null},{elementId:"stopNode",stepId:"ccf0d71b-a81e-47f6-80f6-ec3dfb270f9c",nextStep:null},{elementId:"switchNode",stepId:"bda7748f-f87d-4a04-880e-eca936d59a0e",nextSteps:[{nextStep:"ccd691fc-8301-404b-847a-0304a7ef7a45",name:"1",isDefault:!1},{nextStep:"9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6",name:"2",isDefault:!1},{nextStep:"cedce24b-b0bb-4e3c-bc08-d0a63794c16c",name:"3",isDefault:!1},{nextStep:"9ac93355-d562-429c-b533-f80aa73771e0",name:"4",isDefault:!1},{nextStep:"b5b80616-46db-433a-856c-176b2e53f3bb",name:"5",isDefault:!1}],stepName:"条件分组"},{elementId:"tempNode",stepId:"ccd691fc-8301-404b-847a-0304a7ef7a45",nextStep:null},{elementId:"tempNode",stepId:"9f0a671f-5fa4-4e2b-84d0-3f157a7f5da6",nextStep:null},{elementId:"tempNode",stepId:"cedce24b-b0bb-4e3c-bc08-d0a63794c16c",nextStep:null},{elementId:"tempNode",stepId:"9ac93355-d562-429c-b533-f80aa73771e0",nextStep:null},{elementId:"tempNode",stepId:"b5b80616-46db-433a-856c-176b2e53f3bb",nextStep:null}]},lt=n("e193"),rt=n("2ef0"),dt=n.n(rt),ct=[],ut={animation:0,group:"description",disabled:!1,ghostClass:"sortable-ghost"},ft=120,pt=80,mt=130,ht=30,vt=30,wt=st,gt={name:"Workflow",jsPlumb:null,data:function(){return{flowTypeConstant:u,flowItemTypeConstant:f,flowAllList:m,jsPlumbInit:!1,dialogObj:{visible:!1,editType:void 0,flowUUid:void 0,editForm:void 0,isBetween:!1,flowPreUuid:void 0,flowNextUuid:void 0},dialogVisible:!1,flowList:[],dragConfig:ut,movingFlowItem:void 0,movedFlowItem:void 0,canvasDataRoom:100,canvasDataCursor:"grab",canvasData:{left:0,top:0},toggleGridLine:!0,toggleAutoSort:!0,canUndo:!1,tempLayerMap:[],tempMouse:{x:0,y:0,dragging:!1}}},components:{Draggable:c["a"],ListForm:_,StartNodeForm:U,NodeNodeForm:q,IfNodeForm:Q,ExpandNodeForm:at},mounted:function(){this.$options.jsPlumb=lt["jsPlumb"].getInstance(),this.initJsPlumb(),wt.steps.length>0?this.updateFlow(wt,this.$_updatePositionByAutoSort):this.initFlow(),window.addEventListener("mouseup",this.handleCanvasMouseUp)},computed:{dialogFlowItemComponent:function(){return this.dialogObj.editType+"Form"},canvasRoomMinusEnable:function(){return this.canvasDataRoom>50},canvasRoomPlusEnable:function(){return this.canvasDataRoom<100},canvasRoomScaleStyle:function(){return{transform:"scale("+this.canvasDataRoom/100+")",left:this.canvasData.left+"px",top:this.canvasData.top+"px"}},canvasRoomCursorStyle:function(){return{cursor:this.tempMouse.dragging?"grabbing":"grab"}},toggleGridLineClass:function(){return this.toggleGridLine?"icon-wangge-open":"icon-wangge-close"},toggleSortClass:function(){return this.toggleAutoSort?"icon-auto-sort-open":"icon-auto-sort-close"}},methods:{initFlow:function(){var t=this.createFlowItem(f.startNode);this.addTempFlowItem(t)},updateFlow:function(t,e){var n=this,o=JSON.parse(t.positions),i=t.steps,a=[];i.forEach((function(t){var e=n.getFlowItemById(t.elementId);if(e){e.next=[],e.prev=[],e.uuid=t.stepId;var i=o[t.stepId];if(i&&(e.left=i.left,e.top=i.top),t.nextStep?e.next=[t.nextStep]:t.nextSteps&&(e.next=t.nextSteps.map((function(t){return t.nextStep}))),e.type!==f.endNode)if(n.isIfFlowItem(e.type)){var s=w(t.nextSteps[0]);if(s.stepName=t.stepName,e.formData=n.getFlowItemFormData(s),s.isDefault?(e.nextElseId=s.nextStep,e.nextIfId=t.nextSteps[1].nextStep):(e.nextIfId=s.nextStep,e.nextElseId=t.nextSteps[1].nextStep),t.stepJson){var l=JSON.parse(t.stepJson);e.formData.ifNodeTitle=l.ifNodeTitle}}else if(n.isExpandFlowItem(e.type)){var r=t.nextSteps,d={};d.stepName=t.stepName,d.ruleGroupList=r,e.formData=d}else e.formData=n.getFlowItemFormData(t);a.push(e)}})),a.forEach((function(t){t.next.length>0&&t.next.forEach((function(e){var n=dt.a.find(a,(function(t){return t.uuid===e}));n&&-1===n.prev.indexOf(t.uuid)&&n.prev.push(t.uuid)}))})),a.forEach((function(t){if(n.isIfFlowItem(t.type)){var e=dt.a.find(a,(function(e){return e.uuid===t.nextIfId})),o=dt.a.find(a,(function(e){return e.uuid===t.nextElseId}));e.left10&&ct.shift(),ct.push(t),this.$_updateCanUndoBtn()},$_sortFlowItemNext:function(t){var e=this,n=this.getFlow(t.prev[0]);if(this.isExpandFlowItem(n.type)){var o=n.next.map((function(t){return e.getFlow(t)}));o.sort((function(t,e){return t.left-e.left})),n.next=o.map((function(t){return t.uuid}))}else if(this.isIfFlowItem(n.type)){var i=this.getFlow(n.nextIfId),a=this.getFlow(n.nextElseId);i.left0},initJsPlumb:function(){var t=this;this.$options.jsPlumb.ready((function(){t.jsPlumbInit=!0,t.$options.jsPlumb.importDefaults({ConnectionsDetachable:!1,LogEnabled:!0})}))},createFlowConnectionLabel:function(t,e){var n=this;Array.isArray(t)||(t=[t]),t.forEach((function(t){var o=n.$options.jsPlumb.getConnections({source:t,target:e});o.forEach((function(t){t.getOverlay("nodeTempSmall").setVisible(!0),t.bind("click",n.handleFlowLabelClick)}))}))},createFlowItemLabel:function(t,e,n){var o=this;this.$nextTick((function(){var i=o.$options.jsPlumb.getConnections({source:t,target:e});i.length>0&&i[0].getOverlay("flowItemDesc").setLabel('').concat(n,""))}))},removeFlowConnection:function(t,e){var n=this,o=this.$options.jsPlumb.getConnections({source:t,target:e});o.forEach((function(t){n.$options.jsPlumb.deleteConnection(t)}))},handleFlowLabelClick:function(t){var e=t.component;if(e){var n=e.sourceId,o=e.targetId;this.showDialog({isBetween:!0,flowPreUuid:n,flowNextUuid:o})}},handleEditFlowItem:function(t,e){var n=e.currentTarget;"true"===n.dataset.isClick&&this.showDialog({flowItemType:t.type,flowUuid:t.uuid,flowFormData:t.formData})},draggableFlowConnect:function(t,e,n){var o=this;function i(){o.jsPlumbInit&&o.$options.jsPlumb.connect({source:t,target:e,endpoint:"Dot",connectorStyle:{strokeStyle:"#ccc",joinStyle:"round",outlineColor:"#ccc"},connector:["Flowchart",{stub:[10,20],gap:1,cornerRadius:2,alwaysRespectStubs:!0}],endpointStyle:{fill:"transparent",outlineStroke:"transparent",outlineWidth:2},paintStyle:{stroke:"lightgray",strokeWidth:2},anchor:["BottomCenter","TopCenter"],overlays:[["PlainArrow",{width:10,length:10,location:1}],["Custom",{location:.5,id:"nodeTempSmall",create:function(){var n=o.$refs[e][0].$el;return n.dataset.target=e,n.dataset.source=t,n},visible:!1}],["Label",{location:1,id:"flowItemDesc",cssClass:"node-item-label",visible:!0}]]})}n?i():this.$nextTick((function(){i()}))},getFlowItemInitLeft:function(){var t=this.$refs.campaignCanvas,e=N(t),n=500;return e&&(n=e/2),n},createFlowItem:function(t,e,n){var o=this;n=n||{};var i=v(),a=this.getFlowItemByType(t),s=[];if(a){if(a.prev=[],a.next=[],a.formData={},a.left=this.getFlowItemInitLeft(),a.top=vt,a.uuid=i,e&&(Array.isArray(e)||(e=[e]),a.prev=e,e.forEach((function(t){var e=dt.a.find(o.flowList,(function(e){return e.uuid===t}));e&&(s.push(e),-1===e.next.indexOf(i)&&(dt.a.isUndefined(n.index)||-1===n.index?e.next.push(i):e.next.splice(n.index,0,i)))}))),s.length>0&&1===s.length){var l=s[0];n.offsetLeft?a.left=l.left+n.offsetLeft:n.left?a.left=n.left:a.left=l.left,a.top=l.top+ft}this.flowList.push(a),this.$nextTick((function(){o.$options.jsPlumb.draggable(i,{})}))}return a?i:null},updateFlowItem:function(t,e){var n=this.getFlow(e),o=this.getFlowItemByType(t);for(var i in o)n[i]=o[i];return n},deleteFlowItem:function(t){if(this.isOnePreOneNext(t)||this.isEndFlowItem(t)){var e=this.getFlowIndex(t.uuid);this.handleDeleteOnePrevOneNextFlowItem(t,e)}else if(this.isHasMoreNextFlowItem(t)){this.deleteNextFlowItem(t.uuid);var n=this.getFlow(t.prev[0]);if(this.isIfFlowItem(n.type))this.addIfOneTempFlowItem(n.uuid,n.nextIfId===t.uuid);else if(this.isExpandFlowItem(n.type)){var o=this.getExpandFlowItem(n,t.uuid);this.addExpandOneTempFlowItem(n,t.left,o.name)}else this.addTempFlowItem(t.prev[0])}},handleDeleteOnePrevOneNextFlowItem:function(t,e){var n=[],o=[],i=this.flowList[e];this.flowList.forEach((function(e){e.prev.length>0&&-1!==e.prev.indexOf(t.uuid)?o.push(e):e.next.length>0&&-1!==e.next.indexOf(t.uuid)&&n.push(e)}));var a={};t.type===f.endNode&&n[0].type===f.expandNode&&(a=this.getExpandFlowItem(n[0],t.uuid));var s=-1;o.forEach((function(e){var n=e.prev.indexOf(t.uuid);s=n,e.prev.splice(n,1)}));var l=-1;n.forEach((function(e){var n=e.next.indexOf(t.uuid);l=n,e.next.splice(n,1)})),this.$options.jsPlumb.removeAllEndpoints(t.uuid,!0),this.flowList.splice(e,1),this.$nextTick((function(){var e=this,r=n[0],d=o[0];if(r&&d)if(-1!==l?r.next.splice(l,0,d.uuid):r.next.push(d.uuid),-1!==s?d.prev.splice(s,0,r.uuid):d.prev.push(r.uuid),this.draggableFlowConnect(r.uuid,d.uuid,!0),d.type!==f.tempNode&&this.createFlowConnectionLabel(r.uuid,d.uuid),this.isIfFlowItem(r.type)){var c=r.nextIfId===t.uuid;c?r.nextIfId=d.uuid:r.nextElseId=d.uuid,this.createFlowItemLabel(r.uuid,d.uuid,c?"是":"否")}else if(this.isExpandFlowItem(r.type)){var u=this.getExpandFlowItem(r,i.uuid);u&&(u.nextStep=d.uuid),this.createFlowItemLabel(r.uuid,d.uuid,u.name)}if(t.type===f.endNode&&r)if(this.isIfFlowItem(r.type)){var p=r.nextIfId===t.uuid;this.addIfOneTempFlowItem(r.uuid,p)}else if(this.isExpandFlowItem(r.type)){var m=this.addExpandOneTempFlowItem(r,t.left,a.name);a.nextStep=m}else this.addTempFlowItem(r.uuid);this.$nextTick((function(){d&&(e.moveFlowItem(d.uuid),e.$_plumbRepaintEverything())}))}))},$_plumbRepaintEverything:function(){var t=this;this.$nextTick((function(){t.$options.jsPlumb.repaintEverything(!0)}))},getFlowItemById:function(t){var e=null;return Object.keys(p).forEach((function(n){var o=p[n];if(o&&o.length>0){var i=dt.a.find(o,(function(e){return e.id===t}));i&&(e=w(i))}})),e},getFlowItemByType:function(t){var e=null;return Object.keys(p).forEach((function(n){var o=p[n];if(o&&o.length>0){var i=dt.a.find(o,(function(e){return e.type===t}));i&&(e=w(i))}})),e},handleFlowMoveItem:function(t){var e=t.to,n=t.dragged;if(n.dataset.id===f.startNode)return!1;this.movedFlowItem?this.movedFlowItem&&this.movedFlowItem!==e&&(x(this.movedFlowItem,"is-active"),this.movedFlowItem=e,I(e,"is-active")):(this.movedFlowItem=e,I(e,"is-active"))},handleDeleteFlowItem:function(t){var e=this;this.$confirm("确定要删除吗?Tips: ifNode 和 expandNode 会删除下面所有节点","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((function(){e.$_updateMemoryList(),e.deleteFlowItem(t),e.$_updatePositionByAutoSort()})).catch((function(t){console.warn(t)}))},handleFlowMoveStart:function(t){var e=t.item,n=e.dataset;this.movingFlowItem={group:n.group,type:n.type}},handleFlowMoveEnd:function(t){var e=t.originalEvent;if(this.movedFlowItem){if(x(this.movedFlowItem,"is-active"),e.toElement!==this.movedFlowItem)return this.movedFlowItem=void 0,void(this.movingFlowItem=void 0);var n={flowItemType:this.movingFlowItem.type,flowUuid:this.movedFlowItem.id};this.movedFlowItem.dataset.source&&this.movedFlowItem.dataset.target&&(n.isBetween=!0,n.flowPreUuid=this.movedFlowItem.dataset.source,n.flowNextUuid=this.movedFlowItem.dataset.target,delete n.flowUuid),this.showDialog(n)}this.movedFlowItem=void 0,this.movingFlowItem=void 0},handleSelectFlowItem:function(t){var e=this;if(t.type!==f.endNode)this.showDialog({flowItemType:t.type,flowUuid:this.dialogObj.flowUUid});else{if(this.$_updateMemoryList(),this.dialogObj.isBetween){var n=this.dialogObj.flowPreUuid,o=this.dialogObj.flowNextUuid,i=this.getFlow(n),a={};if(this.isHasMoreNextFlowItemByType(i.type)){var s=this.getFlow(o);a.left=s.left}this.deleteNextFlowItem(o),this.$nextTick((function(){var o=e.addTempFlowItem(n,a);e.$nextTick((function(){e.handleAddFlowItem(t.type,o)}))}))}else this.handleAddFlowItem(t.type,this.dialogObj.flowUUid);this.initDialog()}},handleAddFlowItem:function(t,e){var n=this.updateFlowItem(t,e);if(this.createFlowConnectionLabel(n.prev,n.uuid),this.isOnePreOneNext(n))this.addTempFlowItem(e);else if(n.groupType===u.condition){var o=this.getFlow(n.prev[0]);if(this.isIfFlowItem(t))this.isIfFlowItem(o.type)&&(o.nextIfId===n.uuid?n.left-=ht:o.nextElseId===n.uuid&&(n.left+=ht)),this.addIfTempFlowItem(e);else if(this.isExpandFlowItem(t)){if(this.isIfFlowItem(o.type)){var i=n.formData.ruleGroupList.length,a=i%2===0,s=parseInt(i/2,10),l=(a?s:s+1)*pt+ht;o.nextIfId===n.uuid?n.left-=l:o.nextElseId===n.uuid&&(n.left+=l)}this.addExpandTempFlowItem(e,n.formData.ruleGroupList)}}return n},handleUpdateFlowItem:function(t){var e=this,n=t.flowItemType,o=t.tempFlowId,i=this.getFlow(o),a=!1,s=this.updateFlowItem(n,o);if(n!==i.type)this.isHasMoreNextFlowItem(i)&&(a=!0,i.next.forEach((function(t){e.deleteNextFlowItem(t)}))),this.isIfFlowItem(n)?this.handleUpdateIfFlowItem(s):this.isExpandFlowItem(n)?this.handleUpdateExpandFlowItem(s):a&&this.addTempFlowItem(s.uuid);else if(this.isExpandFlowItem(n)){var l=s.formData.ruleGroupList,r=s.next,d=[],c=[],u=[];if(l.forEach((function(t){var n=t.nextStep;n?(d.push(n),e.createFlowItemLabel(s.uuid,n,t.name)):c.push(t)})),u=dt.a.difference(r,d),u.length>0&&(s.next=d,u.forEach((function(t){e.deleteNextFlowItem(t)}))),c.length>0){var p=0;s.next.forEach((function(t){var n=e.getFlow(t);p0){var o=this.getFlow(n.prev[0]);n.top=o.top+ft}n.next.forEach((function(t){e.moveFlowItem(t)}))},deleteNextFlowItem:function(t){var e=this,n=this.getFlow(t),o=this.getFlowIndex(t);if(n){if(n.prev[0]){var i=this.getFlow(n.prev[0]);if(i){var a=i.next.indexOf(t);-1!==a&&i.next.splice(a,1)}}this.flowList.splice(o,1),this.$nextTick((function(){e.$options.jsPlumb.removeAllEndpoints(n.uuid)})),n.next.forEach((function(t){e.deleteNextFlowItem(t)}))}},getFlow:function(t){var e=dt.a.find(this.flowList,(function(e){return e.uuid===t}));return e},getFlowIndex:function(t){var e=dt.a.findIndex(this.flowList,(function(e){return e.uuid===t}));return e},addTempFlowItem:function(t,e){var n=this.createFlowItem(f.tempNode,t,e);return this.draggableFlowConnect(t,n),n},addIfTempFlowItem:function(t){this.addIfOneTempFlowItem(t,!0),this.addIfOneTempFlowItem(t,!1)},addIfOneTempFlowItem:function(t,e){var n=this.getFlow(t),o=e?-pt:pt,i=this.createFlowItem(f.tempNode,t,{offsetLeft:o});return this.draggableFlowConnect(t,i),this.createFlowItemLabel(t,i,e?"是":"否"),e?n.nextIfId=i:n.nextElseId=i,i},addExpandTempFlowItem:function(t,e){var n,o=e.length,i=o%2===0,a=parseInt(o/2,10);a=i?a-1:a;for(var s={},l=0;l<=a;l++){n=e[l];var r=a-l,d=r*(2*pt);i&&(d+=pt),s.offsetLeft=-d;var c=this.createFlowItem(f.tempNode,t,s);this.draggableFlowConnect(t,c),this.createFlowItemLabel(t,c,n.name),n.nextStep=c}for(var u=a+1;u1)if(t.isIfFlowItem(e.type)){var a=e.formData.ruleGroups||[],s={nextStep:e.nextIfId,name:"是",isDefault:!1,ruleGroups:a},l={nextStep:e.nextElseId,name:"否",isDefault:!0,ruleGroups:[]};i.nextSteps=[s,l],i.stepName=e.formData.stepName,i.stepJson=JSON.stringify({ifNodeTitle:e.formData.ifNodeTitle})}else if(t.isExpandFlowItem(e.type)){var r=e.formData.ruleGroupList,d=[];r.forEach((function(t){var e={nextStep:t.nextStep,name:t.name,ruleGroups:t.ruleGroups,isDefault:!!t.isDefault};d.push(e)})),i.nextSteps=d,i.stepName=e.formData.stepName}else i.nextSteps=e.next.map((function(t){return{nextStep:t}}));else i.nextStep=e.next[0]||null;t.isIfFlowItem(e.type)||t.isExpandFlowItem(e.type)||(i=Object.assign(i,e.formData)),o.push(i),n[e.uuid]={left:e.left,top:e.top}})),e.positions=JSON.stringify(n),e.steps=o,e},handleMinusCanvas:function(){this.canvasDataRoom<=50||(this.canvasDataRoom=this.canvasDataRoom-10)},handlePlusCanvas:function(){100!==this.canvasDataRoom&&(this.canvasDataRoom=this.canvasDataRoom+10)},handleCanvasMouseDown:function(t){var e=g(t),n=e.posX,o=e.posY;this.tempMouse.x=n,this.tempMouse.y=o,this.tempMouse.dragging=!0},handleCanvasMouseUp:function(t){this.tempMouse.dragging&&(this.tempMouse={x:0,y:0,dragging:!1})},handleCanvasMouseMove:function(t){if(this.tempMouse.dragging){var e=g(t),n=e.posX,o=e.posY,i=this.tempMouse.x-n,a=this.tempMouse.y-o;this.canvasData.left=this.canvasData.left-i,this.canvasData.top=this.canvasData.top-a,this.tempMouse.x=n,this.tempMouse.y=o}},handleSort:function(){this.$_updatePosition()},handleClear:function(){var t=this;this.$confirm("确定要清空数据,重做吗?","提示",{confirmButtonText:"确定",cancelButtonText:"取消",type:"warning"}).then((function(){t.$_doClear(!0)})).catch((function(){}))},handleToggleAutoSort:function(){this.toggleAutoSort=!this.toggleAutoSort,this.$_updatePositionByAutoSort()},$_updatePositionByAutoSort:function(){var t=this;this.toggleAutoSort&&this.$nextTick((function(){t.$_updatePosition()}))},handleUndo:function(){var t=this;if(this.canUndo){if(ct.length>0){var e=ct.pop();this.$_doClear(),this.$options.jsPlumb.reset(),this.$nextTick((function(){t.updateFlow(e,t.$_plumbRepaintEverything)}))}this.$_updateCanUndoBtn()}},$_updatePosition:function(){var t=this;console.log("$_updatePosition"),this.tempLayerMap=[];var e=dt.a.find(this.flowList,(function(e){return t.isStartFlowItem(e)}));e.top=vt,e.left=this.getFlowItemInitLeft(),this.tempLayerMap[0]=[e],this.$_layoutChild(e,1),this.$_adjustChild();var n=this.$_getFirstLeft();if(n<0){var o=-n;this.$_offsetFlowListLeft(o)}this.$_plumbRepaintEverything()},$_getFirstLeft:function(){var t=this.flowList[0].left;return this.flowList.forEach((function(e){t>e.left&&(t=e.left)})),t},$_offsetFlowListLeft:function(t){this.flowList.forEach((function(e){e.left+=t}))},$_updateOneFlowPosition:function(t){this.isHasMoreNextFlowItemByType(t.type)},$_adjustChild:function(){for(var t=this,e=null,n=this.tempLayerMap.length-1;n>=0;n--)e=this.tempLayerMap[n],e.forEach((function(o,i){var a=e[i-1];if(a&&o.left-a.left0){if(1===t.next.length){var o=this.getFlow(t.next[0]);n=t.left-o.left}else{var i=this.getFlow(t.next[0]),a=this.getFlow(t.next[t.next.length-1]);n=t.left-(i.left+(a.left-i.left)/2)}n&&t.next.forEach((function(t){var o=e.getFlow(t);o&&e.$_translateXTree(o,n)}))}},$_translateXTree:function(t,e){var n=this;t.left+=e,t.next&&t.next.length>0&&t.next.forEach((function(t){var o=n.getFlow(t);o&&n.$_translateXTree(o,e)}))},$_findCommonParentNode:function(t,e){if(t.prev[0]===e.prev[0])return e;var n=this.getFlow(t.prev[0]),o=this.getFlow(e.prev[0]);return this.$_findCommonParentNode(n,o)},$_layoutChild:function(t,e){var n=this,o=t.next,i=o.length;void 0===this.tempLayerMap[e]&&(this.tempLayerMap[e]=[]),o.forEach((function(o,a){var s=n.getFlow(o);if(s){s.top=t.top+ft;var l=t.left-mt*(i-1)/2;s.left=l+mt*a,n.tempLayerMap[e].push(s),s.next&&s.next.length>0&&n.$_layoutChild(s,e+1)}}))},$_doClear:function(t){var e=this,n=dt.a.find(this.flowList,(function(t){return e.isStartFlowItem(t)}));n&&(this.deleteNextFlowItem(n.uuid),t&&this.$nextTick((function(){e.initFlow()})))},handleGetData:function(){var t=this,e=this.formatData();console.log("formData",JSON.stringify(e));var n=new d.a(e,3);this.dialogVisible=!0,this.$nextTick((function(){t.$refs.preShow.appendChild(n.render())}))},getFlowItemFormData:function(t){var e=w(t);return delete e.elementId,delete e.stepId,e.nextStep&&delete e.nextStep,e.nextSteps&&delete e.nextSteps,e},_message:function(t,e){this.$message({type:e||"error",message:t})},isOnePreOneNext:function(t){return t.groupType===u.action||t.type===f.waitNode},isTempFlowItem:function(t){return t.type===f.tempNode},isStartFlowItem:function(t){return t.type===f.startNode},isEndFlowItem:function(t){return t.type===f.endNode},isIfFlowItem:function(t){return t===f.ifNode},isExpandFlowItem:function(t){return t===f.expandNode},isHasMoreNextFlowItem:function(t){return this.isHasMoreNextFlowItemByType(t.type)},isHasMoreNextFlowItemByType:function(t){return this.isIfFlowItem(t)||this.isExpandFlowItem(t)},isHasStepCountFlowItem:function(t){return t.groupType===u.action||t.type===f.startNode}},beforeDestroy:function(){window.removeEventListener("mouseup",this.handleCanvasMouseUp)}},bt=gt,It=(n("d4ee"),Object(O["a"])(bt,s,l,!1,null,null,null)),xt=It.exports,Ft={name:"App",components:{Workflow:xt}},yt=Ft,Nt=Object(O["a"])(yt,i,a,!1,null,null,null),Ct=Nt.exports,Tt=n("5c96"),St=n.n(Tt);n("0fae");o["default"].config.productionTip=!1,o["default"].use(St.a),new o["default"]({render:function(t){return t(Ct)}}).$mount("#app")},6523:function(t,e,n){"use strict";var o=n("ff6f"),i=n.n(o);i.a},"83c4":function(t,e,n){},b37d:function(t,e,n){},d4ee:function(t,e,n){"use strict";var o=n("83c4"),i=n.n(o);i.a},fc80:function(t,e,n){"use strict";(function(t){n("99af"),n("4de4"),n("4160"),n("caad"),n("c975"),n("d81d"),n("a434");var o=n("2909"),i=n("53fe");function a(){return"undefined"!==typeof window?window.console:t.console}var s=a();function l(t,e,n){return void 0==n||(t=null==t?{}:t,t[e]=n),t}function r(t){null!==t.parentElement&&t.parentElement.removeChild(t)}function d(t,e,n){var o=0===n?t.children[0]:t.children[n-1].nextSibling;t.insertBefore(e,o)}function c(t,e){return t.map((function(t){return t.elm})).indexOf(e)}function u(t,e,n){if(!t)return[];var i=t.map((function(t){return t.elm})),a=Object(o["a"])(e).map((function(t){return i.indexOf(t)}));return n?a.filter((function(t){return-1!==t})):a}function f(t,e){var n=this;this.$nextTick((function(){return n.$emit(t.toLowerCase(),e)}))}function p(t){var e=this;return function(n){null!==e.realList&&e["onDrag"+t](n),f.call(e,t,n)}}function m(t){if(!t)return!1;var e=t.pull;return"function"===typeof e?"clone"===e():"clone"===e}var h=["Start","Add","Remove","Update","End"],v=["Choose","Sort","Filter","Clone"],w=["Move"].concat(h,v).map((function(t){return"on"+t})),g=null,b={options:Object,list:{type:Array,required:!1,default:null},value:{type:Array,required:!1,default:null},noTransitionOnDrag:{type:Boolean,default:!1},clone:{type:Function,default:function(t){return t}},element:{type:String,default:"div"},tag:{type:String,default:null},move:{type:Function,default:null},componentData:{type:Object,required:!1,default:null}},I={name:"draggable",inheritAttrs:!0,props:b,data:function(){return{transitionMode:!1,noneFunctionalComponentMode:!1,init:!1,isCloning:!1}},render:function(t){var e=this.$slots.default;if(e&&1===e.length){var n=e[0];n.componentOptions&&["transition-group","TransitionGroup"].includes(n.componentOptions.tag)&&(this.transitionMode=!0)}var i=0,a=e,s=this.$slots,r=s.header,d=s.footer;r&&(i=r.length,a=a?[].concat(Object(o["a"])(r),Object(o["a"])(a)):Object(o["a"])(r)),d&&(a=a?[].concat(Object(o["a"])(a),Object(o["a"])(d)):Object(o["a"])(d)),this.headerOffset=i;var c=null,u=function(t,e){c=l(c,t,e)};if(this.componentData){var f=this.componentData,p=f.on,m=f.props;u("on",p),u("props",m)}return t(this.getTag(),c,a)},created:function(){null!==this.list&&null!==this.value&&s.error("Value and list props are mutually exclusive! Please set one or another."),"div"!==this.element&&s.warn("Element props is deprecated please use tag props instead. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#element-props"),void 0!==this.options&&s.warn("Options props is deprecated, add sortable options directly as vue.draggable item, or use v-bind. See https://github.com/SortableJS/Vue.Draggable/blob/master/documentation/migrate.md#options-props")},mounted:function(){var t=this;if(this.noneFunctionalComponentMode=this.getTag().toLowerCase()!==this.$el.nodeName.toLowerCase(),this.noneFunctionalComponentMode&&this.transitionMode)throw new Error("Transition-group inside component is not supported. Please alter tag value or remove transition-group. Current tag value: ".concat(this.getTag()));var e={};h.forEach((function(n){e["on"+n]=p.call(t,n)})),v.forEach((function(n){e["on"+n]=f.bind(t,n)}));var n=Object.assign({},this.options,this.$attrs,e,{onMove:function(e,n){return t.onDragMove(e,n)}});!("draggable"in n)&&(n.draggable=">*"),this._sortable=new i(this.rootContainer,n),this.computeIndexes()},beforeDestroy:function(){void 0!==this._sortable&&this._sortable.destroy()},computed:{rootContainer:function(){return this.transitionMode?this.$el.children[0]:this.$el},realList:function(){return this.list?this.list:this.value}},watch:{options:{handler:function(t){this.updateOptions(t)},deep:!0},$attrs:{handler:function(t){this.updateOptions(t)},deep:!0},realList:function(){this.computeIndexes()}},methods:{getTag:function(){return this.tag||this.element},getIsCloning:function(){var t=this.$attrs.group,e=t||this.getOptionGroup();return m(e)},getOptionGroup:function(){var t=this.options;if(t)return t.group},updateOptions:function(t){for(var e in t)-1==w.indexOf(e)&&this._sortable.option(e,t[e])},getChildrenNodes:function(){if(this.init||(this.noneFunctionalComponentMode=this.noneFunctionalComponentMode&&1==this.$children.length,this.init=!0),this.noneFunctionalComponentMode)return this.$children[0].$slots.default;var t=this.$slots.default;return this.transitionMode?t[0].child.$slots.default:t},computeIndexes:function(){var t=this;this.$nextTick((function(){t.visibleIndexes=u(t.getChildrenNodes(),t.rootContainer.children,t.transitionMode)}))},getUnderlyingVm:function(t){var e=c(this.getChildrenNodes()||[],t);if(-1===e)return null;var n=this.realList[e];return{index:e,element:n}},getUnderlyingPotencialDraggableComponent:function(t){var e=t.__vue__;return e&&e.$options&&"transition-group"===e.$options._componentTag?e.$parent:e},emitChanges:function(t){var e=this;this.$nextTick((function(){e.$emit("change",t)}))},alterList:function(t){if(this.list)t(this.list);else{var e=Object(o["a"])(this.value);t(e),this.$emit("input",e)}},spliceList:function(){var t=arguments,e=function(e){return e.splice.apply(e,Object(o["a"])(t))};this.alterList(e)},updatePosition:function(t,e){var n=function(n){return n.splice(e,0,n.splice(t,1)[0])};this.alterList(n)},getRelatedContextFromMoveEvent:function(t){var e=t.to,n=t.related,o=this.getUnderlyingPotencialDraggableComponent(e);if(!o)return{component:o};var i=o.realList,a={list:i,component:o};if(e!==n&&i&&o.getUnderlyingVm){var s=o.getUnderlyingVm(n);if(s)return Object.assign(s,a)}return a},getVmIndex:function(t){var e=this.visibleIndexes,n=e.length;return t>n-1?n:e[t]},getComponent:function(){return this.$slots.default[0].componentInstance},resetTransitionData:function(t){if(this.noTransitionOnDrag&&this.transitionMode){var e=this.getChildrenNodes();e[t].data=null;var n=this.getComponent();n.children=[],n.kept=void 0}},onDragStart:function(t){this.context=this.getUnderlyingVm(t.item),this.isCloning=this.getIsCloning(),t.item._underlying_vm_=this.clone(this.context.element),g=t.item},onDragAdd:function(t){var e=t.item._underlying_vm_;if(void 0!==e){r(t.item);var n=this.getVmIndex(t.newIndex);this.spliceList(n,0,e),this.computeIndexes();var o={element:e,newIndex:n};this.emitChanges({added:o})}},onDragRemove:function(t){if(d(this.rootContainer,t.item,t.oldIndex),this.isCloning)r(t.clone);else{var e=this.context.index;this.spliceList(e,1);var n={element:this.context.element,oldIndex:e};this.resetTransitionData(e),this.emitChanges({removed:n})}},onDragUpdate:function(t){r(t.item),d(t.from,t.item,t.oldIndex);var e=this.context.index,n=this.getVmIndex(t.newIndex);this.updatePosition(e,n);var o={element:this.context.element,oldIndex:e,newIndex:n};this.emitChanges({moved:o})},updateProperty:function(t,e){t.hasOwnProperty(e)&&(t[e]+=this.headerOffset)},computeFutureIndex:function(t,e){if(!t.element)return 0;var n=Object(o["a"])(e.to.children).filter((function(t){return"none"!==t.style["display"]})),i=n.indexOf(e.related),a=t.component.getVmIndex(i),s=-1!=n.indexOf(g);return s||!e.willInsertAfter?a:a+1},onDragMove:function(t,e){var n=this.move;if(!n||!this.realList)return!0;var o=this.getRelatedContextFromMoveEvent(t),i=this.context,a=this.computeFutureIndex(o,t);return Object.assign(i,{futureIndex:a}),Object.assign(t,{relatedContext:o,draggedContext:i}),n(t,e)},onDragEnd:function(){this.computeIndexes(),g=null}}};e["a"]=I}).call(this,n("c8ba"))},ff6f:function(t,e,n){}}); 2 | //# sourceMappingURL=app.ed3bd818.js.map --------------------------------------------------------------------------------