/* * @Copyright (c) 2018 缪聪(mcg-helper@qq.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* 基本数据Map * selector: 当前拖拽控件id * runnerFlowId: 当前执行的流程id * runnerFlowElementId: 当前执行流程正在执行控件id * status: 0:流程区正常操作 1:重绘流程区时 * highlight: 当前控制台日志高亮显示的id * flowDataSourceModalId 数据源弹出框的id,点击数据源时触发保存id */ var baseMap = new Map(); /* 流程节点Map */ var elementMap = new Map(); /* html工具Map*/ var htmlToolsMap = new Map(); var setting = { view: { addHoverDom: addHoverDom, removeHoverDom: removeHoverDom, selectedMulti: false }, callback: { beforeRename: beforeRename, // beforeEditName: beforeEditName, beforeRemove: beforeRemove, // onRemove: onRemove, onClick: onClick }, check: { enable: false }, data: { simpleData: { enable: true } }, edit: { enable: true, showRemoveBtn: setRemoveBtn } }; $(function() { setAutoHeight($("body"), 500); /* $('#mcg_toolbar').affix({ offset: { bottom: 0 }, target: $("#flowarea") }); $('#console_header').affix({ offset: { bottom: 0 }, target: $("#flowarea") }); */ if($("#mcg_flow").height() <= 0) { $("#mcg_flow").height(500); $("#flowarea").height(460); } /* 设置流程管理树高度为流程区的高度 */ $("#flowTree").height($("#flowarea").height() - 60); common.ajax({ url : "/flowTree/getDatas", type : "GET", data : null, contentType : "application/json" }, function(data) { $.fn.zTree.init($("#flowTree"), setting, data.topologys); var treeObj = $.fn.zTree.getZTreeObj("flowTree"); treeObj.expandAll(true); var rootNode = treeObj.getNodeByParam("id", data.selected.id, null); nodeSelected(rootNode); fuzzySearch('flowTree','#flowTreeKey', null, true); // 系统初始化 initFlowSystem(); }); }); /* * 初始化流程控制台,主要以下: * 绑定按钮功能 */ function initFlowConsole() { $("#flowStopBtn").click(function(){ if($("#flowStopBtn span").is(".text-danger")) { common.ajax({ url : "/flow/stop", type : "POST", data : "flowId=" + $("#flowSelect").attr("flowId") }, function(data) { if(data.statusCode == 1) { $("#flowStopBtn span").removeClass("text-danger"); } else { Messenger().post({ message: "停止流程失败!", type: "error", hideAfter: 5, showCloseButton: true }); } }); } else { Messenger().post({ message: "流程未执行,无法停止!", type: "error", hideAfter: 5, showCloseButton: true }); } }); $("#flowLogCleanBtn").click(function() { $("#console").html(""); }); } /* * 绑定流程控件拖拽事件 */ function flowDropBind() { baseMap.put("selector", ""); baseMap.put("status", 0); $("#flowarea").droppable({ drop: function( event, ui ) { //排除流程区中,非流程控件的html对象拖拽事件 if(ui.draggable.attr("eletype") == undefined || ui.draggable.attr("eletype") == "undefined") { return ; } // 从工具栏拖拽到流程区时 if(ui.draggable.attr("clone") != "true" && ui.draggable.attr("eletype") != undefined) { var element = new $.DragWidget({ id:ui.draggable.attr("id")+Math.uuid(), label:$("#"+ui.draggable.attr("id")).text() ,name:$("#"+ui.draggable.attr("id")).text(), classname:"w eletype",eletype:ui.draggable.attr("eletype"), clone:'true',left:ui.offset.left,top:ui.offset.top,sign:"false" }); var divNode = $("
工具
"); divNode.css("left", element.getLeft()+"px"); divNode.css("top", element.getTop()+"px"); $(this).append(divNode); var xy = getXY(element.getId(),"false"); element.setLeft(xy.x); element.setTop(xy.y); elementMap.put(element.getId(), element); setXY(element.getId(), xy); //重绘流程区节点和连接线 repaint(this); //初始化流程节点工具层 initPopover(); //初始化流程节点拖拽功能和连接线连接功能 initConnectLine(); } else { //在流程区中移动节点时,重新记录坐标 var xy = getXY(ui.draggable.attr("id"),ui.draggable.attr("clone")); var element = elementMap.get(ui.draggable.attr("id")); element.setLeft(xy.x); element.setTop(xy.y); saveXY(ui.draggable.attr("id"), xy); elementMap.put(ui.draggable.attr("id"), element); } $(".draggable").draggable({containment: "parent", zIndex: 100 }); //grid: [ 50, 20 ] } }); } /* 计算流程节点坐标 * (flag="true") 第一次生成节点时 * (flag="false") 在流程区中拖拽已有节点时 */ function getXY(id, flag) { if(id == undefined || flag == undefined) { return false; } var xy = {x:0, y:0}; if(flag != "true") { // xy.x = $("#"+id).position().left - $("#flowarea").offset().left; // xy.y = $("#"+id).position().top - $("#flowarea").offset().top; xy.x = document.getElementById(id).offsetLeft + document.getElementById("flowarea").scrollLeft - $("#flowarea").offset().left; xy.y = document.getElementById(id).offsetTop + document.getElementById("flowarea").scrollTop - $("#flowarea").offset().top; } else { xy.x = document.getElementById(id).offsetLeft; xy.y = document.getElementById(id).offsetTop; } return xy; } //给流程节点绑定事件 function bindEvent(id) { $("#"+id).dblclick(function(){ createHtmlModal(id, null); }); $("#"+id).click(function(){ baseMap.put("selector", id); removePopover(); //删除所有流程节点悬浮工具层 $("#"+id).popover('show'); //显示流程节点悬浮工具层 }); } //删除所有流程节点县浮工具层 function removePopover() { $("#flowarea").children("div[data-toggle='popover']").each(function() { $(this).popover('hide'); }); } //初始化流程节点工具层 function initPopover() { $("#flowarea").children("[data-toggle='popover']").popover({ // delay:{ show: 0, hide: 1000 }, trigger:"manual",//manual,focus,click placement:"bottom", // title:"流程节点工具层", html:true, container: $("#flowarea"), animation: false, content:baseMap.get("popoverContent") }).on("mouseenter", function () { removePopover(); var _this = this; $(this).popover("show"); $(this).siblings(".popover").on("mouseleave", function () { $(_this).popover('hide'); }); }).on("mouseleave", function () { var _this = this; setTimeout(function () { if (!$(".popover:hover").length) { $(_this).popover("hide") } }, 100); }).on("show.bs.popover", function() { var _this = this; baseMap.put("selector", $(_this).attr("id")); }); } /** * 控件悬浮工具功能(修改、删除、日志定位) * @param operate (edit:修改 delete:删除 logOut:日志定位) */ function suspend(operate) { if(operate == "edit") { createHtmlModal(baseMap.get("selector"), null); } else if(operate == "delete") { removePopover(); removeElement(baseMap.get("selector")); } else if(operate == "logOut") { removePopover(); if(baseMap.get("selector") != null && baseMap.get("selector") != "" && baseMap.get("selector") != undefined) { if($("#log" + baseMap.get("selector")).length > 0) { if($("#" + baseMap.get("highlight")).length > 0) { $("#" + baseMap.get("highlight")).removeClass("highlight"); //把上次被高亮标记div去除高亮样式 } $("#highlight" + baseMap.get("selector")).addClass("highlight"); baseMap.put("highlight", "highlight" + baseMap.get("selector")); //把当前被高亮标记div的id放入缓存 var pos = $("#log" + baseMap.get("selector")).offset().top; // $("html,body").animate({scrollTop: pos}, 100); $("#mcg_flow").animate({scrollTop: (pos - 40)}, 100); // return false; } } }/* else if(operate == "set") { $(".dropdown-toggle").show(); } else if(operate == "no") { removePopover(); alert("nonono"); } else if(operate == "yes") { removePopover(); alert("yesyes"); }*/ } function clearAll(object) { //删除所有连接线 if(baseMap.get("instance") != undefined) baseMap.get("instance").deleteEveryEndpoint(); var array = elementMap.keySet(); //将当前所有节点删除 if(array.length > 0) { for(var i=0; i 0) { for(var i=0; i" + elementMap.get(array[i]).getLabel() + "
" + name + "
"); divNode.css("left", elementMap.get(array[i]).getLeft()+"px"); divNode.css("top", elementMap.get(array[i]).getTop()+"px"); $(object).append(divNode); eventInterceptor("name_" + elementMap.get(array[i]).getId()); // setXY(elementMap.get(array[i]).getId(), getXY(elementMap.get(array[i]).getId(), "false")); bindEvent(elementMap.get(array[i]).getId()); } } /* 通过流程节点id, 连接线id,删除指定的连接线缓存 */ function removeConnectorsById(elementId, connectorId) { var connectorMap = elementMap.get(elementId).getConnectorMap(); elementMap.get(elementId).getConnectorMap().remove(connectorId); /* var connectorArray = connectorMap.keySet(); for(var i in connectorArray) { var connector = connectorMap.get(connectorArray[i]); elementMap.get(elementId).getConnectorMap().remove(connector.getConnectorId()); }*/ } /* 删除指定的流程节点中,包含的向下、向后连接线的缓存 */ function removeConnectorById(elementId) { var connectors = new Array(); var array = elementMap.keySet(); if(array.length > 0) { for(var i=0; i 0) { for(var i=0; i0)) { flowSelectTreeHide(); } } /* 初始化功能区按钮 */ function initFunc() { $('#flowSelect').click(function(){ $("#flowSelectTree").slideDown("fast"); $("body").bind("mousedown", onBodyDown); }); $('#removeFlowTreeKeyBtn').click(function(){ $("#flowTreeKey").val("").trigger('propertychange'); }); $('#flowSaveBtn').click(function(){ var webStruct = convertFlowObject(); common.ajax({ url : "/flow/saveWebStruct", type : "POST", data : JSON.stringify(webStruct), contentType : "application/json" }, function(data) { if(data.statusCode != 1) { Messenger().post({ message: "保存流程失败!", type: "error", hideAfter: 5, showCloseButton: true }); } }); }); $('#flowGenBtn').click(function(){ //清空控制台 $("#console").html(""); var array = elementMap.keySet(); for(var i in array) { $("#name_" + array[i]).children("span").remove(); $("#name_" + array[i]).removeClass("run_state"); } var webStruct = convertFlowObject(); $("#flowStopBtn span").addClass("text-danger"); common.ajax({ isLoading : true, url : "/flow/generate", type : "POST", data : JSON.stringify(webStruct), contentType : "application/json" }, function(data) { if(data.statusCode != 1) { Messenger().post({ message: "执行流程失败!", type: "error", hideAfter: 5, showCloseButton: true }); } }); }); $('#flowImpBtn').click(function(){ var uuid = Math.uuid(); var form = $("
"); form.attr("style", "display:none"); form.attr("method", "post"); form.attr("enctype", "multipart/form-data"); form.attr("action", baseUrl + "/tool/upload"); var input = $(""); var flowIdInput = $(""); var mcgWebScoketCodeInput = $(""); form.append(input); form.append(flowIdInput); form.append(mcgWebScoketCodeInput); form.append($("#" + uuid + "flowFile")); $("body").append(form); /* console.log(document.getElementById("flowUploadForm")); document.getElementById("flowUploadForm").reset(); //$("#flowUploadForm")[0].reset(); $("#test_flowId").val($("#flowSelect").attr("flowId")); $("#test_mcgWebScoketCode").val(mcgWebScoketCode); */ $("#" + uuid + "flowFile").click(); }); $('#flowExpBtn').click(function(){ var form = $(""); form.attr("style", "display:none"); form.attr("target", ""); form.attr("method", "post"); form.attr("action", baseUrl + "/tool/down"); var flowIdInput = $(""); flowIdInput.attr("type","hidden"); flowIdInput.attr("name","flowId"); flowIdInput.attr("value",$("#flowSelect").attr("flowId")); form.append(flowIdInput); var flowNameInput = $(""); flowNameInput.attr("type","hidden"); flowNameInput.attr("name","flowName"); flowNameInput.attr("value",$("#flowSelect").attr("flowName")); form.append(flowNameInput); $("body").append(form); form.submit(); form.remove(); }); $('#flowClearBtn').click(function(){ var parentdiv=$('
'); parentdiv.attr('id', "flowClear"); $(parentdiv).html("
清空数据不可恢复,您确定清空当前流程数据吗?
"); $(parentdiv).dialog({ title: "清空当前流程数据?", resizable: false, autoOpen: false, closeOnEscape: false, modal: true, width: 350, height: "auto", position: { my: "center", at: "center", of: window }, buttons: [ { class: "btn btn-primary", text: "确定", click: function() { var _this = this; common.ajax({ url : "/flow/clearFlowData", type : "POST", data : "mcgWebScoketCode=" + mcgWebScoketCode + "&flowId=" + $("#flowSelect").attr("flowId") }, function(data) { if(data.statusCode == 1) { clearAll($("#flowarea")); $( _this ).dialog( "destroy" ); } else { Messenger().post({ message: "清空流程失败!", type: "error", hideAfter: 5, showCloseButton: true }); } }); } }, { class: "btn btn-default", text: "关闭", click: function() { $( this ).dialog( "destroy" ); } } ] }).on( "dialogclose", function( event, ui ) { $(this).dialog( "destroy" ); }); $(parentdiv).dialog("open"); }); $('#flowDataSourceBtn').click(function(data){ var modalId = createModalId("dataSource"); var param = {}; var option = {}; option["title"] = "数据源管理"; option["width"] = 1100; param["modalId"] = modalId.replace(/_Modal/g, ""); param["eletype"] = "dataSource"; param["option"] = option; common.showAjaxDialog("/html/flowDataSourceModal", setDialogBtns(param), function (data) { baseMap.put("flowDataSourceModalId", param.modalId); initFlowDataSourceModal(param.modalId); }, null, param); }); } /* 将elementMap中的缓存数据转换成WebStruct*/ function convertFlowObject() { var webElementArray = new Array(); var webConnectorArray = new Array(); var array = elementMap.keySet(); for(var i=0; i0) { return; } var addStr = ""; sObj.after(addStr); var btn = $("#addBtn_"+treeNode.tId); if (btn) { btn.bind("click", function(){ var zTree = $.fn.zTree.getZTreeObj("flowTree"); var newNode = zTree.addNodes(treeNode, {id:Math.uuid(), pId:treeNode.id, name:"请输入名称"}); zTree.editName(newNode[0]); return false; }); } }; /* 用于当鼠标移出节点时,隐藏用户自定义控件,显示隐藏状态同 zTree 内部的编辑、删除按钮 */ function removeHoverDom(treeId, treeNode) { $("#addBtn_"+treeNode.tId).unbind().remove(); }; /* 用于捕获节点编辑名称结束(Input 失去焦点 或 按下 Enter 键)之后,更新节点名称数据之前的事件回调函数,并且根据返回值确定是否允许更改名称的操作 */ function beforeRename(treeId, treeNode, newName, isCancel) { common.ajax({ url : "/flowTree/addOrUpdateNode", type : "GET", data : "id=" + treeNode.id + "&name=" + newName + "&pId=" + treeNode.pId, contentType : "application/json" }, function(data) { nodeSelected(treeNode); }); } /* // 用于捕获删除节点之后的事件回调函数 function onRemove(event, treeId, treeNode) {} //用于捕获节点编辑按钮的 click 事件,并且根据返回值确定是否允许进入名称编辑状态 function beforeEditName(treeId, treeNode) { return true; } */ // 设置是否显示删除按钮。过滤根元素不显示删除按钮 function setRemoveBtn(treeId, treeNode) { return treeNode.id == "root" ? false:true; } //用于捕获节点被删除之前的事件回调函数,并且根据返回值确定是否允许删除操作 function beforeRemove(treeId, treeNode) { var isParent = treeNode.isParent; var ids = new Array(); ids = getChildren(ids,treeNode); var parentdiv=$('
'); parentdiv.attr('id', "flowDelete_" + treeId); $(parentdiv).html("
删除当前流程以及所有子流程,您确定需要删除吗?
"); $(parentdiv).dialog({ title: "删除当前流程?", resizable: false, autoOpen: false, closeOnEscape: false, modal: true, width: 350, height: "auto", position: { my: "center", at: "center", of: window }, buttons: [ { class: "btn btn-primary", text: "确定", click: function() { var _this = this; common.ajax({ url : "/flowTree/deleteNode", type : "GET", data : "ids=" + ids, async: false, contentType : "application/json" }, function(data) { if(data.statusCode == 1) { var treeObj = $.fn.zTree.getZTreeObj("flowTree"); treeObj.removeNode(treeNode, false); var rootNode = treeObj.getNodeByParam("id", "root", null); nodeSelected(rootNode); $( _this ).dialog( "destroy" ); Messenger().post({ message: "删除流程成功!", type: "success", hideAfter: 5, showCloseButton: true }); } else { Messenger().post({ message: "清空流程失败!", type: "error", hideAfter: 5, showCloseButton: true }); } }); } }, { class: "btn btn-default", text: "关闭", click: function() { $( this ).dialog( "destroy" ); } } ] }).on( "dialogclose", function( event, ui ) { $(this).dialog( "destroy" ); }); $(parentdiv).dialog("open"); return false; } /* 获取流程树选中的节点id及递归包含的所有子节点id */ function getChildren(ids,treeNode){ ids.push(treeNode.id); if (treeNode.isParent){ for(var node in treeNode.children){ getChildren(ids,treeNode.children[node]); } } return ids; } /* 用于捕获节点被点击的事件回调函数 */ function onClick(event, treeId, treeNode) { nodeSelected(treeNode); }; /* 节点被选中时,更新下拉按钮的值 */ function nodeSelected(treeNode) { var treeObj = $.fn.zTree.getZTreeObj("flowTree"); treeNode.name = treeNode.name.replace(/<[^>]+>/g, ""); treeObj.selectNode(treeNode); $("#flowSelect").html(treeNode.name+" "); $("#flowSelect").attr("flowId", treeNode.id); $("#flowSelect").attr("flowName", treeNode.name); $("#flowSelect").attr("flowPid", treeNode.pId); clearAll($("#flowarea")); initFlowData($("#flowSelect").attr("flowId")); flowSelectTreeHide(); } /*------------------流程树方法结束 ---------------------*/