workflowHelper.js 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined'
  3. ? factory(exports)
  4. : typeof define === 'function' && define.amd
  5. ? define(['exports'], factory)
  6. : (global = global || self, factory(global.vber = { a: "1" }));
  7. // ReSharper disable once ThisInGlobalContext
  8. }(this, (function (exports) {
  9. 'use strict';
  10. let abp = window.abp || {};
  11. let VbWorkflow = function ($) {
  12. let NAME = 'VbWorkflow';
  13. let DATA_KEY = 'vb.workflow';
  14. let EVENT_KEY = "." + DATA_KEY;
  15. let ClassName = {
  16. CONTAINER: "wf-container",
  17. STEP_TAB: "step-tab",
  18. STEP_TAB_ITEM: "step-tab-item",
  19. STEP_CONTENT: "step-content",
  20. STEP_CONTENT_ITEM: "step-content-item",
  21. STEP_TOOL: "step-tool",
  22. STEP_TOOL_BTN_PREV: "prev",
  23. STEP_TOOL_BTN_NEXT: "next",
  24. STEP_TOOL_BTN_COMPLETE: "complete",
  25. DESIGN_CONTAINER: "design-container",
  26. DESIGN_LEFT: "design-left",
  27. DESIGN_MID: "design-mid",
  28. DESIGN_RIGHT: "design-right",
  29. DESIGN_MOVE_COL: "design-move-col",
  30. DRAG_SELECT: "drag-select",
  31. FORM_DESIGN_CONTAINER: "from-design-container",
  32. FORM_COMPONENT: "form-component",
  33. FORM_COMPONENT_ITEM: "form-component-item",
  34. DY_FORM_CONTAINER: "dy-form-container",
  35. DY_FORM_DRAG_BOX: "dy-form-drag-box",
  36. DY_FORM_INPUT_BOX: "dy-form-input-box",
  37. DY_FORM_INPUT_PARAMS: "dy-form-input-params",
  38. FORM_DESIGN: "form-design",
  39. FORM_DESIGN_BTN_GROUP_ADD: "form-design-btn-group-add",
  40. FLOW_DESIGN_CONTAINER: "flow-design-container",
  41. FLOW_DESIGN_NODE_SOURCE: "node-source",
  42. FLOW_DESIGN: "flow-design",
  43. FLOW_DESIGN_NODE: "flow-design-node",
  44. FLOW_DESIGN_DETAIL: "flow-design-detail",
  45. FLOW_DESIGN_DETAIL_BOX: "flow-design-detail-box",
  46. CONDITION: "condition",
  47. HOVER: "hover",
  48. ADD: "add",
  49. DELETE: "delete",
  50. ITEM: "item",
  51. TITLE: "title",
  52. SHOW: "show",
  53. HIDE: "hide",
  54. FINISH: "finished",
  55. ACTIVE: "active"
  56. }
  57. let IdName = {
  58. BASE_FORM: "base-form",
  59. FLOW_DESIGN: "flow-design",
  60. FLOW_DETAIL_TAB_NODE: "flow-detail-tab-node",
  61. FLOW_DETAIL_TAB_CONTENT_NODE: "flow-detail-tab-content-node",
  62. FLOW_DETAIL_TAB_LINE: "flow-detail-tab-line",
  63. FLOW_DETAIL_TAB_CONTENT_LINE: "flow-detail-tab-content-line",
  64. }
  65. let Selector = {
  66. CONTAINER: `.${ClassName.CONTAINER}`,
  67. STEP_TAB: `.${ClassName.CONTAINER} .${ClassName.STEP_TAB}`,
  68. STEP_TAB_ITEM: `.${ClassName.CONTAINER} .${ClassName.STEP_TAB_ITEM}`,
  69. STEP_CONTENT: `.${ClassName.CONTAINER} .${ClassName.STEP_CONTENT}`,
  70. STEP_CONTENT_ITEM: `.${ClassName.CONTAINER} .${ClassName.STEP_CONTENT_ITEM}`,
  71. STEP_CONTENT_ITEM_SHOW: `.${ClassName.CONTAINER} .${ClassName.STEP_CONTENT_ITEM}.${ClassName.SHOW}`,
  72. STEP_TOOL: `.${ClassName.CONTAINER} .${ClassName.STEP_TOOL}`,
  73. STEP_TOOL_BTN_PREV: `.${ClassName.CONTAINER} .${ClassName.STEP_TOOL} .${ClassName.STEP_TOOL_BTN_PREV}`,
  74. STEP_TOOL_BTN_NEXT: `.${ClassName.CONTAINER} .${ClassName.STEP_TOOL} .${ClassName.STEP_TOOL_BTN_NEXT}`,
  75. STEP_TOOL_BTN_COMPLETE: `.${ClassName.CONTAINER} .${ClassName.STEP_TOOL} .${ClassName.STEP_TOOL_BTN_COMPLETE}`,
  76. STEP_TOOL_BTN_SHOW: `.${ClassName.CONTAINER} .${ClassName.STEP_TOOL} .${ClassName.SHOW}`,
  77. STEP_TAB_ITEM_ACTIVE: `.${ClassName.CONTAINER} .${ClassName.STEP_TAB_ITEM}.${ClassName.ACTIVE}`,
  78. STEP_TAB_ITEM_FINISH: `.${ClassName.CONTAINER} .${ClassName.STEP_TAB_ITEM}.${ClassName.FINISH}`,
  79. BASE_FORM: `.${ClassName.CONTAINER} #${IdName.BASE_FORM}`,
  80. DESIGN_CONTAINER: `.${ClassName.CONTAINER} .${ClassName.DESIGN_CONTAINER}`,
  81. DESIGN_LEFT: `.${ClassName.DESIGN_LEFT}`,
  82. DESIGN_MID: `.${ClassName.DESIGN_MID}`,
  83. DESIGN_RIGHT: `.${ClassName.DESIGN_RIGHT}`,
  84. DESIGN_MOVE_COL: `.${ClassName.DESIGN_MOVE_COL}`,
  85. FORM_DESIGN_CONTAINER: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN_CONTAINER} `,
  86. FORM_COMPONENT: `.${ClassName.CONTAINER} .${ClassName.FORM_COMPONENT}`,
  87. FORM_COMPONENT_ITEM: `.${ClassName.CONTAINER} .${ClassName.FORM_COMPONENT} .${ClassName.FORM_COMPONENT_ITEM}`,
  88. FORM_DESIGN: `#${IdName.FORM_DESIGN}`,
  89. DY_FORM_CONTAINER: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER}`,
  90. DY_FORM_DRAG_BOX: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER} .${ClassName.DY_FORM_DRAG_BOX}`,
  91. DY_FORM_DRAG_BOX_DELETE: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER} .${ClassName.DY_FORM_DRAG_BOX}>.${ClassName.DELETE}`,
  92. DY_FORM_DRAG_ITEM: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER} .${ClassName.DY_FORM_DRAG_BOX}>.${ClassName.ITEM}`,
  93. DY_FORM_INPUT_BOX: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER} .${ClassName.DY_FORM_DRAG_BOX}>.${ClassName.ITEM} .${ClassName.DY_FORM_INPUT_BOX} `,
  94. DY_FORM_INPUT_BOX_DELETE: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.DY_FORM_CONTAINER} .${ClassName.DY_FORM_DRAG_BOX}>.${ClassName.ITEM} .${ClassName.DY_FORM_INPUT_BOX} >.${ClassName.DELETE}`,
  95. FORM_DESIGN_RIGHT: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN_CONTAINER} .${ClassName.DESIGN_RIGHT}`,
  96. DY_FORM_INPUT_PARAMS: `.${ClassName.CONTAINER} .${ClassName.DESIGN_CONTAINER} .${ClassName.DESIGN_RIGHT} .${ClassName.DY_FORM_INPUT_PARAMS}`,
  97. FORM_DESIGN_BTN_ROW_ADD: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.ADD}`,
  98. FORM_DESIGN_BTN_GROUP_ADD: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.FORM_DESIGN_BTN_GROUP_ADD}`,
  99. FORM_DESIGN_BTN_GROUP_ADD_BTN: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.FORM_DESIGN_BTN_GROUP_ADD} button`,
  100. FLOW_DESIGN_CONTAINER: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN_CONTAINER}`,
  101. FLOW_DESIGN_NODE_SOURCE: `.${ClassName.CONTAINER} .${ClassName.FORM_DESIGN} .${ClassName.FLOW_DESIGN_NODE_SOURCE}`,
  102. FLOW_DESIGN_NODE_SOURCE_ITEM: `.${ClassName.FLOW_DESIGN_NODE_SOURCE} .${ClassName.ITEM}`,
  103. FLOW_DESIGN: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN}`,
  104. FLOW_DESIGN_NODE: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN} .${ClassName.FLOW_DESIGN_NODE}`,
  105. FLOW_DESIGN_PATH: `.${ClassName.FLOW_DESIGN} .jtk-connector,.${ClassName.FLOW_DESIGN} .jtk-overlay`,
  106. FLOW_DESIGN_PATH_HOVER: `.${ClassName.FLOW_DESIGN} .jtk-connector.jtk-hover,.${ClassName.FLOW_DESIGN} .jtk-overlay.jtk-hover`,
  107. FLOW_DESIGN_PATH_ACTIVE: `.${ClassName.FLOW_DESIGN} .jtk-connector.active,.${ClassName.FLOW_DESIGN} .jtk-overlay.active`,
  108. FLOW_DETAIL_TAB_NODE: `#${IdName.FLOW_DETAIL_TAB_NODE}`,
  109. FLOW_DETAIL_TAB_CONTENT_NODE: `#${IdName.FLOW_DETAIL_TAB_CONTENT_NODE}`,
  110. FLOW_DETAIL_TAB_LINE: `#${IdName.FLOW_DETAIL_TAB_LINE}`,
  111. FLOW_DETAIL_TAB_CONTENT_LINE: `#${IdName.FLOW_DETAIL_TAB_CONTENT_LINE}`,
  112. FLOW_DESIGN_DETAIL: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN_DETAIL}`,
  113. FLOW_DESIGN_DETAIL_TITLE: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN_DETAIL}>.${ClassName.TITLE}`,
  114. FLOW_DESIGN_DETAIL_BOX: `.${ClassName.CONTAINER} .${ClassName.FLOW_DESIGN_DETAIL_BOX}`,
  115. CONDITION: `.${ClassName.CONDITION}`,
  116. ADD_ITEM: `.${ClassName.ADD}-${ClassName.ITEM}`,
  117. }
  118. let JQUERY_NO_CONFLICT = $.fn[NAME];
  119. let Default = {
  120. formComponents: [
  121. {
  122. name: "",
  123. label: "单行文本",
  124. type: "text",
  125. styles: [],
  126. }, {
  127. name: "",
  128. label: "多行文本",
  129. type: "textarea",
  130. styles: []
  131. }, {
  132. name: "",
  133. label: "复选框",
  134. type: "checkbox",
  135. items: [
  136. { label: "item1", value: "item1" },
  137. { label: "item2", value: "item2" }
  138. ],
  139. styles: []
  140. }, {
  141. name: "",
  142. label: "单选框",
  143. type: "radio",
  144. items: [
  145. { label: "item1", value: "item1" },
  146. { label: "item2", value: "item2" }
  147. ],
  148. styles: []
  149. //}, {
  150. // name: "",
  151. // label: "文字",
  152. // type: "paragraph",
  153. // styles: []
  154. }, {
  155. name: "",
  156. label: "下拉选择框",
  157. type: "select",
  158. items: [
  159. { label: "item1", value: "item1" },
  160. { label: "item2", value: "item2" }
  161. ],
  162. styles: []
  163. }, {
  164. name: "",
  165. label: "日期选择器",
  166. type: "date",
  167. styles: [{ name: 'width', value: "100%" }]
  168. }, {
  169. name: "",
  170. label: "日期段选择器",
  171. type: "date-range",
  172. styles: [{ name: 'width', value: "100%" }]
  173. //}, {
  174. // name: "",
  175. // label: "评分器",
  176. // type: "rate",
  177. // styles: []
  178. //}, {
  179. // name: "",
  180. // label: "开关选择器",
  181. // type: "switch",
  182. // styles: []
  183. //}, {
  184. // name: "",
  185. // label: "人民币输入框",
  186. // type: "money",
  187. // styles: [{ name: 'width', value: "100%" }]
  188. }, {
  189. name: "",
  190. label: "数字输入框",
  191. type: "number",
  192. styles: [{ name: 'width', value: "100%" }]
  193. }, {
  194. name: "",
  195. label: "图片上传",
  196. type: "uploadImages",
  197. styles: []
  198. }, {
  199. name: "",
  200. label: "文件上传",
  201. type: "uploadFiles",
  202. styles: []
  203. }],
  204. rules: [{
  205. name: "required",
  206. label: "必填",
  207. value: { required: true, message: "此项必填" }
  208. }, {
  209. name: "number",
  210. label: "整数",
  211. value: { type: "string", message: "请输入数字", pattern: /^-?\d+$/ }
  212. }, {
  213. name: "email",
  214. label: "邮箱",
  215. value: { type: 'email', message: "请输入正确的邮箱" }
  216. }, {
  217. name: "phonenumber",
  218. label: "手机号",
  219. value: { type: "string", message: "请输入正确的手机号", pattern: /^1[3|4|5|7|8]d{9}$/ }
  220. }],
  221. sourceNodes: [{
  222. key: "start",
  223. title: "流程开始",
  224. icon: "fa fa-play",
  225. type: "success",
  226. group: "1",
  227. endpointOptions: [{
  228. anchor: "Bottom",
  229. maxConnections: -1
  230. }],
  231. position: [20, 20],
  232. stepBody: {},
  233. parentNodes: [],
  234. nextNodes: []
  235. },
  236. {
  237. key: "end",
  238. title: "流程结束",
  239. icon: "fa fa-square",
  240. type: "danger",
  241. group: "1",
  242. endpointOptions: [{
  243. anchor: "Top",
  244. maxConnections: -1
  245. }],
  246. position: [20, 20],
  247. stepBody: {},
  248. parentNodes: [],
  249. nextNodes: []
  250. },
  251. {
  252. key: "step",
  253. title: "任务节点",
  254. icon: "fa fa-cog",
  255. type: "primary",
  256. group: "2",
  257. endpointOptions: [{
  258. anchor: "Top",
  259. maxConnections: -1
  260. }, {
  261. anchor: "Bottom",
  262. maxConnections: -1
  263. }],
  264. position: [20, 20],
  265. stepBody: {},
  266. parentNodes: [],
  267. nextNodes: []
  268. }
  269. ],
  270. endpointOptions: {
  271. isSource: true,
  272. isTarget: true,
  273. connector: "Flowchart",
  274. maxConnections: 1,
  275. paintStyle: {
  276. fill: "#FFDA59",
  277. strokeWidth: 1
  278. }
  279. },
  280. jsPlumbOptions: {
  281. DragOptions: { cursor: "crosshair" },
  282. Endpoint: [
  283. "Dot",
  284. {
  285. radius: 8,
  286. cssClass: "point",
  287. hoverClass: "hover",
  288. }
  289. ],
  290. PaintStyle: {
  291. stroke: "#FFE177",
  292. strokeWidth: 3
  293. },
  294. HoverPaintStyle: {
  295. stroke: "#FFDA59",
  296. strokeWidth: 4
  297. },
  298. //Container: "jsPlumb-container",
  299. Connector: [
  300. "Flowchart",
  301. { gap: 5, cornerRadius: 5, alwaysRespectStubs: true }
  302. ],
  303. ConnectionOverlays: [
  304. [
  305. "Arrow",
  306. {
  307. width: 12,
  308. length: 15,
  309. location: 0.9
  310. }
  311. ], [
  312. "Arrow",
  313. {
  314. width: 12,
  315. length: 15,
  316. location: "30px"
  317. }
  318. ],
  319. [
  320. "Label",
  321. {
  322. label: "",
  323. cssClass: "",
  324. id: "label",
  325. labelStyle: {
  326. color: "#009ef7",
  327. fontSize: "15px",
  328. fontWeight: "600"
  329. },
  330. //events: {
  331. // click: function (labelOverlay, originalEvent) {
  332. // console.log(labelOverlay, originalEvent);
  333. // }
  334. //}
  335. }
  336. ]
  337. ]
  338. },
  339. stepBodies: [],
  340. submit: undefined,
  341. data: undefined
  342. }
  343. const ALLOW_METHOD = [
  344. 'init',
  345. 'getStepBodies',
  346. 'setStepBodies',
  347. ];
  348. const ALLOW_METHOD_2 = [
  349. 'useDyForm',
  350. 'getDyFormData',
  351. ];
  352. let Workflow = function () {
  353. function Workflow(element, config) {
  354. this._element = element;
  355. this._config = config;
  356. return this;
  357. }
  358. let instance, maxStep = 3, curStep = 0, curNode = {}, curConnection = {}, conditionNode = { label: "", conditions: [] }, templates = [`<span class="drag-info">请将组件拖至此处</span><div></div>`];
  359. const guid = function () {
  360. return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
  361. var r = Math.random() * 16 | 0,
  362. v = c == 'x' ? r : (r & 0x3 | 0x8);
  363. return v.toString(16);
  364. });
  365. }
  366. // Public
  367. let _proto = Workflow.prototype;
  368. _proto.init = function () {
  369. let _this = this, _config = _this._config;
  370. $.metPageJs("/libs-ext/jsplumb/dist/js/jsplumb.min.js", "dy-js-plumb");
  371. $.metPageCss("/css/workflow.min.css", "dy-css-plumb");
  372. _config.data = _config.data || {
  373. id: "",
  374. version: "",
  375. title: "",
  376. group: "",
  377. icon: "",
  378. color: "",
  379. description: "",
  380. inputs: [],
  381. nodes: []
  382. }
  383. _this.createContainer();
  384. instance = jsPlumb.getInstance(_this.getJsPlumbOptions());
  385. instance.setContainer($(Selector.FORM_DESIGN)[0]);
  386. _this.bindEvent();
  387. };
  388. _proto.getJsPlumbOptions = function () {
  389. let _this = this, _config = _this._config;
  390. return _config.jsPlumbOptions;
  391. }
  392. _proto.getNode = function (key) {
  393. let _this = this, _config = _this._config;
  394. return _config.data.nodes.find(v => v.key == key);
  395. }
  396. _proto.createContainer = function () {
  397. let _this = this, _config = _this._config, data = _config.data;
  398. //data = {
  399. // id: "TEST",
  400. // title: "测试工作流",
  401. // group: "GR1 ",
  402. //}
  403. let str = `<div class="${ClassName.CONTAINER}">
  404. <div class="${ClassName.STEP_TAB}">
  405. <div class="${ClassName.STEP_TAB_ITEM} ${ClassName.STEP_TAB_ITEM}_0 ${ClassName.ACTIVE}" data-index="0"><i class="fas fa-file-alt"></i>基本信息</div>
  406. <div class="${ClassName.STEP_TAB_ITEM} ${ClassName.STEP_TAB_ITEM}_1" data-index="1"><i class="fas fa-table"></i>表单设计</div>
  407. <div class="${ClassName.STEP_TAB_ITEM} ${ClassName.STEP_TAB_ITEM}_2" data-index="2"><i class="fas fa-sitemap"></i>流程设计</div>
  408. </div>
  409. <div class="${ClassName.STEP_CONTENT}">
  410. <div class="${ClassName.STEP_CONTENT_ITEM} ${ClassName.STEP_CONTENT_ITEM}_0 ${ClassName.SHOW}" data-index="0">${createBaseInfo()}</div>
  411. <div class="${ClassName.STEP_CONTENT_ITEM} ${ClassName.STEP_CONTENT_ITEM}_1" data-index="1">${createFormDesign()}</div>
  412. <div class="${ClassName.STEP_CONTENT_ITEM} ${ClassName.STEP_CONTENT_ITEM}_2" data-index="2">${createFlowDesign()}</div>
  413. </div>
  414. <div class="${ClassName.STEP_TOOL}">
  415. <button type="button" class="btn btn-primary ${ClassName.STEP_TOOL_BTN_PREV}">上一步</button>
  416. <button type="button" class="btn btn-primary ${ClassName.STEP_TOOL_BTN_NEXT} ${ClassName.SHOW}">下一步</button>
  417. <button type="button" class="btn btn-success ${ClassName.STEP_TOOL_BTN_COMPLETE}">完成</button>
  418. </div>
  419. </div>`;
  420. $(_this._element).html(str);
  421. _this.renderForm(data.inputs, true)
  422. function createBaseInfo() {
  423. let str = `<form id="${IdName.BASE_FORM}">
  424. <input type="hidden" name="version" value="${data.version || "1"}">
  425. <div class="d-flex flex-column">
  426. <label class="fs-6 fw-bolder required mb-1">流程编号</label>
  427. <input type="text" class="form-control form-control-sm form-control-solid required" name="id" value="${data.id || ""}" placeholder="请输入流程编号...">
  428. <div class="invalid-feedback"></div>
  429. </div>
  430. <div class="d-flex flex-column">
  431. <label class="fs-6 fw-bolder required mb-1">流程名称</label>
  432. <input type="text" class="form-control form-control-sm form-control-solid required" name="title" value="${data.title || ""}" placeholder="请输入流程名称...">
  433. <div class="invalid-feedback"></div>
  434. </div>
  435. <div class="d-flex flex-column">
  436. <label class="fs-6 fw-bolder mb-1">流程图标</label>
  437. <input type="text" class="form-control form-control-sm form-control-solid" name="icon" value="${data.icon || ""}" placeholder="请输入流程图标...">
  438. <div class="invalid-feedback"></div>
  439. </div>
  440. <div class="d-flex flex-column">
  441. <label class="fs-6 fw-bolder mb-1">流程描述</label>
  442. <textarea type="text" class="form-control form-control-sm form-control-solid" name="description" value="${data.description || ""}" placeholder="请输入流程描述..."style="height: 200px;"></textarea>
  443. <div class="invalid-feedback"></div>
  444. </div>
  445. </form>`;
  446. ` <div class="d-flex flex-column">
  447. <label class="fs-6 fw-bolder required mb-1">流程分组</label>
  448. <input type="text" class="form-control form-control-sm form-control-solid required" name="group" value="${data.group || ""}" placeholder="请输入流程分组...">
  449. <div class="invalid-feedback"></div>
  450. </div>
  451. <div class="d-flex flex-column">
  452. <label class="fs-6 fw-bolder mb-1">流程颜色</label>
  453. <input type="text" class="form-control form-control-sm form-control-solid" name="color" value="${data.color || ""}" placeholder="请输入流程颜色...">
  454. <div class="invalid-feedback"></div>
  455. </div>`
  456. return str;
  457. }
  458. function createFormDesign() {
  459. let str = `<div class="${ClassName.DESIGN_CONTAINER} ${ClassName.FORM_DESIGN_CONTAINER}">
  460. <div class="${ClassName.DESIGN_LEFT}">${left()}</div>
  461. ${moveCol()}
  462. <div class="${ClassName.DESIGN_MID}">${mid()}</div>
  463. ${moveCol()}
  464. <div class="${ClassName.DESIGN_RIGHT}">${right()}</div>
  465. </div>`;
  466. function left() {
  467. let str1 = `<div class="${ClassName.FORM_COMPONENT}">`;
  468. str1 += `<div class="title">表单组件</div>`;
  469. _config.formComponents.forEach(v => { str1 += `<button type="button" class="${ClassName.FORM_COMPONENT_ITEM}" draggable="true" data-type="${v.type}" >${v.label}</button>`; });
  470. str1 += `</div>`;
  471. return str1;
  472. }
  473. function mid() {
  474. let str2 = `<div class="${ClassName.FORM_DESIGN}">`;
  475. str2 += `<div class="${ClassName.DY_FORM_CONTAINER}">`;
  476. str2 += `</div>`;
  477. str2 += `<button type="button" class="${ClassName.ADD}" onclick="$('${Selector.FORM_DESIGN_BTN_GROUP_ADD}').toggleClass('${ClassName.SHOW}')"><i class="fa fa-plus-circle"></i>添加行</button>`;
  478. str2 += `<div class="${ClassName.FORM_DESIGN_BTN_GROUP_ADD}">
  479. <div class="arrow"></div>
  480. <button type="button" data-col="1">一行一列</button>
  481. <button type="button" data-col="2">一行二列</button>
  482. <button type="button" data-col="3">一行三列</button>
  483. <button type="button" data-col="4">一行四列</button>
  484. </div>`;
  485. str2 += `</div>`;
  486. return str2;
  487. }
  488. function right() {
  489. let str3 = ``;
  490. return str3;
  491. }
  492. return str;
  493. }
  494. function createFlowDesign() {
  495. let str = `<div class="${ClassName.DESIGN_CONTAINER} ${ClassName.FLOW_DESIGN_CONTAINER}">
  496. <div class="${ClassName.DESIGN_LEFT}">${left()}</div>
  497. ${moveCol()}
  498. <div class="${ClassName.DESIGN_MID}"><div class="${ClassName.FLOW_DESIGN}" id="${IdName.FLOW_DESIGN}"></div></div>
  499. ${moveCol()}
  500. <div class="${ClassName.DESIGN_RIGHT}">${right()}</div>
  501. </div>`;
  502. function left() {
  503. let str = `<div class="${ClassName.FLOW_DESIGN_NODE_SOURCE}">`;
  504. str += `<div class="title">活动节点</div>`;
  505. if (_config.sourceNodes && _config.sourceNodes.length) {
  506. _config.sourceNodes.forEach(v => { str += `<button type="button" class="${ClassName.ITEM} btn btn-${v.type}" data-key="${v.key}" data-type="${v.type}"><i class="${v.icon}"></i>${v.title}</button>`; });
  507. }
  508. str += `</div>`;
  509. return str;
  510. }
  511. function right() {
  512. //let str = `<ul class="nav nav-tabs nav-line-tabs tab-auto">
  513. // <li class="nav-item"><button type="button" class="nav-link active" id="${IdName.FLOW_DETAIL_TAB_NODE}" disabled data-bs-toggle="tab" data-bs-target="#${IdName
  514. // .FLOW_DETAIL_TAB_CONTENT_NODE}">节点</button></li>
  515. // <li class="nav-item"><button type="button" class="nav-link" id="${IdName.FLOW_DETAIL_TAB_LINE}" disabled data-bs-toggle="tab" data-bs-target="#${IdName
  516. // .FLOW_DETAIL_TAB_CONTENT_LINE}">连线</button></li>
  517. // </ul>
  518. // <div class="tab-content" id="">
  519. // <div class="tab-pane fade show active" id="${IdName.FLOW_DETAIL_TAB_CONTENT_NODE}">1</div>
  520. // <div class="tab-pane fade" id="${IdName.FLOW_DETAIL_TAB_CONTENT_LINE}">2</div>
  521. // </div>`;
  522. let str = `<div class="${ClassName.FLOW_DESIGN_DETAIL}">`;
  523. //str += `<div class="${ClassName.TITLE}">节点详情</div>`;
  524. //str += `<div class="${ClassName.FLOW_DESIGN_DETAIL_BOX}"></div>`;
  525. str += `</div>`;
  526. return str;
  527. }
  528. return str;
  529. }
  530. function moveCol() {
  531. return `<div class="${ClassName.DESIGN_MOVE_COL}"><div class="bar"></div><div class="bar"></div><div class="bar"></div><div class="bar"></div></div>`
  532. }
  533. }
  534. _proto.createFlow = function () {
  535. let _this = this, _config = _this._config;
  536. if ($(Selector.FLOW_DESIGN).data('inti')) {
  537. return;
  538. }
  539. $(Selector.FLOW_DESIGN).data('inti', true);
  540. if (_config.data.nodes) {
  541. var newData = [];
  542. _config.data.nodes.forEach(v => {
  543. let node = $.extend(true, {}, _this.createNode(v.type, v.key), v);
  544. _this.renderNode(node);
  545. newData.push(node);
  546. })
  547. _config.data.nodes = newData;
  548. _config.data.nodes.forEach(v => { _this.createConnect(v); })
  549. }
  550. }
  551. _proto.createConnect = function (node) {
  552. let _this = this, _config = _this._config;
  553. const nodeEndpoints = node.endpointOptions;
  554. node.nextNodes.forEach((v) => {
  555. let endpoints = _this.getNode(v.nodeId).endpointOptions;
  556. instance.connect({
  557. uuids: [nodeEndpoints[nodeEndpoints.length - 1].uuid, endpoints[0].uuid],
  558. endpoint: _config.endpointOptions,
  559. });
  560. });
  561. }
  562. _proto.createNode = function (type, key) {
  563. let _this = this, _config = _this._config;
  564. if (!key && type == "success" && _config.data.nodes.filter((i) => i.type == type).length > 0) {
  565. abp.message.warn("只能有一个开始节点");
  566. return undefined;
  567. }
  568. let node = JSON.parse(JSON.stringify(_config.sourceNodes.find(v => { return v.type == type; })));
  569. node.key = key ? key : node.key + "_" + guid();
  570. if (node.endpointOptions) {
  571. node.endpointOptions.forEach((option) => {
  572. option.uuid = node.key + "_" + option.anchor;
  573. });
  574. }
  575. return node;
  576. }
  577. _proto.renderNode = function (node, isUpdate) {
  578. let _this = this, _config = _this._config;
  579. let str = `<button type="button" class="btn btn-${node.type} ${ClassName.FLOW_DESIGN_NODE}" id="${node.key}" data-key="${node.key}"><i class="${node.icon}"></i><span>${node.title}</span></button>`;
  580. if (isUpdate) {
  581. $(`#${node.key} span`).html(node.title);
  582. instance.revalidate(node.key);
  583. } else {
  584. $(Selector.FLOW_DESIGN).append(str);
  585. $('#' + node.key).css({ left: node.position[0], top: node.position[1] });
  586. //console.log($('#' + node.key));
  587. instance.draggable(node.key, {
  588. containment: IdName.FLOW_DESIGN,
  589. grid: [10, 10],
  590. drag: (params) => {
  591. curNode.position = params.pos;
  592. //console.log("drag====>", params, curNode);
  593. }
  594. });
  595. if (node.endpointOptions && node.endpointOptions.length) {
  596. node.endpointOptions.forEach(v => { instance.addEndpoint(node.key, v, _config.endpointOptions); });
  597. }
  598. //else {
  599. // node.endpointOptions = [];
  600. // const sourceNode = JSON.parse(JSON.stringify(_config.sourceNodes.find(v => { return v.type == node.type; })));
  601. // sourceNode.endpointOptions.forEach(v => {
  602. // let endPoint= instance.addEndpoint(node.key, v, _config.endpointOptions)
  603. // endPoint.uuid = node.key + "_" + v.anchor;
  604. // node.endpointOptions.push(endPoint);
  605. // })
  606. //}
  607. _this.renderFLowNodeDetail(node);
  608. $(Selector.FLOW_DESIGN_NODE).off('mousedown' + EVENT_KEY).on('mousedown' + EVENT_KEY,
  609. function () {
  610. const key = $(this).data('key');
  611. curNode = _this.getNode(key);
  612. //console.log("mousedown======>", curNode);
  613. _this.renderFLowNodeDetail(curNode);
  614. });
  615. }
  616. }
  617. _proto.deleteNode = function (data) {
  618. let _this = this, _config = _this._config;
  619. abp.message.confirm(`确定删除节点[${data.title}]吗?`, "删除节点", function (isConfirmed) {
  620. if (isConfirmed) {
  621. _config.data.nodes.forEach(v => {
  622. v.nextNodes = v.nextNodes.filter(u => u.nodeId != data.key);
  623. v.parentNodes = v.parentNodes.filter(u => u.nodeId != data.key);
  624. });
  625. const index = _config.data.nodes.findIndex(v => v.key == data.key);
  626. instance.remove(data.key);
  627. _config.data.nodes.splice(index, 1);
  628. $(Selector.FLOW_DESIGN_DETAIL).html('');
  629. }
  630. });
  631. }
  632. _proto.addConnection = function (data) {
  633. let _this = this, _config = _this._config;
  634. let source = _this.getNode(data.sourceId);
  635. let target = _this.getNode(data.targetId);
  636. if (target.parentNodes.filter(v => v == source.key).length <= 0) {
  637. target.parentNodes.push(source.key);
  638. }
  639. conditionNode = source.nextNodes.find(v => v.nodeId == target.key);
  640. if (!conditionNode) {
  641. conditionNode = {
  642. nodeId: target.key,
  643. label: "连线",
  644. conditions: []
  645. }
  646. source.nextNodes.push(conditionNode);
  647. }
  648. curConnection = data.connection;
  649. _this.revalidateConnection(conditionNode);
  650. _this.renderFLowConnectionDetail(conditionNode);
  651. //console.log("==?>>>>>", data, _config.data.nodes);
  652. }
  653. _proto.revalidateConnection = function (data) {
  654. if (data != null) {
  655. const label = curConnection.getOverlay("label")
  656. label.setLabel(data.label);
  657. //console.log("==?>>>>>", label)
  658. $(label.canvas).removeClass(ClassName.HIDE)
  659. if (!data.label) {
  660. $(label.canvas).addClass(ClassName.HIDE)
  661. }
  662. }
  663. }
  664. _proto.deleteConnection = function (label) {
  665. let _this = this, _config = _this._config;
  666. abp.message.confirm(`确定删除连接[${label}]吗?`, "删除连接",
  667. function (isConfirmed) {
  668. if (isConfirmed) {
  669. let source = _this.getNode(curConnection.sourceId);
  670. let target = _this.getNode(curConnection.targetId);
  671. source.nextNodes = source.nextNodes.filter(
  672. (u) => u.nodeId != curConnection.targetId
  673. );
  674. target.parentNodes = source.parentNodes.filter(
  675. (u) => u != curConnection.sourceId
  676. );
  677. instance.deleteConnection(curConnection);
  678. }
  679. });
  680. }
  681. _proto.renderForm = function (inputs, bindEvent, container) {
  682. let _this = this;
  683. if (inputs && inputs.length) {
  684. inputs.forEach(v => {
  685. _this.renderFormComponent(v.length, v, bindEvent, container);
  686. v.forEach(vv => {
  687. _this.renderInputDom(vv, bindEvent);
  688. })
  689. });
  690. }
  691. }
  692. _proto.renderInputDom = function (data, bindEvent, container) {
  693. let _this = this, _config = _this._config;
  694. let str = `<div class="${ClassName.DY_FORM_INPUT_BOX}">
  695. <div class="d-flex flex-column">
  696. <label class="fs-6 fw-bolder mb-1">${data.label}</label>
  697. ${getInputDomStr(data.type)}
  698. <div class="invalid-feedback"></div>
  699. </div>
  700. ${bindEvent ? `<i class="fa fa-trash-alt ${ClassName.DELETE}"></i>` : ""}
  701. </div>`;
  702. const $container = container ? $(container) : $('#i_' + data.id);
  703. $container.html(str);
  704. if (bindEvent) {
  705. _this.bindDyItemInputEvent();
  706. }
  707. function getInputDomStr(type) {
  708. let str1 = '';
  709. let styleStr = '';
  710. if (data.styles && data.styles.length) {
  711. data.styles.forEach(v => { styleStr += `${v.name}:${v.value};`; });
  712. }
  713. switch (type) {
  714. case 'text':
  715. case 'number':
  716. str1 =
  717. `<input type="${type}" class="form-control form-control-sm form-control-solid" style="${styleStr}" disabled name="${data.name}" placeholder="请输入${data.label}...">`;
  718. break;
  719. case 'textarea':
  720. str1 =
  721. `<textarea type="text" class="form-control form-control-sm form-control-solid" style="${styleStr}" disabled name="${data.name}" placeholder="请输入${data.label}..."></textarea>`;
  722. break;
  723. case 'checkbox':
  724. case 'radio':
  725. str1 = `<div class="d-flex align-items-center">`;
  726. if (data.items && data.items.length) {
  727. data.items.forEach(v => {
  728. str1 +=
  729. `<label class="form-check form-check-custom form-check-solid form-check-sm me-5" style="height: 34px;">
  730. <input class=" form-check-input" name="${data.name}" type="${type}" value="${v.value}">
  731. <span class="form-check-label">${v.label}</span>
  732. </label>`;
  733. });
  734. }
  735. str1 += `</div>`;
  736. break;
  737. case 'select':
  738. str1 =
  739. `<select class="form-control form-control-sm form-control-solid" style="${styleStr}" disabled name="${data.name}" placeholder="请选择${data.label}...">`;
  740. data.items.forEach(v => { str1 += `<option value="${v.value}">${v.label}</option>`; });
  741. str1 += `</select>`;
  742. break;
  743. case 'date':
  744. case 'date-range':
  745. str1 =
  746. `<div class="position-relative d-flex align-items-center" >
  747. <div class="symbol symbol-20px me-4 position-absolute ms-4" data-toggle>
  748. <span class="symbol-label bg-secondary">
  749. <!--Svg Icon | path: icons/duotone/Layout/Layout-grid.svg-->
  750. <span class="svg-icon">
  751. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24px" height="24px" viewBox="0 0 24 24" version="1.1">
  752. <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
  753. <rect x="0" y="0" width="24" height="24"></rect>
  754. <rect fill="#000000" opacity="0.3" x="4" y="4" width="4" height="4" rx="1"></rect>
  755. <path d="M5,10 L7,10 C7.55228475,10 8,10.4477153 8,11 L8,13 C8,13.5522847 7.55228475,14 7,14 L5,14 C4.44771525,14 4,13.5522847 4,13 L4,11 C4,10.4477153 4.44771525,10 5,10 Z M11,4 L13,4 C13.5522847,4 14,4.44771525 14,5 L14,7 C14,7.55228475 13.5522847,8 13,8 L11,8 C10.4477153,8 10,7.55228475 10,7 L10,5 C10,4.44771525 10.4477153,4 11,4 Z M11,10 L13,10 C13.5522847,10 14,10.4477153 14,11 L14,13 C14,13.5522847 13.5522847,14 13,14 L11,14 C10.4477153,14 10,13.5522847 10,13 L10,11 C10,10.4477153 10.4477153,10 11,10 Z M17,4 L19,4 C19.5522847,4 20,4.44771525 20,5 L20,7 C20,7.55228475 19.5522847,8 19,8 L17,8 C16.4477153,8 16,7.55228475 16,7 L16,5 C16,4.44771525 16.4477153,4 17,4 Z M17,10 L19,10 C19.5522847,10 20,10.4477153 20,11 L20,13 C20,13.5522847 19.5522847,14 19,14 L17,14 C16.4477153,14 16,13.5522847 16,13 L16,11 C16,10.4477153 16.4477153,10 17,10 Z M5,16 L7,16 C7.55228475,16 8,16.4477153 8,17 L8,19 C8,19.5522847 7.55228475,20 7,20 L5,20 C4.44771525,20 4,19.5522847 4,19 L4,17 C4,16.4477153 4.44771525,16 5,16 Z M11,16 L13,16 C13.5522847,16 14,16.4477153 14,17 L14,19 C14,19.5522847 13.5522847,20 13,20 L11,20 C10.4477153,20 10,19.5522847 10,19 L10,17 C10,16.4477153 10.4477153,16 11,16 Z M17,16 L19,16 C19.5522847,16 20,16.4477153 20,17 L20,19 C20,19.5522847 19.5522847,20 19,20 L17,20 C16.4477153,20 16,19.5522847 16,19 L16,17 C16,16.4477153 16.4477153,16 17,16 Z" fill="#000000"></path>
  756. </g>
  757. </svg>
  758. </span>
  759. </span>
  760. </div>
  761. <input type="text" class="form-control form-control-sm form-control-solid ps-12 flatpickr-input vb-${type}" data-vb-date="${type == 'date' ? 'date' : 'r_date'}" name="${data.name}" placeholder="请选择日期..."/>
  762. </div>`;
  763. break;
  764. case 'uploadFiles':
  765. case 'uploadImages':
  766. str1 =
  767. `<div class="position-relative d-flex align-items-center" data-vb-file-box="" data-vb-file="upload">
  768. <input type="hidden" name="${data.name}" value="" />
  769. <input type="hidden" name="name_${data.name}" value="" />
  770. <input type="hidden" name="ext_${data.name}" value="" />
  771. <input type="file" class="form-control form-control-sm form-control-solid" data-vb-file-target-info="${data.name}" data-vb-file-target-ext="ext_${data.name}" data-vb-file-target-name="name_${data.name}" data-vb-file-image="${type == 'uploadImages' ? "1" : "0"}" data-vb-file-max-size="5"/>
  772. <div class="position-absolute translate-middle-y top-50 end-0">
  773. <button type="button" data-vb-file-btn="clean" class="btn btn-icon btn-active-color-primary " data-bs-toggle="tooltip" title="@(L("Clean"))" style="cursor: pointer;">
  774. <span class="svg-icon svg-icon-1">
  775. <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
  776. <path opacity="0.25" d="M6.54184 2.36899C4.34504 2.65912 2.65912 4.34504 2.36899 6.54184C2.16953 8.05208 2 9.94127 2 12C2 14.0587 2.16953 15.9479 2.36899 17.4582C2.65912 19.655 4.34504 21.3409 6.54184 21.631C8.05208 21.8305 9.94127 22 12 22C14.0587 22 15.9479 21.8305 17.4582 21.631C19.655 21.3409 21.3409 19.655 21.631 17.4582C21.8305 15.9479 22 14.0587 22 12C22 9.94127 21.8305 8.05208 21.631 6.54184C21.3409 4.34504 19.655 2.65912 17.4582 2.36899C15.9479 2.16953 14.0587 2 12 2C9.94127 2 8.05208 2.16953 6.54184 2.36899Z" fill="#12131A"></path>
  777. <path d="M8 13C7.44772 13 7 12.5523 7 12C7 11.4477 7.44772 11 8 11H16C16.5523 11 17 11.4477 17 12C17 12.5523 16.5523 13 16 13H8Z" fill="#12131A"></path>
  778. </svg>
  779. </span>
  780. </button>
  781. </div>
  782. </div>`;
  783. break;
  784. }
  785. return str1;
  786. }
  787. return str;
  788. }
  789. _proto.renderFormComponent = function (colCount, data, bindEvent, container) {
  790. let _this = this, _config = _this._config;
  791. let newData = data || generateInputData(colCount);
  792. let str = `<div class="row g-3 mb-3 ${bindEvent ? ClassName.DY_FORM_DRAG_BOX : ""}">`;
  793. let col = 12 / colCount;
  794. for (var i = 0; i < colCount; i++) {
  795. str += `<div class="col-${col} item" id="i_${newData[i].id}">${bindEvent ? templates[0] : ""}</div>`;
  796. }
  797. if (bindEvent) {
  798. str += `<i class="fa fa-trash-alt ${ClassName.DELETE}"></i></div>`;
  799. }
  800. const $container = container ? $(container) : $(Selector.DY_FORM_CONTAINER);
  801. $container.append($(str));
  802. if (!data) {
  803. _config.data.inputs = _config.data.inputs || [];
  804. _config.data.inputs.push(newData);
  805. }
  806. if (bindEvent) {
  807. $(Selector.DY_FORM_DRAG_BOX).off("mouseover" + EVENT_KEY).on("mouseover" + EVENT_KEY, function () { $(this).addClass(ClassName.HOVER); });
  808. $(Selector.DY_FORM_DRAG_BOX).off("mouseout" + EVENT_KEY).on("mouseout", function () { $(this).removeClass(ClassName.HOVER); });
  809. $(Selector.DY_FORM_DRAG_BOX_DELETE).off("click" + EVENT_KEY).on('click' + EVENT_KEY, function (e) {
  810. e.preventDefault();
  811. let index = $(Selector.DY_FORM_DRAG_BOX).index($(this).parent());
  812. _config.data.inputs.splice(index, 1);
  813. $(this).parent().remove();
  814. });
  815. _this.bindDyItemDragEvent();
  816. }
  817. //console.log(_config.data.inputs);
  818. function generateInputData(count) {
  819. const data = [];
  820. for (var i = 0; i < count; i++) {
  821. data.push({
  822. id: guid(),
  823. name: "",
  824. label: "",
  825. items: [],
  826. styles: [],
  827. rules: []
  828. });
  829. }
  830. return data;
  831. }
  832. }
  833. _proto.renderInputParamsDetail = function (data) {
  834. let _this = this, _config = _this._config;
  835. if (!data.id) {
  836. return;
  837. }
  838. //data.id = data.id || guid();
  839. let str = `<form class="${ClassName.DY_FORM_INPUT_PARAMS}">
  840. <div class="d-flex flex-column">
  841. <label class="fs-6 fw-bolder mb-1">编号</label>
  842. <input type="text" class="form-control form-control-sm form-control-solid" disabled name="id" value="${data.id || ""}" placeholder="请输入编号...">
  843. <div class="invalid-feedback"></div>
  844. </div>
  845. <div class="d-flex flex-column">
  846. <label class="fs-6 fw-bolder mb-1">标签</label>
  847. <input type="text" class="form-control form-control-sm form-control-solid" name="label" value="${data.label || ""}" placeholder="请输入标签...">
  848. <div class="invalid-feedback"></div>
  849. </div>
  850. <div class="d-flex flex-column">
  851. <label class="fs-6 fw-bolder mb-1">字段名</label>
  852. <input type="text" class="form-control form-control-sm form-control-solid" name="name" value="${data.name || ""}" placeholder="请输入字段名...">
  853. <div class="invalid-feedback"></div>
  854. </div>
  855. <div class="d-flex flex-column">
  856. <label class="fs-6 fw-bolder mb-1">长度</label>
  857. <div class="input-group input-group-sm">
  858. <input type="number" class="form-control form-control-sm form-control-solid " name="minLength" value="${data.minLength || ""}" placeholder="最小长度...">
  859. <span class="input-group-text"> - </span>
  860. <input type="number" class="form-control form-control-sm form-control-solid " name="maxLength" value="${data.maxLength || ""}" placeholder="最大长度...">
  861. </div>
  862. <div class="invalid-feedback"></div>
  863. </div>
  864. ${itemStr(data.items)}
  865. <div class="d-flex flex-column params">
  866. <div class="label"><label class="fs-6 fw-bolder">样式</label><span class="fa fa-plus ${ClassName.ADD}-${ClassName.ITEM}" title="添加样式" data-name="style"></span></div>
  867. ${styleStr(data.styles)}
  868. <div class="invalid-feedback"></div>
  869. </div>
  870. <div class="d-flex flex-column">
  871. <label class="fs-6 fw-bolder mb-1">数据验证</label>
  872. <div class="d-flex align-items-center">${ruleStr(data.rules)}</div>
  873. <div class="invalid-feedback"></div>
  874. </div>
  875. </form>`;
  876. $(Selector.FORM_DESIGN_RIGHT).html(str);
  877. bindChangeEvent();
  878. $(Selector.FORM_DESIGN_RIGHT).find(Selector.ADD_ITEM).off("click" + EVENT_KEY).on("click" + EVENT_KEY, function () {
  879. let name = $(this).data('name');
  880. $(this).parent().after(
  881. `<div class="input-group input-group-sm" ><input type="text" class="form-control form-control-sm form-control-solid" name="${name}_name" >
  882. <span class="input-group-text"> : </span><input type="text" class="form-control form-control-sm form-control-solid" name="${name
  883. }_value" ><button class="btn btn-danger btn-sm" type="button" onclick=""><i class="fas fa-minus-square"></i></button>
  884. </div>`);
  885. bindChangeEvent();
  886. });
  887. function itemStr(items) {
  888. let str3 = "";
  889. if (items && items.length) {
  890. str3 += `<div class="d-flex flex-column params">
  891. <div class="label"><label class="fs-6 fw-bolder">选项</label><span class="fa fa-plus ${ClassName.ADD}-${ClassName.ITEM}" title="添加选项" data-name="item"></span></div>`;
  892. items.forEach(v => {
  893. str3 += `<div class="input-group input-group-sm">
  894. <input type="text" class="form-control form-control-sm form-control-solid" name="item_name" value="${v.label || ""}">
  895. <span class="input-group-text"> : </span>
  896. <input type="text" class="form-control form-control-sm form-control-solid" name="item_value" value="${v.value || ""}">
  897. <button class="btn btn-danger btn-sm" type="button"><i class="fas fa-minus-square"></i></button>
  898. </div>`;
  899. });
  900. str3 += `<div class="invalid-feedback"></div>
  901. </div>`;
  902. }
  903. return str3;
  904. }
  905. function styleStr(styles) {
  906. let str1 = ``;
  907. if (styles && styles.length) {
  908. styles.forEach(v => {
  909. str1 += `<div class="input-group input-group-sm">
  910. <input type="text" class="form-control form-control-sm form-control-solid" name="style_name" value="${v.name || ""}">
  911. <span class="input-group-text"> : </span>
  912. <input type="text" class="form-control form-control-sm form-control-solid" name="style_value" value="${v.value || ""}">
  913. <button class="btn btn-danger btn-sm" type="button"><i class="fas fa-minus-square"></i></button>
  914. </div>`;
  915. });
  916. } else {
  917. str1 = `<div class="input-group input-group-sm">
  918. <input type="text" class="form-control form-control-sm form-control-solid" name="style_name">
  919. <span class="input-group-text"> : </span>
  920. <input type="text" class="form-control form-control-sm form-control-solid" name="style_value">
  921. <button class="btn btn-danger btn-sm" type="button" onclick=""><i class="fas fa-minus-square"></i></button>
  922. </div>`;
  923. }
  924. return str1;
  925. }
  926. function ruleStr(rules) {
  927. let str2 = ``;
  928. rules = rules || [];
  929. if (_config.rules && _config.rules.length) {
  930. _config.rules.forEach(v => {
  931. let checked = rules.length && (rules.fieldIndex(function (vv) { return vv.name == v.name }) >= 0)
  932. str2 +=
  933. `<label class="form-check form-check-custom form-check-solid form-check-sm me-5" style="height: 34px;">
  934. <input class=" form-check-input" name="rules" type="checkbox" value="${v.name
  935. }" ${checked ? 'checked="checked"' : ''} >
  936. <span class="form-check-label">${v.label}</span>
  937. </label>`;
  938. });
  939. }
  940. return str2;
  941. }
  942. function bindChangeEvent() {
  943. $(Selector.FORM_DESIGN_RIGHT).find('input').off('change' + EVENT_KEY).on('change' + EVENT_KEY, function () { saveData($(this).attr('name')); });
  944. $(Selector.FORM_DESIGN_RIGHT).find('.params button').off('click' + EVENT_KEY).on(
  945. 'click' + EVENT_KEY,
  946. function () {
  947. let name = $(this).prev().attr('name');
  948. $(this).parent().remove();
  949. saveData(name);
  950. });
  951. }
  952. function saveData(name) {
  953. let newData = "";
  954. if (name.indexOf("item") == 0) {
  955. name = 'items';
  956. newData = [];
  957. var items = $(Selector.DY_FORM_INPUT_PARAMS).find(`[name="item_name"]`);
  958. items.each(function () {
  959. let itemLabel = $(this).val(), itemValue = $(this).parent().find(`[name="item_value"]`).val();
  960. if (itemLabel && itemValue) {
  961. newData.push({
  962. label: itemLabel,
  963. value: itemValue
  964. });
  965. }
  966. });
  967. } else if (name.indexOf("style") == 0) {
  968. name = 'styles';
  969. newData = [];
  970. var styles = $(Selector.DY_FORM_INPUT_PARAMS).find(`[name="style_name"]`);
  971. styles.each(function () {
  972. let styleName = $(this).val(), styleValue = $(this).parent().find(`[name="style_value"]`).val();
  973. if (styleName && styleValue) {
  974. newData.push({
  975. name: styleName,
  976. value: styleValue
  977. });
  978. }
  979. });
  980. } else if (name == "rules") {
  981. newData = [];
  982. $(Selector.DY_FORM_INPUT_PARAMS).find(`[name="rules"]:checked`).each(function () {
  983. newData.push($(this).val());
  984. });
  985. } else {
  986. newData = $(Selector.DY_FORM_INPUT_PARAMS).find(`[name="${name}"]`).val();
  987. }
  988. data[name] = newData;
  989. //console.log("newData", newData, _config.data.inputs);
  990. if (
  991. //name == "name" ||
  992. name == "minLength" ||
  993. name == "minLength" ||
  994. name == "maxLength" ||
  995. name == "rules") {
  996. return;
  997. }
  998. _this.renderInputDom(data, true);
  999. }
  1000. }
  1001. _proto.renderFLowNodeDetail = function (data) {
  1002. let _this = this, _config = _this._config;
  1003. curNode = data;
  1004. let str = '';
  1005. str += `<div class="${ClassName.TITLE}">节点详情</div>`;
  1006. str += `<form class="${ClassName.FLOW_DESIGN_DETAIL_BOX}" id="form_${data.key}">
  1007. <div class="d-flex flex-column">
  1008. <label class="fs-6 fw-bolder mb-1">节点编号</label>
  1009. <input type="text" class="form-control form-control-sm form-control-solid" disabled name="key" value="${data.key || ""}" placeholder="请输入编号...">
  1010. <div class="invalid-feedback"></div>
  1011. </div>
  1012. <div class="d-flex flex-column">
  1013. <label class="fs-6 fw-bolder mb-1">节点标题</label>
  1014. <input type="text" class="form-control form-control-sm form-control-solid" name="title" value="${data.title || ""}" placeholder="请输入标题...">
  1015. <div class="invalid-feedback"></div>
  1016. </div>
  1017. <div class="d-flex flex-column">
  1018. <label class="fs-6 fw-bolder mb-1">执行操作</label>
  1019. <select class="form-control form-control-sm form-control-solid" name="stepBody" placeholder="请选择操作...">${stepBodySelectStr()}</select>
  1020. <div class="invalid-feedback"></div>
  1021. </div>
  1022. <div class="d-flex flex-column">
  1023. <button type="button" class="btn btn-outline btn-outline-dashed btn-outline-danger btn-active-light-danger ${ClassName.DELETE}"><i class="far fa-trash-alt text-danger"></i>删除节点</button>
  1024. </div>
  1025. </form>`;
  1026. $(Selector.FLOW_DESIGN_NODE).removeClass(ClassName.ACTIVE);
  1027. $(Selector.FLOW_DESIGN_PATH).removeClass(ClassName.ACTIVE);
  1028. $('#' + data.key).addClass(ClassName.ACTIVE);
  1029. $(Selector.FLOW_DESIGN_DETAIL).html(str);
  1030. //$(Selector.FLOW_DESIGN_DETAIL_BOX).find('select').select2();
  1031. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.form-control').off('change' + EVENT_KEY).on('change' + EVENT_KEY,
  1032. function () {
  1033. const name = $(this).attr("name"), val = $(this).val();
  1034. if (name == "stepBody") {
  1035. let stepBody = _config.stepBodies.find(v => { return v.name == val });
  1036. stepBody = $.extend(true, {}, stepBody, data.stepBody && data.stepBody.name && data.stepBody.name == val ? data.stepBody : {});
  1037. data.stepBody = stepBody;
  1038. //console.log("stepBody=========>", stepBody)
  1039. if (stepBody) {
  1040. $(Selector.FLOW_DESIGN_DETAIL_BOX + ' .stepBody').remove();
  1041. if (stepBody.inputs) {
  1042. let str = ``;
  1043. if (stepBody.inputs) {
  1044. for (let k in stepBody.inputs) {
  1045. if (Object.prototype.hasOwnProperty.call(stepBody.inputs, k)) {
  1046. const v = stepBody.inputs[k];
  1047. str += `<div class="d-flex flex-column stepBody">
  1048. <label class="fs-6 fw-bolder mb-1">${v.displayName}</label>
  1049. ${getDyInput(v.inputType)}
  1050. <div class="invalid-feedback"></div>
  1051. </div>`;
  1052. function getDyInput() {
  1053. let str1 = "";
  1054. switch (v.inputType.name) {
  1055. case "Select":
  1056. str1 += `<select class="form-control form-control-sm form-control-solid" name="${v.name}" data-key="${k}">`;
  1057. str1 += `<option value="" disabled>请选择</option>`
  1058. if (v.inputType.attributes.selectOptions) {
  1059. for (let kk in v.inputType.attributes.selectOptions) {
  1060. const vv = v.inputType.attributes.selectOptions[kk];
  1061. str1 += `<option value="${kk}" ${kk == v.value ? "selected" : ""}>${vv}</option>`
  1062. }
  1063. }
  1064. str1 += `</select>`;
  1065. break;
  1066. case "AjaxSelect":
  1067. str1 = '<div class="dy-select">';
  1068. str1 += `<input type="hidden" class="form-control" name="${v.name}" value="${v.value || ""}" data-key="${k}"/>`;
  1069. str1 += `<input class="form-control form-control-sm form-control-solid ajaxSelect" data-key="${k}" name="${v.name}" data-url="${v.inputType.attributes.ajaxUrl}" value="${v.extend || ""}" onblur="setTimeout(()=>$(this).parent().find('.dy-select-result').hide(),200)"/>`;
  1070. str1 += '<div class="dy-select-result"></div>'
  1071. str1 += `</div>`;
  1072. break;
  1073. case "Number":
  1074. str1 += `<input type="number" class="form-control form-control-sm form-control-solid" name="${v.name}" value="${v.value || ""}" data-key="${k}" placeholder="请输入...">`;
  1075. break;
  1076. default:
  1077. str1 += `<input type="text" class="form-control form-control-sm form-control-solid" name="${v.name}" value="${v.value || ""}" data-key="${k}" placeholder="请输入...">`;
  1078. break;
  1079. }
  1080. return str1;
  1081. }
  1082. }
  1083. }
  1084. }
  1085. $(this).closest('div').after(str);
  1086. $(Selector.FLOW_DESIGN_DETAIL_BOX + ' .stepBody .form-control').off('change' + EVENT_KEY).on(
  1087. 'change' + EVENT_KEY,
  1088. function () {
  1089. const key = $(this).data('key');
  1090. stepBody.inputs[key].value = $(this).val();
  1091. //console.log("======", curNode);
  1092. });
  1093. let ajaxTimer;
  1094. $(Selector.FLOW_DESIGN_DETAIL_BOX + ' .stepBody .ajaxSelect').off('change' + EVENT_KEY).off('keyup' + EVENT_KEY).on(
  1095. 'keyup' + EVENT_KEY,
  1096. function () {
  1097. const key = $(this).data('key'), value = $(this).val(), url = $(this).data('url'), $this = $(this);
  1098. clearTimeout(ajaxTimer);
  1099. ajaxTimer = setTimeout(() => {
  1100. //$.ajax({
  1101. // async: true,
  1102. // type: "Post",
  1103. // contentType: "application/json; charset=UTF-8",
  1104. // dataType:"josn",
  1105. //})
  1106. $.vbAjax4({
  1107. url: abp.appUrl + url + `?keyword=${value}&take=10`,
  1108. success: (res) => {
  1109. console.log("========================>>>>>", res)
  1110. let str = "";
  1111. for (const k in res) {
  1112. if (Object.prototype.hasOwnProperty.call(res, k)) {
  1113. const v = res[k];
  1114. str += `<span data-value="${k}" data-name="${v}">${v}(${k})</span>`
  1115. }
  1116. }
  1117. if (!str) {
  1118. str = `<strong>没有查询到数据</strong>`
  1119. }
  1120. $this.parent().find('.dy-select-result').html(str).show();
  1121. $this.parent().find('.dy-select-result span').off('click' + EVENT_KEY).on('click' + EVENT_KEY, function () {
  1122. const name = $(this).data("name"),
  1123. val = $(this).data("value");
  1124. stepBody.inputs[key].value = val;
  1125. stepBody.inputs[key].extend = name;
  1126. $this.val(name);
  1127. })
  1128. }
  1129. })
  1130. }, 500);
  1131. stepBody.inputs[key].value = value;
  1132. stepBody.inputs[key].extend = value;
  1133. console.log("======", curNode);
  1134. });
  1135. }
  1136. }
  1137. } else {
  1138. data[name] = val;
  1139. _this.renderNode(data, true);
  1140. }
  1141. //console.log("======", curNode);
  1142. });
  1143. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.' + ClassName.DELETE).off('click' + EVENT_KEY).on('click' + EVENT_KEY, function () { _this.deleteNode(data) });
  1144. if (data.stepBody && data.stepBody.name) {
  1145. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.form-control[name="stepBody"]').val(data.stepBody.name).trigger('change')
  1146. }
  1147. function stepBodySelectStr() {
  1148. let str = `<option value="">请选择执行操作</option>`;
  1149. if (_config.stepBodies && _config.stepBodies.length) {
  1150. _config.stepBodies.forEach(v => { str += `<option value="${v.name}" $>${v.displayName}</option>`; });
  1151. }
  1152. return str;
  1153. }
  1154. }
  1155. _proto.renderFLowConnectionDetail = function (data) {
  1156. let _this = this, _config = _this._config;
  1157. data.conditions = data.conditions || [];
  1158. //console.log(data);
  1159. let str = '';
  1160. str += `<div class="${ClassName.TITLE}">连线详情</div>`;
  1161. str += `<form class="${ClassName.FLOW_DESIGN_DETAIL_BOX}">
  1162. <div class="d-flex flex-column">
  1163. <label class="fs-6 fw-bolder mb-1">连线标题</label>
  1164. <input type="text" class="form-control form-control-sm form-control-solid" name="label" value="${data.label || ""}" placeholder="请输入连线标题...">
  1165. <div class="invalid-feedback"></div>
  1166. </div>
  1167. <div class="d-flex flex-column params">
  1168. <div class="label"><label class="fs-6 fw-bolder">条件</label><span class="fa fa-plus ${ClassName.ADD}-${ClassName.ITEM}" title="添加条件" data-name="style"></span></div>${conditionsStr()}
  1169. <div class="invalid-feedback"></div>
  1170. </div>
  1171. <div class="d-flex flex-column">
  1172. <button type="button" class="btn btn-outline btn-outline-dashed btn-outline-danger btn-active-light-danger ${ClassName.DELETE}"><i class="far fa-trash-alt text-danger"></i>删除连线</button>
  1173. </div>
  1174. </form>`;
  1175. function conditionsStr() {
  1176. let str = '';
  1177. if (data.conditions && data.conditions.length) {
  1178. data.conditions.forEach(v => { str += conditionStr(v); });
  1179. } else {
  1180. //str = conditionStr();
  1181. }
  1182. return str;
  1183. }
  1184. function conditionStr(v) {
  1185. let str =
  1186. `<div class="input-group input-group-sm ${ClassName.CONDITION}" >
  1187. <select type="text" class="form-control form-control-sm form-select form-control-solid" name="field" style="width:30%">${inputSelectStr(v ? v.field : "")}</select>
  1188. <select type="text" class="form-control form-control-sm form-select form-control-solid" name="operator" style="width:15%">
  1189. <option value="">请选择</option>
  1190. <option value=">" ${v && v.operator == '>' ? 'selected' : ''}>大于</option>
  1191. <option value=">=" ${v && v.operator == '>=' ? 'selected' : ''}>不小于</option>
  1192. <option value="<" ${v && v.operator == '<' ? 'selected' : ''}>小于</option>
  1193. <option value="<=" ${v && v.operator == '<=' ? 'selected' : ''}>不大于</option>
  1194. <option value="!=" ${v && v.operator == '!=' ? 'selected' : ''}>不等于</option>
  1195. <option value="==" ${v && v.operator == '==' ? 'selected' : ''}>等于</option>
  1196. </select>
  1197. <input type="text" class="form-control form-control-sm form-control-solid" name="value" value="${v ? v.value || "" : ""}">
  1198. <button class="btn btn-danger btn-sm" type="button" onclick=""><i class="fas fa-minus-square"></i></button>
  1199. </div>`;
  1200. return str;
  1201. }
  1202. function inputSelectStr(field) {
  1203. let str = '<option value="">请选择</option> ';
  1204. const inputs = _this.filterDataInputs();
  1205. inputs.forEach(v => { str += ` <option value="${v.name}" ${v.name == field ? 'selected' : ''}>${v.name}</option>`; });
  1206. return str;
  1207. }
  1208. function bindChangeEvent() {
  1209. $(Selector.FLOW_DESIGN_DETAIL_BOX).find(Selector.CONDITION + ' .form-control').off('change' + EVENT_KEY).on('change' + EVENT_KEY, function () {
  1210. const $parent = $(this).closest(Selector.CONDITION),
  1211. val = $(this).val(),
  1212. name = $(this).attr('name');
  1213. const index = $(Selector.FLOW_DESIGN_DETAIL_BOX).find(Selector.CONDITION).index($parent);
  1214. try {
  1215. let condition = data.conditions[index];
  1216. condition[name] = val;
  1217. } catch (e) {
  1218. console.error(e);
  1219. }
  1220. });
  1221. $(Selector.FLOW_DESIGN_DETAIL_BOX).find(Selector.CONDITION + ` button`).off('click' + EVENT_KEY).on('click' + EVENT_KEY, function () {
  1222. const $parent = $(this).closest(Selector.CONDITION);
  1223. const index = $(Selector.FLOW_DESIGN_DETAIL_BOX).find(Selector.CONDITION).index($parent);
  1224. conditionNode.conditions.splice(index, 1);
  1225. $(this).closest(Selector.CONDITION).remove();
  1226. });
  1227. }
  1228. $(Selector.FLOW_DESIGN_NODE).removeClass(ClassName.ACTIVE);
  1229. $(Selector.FLOW_DESIGN_PATH).removeClass(ClassName.ACTIVE);
  1230. $(Selector.FLOW_DESIGN_PATH_HOVER).addClass(ClassName.ACTIVE);
  1231. $(Selector.FLOW_DESIGN_DETAIL).html(str);
  1232. //$(Selector.FLOW_DESIGN_DETAIL).find('select').select2();
  1233. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.form-control[name="label"]').off('change' + EVENT_KEY).on('change' + EVENT_KEY, function () {
  1234. data.label = $(this).val();
  1235. _this.revalidateConnection(data);
  1236. });
  1237. bindChangeEvent();
  1238. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.' + ClassName.DELETE).off('click' + EVENT_KEY).on('click' + EVENT_KEY, function () { _this.deleteConnection(data.label) });
  1239. $(Selector.FLOW_DESIGN_DETAIL_BOX).find(Selector.ADD_ITEM).off("click" + EVENT_KEY).on("click" + EVENT_KEY, function () {
  1240. $(Selector.FLOW_DESIGN_DETAIL_BOX).find('.' + ClassName.DELETE).parent().before(conditionStr());
  1241. data.conditions.push({
  1242. field: "",
  1243. operator: "",
  1244. value: ""
  1245. });
  1246. bindChangeEvent();
  1247. });
  1248. }
  1249. _proto.getStepBodies = function () {
  1250. let _this = this, _config = _this._config;
  1251. return _config.stepBodies;
  1252. }
  1253. _proto.setStepBodies = function (data, isCover) {
  1254. let _this = this, _config = _this._config;
  1255. isCover = isCover == undefined ? true : (isCover || false);
  1256. if (isCover) {
  1257. _config.stepBodies = data;
  1258. } else {
  1259. $.extend(true, _config.stepBodies || [], data || []);
  1260. }
  1261. return _config.stepBodies;
  1262. }
  1263. _proto.getInputDataByDom = function (that) {
  1264. let _this = this, _config = _this._config;
  1265. let $item = $(that).closest("." + ClassName.ITEM), $box = $(that).closest("." + ClassName.DY_FORM_DRAG_BOX);
  1266. var index1 = $(Selector.DY_FORM_DRAG_BOX).index($box),
  1267. index2 = $box.find("." + ClassName.ITEM).index($item);
  1268. try {
  1269. let data = _config.data.inputs[index1][index2];
  1270. return data;
  1271. } catch (e) {
  1272. console.error(e);
  1273. return undefined;
  1274. }
  1275. }
  1276. _proto.completeFlow = function () {
  1277. let _this = this, _config = _this._config;
  1278. //console.log(_config.data);
  1279. //console.log(JSON.stringify(_config.data));
  1280. if (_config.submit) {
  1281. _config.data.version = _config.data.version || 1;
  1282. _config.data.group = _config.data.group || "G1";
  1283. _config.data.color = _config.data.color || "red";
  1284. _config.submit.call(_this, _config.data);
  1285. }
  1286. }
  1287. _proto.filterDataInputs = function () {
  1288. let _this = this, _config = _this._config;
  1289. let inputs = [];
  1290. _config.data.inputs.forEach(v => {
  1291. if (v.length > 0) {
  1292. v.forEach(vv => {
  1293. if (vv.name) {
  1294. inputs.push(vv);
  1295. }
  1296. })
  1297. }
  1298. });
  1299. return inputs;
  1300. }
  1301. _proto.bindEvent = function () {
  1302. let _this = this, _config = _this._config;
  1303. _this.bindStepToolEvent();
  1304. _this.bindDesignMoveEvent();
  1305. _this.bindAddFormComponentEvent();
  1306. _this.bindFormComponentDragEvent();
  1307. _this.bindSourceNodeEvent();
  1308. _this.bindIntanceEvent();
  1309. }
  1310. _proto.bindStepToolEvent = function () {
  1311. let _this = this, _config = _this._config;
  1312. $(Selector.STEP_TOOL_BTN_PREV).on('click' + EVENT_KEY, function () { toggleStep() });
  1313. $(Selector.STEP_TOOL_BTN_NEXT).on('click' + EVENT_KEY, function () { toggleStep(true) });
  1314. $(Selector.STEP_TOOL_BTN_COMPLETE).on('click' + EVENT_KEY, function () { _this.completeFlow() });
  1315. $(Selector.BASE_FORM).find('.form-control').on('change' + EVENT_KEY,
  1316. function () {
  1317. let $this = $(this), name = $this.attr('name');
  1318. _config.data[name] = $this.val();
  1319. });
  1320. function toggleStep(isNext) {
  1321. if (isNext) {
  1322. if (curStep == 0 && !$.formValidate($(Selector.BASE_FORM))) {
  1323. console.log(`STEP表单验证失败==>${curStep}`);
  1324. return;
  1325. }
  1326. }
  1327. var step = isNext ? curStep + 1 : curStep - 1;
  1328. if (step < 0 || step >= maxStep) {
  1329. console.log(`STEP超出范围[0-${maxStep}]==>${step}`);
  1330. return;
  1331. }
  1332. curStep = step;
  1333. if (isNext) {
  1334. $(Selector.STEP_TAB_ITEM_ACTIVE).removeClass(ClassName.ACTIVE).addClass(ClassName.FINISH);
  1335. } else {
  1336. $(Selector.STEP_TAB_ITEM_ACTIVE).removeClass(ClassName.ACTIVE);
  1337. $(Selector.STEP_TAB_ITEM + "_" + curStep).removeClass(ClassName.FINISH);
  1338. }
  1339. $(Selector.STEP_TAB_ITEM + "_" + curStep).addClass(ClassName.ACTIVE);
  1340. $(Selector.STEP_CONTENT_ITEM).removeClass(ClassName.SHOW);
  1341. $(Selector.STEP_CONTENT_ITEM + "_" + curStep).addClass(ClassName.SHOW);
  1342. $(Selector.STEP_TOOL_BTN_SHOW).removeClass(ClassName.SHOW);
  1343. switch (curStep) {
  1344. case 0:
  1345. $(Selector.STEP_TOOL_BTN_NEXT).addClass(ClassName.SHOW);
  1346. break;
  1347. case 1:
  1348. $(Selector.STEP_TOOL_BTN_PREV).addClass(ClassName.SHOW);
  1349. $(Selector.STEP_TOOL_BTN_NEXT).addClass(ClassName.SHOW);
  1350. //console.log("STEP_1", _config.data);
  1351. break;
  1352. case 2:
  1353. $(Selector.STEP_TOOL_BTN_PREV).addClass(ClassName.SHOW);
  1354. $(Selector.STEP_TOOL_BTN_COMPLETE).addClass(ClassName.SHOW);
  1355. _this.createFlow();
  1356. break;
  1357. }
  1358. }
  1359. }
  1360. _proto.bindDesignMoveEvent = function () {
  1361. const designMoveDrag = { moving: false, mouseStartPoint: [], distance: [], target: undefined };
  1362. $(Selector.DESIGN_CONTAINER).on('mousedown' + EVENT_KEY, Selector.DESIGN_MOVE_COL, function (e) {
  1363. //webkit内核和火狐禁止文字被选中
  1364. $('body').addClass(ClassName.DRAG_SELECT);
  1365. //ie浏览器禁止文字选中
  1366. document.body.onselectstart = document.body.ondrag = function () {
  1367. return false;
  1368. };
  1369. designMoveDrag.moving = true;
  1370. designMoveDrag.mouseStartPoint = [e.clientX, e.pageY];
  1371. designMoveDrag.distance = [$(this).prev().width(), $(this).next().width()];
  1372. designMoveDrag.target = $(this);
  1373. //console.log(designMoveDrag);
  1374. });
  1375. $('body').on('mouseup' + EVENT_KEY, function () {
  1376. $('body').removeClass(ClassName.DRAG_SELECT);
  1377. document.body.onselectstart = document.body.ondrag = null;
  1378. designMoveDrag.moving = false;
  1379. designMoveDrag.mouseStartPoint = [];
  1380. designMoveDrag.distance = [];
  1381. designMoveDrag.target = undefined;
  1382. //console.log("===>", designMoveDrag);
  1383. });
  1384. $(Selector.DESIGN_CONTAINER).on('mousemove' + EVENT_KEY, function (e) {
  1385. if (designMoveDrag.moving) {
  1386. //console.log("======>", e.clientX, designMoveDrag);
  1387. let moveDistance = e.clientX - designMoveDrag.mouseStartPoint[0];
  1388. let d1 = designMoveDrag.distance[0] + moveDistance;
  1389. let d2 = designMoveDrag.distance[1] - moveDistance;
  1390. if (d1 < 50) {
  1391. d1 = 50;
  1392. d2 = designMoveDrag.distance[0] + designMoveDrag.distance[1] - 50;
  1393. } else if (d2 < 50) {
  1394. d2 = 50;
  1395. d1 = designMoveDrag.distance[0] + designMoveDrag.distance[1] - 50;
  1396. }
  1397. designMoveDrag.target.prev().width(d1);
  1398. designMoveDrag.target.next().width(d2);
  1399. }
  1400. });
  1401. }
  1402. _proto.bindAddFormComponentEvent = function () {
  1403. let _this = this, _config = _this._config;
  1404. $(Selector.FORM_DESIGN_BTN_GROUP_ADD_BTN).on('click' + EVENT_KEY, function () {
  1405. const colCount = $(this).data('col');
  1406. _this.renderFormComponent(colCount, undefined, true);
  1407. });
  1408. }
  1409. _proto.bindFormComponentDragEvent = function () {
  1410. $(Selector.FORM_COMPONENT_ITEM).on("dragstart" + EVENT_KEY,
  1411. function (e) {
  1412. this.style.borderColor = '#2d8cf0';
  1413. this.style.borderStyle = 'solid';
  1414. this.style.fontWeight = '600';
  1415. const type = $(this).data('type');
  1416. e.originalEvent.dataTransfer.setData('type', type);
  1417. });
  1418. $(Selector.FORM_COMPONENT_ITEM).on("dragend" + EVENT_KEY,
  1419. function (e) {
  1420. this.style.borderColor = '#dcdee2';
  1421. this.style.borderStyle = 'dashed';
  1422. this.style.fontWeight = '400';
  1423. e.originalEvent.dataTransfer.clearData();
  1424. });
  1425. }
  1426. _proto.bindDyItemDragEvent = function () {
  1427. let _this = this, _config = _this._config;
  1428. $(Selector.DY_FORM_DRAG_ITEM).off("dragover" + EVENT_KEY).on("dragover" + EVENT_KEY, function (e) {
  1429. e.preventDefault();
  1430. changeStyle(this);
  1431. });
  1432. $(Selector.DY_FORM_DRAG_ITEM).off("dragenter" + EVENT_KEY).on("dragenter" + EVENT_KEY, function (e) {
  1433. e.preventDefault();
  1434. changeStyle(this);
  1435. });
  1436. $(Selector.DY_FORM_DRAG_ITEM).off("dragleave" + EVENT_KEY).on("dragleave" + EVENT_KEY, function (e) {
  1437. e.preventDefault();
  1438. changeStyle(this, true);
  1439. });
  1440. $(Selector.DY_FORM_DRAG_ITEM).off("drop" + EVENT_KEY).on("drop" + EVENT_KEY, function (e) {
  1441. e.preventDefault();
  1442. changeStyle(this, true);
  1443. const type = e.originalEvent.dataTransfer.getData('type');
  1444. const input = JSON.parse(JSON.stringify(_config.formComponents.find(v => { return v.type == type })));
  1445. //console.log("=========>", type, input);
  1446. let data = _this.getInputDataByDom($(this));
  1447. if (data) {
  1448. data.name = '';
  1449. data.label = input.label;
  1450. data.type = input.type;
  1451. data.items = input.items || [];
  1452. data.styles = input.styles || [];
  1453. data.rules = [];
  1454. }
  1455. _this.renderInputDom(data, true);
  1456. });
  1457. function changeStyle(_this, isRecover) {
  1458. if (isRecover) {
  1459. _this.style.borderColor = '#ddd';
  1460. _this.style.borderStyle = 'dotted';
  1461. _this.style.borderWidth = '1px';
  1462. } else {
  1463. _this.style.borderColor = '#2d8cf0';
  1464. _this.style.borderStyle = 'solid';
  1465. _this.style.borderWidth = '2px';
  1466. }
  1467. }
  1468. }
  1469. _proto.bindDyItemInputEvent = function () {
  1470. let _this = this, _config = _this._config;
  1471. $(Selector.DY_FORM_INPUT_BOX).off('click' + EVENT_KEY).on('click' + EVENT_KEY,
  1472. function () {
  1473. $(Selector.DY_FORM_INPUT_BOX).removeClass(ClassName.ACTIVE);
  1474. $(this).addClass(ClassName.ACTIVE);
  1475. let data = _this.getInputDataByDom($(this));
  1476. _this.renderInputParamsDetail(data);
  1477. //console.log("=========>", _config.data.inputs);
  1478. });
  1479. $(Selector.DY_FORM_INPUT_BOX_DELETE).off('click' + EVENT_KEY).on('click' + EVENT_KEY,
  1480. function (e) {
  1481. e.preventDefault();
  1482. let data = _this.getInputDataByDom($(this));
  1483. if (data) {
  1484. data.id = '';
  1485. data.name = '';
  1486. data.label = '';
  1487. data.type = '';
  1488. data.minLength = undefined;
  1489. data.maxLength = undefined;
  1490. data.items = [];
  1491. data.styles = [];
  1492. data.rules = [];
  1493. $(this).closest("." + ClassName.ITEM).html(templates[0]);
  1494. }
  1495. //console.log("==============>", _config.data.inputs);
  1496. });
  1497. }
  1498. _proto.bindSourceNodeEvent = function () {
  1499. let _this = this, _config = _this._config;
  1500. $(Selector.FLOW_DESIGN_NODE_SOURCE_ITEM).off('dblclick' + EVENT_KEY)
  1501. .on('dblclick' + EVENT_KEY, function () {
  1502. let type = $(this).data('type');
  1503. let node = _this.createNode(type);
  1504. if (node) {
  1505. _config.data.nodes.push(node);
  1506. _this.renderNode(node);
  1507. }
  1508. });
  1509. }
  1510. _proto.bindIntanceEvent = function () {
  1511. let _this = this, _config = _this._config;
  1512. instance.bind('connection', function (info) { _this.addConnection(info) });
  1513. instance.bind('click', function (connection) {
  1514. let source = _this.getNode(connection.sourceId);
  1515. conditionNode = source.nextNodes.find(v => v.nodeId == connection.targetId) || {
  1516. nodeId: connection.targetId,
  1517. label: "",
  1518. conditions: []
  1519. };
  1520. curConnection = connection;
  1521. //console.log(connection);
  1522. //console.log("======>", connection, conditionNode);
  1523. _this.renderFLowConnectionDetail(conditionNode);
  1524. });
  1525. }
  1526. _proto.setZoom = function (zoom, transformOrigin, el) {
  1527. transformOrigin = transformOrigin || [0.5, 0.5];
  1528. el || instance.getContainer();
  1529. var p = ["webkit", "moz", "ms", "o"],
  1530. s = "scale(" + zoom + ")",
  1531. oString = (transformOrigin[0] * 100) + "% " + (transformOrigin[1] * 100) + "%";
  1532. for (var i = 0; i < p.length; i++) {
  1533. el.style[p[i] + "Transform"] = s;
  1534. el.style[p[i] + "TransformOrigin"] = oString;
  1535. }
  1536. el.style["transform"] = s;
  1537. el.style["transformOrigin"] = oString;
  1538. instance.setZoom(zoom);
  1539. }
  1540. //可以不渲染workflow就可以使用
  1541. _proto.useDyForm = function (inputs, isDisabled, container) {
  1542. let _this = this;
  1543. if (!container) {
  1544. container = _this._element;
  1545. }
  1546. $(container).html("");
  1547. _this.renderForm(inputs, false, container);
  1548. if (isDisabled) {
  1549. $(container).find('input').prop("disabled", true);
  1550. $(container).find('select').prop("readonly", true);
  1551. }
  1552. $(container).find('select').select2();
  1553. $(container).find('input[data-vb-date]').VbDate();
  1554. }
  1555. _proto.getDyFormData = function (inputs, container) {
  1556. let _this = this;
  1557. if (!container) {
  1558. container = _this._element;
  1559. }
  1560. let data = {};
  1561. $(container).find(".form-control").each(function () {
  1562. const name = $(this).attr('name'), value = $(this).val();
  1563. data[name] = value;
  1564. })
  1565. $(container).find(".form-check-input[type='radio']:checked").each(function () {
  1566. const name = $(this).attr('name'), value = $(this).attr('value');
  1567. data[name] = value;
  1568. })
  1569. $(container).find(".form-check-input[type='checkbox']:checked").each(function () {
  1570. const name = $(this).attr('name'), value = $(this).attr('value');
  1571. if (!data[name] || !data[name].length) {
  1572. data[name] = [];
  1573. }
  1574. data[name].push(value);
  1575. })
  1576. //inputs.forEach(v => {
  1577. // v.forEach(vv => {
  1578. // vv.value = data[vv.name] || "";
  1579. // data[vv.name] = vv;
  1580. // })
  1581. //})
  1582. return data;
  1583. }
  1584. Workflow._jQueryInterface = function _jQueryInterface(option) {
  1585. let value, args = Array.prototype.slice.call(arguments, 1);
  1586. this.each(function () {
  1587. let data = $(this).data(DATA_KEY);
  1588. let _options = $.extend({}, Default, $(this).data(), typeof option === 'object' && option);
  1589. if ($.inArray(option, ALLOW_METHOD_2) >= 0) {
  1590. data = new Workflow(this)
  1591. value = data[option].apply(data, args);
  1592. } else if (!data) {
  1593. data = new Workflow(this, _options);
  1594. data.init();
  1595. $(this).data(DATA_KEY, data);
  1596. } else if (typeof option === 'string') {
  1597. if ($.inArray(option, ALLOW_METHOD) < 0) {
  1598. throw new Error("Unknown method: " + option);
  1599. }
  1600. value = data[option].apply(data, args);
  1601. }
  1602. });
  1603. return typeof value === 'undefined' ? this : value;
  1604. };
  1605. return Workflow;
  1606. }();
  1607. /**
  1608. * jQuery API
  1609. * ====================================================
  1610. */
  1611. $.fn[NAME] = Workflow._jQueryInterface;
  1612. $.fn[NAME].Constructor = Workflow;
  1613. $.fn[NAME].noConflict = function () {
  1614. $.fn[NAME] = JQUERY_NO_CONFLICT;
  1615. return Workflow._jQueryInterface;
  1616. };
  1617. return Workflow;
  1618. }(jQuery);
  1619. exports.VbWorkflow = VbWorkflow;
  1620. Object.defineProperty(exports, '__esModule', { value: true });
  1621. })));