activiti设置驳回节点的问题

最近项目里碰到用activiti工作流来做一个驳回功能,要求驳回到上一个指定的流程,比方说部门职员写申请给部门经理,部门经理审批完给总经理,然后总经理看完不行就驳回给部门经理,我现在写的代码会从总经理这里直接驳回给部门员工,各位看看该怎么写比较好,多谢了

img


``
public void backToActivity(String taskId, String activityId) {
    Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
    if (task == null) {
        throw new RuntimeException("任务不存在");
    }

    List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
            .processInstanceId(task.getProcessInstanceId()).orderByHistoricTaskInstanceEndTime().desc().list();
    HistoricTaskInstance lastTask = null;
    for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
        if (historicTaskInstance.getTaskDefinitionKey().equals(activityId)) {
            lastTask = historicTaskInstance;
            break;
        }
    }

    if (lastTask == null) {
        throw new RuntimeException("没有找到指定节点的任务");
    }
    String lastAssignee = lastTask.getAssignee();
    Map<String, Object> variables = new HashMap<>();
    variables.put("assigneeList", Arrays.asList(lastAssignee));
    runtimeService.createProcessInstanceModification(task.getProcessInstanceId())
            .startBeforeActivity(activityId).setVariables(variables).execute();
}

```

引用chatGPT作答,实现这样的驳回功能需要以下步骤:

1.在流程定义中定义一个变量来存储上一个处理人的信息,例如“previousAssignee”,这样当流程被驳回时,就可以将该变量的值设为上一个处理人的ID。

2.在驳回任务的处理逻辑中,获取该变量的值,并将其作为任务的候选人或者候选组,这样任务就会被分配给上一个处理人。

3.如果驳回到的上一个处理人不是固定的,可以在任务处理时,根据该变量的值动态地设置候选人或者候选组。例如,可以在部门经理审批任务中将该变量的值设为总经理的ID,然后在总经理审批任务中将该变量的值设为部门经理的ID。

下面是一个示例代码片段,用于实现上述逻辑:

// 获取上一个处理人的ID
String previousAssignee = (String) taskService.getVariable(taskId, "previousAssignee");

// 如果上一个处理人不为空,则将任务的候选人或候选组设置为上一个处理人
if (StringUtils.isNotEmpty(previousAssignee)) {
    // 判断上一个处理人是个人还是组
    if (previousAssignee.startsWith("user_")) {
        taskService.setAssignee(taskId, previousAssignee);
    } else if (previousAssignee.startsWith("group_")) {
        taskService.addCandidateGroup(taskId, previousAssignee);
    }
}

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/1092754
  • 这篇博客你也可以参考下:Activiti6-流程跟踪监控图-节点-流程线高亮显示-支持通过、不通过、驳回、退回
  • 除此之外, 这篇博客: Activiti工作流使用之一基础集成中的 3.4.1 控制台循环报循环依赖错误或者启动后出现了校验页面(非自身登录页) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 解决办法:Application启动类上加注解

    • 单体版
    @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, 
    							SecurityAutoConfiguration.class,        
    							org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class})
    
    > 第二个排除全路径为:org.activiti.spring.boot.SecurityAutoConfiguration.class,如找不到,就改为 全路径
    
    • 分离版
    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, SecurityAutoConfiguration.class})
    

    全路径:org.activiti.spring.boot.SecurityAutoConfiguration.class;org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.class

以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:
通过设置驳回节点,实现回退到上一个设定的指定流程节点。可以通过以下代码实现:

1. 在流程定义文件中,设置驳回节点backUserTask

xml
<bpmn:userTask id="usertask3" name="驳回节点" activiti:exclusive="true">
<bpmn:extensionElements>
<activiti:taskListener event="complete" class="com.xx.xx.xxx.BackTaskListener" />
</bpmn:extensionElements>
</bpmn:userTask>


2. 在BackTaskListener中编写处理驳回的代码逻辑

java
public class BackTaskListener implements TaskListener {

public void notify(DelegateTask delegateTask) {
/*获取驳回节点*/
String rejectTargetTaskDefinitionKey = (String)
delegateTask.getVariable("rejectTargetTaskDefinitionKey");
/*获取上一级节点*/
String previousTaskDefinitionKey = (String)
delegateTask.getVariable("previousTaskDefinitionKey");

/*设置流程定义ID*/
String processDefinitionId = delegateTask.getProcessDefinitionId();

/*获取上一个任务节点*/
UserTask userTask = (UserTask)
getFlowElementByActivitiId(processDefinitionId, previousTaskDefinitionKey);

if (userTask != null) {
/*设置回退的节点为指定的节点*/
delegateTask.getExecution().setVariable("backTarget", previousTaskDefinitionKey);
/*设置回退的节点以及处理人*/
delegateTask.setVariable("backTaskUser",userTask.getName());
delegateTask.setVariable("previousTaskUser", delegateTask.getAssignee());

/*把下一节点的执行人设置为空*/
delegateTask.setAssignee(null);

if (StringUtils.isNotEmpty(rejectTargetTaskDefinitionKey)) {
/*移除指定节点后所有节点的任务完成记录*/
ActivityExecution execution = (ActivityExecution) delegateTask.getExecution();
FlowElement rejectFlowElement = getFlowElementByActivitiId(processDefinitionId,
rejectTargetTaskDefinitionKey);
execution.setActivity(rejectFlowElement);
List<Execution> executions = runtimeService.createExecutionQuery()
.parentId(delegateTask.getExecutionId()).list();
for (Execution exe : executions) {
runtimeService.deleteProcessInstance(exe.getId(), "reject");
}
}
}
}

/**
* 根据流程定义ID和ActivitiID获取FlowElement(节点)
* @param processDefinitionId 流程定义ID
* @param activitiId 节点的ActivitiID
* @return FlowElement(节点)
*/
private FlowElement getFlowElementByActivitiId(String processDefinitionId,
String activitiId) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(activitiId);
return flowElement;
}
}


3. 在驳回的Handler中设置指定的驳回节点backUserTask,并传递参数

java
public class RejectEventHandler implements JavaDelegate {

public void execute(DelegateExecution execution) {
/*设置驳回节点*/
execution.setVariable("rejectTargetTaskDefinitionKey","backUserTask");
throw new ActivitiException("驳回...");
}
}


通过以上代码实现活动任务的驳回,可以回退到上一个指定的流程。