最近项目里碰到用activiti工作流来做一个驳回功能,要求驳回到上一个指定的流程,比方说部门职员写申请给部门经理,部门经理审批完给总经理,然后总经理看完不行就驳回给部门经理,我现在写的代码会从总经理这里直接驳回给部门员工,各位看看该怎么写比较好,多谢了
``
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);
}
}
解决办法
: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
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>
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;
}
}
java
public class RejectEventHandler implements JavaDelegate {
public void execute(DelegateExecution execution) {
/*设置驳回节点*/
execution.setVariable("rejectTargetTaskDefinitionKey","backUserTask");
throw new ActivitiException("驳回...");
}
}