index.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. "use strict";
  2. var __read = (this && this.__read) || function (o, n) {
  3. var m = typeof Symbol === "function" && o[Symbol.iterator];
  4. if (!m) return o;
  5. var i = m.call(o), r, ar = [], e;
  6. try {
  7. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  8. }
  9. catch (error) { e = { error: error }; }
  10. finally {
  11. try {
  12. if (r && !r.done && (m = i["return"])) m.call(i);
  13. }
  14. finally { if (e) throw e.error; }
  15. }
  16. return ar;
  17. };
  18. Object.defineProperty(exports, "__esModule", { value: true });
  19. exports.BpmnXmlAdapter = exports.BpmnAdapter = void 0;
  20. var bpmnIds_1 = require("./bpmnIds");
  21. var json2xml_1 = require("./json2xml");
  22. var xml2json_1 = require("./xml2json");
  23. var constant_1 = require("../bpmn/constant");
  24. var BpmnElements;
  25. (function (BpmnElements) {
  26. BpmnElements["START"] = "bpmn:startEvent";
  27. BpmnElements["END"] = "bpmn:endEvent";
  28. BpmnElements["GATEWAY"] = "bpmn:exclusiveGateway";
  29. BpmnElements["USER"] = "bpmn:userTask";
  30. BpmnElements["SYSTEM"] = "bpmn:serviceTask";
  31. BpmnElements["FLOW"] = "bpmn:sequenceFlow";
  32. })(BpmnElements || (BpmnElements = {}));
  33. var defaultAttrs = ['-name', '-id', 'bpmn:incoming', 'bpmn:outgoing', '-sourceRef', '-targetRef'];
  34. /**
  35. * 将普通json转换为xmlJson
  36. * xmlJson中property会以“-”开头
  37. * 如果没有“-”表示为子节点
  38. */
  39. function toXmlJson(json) {
  40. var xmlJson = {};
  41. Object.entries(json).forEach(function (_a) {
  42. var _b = __read(_a, 2), key = _b[0], value = _b[1];
  43. if (typeof value !== 'object') {
  44. if (key.indexOf('-') === 0) { // 如果本来就是“-”开头的了,那就不处理了。
  45. xmlJson[key] = value;
  46. }
  47. else {
  48. xmlJson["-" + key] = value;
  49. }
  50. }
  51. else {
  52. xmlJson[key] = toXmlJson(value);
  53. }
  54. });
  55. return xmlJson;
  56. }
  57. /**
  58. * 将xmlJson转换为普通的json,在内部使用。
  59. */
  60. function toNormalJson(xmlJson) {
  61. var json = {};
  62. Object.entries(xmlJson).forEach(function (_a) {
  63. var _b = __read(_a, 2), key = _b[0], value = _b[1];
  64. if (typeof value === 'string') {
  65. if (key.indexOf('-') === 0) { // 如果本来就是“-”开头的了,那就不处理了。
  66. json[key.substr(1)] = value;
  67. }
  68. else {
  69. json[key] = value;
  70. }
  71. }
  72. else if (typeof value === 'object') {
  73. json[key] = toNormalJson(value);
  74. }
  75. else {
  76. json[key] = value;
  77. }
  78. });
  79. return json;
  80. }
  81. /**
  82. * 设置bpmn process信息
  83. * 目标格式请参考examples/bpmn.json
  84. * bpmn因为是默认基于xml格式的,其特点与json存在差异。
  85. * 1) 如果是xml的属性,json中属性用'-'开头
  86. * 2)如果只有一个子元素,json中表示为正常属性
  87. * 3)如果是多个子元素,json中使用数组存储
  88. */
  89. function convertLf2ProcessData(bpmnProcessData, data) {
  90. var nodeMap = new Map();
  91. data.nodes.forEach(function (node) {
  92. var _a;
  93. var processNode = {
  94. '-id': node.id,
  95. };
  96. if ((_a = node.text) === null || _a === void 0 ? void 0 : _a.value) {
  97. processNode['-name'] = node.text.value;
  98. }
  99. if (node.properties) {
  100. var properties = toXmlJson(node.properties);
  101. Object.assign(processNode, properties);
  102. }
  103. nodeMap.set(node.id, processNode);
  104. if (!bpmnProcessData[node.type]) {
  105. bpmnProcessData[node.type] = processNode; // 如果只有一个子元素,json中表示为正常属性
  106. }
  107. else if (Array.isArray(bpmnProcessData[node.type])) { // 如果是多个子元素,json中使用数组存储
  108. bpmnProcessData[node.type].push(processNode);
  109. }
  110. else { // 如果是多个子元素,json中使用数组存储
  111. bpmnProcessData[node.type] = [
  112. bpmnProcessData[node.type],
  113. processNode,
  114. ];
  115. }
  116. });
  117. var sequenceFlow = data.edges.map(function (edge) {
  118. var _a, _b;
  119. var targetNode = nodeMap.get(edge.targetNodeId);
  120. // @see https://github.com/didi/LogicFlow/issues/325
  121. // 需要保证incomming在outgoing之前
  122. if (!targetNode['bpmn:incoming']) {
  123. targetNode['bpmn:incoming'] = edge.id;
  124. }
  125. else if (Array.isArray(targetNode['bpmn:incoming'])) {
  126. targetNode['bpmn:incoming'].push(edge.id);
  127. }
  128. else {
  129. targetNode['bpmn:incoming'] = [
  130. targetNode['bpmn:incoming'],
  131. edge.id,
  132. ];
  133. }
  134. var sourceNode = nodeMap.get(edge.sourceNodeId);
  135. if (!sourceNode['bpmn:outgoing']) {
  136. sourceNode['bpmn:outgoing'] = edge.id;
  137. }
  138. else if (Array.isArray(sourceNode['bpmn:outgoing'])) {
  139. sourceNode['bpmn:outgoing'].push(edge.id);
  140. }
  141. else { // 字符串转数组
  142. sourceNode['bpmn:outgoing'] = [
  143. sourceNode['bpmn:outgoing'],
  144. edge.id,
  145. ];
  146. }
  147. var edgeConfig = {
  148. '-id': edge.id,
  149. '-sourceRef': edge.sourceNodeId,
  150. '-targetRef': edge.targetNodeId,
  151. };
  152. if ((_a = edge.text) === null || _a === void 0 ? void 0 : _a.value) {
  153. edgeConfig['-name'] = (_b = edge.text) === null || _b === void 0 ? void 0 : _b.value;
  154. }
  155. if (edge.properties) {
  156. var properties = toXmlJson(edge.properties);
  157. Object.assign(edgeConfig, properties);
  158. }
  159. return edgeConfig;
  160. });
  161. bpmnProcessData[BpmnElements.FLOW] = sequenceFlow;
  162. }
  163. /**
  164. * adapterOut 设置bpmn diagram信息
  165. */
  166. function convertLf2DiagramData(bpmnDiagramData, data) {
  167. bpmnDiagramData['bpmndi:BPMNEdge'] = data.edges.map(function (edge) {
  168. var _a;
  169. var edgeId = edge.id;
  170. var pointsList = edge.pointsList.map(function (_a) {
  171. var x = _a.x, y = _a.y;
  172. return ({ '-x': x, '-y': y });
  173. });
  174. var diagramData = {
  175. '-id': edgeId + "_di",
  176. '-bpmnElement': edgeId,
  177. 'di:waypoint': pointsList,
  178. };
  179. if ((_a = edge.text) === null || _a === void 0 ? void 0 : _a.value) {
  180. diagramData['bpmndi:BPMNLabel'] = {
  181. 'dc:Bounds': {
  182. '-x': edge.text.x - (edge.text.value.length * 10) / 2,
  183. '-y': edge.text.y - 7,
  184. '-width': edge.text.value.length * 10,
  185. '-height': 14,
  186. },
  187. };
  188. }
  189. return diagramData;
  190. });
  191. bpmnDiagramData['bpmndi:BPMNShape'] = data.nodes.map(function (node) {
  192. var _a;
  193. var nodeId = node.id;
  194. var width = 100;
  195. var height = 80;
  196. var x = node.x, y = node.y;
  197. // bpmn坐标是基于左上角,LogicFlow基于中心点,此处处理一下。
  198. var shapeConfig = BpmnAdapter.shapeConfigMap.get(node.type);
  199. if (shapeConfig) {
  200. width = shapeConfig.width;
  201. height = shapeConfig.height;
  202. }
  203. x -= width / 2;
  204. y -= height / 2;
  205. var diagramData = {
  206. '-id': nodeId + "_di",
  207. '-bpmnElement': nodeId,
  208. 'dc:Bounds': {
  209. '-x': x,
  210. '-y': y,
  211. '-width': width,
  212. '-height': height,
  213. },
  214. };
  215. if ((_a = node.text) === null || _a === void 0 ? void 0 : _a.value) {
  216. diagramData['bpmndi:BPMNLabel'] = {
  217. 'dc:Bounds': {
  218. '-x': node.text.x - (node.text.value.length * 10) / 2,
  219. '-y': node.text.y - 7,
  220. '-width': node.text.value.length * 10,
  221. '-height': 14,
  222. },
  223. };
  224. }
  225. return diagramData;
  226. });
  227. }
  228. /**
  229. * 将bpmn数据转换为LogicFlow内部能识别数据
  230. */
  231. function convertBpmn2LfData(bpmnData) {
  232. var nodes = [];
  233. var edges = [];
  234. var definitions = bpmnData['bpmn:definitions'];
  235. if (definitions) {
  236. var process_1 = definitions['bpmn:process'];
  237. Object.keys(process_1).forEach(function (key) {
  238. if (key.indexOf('bpmn:') === 0) {
  239. var value = process_1[key];
  240. if (key === BpmnElements.FLOW) {
  241. var bpmnEdges = definitions['bpmndi:BPMNDiagram']['bpmndi:BPMNPlane']['bpmndi:BPMNEdge'];
  242. edges = getLfEdges(value, bpmnEdges);
  243. }
  244. else {
  245. var shapes = definitions['bpmndi:BPMNDiagram']['bpmndi:BPMNPlane']['bpmndi:BPMNShape'];
  246. nodes = nodes.concat(getLfNodes(value, shapes, key));
  247. }
  248. }
  249. });
  250. }
  251. return {
  252. nodes: nodes,
  253. edges: edges,
  254. };
  255. }
  256. function getLfNodes(value, shapes, key) {
  257. var nodes = [];
  258. if (Array.isArray(value)) { // 数组
  259. value.forEach(function (val) {
  260. var shapeValue;
  261. if (Array.isArray(shapes)) {
  262. shapeValue = shapes.find(function (shape) { return shape['-bpmnElement'] === val['-id']; });
  263. }
  264. else {
  265. shapeValue = shapes;
  266. }
  267. var node = getNodeConfig(shapeValue, key, val);
  268. nodes.push(node);
  269. });
  270. }
  271. else {
  272. var shapeValue = void 0;
  273. if (Array.isArray(shapes)) {
  274. shapeValue = shapes.find(function (shape) { return shape['-bpmnElement'] === value['-id']; });
  275. }
  276. else {
  277. shapeValue = shapes;
  278. }
  279. var node = getNodeConfig(shapeValue, key, value);
  280. nodes.push(node);
  281. }
  282. return nodes;
  283. }
  284. function getNodeConfig(shapeValue, type, processValue) {
  285. var x = Number(shapeValue['dc:Bounds']['-x']);
  286. var y = Number(shapeValue['dc:Bounds']['-y']);
  287. var name = processValue['-name'];
  288. var shapeConfig = BpmnAdapter.shapeConfigMap.get(type);
  289. if (shapeConfig) {
  290. x += shapeConfig.width / 2;
  291. y += shapeConfig.height / 2;
  292. }
  293. var properties;
  294. // 判断是否存在额外的属性,将额外的属性放到properties中
  295. Object.entries(processValue).forEach(function (_a) {
  296. var _b = __read(_a, 2), key = _b[0], value = _b[1];
  297. if (defaultAttrs.indexOf(key) === -1) {
  298. if (!properties)
  299. properties = {};
  300. properties[key] = value;
  301. }
  302. });
  303. if (properties) {
  304. properties = toNormalJson(properties);
  305. }
  306. var text;
  307. if (name) {
  308. text = {
  309. x: x,
  310. y: y,
  311. value: name,
  312. };
  313. // 自定义文本位置
  314. if (shapeValue['bpmndi:BPMNLabel'] && shapeValue['bpmndi:BPMNLabel']['dc:Bounds']) {
  315. var textBounds = shapeValue['bpmndi:BPMNLabel']['dc:Bounds'];
  316. text.x = Number(textBounds['-x']) + Number(textBounds['-width']) / 2;
  317. text.y = Number(textBounds['-y']) + Number(textBounds['-height']) / 2;
  318. }
  319. }
  320. var nodeConfig = {
  321. id: shapeValue['-bpmnElement'],
  322. type: type,
  323. x: x,
  324. y: y,
  325. properties: properties,
  326. };
  327. if (text) {
  328. nodeConfig.text = text;
  329. }
  330. return nodeConfig;
  331. }
  332. function getLfEdges(value, bpmnEdges) {
  333. var edges = [];
  334. if (Array.isArray(value)) {
  335. value.forEach(function (val) {
  336. var edgeValue;
  337. if (Array.isArray(bpmnEdges)) {
  338. edgeValue = bpmnEdges.find(function (edge) { return edge['-bpmnElement'] === val['-id']; });
  339. }
  340. else {
  341. edgeValue = bpmnEdges;
  342. }
  343. edges.push(getEdgeConfig(edgeValue, val));
  344. });
  345. }
  346. else {
  347. var edgeValue = void 0;
  348. if (Array.isArray(bpmnEdges)) {
  349. edgeValue = bpmnEdges.find(function (edge) { return edge['-bpmnElement'] === value['-id']; });
  350. }
  351. else {
  352. edgeValue = bpmnEdges;
  353. }
  354. edges.push(getEdgeConfig(edgeValue, value));
  355. }
  356. return edges;
  357. }
  358. function getEdgeConfig(edgeValue, processValue) {
  359. var text;
  360. var textVal = processValue['-name'];
  361. if (textVal) {
  362. var textBounds = edgeValue['bpmndi:BPMNLabel']['dc:Bounds'];
  363. // 如果边文本换行,则其偏移量应该是最长一行的位置
  364. var textLength_1 = 0;
  365. textVal.split('\n').forEach(function (textSpan) {
  366. if (textLength_1 < textSpan.length) {
  367. textLength_1 = textSpan.length;
  368. }
  369. });
  370. text = {
  371. value: textVal,
  372. x: Number(textBounds['-x']) + (textLength_1 * 10) / 2,
  373. y: Number(textBounds['-y']) + 7,
  374. };
  375. }
  376. var properties;
  377. // 判断是否存在额外的属性,将额外的属性放到properties中
  378. Object.entries(processValue).forEach(function (_a) {
  379. var _b = __read(_a, 2), key = _b[0], value = _b[1];
  380. if (defaultAttrs.indexOf(key) === -1) {
  381. if (!properties)
  382. properties = {};
  383. properties[key] = value;
  384. }
  385. });
  386. if (properties) {
  387. properties = toNormalJson(properties);
  388. }
  389. var edge = {
  390. id: processValue['-id'],
  391. type: BpmnElements.FLOW,
  392. pointsList: edgeValue['di:waypoint'].map(function (point) { return ({
  393. x: Number(point['-x']),
  394. y: Number(point['-y']),
  395. }); }),
  396. sourceNodeId: processValue['-sourceRef'],
  397. targetNodeId: processValue['-targetRef'],
  398. properties: properties,
  399. };
  400. if (text) {
  401. edge.text = text;
  402. }
  403. return edge;
  404. }
  405. var BpmnAdapter = {
  406. pluginName: 'bpmn-adapter',
  407. install: function (lf) {
  408. lf.adapterIn = this.adapterIn;
  409. lf.adapterOut = this.adapterOut;
  410. },
  411. shapeConfigMap: new Map(),
  412. setCustomShape: function (key, val) {
  413. this.shapeConfigMap.set(key, val);
  414. },
  415. adapterOut: function (data) {
  416. var bpmnProcessData = {
  417. '-id': "Process_" + bpmnIds_1.getBpmnId(),
  418. '-isExecutable': 'false',
  419. };
  420. convertLf2ProcessData(bpmnProcessData, data);
  421. var bpmnDiagramData = {
  422. '-id': 'BPMNPlane_1',
  423. '-bpmnElement': bpmnProcessData['-id'],
  424. };
  425. convertLf2DiagramData(bpmnDiagramData, data);
  426. var bpmnData = {
  427. 'bpmn:definitions': {
  428. '-id': "Definitions_" + bpmnIds_1.getBpmnId(),
  429. '-xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
  430. '-xmlns:bpmn': 'http://www.omg.org/spec/BPMN/20100524/MODEL',
  431. '-xmlns:bpmndi': 'http://www.omg.org/spec/BPMN/20100524/DI',
  432. '-xmlns:dc': 'http://www.omg.org/spec/DD/20100524/DC',
  433. '-xmlns:di': 'http://www.omg.org/spec/DD/20100524/DI',
  434. '-targetNamespace': 'http://bpmn.io/schema/bpmn',
  435. '-exporter': 'bpmn-js (https://demo.bpmn.io)',
  436. '-exporterVersion': '7.3.0',
  437. 'bpmn:process': bpmnProcessData,
  438. 'bpmndi:BPMNDiagram': {
  439. '-id': 'BPMNDiagram_1',
  440. 'bpmndi:BPMNPlane': bpmnDiagramData,
  441. },
  442. },
  443. };
  444. return bpmnData;
  445. },
  446. adapterIn: function (bpmnData) {
  447. if (bpmnData) {
  448. return convertBpmn2LfData(bpmnData);
  449. }
  450. },
  451. };
  452. exports.BpmnAdapter = BpmnAdapter;
  453. BpmnAdapter.shapeConfigMap.set(BpmnElements.START, {
  454. width: constant_1.StartEventConfig.width,
  455. height: constant_1.StartEventConfig.height,
  456. });
  457. BpmnAdapter.shapeConfigMap.set(BpmnElements.END, {
  458. width: constant_1.EndEventConfig.width,
  459. height: constant_1.EndEventConfig.height,
  460. });
  461. BpmnAdapter.shapeConfigMap.set(BpmnElements.GATEWAY, {
  462. width: constant_1.ExclusiveGatewayConfig.width,
  463. height: constant_1.ExclusiveGatewayConfig.height,
  464. });
  465. BpmnAdapter.shapeConfigMap.set(BpmnElements.SYSTEM, {
  466. width: constant_1.ServiceTaskConfig.width,
  467. height: constant_1.ServiceTaskConfig.height,
  468. });
  469. BpmnAdapter.shapeConfigMap.set(BpmnElements.USER, {
  470. width: constant_1.UserTaskConfig.width,
  471. height: constant_1.UserTaskConfig.height,
  472. });
  473. var BpmnXmlAdapter = {
  474. pluginName: 'bpmnXmlAdapter',
  475. install: function (lf) {
  476. lf.adapterIn = this.adapterXmlIn;
  477. lf.adapterOut = this.adapterXmlOut;
  478. },
  479. adapterXmlIn: function (bpmnData) {
  480. var json = xml2json_1.lfXml2Json(bpmnData);
  481. return BpmnAdapter.adapterIn(json);
  482. },
  483. adapterXmlOut: function (data) {
  484. var outData = BpmnAdapter.adapterOut(data);
  485. return json2xml_1.lfJson2Xml(outData);
  486. },
  487. };
  488. exports.BpmnXmlAdapter = BpmnXmlAdapter;
  489. exports.default = BpmnAdapter;