| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619 |
- import { changeTypeByTaskShape, changeTypeByTrigger, hasGatewayType, typeConfig } from '../../../config';
- import { jnpfConfigBpmnContextPad } from '../../../config/contextPad';
- import {
- bpmnEnd,
- bpmnTask,
- typeTask,
- typeSubFlow,
- typeLabel,
- bpmnInclusive,
- typeConfluence,
- bpmnStart,
- typeTrigger,
- bpmnTrigger,
- typeExecute,
- bpmnLabel,
- typeStart,
- typeCopy,
- bpmnCopy,
- bpmnPaste,
- typePaste,
- bpmnChoose,
- typeProcessing,
- typeOutside,
- typeEnd,
- typeChoose,
- typeCondition,
- } from '../../../config/variableName';
- import { BPMNTreeBuilder } from '../../../utils/constructTreeUtil';
- import { DEFAULT_DISTANCE } from '../../../config/constants';
- import { buildBitUUID } from '../../../utils/uuidUtil';
- import { NodeUtils } from '../../../utils/nodeUtil';
- import bpmnType from '../../../palette/bpmnType';
- const CustomizeContextPad = (contextPadProvider: any, element: any) => {
- let type = element.type;
- let isAction = true;
- if (typeConfig[type]) {
- const {
- _autoPlace: autoPlace,
- _create: create,
- _elementFactory: elementFactory,
- _modeling: modeling,
- _connect: connects,
- _injector: injector,
- _rules: rules,
- _eventBus: eventBus,
- } = contextPadProvider;
- let wnType = element.wnType;
- if (wnType === bpmnTrigger) type = bpmnTrigger;
- if (changeTypeByTaskShape[wnType]) type = changeTypeByTaskShape[wnType];
- const { contextPad, shapeType } = typeConfig[type];
- const { del, copy, paste } = jnpfConfigBpmnContextPad;
- let customization = contextPad?.customization;
- if (type === bpmnLabel) {
- let connect = element?.labelTarget;
- let target = connect.target;
- // 执行节点的线label使用groupCustomization
- if (changeTypeByTaskShape[target.wnType]) {
- customization = contextPad?.groupCustomization;
- }
- }
- if (type === shapeType) {
- if (contextPad) {
- let jnpfData = injector.get('jnpfData');
- let copyElement = jnpfData.getValue('copyType');
- if (element.wnType === typeTrigger && changeTypeByTaskShape[copyElement.type]) customization = contextPad?.otherCustomization;
- if (changeTypeByTaskShape[element.wnType] && changeTypeByTaskShape[copyElement.type]) customization = contextPad?.otherCustomization;
- if (contextPad.default) return defaultContextPad;
- else if (customization) {
- let result: any = {};
- for (let key of Object.keys(customization)) {
- let data = customization[key];
- if (data.group === 'model') {
- let options: any = {
- wnName: typeConfig[key]?.renderer.rendererName,
- };
- if (element.type === bpmnStart && hasGatewayType.has(key)) {
- // 开始节点只有分类节点 因为网关的分流节点和合流节点类型一致 多增加一个字段来表示
- options = {
- wnName: typeConfig[key]?.renderer.rendererName,
- wnGatewayType: key,
- wnType: key,
- icon: data.icon,
- };
- }
- result[data.name] = appendAction(data.type, data.elementName, data.className, data.title, data.wnType, options);
- } else if (data.group === 'connect') {
- result[data.name] = {
- group: data.group,
- className: data.className,
- title: data.title,
- action: {
- click: isAction && startConnect,
- },
- };
- } else if (data.group === 'edit') {
- result[data.name] = {
- group: data.group,
- className: data.className,
- title: data.title,
- action: {
- click: removeElement,
- },
- };
- }
- }
- return Object.assign(result);
- } else return defaultContextPad();
- }
- // 单个节点删除功能
- function removeElement() {
- rules.allowed('elements.delete', { elements: [element] });
- }
- // 开始连线(拖拽)
- function startConnect(event: any, element: any) {
- connects.start(event, element);
- }
- // 添加事件
- function appendAction(type: any, name: any, className: any, title: any, wnType: any, options?: any) {
- const appendStart = (event: any, element: any) => {
- let bpmnFactory = elementFactory._bpmnFactory;
- if ([typeSubFlow, typeProcessing, typeOutside].includes(type)) type = bpmnTask;
- let businessObject = bpmnFactory.create(type);
- let shape = elementFactory.createShape(Object.assign({ type, name, wnType, ...options }, businessObject));
- create.start(event, shape, { source: element });
- };
- const autoPlaceAppend = async (_event: any, element: any) => {
- let isPaste = false;
- if (wnType === typeCopy) {
- copyElement(element.wnType);
- return;
- }
- if (wnType === typePaste) {
- let jnpfData = injector.get('jnpfData');
- let data = jnpfData.getValue(bpmnCopy);
- let copyElement = jnpfData.getValue('copyType');
- isPaste = true;
- if ([typeOutside, typeTrigger, 'default'].includes(copyElement.type)) {
- type = data.type;
- wnType = data.wnType;
- className = data.className;
- title = data.title;
- options = data.options;
- if (element.outgoing.length > 1) {
- let connect = element.outgoing.find(connect => connect.target.wnType != typeTrigger);
- element = connect.label;
- } else {
- element = element.outgoing[0]?.label;
- }
- }
- if (copyElement.type === typeTrigger || changeTypeByTaskShape[copyElement.type]) {
- type = data.type;
- wnType = data.wnType;
- className = data.className;
- title = data.title;
- options = data.options;
- name = data.name;
- }
- }
- let hasTaskType = new Set([typeSubFlow, typeProcessing, typeTrigger, typeOutside]);
- if (hasTaskType.has(type) || changeTypeByTaskShape[wnType]) type = bpmnTask;
- let bpmnFactory = elementFactory._bpmnFactory;
- let isChoose = false;
- if (type === bpmnChoose) {
- type = bpmnInclusive;
- isChoose = true;
- }
- let businessObject = type === bpmnType ? bpmnFactory.create(element.type) : bpmnFactory.create(type);
- let shape = elementFactory.createShape(Object.assign({ type, name: name, businessObject, wnType: wnType }, options));
- if (element.type === typeLabel) {
- let businessTaskObject = bpmnFactory.create(bpmnTask);
- let businessTask2Object = bpmnFactory.create(bpmnTask);
- let businessInclusiveObject = bpmnFactory.create(bpmnInclusive);
- let shape: any;
- if (hasGatewayType.has(wnType)) {
- let id = `Gateway_${buildBitUUID()}_isSimple`;
- businessObject.id = id;
- shape = elementFactory.createShape(Object.assign({ type, id: id, name: name, businessObject, wnType: wnType }, options));
- } else {
- shape = elementFactory.createShape(Object.assign({ type, name: name, businessObject, wnType: wnType }, options));
- }
- updateShapePosition(shape, element, businessTaskObject, businessInclusiveObject, businessTask2Object);
- if (isChoose) {
- modeling.updateProperties(shape, {
- type: bpmnChoose,
- });
- }
- } else {
- autoPlace.append(element, shape);
- // 自研
- if (hasGatewayType.has(element.wnType)) {
- // 获取对应的合流网关
- const gateway = injector.get('elementRegistry').get(element.id + '_confluence');
- modeling.connect(shape, gateway);
- }
- // 处理执行节点的美化 (获取到最近的合流节点 判断分组与合流坐标距离计算是否需要进行偏移)
- if (changeTypeByTaskShape[shape.wnType]) {
- modeling.updateProperties(shape, {
- customGroupId: element.businessObject.$attrs.customGroupId,
- });
- let groupShape = injector.get('elementRegistry').get(element.businessObject.$attrs.customGroupId);
- let shapeRight = shape.x + shape.width;
- let shapeBottom = shape.y + shape.height;
- let groupRight = groupShape.x + groupShape.width;
- let groupBottom = groupShape.y + groupShape.height;
- var newBounds: any = {
- x: groupShape.x, // 保持 x 位置不变
- y: groupShape.y, // 保持 y 位置不变
- width: groupShape.width,
- height: groupShape.height,
- };
- if (shapeRight >= groupRight) newBounds.width = shapeRight + 25 - groupShape.x;
- if (shapeBottom >= groupBottom) newBounds.height = shapeBottom + 15 - groupShape.y;
- modeling.resizeShape(groupShape, newBounds);
- autoExecute(groupShape);
- }
- }
- // 计算需要横向偏移的元素(只有出现分流的情况下需要用到)
- if (element?.type === typeLabel || hasGatewayType.has(element.wnType) || element.wnType === typeTrigger || changeTypeByTaskShape[element.wnType])
- onAutoPosition();
- // 粘贴节点属性(需modeling.create后才能使用modeling.updatePropertie()生效)
- if (isPaste) {
- let jnpfData = injector.get('jnpfData');
- let copyElement = jnpfData.getValue('copyType');
- let newData = copyElement.data;
- let newShape = injector.get('elementRegistry').get(shape.id);
- let customGroupId = "";
- if (changeTypeByTrigger[newShape.wnType] || newShape.wnType === typeTrigger) customGroupId = newShape?.businessObject?.$attrs?.customGroupId
- else if (changeTypeByTaskShape[newShape.wnType]) customGroupId = element?.businessObject?.$attrs?.customGroupId
- jnpfData.setValue(shape.id, { ...newData, nodeId: shape.id, groupId: customGroupId });
- if (newShape) {
- newShape['elementBodyName'] = newData?.content || '';
- newShape['nodeName'] = newData?.nodeName || '';
- modeling.updateProperties(newShape, {
- customGroupId: customGroupId,
- });
- }
- }
- };
- var append = autoPlace ? autoPlaceAppend : appendStart;
- let disable = isAction;
- let lastsource = element?.labelTarget?.source;
- let nextTarget = element?.labelTarget?.target;
- let targetType = nextTarget?.wnType
- let sourceType = lastsource?.wnType
- if ([typeConfluence].includes(sourceType) && (hasGatewayType.has(wnType) || wnType === typeTrigger)) disable = false;
- if (sourceType === typeSubFlow && ([typeChoose].includes(wnType))) disable = false;
- if (sourceType === typeOutside && ([typeChoose, typeTrigger, typeOutside, typeSubFlow].includes(wnType))) disable = false;
- if (hasGatewayType.has(nextTarget?.wnType) && hasGatewayType.has(wnType)) disable = false;
- if (nextTarget?.wnType === typeTrigger && ([typeSubFlow, typeSubFlow, typeExecute, typeTask].includes(wnType) || hasGatewayType.has(wnType)))
- if (changeTypeByTaskShape[nextTarget?.wnType] && hasGatewayType.has(wnType)) disable = false;
- if ([typeStart, typeSubFlow].includes(sourceType) && wnType === typeTrigger) disable = false;
- if (([typeOutside].includes(wnType) && [typeOutside, typeSubFlow, typeChoose, typeEnd].includes(targetType))) disable = false;
- if (([typeSubFlow].includes(wnType) && [typeChoose].includes(targetType))) disable = false;
- if (([typeOutside].includes(wnType) && hasGatewayType.has(targetType))) {
- if (nextTarget.outgoing.some(o => [typeOutside, typeSubFlow].includes(o.target.wnType))) disable = false;
- let jnpfData = injector.get('jnpfData');
- if (nextTarget.outgoing.some(o => jnpfData.getValue(o.id)?.conditions?.length > 0)) disable = false; // 线条如果有条件也无法添加外部节点
- }
- if ([typeOutside].includes(wnType)) {
- // 如果外部节点的下一个节点是合流节点,则继续检查合流节点的下一个节点是否为结束节点,如果是则不可添加外部节点
- while (nextTarget && targetType === typeConfluence) {
- let nextOutgoing = nextTarget.outgoing || [];
- // 合流网关后面如果是子流程,外部节点,结束节点,则禁用当前的外部节点
- if (nextOutgoing.some(out => out.target && [typeEnd, typeSubFlow, typeOutside].includes(out.target.wnType))) {
- disable = false;
- break;
- }
- // 如果有多个分支,取第一个不是合流节点的分支继续判断,否则继续循环
- let nextConfluence = nextOutgoing.find(out => out.target && out.target.wnType === typeConfluence);
- if (nextConfluence) nextTarget = nextConfluence.target;
- else break;
- }
- while (lastsource && sourceType === typeConfluence) {
- let lastIncoming = lastsource.incoming || [];
- // 合流网关后面如果是子流程,外部节点,结束节点,则禁用当前的外部节点
- if (lastIncoming.some(incoming => incoming.source && [typeOutside].includes(incoming.source.wnType))) {
- disable = false;
- break;
- }
- // 如果有多个分支,取第一个不是合流节点的分支继续判断,否则继续循环
- let lastConfluence = lastIncoming.find(incoming => incoming.source?.wnType === typeConfluence);
- if (lastConfluence) lastsource = lastConfluence.source;
- else break;
- }
- }
- return {
- group: 'model',
- className: className,
- title: title,
- disable: disable,
- action: { click: disable && append },
- };
- }
- // 默认contextPad
- function defaultContextPad() {
- let obj = Object.assign({
- [del.name]: {
- group: del.group,
- className: del.className,
- title: del.title,
- action: {
- click: removeElement,
- },
- },
- [copy.name]: {
- group: copy.group,
- className: copy.className,
- title: copy.title,
- action: {
- click: () => copyElement(wnType === typeOutside ? typeOutside : "default"),
- },
- },
- });
- let jnpfData = injector.get('jnpfData');
- let data = jnpfData.getValue('copyType');
- let copyNode = jnpfData.getValue('copy');
- let outgoing = element.outgoing?.filter(o => o.target.wnType != typeTrigger)
- if (data.type === typeOutside) {
- if ([typeTask, typeProcessing, typeSubFlow, typeStart].includes(wnType)) {
- if (![typeOutside, typeSubFlow].includes(outgoing[0]?.target?.wnType)) {
- obj[paste.name] = appendAction(bpmnPaste, typePaste, paste.className, paste.title, typePaste, { wnName: null });
- }
- }
- } else if (wnType === typeOutside) {
- if (([typeTask, typeProcessing, typeSubFlow, typeEnd].includes(outgoing[0]?.target?.wnType) && [typeTask, typeProcessing].includes(copyNode?.wnType)) || data.type === bpmnTrigger) {
- obj[paste.name] = appendAction(bpmnPaste, typePaste, paste.className, paste.title, typePaste, { wnName: null });
- }
- } else {
- if (data.type === 'default' || data.type === bpmnTrigger) {
- if (!(data.type === bpmnTrigger && wnType === typeSubFlow)) {
- if (!(outgoing[0]?.target?.wnType === typeOutside && [typeSubFlow].includes(copyNode.wnType)))
- obj[paste.name] = appendAction(bpmnPaste, typePaste, paste.className, paste.title, typePaste, { wnName: null });
- }
- }
- }
- return obj;
- }
- // 判断元素与网关之间的垂直距离是否小于某个阈值
- function isWithinThreshold(target, source, threshold, processedElements: any) {
- // 这里假设网关在上方,即网关的 y 坐标小于当前元素的 y 坐标
- let gatewayY = target.y;
- let sourceElementY = source.y;
- // let elementObj: any;
- let map = new Map(
- Array.from(processedElements, (item: any) => [item.id, item]), // 使用 id 作为键
- );
- // 如果当前元素是合流网关 获取分流到合流内所有元素 并且获取y最大值的元素与 当前分流坐标做对比
- if (target.wnType === typeConfluence) {
- let allElements = injector.get('elementRegistry').getAll();
- let treeBuilder = new BPMNTreeBuilder(allElements);
- let gatewayElement = injector.get('elementRegistry').get(target.id.replace('_confluence', ''));
- treeBuilder.onComputerMaxElementH(injector, target, gatewayElement, [], null, false, map, threshold);
- }
- if (map.has(source.id)) {
- sourceElementY = sourceElementY + threshold;
- }
- return gatewayY - sourceElementY > threshold && gatewayY > sourceElementY;
- }
- function moveConnectedElements(connection: any, height: any, useWithinThreshold: boolean = true) {
- const stack: any = []; // 用于存储待处理的连接线
- const processedElements = new Set(); // 记录已经处理过的目标元素
- stack.push(connection); // 从给定的连接线开始
- while (stack.length > 0) {
- const currentConnection: any = stack.pop();
- const target = currentConnection.target;
- if (!target) continue; // 如果没有目标元素,跳过
- if (processedElements.has(target)) continue; // 如果目标元素已经处理过,跳过
- if (useWithinThreshold && isWithinThreshold(target, currentConnection.source, height, processedElements)) continue;
- processedElements.add(target); // 标记该元素已经被处理
- // 遍历目标元素的所有出线连接,并将它们压入栈
- const outgoingConnections: any = target.outgoing || [];
- for (const outgoingConnection of outgoingConnections) {
- stack.push(outgoingConnection); // 将所有关联的连接线压入栈中
- }
- }
- return Array.from(processedElements);
- }
- function autoExecute(groupShape: any) {
- // 判断groupBottom 和该触发节点对应的任务节点元素与合流节点间的距离
- // 1. 获取到触发节点对应的任务节点 后续获取到该元素在哪个合流元素内部 获取到合流网关 判断合流网关和当前的判断groupBottom坐标 如果小于则需要对合流后的所有元素进行统一偏移
- let triggerSourceShape: any;
- injector.get('elementRegistry').forEach(e => {
- if (e.businessObject.$attrs.customGroupId === groupShape.id && e.wnType === typeTrigger) triggerSourceShape = e.incoming[0].source;
- });
- // 迭代获取最近的合流节点 如果下一个节点时分流节点 则获取到对应的合流节点继续获取下一个节点
- function getConfluence(shape: any) {
- let targetList = NodeUtils.getNextElementList(shape, injector.get('elementRegistry').getAll());
- let confluence: any;
- targetList.map((element: any) => {
- if (element.wnType === typeConfluence) {
- confluence = element;
- return;
- }
- if (element.wnType != typeTrigger) confluence = getConfluence(element);
- if (hasGatewayType.has(element.wnType)) confluence = getConfluence(injector.get('elementRegistry').get(element.id + '_confluence'));
- });
- return confluence;
- }
- let confluenceShape = getConfluence(triggerSourceShape);
- if (confluenceShape) {
- if (groupShape && groupShape.y + groupShape.height + 50 >= confluenceShape.y) {
- modeling.moveElements(moveConnectedElements(confluenceShape.incoming[0], 0, false), {
- x: 0,
- y: groupShape.y + groupShape.height + DEFAULT_DISTANCE - 15 - confluenceShape.y,
- });
- }
- }
- }
- async function updateShapePosition(shape: any, element: any, businessTaskObject, businessInclusiveObject, businessTask2Object) {
- let connectElement: any = element?.labelTarget;
- let targetElement = connectElement?.target;
- let sourceElement = connectElement?.source;
- let promises: any = [];
- if (shape.wnType === typeTrigger) {
- // 生成一个触发节点
- let labelTargetY = (DEFAULT_DISTANCE + typeConfig[bpmnTask].renderer.attr.height) * 2;
- let y = labelTargetY - (targetElement.y - sourceElement.y);
- if (targetElement.wnType === typeConfluence) {
- modeling.moveElements(moveConnectedElements(element.labelTarget, labelTargetY), {
- x: 0,
- y: y,
- });
- }
- autoPlace.append(sourceElement, shape);
- let groupShapes = modeling.createShape(
- {
- type: 'bpmn:Group',
- },
- { x: shape.x - 25, y: shape.y - 15, width: 250, height: 118 },
- shape.parent,
- );
- modeling.updateProperties(shape, {
- customGroupId: groupShapes.id,
- });
- } else if (hasGatewayType.has(shape.wnType)) {
- // 生成两个分支 包含分支 → 条件节点*2 → 任务节点*2 → 合流节点*1 最后融入到旧元素内
- let shape1 = elementFactory.createShape(
- Object.assign({ type: bpmnTask, name: typeTask, businessObject: businessTaskObject, wnType: typeTask }, { wnName: '审批节点' }),
- );
- businessInclusiveObject.id = shape.id + '_confluence';
- let gateway = elementFactory.createShape(
- Object.assign(
- {
- id: shape.id + '_confluence',
- type: bpmnInclusive,
- name: typeConfluence,
- businessObject: businessInclusiveObject,
- wnType: typeConfluence,
- },
- { wnName: '合流' },
- ),
- );
- let shape2 = elementFactory.createShape(
- Object.assign({ type: bpmnTask, name: typeTask, businessObject: businessTask2Object, wnType: typeTask }, { wnName: '审批节点' }),
- );
- let labelTargetY =
- DEFAULT_DISTANCE * 4 +
- typeConfig[bpmnTask].renderer.attr.height +
- typeConfig[sourceElement.type].renderer.attr.height +
- typeConfig[bpmnInclusive].renderer.attr.height;
- promises.push(
- modeling.moveElements(moveConnectedElements(element.labelTarget, labelTargetY), {
- x: 0,
- y: labelTargetY - (targetElement.y - sourceElement.y),
- }),
- );
- promises.push(modeling.removeConnection(connectElement));
- promises.push(autoPlace.append(sourceElement, shape));
- promises.push(autoPlace.append(shape, shape1));
- promises.push(autoPlace.append(shape, shape2));
- promises.push(autoPlace.append(shape1, gateway));
- promises.push(modeling.connect(shape2, gateway));
- promises.push(modeling.connect(gateway, targetElement));
- } else if (targetElement) {
- let labelTargetY = (DEFAULT_DISTANCE + typeConfig[bpmnTask].renderer.attr.height) * 2;
- let y = labelTargetY - (targetElement.y - sourceElement.y);
- if (targetElement.type === bpmnEnd) y = DEFAULT_DISTANCE + typeConfig[bpmnTask].renderer.attr.height;
- if (sourceElement.type === bpmnStart) y = DEFAULT_DISTANCE + typeConfig[bpmnTask].renderer.attr.height;
- if (sourceElement.wnType === typeConfluence) {
- y = DEFAULT_DISTANCE + typeConfig[bpmnTask].renderer.attr.height;
- if (targetElement.y - sourceElement.y - DEFAULT_DISTANCE * 2 - typeConfig[bpmnTask].renderer.attr.height > 0) y = 0;
- if (targetElement.y - sourceElement.y - DEFAULT_DISTANCE * 2 - typeConfig[bpmnTask].renderer.attr.height < 0)
- y = (sourceElement.y + DEFAULT_DISTANCE * 2 + typeConfig[bpmnTask].renderer.attr.height) - targetElement.y;
- }
- if (sourceElement?.wnType === typeConfluence && targetElement?.wnType === typeConfluence) {
- let maxY = -Infinity;
- let id;
- targetElement = injector.get('elementRegistry').get(targetElement.id);
- targetElement.incoming?.length > 0 &&
- targetElement.incoming.map(item => {
- let currentElement: any = injector.get('elementRegistry').get(item.id);
- if (currentElement.source?.y > maxY) {
- id = currentElement.source.id;
- maxY = currentElement.source.y;
- }
- });
- if (targetElement.y - maxY <= DEFAULT_DISTANCE && sourceElement.id != id) {
- y = DEFAULT_DISTANCE - (targetElement.y - maxY);
- }
- }
- if (changeTypeByTaskShape[shape.wnType]) {
- let source = contextPadProvider._injector.get('elementRegistry').get(connectElement.id).source;
- // 需要增加customGroupId
- modeling.updateProperties(shape, {
- customGroupId: source.businessObject.$attrs.customGroupId,
- });
- }
- promises.push(
- modeling.moveElements(moveConnectedElements(element.labelTarget, labelTargetY), {
- x: 0,
- y: y,
- }),
- );
- promises.push(modeling.removeConnection(connectElement));
- autoPlace.append(sourceElement, shape);
- promises.push(modeling.connect(shape, targetElement));
- }
- Promise.all(promises);
- let elementRegistry = injector.get('elementRegistry');
- let treeBuilder = new BPMNTreeBuilder(elementRegistry.getAll()); // 实例化工具类
- treeBuilder.resizeGroupShape(elementRegistry.getAll(), injector);
- if (changeTypeByTaskShape[shape.wnType]) {
- let groupShape = injector.get('elementRegistry').get(targetElement.businessObject.$attrs.customGroupId);
- autoExecute(groupShape);
- }
- }
- async function onAutoPosition() {
- let elementRegistry: any = await contextPadProvider._injector.get('elementRegistry');
- let allElements = elementRegistry.getAll();
- let treeBuilder = new BPMNTreeBuilder(allElements); // 实例化工具类
- let bpmnTree = treeBuilder.constructTree(1); // 构建树状数据结构
- let visited: any = new Map(); // 用于防止重复访问
- let shapeList: any = []; // 修改触发节点旁的连接线坐标
- let confluenceMap: any = new Map();
- treeBuilder.calculateVirtualWidth(bpmnTree, elementRegistry); // 计算虚拟宽度
- treeBuilder.traverseTreeBFS(bpmnTree, node => {
- node?.offset && node.x != node.offset.x && visited.set(node.id, node);
- if (node?.children?.length > 0) {
- let hasTrigger = node.children.some(o => o.wnType === typeTrigger);
- let hasConfluence = node.children.some(o => o.wnType === typeConfluence);
- let shape = elementRegistry.get(node.id);
- let confluence: any;
- if (shape.outgoing?.length) {
- shape.outgoing.map((connect: any) => {
- if (connect.target.wnType === typeTrigger) hasTrigger = true;
- if (connect.target.wnType === typeConfluence) {
- confluence = connect.target;
- hasConfluence = true;
- }
- });
- }
- if (hasTrigger && hasConfluence)
- shapeList.push({ shape: elementRegistry.get(node.id), treeShape: node, treeConfluence: node.children[0], confluence: confluence });
- if (node.wnType === typeConfluence) confluenceMap.set(node.id, node);
- }
- });
- treeBuilder.formatCanvas(Array.from(visited.values()), modeling, elementRegistry);
- // 如果某个节点的出线包含合流及触发节点元素 则将连接合流节点的线进行进行重新绘制(根据当前节点的虚拟宽度计算出偏移的xy轴坐标中点)
- // 虚拟宽度的最左侧坐标为 当前元素的x + width/2 - 虚拟宽度/2
- shapeList.map(({ shape, treeShape, treeConfluence, confluence }) => {
- let confluenceElement = confluenceMap.get(treeConfluence.id);
- let x = shape.x + shape.width / 2 - treeShape.virtualWidth / 2 + shape.width / 2;
- let newWaypoints: any = [];
- if (!confluenceElement) {
- confluenceElement = confluenceMap.get(confluence.id);
- let childrenShape = treeShape.children[treeShape.children.length - 1];
- if (childrenShape.wnType === typeConfluence) {
- childrenShape = treeShape.children[treeShape.children.length - 2];
- }
- x = (childrenShape.offset?.x ? childrenShape.offset.x : childrenShape.x) + childrenShape.virtualWidth / 2 + childrenShape.width / 2 + 120;
- newWaypoints = [
- { x: shape.x + shape.width, y: shape.y + shape.height / 2 },
- { x: x, y: shape.y + shape.height / 2 },
- { x: x, y: confluenceElement.y },
- { x: confluenceElement.x, y: confluenceElement.y },
- ];
- } else {
- newWaypoints = [
- { x: shape.x, y: shape.y + shape.height / 2 },
- { x: x, y: shape.y + shape.height / 2 },
- { x: x, y: confluenceElement.y },
- { x: confluenceElement.x, y: confluenceElement.y },
- ];
- }
- let connect = shape.outgoing[0];
- if (shape.outgoing?.length) {
- connect = shape.outgoing.find(connect => connect.target.wnType != typeTrigger);
- }
- modeling.updateWaypoints(connect, newWaypoints);
- });
- treeBuilder.resizeGroupShape(elementRegistry.getAll(), injector);
- }
- // 复制节点
- function copyElement(type) {
- let jnpfData = injector.get('jnpfData');
- let selection = injector.get('selection');
- let copyData = jnpfData.getValue(element.id);
- jnpfData.setValue(bpmnCopy, element);
- jnpfData.setValue('copyType', { type: type, data: copyData });
- eventBus.fire('custom.message', {
- context: '复制成功',
- messageType: 'success',
- });
- selection.select(null);
- }
- }
- return undefined;
- }
- return undefined;
- };
- export default CustomizeContextPad;
|