demo.html 17.3 KB
<html>
<head>
    <meta charset="utf-8">
    <title>vue-flow-editor demo</title>
    <link type="text/css" rel="stylesheet" href="http://martsforever-pot.gitee.io/vue-flow-editor/dist/vue-flow-editor.css">
    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">

    <style>
        html, body {
            padding: 0;
            margin: 0;
        }
    </style>
</head>
<body>
<div id="app">

</div>
<script src="http://martsforever-pot.gitee.io/vue-flow-editor/lib/g6.umd.min.js"></script>
<script src="http://martsforever-pot.gitee.io/vue-flow-editor/lib/vue.min.js"></script>
<script src="http://martsforever-pot.gitee.io/vue-flow-editor/lib/vue-composition-api.umd.js"></script>
<script src="http://martsforever-pot.gitee.io/vue-flow-editor/lib/element-ui.js"></script>
<script src="http://martsforever-pot.gitee.io/vue-flow-editor/dist/vue-flow-editor.js"></script>
<script>

    "use strict";

    function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

    function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

    function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

    function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

    function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

    console.log(window);
    Vue.use(window.vueCompositionApi.default);
    Vue.use(window.VueFlowEditor);
    var Ele = window.ELEMENT;
    var G6 = window.G6.default;
    var reactive = window.vueCompositionApi.reactive;

    function delay(time) {
        return new Promise(function (resolve) {
            return setTimeout(resolve, time);
        });
    }

    var AppData = {
        "nodes": [{
            "data": {},
            "id": "start-node",
            "label": "开始",
            "shape": "ellipse",
            "size": [120, 40],
            "x": 380,
            "y": 100
        }, {
            "data": {},
            "id": "1588848310120",
            "label": "主管审批",
            "shape": "rect",
            "size": [120, 40],
            "x": 380,
            "y": 180
        }, {
            "data": {},
            "id": "1588848322179",
            "label": "经理审批",
            "shape": "rect",
            "size": [120, 40],
            "x": 380,
            "y": 260
        }, {
            "data": {},
            "id": "1588848338211",
            "label": "金额>2万",
            "shape": "diamond",
            "size": [120, 40],
            "x": 380,
            "y": 340
        }, {
            "data": {},
            "id": "1588848351476",
            "label": "财务打款",
            "shape": "rect",
            "size": [120, 40],
            "x": 380,
            "y": 460
        }, {
            "data": {},
            "id": "end-node",
            "label": "结束",
            "shape": "ellipse",
            "size": [120, 40],
            "x": 380,
            "y": 540
        }, {
            "data": {},
            "id": "1588848397511",
            "label": "VIP审批",
            "shape": "rect",
            "size": [120, 40],
            "x": 620,
            "y": 340
        }, {
            "data": {},
            "id": "1588848436694",
            "label": "金额>10万",
            "shape": "diamond",
            "size": [120, 40],
            "x": 780,
            "y": 340
        }, {
            "data": {},
            "id": "1588848449431",
            "label": "CEO审批",
            "shape": "rect",
            "size": [120, 40],
            "x": 980,
            "y": 460
        }],
        "edges": [{
            "shape": "flow-polyline-round",
            "source": "start-node",
            "sourceAnchor": 2,
            "target": "1588848310120",
            "targetAnchor": 0
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848310120",
            "sourceAnchor": 2,
            "target": "1588848322179",
            "targetAnchor": 0
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848322179",
            "sourceAnchor": 2,
            "target": "1588848338211",
            "targetAnchor": 0
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848338211",
            "sourceAnchor": 2,
            "target": "1588848351476",
            "targetAnchor": 0,
            "label": "否"
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848351476",
            "sourceAnchor": 2,
            "target": "end-node",
            "targetAnchor": 0
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848338211",
            "sourceAnchor": 3,
            "target": "1588848397511",
            "targetAnchor": 1,
            "label": "是"
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848436694",
            "sourceAnchor": 3,
            "target": "1588848449431",
            "targetAnchor": 0,
            "label": "是"
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848449431",
            "sourceAnchor": 1,
            "target": "1588848351476",
            "targetAnchor": 3
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848436694",
            "sourceAnchor": 2,
            "target": "1588848351476",
            "targetAnchor": 3,
            "label": "否"
        }, {
            "shape": "flow-polyline-round",
            "source": "1588848397511",
            "sourceAnchor": 3,
            "target": "1588848436694",
            "targetAnchor": 1
        }]
    };
    new Vue({
        el: '#app',
        template: "\n        <div class=\"app\" style=\"height: 100vh\">\n            <vue-flow-editor\n                    ref=\"editor\"\n                    :data=\"state.data\"\n                    :grid=\"showGrid\"\n                    :miniMap=\"showMiniMap\"\n                    :onRef=\"onRef\"\n                    :multipleSelect=\"true\"\n                    :loading=\"state.editorLoading\"\n\n                    :disabledUndo=\"false\"\n                    :disabledDragEdge=\"true\"\n\n                    :beforeDelete=\"handleBeforeDelete\"\n                    :afterDelete=\"handleAfterDelete\"\n                    :beforeAdd=\"handleBeforeAdd\"\n                    :afterAdd=\"handleAfterAdd\"\n\n                    @dblclick-node=\"onDblclickNode\"\n                    @dblclick-edge=\"onDblClickEdge\"\n            >\n                <div slot=\"menu\">\n                    <vue-flow-edit-menu-group v-for=\"(group,groupIndex) in state.menuData\" :label=\"group.label\" :key=\"groupIndex\">\n                        <vue-flow-edit-menu v-for=\"(menu,menuIndex) in group.menus\" :key=\"menuIndex\" :model=\"menu\"/>\n                    </vue-flow-edit-menu-group>\n                </div>\n                <div slot=\"model\" style=\"padding: 16px\">\n                    <el-form v-if=\"!!state.detailModel\" ref=\"form\" :model=\"state.detailModel\" label-width=\"100px\">\n\n                        <el-form-item label=\"\u8282\u70B9\u540D\u79F0\" prop=\"label\">\n                            <el-input v-model=\"state.detailModel.label\"/>\n                        </el-form-item>\n\n                        <template v-if=\"state.detailModel.type !== 'edge'\">\n                            <el-form-item label=\"\u8282\u70B9\u80CC\u666F\u8272\" prop=\"style.fill\">\n                                <el-color-picker v-model=\"state.detailModel.style.fill\"/>\n                            </el-form-item>\n                            <el-form-item label=\"\u8282\u70B9\u8FB9\u6846\u8272\" prop=\"style.stroke\">\n                                <el-color-picker v-model=\"state.detailModel.style.stroke\"/>\n                            </el-form-item>\n                            <el-form-item label=\"\u8282\u70B9\u6587\u5B57\u8272\" prop=\"labelCfg.style.stroke\">\n                                <el-color-picker v-model=\"state.detailModel.labelCfg.style.fill\"/>\n                            </el-form-item>\n                        </template>\n\n                    </el-form>\n                </div>\n\n                <template slot=\"toolbar\">\n                    <el-tooltip content=\"\u6D4B\u8BD5\u5DE5\u5177\u680F\u63D2\u69FD\">\n                        <div class=\"vue-flow-editor-toolbar-item\">\n                            <i class=\"el-icon-search\"/>\n                        </div>\n                    </el-tooltip>\n                </template>\n\n                <template slot=\"foot\">\n                    <el-button type=\"primary\" @click=\"save\">\u4FDD\u5B58</el-button>\n                    <el-button @click=\"cancel\">\u53D6\u6D88</el-button>\n                </template>\n            </vue-flow-editor>\n        </div>\n        ",
        setup: function setup() {
            var state = reactive({
                data: AppData,
                detailModel: null,
                editorLoading: false,
                selectOptions: [{
                    label: '待确认',
                    value: '0'
                }, {
                    label: '填写表单',
                    value: '1'
                }, {
                    label: '部门负责人审批',
                    value: '2'
                }, {
                    label: '总经理审批',
                    value: '3'
                }],
                menuData: [{
                    label: '流程节点',
                    menus: [{
                        label: '开始',
                        shape: 'ellipse',
                        id: 'start-node'
                    }, {
                        label: '结束',
                        shape: 'ellipse',
                        id: 'end-node'
                    }, {
                        label: '审批节点',
                        busType: '123'
                    }, {
                        label: '判断节点'
                    }]
                }, {
                    label: '其他形状节点',
                    menus: [{
                        label: '矩形节点',
                        shape: 'rect'
                    }, {
                        label: '圆形节点',
                        shape: 'circle'
                    }, {
                        label: '椭圆节点',
                        shape: 'ellipse'
                    }, {
                        label: '菱形节点',
                        shape: 'diamond'
                    }, {
                        label: '三角形节点',
                        shape: 'triangle'
                    }, {
                        label: '星形节点',
                        shape: 'star'
                    }]
                }]
            });
            var editor;

            function onDblclickNode(e) {
                var model = G6.Util.clone(e.item.get('model'));
                model.style = model.style || {};
                model.labelCfg = model.labelCfg || {
                    style: {}
                };
                state.detailModel = model;
                editor.openModel();
            }

            function onDblClickEdge(e) {
                var _e$item$get = e.item.get('model'),
                    source = _e$item$get.source,
                    target = _e$item$get.target,
                    style = _e$item$get.style,
                    labelCfg = _e$item$get.labelCfg,
                    label = _e$item$get.label;

                var model = {
                    label: label,
                    source: source,
                    target: target,
                    style: style || {},
                    labelCfg: labelCfg || {
                        style: {}
                    },
                    type: null,
                    id: null
                };
                model.type = e.item.get('type');
                model.id = e.item.get('id');
                state.detailModel = model;
                editor.openModel();
            }

            function cancel() {
                editor.closeModel();
            }

            function save() {
                editor.updateModel(state.detailModel);
                editor.closeModel();
            }

            function handleBeforeDelete(_x, _x2) {
                return _handleBeforeDelete.apply(this, arguments);
            }

            function _handleBeforeDelete() {
                _handleBeforeDelete = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(model, type) {
                    return regeneratorRuntime.wrap(function _callee$(_context) {
                        while (1) {
                            switch (_context.prev = _context.next) {
                                case 0:
                                    if (!(type === 'node')) {
                                        _context.next = 8;
                                        break;
                                    }

                                    if (!(model.label === '开始')) {
                                        _context.next = 8;
                                        break;
                                    }

                                    state.editorLoading = true;
                                    _context.next = 5;
                                    return delay(1000);

                                case 5:
                                    state.editorLoading = false;
                                    Ele.Notification.error('不可以删除【开始】节点');
                                    return _context.abrupt("return", Promise.reject('reject'));

                                case 8:
                                case "end":
                                    return _context.stop();
                            }
                        }
                    }, _callee);
                }));
                return _handleBeforeDelete.apply(this, arguments);
            }

            function handleAfterDelete(model, type) {
                if (type === 'edge') {
                    console.log('delete edge');
                } else {
                    console.log('after delete', model.label, _objectSpread({}, model));
                }
            }

            function handleBeforeAdd(model, type) {
                if (type === 'edge') {
                    if (model.source === 'end-node') {
                        Ele.Notification.error('结束节点不能输出连线其他节点');
                        return Promise.reject('reject');
                    }
                }

                if (type === 'node') {
                    if (model.id === 'start-node' || model.id === 'end-node') {
                        var data = editor.editorState.graph.save();

                        for (var i = 0; i < data.nodes.length; i++) {
                            var node = data.nodes[i];

                            if (node.id === model.id) {
                                Ele.Notification.error("\u53EA\u80FD\u6709\u4E00\u4E2A" + (model.id === 'start-node' ? '开始' : '结束') + "\u8282\u70B9");
                                return Promise.reject('reject');
                            }
                        }
                    }
                }
            }

            function handleAfterAdd(model, type) {
                if (type === 'edge') {
                    console.log("\u65B0\u589E\u8FDE\u63A5\u7EBF");
                }
            }

            return {
                state: state,
                showGrid: true,
                showMiniMap: false,
                onDblclickNode: onDblclickNode,
                onDblClickEdge: onDblClickEdge,
                cancel: cancel,
                save: save,
                handleBeforeDelete: handleBeforeDelete,
                handleAfterDelete: handleAfterDelete,
                handleBeforeAdd: handleBeforeAdd,
                handleAfterAdd: handleAfterAdd,
                onRef: function onRef(e) {
                    return editor = e;
                }
            };
        }
    }).$mount();
</script>
</body>
</html>