flow.js 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312
  1. /**
  2. *
  3. * 基于jsplumb-2.12.9流程设计器
  4. *
  5. * @author xiacj
  6. * @version 1.0
  7. * @date 2020-10-24
  8. *
  9. */
  10. //流程基本信息
  11. var processInfo = {};
  12. //节点基本信息
  13. var stepList = [];
  14. //连线基本信息
  15. var transList = [];
  16. var loadFlowFinish = false;
  17. //当前连线
  18. var _currConn;
  19. //当前节点
  20. var _currNodeId;
  21. var jsplumbSetting = {
  22. // 动态锚点、位置自适应
  23. Anchors: ['Top', 'TopCenter', 'TopRight', 'TopLeft', 'Right', 'RightMiddle', 'Bottom', 'BottomCenter', 'BottomRight',
  24. 'BottomLeft', 'Left', 'LeftMiddle'
  25. ],
  26. Container: 'flowBox',
  27. // 连线的样式 StateMachine、Flowchart、Bezier
  28. Connector: 'Flowchart',
  29. // 鼠标不能拖动删除线
  30. ConnectionsDetachable: false,
  31. // 删除线的时候节点不删除
  32. DeleteEndpointsOnDetach: false,
  33. // 连线的端点
  34. // Endpoint: ["Dot", {radius: 5}],
  35. Endpoint: ["Rectangle", {
  36. height: 10,
  37. width: 10
  38. }],
  39. // 线端点的样式
  40. EndpointStyle: {
  41. fill: 'rgba(255,255,255,0)',
  42. outlineWidth: 1
  43. },
  44. LogEnabled: true, //是否打开jsPlumb的内部日志记录
  45. // 绘制线
  46. PaintStyle: {
  47. stroke: '#6891a4',
  48. strokeWidth: 3
  49. },
  50. // 绘制箭头
  51. Overlays: [
  52. ['Arrow', {
  53. width: 12,
  54. length: 12,
  55. location: 1
  56. }]
  57. ],
  58. RenderMode: "svg"
  59. };
  60. // jsplumb连接参数
  61. var jsplumbConnectOptions = {
  62. isSource: true,
  63. isTarget: true,
  64. // 动态锚点、提供了4个方向 Continuous、AutoDefault
  65. anchor: "Continuous"
  66. };
  67. var jsplumbSourceOptions = {
  68. /*"span"表示标签,".className"表示类,"#id"表示元素id*/
  69. filter: ".flow-node-drag",
  70. filterExclude: false,
  71. anchor: "Continuous",
  72. allowLoopback: false
  73. };
  74. var jsplumbTargetOptions = {
  75. /*"span"表示标签,".className"表示类,"#id"表示元素id*/
  76. filter: ".flow-node-drag",
  77. filterExclude: false,
  78. anchor: "Continuous",
  79. allowLoopback: false
  80. };
  81. //设置连接属性
  82. function setConn(condiVal, condiExpr) {
  83. _currConn.setLabel({
  84. label: condiVal,
  85. cssClass: 'labelClass'
  86. });
  87. var from = _currConn.sourceId;
  88. var to = _currConn.targetId;
  89. $(transList).each(function (idx, line) {
  90. if (line.fromStepId === from && line.toStepId === to) {
  91. line['condiExpr'] = condiExpr;
  92. line['condiVal'] = condiVal;
  93. }
  94. });
  95. }
  96. //删除jsPlumb实例连线
  97. function delConn() {
  98. if (prevFlag) {
  99. return;
  100. }
  101. jsPlumb.deleteConnection(_currConn);
  102. }
  103. //删除jsPlumb连线后回调,删除transList中的数据
  104. function deleteTransList(from, to) {
  105. transList = transList.filter(function (step) {
  106. return (step.fromStepId != from) && (step.toStepId != to)
  107. });
  108. }
  109. //添加节点
  110. function addNode(node, updateFlag) {
  111. //alert(jsplumbInstance)
  112. //node。id
  113. if (!updateFlag) {
  114. stepList.push(node);
  115. }
  116. drawNode(node);
  117. if (prevFlag) {
  118. return;
  119. }
  120. //设置源点,可以拖出线连接其他节点
  121. jsPlumb.makeSource(node.stepId, jsplumbSourceOptions);
  122. // // 设置目标点,其他源点拖出的线可以连接该节点
  123. jsPlumb.makeTarget(node.stepId, jsplumbTargetOptions);
  124. //设置拖拽范围为父级容器
  125. jsPlumb.draggable(node.stepId, {
  126. containment: 'parent'
  127. });
  128. }
  129. //展示节点编辑按钮
  130. function onmouseoverNode(e) {
  131. $(e).find(".flow-node-operate").show();
  132. }
  133. //隐藏节点编辑按钮
  134. function onmouseoutNode(e) {
  135. $(e).find(".flow-node-operate").hide();
  136. }
  137. //绘制节点html
  138. function drawNode(node) {
  139. // var node = ['<div id="' + node.stepId +
  140. // '" class="nodeBox" onmouseup="changeNodeSite(this)" onmouseover="onmouseoverNode(this)" onmouseout="onmouseoutNode(this)" style="left:' +
  141. // node.posLeft + ';top:' + node.posTop + '">',
  142. // '<div class="flow-node-header">',
  143. // '<span class="fa fa-bars flow-node-drag"></span>',
  144. // '<div class="flow-node-operate" style="display:none;">',
  145. // '<span onclick="editNode(this)" >编辑</span>&nbsp;',
  146. // '<span onclick="deleteNode(this)" >删除</span>&nbsp;',
  147. // '</div>',
  148. // '</div>',
  149. // '<div class="flow-node-body">' + node.stepName + '</div>',
  150. // '</div>'
  151. // ].join('');
  152. var node = '<div id=' + node.stepId + ' class="nodeBox nodetype' + node.type + ' nodeShowSts' + node.showSts + '" onmousemove="changeNodePosition.call(this)" onmouseup="changeNodeSite(this)" onmouseover="onmouseoverNode(this)" onmouseout="onmouseoutNode(this)" style="left:' + node.posLeft + ';top:' + node.posTop + '">' +
  153. '<div class="tools">' +
  154. '<svg class="icon editNode" aria-hidden="true" onclick="editNode(this)">' +
  155. '<use xlink:href="#iconbianji"></use>' +
  156. '</svg>' +
  157. '<svg class="icon deleteNode" aria-hidden="true" onclick="deleteNode(this)">' +
  158. '<use xlink:href="#iconshanchu"></use>' +
  159. '</svg>' +
  160. '</div>' +
  161. '<div class="flow-node-body">' +
  162. '<span>' +
  163. '<span class="fa fa-bars flow-node-drag"></span>' +
  164. '<svg class="icon " aria-hidden="true">' +
  165. '<use xlink:href="#iconlianjie"></use>' +
  166. '</svg>' +
  167. '</span>' +
  168. '&nbsp;' +
  169. '&nbsp;' +
  170. '<div class="div-stepName">' + node.stepName + '</div>' +
  171. '</div>' +
  172. '</div>'
  173. $("#flowBox").append(node);
  174. }
  175. function editNode(e) {
  176. if (prevFlag) {
  177. return;
  178. }
  179. var currentNode = $(e).parents(".nodeBox");
  180. var nodeId = currentNode.attr("id");
  181. _currNodeId = nodeId;
  182. var node = getNodeInfo(_currNodeId)
  183. if (node.type === 'task') {
  184. util.openWin("setNode_" + node.type + ".html?stepId=" + node.stepId, node.stepName, 600, 400);
  185. } else {
  186. util.openWin("setNode_" + node.type + ".html?stepId=" + node.stepId, node.stepName, 600, 240);
  187. }
  188. //alert("待处理编辑节点界面,nodeId="+nodeId);
  189. }
  190. //变更节点位置
  191. function changeNodeSite(e) {
  192. if (prevFlag) {
  193. return;
  194. }
  195. var data = {};
  196. data.nodeId = $(e).attr("id");
  197. data.posLeft = $(e).css("left");
  198. data.posTop = $(e).css("top");
  199. for (var i = 0; i < stepList.length; i++) {
  200. var node = stepList[i];
  201. if (node.stepId == data.nodeId) {
  202. node.posLeft = data.posLeft;
  203. node.posTop = data.posTop;
  204. }
  205. }
  206. }
  207. //鼠标移动事件
  208. function changeNodePosition() {
  209. if (prevFlag) {
  210. return;
  211. }
  212. let element = this
  213. drag(element, document.querySelector('.flowRightItem'))
  214. // var el = (typeof element == "string") ? document.getElementById(element) : element;
  215. // if (el.parentNode === null || el.style.display == 'none') {
  216. // return false;
  217. // }
  218. // console.log(`Y--------${el.offsetTop - el.parentNode.offsetTop + 118}-----X---------${el.offsetLeft - el.parentNode.offsetLeft + 243}`);
  219. // // console.log(el.offsetLeft - el.parentNode.offsetLeft);
  220. // console.log(`${el.parentNode.clientHeight}----------${el.parentNode.clientWidth}`);
  221. // return el.offsetTop - el.parentNode.offsetTop;
  222. }
  223. function drag(obj, document) {
  224. if (prevFlag) {
  225. return;
  226. }
  227. obj.onmousedown = function (ev) {
  228. var ev = ev || event;
  229. console.log(this);
  230. var disX = ev.clientX - this.offsetLeft;
  231. var disY = ev.clientY - this.offsetTop;
  232. document.onmousemove = function (ev) {
  233. var ev = ev || event;
  234. var L = ev.clientX - disX; //拖动元素左侧的位置=当前鼠标距离浏览器左侧的距离 - (物体宽度的一半)
  235. var T = ev.clientY - disY; //拖动元素顶部的位置=当前鼠标距离浏览器顶部的距离 - (物体高度的一半)
  236. console.log(L);
  237. console.log(T);
  238. }
  239. document.onmouseup = function () {
  240. document.onmousemove = document.onmouseup = null;
  241. if (obj.releaseCapture) {
  242. obj.releaseCapture();
  243. }
  244. }
  245. return false;
  246. }
  247. }
  248. //删除节点
  249. function deleteNode(e) {
  250. var currentNode = $(e).parents(".nodeBox");
  251. var nodeId = currentNode.attr("id");
  252. _currNodeId = nodeId;
  253. util.showDialog("确认删除环节么?", 3, doDeleteNode);
  254. }
  255. function doDeleteNode() {
  256. stepList = stepList.filter(function (node) {
  257. if (node.stepId === _currNodeId) {
  258. // // 伪删除,将节点隐藏,否则会导致位置错位
  259. // node.show = false;
  260. // $("#" + _currNodeId).hide();
  261. $("#" + _currNodeId).remove();
  262. return false;
  263. }
  264. return true
  265. });
  266. setInterval(function () {
  267. jsPlumb.removeAllEndpoints(_currNodeId);
  268. }, 50);
  269. }
  270. //编辑流程信息
  271. function editFlowInfo() {
  272. util.openWin("editFlow.html", "流程信息", 600, 240);
  273. }
  274. //设置流程信息
  275. function setFlowInfo(procName, processDesc) {
  276. if (procName) {
  277. processInfo["procName"] = procName;
  278. }
  279. if (processDesc) {
  280. processInfo["processDesc"] = processDesc;
  281. }
  282. }
  283. //保存流程信息
  284. function saveFlowInfo() {
  285. util.showDialog("确认保存流程信息么?", 3, doSaveFlowInfo);
  286. }
  287. function addRow() {
  288. var lastChild = $("#ydt").children('.div-row-last')
  289. lastChild.after($('<div class="div-row div-row-last " style="height:' + border + 'px;left:0px; top:' + (parseInt(lastChild.css("top").replace("px", '')) + defaultH + border) + 'px"></div>'));
  290. lastChild.after($('<div class="div-col-content" style="top:' + (parseInt(lastChild.css("top").replace("px", '')) + border) + 'px;height:' + defaultH +
  291. 'px">行</div>'));
  292. lastChild.after($('<div class="div-col-title div-display" style="top:' + (parseInt(lastChild.css("top").replace("px", '')) + border) + 'px;height:' +
  293. defaultH + 'px"><textarea ></textarea></div>'));
  294. lastChild.removeClass('div-row-last');
  295. var lastTop = $(".div-row-last").height() + parseInt($(".div-row-last").css("top").replace("px", ""));
  296. var updateHeight = lastTop > $("#ydt").height() ? lastTop : $("#ydt").height();
  297. $.each($(".div-col ,.div-col-first"), function () {
  298. $(this).height(updateHeight);
  299. });
  300. }
  301. function addCol() {
  302. var lastChild = $("#ydt").children('.div-col-last')
  303. lastChild.after($('<div class="div-col div-col-last" style="width:' + border + 'px;top:0px;height:' + lastChild.height() + 'px;left:' + (parseInt(lastChild.css("left").replace("px", '')) + defaultW + border) +
  304. 'px"></div>'));
  305. lastChild.after($('<div class="div-row-content" style="left:' + (parseInt(lastChild.css("left").replace("px", '')) + border) + 'px;width:' + defaultW + 'px;">列</div>'));
  306. lastChild.after($('<div class="div-row-title div-display" style="left:' + (parseInt(lastChild.css("left").replace("px", '')) + border) + 'px;width:' + defaultW + 'px;"><textarea ></textarea></div>'));
  307. lastChild.removeClass('div-col-last');
  308. var lastLeft = $(".div-col-last").width() + parseInt($(".div-col-last").css("left").replace("px", ""));
  309. var updateWidth = lastLeft > $("#ydt").width() ? lastLeft : $("#ydt").width();
  310. $.each($(".div-row ,.div-row-first"), function () {
  311. $(this).width(updateWidth);
  312. });
  313. }
  314. function initColRow(colNum, rowNum) {
  315. var h = $("#ydt").height();
  316. var w = $("#ydt").width();
  317. for (var i = 0; i < colNum; i++) {
  318. var left = defaultW;
  319. var colLeft = (defaultW + border) * (i + 1) + defaultBtn;
  320. if (i == 0) {
  321. $("#ydt").append($('<div class="div-col-first " style="width:' + border + 'px; top:0px;left: ' + defaultBtn + 'px"></div>'));
  322. $("#ydt").append($('<div class="div-row-title div-display" style="left:' + (defaultBtn + border) + 'px;width:' +
  323. left + 'px;"><textarea ></textarea></div>'));
  324. $("#ydt").append($('<div class="div-row-content" style="left:' + (defaultBtn + border) + 'px;width:' + left +
  325. 'px;">列</div>'));
  326. }
  327. var lastCol = (i + 1 == colNum) ? 'div-col-last' : '';
  328. $("#ydt").append($('<div class="div-col ' + lastCol + '" style="width:' + border + 'px;top:0px;left:' + colLeft +
  329. 'px"></div>'));
  330. if (i + 1 != colNum) {
  331. $("#ydt").append($('<div class="div-row-title div-display" style="left:' + (colLeft + border) + 'px;width:' + (left) + 'px;"><textarea ></textarea></div>'));
  332. $("#ydt").append($('<div class="div-row-content" style="left:' + (colLeft + border) + 'px;width:' + (left) + 'px;">列</div>'));
  333. }
  334. }
  335. for (var i = 0; i < rowNum; i++) {
  336. var top = defaultBtn + (defaultH + border) * (i + 1);
  337. var topHeight = defaultH;
  338. if (i == 0) {
  339. $("#ydt").append($('<div class="div-row-first" style=" top:' + defaultBtn + 'px;left:0;height:' + border + 'px;"></div>'));
  340. $("#ydt").append($('<div class="div-col-title div-display" style="top:' + (defaultBtn + border) + 'px;height:' +
  341. topHeight + 'px"><textarea ></textarea></div>'));
  342. $("#ydt").append($('<div class="div-col-content" style="top:' + (defaultBtn + border) + 'px;height:' + topHeight +
  343. 'px">行</div>'));
  344. }
  345. var lastRow = (i + 1 == rowNum) ? 'div-row-last' : '';
  346. $("#ydt").append($('<div class="div-row ' + lastRow + '" style="height:' + border + 'px;left:0px; top:' + top + 'px"></div>'));
  347. if (i + 1 != rowNum) {
  348. $("#ydt").append($('<div class="div-col-title div-display" style="top:' + (top + border) + 'px;height:' +
  349. topHeight + 'px"><textarea ></textarea></div>'));
  350. $("#ydt").append($('<div class="div-col-content" style="top:' + (top + border) + 'px;height:' + topHeight +
  351. 'px">行</div>'));
  352. }
  353. }
  354. }
  355. function initFirstLeftTop() {
  356. if (prevFlag) {
  357. return;
  358. }
  359. //2020年11月5日14:57:24 JIANGYONG 修改
  360. $("#ydt").append($('<div class="div-first" style="width:40px;top:0px;height:40px;left:">' +
  361. '<ul>' +
  362. '<li onClick="addRow();dynaEvent()">增加行</li>' +
  363. '<li onClick="addCol();dynaEvent()">增加列</li>' +
  364. '</ul>' +
  365. '<svg class="icon" aria-hidden="true">' +
  366. '<use xlink:href="#icongengduo"></use>' +
  367. '</svg>' +
  368. '</div>'
  369. ))
  370. }
  371. function loadColRow(swimList) {
  372. var colArr = new Array();
  373. var rowArr = new Array();
  374. // 0是row 1是col
  375. swimList.forEach(function (item, i) {
  376. if (item.cellType == '1') {
  377. colArr.push(item);
  378. return true;
  379. }
  380. rowArr.push(item);
  381. })
  382. var w = $("#ydt").width();
  383. var h = $("#ydt").height();
  384. if (rowArr.length == 0) {
  385. initColRow(1, 0);
  386. }
  387. for (var i = 0; i < rowArr.length; i++) {
  388. var colCss = i == 0 ? 'div-col-first' : 'div-col'
  389. $("#ydt").append($('<div class="' + colCss + '" style="width:' + border + 'px;top:0px;bottom:0px; left:' + (parseInt(rowArr[i].posLeft.replace("px", "")) - 5) +
  390. 'px"></div>'));
  391. $("#ydt").append($('<div class="div-row-title div-display" style="left:' + rowArr[i].posLeft + ';width:' + rowArr[i].cellWidth + 'px;"><textarea ></textarea></div>'));
  392. $("#ydt").append($('<div class="div-row-content" style="left:' + rowArr[i].posLeft + ';width:' + rowArr[i].cellWidth + 'px;">' + rowArr[i].title + '</div>'));
  393. if (i + 1 == rowArr.length) {
  394. console.log(parseInt(rowArr[i].posLeft.replace("px", "")) + "," + rowArr[i].cellWidth);
  395. $("#ydt").append($('<div class="' + colCss + ' div-col-last" style="width:' + border + 'px;top:0px;bottom:0px;left:' + (parseInt(rowArr[i].posLeft.replace("px", "")) - 5 + parseInt(rowArr[i].cellWidth)) +
  396. 'px"></div>'));
  397. console.log($(".div-col-last").css("left"));
  398. }
  399. }
  400. if (colArr.length == 0) {
  401. initColRow(0, 1);
  402. }
  403. for (var i = 0; i < colArr.length; i++) {
  404. var rowCss = i == 0 ? 'div-row-first' : 'div-row'
  405. $("#ydt").append($('<div class="' + rowCss + '" style="height:' + border + 'px;left:0px;right:0px; top:' + (parseInt(colArr[i].posTop.replace('px', '')) - 5) + 'px"></div>'));
  406. $("#ydt").append($('<div class="div-col-title div-display" style="top:' + colArr[i].posTop + ';height:' +
  407. colArr[i].cellHeight + 'px"><textarea ></textarea></div>'));
  408. $("#ydt").append($('<div class="div-col-content" style="top:' + colArr[i].posTop + ';height:' + colArr[i].cellHeight +
  409. 'px">' + colArr[i].title + '</div>'));
  410. if (i + 1 == colArr.length) {
  411. $("#ydt").append($('<div class="' + rowCss + ' div-row-last" style="height:' + border + 'px;right:0px;left:0px; top:' + (parseInt(colArr[i].posTop.replace('px', '')) - 5 + parseInt(colArr[i].cellHeight)) + 'px"></div>'));
  412. }
  413. }
  414. }
  415. function dynaEvent() {
  416. if (prevFlag) {
  417. return;
  418. }
  419. var sourceNum = 0;
  420. var sourceTop = 0;
  421. var prevSource = null;
  422. var nextSource = null;
  423. $(".div-col").draggable(
  424. {
  425. axis: "x",
  426. scroll: true,
  427. start: function (e, ui) {
  428. sourceNum = ui.position.left;
  429. prevSource = { left: $(e.target).prev().css('left'), width: $(e.target).prev().width() };
  430. nextSource = { left: $(e.target).next().css('left'), width: $(e.target).next().width() };
  431. },
  432. drag: function (e, ui) {
  433. var flag = offsetLeft(e.target, ui.position.left - sourceNum);
  434. if (!flag) {
  435. return;
  436. }
  437. sourceNum = ui.position.left;
  438. },
  439. stop: function (e, ui) {
  440. var revert = $(".div-col").draggable("option", "revert");
  441. if (revert) {
  442. resetLeft(e.target, prevSource, nextSource);
  443. }
  444. $(".div-col").draggable({ revert: false });
  445. }
  446. }
  447. );
  448. $(".div-row").draggable(
  449. {
  450. axis: "y",
  451. scroll: true,
  452. start: function (e, ui) {
  453. sourceNum = ui.position.top;
  454. prevSource = { top: $(e.target).prev().css('top'), height: $(e.target).prev().height() };
  455. nextSource = { top: $(e.target).next().css('top'), height: $(e.target).next().height() };
  456. },
  457. drag: function (e, ui) {
  458. var flag = offsetTop(e.target, ui.position.top - sourceNum);
  459. if (!flag) {
  460. return;
  461. }
  462. sourceNum = ui.position.top;
  463. },
  464. stop: function (e, ui) {
  465. var revert = $(".div-row").draggable("option", "revert");
  466. if (revert) {
  467. resetTop(e.target, prevSource, nextSource);
  468. }
  469. $(".div-row").draggable({ revert: false });
  470. }
  471. }
  472. );
  473. $('div.div-row-content,div.div-col-content').contextMenu('myMenu1',
  474. {
  475. bindings:
  476. {
  477. 'deleteBtn': function (t) {
  478. dynaCol(t);
  479. if ($(t).next().hasClass('div-col-last')) {
  480. $(t).prev().prev().addClass('div-col-last')
  481. }
  482. dynaRow(t);
  483. if ($(t).next().hasClass('div-row-last')) {
  484. $(t).prev().prev().addClass('div-row-last');
  485. }
  486. $(t).prev().remove();
  487. $(t).next().remove();
  488. $(t).remove();
  489. }
  490. }
  491. });
  492. }
  493. function dynaRow(t) {
  494. if ($(t).hasClass('div-col-content') && !$(t).next().hasClass('div-row-last')) {
  495. var height = $(t).height() + $(t).next().height();
  496. var title = $(t).next().next();
  497. var content = title.next();
  498. var col = content.next();
  499. content.attr('style', 'top:' + (parseInt(content.css('top').replace('px', '')) - height) + 'px;height:' + content.height() + 'px');
  500. title.attr('style', 'top:' + (parseInt(title.css('top').replace('px', '')) - height) + ';height:' + title.height() + 'px');
  501. col.attr('style', 'top:' + (parseInt(col.css('top').replace('px', '')) - height) + ';width:' + col.width() + 'px;height:' + col.height() + 'px');
  502. return dynaRow($(t).next().next().next());
  503. }
  504. }
  505. function dynaCol(t) {
  506. if ($(t).hasClass('div-row-content') && !$(t).next().hasClass('div-col-last')) {
  507. var width = $(t).width() + $(t).next().width();
  508. var title = $(t).next().next();
  509. var content = title.next();
  510. var col = content.next();
  511. content.attr('style', 'left:' + (parseInt(content.css('left').replace('px', '')) - width) + 'px;width:' + content.width() + 'px');
  512. title.attr('style', 'left:' + (parseInt(title.css('left').replace('px', '')) - width) + ';width:' + title.width() + 'px');
  513. col.attr('style', 'left:' + (parseInt(col.css('left').replace('px', '')) - width) + ';width:' + col.width() + 'px;height:' + col.height() + 'px');
  514. return dynaCol($(t).next().next().next());
  515. }
  516. }
  517. function addContentEvent() {
  518. if (prevFlag) {
  519. return;
  520. }
  521. $(document.body).delegate('.div-col-content,.div-row-content', 'dblclick', function (e) {
  522. $(this).prev().toggleClass('div-display');
  523. $(this).prev().find("textarea").val($(this).html());
  524. $(this).toggleClass('div-display');
  525. })
  526. $(document.body).delegate('div', 'click', function (e) {
  527. if ($(this).hasClass('div-row-title') || $(this).hasClass('div-col-title') || $(this).hasClass('div-col-content') ||
  528. $(this).hasClass('div-row-content')) {
  529. e.stopPropagation();
  530. return;
  531. }
  532. $.each($($('.div-col-title:not(.div-display),.div-row-title:not(.div-display)')), function () {
  533. $(this).next().toggleClass('div-display');
  534. $(this).toggleClass('div-display');
  535. $(this).next().html($(this).find("textarea").val());
  536. });
  537. })
  538. dynaEvent();
  539. $('.div-first').contextMenu('myMenu2',
  540. {
  541. bindings:
  542. {
  543. 'addRow': function (t) {
  544. addRow();
  545. dynaEvent();
  546. },
  547. 'addCol': function (t) {
  548. addCol();
  549. dynaEvent();
  550. }
  551. }
  552. });
  553. }
  554. function resetTop(dom, nextSource, prevSource) {
  555. var content = $(dom).next().next();
  556. var prevContent = $(dom).prev();
  557. var title = $(dom).next();
  558. var prevTitle = $(dom).prev().prev();
  559. content.attr('style', 'top:' + prevSource.top + ';height:' + prevSource.height + 'px')
  560. title.attr('style', 'top:' + prevSource.top + ';height:' + prevSource.height + 'px')
  561. prevContent.attr('style', 'top:' + nextSource.top + ';height:' + nextSource.height + 'px')
  562. prevTitle.attr('style', 'top:' + nextSource.top + ';height:' + nextSource.height + 'px')
  563. }
  564. function offsetTop(dom, offTop, flag) {
  565. var content = $(dom).next().next();
  566. var prevContent = $(dom).prev();
  567. var title = $(dom).next('.div-col-title');
  568. var prevTitle = $(dom).prev().prev();
  569. var prevTitleWidth = prevTitle.height() + offTop;
  570. var prevContentWith = prevContent.height() + offTop;
  571. if ((title.length > 0 && title.height() < 50) || prevContent.height() < 50) {
  572. $(".div-row").draggable({ revert: true });
  573. return false;
  574. }
  575. if (title.length > 0) {
  576. var contentWidth = content.height() - offTop;
  577. var titleWidth = title.height() - offTop;
  578. content.attr('style', 'top:' + (parseInt(content.css("top").replace('px', '')) + offTop) + 'px;height:' + contentWidth + 'px')
  579. title.attr('style', 'top:' + (parseInt(title.css("top").replace('px', '')) + offTop) + 'px;height:' + titleWidth + 'px')
  580. }
  581. prevContent.attr('style', 'top:' + prevContent.css("top") + ';height:' + prevContentWith + 'px')
  582. prevTitle.attr('style', 'top:' + prevTitle.css("top") + ';height:' + prevTitleWidth + 'px')
  583. return true;
  584. }
  585. function resetLeft(dom, nextSource, prevSource) {
  586. var content = $(dom).next().next();
  587. var prevContent = $(dom).prev();
  588. var title = $(dom).next('.div-row-title');
  589. var prevTitle = $(dom).prev().prev();
  590. if (title.length > 0) {
  591. content.attr('style', 'left:' + prevSource.left + ';width:' + prevSource.width + 'px')
  592. title.attr('style', 'left:' + prevSource.left + ';width:' + prevSource.width + 'px')
  593. } else {
  594. }
  595. prevContent.attr('style', 'left:' + nextSource.left + ';width:' + nextSource.width + 'px')
  596. prevTitle.attr('style', 'left:' + nextSource.left + ';width:' + nextSource.width + 'px')
  597. }
  598. function offsetLeft(dom, offLeft) {
  599. var title = $(dom).next('.div-row-title');
  600. var content = $(dom).next().next();
  601. var prevTitle = $(dom).prev().prev();
  602. var prevContent = $(dom).prev();
  603. var prevTitleWidth = prevTitle.width() + offLeft;
  604. var prevContentWith = prevContent.width() + offLeft;
  605. if ((title.length > 0 && title.width() < 50) || prevContent.width() < 50) {
  606. $(".div-col").draggable({ revert: true });
  607. return false;
  608. }
  609. if (title.length > 0) {
  610. var contentWidth = content.width() - offLeft;
  611. var titleWidth = title.width() - offLeft;
  612. content.attr('style', 'left:' + (parseInt(content.css("left").replace("px", '')) + offLeft) + 'px;width:' + contentWidth + 'px')
  613. title.attr('style', 'left:' + (parseInt(title.css("left").replace("px", '')) + offLeft) + 'px;width:' + titleWidth + 'px')
  614. }
  615. prevContent.attr('style', 'left:' + prevContent.css("left") + ';width:' + prevContentWith + 'px')
  616. prevTitle.attr('style', 'left:' + prevTitle.css("left") + ';width:' + prevTitleWidth + 'px')
  617. return true;
  618. }
  619. var bean = { cellType: '', cellTypeName: '', title: '', cellWidth: '', cellHeight: '', posLeft: '', posTop: '', orderNum: '' }
  620. var border = 1;
  621. var defaultW = 200;
  622. var defaultH = 200;
  623. var defaultBtn = 40;
  624. function saveInitYdT() {
  625. var orderNum = 1;
  626. var arr = new Array();
  627. // 0是row 1是col
  628. $.each($('.div-col-content'), function () {
  629. var col = $.extend({}, bean);
  630. col.cellType = '1';
  631. col.cellTypeName = '列';
  632. col.title = $(this).html();
  633. col.cellWidth = $(this).width();
  634. col.cellHeight = $(this).height();
  635. col.posLeft = $(this).css('left');
  636. col.posTop = $(this).css('top');
  637. col.orderNum = orderNum;
  638. arr.push(col);
  639. orderNum++;
  640. });
  641. $.each($('.div-row-content'), function () {
  642. var row = $.extend({}, bean);
  643. row.cellType = '0';
  644. row.cellTypeName = '行';
  645. row.title = $(this).html();
  646. row.cellWidth = $(this).width();
  647. row.cellHeight = $(this).height();
  648. row.posLeft = $(this).css('left');
  649. row.posTop = $(this).css('top');
  650. row.orderNum = orderNum;
  651. arr.push(row);
  652. orderNum++;
  653. });
  654. return arr;
  655. }
  656. function doSaveFlowInfo() {
  657. //alert("in save flow 2")
  658. let list = [];
  659. for(let i=0;i<transList.length;i++){
  660. let sts =true;
  661. for(let j=0;j<list.length;j++){
  662. if(transList[i].fromStepId === list[j].fromStepId && transList[i].toStepId === list[j].toStepId){
  663. sts = false;
  664. }
  665. }
  666. if(sts){
  667. list.push(transList[i]);
  668. }
  669. }
  670. var process = {
  671. "proc": processInfo,
  672. "stepList": stepList,
  673. "transList": list,
  674. "swimList": saveInitYdT()
  675. }
  676. var url = ctx + "/bpm/api/saveFlow";
  677. util.ajaxJson("保存中,请稍后...", url, process, function (data) {
  678. var result = data.result;
  679. var desc = data.desc;
  680. if (result == 0) {
  681. var retProc = data.body;
  682. processInfo['procId'] = retProc.proc.procId;
  683. util.showDialog("保存成功", 2);
  684. } else {
  685. util.showDialog("保存失败", 0);
  686. }
  687. }, undefined, false);
  688. }
  689. //根据nodeId获取node的数据信息
  690. function getNodeInfo(nodeId) {
  691. var retNode;
  692. $(stepList).each(function (idx, node) {
  693. if (nodeId === node.stepId) {
  694. retNode = node;
  695. // alert(JSON.stringify(retNode))
  696. }
  697. });
  698. return retNode;
  699. }
  700. //设置环节信息
  701. function setNode(params) {
  702. var node = getNodeInfo(_currNodeId);
  703. $.extend(true, node, params);
  704. $("#" + _currNodeId).find(".div-stepName").html(params.stepName);
  705. }
  706. //加载流程数据
  707. function loadFlowData() {
  708. var url = ctx + "/bpm/api/loadFlow";
  709. var urlParam = util.getUrlParam();
  710. util.ajaxJson("加载中,请稍后...", url, urlParam, function (data) {
  711. var result = data.result;
  712. var desc = data.desc;
  713. if (result == 0) {
  714. var retProc = data.body;
  715. stepList = retProc.stepList;
  716. transList = retProc.transList;
  717. processInfo = retProc.proc;
  718. loadFlow();
  719. if (retProc.swimList.length != 0) {
  720. loadColRow(retProc.swimList);
  721. addContentEvent();
  722. return;
  723. }
  724. initYdt();
  725. } else {
  726. util.showDialog("加载失败", 0);
  727. }
  728. }, undefined, false);
  729. }
  730. function loadFlow() {
  731. // $("#flowBox").empty();
  732. // 初始化节点
  733. for (var i = 0; i < stepList.length; i++) {
  734. var node = stepList[i];
  735. addNode(node, true)
  736. }
  737. var transLength = transList.length;
  738. // 初始化连线
  739. //alert("transList.len="+transList.length);
  740. //alert(JSON.stringify(transList))
  741. for (var i = 0; i < transList.length; i++) {
  742. var line = transList[i];
  743. var curline = jsPlumb.connect({
  744. source: line.fromStepId,
  745. target: line.toStepId
  746. }, jsplumbConnectOptions);
  747. //transList[i].conn_id = curline.id;
  748. if (line.condiVal != "" && line.condiVal != null) {
  749. curline.setLabel({
  750. label: line.condiVal,
  751. cssClass: 'labelClass'
  752. })
  753. }
  754. }
  755. transList.splice(transLength);
  756. initFlow();
  757. }
  758. function initFlowCondi() {
  759. jsPlumb.importDefaults(jsplumbSetting);
  760. jsPlumb.setContainer('flowBox');
  761. jsPlumb.setSuspendDrawing(false, true);
  762. var urlParam = util.getUrlParam();
  763. initFirstLeftTop();
  764. if (util.isNull(urlParam.procId)) {
  765. initFlow();
  766. initYdt();
  767. return;
  768. }
  769. //修改流程时加载流程数据--xiacj根据流程id判断
  770. loadFlowData();
  771. }
  772. function initYdt() {
  773. initColRow(2, 2);
  774. addContentEvent();
  775. }
  776. function initFlow() {
  777. if (prevFlag) {
  778. return;
  779. }
  780. $(".menuItems").draggable({
  781. helper: 'clone',
  782. scope: 'ss'
  783. });
  784. $("#flowBox").droppable({
  785. scope: 'ss',
  786. drop: function (event, ui) {
  787. var $btn = $(ui.draggable[0]).find(".btn");
  788. var node = {};
  789. //环节id
  790. node.stepId = "node" + Math.random().toString(36).substr(3, 10);
  791. //环节名称
  792. node.stepName = $btn.attr("data_name");
  793. //环节类型
  794. node.type = $btn.attr("data_type");
  795. node.userType = 1;
  796. node.pushType = 1;
  797. node.show = true;
  798. node.posLeft = (ui.position.left - 100) + "px";
  799. node.posTop = (ui.position.top - 50) + "px";
  800. addNode(node, false);
  801. }
  802. });
  803. //单击连线设置条件或者删除连线
  804. jsPlumb.bind("click", function (conn, originalEvent) {
  805. //记录当前连接
  806. _currConn = conn;
  807. var fromStepId = conn.sourceId;
  808. var toStepId = conn.targetId;
  809. var condiVal = "",
  810. condiExpr = "";
  811. $(transList).each(function (idx, trans) {
  812. if (trans.fromStepId === fromStepId && trans.toStepId == toStepId) {
  813. condiVal = trans['condiVal'];
  814. condiExpr = trans['condiExpr'];
  815. }
  816. });
  817. util.openWin("setCondi.html?condiVal=" + condiVal + "&condiExpr=" + condiExpr, "连线设置", 600, 300);
  818. });
  819. //连线事件处理
  820. jsPlumb.bind("connection", function (evt) {
  821. var from = evt.source.id;
  822. var to = evt.target.id;
  823. transList.push({
  824. "fromStepId": from,
  825. "toStepId": to
  826. })
  827. });
  828. //删除jsPlumb连线回调
  829. jsPlumb.bind("connectionDetached", function (evt) {
  830. deleteTransList(evt.sourceId, evt.targetId)
  831. });
  832. }
  833. var prevFlag = false;
  834. $(document).ready(function () {
  835. var param = util.getUrlParam();
  836. prevFlag = util.isNull(param.prevFlag) ? false : param.prevFlag;
  837. jsPlumb.ready(initFlowCondi);
  838. });