activiti代码实现驳回

1. acitiviti5流程图实现驳回

在这里插入图片描述
rejectProcess.bpmn

<?xml version="1.0" encoding="UTF-8"?>
<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">
  <process id="rejectProcess" name="驳回流程测试" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <endEvent id="endevent1" name="End"></endEvent>
    <userTask id="applySubmit" name="申请人提交" activiti:assignee="${applySubmit}"></userTask>
    <userTask id="check" name="审批" activiti:assignee="${check}"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="applySubmit"></sequenceFlow>
    <sequenceFlow id="flow2" sourceRef="applySubmit" targetRef="check">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${applySubmitPass}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="check" targetRef="endevent1">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkPass}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow4" name="驳回" sourceRef="check" targetRef="applySubmit">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${checkReject}]]></conditionExpression>
    </sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_rejectProcess">
    <bpmndi:BPMNPlane bpmnElement="rejectProcess" id="BPMNPlane_rejectProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="70.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="550.0" y="200.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="applySubmit" id="BPMNShape_applySubmit">
        <omgdc:Bounds height="55.0" width="105.0" x="180.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="check" id="BPMNShape_check">
        <omgdc:Bounds height="55.0" width="105.0" x="360.0" y="190.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="105.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="180.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="285.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="360.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="465.0" y="217.0"></omgdi:waypoint>
        <omgdi:waypoint x="550.0" y="217.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="412.0" y="190.0"></omgdi:waypoint>
        <omgdi:waypoint x="412.0" y="144.0"></omgdi:waypoint>
        <omgdi:waypoint x="232.0" y="144.0"></omgdi:waypoint>
        <omgdi:waypoint x="232.0" y="190.0"></omgdi:waypoint>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="14.0" width="100.0" x="420.0" y="171.0"></omgdc:Bounds>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>
2. 测试
@Slf4j
public class TestAutoSubmit {
    /**
     * 部署流程
     */
    @Test
    public void deployProcessDefinition() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取流程定义与部署相关Service
        Deployment deployment = processEngine.getRepositoryService()
                // 创建一个部署对象
                .createDeployment()
                .name("驳回流程测试")
                // 加载资源文件
                .addClasspathResource("processes/rejectProcess.bpmn")
                .addClasspathResource("processes/rejectProcess.png")
                // 完成部署
                .deploy();
        log.info(deployment.getId());
        log.info(deployment.getName());
    }
     /**
     * 启动流程实例
     */
    @Test
    public void startProcessInstance() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        Map<String, Object> varMap = new HashMap<>();
        varMap.put("applySubmit", "张三");
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .startProcessInstanceByKey("autoSubmit", "autoSubmit", varMap);
        log.info(processInstance.getId());
        log.info(processInstance.getProcessDefinitionId());
        taskQuery();
    }
     /**
     * 申请人提交审批节点
     */
    @Test
    public void doApplySubmitTask() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Map<String, Object> varMap = new HashMap<>();
        varMap.put("applySubmitPass", true);
        varMap.put("check", "李四");
        taskService.complete("7509", varMap);
        taskQuery();
    }
  /**
     * 审批节点,驳回
     */
    @Test
    public void doCheckRejectTask() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        Map<String, Object> varMap = new HashMap<>();
        varMap.put("checkReject", true);
        varMap.put("checkPass", false);
        taskService.complete("7509", varMap);
        taskQuery();
    }
  /**
     * 查询待办任务
     */
    @Test
    public void taskQuery() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<Task> list = processEngine.getTaskService().createTaskQuery()
                // 筛选 multiMeetingApprove 流程
                .processDefinitionKey("rejectProcess")
                .list();
        list.forEach(task -> {
            log.info("流程实例id:{}, 任务处理人:{}, 任务名:{}, 任务定义Key:{}, 任务id:{}", task.getProcessInstanceId(), task.getAssignee(), task.getName(), task.getTaskDefinitionKey(), task.getId());
        });
        if (list.isEmpty()) {
            log.info("没有代办任务了,流程结束");
        }
    }
3. 去除驳回连线,代码实现驳回

在这里插入图片描述

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.ObjectUtils;
    /**
     * 往回跳转到任意节点
     *
     * @param taskId      任务id
     * @param varMap      流程变量
     * @param destTaskKey 跳转的目标任务节点key
     * @apiNote 这里使用的是activiti5中 pvm包API,activiti6没有,不兼容
     */
    public void rollBackToAnyTask(String taskId, Map<String, Object> varMap, String destTaskKey) {
        //查询当前流程实例的待办任务
        List<Task> taskList = taskService.createTaskQuery().taskId(taskId).list();
        if (taskList == null || taskList.size() == 0) {
            throw new ActivitiException("任务已经执行完成,无法跳转处理");
        }

        Task task = taskList.get(0);
        // 取得当前执行对象
        ExecutionEntity executionEntity = (ExecutionEntity) runtimeService.createExecutionQuery()
                .executionId(task.getExecutionId())
                .singleResult();
        //流程定义对象
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(executionEntity.getProcessDefinitionId());
        //流程变量
        Map<String, Object> variables = executionEntity.getProcessVariables();
        if (varMap != null) {
            variables.putAll(varMap);
        }

        //当前活动节点
        ActivityImpl currActivityImpl = processDefinitionEntity.findActivity(executionEntity.getActivityId());
        //目标活动节点
        ActivityImpl nextActivityImpl = processDefinitionEntity.findActivity(destTaskKey);

        //目标活动节点 不能是 当前活动节点
        if (currActivityImpl != null && nextActivityImpl != currActivityImpl) {
            //所有的出口连线集合
            List<PvmTransition> pvmTransitions = currActivityImpl.getOutgoingTransitions();
            List<PvmTransition> oriPvmTransitions = new ArrayList<>();
            oriPvmTransitions.addAll(pvmTransitions);

            //清除所有出口连线
            pvmTransitions.clear();

            //建立新的出口连线
            TransitionImpl tImpl = currActivityImpl.createOutgoingTransition();
            tImpl.setDestination(nextActivityImpl);


            taskService.complete(task.getId(), variables);
            //完成任务会新增历史任务记录,根据需要删除
//                historyService.deleteHistoricTaskInstance(task.getId());

            //删除新的出口
            currActivityImpl.getOutgoingTransitions().remove(tImpl);

            //恢复之前的所有出口
            pvmTransitions.addAll(oriPvmTransitions);
        }
    }
4. activiti5中Command模式驳回
package com.yl.activiti.service;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.impl.TaskServiceImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.ScopeImpl;
import org.activiti.engine.task.IdentityLinkType;

import java.util.List;
import java.util.Map;

/**
 * activiti5中 常规任务节点跳转
 *
 * @author liuxubo
 * @date 2022/10/25 23:20
 */
public class CommonJumpCmd implements Command {
	/**
	 * 任务id
	 */
	private String taskId;
	/**
	 * 流程变量
	 */
	private Map<String, Object> variables;
	/**
	 * taskKey名
	 */
	private String desActivityId;

	/**
	 * 构造器
	 * @param taskId		  任务id
	 * @param variables		  流程变量
	 * @param desActivityId   taskKey名
	 */
	public CommonJumpCmd(String taskId, Map<String, Object> variables, String desActivityId) {
		this.taskId = taskId;
		this.variables = variables;
		this.desActivityId = desActivityId;
	}

	@Override
	public Object execute(CommandContext commandContext) {
		//获取任务实例管理类
		TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
		//获取当前任务实例
		TaskEntity taskEntity = taskEntityManager.findTaskById(taskId);

		//获取当前节点的执行实例
		ExecutionEntity executionEntity = taskEntity.getExecution();
		// 设置流程变量
		executionEntity.setVariables(variables);
 
		// 触发执行监听器complete事件
		taskEntity.fireEvent(TaskListener.EVENTNAME_COMPLETE);
 
		// 触发全局事件转发器TASK_COMPLETED事件
		if (Context.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {
			Context.getProcessEngineConfiguration().getEventDispatcher()
					.dispatchEvent(ActivitiEventBuilder.createEntityWithVariablesEvent(ActivitiEventType.TASK_COMPLETED, this, variables, false));
		}
 
		// 添加act_ru_identitylink表记录。常规流程实例id与执行id相同
		if (Authentication.getAuthenticatedUserId() != null && executionEntity.getProcessInstanceId() != null) {
			executionEntity.involveUser(Authentication.getAuthenticatedUserId(), IdentityLinkType.PARTICIPANT);
		}
 
		// 删除任务
		// deleteTask(String taskId, String deleteReason, boolean cascade), 判断taskId对应的TaskEntity的executionId是否为空,非空则抛出异常,导致无法删除任务
		taskEntityManager.deleteTask(taskEntity, TaskEntity.DELETE_REASON_COMPLETED, false);
 
		//触发执行监听器end事件  获取当前活动节点对应的执行监听器并触发end事件,进而会调用内置的记录监听器。如果漏了这一步骤,会影响历史表记录
		ScopeImpl scope = executionEntity.getActivity();
		List<ExecutionListener> exectionListeners = scope.getExecutionListeners("end");
		for(ExecutionListener listener : exectionListeners) {
			executionEntity.setEventName("end");
			executionEntity.setEventSource(scope);
			try {
				listener.notify(executionEntity);
			} catch (Exception e) {
				throw new ActivitiException(e.getMessage());
			}
		}

		//获取流程定义id
		String processDefinitionId = executionEntity.getProcessDefinitionId();
		ProcessDefinitionEntity processDefinitionEntity = Context.getProcessEngineConfiguration().getDeploymentManager()
				.findDeployedProcessDefinitionById(processDefinitionId);

		ActivityImpl desActivityimpl = processDefinitionEntity.findActivity(desActivityId);
		//设置执行实例的当前活动节点为目标节点
		executionEntity.executeActivity(desActivityimpl);
 
		return null;
	}

	/**
	 * 常规任务节点跳转
	 * @param taskService
	 */
	public void jump(TaskService taskService) {
		TaskServiceImpl taskServiceImpl = (TaskServiceImpl)taskService;
		CommandExecutor commandExecutor = taskServiceImpl.getCommandExecutor();
		commandExecutor.execute(this);
	}
}
5.activiti6Command模式驳回
package com.yl.activiti.service;

import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.ManagementService;
import org.activiti.engine.impl.history.HistoryManager;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
import org.activiti.engine.impl.util.ProcessDefinitionUtil;

/**
 * activiti6中 常规任务节点跳转
 *
 * @author liuxubo
 * @date 2022/10/26 23:39
 */
public class JumpAnyWhereCmd implements Command {
    /**
     * 任务ID
     */
    private String taskId;
    /**
     * 目标任务节点key
     */
    private String destTaskKey;

    /**
     *
     * @param taskId        任务ID
     * @param destTaskKey   目标任务节点key
     */
    public JumpAnyWhereCmd(String taskId, String destTaskKey) {
        this.taskId = taskId;
        this.destTaskKey = destTaskKey;
    }

    /**
     * 执行
     * @param commandContext
     * @return
     */
    public Object execute(CommandContext commandContext) {
        //获取任务实例管理类
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        //获取当前任务实例
        TaskEntity currentTask = taskEntityManager.findById(taskId);

        //获取当前节点的执行实例
        ExecutionEntity execution = currentTask.getExecution();

        //获取流程定义id
        String processDefinitionId = execution.getProcessDefinitionId();
        //获取目标节点
        Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
        FlowElement flowElement = process.getFlowElement(destTaskKey);

        //获取历史管理
        HistoryManager historyManager = commandContext.getHistoryManager();

        //通知当前活动结束(更新act_hi_actinst)
        historyManager.recordActivityEnd(execution, "jump to userTask1");
        //通知任务节点结束(更新act_hi_taskinst)
        historyManager.recordTaskEnd(taskId, "jump to userTask1");
        //删除正在执行的当前任务
        taskEntityManager.delete(taskId);

        //此时设置执行实例的当前活动节点为目标节点
        execution.setCurrentFlowElement(flowElement);

        //向operations中压入继续流程的操作类
        commandContext.getAgenda().planContinueProcessOperation(execution);

        return null;
    }

    /**
     * 跳转任意节点
     * @param managementService
     */
    public void jump(ManagementService managementService){
        managementService.executeCommand(this);
    }

}
  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您好,Activiti 7 中的驳回操作可以通过以下代码实现: ```java public void rejectTask(String taskId) { // 获取当前任务 Task task = taskService.createTaskQuery() .taskId(taskId) .singleResult(); if (task == null) { throw new RuntimeException("任务不存在"); } // 获取当前任务的流程实例 String processInstanceId = task.getProcessInstanceId(); // 获取当前任务的历史任务实例列表 List<HistoricTaskInstance> historicTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricTaskInstanceEndTime() .asc() .list(); // 获取需要驳回到的任务 HistoricTaskInstance targetTask = null; for (int i = 0; i < historicTaskList.size(); i++) { HistoricTaskInstance historicTask = historicTaskList.get(i); if (historicTask.getId().equals(taskId)) { if (i == 0) { throw new RuntimeException("该任务已经是第一个任务,无法驳回"); } targetTask = historicTaskList.get(i - 1); break; } } if (targetTask == null) { throw new RuntimeException("未找到驳回目标任务"); } // 驳回操作 BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); Process process = bpmnModel.getProcesses().get(0); FlowNode sourceNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey()); FlowNode targetNode = (FlowNode) process.getFlowElement(targetTask.getTaskDefinitionKey()); List<Execution> executionList = runtimeService.createExecutionQuery() .processInstanceId(processInstanceId) .list(); for (Execution execution : executionList) { if (execution instanceof ExecutionEntity) { ExecutionEntity executionEntity = (ExecutionEntity) execution; executionEntity.setCurrentFlowElement(sourceNode); runtimeService.createChangeActivityStateBuilder() .processInstanceId(processInstanceId) .moveExecutionToActivityId(executionEntity.getId(), targetNode.getId()) .changeState(); } } } ``` 该代码实现了将当前任务驳回到上一步任务的操作,具体的实现过程请参考注释。需要注意的是,该代码中使用了 Activiti 7 中的一些 API,如 `BpmnModel`、`FlowNode` 等,如果您之前使用的是 Activiti 6,可能需要进行一些调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值