/** * * 基于jsplumb-2.12.9流程设计器 * * @author xiacj * @version 1.0 * @date 2020-10-24 * */ //流程基本信息 var processInfo = {}; //节点基本信息 var stepList = []; //连线基本信息 var transList = []; var loadFlowFinish = false; //当前连线 var _currConn; //当前节点 var _currNodeId; var jsplumbSetting = { // 动态锚点、位置自适应 Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter', 'BottomRight', 'BottomLeft', 'Left', 'LeftMiddle' ], Container: 'flowBox', // 连线的样式 StateMachine、Flowchart、Bezier Connector: 'Flowchart', // 鼠标不能拖动删除线 ConnectionsDetachable: false, // 删除线的时候节点不删除 DeleteEndpointsOnDetach: false, // 连线的端点 // Endpoint: ["Dot", {radius: 5}], Endpoint: ["Rectangle", { height: 10, width: 10 }], // 线端点的样式 EndpointStyle: { fill: 'rgba(255,255,255,0)', outlineWidth: 1 }, LogEnabled: true, //是否打开jsPlumb的内部日志记录 // 绘制线 PaintStyle: { stroke: '#6891a4', strokeWidth: 3 }, // 绘制箭头 Overlays: [ ['Arrow', { width: 12, length: 12, location: 1 }] ], RenderMode: "svg" }; // jsplumb连接参数 var jsplumbConnectOptions = { isSource: true, isTarget: true, // 动态锚点、提供了4个方向 Continuous、AutoDefault anchor: "Continuous" }; var jsplumbSourceOptions = { /*"span"表示标签,".className"表示类,"#id"表示元素id*/ filter: ".flow-node-drag", filterExclude: false, anchor: "Continuous", allowLoopback: false }; var jsplumbTargetOptions = { /*"span"表示标签,".className"表示类,"#id"表示元素id*/ filter: ".flow-node-drag", filterExclude: false, anchor: "Continuous", allowLoopback: false }; //设置连接属性 function setConn(condiVal, condiExpr) { _currConn.setLabel({ label: condiVal, cssClass: 'labelClass' }); var from = _currConn.sourceId; var to = _currConn.targetId; $(transList).each(function (idx, line) { if (line.fromStepId === from && line.toStepId === to) { line['condiExpr'] = condiExpr; line['condiVal'] = condiVal; } }); } //删除jsPlumb实例连线 function delConn() { if (prevFlag) { return; } jsPlumb.deleteConnection(_currConn); } //删除jsPlumb连线后回调,删除transList中的数据 function deleteTransList(from, to) { transList = transList.filter(function (step) { return (step.fromStepId != from) && (step.toStepId != to) }); } //添加节点 function addNode(node, updateFlag) { //alert(jsplumbInstance) //node。id if (!updateFlag) { stepList.push(node); } drawNode(node); if (prevFlag) { return; } //设置源点,可以拖出线连接其他节点 jsPlumb.makeSource(node.stepId, jsplumbSourceOptions); // // 设置目标点,其他源点拖出的线可以连接该节点 jsPlumb.makeTarget(node.stepId, jsplumbTargetOptions); //设置拖拽范围为父级容器 jsPlumb.draggable(node.stepId, { containment: 'parent' }); } //展示节点编辑按钮 function onmouseoverNode(e) { $(e).find(".flow-node-operate").show(); } //隐藏节点编辑按钮 function onmouseoutNode(e) { $(e).find(".flow-node-operate").hide(); } //绘制节点html function drawNode(node) { // var node = ['
', // '
', // '', // '', // '
', // '
' + node.stepName + '
', // '
' // ].join(''); var node = '
' + '
' + '' + '' + '
' + '
' + '' + '' + '' + '' + ' ' + ' ' + '
' + node.stepName + '
' + '
' + '
' $("#flowBox").append(node); } function editNode(e) { if (prevFlag) { return; } var currentNode = $(e).parents(".nodeBox"); var nodeId = currentNode.attr("id"); _currNodeId = nodeId; var node = getNodeInfo(_currNodeId) if (node.type === 'task') { util.openWin("setNode_" + node.type + ".html?stepId=" + node.stepId, node.stepName, 600, 400); } else { util.openWin("setNode_" + node.type + ".html?stepId=" + node.stepId, node.stepName, 600, 240); } //alert("待处理编辑节点界面,nodeId="+nodeId); } //变更节点位置 function changeNodeSite(e) { if (prevFlag) { return; } var data = {}; data.nodeId = $(e).attr("id"); data.posLeft = $(e).css("left"); data.posTop = $(e).css("top"); for (var i = 0; i < stepList.length; i++) { var node = stepList[i]; if (node.stepId == data.nodeId) { node.posLeft = data.posLeft; node.posTop = data.posTop; } } } //鼠标移动事件 function changeNodePosition() { if (prevFlag) { return; } let element = this drag(element, document.querySelector('.flowRightItem')) // var el = (typeof element == "string") ? document.getElementById(element) : element; // if (el.parentNode === null || el.style.display == 'none') { // return false; // } // console.log(`Y--------${el.offsetTop - el.parentNode.offsetTop + 118}-----X---------${el.offsetLeft - el.parentNode.offsetLeft + 243}`); // // console.log(el.offsetLeft - el.parentNode.offsetLeft); // console.log(`${el.parentNode.clientHeight}----------${el.parentNode.clientWidth}`); // return el.offsetTop - el.parentNode.offsetTop; } function drag(obj, document) { if (prevFlag) { return; } obj.onmousedown = function (ev) { var ev = ev || event; console.log(this); var disX = ev.clientX - this.offsetLeft; var disY = ev.clientY - this.offsetTop; document.onmousemove = function (ev) { var ev = ev || event; var L = ev.clientX - disX; //拖动元素左侧的位置=当前鼠标距离浏览器左侧的距离 - (物体宽度的一半) var T = ev.clientY - disY; //拖动元素顶部的位置=当前鼠标距离浏览器顶部的距离 - (物体高度的一半) console.log(L); console.log(T); } document.onmouseup = function () { document.onmousemove = document.onmouseup = null; if (obj.releaseCapture) { obj.releaseCapture(); } } return false; } } //删除节点 function deleteNode(e) { var currentNode = $(e).parents(".nodeBox"); var nodeId = currentNode.attr("id"); _currNodeId = nodeId; util.showDialog("确认删除环节么?", 3, doDeleteNode); } function doDeleteNode() { stepList = stepList.filter(function (node) { if (node.stepId === _currNodeId) { // // 伪删除,将节点隐藏,否则会导致位置错位 // node.show = false; // $("#" + _currNodeId).hide(); $("#" + _currNodeId).remove(); return false; } return true }); setInterval(function () { jsPlumb.removeAllEndpoints(_currNodeId); }, 50); } //编辑流程信息 function editFlowInfo() { util.openWin("editFlow.html", "流程信息", 600, 240); } //设置流程信息 function setFlowInfo(procName, processDesc) { if (procName) { processInfo["procName"] = procName; } if (processDesc) { processInfo["processDesc"] = processDesc; } } //保存流程信息 function saveFlowInfo() { util.showDialog("确认保存流程信息么?", 3, doSaveFlowInfo); } function addRow() { var lastChild = $("#ydt").children('.div-row-last') lastChild.after($('
')); lastChild.after($('
')); lastChild.after($('
')); lastChild.removeClass('div-row-last'); var lastTop = $(".div-row-last").height() + parseInt($(".div-row-last").css("top").replace("px", "")); var updateHeight = lastTop > $("#ydt").height() ? lastTop : $("#ydt").height(); $.each($(".div-col ,.div-col-first"), function () { $(this).height(updateHeight); }); } function addCol() { var lastChild = $("#ydt").children('.div-col-last') lastChild.after($('
')); lastChild.after($('
')); lastChild.after($('
')); lastChild.removeClass('div-col-last'); var lastLeft = $(".div-col-last").width() + parseInt($(".div-col-last").css("left").replace("px", "")); var updateWidth = lastLeft > $("#ydt").width() ? lastLeft : $("#ydt").width(); $.each($(".div-row ,.div-row-first"), function () { $(this).width(updateWidth); }); } function initColRow(colNum, rowNum) { var h = $("#ydt").height(); var w = $("#ydt").width(); for (var i = 0; i < colNum; i++) { var left = defaultW; var colLeft = (defaultW + border) * (i + 1) + defaultBtn; if (i == 0) { $("#ydt").append($('
')); $("#ydt").append($('
')); $("#ydt").append($('
')); } var lastCol = (i + 1 == colNum) ? 'div-col-last' : ''; $("#ydt").append($('
')); if (i + 1 != colNum) { $("#ydt").append($('
')); $("#ydt").append($('
')); } } for (var i = 0; i < rowNum; i++) { var top = defaultBtn + (defaultH + border) * (i + 1); var topHeight = defaultH; if (i == 0) { $("#ydt").append($('
')); $("#ydt").append($('
')); $("#ydt").append($('
')); } var lastRow = (i + 1 == rowNum) ? 'div-row-last' : ''; $("#ydt").append($('
')); if (i + 1 != rowNum) { $("#ydt").append($('
')); $("#ydt").append($('
')); } } } function initFirstLeftTop() { if (prevFlag) { return; } //2020年11月5日14:57:24 JIANGYONG 修改 $("#ydt").append($('
' + '' + '' + '
' )) } function loadColRow(swimList) { var colArr = new Array(); var rowArr = new Array(); // 0是row 1是col swimList.forEach(function (item, i) { if (item.cellType == '1') { colArr.push(item); return true; } rowArr.push(item); }) var w = $("#ydt").width(); var h = $("#ydt").height(); if (rowArr.length == 0) { initColRow(1, 0); } for (var i = 0; i < rowArr.length; i++) { var colCss = i == 0 ? 'div-col-first' : 'div-col' $("#ydt").append($('
')); $("#ydt").append($('
')); $("#ydt").append($('
' + rowArr[i].title + '
')); if (i + 1 == rowArr.length) { console.log(parseInt(rowArr[i].posLeft.replace("px", "")) + "," + rowArr[i].cellWidth); $("#ydt").append($('
')); console.log($(".div-col-last").css("left")); } } if (colArr.length == 0) { initColRow(0, 1); } for (var i = 0; i < colArr.length; i++) { var rowCss = i == 0 ? 'div-row-first' : 'div-row' $("#ydt").append($('
')); $("#ydt").append($('
')); $("#ydt").append($('
' + colArr[i].title + '
')); if (i + 1 == colArr.length) { $("#ydt").append($('
')); } } } function dynaEvent() { if (prevFlag) { return; } var sourceNum = 0; var sourceTop = 0; var prevSource = null; var nextSource = null; $(".div-col").draggable( { axis: "x", scroll: true, start: function (e, ui) { sourceNum = ui.position.left; prevSource = { left: $(e.target).prev().css('left'), width: $(e.target).prev().width() }; nextSource = { left: $(e.target).next().css('left'), width: $(e.target).next().width() }; }, drag: function (e, ui) { var flag = offsetLeft(e.target, ui.position.left - sourceNum); if (!flag) { return; } sourceNum = ui.position.left; }, stop: function (e, ui) { var revert = $(".div-col").draggable("option", "revert"); if (revert) { resetLeft(e.target, prevSource, nextSource); } $(".div-col").draggable({ revert: false }); } } ); $(".div-row").draggable( { axis: "y", scroll: true, start: function (e, ui) { sourceNum = ui.position.top; prevSource = { top: $(e.target).prev().css('top'), height: $(e.target).prev().height() }; nextSource = { top: $(e.target).next().css('top'), height: $(e.target).next().height() }; }, drag: function (e, ui) { var flag = offsetTop(e.target, ui.position.top - sourceNum); if (!flag) { return; } sourceNum = ui.position.top; }, stop: function (e, ui) { var revert = $(".div-row").draggable("option", "revert"); if (revert) { resetTop(e.target, prevSource, nextSource); } $(".div-row").draggable({ revert: false }); } } ); $('div.div-row-content,div.div-col-content').contextMenu('myMenu1', { bindings: { 'deleteBtn': function (t) { dynaCol(t); if ($(t).next().hasClass('div-col-last')) { $(t).prev().prev().addClass('div-col-last') } dynaRow(t); if ($(t).next().hasClass('div-row-last')) { $(t).prev().prev().addClass('div-row-last'); } $(t).prev().remove(); $(t).next().remove(); $(t).remove(); } } }); } function dynaRow(t) { if ($(t).hasClass('div-col-content') && !$(t).next().hasClass('div-row-last')) { var height = $(t).height() + $(t).next().height(); var title = $(t).next().next(); var content = title.next(); var col = content.next(); content.attr('style', 'top:' + (parseInt(content.css('top').replace('px', '')) - height) + 'px;height:' + content.height() + 'px'); title.attr('style', 'top:' + (parseInt(title.css('top').replace('px', '')) - height) + ';height:' + title.height() + 'px'); col.attr('style', 'top:' + (parseInt(col.css('top').replace('px', '')) - height) + ';width:' + col.width() + 'px;height:' + col.height() + 'px'); return dynaRow($(t).next().next().next()); } } function dynaCol(t) { if ($(t).hasClass('div-row-content') && !$(t).next().hasClass('div-col-last')) { var width = $(t).width() + $(t).next().width(); var title = $(t).next().next(); var content = title.next(); var col = content.next(); content.attr('style', 'left:' + (parseInt(content.css('left').replace('px', '')) - width) + 'px;width:' + content.width() + 'px'); title.attr('style', 'left:' + (parseInt(title.css('left').replace('px', '')) - width) + ';width:' + title.width() + 'px'); col.attr('style', 'left:' + (parseInt(col.css('left').replace('px', '')) - width) + ';width:' + col.width() + 'px;height:' + col.height() + 'px'); return dynaCol($(t).next().next().next()); } } function addContentEvent() { if (prevFlag) { return; } $(document.body).delegate('.div-col-content,.div-row-content', 'dblclick', function (e) { $(this).prev().toggleClass('div-display'); $(this).prev().find("textarea").val($(this).html()); $(this).toggleClass('div-display'); }) $(document.body).delegate('div', 'click', function (e) { if ($(this).hasClass('div-row-title') || $(this).hasClass('div-col-title') || $(this).hasClass('div-col-content') || $(this).hasClass('div-row-content')) { e.stopPropagation(); return; } $.each($($('.div-col-title:not(.div-display),.div-row-title:not(.div-display)')), function () { $(this).next().toggleClass('div-display'); $(this).toggleClass('div-display'); $(this).next().html($(this).find("textarea").val()); }); }) dynaEvent(); $('.div-first').contextMenu('myMenu2', { bindings: { 'addRow': function (t) { addRow(); dynaEvent(); }, 'addCol': function (t) { addCol(); dynaEvent(); } } }); } function resetTop(dom, nextSource, prevSource) { var content = $(dom).next().next(); var prevContent = $(dom).prev(); var title = $(dom).next(); var prevTitle = $(dom).prev().prev(); content.attr('style', 'top:' + prevSource.top + ';height:' + prevSource.height + 'px') title.attr('style', 'top:' + prevSource.top + ';height:' + prevSource.height + 'px') prevContent.attr('style', 'top:' + nextSource.top + ';height:' + nextSource.height + 'px') prevTitle.attr('style', 'top:' + nextSource.top + ';height:' + nextSource.height + 'px') } function offsetTop(dom, offTop, flag) { var content = $(dom).next().next(); var prevContent = $(dom).prev(); var title = $(dom).next('.div-col-title'); var prevTitle = $(dom).prev().prev(); var prevTitleWidth = prevTitle.height() + offTop; var prevContentWith = prevContent.height() + offTop; if ((title.length > 0 && title.height() < 50) || prevContent.height() < 50) { $(".div-row").draggable({ revert: true }); return false; } if (title.length > 0) { var contentWidth = content.height() - offTop; var titleWidth = title.height() - offTop; content.attr('style', 'top:' + (parseInt(content.css("top").replace('px', '')) + offTop) + 'px;height:' + contentWidth + 'px') title.attr('style', 'top:' + (parseInt(title.css("top").replace('px', '')) + offTop) + 'px;height:' + titleWidth + 'px') } prevContent.attr('style', 'top:' + prevContent.css("top") + ';height:' + prevContentWith + 'px') prevTitle.attr('style', 'top:' + prevTitle.css("top") + ';height:' + prevTitleWidth + 'px') return true; } function resetLeft(dom, nextSource, prevSource) { var content = $(dom).next().next(); var prevContent = $(dom).prev(); var title = $(dom).next('.div-row-title'); var prevTitle = $(dom).prev().prev(); if (title.length > 0) { content.attr('style', 'left:' + prevSource.left + ';width:' + prevSource.width + 'px') title.attr('style', 'left:' + prevSource.left + ';width:' + prevSource.width + 'px') } else { } prevContent.attr('style', 'left:' + nextSource.left + ';width:' + nextSource.width + 'px') prevTitle.attr('style', 'left:' + nextSource.left + ';width:' + nextSource.width + 'px') } function offsetLeft(dom, offLeft) { var title = $(dom).next('.div-row-title'); var content = $(dom).next().next(); var prevTitle = $(dom).prev().prev(); var prevContent = $(dom).prev(); var prevTitleWidth = prevTitle.width() + offLeft; var prevContentWith = prevContent.width() + offLeft; if ((title.length > 0 && title.width() < 50) || prevContent.width() < 50) { $(".div-col").draggable({ revert: true }); return false; } if (title.length > 0) { var contentWidth = content.width() - offLeft; var titleWidth = title.width() - offLeft; content.attr('style', 'left:' + (parseInt(content.css("left").replace("px", '')) + offLeft) + 'px;width:' + contentWidth + 'px') title.attr('style', 'left:' + (parseInt(title.css("left").replace("px", '')) + offLeft) + 'px;width:' + titleWidth + 'px') } prevContent.attr('style', 'left:' + prevContent.css("left") + ';width:' + prevContentWith + 'px') prevTitle.attr('style', 'left:' + prevTitle.css("left") + ';width:' + prevTitleWidth + 'px') return true; } var bean = { cellType: '', cellTypeName: '', title: '', cellWidth: '', cellHeight: '', posLeft: '', posTop: '', orderNum: '' } var border = 1; var defaultW = 200; var defaultH = 200; var defaultBtn = 40; function saveInitYdT() { var orderNum = 1; var arr = new Array(); // 0是row 1是col $.each($('.div-col-content'), function () { var col = $.extend({}, bean); col.cellType = '1'; col.cellTypeName = '列'; col.title = $(this).html(); col.cellWidth = $(this).width(); col.cellHeight = $(this).height(); col.posLeft = $(this).css('left'); col.posTop = $(this).css('top'); col.orderNum = orderNum; arr.push(col); orderNum++; }); $.each($('.div-row-content'), function () { var row = $.extend({}, bean); row.cellType = '0'; row.cellTypeName = '行'; row.title = $(this).html(); row.cellWidth = $(this).width(); row.cellHeight = $(this).height(); row.posLeft = $(this).css('left'); row.posTop = $(this).css('top'); row.orderNum = orderNum; arr.push(row); orderNum++; }); return arr; } function doSaveFlowInfo() { //alert("in save flow 2") let list = []; for(let i=0;i