BPM引擎Activiti6.0任务撤回实现方法

文章详细阐述了在Activiti6.0中如何实现流程发起人撤销整个流程以及办理人撤回已办理任务的功能。流程撤销直接删除流程实例,而任务撤回涉及一系列复杂步骤,包括查询历史任务实例,判断流程状态,反向执行任务等,以完成任务撤回操作。
摘要由CSDN通过智能技术生成

当前使用的BPM引擎为Activiti6.0,客户需求是流程发起人能将整个流程撤销,对于某个流程节点,办理人可以撤回已经办理的任务,同时前提是该任务节点的下个节点未被办理。

1、流程撤销

首先说下发起人对整个流程的撤销,直接删除流程,传入流程实例ID,结束一个流程。执行此方法后,流程实例的当前任务act_ru_task会被删除,流程历史act_hi_taskinst不会被删除,并且流程历史的状态置为finished完成。

runtimeService.deleteProcessInstance(instanceId, deleteReason);

2、任务撤回

已执行任务的撤回操作相对来说复杂些,这里先分步骤说下总体思路:

1)选择一条已办理任务,根据该任务查询出任务ID =myTaskId和流程实例ID=processInstanceId;

2)根据processInstanceId判断当前流程是否已结束或已挂起,流程结束或挂起则无法执行撤回操作;

3)根据myTaskId查询选择任务的历史任务实例historicTaskInstance,进而查询出对应历史活动实例historicActivityInstance,最终得到活动标识myActivityId;

4)根据活动标识myActivityId获取该任务对应的FlowNode对象myFlowNode;

5)查询出该任务节点的所有下一任务节点flowElementList,此处是任务节点Task,排查其它类型活动节点;

6)判断flowElementList中是否有代办事项,如果有则可以执行撤回操作,否则表示该任务的所有下一任务都执行完毕,此时不允许再执行撤回操作;

7)对下一节点代办任务,同样查询出对应的FlowNode对象flowNode;

8)借助FlowNode对象myFlowNode和flowNode,反方向执行一次任务,即从代办任务节点反方向流转到当前任务节点,从而完成了任务撤回操作。

完整代码如下:

public Result cancelTask(ActivitiTask doneTask) {
    try {
        // doneTask为封装的Task对象
String processInstanceId = doneTask.getInstanceId();
        String myTaskId = doneTask.getTaskId();
        // 校验流程是否结束
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).active()
                .singleResult();
        if(processInstance == null) {
            return Result.error("流程已结束或已挂起,无法执行撤回操作");
        }
        // 当前任务
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(myTaskId)
            .processInstanceId(processInstanceId).singleResult();
        if(historicTaskInstance==null) {
            return Result.error("当前任务不存在,无法撤回");
        }
        String myActivityId = null;
        List<HistoricActivityInstance> actInstList =
            historyService.createHistoricActivityInstanceQuery()
                .executionId(historicTaskInstance.getExecutionId())
                .finished().list();
        for(HistoricActivityInstance hai : actInstList) {
            if(myTaskId.equals(hai.getTaskId())) {
            myActivityId = hai.getActivityId();
            break;
            }
        }
        
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(myActivityId);
        // 获取所有下一任务节点的标识ID
        Map<String, String> taskKeyMap = Maps.newHashMap();
        // 获取所有下一任务节点对应的FlowElement
        List<FlowElement> flowElementList = getOutgoingTask(bpmnModel, myActivityId);
        for(FlowElement flowElement : flowElementList) {
            String eleId = flowElement.getId();
            taskKeyMap.put(eleId, eleId);
        }
        // 获取当前流程代办事项,没有代办事项表明流程结束或已挂起
        List<Task> alltaskList = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        if(alltaskList.size() <= 0) {
            return Result.error("流程已结束或已挂起,无法执行撤回操作");
        }
        // 判断所有下一任务节点中是否有代办任务,没有则表示任务已办理或已撤回,此时无法再执行撤回操作
        List<Task> nextTaskList = Lists.newArrayList();
        for(Task task : alltaskList) {
            if(taskKeyMap.containsKey(task.getTaskDefinitionKey())) {
                nextTaskList.add(task);
            }
        }
        if(nextTaskList.size() <= 0) {
            return Result.error("任务已办理或已撤回,无法执行撤回操作");
        }
        
        // 执行撤回操作
        for(Task task : nextTaskList) {
            Execution execution = runtimeService.createExecutionQuery()
                .executionId(task.getExecutionId()).singleResult();
            String activityId = execution.getActivityId();
            FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess()
                .getFlowElement(activityId);
            
            // 记录原活动方向
            List<SequenceFlow> oriSequenceFlows = new ArrayList<SequenceFlow>();
            oriSequenceFlows.addAll(flowNode.getOutgoingFlows());
            flowNode.getOutgoingFlows().clear();
            // 建立新方向
            List<SequenceFlow> newSequenceFlowList = new ArrayList<SequenceFlow>();
            SequenceFlow newSequenceFlow = new SequenceFlow();
            newSequenceFlow.setId("sid-"+UUID.randomUUID().toString());
            newSequenceFlow.setSourceFlowElement(flowNode);
            newSequenceFlow.setTargetFlowElement(myFlowNode);
            newSequenceFlowList.add(newSequenceFlow);
            flowNode.setOutgoingFlows(newSequenceFlowList);
            
            taskService.addComment(task.getId(), task.getProcessInstanceId(), "主动撤回");
            taskService.resolveTask(task.getId());
            taskService.claim(task.getId(), doneTask.getTodoUserId());
            taskService.complete(task.getId());
            flowNode.setOutgoingFlows(oriSequenceFlows);
        }
        
        return Result.success();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        return Result.error("任务撤回失败500");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值