我们在开发的时候,有一种情况是这样的,
我们有一个任务,可以让多个用户中的任何一个人办理即可,比如某个审批任务,
谢霆锋,杨幂,高圆圆他们中的任何一人办理下都行,这时候,我们用到多用户任务分配。
方式一、直接流程图配置中写死
上面是某个人审批写死。
上面是组审批写死。这里我们分配2个人【3XXA、5KLM】 ,中间用逗号隔开。
实例代码为:
public class AssignTest {
/**
* 获取默认流程引擎实例,会自动读取activiti.cfg.xml文件
*/
private ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
/**
* 部署流程定义
*/
@Test
public void deploy(){
Deployment deployment=processEngine.getRepositoryService() // 获取部署相关Service
.createDeployment() // 创建部署
.addClasspathResource("diagrams/multiUserProcess.bpmn") // 加载资源文件
.addClasspathResource("diagrams/multiUserProcess.png") // 加载资源文件
.name("学生请假流程5") // 流程名称
.deploy(); // 部署
System.out.println("流程部署ID:"+deployment.getId());
System.out.println("流程部署Name:"+deployment.getName());
}
/**
* 启动流程实例
*/
@Test
public void start(){
ProcessInstance pi=processEngine.getRuntimeService() // 运行时Service
.startProcessInstanceByKey("multiUserProcess"); // 流程定义表的KEY字段值
System.out.println("流程实例ID:"+pi.getId());
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
}
/**
* 查看任务
*/
@Test
public void findTask(){
List<Task> taskList=processEngine.getTaskService() // 任务相关Service
.createTaskQuery() // 创建任务查询
//.taskAssignee("谢霆锋") // 指定某个人
.taskCandidateUser("杨幂") // 候选人查询
.list();
for(Task task:taskList){
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println("任务委派人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
}
}
/**
* 完成任务
*/
@Test
public void completeTask(){
processEngine.getTaskService() // 任务相关Service
.complete("305004");
}
}
这里有几点说明下:
1,任务查询的时候 ,我们用 taskCandidateUser 候选人查询方法,不能用taskAssignee。单个在Assignee上写死的用户才能用 taskAssignee查询。
2,启动流程实例后,我们在act_ru_identitylink表。
我们可以看到 activit的设计很巧妙, 在流程图里配置的用户 全是参与者participant,然后还有一份候选人candidate。
候选人绑定任务id,参与者绑定流程实例ID,这里我们可以通过Activiti的接口来增加或者减少候选人,自行查询Activiti官方文档。
我们用任何一人,都能查询到任务,最后任何一人完整任务即可;
方式二、使用流程变量
我们启动流程的时候设置流程变量的值,其他的和上面一样。
小二,上代码
public class AssignTest2 {
/**
* 获取默认流程引擎实例,会自动读取activiti.cfg.xml文件
*/
private ProcessEngine processEngine=ProcessEngines.getDefaultProcessEngine();
/**
* 部署流程定义
*/
@Test
public void deploy(){
Deployment deployment=processEngine.getRepositoryService() // 获取部署相关Service
.createDeployment() // 创建部署
.addClasspathResource("diagrams/multiUserProcess2.bpmn") // 加载资源文件
.addClasspathResource("diagrams/multiUserProcess2.png") // 加载资源文件
.name("学生请假流程5") // 流程名称
.deploy(); // 部署
System.out.println("流程部署ID:"+deployment.getId());
System.out.println("流程部署Name:"+deployment.getName());
}
/**
* 启动流程实例
*/
@Test
public void start(){
Map<String,Object> variables=new HashMap<String,Object>();
variables.put("userIds", "谢霆锋,高圆圆,杨幂");
ProcessInstance pi=processEngine.getRuntimeService() // 运行时Service
.startProcessInstanceByKey("multiUserProcess2",variables); // 流程定义表的KEY字段值
System.out.println("流程实例ID:"+pi.getId());
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
}
/**
* 查看任务
*/
@Test
public void findTask(){
List<Task> taskList=processEngine.getTaskService() // 任务相关Service
.createTaskQuery() // 创建任务查询
//.taskAssignee("杨幂") // 指定某个人
.taskCandidateUser("谢霆锋") // 候选人查询
.list();
for(Task task:taskList){
System.out.println("任务ID:"+task.getId());
System.out.println("任务名称:"+task.getName());
System.out.println("任务创建时间:"+task.getCreateTime());
System.out.println("任务委派人:"+task.getAssignee());
System.out.println("流程实例ID:"+task.getProcessInstanceId());
}
}
/**
* 完成任务
*/
@Test
public void completeTask(){
processEngine.getTaskService() // 任务相关Service
.complete("317505");
}
}
方式三、TaskListener监听实现
我们定义一个监听类 MyTaskListener 实现 TaskListener接口。
上代码
/**
* 审批人直属主管 一般为协理、副总
* 在这个监听器中给协理、副总审批赋予处理人
* @param
* @return
* @author by 叶勇 2021-8-05 上午10:30:25
*/
public class MyTaskCreateListener2 implements TaskListener{
@Override
public void notify(DelegateTask delegateTask) {
// 1.获取当前登录用户id
String userId = UsertUtil.getUserId();
// 2.获取ServletRequestAttributes
ServletRequestAttributes servletRequestAttribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
// 3.通过ServletRequestAttributes获取req对象
HttpServletRequest request = servletRequestAttribute.getRequest();
// 4.通过req获取session,通过sesion获取servletContext
ServletContext servletContext = request.getSession().getServletContext();
// 5.通过servletContext获取Spring容器
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
// 6.从ctx中获取userService
FlowUserRoleMapper flowUserRoleMapper=ctx.getBean(FlowUserRoleMapper.class);
// 7.根据登录用户id 查询流程岗位对象
FlowUserRole flowUserRole = flowUserRoleMapper.getRoleName(userId);
String approver=flowUserRole.getUserIdList().replaceAll(";", "");
//System.out.println("===============协理、副总审批:"+approver);
// 8.设置处理人
//delegateTask.setAssignee(approver); //单个用户
delegateTask.addCandidateUsers(Arrays.asList(approver));
}
}