Activiti框架——按角色分配走流程
在Activiti框架搭建好之后,我们要怎么使用这个框架呢?很简单,官方为我们提供了7个接口,分别操控框架的对应内容,下面我们来一起学习,简单的走一套完整的流程吧。
一、创建测试类,引入测试用到的配置文件
下边是官方为我们提供的7大接口,他们的作用如下
private final String key = "groupTaskDelegate";//key值
private final int version = 1;//版本号
//Service接口的父类,可以直接获取下边的Service
private ProcessEngine processEngine;
//Activiti的七大Service类
private RepositoryService repositoryService;
private RuntimeService runtimeService;
private HistoryService historyService;
private ManagementService managementService;
private TaskService taskService;
private IdentityService identityService;
private FormService formService;
@Before
public void init() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-activiti.xml");
processEngine = ProcessEngines.getDefaultProcessEngine();
repositoryService = (RepositoryService) context.getBean("repositoryService");
runtimeService = (RuntimeService) context.getBean("runtimeService");
historyService = (HistoryService) context.getBean("historyService");
managementService = (ManagementService) context.getBean("managementService");
identityService = (IdentityService) context.getBean("identityService");
formService = (FormService) context.getBean("formService");
taskService = processEngine.getTaskService();
System.out.println("========== 初始化完成 ==========");
}
二、部署流程
/**
* 流程定义(流程图的设计)好以后,需要部署
* 流程部署涉及到的几个动作和表
* 流程部署表 act_re_deployment
* 流程定义表 act_re_procdef
* 流程资源表 act_ge_bytearray
*/
@Test
public void complateTask() {
Deployment deploy = processEngine.getRepositoryService()
.createDeployment()
.name("Activiti角色配置流程")//部署上去名字
.addClasspathResource("leave.bpmn")//bpmn文件路径
.addClasspathResource("leave.png")//流程图 选择可有可无
.deploy();//部署
System.out.println("流程实例Id--->" + deploy.getId());
System.out.println("流程实例Name--->" + deploy.getName());
}
在部署流程执行之后,我们在数据库中就会发现,多了很多的表,其中查看 act_re_procdef 在表
三、创建用户、角色、以及他们的对应关系
/**
* 创建 角色/分组
*/
@Test
public void testProcessDeploy() {
IdentityService identityService = processEngine.getIdentityService();
//创建用户 act_id_user表
identityService.saveUser(new UserEntity("张三"));
identityService.saveUser(new UserEntity("李四"));
identityService.saveUser(new UserEntity("王五"));
identityService.saveUser(new UserEntity("赵六"));
identityService.saveUser(new UserEntity("田七"));
identityService.saveUser(new UserEntity("胡八"));
//创建角色 act_id_group表
identityService.saveGroup(new GroupEntity("部门主管"));
identityService.saveGroup(new GroupEntity("部门经理"));
identityService.saveGroup(new GroupEntity("CTO"));
System.out.println("角色创建完成");
//创建角色和用户的对应关系 act_id_membership表
identityService.createMembership("张三", "部门主管");
identityService.createMembership("李四", "部门主管");
identityService.createMembership("王五", "部门经理");
identityService.createMembership("赵六", "部门经理");
identityService.createMembership("田七", "CTO");
identityService.createMembership("胡八", "CTO");
System.out.println("角色关系分配完成");
}
四、启动流程
流程的启动方法有几种,我们采用最安全稳定的一种。通过实例ID来启动,保证唯一性。
/**
* 流程的启动(流程实例的产生) new Class->Object
* 涉及到的表 :
* act_ru_execution 流程实例表
* act_ru_task 会产生一条待执行的任务记录
* act_hi_taskinst 也会产生一条历史任务记录(注意:endtime is null)
* 注意: 以流程定义的key启动的话,默认会进入版本最新的流程
*/
@Test
public void testStartProcess() {
//根据key和version查出对应版本的实例Id
String InstanceId = findProcessDefinition(key, version);
//流程定义的key启动的话,默认会进入版本最新的流程
ProcessInstance processInstance = processEngine.getRuntimeService() .startProcessInstanceById(InstanceId,key);//启动流程 ,生成一个流程实例
System.out.println("流程部署的ID:" + processInstance.getDeploymentId());
System.out.println("流程定义的ID:" + processInstance.getProcessDefinitionId());
System.out.println("流程实例的ID:" + processInstance.getProcessInstanceId());
System.out.println("流程启动完毕");
}
五、根据角色查询Task节点
/**
* 根据角色查询某组的任务
*/
@Test
public void testQueryMyGroupTask() {
String assignee = "李四";
String processinstanceId = "30021";
List<Task> taskList = processEngine.getTaskService() //跟任务处理相关的服务类
.createTaskQuery() //创建一个任务查询
.taskCandidateUser(assignee) //加入查询条件
// .processInstanceId(processinstanceId)//查询某个任务
.list(); //返回形式
if (taskList != null && taskList.size() > 0) {
for (Task task : taskList) {
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("流程实例ID:" + task.getProcessInstanceId());
System.out.println("执行对象ID:" + task.getExecutionId());
System.out.println("任务ID:" + task.getId());//任务ID:130004
System.out.println("任务名称:" + task.getName());
System.out.println("任务的创建时间:" + task.getCreateTime());
}
}
}
六、节点通过——人工
流程申请过来的时候,我们要让对应的角色来完成任务,保证流程继续走下去
在分组的情况下,有人要来处理任务的时候,我们要保证只有一个人正在处理,所以我们用拾取任务来保证工作的唯一性。
/**
* 任务拾取
* 我们设置的任务处理人员暂时都只是候选人 ,并不是实际处理人,必须经过任务拾取的过程来确定谁来处理任务
* 任务拾取的过程,就是给执行任务表指定assginee字段值的过程
*/
@Test
public void claimTask() {
String taskId = "2504";//刚才启动的Task的Id
String userId = "张三";//任务拾取的用户
taskService.claim(taskId, userId);
//任务拾取以后, 可以回退给组
//processEngine.getTaskService().setAssignee(taskId, null);
//任务拾取以后,可以转给别人去处理(别人可以是组成员也可以不是)
//processEngine.getTaskService().claim(taskId, "xiaoxi");
}
/**
* 人工节点通过方法
* 流程处理过程:完成个人任务
* 处理流程的步骤:查询个人任务 完成个人任务
* 涉及到的表:act_ru_task
*/
@Test
public void testCompleteMyTask() {
String taskId = "22504";
Map<String, Object> mapVariables = new HashMap<String, Object>();
// mapVariables.put("manageId01", "部门主管");
// mapVariables.put("mes01", "同意,好好干,年底发红包");
mapVariables.put("manageId02", "部门经理");
mapVariables.put("mes02", "同意,好好干,年底发奖金");
// mapVariables.put("manageId03", "部门CTO");
// mapVariables.put("mes03", "同意,好好干,年底发分红");
//带审核意见
processEngine.getTaskService().complete(taskId, mapVariables);
System.out.println("审批完成");
//不带审核意见
// String taskId = "25002";
// processEngine.getTaskService().complete(taskId);
// System.out.println("审批任务完成");
}
七、通过节点——自动
/**
* 自动审核通过节点
*/
@Test
public void testCompleteMyTaskSelf(){
String processDefinId = findProcessDefinition(key, version);
ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinId,key);//启动流程 ,生成一个流程实例
System.out.println("流程定义的ID:" + instance.getProcessDefinitionId());
System.out.println("流程实例的ID:" + instance.getProcessInstanceId());
Task task = taskService.createTaskQuery().processInstanceId(instance.getProcessInstanceId()).active().singleResult();
while (task!=null){
System.out.println("============"+task.getName()+" 流程开始 ============");
Map<String, Object> mapVariables = new HashMap<String, Object>();
if ("usertask1".equals(task.getTaskDefinitionKey())){
mapVariables.put("manageId01", "部门主管");
mapVariables.put("mes01", "同意,好好干,年底发红包");
}
if ("usertask2".equals(task.getTaskDefinitionKey())){
mapVariables.put("manageId02", "部门经理");
mapVariables.put("mes02", "同意,好好干,年底发奖金");
}
if ("usertask3".equals(task.getTaskDefinitionKey())){
mapVariables.put("manageId03", "部门CTO");
mapVariables.put("mes03", "同意,好好干,年底发分红");
}
System.out.println("============"+task.getName()+" 流程结束 ============");
//带审核意见
processEngine.getTaskService().complete(task.getId(), mapVariables);
//重新获取task
task = taskService.createTaskQuery().processInstanceId(instance.getProcessInstanceId()).active().singleResult();
}
System.out.println("审批完成");
}