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

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

向前加签向后加签

  • 前言
  • 一、解决思路
  • 二、代码
  • 测试

前言

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

一、解决思路

向前加签:向前加一个节点 把当前节点数据删除 将新生成的节点置换到当前实例中
向后加签:向后加一个节点
既然是加节点 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;}@Overridepublic Void execute(CommandContext commandContext) {createDerivedProcessDefinitionForProcessInstance(commandContext, processInstanceId);return null;}@Overrideprotected 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;}@Overrideprotected 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()));}}
}

测试

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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部