workflowsetting.vue 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. <!--
  2. * @Author: zwy
  3. * @Date: 2021-02-21 10:11:08
  4. * @LastEditors: zwy
  5. * @LastEditTime: 2021-03-11 15:39:12
  6. * @Descripttion: 巡检任务流程
  7. -->
  8. <template>
  9. <div class="bpmn">
  10. <div class="bpmn-left" ref="bpmn">
  11. <div class="bpmn-title">流程图设计</div>
  12. </div>
  13. <div class="bpmn-right">
  14. <div class="bpmn-title">节点配置</div>
  15. <div class="no-scrollbar">
  16. <div class="bpmn-node">节点ID: {{ nodeId }}</div>
  17. <user
  18. :values="userValues"
  19. v-if="showUserSelect"
  20. :channelId="channelId"
  21. :prevTask="prevUserTaskObj"
  22. :isReject="isReject"
  23. :rejectUser="rejectUserValue"
  24. @change="userChange"
  25. @rejectUserChange="rejectUserChange"
  26. ></user>
  27. <condition
  28. :values="conditionValues"
  29. :channelId="channelId"
  30. :formId="prevFormId"
  31. @change="conditionChange"
  32. v-if="showConditionSelect"
  33. ></condition>
  34. <bpmn-form
  35. v-if="showFormSelect"
  36. :values="formValues"
  37. @change="formChange"
  38. :channelId="channelId"
  39. :getFormList="getFormList"
  40. ></bpmn-form>
  41. <service
  42. v-if="showSerivceSelect"
  43. :values="serviceValues"
  44. @change="serviceChange"
  45. :channelId="channelId"
  46. :prevTask="prevUserTaskObj"
  47. ></service>
  48. <!-- <user v-if='showAssign' :values='assignValues' @change='assignChange' :isAssign='true' :channelId='channelId'></user> -->
  49. <sequence
  50. v-if="showSequence"
  51. :formKey="sequenceFormKey"
  52. :channelId="channelId"
  53. @change="sequenceChange"
  54. :values="sequenceValue"
  55. ></sequence>
  56. </div>
  57. </div>
  58. </div>
  59. </template>
  60. <script>
  61. import 'bpmn-js/dist/assets/diagram-js.css'; //左边工具栏以及编辑节点的样式
  62. import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css';
  63. import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css';
  64. import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'; //这四个为bpmn工作流绘图工具的样式
  65. import BpmnModeler from 'bpmn-js/lib/Modeler'; //建模器
  66. import translateModer from '@utils/translate.js';
  67. import Provider from './bpmn/Provider';
  68. import BpmnModdle from 'bpmn-moddle';
  69. import condition from './bpmn/condition.vue';
  70. import user from './bpmn/user.vue';
  71. import bpmnForm from './bpmn/form.vue';
  72. import service from './bpmn/service.vue';
  73. import sequence from './bpmn/sequence.vue';
  74. // 初始化的xml
  75. let initXml = '';
  76. export default {
  77. props: ['params'],
  78. components: {
  79. condition,
  80. user,
  81. bpmnForm,
  82. service,
  83. sequence
  84. },
  85. data() {
  86. return {
  87. bmpn: '',
  88. model: '',
  89. // 节点ID
  90. nodeId: '',
  91. // 是否显示条件选择
  92. showConditionSelect: false,
  93. // 是否显示用户选择
  94. showUserSelect: false,
  95. // 是否显示表单
  96. showFormSelect: false,
  97. // 是否显示服务设置
  98. showSerivceSelect: false,
  99. // 是否显示指派设置
  100. showAssign: false,
  101. // 显示节点之间连接的节点动作配置
  102. showSequence: false,
  103. prevUserTaskObj: {},
  104. // 是否为驳回表单
  105. isReject: '',
  106. // 驳回节点处理的值
  107. rejectUserValue: '',
  108. // 连线起始节点的表单Key
  109. sequenceFormKey: '',
  110. sequenceValue: '',
  111. // 节点ID的顺序集合
  112. nodeIdOrderList: [],
  113. getFormList: []
  114. };
  115. },
  116. methods: {
  117. fromXML() {
  118. return new Promise((resolve) => {
  119. this.model.fromXML(xml, { format: true }, (err, res) => {
  120. resolve(res);
  121. });
  122. });
  123. },
  124. toXML(result) {
  125. return new Promise((resolve) => {
  126. this.model.toXML(result, { format: true }, (err, xml) => {
  127. resolve(xml);
  128. });
  129. });
  130. },
  131. getBpmn() {
  132. return new Promise((resolve) => {
  133. this.$http
  134. .get('/sc-community/workflow/process/getBpmnContent', {
  135. id: this.params.data.id
  136. })
  137. .then((res) => {
  138. initXml = res.data || '';
  139. resolve(res.data || '');
  140. });
  141. });
  142. },
  143. getXML() {
  144. //下载为bpmn格式
  145. return new Promise((resolve) => {
  146. this.bpmn.saveXML({ format: true }, (err, xml) => {
  147. this.model.fromXML(xml, { format: true }, (err, definitions, context) => {
  148. resolve({ definitions, context });
  149. });
  150. });
  151. });
  152. },
  153. getIdOrder(root) {
  154. let i = root.length,
  155. dataArr = [],
  156. loop = function (node, arr) {
  157. if (!node) return;
  158. if (node instanceof Array) {
  159. let j = node.length;
  160. while (j--) {
  161. let arrs = [...arr];
  162. if (node[j].$type == 'bpmn:EndEvent' || (!node[j].outgoing && !node[j].targetRef)) {
  163. dataArr.push(arr);
  164. return;
  165. }
  166. loop(node[j].targetRef, arrs);
  167. }
  168. } else {
  169. let set = new Set(arr);
  170. if (set.has(node.id)) return;
  171. if (node.$type == 'bpmn:UserTask' || node.$type == 'bpmn:ServiceTask') {
  172. arr.push(node.id);
  173. }
  174. if (node.$type == 'bpmn:EndEvent' || (!node.outgoing && !node.targetRef)) {
  175. dataArr.push(arr);
  176. return;
  177. }
  178. loop(node.outgoing, arr);
  179. }
  180. },
  181. start;
  182. while (i--) {
  183. if ('bpmn:StartEvent' == root[i].$type) {
  184. start = root[i];
  185. break;
  186. }
  187. }
  188. loop(start.outgoing, []);
  189. this.nodeIdOrderList = dataArr;
  190. },
  191. // 获取选择的用户
  192. userChange(arr) {
  193. if (!this.nodeId) return;
  194. this.getXML().then(({ definitions, context }) => {
  195. let eles = definitions.rootElements[0].flowElements,
  196. selectModel,
  197. i = eles.length;
  198. while (i--) {
  199. if (this.nodeId == eles[i].id) {
  200. selectModel = eles[i];
  201. break;
  202. }
  203. }
  204. if (selectModel.documentation == undefined) {
  205. selectModel.extensionElements = this.model.create('bpmn:Documentation', { text: JSON.stringify(arr) });
  206. } else {
  207. selectModel.documentation[0].text = JSON.stringify(arr);
  208. }
  209. // 渲染xml
  210. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  211. this.bpmn.importXML(xml, (_) => {
  212. // 改变元素颜色
  213. // let modeling = this.bpmn.get('modeling');
  214. // let elementRegistry = this.bpmn.get('elementRegistry');//使用elementRegistry来获取Shape信息
  215. // let elementToColor = elementRegistry.get(this.nodeId);//传递id进去
  216. // modeling.setColor(elementToColor, {
  217. // stroke: 'green',
  218. // fill: 'yellow'
  219. // })
  220. });
  221. });
  222. });
  223. },
  224. // 用户节点驳回处理人员改变
  225. rejectUserChange(val) {
  226. if (!this.nodeId) return;
  227. this.getXML().then(({ definitions, context }) => {
  228. let root = definitions.rootElements[0],
  229. obj = {},
  230. documentation = root.get('documentation');
  231. // 根节点添加documentation,用来存储各个节点的驳回处理人
  232. if (documentation.length) {
  233. obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
  234. obj[this.nodeId] = val;
  235. documentation[0].text = JSON.stringify(obj);
  236. } else {
  237. obj[this.nodeId] = val;
  238. documentation = this.model.create('bpmn:Documentation', { text: JSON.stringify(obj) });
  239. root.get('documentation').push(documentation);
  240. }
  241. // 2,驳回后的节点加监听器
  242. // <extensionElements>
  243. // <activiti:taskListener event="create" class="com.bz.smart_city.activiti.listener.ReturnTaskListener"></activiti:taskListener>
  244. // </extensionElements>
  245. // 3,驳回后的节点加内容
  246. // from上级节点
  247. // assignee:first受理人,last处理人
  248. // <documentation>{"rejectConfig":[{"from":"usertask2","assignee":"first"},{"from":"usertask3","assignee":"last"}]}</documentation>
  249. let selectEl = context.elementsById[this.nodeId],
  250. out = selectEl.outgoing || [],
  251. i = out.length,
  252. targetRef;
  253. // 获取驳回连线的目标节点
  254. while (i--) {
  255. if (out[i].conditionExpression && out[i].conditionExpression.body == '${action=="reject"}') {
  256. targetRef = out[i].targetRef;
  257. break;
  258. }
  259. }
  260. if (targetRef) {
  261. let targetRefDoc = targetRef.get('documentation');
  262. if (targetRefDoc.length) {
  263. let temp = targetRefDoc[0].text;
  264. temp = temp ? JSON.parse(temp) : {};
  265. let config = temp.rejectConfig,
  266. tag = false;
  267. // 如果已有,则替换assignee的值
  268. for (let i in config) {
  269. if (config[i].from == this.nodeId) {
  270. tag = true;
  271. config[i].assignee = val;
  272. break;
  273. }
  274. }
  275. // 没有则添加一条记录
  276. if (!tag) {
  277. config.push({
  278. from: this.nodeId,
  279. assignee: val
  280. });
  281. }
  282. targetRefDoc[0].text = JSON.stringify({ rejectConfig: config });
  283. } else {
  284. let doc = this.model.create('bpmn:Documentation', {
  285. text: '{"rejectConfig":[{"from":"' + this.nodeId + '","assignee":"' + assignee + '"}]}'
  286. });
  287. targetRefDoc.push(doc);
  288. }
  289. // let extensionElements = this.model.create('bpmn:ExtensionElements'),
  290. // foo = this.model.createAny('activiti:taskListener', 'http://activiti.org/bpmn', {
  291. // event: 'create',
  292. // class: 'com.bz.smart_city.activiti.listener.ReturnTaskListener'
  293. // });
  294. // extensionElements.get('values').push(foo);
  295. // targetRef.extensionElements = extensionElements
  296. }
  297. // 渲染xml
  298. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  299. this.bpmn.importXML(xml);
  300. });
  301. });
  302. },
  303. // 获取分支条件
  304. // conditionChange(obj) {
  305. // let temp = {}
  306. // for(let item in obj) {
  307. // if(obj[item] instanceof Array && obj[item].length) {
  308. // temp[item] = obj[item]
  309. // }
  310. // if('alarmTimeRange' == item && '-' != obj[item]) {
  311. // temp[item] = obj[item]
  312. // }
  313. // if('preHandleResult' == item && obj[item]) {
  314. // temp[item] = obj[item]
  315. // }
  316. // }
  317. // if(!this.nodeId) return
  318. // this.getXML().then(({definitions, context}) => {
  319. // let eles = definitions.rootElements[0].flowElements,
  320. // selectModel,
  321. // i = eles.length;
  322. // while(i--) {
  323. // if(this.nodeId == eles[i].id) {
  324. // selectModel = eles[i]
  325. // break;
  326. // }
  327. // }
  328. // if('{}' != JSON.stringify(temp)) {
  329. // selectModel.conditionExpression = this.model.create('bpmn:FormalExpression', {
  330. // body: "${workFlowConditionService.checkCondition(execution,\""+JSON.stringify(temp).replace(/\"/g,"\\\"")+"\")}"
  331. // })
  332. // } else {
  333. // selectModel.conditionExpression = null;
  334. // }
  335. // // 渲染xml
  336. // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
  337. // this.bpmn.importXML(xml)
  338. // })
  339. // })
  340. // },
  341. // 表单选择
  342. formChange(val) {
  343. if (!this.nodeId) return;
  344. this.getFormDetail(val);
  345. this.getXML().then(({ definitions, context }) => {
  346. let eles = definitions.rootElements[0].flowElements,
  347. selectModel,
  348. i = eles.length;
  349. while (i--) {
  350. if (this.nodeId == eles[i].id) {
  351. selectModel = eles[i];
  352. break;
  353. }
  354. }
  355. // 置空下游连接线上的节点动作值
  356. let outgoing = selectModel.outgoing || [],
  357. j = outgoing.length,
  358. temp;
  359. while (j--) {
  360. outgoing[j].conditionExpression = null;
  361. }
  362. selectModel.$attrs['activiti:formKey'] = val;
  363. // 渲染xml
  364. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  365. this.bpmn.importXML(xml);
  366. });
  367. });
  368. },
  369. // 根据表单key获取表单详情
  370. getFormDetail(key, resolve) {
  371. this.showAssign = false;
  372. this.isReject = false;
  373. if ('water-form' == key) {
  374. this.showAssign = true;
  375. resolve && resolve();
  376. return;
  377. }
  378. this.$http
  379. .get('/sc-community/workflow/form/' + key, {
  380. channelId: this.channelId
  381. })
  382. .then(({ data = {} }) => {
  383. let actionList = data.userActionList || [],
  384. i = actionList.length;
  385. while (i--) {
  386. if ('指派' == actionList[i].actionName) {
  387. this.showAssign = true;
  388. break;
  389. }
  390. if ('reject' == actionList[i].actionValue) {
  391. this.isReject = true;
  392. }
  393. }
  394. resolve && resolve();
  395. });
  396. },
  397. // 服务任务改变
  398. serviceChange(arr) {
  399. if (!this.nodeId) return;
  400. this.getXML().then(({ definitions, context }) => {
  401. let eles = definitions.rootElements[0].flowElements,
  402. selectModel,
  403. i = eles.length;
  404. while (i--) {
  405. if (this.nodeId == eles[i].id) {
  406. selectModel = eles[i];
  407. break;
  408. }
  409. }
  410. // selectModel.$arrts['activiti:delegateExpression']="";
  411. // activiti:delegateExpression="${progressSevice.runWithParticipants(execution,'')}
  412. selectModel.$attrs['activiti:expression'] =
  413. "#{progressSevice.runWithParticipants(execution,'" + JSON.stringify(arr) + "')}";
  414. // console.log('服务任务的节点',selectModel)
  415. // console.log("arr的值",arr)
  416. if (selectModel.documentation == undefined) {
  417. selectModel.extensionElements = this.model.create('bpmn:Documentation', { text: JSON.stringify(arr) });
  418. } else {
  419. selectModel.documentation[0].text = JSON.stringify(arr);
  420. }
  421. // selectModel.$attrs['activiti:field'] = JSON.stringify(arr);
  422. // let extensionElements = this.model.create('bpmn:ExtensionElements'),
  423. // field = this.model.createAny('activiti:field', 'http://activiti.org/bpmn', {
  424. // event: 'create',
  425. // name:'expression',
  426. // }),
  427. // string = this.model.createAny('activiti:string', 'http://activiti.org/bpmn', {
  428. // event: 'create',
  429. // });
  430. // console.log("field",field)
  431. // field.extensionElements = string
  432. // extensionElements.get('values').push(field);
  433. // selectModel.extensionElements = extensionElements
  434. // selectModel.value.push(field)
  435. // 渲染xml
  436. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  437. this.bpmn.importXML(xml);
  438. });
  439. });
  440. },
  441. // 指派用户改变事件
  442. // assignChange(arr) {
  443. // if(!this.nodeId) return
  444. // this.getXML().then(({definitions, context}) => {
  445. // let eles = definitions.rootElements[0].extensionElements;
  446. // if(eles) {
  447. // let values = eles.get('values'),
  448. // i = values.length,
  449. // index;
  450. // while(i--) {
  451. // if('sc:transfer' == values[i].$type && this.nodeId == values[i].taskRef) {
  452. // index = i;
  453. // break
  454. // }
  455. // }
  456. // if(index) {
  457. // if(arr.length) {
  458. // values[index].usersRange = "${workOrderUserService.findUsers('"+arr+"')}"
  459. // } else {
  460. // values.splice(index, 1)
  461. // }
  462. // } else {
  463. // if(arr.length) {
  464. // let scTransfer = this.model.createAny('sc:transfer', 'http://sc', {
  465. // id: 'sc_transfer_'+(+new Date()),
  466. // taskRef: this.nodeId,
  467. // usersRange: "${workOrderUserService.findUsers('"+arr+"')}"
  468. // })
  469. // eles.get('values').push(scTransfer);
  470. // }
  471. // }
  472. // } else {
  473. // // if(arr.length) {
  474. // // eles = this.model.create('bpmn:ExtensionElements');
  475. // // let scTransfer = this.model.createAny('sc:transfer', 'http://sc', {
  476. // // id: 'sc_transfer_'+(+new Date()),
  477. // // taskRef: this.nodeId,
  478. // // usersRange: "${workOrderUserService.findUsers('"+arr+"')}"
  479. // // })
  480. // // eles.get('values').push(scTransfer);
  481. // // } else {
  482. // // return;
  483. // // }
  484. // }
  485. // // 渲染xml
  486. // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
  487. // this.bpmn.importXML(xml)
  488. // })
  489. // })
  490. // },
  491. // 节点连线的节点动作值改变
  492. sequenceChange(val) {
  493. if (!this.nodeId) return;
  494. this.getXML().then(({ definitions, context }) => {
  495. let eles = definitions.rootElements[0].flowElements,
  496. selectModel,
  497. i = eles.length;
  498. while (i--) {
  499. if (this.nodeId == eles[i].id) {
  500. selectModel = eles[i];
  501. break;
  502. }
  503. }
  504. console.log('节点动作的值', val);
  505. let scTransfer = this.model.create('bpmn:FormalExpression', {
  506. body: '${action=="' + val + '"}'
  507. });
  508. if (!val) {
  509. scTransfer = null;
  510. }
  511. /**
  512. *
  513. 2,驳回后的节点加监听器
  514. <extensionElements>
  515. <activiti:taskListener event="create" class="com.bz.smart_city.activiti.listener.ReturnTaskListener"></activiti:taskListener>
  516. </extensionElements>
  517. 3,驳回后的节点加内容
  518. from上级节点
  519. assignee:first受理人,last处理人
  520. <documentation>{"rejectConfig":[{"from":"usertask2","assignee":"first"},{"from":"usertask3","assignee":"last"}]}</documentation>
  521. */
  522. if (val === 'reject') {
  523. // 获取节点的驳回处理人
  524. let root = definitions.rootElements[0],
  525. obj = {},
  526. documentation = root.get('documentation');
  527. if (documentation.length) {
  528. obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
  529. }
  530. let sourceRef = selectModel.sourceRef,
  531. targetRef = selectModel.targetRef,
  532. targetRefDoc = targetRef.get('documentation'),
  533. doc = this.model.create('bpmn:Documentation', {
  534. text: '{"rejectConfig":[{"from":"' + sourceRef.id + '","assignee":"' + obj[sourceRef.id] + '"}]}'
  535. });
  536. if (obj[sourceRef.id]) {
  537. if (targetRefDoc.length) {
  538. let temp = targetRefDoc[0].text;
  539. temp = temp ? JSON.parse(temp) : {};
  540. let config = temp.rejectConfig,
  541. tag = false;
  542. // 如果已有,则替换assignee的值
  543. for (let i in config) {
  544. if (config[i].from == sourceRef.id) {
  545. tag = true;
  546. config[i].assignee = obj[sourceRef.id];
  547. break;
  548. }
  549. }
  550. // 没有则添加一条记录
  551. if (!tag) {
  552. config.push({
  553. from: sourceRef.id,
  554. assignee: obj[sourceRef.id]
  555. });
  556. }
  557. targetRefDoc[0].text = JSON.stringify({ rejectConfig: config });
  558. } else {
  559. targetRefDoc.push(doc);
  560. }
  561. // let extensionElements = this.model.create('bpmn:ExtensionElements'),
  562. // foo = this.model.createAny('activiti:taskListener', 'http://activiti.org/bpmn', {
  563. // event: 'create',
  564. // class: 'com.bz.smart_city.activiti.listener.ReturnTaskListener'
  565. // });
  566. // extensionElements.get('values').push(foo);
  567. // targetRef.extensionElements = extensionElements
  568. } else {
  569. // this.$message.error('该驳回操作没有设置驳回处理人员')
  570. }
  571. }
  572. selectModel.conditionExpression = scTransfer;
  573. // // 渲染xml
  574. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  575. this.bpmn.importXML(xml);
  576. });
  577. });
  578. },
  579. // 获取所有的上游用户节点ID及名字
  580. getPrevUserTaskObj(id, context) {
  581. let list = this.nodeIdOrderList,
  582. i = list.length,
  583. index,
  584. temp;
  585. while (i--) {
  586. index = list[i].indexOf(id);
  587. while (index > 0 && index--) {
  588. temp = context.elementsById[list[i][index]];
  589. if (temp.$type == 'bpmn:UserTask') {
  590. this.prevUserTaskObj[list[i][index]] = temp.name || temp.id;
  591. }
  592. }
  593. }
  594. },
  595. // 保存BPMN内容
  596. submit(callback) {
  597. //
  598. this.getXML().then(({ definitions, context }) => {
  599. let rootElements = definitions.rootElements[0];
  600. rootElements.id = this.params.data.processKey;
  601. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  602. this.bpmn.importXML(xml); //将字符串转换成图表显示出来, this.bpmnModeler.importXML(xmlStr, (err) => {if(err){}else{成功之后的回调}}
  603. let $loading = this.$loading();
  604. initXml = xml;
  605. this.$http
  606. .postForm('/sc-community/workflow/process/saveBpmnContent', {
  607. id: this.params.data.id,
  608. content: xml,
  609. svg: ''
  610. })
  611. .then((res) => {
  612. $loading.close();
  613. if (0 == res.status) {
  614. this.$message.success(res.msg);
  615. this.params.callback && this.params.callback();
  616. this.$emit('close');
  617. } else {
  618. this.$message.error(res.msg);
  619. }
  620. callback && callback();
  621. })
  622. .catch((err) => {
  623. $loading.close();
  624. callback && callback();
  625. });
  626. });
  627. });
  628. },
  629. getForm() {
  630. this.$http
  631. .get('/sc-community/workflow/form/list')
  632. .then((data) => {
  633. this.getFormList = data.data;
  634. })
  635. .catch(function () {});
  636. }
  637. },
  638. mounted() {
  639. this.bpmn = new BpmnModeler({
  640. container: this.$refs.bpmn,
  641. additionalModules: [
  642. {
  643. __init__: ['Provider'], //定义完provider这个类后,必须导出
  644. translate: ['value', translateModer],
  645. Provider: ['type', Provider]
  646. // Context: ['type', Context]
  647. }
  648. ]
  649. });
  650. //向后台请求xml数据,如果没有的话,给一段默认的xml字符串
  651. this.getBpmn().then((xml) => {
  652. if (xml) {
  653. this.bpmn.importXML(xml, (err) => {
  654. // 连接两个节点
  655. // let elementRegistry = this.bpmn.get('elementRegistry'),
  656. // ele1 = elementRegistry.get('startevent1'),
  657. // ele2 = elementRegistry.get('Task_1iyqgyp'),
  658. // ele3 = elementRegistry.get('EndEvent_0botuxl'),
  659. // modeling = this.bpmn.get('modeling')
  660. // modeling.connect(ele1, ele2, {
  661. // type: 'bpmn:SequenceFlow'//线
  662. // })
  663. // modeling.connect(ele2, ele3, {
  664. // type: 'bpmn:SequenceFlow'
  665. // })
  666. });
  667. } else {
  668. this.bpmn.importXML(
  669. `
  670. <?xml version="1.0" encoding="UTF-8"?>
  671. <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  672. <process id="myProcess" name="My process" isExecutable="true">
  673. <startEvent id="startevent1" name="开始"></startEvent>
  674. </process>
  675. <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
  676. <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
  677. <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
  678. <omgdc:Bounds height="35.0" width="35.0" x="84.0" y="150.0"></omgdc:Bounds>
  679. </bpmndi:BPMNShape>
  680. </bpmndi:BPMNPlane>
  681. </bpmndi:BPMNDiagram>
  682. </definitions>
  683. `,
  684. (err) => {
  685. // 手动创建节点
  686. // this.getXML().then(({definitions, context}) => {
  687. // let model = new BpmnModdle();
  688. // var bpmnProcess = model.create('bpmn:UserTask', {
  689. // id: 'UserTask_1_1',
  690. // });
  691. // var bpmdi = model.create('bpmndi:BPMNShape', {
  692. // // 填充颜色
  693. // fill: '#fff',
  694. // // 边框颜色
  695. // stroke: '#000',
  696. // bpmnElement: bpmnProcess,
  697. // bounds: model.create('dc:Bounds', { x: 100.0, y: 200.0, width: 100.0, height: 50.0 })
  698. // })
  699. // definitions.get('rootElements')[0].flowElements.push(bpmnProcess);
  700. // definitions.diagrams[0].plane.planeElement.push(bpmdi)
  701. // model.toXML(definitions, (err, xmlStrUpdated) => {
  702. // // console.log(xmlStrUpdated)
  703. // this.bpmn.importXML(xmlStrUpdated)
  704. // });
  705. // })
  706. }
  707. );
  708. }
  709. });
  710. // 给图绑定事件,当图有发生改变就会触发这个事件
  711. // this.bpmn.on('commandStack.changed', (e) => {
  712. // console.log(e)
  713. // // this.bpmn.on('canvas.viewbox.changed', () => {
  714. // // this.bpmn.saveXML({format: true}, (err, xml) => {
  715. // // console.log(xml)
  716. // // })
  717. // // })
  718. // })
  719. // this.bpmn.injector._instances.eventBus所有事件// 监听 element
  720. // console.log(this.bpmn.injector._instances.eventBus._listeners)
  721. // 删除元素
  722. this.bpmn.on('commandStack.elements.delete.postExecuted', (e) => {
  723. this.getXML().then(({ definitions, context }) => {
  724. definitions.$model.toXML(definitions, { format: true }, (err, xml) => {
  725. this.bpmn.importXML(xml);
  726. });
  727. });
  728. });
  729. // 自动给添加的节点赋名
  730. // this.bpmn.on('element.changed', e => {
  731. // this.getXML().then(({definitions, context}) => {
  732. // let el = context.elementsById[e.element.id];
  733. // if(!el || el.name) return
  734. // let type = el.$type,
  735. // set = new Set(['bpmn:UserTask', 'bpmn:ServiceTask', 'bpmn:EndEvent', 'bpmn:StartEvent', 'bpmn:ExclusiveGateway'])//ExclusiveGateway:网关
  736. // if(!set.has(type)) return
  737. // if(type === 'bpmn:UserTask') {
  738. // el.name = '用户节点' + el.id.replace('UserTask_', '')
  739. // }
  740. // if(type === 'bpmn:ServiceTask') {
  741. // el.name = '服务节点' + el.id.replace('ServiceTask_', '')
  742. // }
  743. // if(type === 'bpmn:EndEvent') {
  744. // el.name = '结束'
  745. // }
  746. // if(type === 'bpmn:StartEvent') {
  747. // el.name = '开始'
  748. // }
  749. // if(type === 'bpmn:ExclusiveGateway') {
  750. // el.name = '网关' + el.id.replace('ExclusiveGateway_', '')
  751. // }
  752. // definitions.$model.toXML(definitions, {format: true}, (err,xml) => {
  753. // this.bpmn.importXML(xml)
  754. // })
  755. // })
  756. // })
  757. this.model = new BpmnModdle();
  758. // 控制用户选择模块、网关条件显示
  759. this.bpmn.on('element.click', (e) => {
  760. this.nodeId = e.element.id;
  761. this.showConditionSelect = false;
  762. this.showUserSelect = false;
  763. this.showFormSelect = false;
  764. this.showSerivceSelect = false;
  765. this.showAssign = false;
  766. this.showSequence = false;
  767. this.prevUserTaskObj = {};
  768. this.isReject = false;
  769. this.rejectUserValue = '';
  770. this.sequenceFormKey = null;
  771. this.sequenceValue = null;
  772. this.getXML().then(({ definitions, context }) => {
  773. this.getIdOrder(definitions.rootElements[0].flowElements);
  774. let el = context.elementsById[this.nodeId];
  775. if (!el) return;
  776. // 用户设置显示控制
  777. if ('bpmn:UserTask' == el.$type) {
  778. // 获取节点的驳回处理人
  779. let root = definitions.rootElements[0],
  780. obj = {},
  781. documentation = root.get('documentation');
  782. if (documentation.length) {
  783. obj = documentation[0].text ? JSON.parse(documentation[0].text) : {};
  784. this.rejectUserValue = obj[this.nodeId];
  785. }
  786. this.showUserSelect = true;
  787. this.showFormSelect = true;
  788. let arrts = el.$attrs;
  789. this.userValues = el.documentation[0].text;
  790. this.formValues = arrts['activiti:formKey'];
  791. // 驳回表单
  792. this.userFormKey = this.formValues;
  793. this.assignValues = '';
  794. new Promise((resolve) => {
  795. this.getFormDetail(this.formValues, resolve);
  796. }).then((_) => {
  797. // 获取指派信息
  798. // let values = definitions.rootElements[0].extensionElements.values,
  799. // i = values.length;
  800. // while(i--) {
  801. // if('sc:transfer' == values[i].$type && this.nodeId == values[i].taskRef) {
  802. // this.assignValues = values[i].usersRange
  803. // }
  804. // }
  805. });
  806. // 获取所有上游用户节点对象
  807. this.getPrevUserTaskObj(el.id, context);
  808. } else {
  809. this.showUserSelect = false;
  810. this.showFormSelect = false;
  811. this.userValues = '';
  812. this.formValues = '';
  813. this.prevUserTaskObj = {};
  814. }
  815. // 服务设置显示控制
  816. if ('bpmn:ServiceTask' == el.$type) {
  817. console.log('ServiceTask', el);
  818. this.showSerivceSelect = true;
  819. let arrts = el.$attrs;
  820. this.serviceValues = JSON.parse(el.documentation[0].text);
  821. // this.serviceValues = arrts['activiti:expression']
  822. // 获取所有上游用户节点对象
  823. this.getPrevUserTaskObj(el.id, context);
  824. } else {
  825. this.showSerivceSelect = false;
  826. this.serviceValues = '';
  827. }
  828. // 连接线显示控制
  829. if ('bpmn:SequenceFlow' == el.$type) {
  830. // 网关条件设置显示控制
  831. if (el.sourceRef && 'bpmn:ExclusiveGateway' == el.sourceRef.$type) {
  832. this.showConditionSelect = true;
  833. this.conditionValues = el.conditionExpression && el.conditionExpression.body;
  834. // 获取当前网关条件上游最近一个用户节点
  835. let id = this.getPrevNode(context, el);
  836. // 获取节点的表单key集合
  837. let formArr = [],
  838. node,
  839. i = id.length;
  840. while (i--) {
  841. node = context.elementsById[id[i]];
  842. if (node.$attrs) {
  843. formArr.push(node.$attrs['activiti:formKey']);
  844. }
  845. }
  846. this.prevFormId = formArr;
  847. // 获取网关节点的上游连接线的actionValue
  848. let incoming = el.sourceRef.incoming,
  849. actionValueArr = [],
  850. temp;
  851. i = incoming.length;
  852. while (i--) {
  853. temp = incoming[i].conditionExpression;
  854. if (temp && temp.body) {
  855. actionValueArr.push(temp.body.substr(20, 4));
  856. }
  857. }
  858. } else {
  859. debugger;
  860. this.showConditionSelect = false;
  861. this.conditionValues = '';
  862. let sourceRef = el.sourceRef, // 起始节点
  863. targetRef = el.targetRef; // 目标节点
  864. this.showSequence = true;
  865. // 获取起始节点的formKey
  866. this.sequenceFormKey = sourceRef.$attrs['activiti:formKey'];
  867. this.sequenceValue = el.conditionExpression && el.conditionExpression.body;
  868. }
  869. } else {
  870. this.showSequence = false;
  871. this.sequenceFormKey = null;
  872. this.sequenceValue = null;
  873. }
  874. });
  875. });
  876. },
  877. created() {
  878. this.getForm();
  879. }
  880. };
  881. </script>
  882. <style lang='scss'>
  883. .bpmn {
  884. width: 100%;
  885. height: 100%;
  886. display: flex;
  887. justify-content: space-between;
  888. .bpmn-title {
  889. line-height: 30px;
  890. // padding: 0 20px;
  891. border-bottom: 1px solid #d8d8d8;
  892. }
  893. .bpmn-left {
  894. width: 80%;
  895. height: 100%;
  896. }
  897. .bpmn-right {
  898. width: 20%;
  899. .bpmn-node {
  900. padding: 20px;
  901. border: 1px solid #d8d8d8;
  902. margin: 5px 0;
  903. }
  904. }
  905. .djs-palette.two-column.open {
  906. width: auto;
  907. .entry {
  908. float: inherit;
  909. }
  910. }
  911. .djs-context-pad .entry {
  912. .bpmn-icon-end-event-none {
  913. display: none;
  914. width: 0;
  915. height: 0;
  916. }
  917. }
  918. .bjs-powered-by,
  919. .group[data-group='tools'],
  920. .group[data-group='gateway'],
  921. .group[data-group='activity'],
  922. .group[data-group='data-object'],
  923. .group[data-group='data-store'],
  924. .group[data-group='collaboration'],
  925. .bpmn-icon-intermediate-event-none,
  926. .bpmn-icon-subprocess-expanded,
  927. .bpmn-icon-gateway-xor,
  928. .djs-context-pad .group[data-group='model'],
  929. .djs-context-pad .bpmn-icon-screw-wrench {
  930. display: none;
  931. width: 0;
  932. height: 0;
  933. }
  934. }
  935. </style>