工作流的向前加签向后加签

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

前言

公司业务要求需要加个向前加签 向后加签的功能,可难为死我小时了,只听过说加签转签 还有向前加签。

一、解决思路

向前加签:向前加一个节点 把当前节点数据删除 将新生成的节点置换到当前实例中
向后加签:向后加一个节点
既然是加节点 flowable 有动态修改节点的功能 参考 flowable 中的 InjectUserTaskInProcessInstanceCmd

二、代码

package com.process.commnd; /**
 * Created by Administrator on 2020/4/8.
 */

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.BpmnAutoLayout;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.cmd.AbstractDynamicInjectionCmd;
import org.flowable.engine.impl.context.Context;
import org.flowable.engine.impl.dynamic.BaseDynamicSubProcessInjectUtil;
import org.flowable.engine.impl.dynamic.DynamicUserTaskBuilder;
import org.flowable.engine.impl.persistence.entity.*;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.job.service.JobService;
import org.flowable.task.service.HistoricTaskService;
import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.flowable.variable.service.VariableService;
import org.springframework.beans.BeanUtils;

import java.util.*;

/**
 * 加签根据flag 区分是向前加 还是向后加
 * @author : shiyushan
 * @date : 2020/10/18 14:46
 */
public class CustomInjectUserTaskInProcessInstanceCmd extends AbstractDynamicInjectionCmd implements Command<Void> {

    protected String processInstanceId;
    protected DynamicUserTaskBuilder dynamicUserTaskBuilder;
    protected Boolean flag;
    protected String currentActivityId;
    protected String formKey;
    protected FlowElement currentFlowElement;


    public CustomInjectUserTaskInProcessInstanceCmd(String processInstanceId, Boolean flag, DynamicUserTaskBuilder dynamicUserTaskBuilder,
                                                    String currentActivityId,String formKey) {
        this.processInstanceId = processInstanceId;
        this.dynamicUserTaskBuilder = dynamicUserTaskBuilder;
        this.currentActivityId = currentActivityId;
        this.flag = flag;
        this.formKey = formKey;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        createDerivedProcessDefinitionForProcessInstance(commandContext, processInstanceId);
        return null;
    }

    @Override
    protected void updateBpmnProcess(CommandContext commandContext, Process process,
                                     BpmnModel bpmnModel, ProcessDefinitionEntity originalProcessDefinitionEntity, DeploymentEntity newDeploymentEntity) {
        this.currentFlowElement = process.getFlowElement(currentActivityId);
        StartEvent initialStartEvent = getStartEvent(process);
        if (currentFlowElement != null) {
            UserTask userTask = getUserTask(process);
            if (flag) {
                addAfter(userTask, process);
            } else {
                addBefore(userTask, process);
            }
            addPoint(bpmnModel, initialStartEvent);
        }

        BaseDynamicSubProcessInjectUtil.processFlowElements(commandContext, process, bpmnModel, originalProcessDefinitionEntity, newDeploymentEntity);
    }

    /**
     * 根据当前节点获取一个新的节点
     * 并设置新节点的处理人为被加签人
     * @param process
     * @return
     */
    private UserTask getUserTask(Process process) {
        UserTask userTask = new UserTask();
        BeanUtils.copyProperties(this.currentFlowElement, userTask);
        if (dynamicUserTaskBuilder.getId() != null) {
            userTask.setId(dynamicUserTaskBuilder.getId());
        } else {
            userTask.setId(dynamicUserTaskBuilder.nextTaskId(process.getFlowElementMap()));
        }
        dynamicUserTaskBuilder.setDynamicTaskId(userTask.getId());
        userTask.setFormKey(formKey);
        userTask.setName(dynamicUserTaskBuilder.getName());
        userTask.setAssignee(dynamicUserTaskBuilder.getAssignee());
        userTask.setCandidateUsers(new ArrayList<>());
        userTask.setCandidateGroups(new ArrayList<>());
        return userTask;
    }

    /**
     * 向前加签
     * 当前节点向前加线
     * 给新任务节点设置出口跟入口
     * @param userTask
     * @param process
     */
    private void addBefore(UserTask userTask, Process process) {
        UserTask currentFlowElement = (UserTask) this.currentFlowElement;

        List<SequenceFlow> outgoingFlows = new ArrayList<>();
        SequenceFlow outgoingFlow = new SequenceFlow(userTask.getId(), currentFlowElement.getId());
        outgoingFlow.setId("seq_" + UUID.randomUUID());
        outgoingFlows.add(outgoingFlow);
        process.addFlowElement(outgoingFlow);

        List<SequenceFlow> incomingFlows = new ArrayList<>();
        for (SequenceFlow sequenceFlow1 : currentFlowElement.getIncomingFlows()) {
            SequenceFlow sequenceFlow = new SequenceFlow(sequenceFlow1.getSourceRef(),userTask.getId());
            incomingFlows.add(getSequence(sequenceFlow, incomingFlows, sequenceFlow1));
            //删除原先节点的入线
            process.removeFlowElement(sequenceFlow1.getId());
            process.addFlowElement(sequenceFlow);
        }

        userTask.setOutgoingFlows(outgoingFlows);
        userTask.setIncomingFlows(incomingFlows);
        process.addFlowElement(userTask);
    }


    /**
     * 向后加签
     * 当前节点向后加线
     * 给新任务节点设置出口跟入口
     * @param userTask
     * @param process
     */
    private void addAfter(UserTask userTask, Process process) {
        UserTask currentFlowElement = (UserTask) this.currentFlowElement;
        List<SequenceFlow> outgoingFlows = new ArrayList<>();
        for (SequenceFlow sequenceFlow1 : currentFlowElement.getOutgoingFlows()) {
            SequenceFlow sequenceFlow = new SequenceFlow( userTask.getId(),sequenceFlow1.getTargetRef());
            outgoingFlows.add(getSequence(sequenceFlow, outgoingFlows, sequenceFlow1));
            //删除原先节点的出线
            process.removeFlowElement(sequenceFlow1.getId());
            process.addFlowElement(sequenceFlow);
        }

        List<SequenceFlow> incomingFlows = new ArrayList<>();
        SequenceFlow incomingFlow = new SequenceFlow(currentFlowElement.getId(), userTask.getId());
        incomingFlow.setId("seq_" + UUID.randomUUID());
        incomingFlows.add(incomingFlow);
        process.addFlowElement(incomingFlow);

        userTask.setOutgoingFlows(outgoingFlows);
        userTask.setIncomingFlows(incomingFlows);
        process.addFlowElement(userTask);
    }

    /**
     * 组装新连线
     *
     * @param sequenceFlow
     * @param incomingFlows
     * @param sequenceFlow1
     */
    private SequenceFlow getSequence(SequenceFlow sequenceFlow, List<SequenceFlow> incomingFlows, SequenceFlow sequenceFlow1) {
        sequenceFlow.setSkipExpression(sequenceFlow1.getSkipExpression());
        sequenceFlow.setConditionExpression(sequenceFlow1.getConditionExpression());
        sequenceFlow.setExtensionElements(sequenceFlow1.getExtensionElements());
        sequenceFlow.setExecutionListeners(sequenceFlow1.getExecutionListeners());
        sequenceFlow.setName(sequenceFlow1.getName());
        sequenceFlow.setId("seq_" + UUID.randomUUID());
        return sequenceFlow;
    }


    /**
     * 新增坐标点
     *
     * @param bpmnModel
     * @param initialStartEvent
     */
    private void addPoint(BpmnModel bpmnModel, StartEvent initialStartEvent) {
        GraphicInfo elementGraphicInfo = bpmnModel.getGraphicInfo(currentFlowElement.getId());
        if (elementGraphicInfo != null) {
            double yDiff = 0;
            double xDiff = 80;
            if (elementGraphicInfo.getY() < 173) {
                yDiff = 173 - elementGraphicInfo.getY();
                elementGraphicInfo.setY(173);
            }

            Map<String, GraphicInfo> locationMap = bpmnModel.getLocationMap();
            for (String locationId : locationMap.keySet()) {
                if (initialStartEvent.getId().equals(locationId)) {
                    continue;
                }

                GraphicInfo locationGraphicInfo = locationMap.get(locationId);
                locationGraphicInfo.setX(locationGraphicInfo.getX() + xDiff);
                locationGraphicInfo.setY(locationGraphicInfo.getY() + yDiff);
            }

            Map<String, List<GraphicInfo>> flowLocationMap = bpmnModel.getFlowLocationMap();
            for (String flowId : flowLocationMap.keySet()) {

                List<GraphicInfo> flowGraphicInfoList = flowLocationMap.get(flowId);
                for (GraphicInfo flowGraphicInfo : flowGraphicInfoList) {
                    flowGraphicInfo.setX(flowGraphicInfo.getX() + xDiff);
                    flowGraphicInfo.setY(flowGraphicInfo.getY() + yDiff);

                }
            }
            new BpmnAutoLayout(bpmnModel).execute();
        }
    }

    /**
     * 得到开始节点
     * @param process
     * @return
     * @author: shiyushan
     * @version: 1.0.0
     * @date: 2023/1/2 6:57 下午
     */
    private StartEvent getStartEvent(Process process) {
        List<StartEvent> startEvents = process.findFlowElementsOfType(StartEvent.class);
        StartEvent initialStartEvent = null;
        for (StartEvent startEvent : startEvents) {
            if (startEvent.getEventDefinitions().size() == 0) {
                initialStartEvent = startEvent;
                break;

            } else if (initialStartEvent == null) {
                initialStartEvent = startEvent;
            }
        }
        return initialStartEvent;
    }

    @Override
    protected void updateExecutions(CommandContext commandContext, ProcessDefinitionEntity processDefinitionEntity,
                                    ExecutionEntity processInstance, List<ExecutionEntity> childExecutions) {

        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        VariableService variableService = CommandContextUtil.getVariableService(commandContext);
        JobService jobService = CommandContextUtil.getJobService(commandContext);

        BpmnModel bpmnModel = ProcessDefinitionUtil.getBpmnModel(processDefinitionEntity.getId());

        ActivityInstanceEntityManager manager = CommandContextUtil.getActivityInstanceEntityManager();
        org.flowable.task.service.TaskService taskService = CommandContextUtil.getTaskService(commandContext);
         HistoricTaskService historicTaskService = CommandContextUtil.getHistoricTaskService(commandContext);

        List<TaskEntity> taskEntities = taskService.findTasksByProcessInstanceId(processInstanceId);
        if (!flag) {
            ExecutionEntity execution = executionEntityManager.createChildExecution(processInstance);
            execution.setVariable("assigneeList_"+dynamicUserTaskBuilder.getId(), Arrays.asList(dynamicUserTaskBuilder.getAssignee()));
            ActivityInstanceEntity activityInstance = manager.findUnfinishedActivityInstance(execution);
            // 删除当前活动任务
            String parentId ="";
            for (TaskEntity taskEntity : taskEntities) {
                taskEntity.getIdentityLinks().stream().forEach(identityLinkEntity -> {
                    taskEntity.deleteUserIdentityLink(identityLinkEntity.getUserId(), "candidate");
                    taskEntity.deleteUserIdentityLink(identityLinkEntity.getUserId(), "participant");
                });
                if (taskEntity.getTaskDefinitionKey().equals(currentFlowElement.getId())) {
                    taskService.deleteTask(taskEntity, true);
                }

              //得到父级实例
                ExecutionEntity executionEntity = executionEntityManager.findById(taskEntity.getExecutionId());
                parentId = executionEntity.getParentId();
            }
            //删除相关联的实例 特别注意如果是会签另一个实例已同意所以进程未删除
            if (StringUtils.isNotBlank(parentId)) {
                ExecutionEntity parentExecution = executionEntityManager.findById(parentId);
                List<ExecutionEntity> executions = executionEntityManager.findChildExecutionsByParentExecutionId(parentId);
                for (ExecutionEntity childExecution : executions) {
                    if (!childExecution.getId().equals(execution.getId())) {
                        jobService.deleteJobsByExecutionId(childExecution.getId());
                        variableService.deleteVariablesByExecutionId(childExecution.getId());
                        executionEntityManager.delete(childExecution);
                    }
                }
                if (StringUtils.isNotBlank(parentExecution.getActivityId())) {
                    jobService.deleteJobsByExecutionId(parentExecution.getId());
                    variableService.deleteVariablesByExecutionId(parentExecution.getId());
                    executionEntityManager.delete(parentExecution);
                    System.out.println("删除父实例");
                }
            }

            List<HistoricTaskInstanceEntity> historyList = historicTaskService.findHistoricTasksByProcessInstanceId(execution.getProcessInstanceId());
            for (HistoricTaskInstanceEntity history : historyList) {
                if (history.getTaskDefinitionKey().equals(currentFlowElement.getId())) {
                    history.setDeleteReason("加签被删除");
                    history.setEndTime(new Date());
                    historicTaskService.updateHistoricTask(history,false);
                }
            }
            //任务节点结束
            if (activityInstance!=null) {
                activityInstance.setEndTime(new Date());
                manager.update(activityInstance);
            }
            //设置活动后的节点
            UserTask userTask = (UserTask) bpmnModel.getProcessById(processDefinitionEntity.getKey()).getFlowElement(dynamicUserTaskBuilder.getId());
            execution.setCurrentFlowElement(userTask);
            Context.getAgenda().planContinueProcessOperation(execution);
        }else {
            processInstance.setVariable("assigneeList_"+dynamicUserTaskBuilder.getId(), Arrays.asList(dynamicUserTaskBuilder.getAssignee()));
        }
    }
}



测试

    @Autowired
    protected ManagementService managementService;
        private void addSign(WfSignPo vo,FlowEnum type) {
        managementService.executeCommand(new CustomInjectUserTaskInProcessInstanceCmd(task.getProcessInstanceId(), flag, dynamicUserTaskBuilder, task.getTaskDefinitionKey()));
    }

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值