activiti功能上很多时候需要驳回,如请假单领导不同意驳回重写。有多种方式可以实现。
一、流程图上任务节点使用assigness或者candidate users动态的指定用户如使用变量${inputuser}如下图所示:
在部门审批时判断是不同意,自动回到发起人那里,因为发起人就一个人。如果到部门主管(假设可以多个)一级审核完成后,到总经理审批,总经理审批后不同意回退到部门主管,无法确定是哪一个,因为candidate有可能多个。
可以在经理审批的时候根据经理的审批判断条件是否驳回,然后根据此task找到此前执行这个任务的人回退给他,就是审批的时候带上${inputuser}。但是这样写不通用,每个task都要写各自的提交。
如果使用监听器,我的代码中是这样实现回退的功能的。
1、流程图
如上所示,显示提交到此任务和回退到此任务实现了两个流程监听器。指向此节点Task的连线监听器中寻找提交请假单人的部门主管。
回退到此Task连线监听器实现驳回后找到原来提交这步骤的人。任务上不要监听器只要指定assigness为${inputuser}。代码如下:
//正向流程
public class LeaveExecutionListener implements ExecutionListener {
Expression type;
private static final long serialVersionUID = 1L;
@Override
public void notify(DelegateExecution execution) throws Exception {
String value = (String) type.getValue(execution); // 获取到传递过来的参数
ExecutionEntity entity=(ExecutionEntity)execution;
TransitionImpl transitionImpl=(TransitionImpl)entity.getEventSource();
ActivityImpl actimpl=transitionImpl.getDestination(); //获取到流程的目的地
String name=(String) actimpl.getProperties().get("name"); //获取目的地的名称
Subject subject = SecurityUtils.getSubject(); //获取shiro
ShiroUser shiroUser=(ShiroUser) subject.getPrincipal();
long userId = 0L;
long deptId = 0L;
if(shiroUser!=null){ //如果用户,不存在就跳转到登录界面
userId=shiroUser.getId();
deptId=shiroUser.getDeptID();
}else{
throw new ExceptionUtil("process can find userid or dept info");
}
String positionName=StringTools.getPosition(name); //获取到领导职称
List<String> userNameList=TransmitType.valueOf(value).exec(positionName,userId,deptId);
//根据树形查找任务分发的人
execution.setVariable(IBaseFlow.SEND_DOC_INPUTUSER, userNameList);
}
}
//驳回功能
public class RejectExecutionListener implements ExecutionListener {
private static final long serialVersionUID = 1L;
@Override
public void notify(DelegateExecution execution) throws Exception {
EngineServices services = execution.getEngineServices();
ExecutionEntity entity = (ExecutionEntity) execution;
String processInstId=entity.getProcessInstanceId(); //流程实例Id
TransitionImpl transitionImpl = (TransitionImpl) entity.getEventSource();
ActivityImpl actimpl = transitionImpl.getDestination();
String taskDefKey= actimpl.getId(); //task1
List<HistoricTaskInstance> list=services.getHistoryService().createHistoricTaskInstanceQuery().orderByTaskCreateTime().desc()
.processInstanceId(processInstId)
.taskDefinitionKey(taskDefKey)
.list();
if(list!=null){
String user=list.get(0).getAssignee(); //获取最新的一个责任人信息回退给他
execution.setVariable(IBaseFlow.SEND_DOC_INPUTUSER, user);
}
}
}
自此流程正向找到我的部门主管。当流程被总经理驳回。找到是谁办理了此任务,然后重新把任务给此人zhenjing。
