workflowsetting.vue 40 KB

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