learun-flowlayout.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. //初始化设计流程器
  2. $.fn.flowdesign = function (options) {
  3. var $frmpreview = $(this);
  4. if (!$frmpreview.attr('id')) {
  5. return false;
  6. }
  7. var FlowPanel;
  8. $frmpreview.html("");
  9. var defaults = {
  10. flowcontent: "",
  11. frmtype: 0,//自定义表单0,系统表单1
  12. frmData: "",
  13. width: $(window).width(),
  14. height: $(window).height() + 2,
  15. OpenNode: function () { return false},
  16. OpenLine: function () { return false },
  17. NodeRemarks: {
  18. cursor: "选择指针",
  19. direct: "步骤连线",
  20. startround: "开始节点",
  21. endround: "结束节点",
  22. stepnode: "普通节点",
  23. shuntnode: "分流节点",
  24. confluencenode: "合流节点",
  25. group: "区域规划"
  26. },
  27. haveTool:true,
  28. toolBtns: ["startround", "endround", "stepnode", "shuntnode", "confluencenode"],
  29. isprocessing: false,
  30. nodeData: null,
  31. activityId: "",
  32. preview:0
  33. };
  34. var options = $.extend(defaults, options);
  35. FlowPanel = $.createGooFlow($(this), {
  36. width: options.width,
  37. height: options.height,
  38. haveHead: true,
  39. headBtns: ["undo", "redo"],
  40. haveTool: options.haveTool,
  41. toolBtns: options.toolBtns,
  42. haveGroup: true,
  43. useOperStack: true
  44. });
  45. FlowPanel.setNodeRemarks(options.NodeRemarks);
  46. FlowPanel.loadData(options.flowcontent);
  47. OpenNode = options.OpenNode;
  48. OpenLine = options.OpenLine;
  49. //导出数据扩展方法
  50. //所有节点必须有进出线段
  51. //必须有开始结束节点(且只能为一个)
  52. //分流合流节点必须成对出现
  53. //分流合流节点必须一一对应且中间必须有且只能有一个普通节点
  54. //分流节点与合流节点之前的审核节点必须有且只能有一条出去和进来节点
  55. FlowPanel.exportDataEx = function () {
  56. var _data = FlowPanel.exportData();
  57. var _fromlines = {}, _tolines = {}, _nodes = {}, _fnodes = [], _hnodes = [], _startroundFlag = 0, _endroundFlag = 0;
  58. for (var i in _data.lines)
  59. {
  60. if (_fromlines[_data.lines[i].from] == undefined)
  61. {
  62. _fromlines[_data.lines[i].from] = [];
  63. }
  64. _fromlines[_data.lines[i].from].push(_data.lines[i].to);
  65. if (_tolines[_data.lines[i].to] == undefined) {
  66. _tolines[_data.lines[i].to] = [];
  67. }
  68. _tolines[_data.lines[i].to].push(_data.lines[i].from);
  69. }
  70. for (var j in _data.nodes)
  71. {
  72. var _node = _data.nodes[j];
  73. var _flag = false;
  74. switch (_node.type)
  75. {
  76. case "startround":
  77. _startroundFlag++;
  78. if (_fromlines[_node.id] == undefined) {
  79. dialogTop("开始节点无法流转到下一个节点", "error");
  80. return -1;
  81. }
  82. break;
  83. case "endround":
  84. _endroundFlag++;
  85. if ( _tolines[_node.id] == undefined) {
  86. dialogTop("无法流转到结束节点", "error");
  87. return -1;
  88. }
  89. break;
  90. case "stepnode":
  91. _flag = true;
  92. break;
  93. case "shuntnode":
  94. _flag = true;
  95. _fnodes.push(_node.id);
  96. break;
  97. case "confluencenode":
  98. _hnodes.push(_node.id);
  99. _flag = true;
  100. break;
  101. default:
  102. dialogTop("节点数据异常,请重新登录下系统!", "error");
  103. return -1;
  104. break;
  105. }
  106. if (_flag)
  107. {
  108. if (_tolines[_node.id] == undefined) {
  109. labellingRedNode(_node.id);
  110. dialogTop("标注红色的节点没有【进来】的连接线段", "error");
  111. return -1;
  112. }
  113. if (_fromlines[_node.id] == undefined) {
  114. labellingRedNode(_node.id);
  115. dialogTop("标注红色的节点没有【出去】的连接线段", "error");
  116. return -1;
  117. }
  118. }
  119. _nodes[_node.id] = _node;
  120. }
  121. if (_startroundFlag == 0) {
  122. dialogTop("必须有开始节点", "error");
  123. return -1;
  124. }
  125. if (_endroundFlag == 0)
  126. {
  127. dialogTop("必须有结束节点", "error");
  128. return -1;
  129. }
  130. if (_fnodes.length != _hnodes.length)
  131. {
  132. dialogTop("分流节点必须等于合流节点", "error");
  133. return -1;
  134. }
  135. for (var a in _fnodes) {
  136. var aNondeid = _fnodes[a];
  137. if (_fromlines[aNondeid].length == 1) {
  138. labellingRedNode(aNondeid);
  139. dialogTop("标注红色的分流节点不允许只有一条【出去】的线段", "error");
  140. return -1;
  141. }
  142. var _hhnodeid = {};
  143. for (var b in _fromlines[aNondeid])
  144. {
  145. btoNode = _fromlines[aNondeid][b];
  146. if (_nodes[btoNode].type == "stepnode") {
  147. var _nextLine = _fromlines[_nodes[btoNode].id];
  148. var _nextNode = _nodes[_nextLine[0]];
  149. if (_nextNode.type != "confluencenode") {
  150. labellingRedNode(_nodes[btoNode].id);
  151. dialogTop("标注红色的普通节点下一个节点必须是合流节点", "error");
  152. return -1;
  153. }
  154. else {
  155. _hhnodeid[_nextLine[0]] = 0;
  156. if (_hhnodeid.length > 1) {
  157. labellingRedNode(aNondeid);
  158. dialogTop("标注红色的分流节点与之对应的合流节点只能有一个", "error");
  159. return -1;
  160. }
  161. if (_tolines[_nextLine[0]].length != _fromlines[aNondeid].length) {
  162. labellingRedNode(_nextLine[0]);
  163. dialogTop("标注红色的合流节点与之对应的分流节点只能有一个", "error");
  164. return -1;
  165. }
  166. }
  167. if (_nextLine.length > 1) {
  168. labellingRedNode(_nodes[btoNode].id);
  169. dialogTop("标注红色的节点只能有一条出去的线条【分流合流之间】", "error");
  170. return -1;
  171. }
  172. else if (_tolines[_nodes[btoNode].id],length > 1) {
  173. labellingRedNode(_nodes[btoNode].id);
  174. dialogTop("标注红色的节点只能有一条进来的线条【分流合流之间】", "error");
  175. return -1;
  176. }
  177. }
  178. else {
  179. labellingRedNode(aNondeid);
  180. dialogTop("标注红色的分流节点必须经过一个普通节点到合流节点", "error");
  181. return -1;
  182. }
  183. }
  184. }
  185. return _data;
  186. }
  187. FlowPanel.SetNodeEx = function (id,data) {
  188. FlowPanel.setName(id, data.NodeName, "node", data);
  189. }
  190. FlowPanel.SetLineEx = function (id, data) {
  191. FlowPanel.setName(id, data.LineName, "line", data);
  192. }
  193. if (options.isprocessing)//如果是显示进程状态
  194. {
  195. var tipHtml = '<div style="position:absolute;left:10px;margin-top: 10px;padding:10px;border-radius:5px;background:rgba(0,0,0,0.05);z-index:1000;display:inline-block;">';
  196. tipHtml += '<div style="display: inline-block;"><i style="padding-right:5px;color:#5cb85c;" class="fa fa-flag"></i><span>已处理</span></div>';
  197. tipHtml += '<div style="display: inline-block;margin-left: 10px;"><i style="padding-right:5px;color:#5bc0de;" class="fa fa-flag"></i><span>正在处理</span></div>';
  198. tipHtml += '<div style="display: inline-block;margin-left: 10px;"><i style="padding-right:5px;color:#d9534f;" class="fa fa-flag"></i><span>不通过</span></div>';
  199. tipHtml += '<div style="display: inline-block;margin-left: 10px;"><i style="padding-right:5px;color:#f0ad4e;" class="fa fa-flag"></i><span>驳回</span></div>';
  200. tipHtml += '<div style="display: inline-block;margin-left: 10px;"><i style="padding-right:5px;color:#999;" class="fa fa-flag"></i><span>未处理</span></div></div>';
  201. $frmpreview.find('.GooFlow_work .GooFlow_work_inner').css('background-image', 'none');
  202. $frmpreview.find('td').css('color', '#fff');
  203. $frmpreview.css('background', '#fff');
  204. $frmpreview.find('.ico').remove();
  205. $frmpreview.find('.GooFlow_item').css('border', '0px');
  206. $frmpreview.append(tipHtml);
  207. $.each(options.nodeData, function (i, item) {
  208. $frmpreview.find("#" + item.id).css("background", "#999");
  209. if (item.type == "startround") {
  210. $frmpreview.find("#" + item.id).css("background", "#5cb85c");
  211. }
  212. else {
  213. if (item.id == options.activityId) {
  214. $frmpreview.find("#" + item.id).css("background", "#5bc0de");//正在处理
  215. }
  216. if (item.setInfo != undefined && item.setInfo.Taged != undefined) {
  217. if (item.setInfo.Taged == -1) {
  218. $frmpreview.find("#" + item.id).css("background", "#d9534f");//不通过
  219. }
  220. else if (item.setInfo.Taged == 1) {
  221. $frmpreview.find("#" + item.id).css("background", "#5cb85c");//通过
  222. }
  223. else {
  224. $frmpreview.find("#" + item.id).css("background", "#f0ad4e");//驳回
  225. }
  226. }
  227. }
  228. if (item.setInfo != undefined && item.setInfo.Taged != undefined)
  229. {
  230. var _one = top.clientuserData[item.setInfo.UserId];
  231. var _row = '<div style="text-align:left">';
  232. var tagname = { "-1": "不通过", "1": "通过", "0": "驳回" };
  233. _row += "<p>处理人:" + (_one == undefined ? item.setInfo.UserId : _one.RealName)+"</p>";
  234. _row += "<p>结果:" + tagname[item.setInfo.Taged] + "</p>";
  235. _row += "<p>处理时间:" + item.setInfo.TagedTime + "</p>";
  236. _row += "<p>备注:" + item.setInfo.description + "</p></div>";
  237. $frmpreview.find('#' + item.id).attr('data-toggle', 'tooltip');
  238. $frmpreview.find('#' + item.id).attr('data-placement', 'bottom');
  239. $frmpreview.find('#' + item.id).attr('title', _row);
  240. }
  241. });
  242. $('[data-toggle="tooltip"]').tooltip({"html":true});
  243. }
  244. if (options.preview == 1)
  245. {
  246. preview();
  247. }
  248. //预览
  249. function preview() {
  250. var _frmitems = {};
  251. for (var i in options.frmData) {
  252. var _frmitem = options.frmData[i];
  253. _frmitems[_frmitem.control_field] = _frmitem.control_label;
  254. }
  255. var DataBaseLinkData = {};
  256. $.ajax({
  257. url: "../../SystemManage/DataBaseLink/GetListJson",
  258. type: "get",
  259. dataType: "json",
  260. async: false,
  261. success: function (data) {
  262. for (var i in data) {
  263. DataBaseLinkData[data[i].DatabaseLinkId] = data[i].DBAlias;
  264. }
  265. },
  266. error: function (XMLHttpRequest, textStatus, errorThrown) {
  267. dialogMsg(errorThrown, -1);
  268. }
  269. });
  270. var _NodeRejectType = { "0": "前一步", "1": "第一步", "2": "某一步", "3": "用户指定", "4": "不处理" };
  271. var _NodeIsOver = { "0": "不允许", "1": "允许" };
  272. var _NodeDesignate = { "NodeDesignateType1": "所有成员", "NodeDesignateType2": "指定成员", "NodeDesignateType3": "发起者领导", "NodeDesignateType4": "前一步骤领导", "NodeDesignateType5": "发起者部门领导", "NodeDesignateType6": "发起者公司领导" };
  273. var _NodeConfluenceType = { "0": "所有步骤通过", "1": "一个步骤通过即可", "2": "按百分比计算" };
  274. $.each(options.flowcontent.nodes, function (i, item) {
  275. if (item.setInfo != undefined) {
  276. var _popoverhtml = "";
  277. _popoverhtml += '<div class="flow-portal-panel-title"><i class="fa fa-navicon"></i>&nbsp;&nbsp;基本信息</div>';
  278. _popoverhtml += '<ul>';
  279. _popoverhtml += '<li>节点标识:' + item.setInfo.NodeCode + '</li>';
  280. _popoverhtml += '<li>驳回类型:' + _NodeRejectType[item.setInfo.NodeRejectType] + '</li>';
  281. _popoverhtml += '<li>终止流程:' + _NodeIsOver[item.setInfo.NodeIsOver] + '</li>';
  282. if (item.setInfo.Description != "") { _popoverhtml += '<li>备注:' + item.setInfo.Description + '</li>'; }
  283. if (item.setInfo.NodeConfluenceType != "") {
  284. _popoverhtml += '<li>会签策略:' + _NodeConfluenceType[item.setInfo.NodeConfluenceType] + '</li>';
  285. if (item.setInfo.NodeConfluenceType == 2) {
  286. _popoverhtml += '<li>会签比例:' + item.setInfo.NodeConfluenceRate + '</li>';
  287. }
  288. }
  289. if (item.setInfo.NodeDataBase != "") {
  290. _popoverhtml += '<li>绑定数据库:' + DataBaseLinkData[item.setInfo.NodeDataBase] + '</li>';
  291. }
  292. if (item.setInfo.NodeTable != "") {
  293. _popoverhtml += '<li>绑定表名:' + item.setInfo.NodeTable + '</li>';
  294. }
  295. if (item.setInfo.NodePram != "") {
  296. _popoverhtml += '<li>绑定字段:' + item.setInfo.NodePram + '</li>';
  297. }
  298. _popoverhtml += '</ul>';
  299. _popoverhtml += '<div class="flow-portal-panel-title"><i class="fa fa-navicon"></i>&nbsp;&nbsp;审核者</div>';
  300. _popoverhtml += '<ul>';
  301. _popoverhtml += '<li>类型:' + _NodeDesignate[item.setInfo.NodeDesignate] + '</li>';
  302. if (item.setInfo.NodeDesignateData != undefined) {
  303. var _rowstr = "";
  304. for (var i in item.setInfo.NodeDesignateData.role) {
  305. var _postitem = item.setInfo.NodeDesignateData.role[i];
  306. var _one = top.clientroleData[_postitem];
  307. _rowstr += ' <span class="label label-success">' + (_one == undefined ? _postitem : _one.FullName) + '</span>';
  308. if (i == item.setInfo.NodeDesignateData.role.length - 1) {
  309. _popoverhtml += '<li>角色:' + _rowstr + '</li>';
  310. }
  311. }
  312. _rowstr = "";
  313. for (var i in item.setInfo.NodeDesignateData.post) {
  314. var _postitem = item.setInfo.NodeDesignateData.post[i];
  315. var _one = top.clientpostData[_postitem];
  316. _rowstr += ' <span class="label label-info">' + (_one == undefined ? _postitem : _one.FullName) + '</span>';
  317. if (i == item.setInfo.NodeDesignateData.post.length - 1) {
  318. _popoverhtml += '<li>岗位:' + _rowstr + '</li>';
  319. }
  320. }
  321. _rowstr = "";
  322. for (var i in item.setInfo.NodeDesignateData.usergroup) {
  323. var _postitem = item.setInfo.NodeDesignateData.usergroup[i];
  324. var _one = top.clientuserGroup[_postitem];
  325. _rowstr += ' <span class="label label-warning">' + (_one == undefined ? _postitem : _one.FullName) + '</span>';
  326. if (i == item.setInfo.NodeDesignateData.usergroup.length - 1) {
  327. _popoverhtml += '<li>用户组:' + _rowstr + '</li>';
  328. }
  329. }
  330. _rowstr = "";
  331. for (var i in item.setInfo.NodeDesignateData.user) {
  332. var _postitem = item.setInfo.NodeDesignateData.user[i];
  333. var _one = top.clientuserData[_postitem];
  334. _rowstr += ' <span class="label label-danger">' + (_one == undefined ? _postitem : _one.RealName) + '</span>';
  335. if (i == item.setInfo.NodeDesignateData.user.length - 1) {
  336. _popoverhtml += '<li>用户:' + _rowstr + '</li>';
  337. }
  338. }
  339. }
  340. _popoverhtml += '</ul>';
  341. var _row = "";
  342. for (var i in item.setInfo.frmPermissionInfo) {
  343. var _item = item.setInfo.frmPermissionInfo[i];
  344. var _downtext = "";
  345. if (_item.down) {
  346. _downtext = ' | 可下载';
  347. }
  348. else if (_item.down != undefined) {
  349. _downtext = ' | 不可下载';
  350. }
  351. _row += '<li>' + _frmitems[_item.fieldid] + ': ' + (_item.look ? '可查看' : '不可查看') + _downtext + '</li>';
  352. if (i == item.setInfo.frmPermissionInfo.length - 1) {
  353. _popoverhtml += '<div class="flow-portal-panel-title"><i class="fa fa-navicon"></i>&nbsp;&nbsp;权限分配</div>';
  354. _popoverhtml += '<ul>';
  355. _popoverhtml += _row;
  356. _popoverhtml += '</ul>';
  357. }
  358. }
  359. if (item.setInfo.NodeDataBaseToSQL != "" || item.setInfo.NodeSQL != "") {
  360. _popoverhtml += '<div class="flow-portal-panel-title"><i class="fa fa-navicon"></i>&nbsp;&nbsp;执行SQL</div>';
  361. _popoverhtml += '<ul>';
  362. _popoverhtml += '<li>数据库:' + DataBaseLinkData[item.setInfo.NodeDataBaseToSQL] + '</li>';
  363. _popoverhtml += '<li>SQL语句:' + item.setInfo.NodeSQL + '</li>';
  364. _popoverhtml += '</ul>';
  365. }
  366. $frmpreview.find('#' + item.id).attr('title', item.name);
  367. $frmpreview.find('#' + item.id).attr('data-toggle', 'popover');
  368. $frmpreview.find('#' + item.id).attr('data-placement', 'bottom');
  369. $frmpreview.find('#' + item.id).attr('data-content', _popoverhtml);
  370. }
  371. else {
  372. $frmpreview.find('#' + item.id).attr('title', item.name);
  373. $frmpreview.find('#' + item.id).attr('data-toggle', 'popover');
  374. $frmpreview.find('#' + item.id).attr('data-placement', 'bottom');
  375. $frmpreview.find('#' + item.id).attr('data-content', "该节点未被设置");
  376. }
  377. });
  378. $frmpreview.find('.GooFlow_item').popover({ html: true });
  379. }
  380. function labellingRedNode(id)
  381. {
  382. $frmpreview.find('.flow-labellingnode-red').removeClass('flow-labellingnode-red');
  383. $frmpreview.find('#' + id).addClass('flow-labellingnode-red');
  384. }
  385. return FlowPanel;
  386. }