导图社区 Activiti7详解
Activiti7详解,包括流程定义、流程实例、个人任务的分配方式、流程变量详解、组任务、网关等内容,很详细,值得看看。
编辑于2021-11-05 15:35:52Activiti7详解
流程定义
流程定义是线下按照 bpmn2.0 标准去描述 业务流程,通常使用 activiti-explorer(web 控制台) 或 activiti-eclipse-designer 插件对业务流程进行建模,这两种方式都遵循 bpmn2.0 标准。
流程定义部署
单文件部署
@Test public void deployProcess() { // 获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // bpmn输入流 InputStream inputStream_bpmn = this.getClass().getClassLoader().getResourceAsStream("diagram/holiday.bpmn"); // 图片输入流 InputStream inputStream_png = this.getClass().getClassLoader().getResourceAsStream(" diagram/holiday.png"); // 流程部署对象 Deployment deployment = repositoryService.createDeployment().addInputStream("holiday.bpmn", inputStream_bpmn).addInputStream("holiday.png", inputStream_png).deploy(); System.out.println("流程部署id: " + deployment.getId()); System.out.println("流程部署名称: " + deployment.getName()); }
压缩包部署
将 holiday.bpmn和holiday.png压缩成zip文件。 @Test public void deployProcessByZip() { // 定义zip输入流 InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(" diagram/holiday.zip"); ZipInputStream zipInputStream = new ZipInputStream(inputStream); // 获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // 流程部署 Deployment deployment = repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy(); System.out.println("流程部署id:" + deployment.getId()); System.out.println("流程部署名称:" + deployment.getName()); }
对应的数据表
act_re_deploymen
流程定义部署表,记录流程部署信息
act_re_procdef
流程定义表,记录流程定义信息
act_re_deployment 和 act_re_procdef 一对多关系,一次部署在流程部署表生成一条记录,但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。每一个流程定义在act_ge_bytearray 会存在两个资源记录, bpmn 和 png。 建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。
act_ge_bytearray
资源表
流程定义查询
@Test public void queryProceccDefinition() { // 流程定义key String processDefinitionKey = "holiday"; // 获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // 查询流程定义 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); //遍历查询结果 List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey(processDefinitionKey).orderByProcessDefinitionVersion().desc().list(); for (ProcessDefinition processDefinition : list) { System.out.println("------------------------"); System.out.println("流程部署id:" + processDefinition.getDeploymentId()); System.out.println("流程定义id: " + processDefinition.getId()); System.out.println("流程定义名称: " + processDefinition.getName()); System.out.println("流程定义key: " + processDefinition.getKey()); System.out.println("流程定义版本: " + processDefinition.getVersion()); } }
流程定义删除
说明: 1、如果该流程定义下没有正在运行的流程,则可以用普通删除。 2、 如果该流程定义下存在已经运行的流程,使用普通删除报错,可用级联删除方法将流程及相关记录全部删除。 项目开发中使用级联删除的情况比较多, 删除操作一般只开放给超级管理员使用。 @Test public void deleteDeployment() { // 流程部署id String deploymentId = "8801"; // 通过流程引擎获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); //删除流程定义, 如果该流程定义已有流程实例启动则删除时出错 repositoryService.deleteDeployment(deploymentId); //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式。 //repositoryService.deleteDeployment(deploymentId, true); }
流程定义资源查询
通过流程定义对象获取流程定义资源
@Test public void getProcessResources() throws IOException { // 流程定义id String processDefinitionId = ""; // 获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); // 流程定义对象 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); //获取bpmn String resource_bpmn = processDefinition.getResourceName(); //获取png String resource_png =processDefinition.getDiagramResourceName(); // 资源信息 System.out.println("bpmn: " + resource_bpmn); System.out.println("png: " + resource_png); File file_png = new File("d:/purchasingflow01.png"); File file_bpmn = new File("d:/purchasingflow01.bpmn"); // 输出bpmn InputStream resourceAsStream = null; resourceAsStream = repositoryService.getResourceAsStream( processDefinition.getDeploymentId(), resource_bpmn); FileOutputStream fileOutputStream = new FileOutputStream(file_bpmn); byte[] b = new byte[1024]; int len = -1; while ((len = resourceAsStream.read(b, 0, 1024)) != -1) { fileOutputStream.write(b, 0, len); } // 输出图片 resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resource_png); fileOutputStream = new FileOutputStream(file_png); // byte[] b = new byte[1024]; // int len = -1; while ((len = resourceAsStream.read(b, 0, 1024)) != -1) { fileOutputStream.write(b, 0, len); } }
通过查询流程部署信息获取流程定义资源
// 获取流程定义图片资源 @Test public void getProcessResources() throws IOException { //流程部署id String deploymentId = "9001"; // 通过流程引擎获取repositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); 说明: 1) deploymentId 为流程部署 ID 2) resource_name 为 act_ge_bytearray 表中 NAME_列的值 3) 使用 repositoryService 的 getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称 4) 使用 repositoryService 的 getResourceAsStream 方法传入部署 ID和资源图片名称可以获取部署下指定名称文件的输入流。 5) 最后的将输入流中的图片资源进行输出。 //读取资源名称 List<String> resources = repositoryService.getDeploymentResourceNames(deploymentId); String resource_image = null; //获取图片 for(String resource_name :resources){ if(resource_name.indexOf(".png")>=0){ resource_image = resource_name; } } //图片输入流 InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resource_image); File exportFile = new File("d:/holiday.png"); FileOutputStream fileOutputStream = new FileOutputStream(exportFile); byte[] buffer = new byte[1024]; int len = -1; //输出图片 while((len = inputStream.read(buffer))!=-1){ fileOutputStream.write(buffer, 0, len); } inputStream.close(); fileOutputStream.close(); }
流程历史信息查看
@Test public void testHistoric01(){ HistoryService historyService = pe.getHistoryService(); HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery(); query.processInstanceId("1501"); List<HistoricActivityInstance> list = query.list(); for(HistoricActivityInstance ai :list){ System.out.println(ai.getActivityId()); System.out.println(ai.getActivityName()); System.out.println(ai.getProcessDefinitionId()); System.out.println(ai.getProcessInstanceId()); System.out.println("=============================="); } }
流程实例
启动
@Test public void startProcessInstance() { // 流程定义key String processDefinitionKey = ""; // 获取RunTimeService RuntimeService runtimeService = processEngine.getRuntimeService(); // 根据流程定义key启动流程 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey); System.out.println("流程定义id:" +processInstance.getProcessDefinitionId()); System.out.println("流程实例id:" + processInstance.getId()); System.out.println("当前活动Id:" + processInstance.getActivityId()); }
Businesskey
业务标识,通常为业务表的主键,业务标识和流程实例一一对应。业务标识来源于业务系统。存储业务标识就是根据业务标识来关联查询业务系统的数据。
数据表
act_ru_execution
流程实例执行表,记录当前流程实例的执行情况。 不论当前有几个分支总会有一条记录的执行表的主键和流程实例 id 相同。 一个流程实例运行完成,此表中与流程实例相关的记录删除。
act_ru_task
任务执行表,记录当前执行的任务。 启动流程实例,流程当前执行到第一个任务结点,此表会插入一条记录表示当前任务的执行情况,如果任务完成则记录删除。
act_ru_identitylink
任务参与者,记录当前参与任务的用户或组。
act_hi_procinst
流程实例历史表。 流程实例启动,会在此表插入一条记录,流程实例运行完成记录也不会删除。
act_hi_taskinst
任务历史表,记录所有任务。 开始一个任务,不仅在 act_ru_task 表插入记录,也会在历史任务表插入一条记录,任务历史表的主键就是任务 id,任务完成此表记录不删除。
act_hi_actinst
活动历史表,记录所有活动 以此表中不仅记录了任务,还记录了流程执行过程的其它活动,比如开始事件、结束事件。
查询流程实例
@Test public void queryProcessInstance() { // 流程定义key String processDefinitionKey = "holiday"; // 获取RunTimeService RuntimeService runtimeService = processEngine.getRuntimeService(); List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(processDefinitionKey).list(); for (ProcessInstance processInstance : list) { System.out.println("----------------------------"); System.out.println("流程实例id:"+ processInstance.getProcessInstanceId()); System.out.println("所属流程定义id:"+ processInstance.getProcessDefinitionId()); System.out.println("是否执行完成:" + processInstance.isEnded()); System.out.println("是否暂停:" + processInstance.isSuspended()); System.out.println("当前活动标识:" +processInstance.getActivityId()); } }
关联BussinessKey
业务系统的数据同步BussenssKey关联Activiti工作流。 比如:在查询流程实例时,通过 businessKey(业务标识 )关联查询业务系统的请假单表,查询出请假天数等信息。
挂起、激活流程实例
某些情况可能由于流程变更需要将当前运行的流程暂停而不是直接删除,流程暂停后将不会继续执行。 流程定义处于挂起状态,不允许启动新的流程实例,同时该流程定义下的流程实例全部挂起暂停执行。
全部挂起、激活
// 挂起激活流程定义 @Test public void suspendOrActivateProcessDefinition() { // 流程定义id String processDefinitionId = ""; RepositoryService repositoryService = processEngine.getRepositoryService(); // 获得流程定义 ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult(); //是否暂停 boolean suspend = processDefinition.isSuspended(); if(suspend){ //如果暂停则激活,这里将流程定义下的所有流程实例全部激活 repositoryService.activateProcessDefinitionById(processDefinitionId,true, null); System.out.println("流程定义: "+processDefinitionId+"激活"); }else{ //如果激活则挂起,这里将流程定义下的所有流程实例全部挂起 repositoryService.suspendProcessDefinitionById(processDefinitionId,true, null); System.out.println("流程定义: "+processDefinitionId+"挂起"); } }
单个流程实例挂起、激活
@Test public void suspendOrActiveProcessInstance() { // 流程实例id String processInstanceId = ""; // 获取RunTimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //根据流程实例id查询流程实例 ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); boolean suspend = processInstance.isSuspended(); if(suspend){ //如果暂停则激活 runtimeService.activateProcessInstanceById(processInstanceId); System.out.println("流程实例: "+processInstanceId+"激活"); }else{ //如果激活则挂起 runtimeService.suspendProcessInstanceById(processInstanceId); System.out.println("流程实例: "+processInstanceId+"挂起"); } }
个人任务
分配方式
固定分配
在业务流程建模时Assignee指定固定负责人。 缺点:固化,只有指定的人可以执行该步操作。
表达式分配
UEL表达式
统一表达式语言
UEL-value
Assignee ${assignee} assignee 这个变量是 activiti 的一个流程变量。 或者 Assignee ${user.assignee} user 也是 activiti 的一个流程变量, user.assignee 表示通过调用 user 的 getter 方法获取值。
UEL-method
Assignee ${UserBean.getUserId()} userBean 是 spring 容器中的一个 bean,表示调用该 bean 的 getUserId()方法。
两者结合
${ldapService.findManagerForEmployee(emp)} ldapService 是 spring 容器的一个 bean, findManagerForEmployee 是该 bean 的一个方法, emp 是 activiti流程变量, emp 作为参数传到 ldapService.findManagerForEmployee 方法中。
条件判断
表达式支持解析基础类型、 bean、 list、 array 和 map,也可作为条件判断。 如下: ${order.price > 100 && order.price < 250}
使用流程变量分配任务
//启动流程实例时设计流程变量 //定义流程变量 Map<String, Object> variables = new HashMap<String, Object>(); //设置流程变量assignee variables.put("assignee", "张三"); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables); 由于使用了表达式分配,必须保证在任务执行过程表达式执行成功,比如: 某个任务使用了表达式${order.price > 100 && order.price < 250},当执行该任务时必须保证 order 在流程变量中存在,否则 activiti 异常。
监听器分配
任务监听器是发生对应的任务相关事件时执行自定义 java 逻辑 或表达式。 任务相当事件包括: Create:任务创建后触发 Assignment:任务分配后触发 Delete:任务完成后触发 All:所有事件发生都触发 定义任务监听类,且类必须实现 org.activiti.engine.delegate.TaskListener 接口 public class MyTaskListener implements TaskListener { @Override public void notify(DelegateTask delegateTask) { //这里指定任务负责人 delegateTask.setAssignee("张三"); } }
任务查询
// 查询当前个人待执行的任务 @Test public void findPersonalTaskList() { // 流程定义key String processDefinitionKey = "holiday"; // 任务负责人 String assignee = "张三丰"; // 创建TaskService TaskService taskService = processEngine.getTaskService(); List<Task> list = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).includeProcessVariables().taskAssignee(assignee).list(); for (Task task : list) { System.out.println("----------------------------"); System.out.println("流程实例id: " + task.getProcessInstanceId()); System.out.println("任务id: " + task.getId()); System.out.println("任务负责人: " + task.getAssignee()); System.out.println("任务名称: " + task.getName()); } }
关联BusinessKey
1、创建RuntimeService对象 2、创建TaskService对象 3、通过TaskService查询到个人任务 4、通过Task对象,获取流程实例id 5、通过流程实例id获取流程实例对象 6、通过流程实例对象获取BusinessKey 7、通过BusinessKey关联业务系统,获取对应数据
办理任务
流程变量详解
定义
流程变量就是 activiti 在管理工作流时根据管理需要而设置的变量。 比如在请假流程流转时如果请假天数大于 3 天则由总经理审核,否则由人事直接审核, 请假天数就可以设置为流程变量,在流程流转时使用。
类型
作用域
流程变量的默认作用域时一个流程实例(global变量) 全局变量中的变量不允许重复,设置相同的变量名称,后设置的的值会覆盖之前设置的值。 也还可以是一个任务或一个执行实例(local变量) Local 变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。 Local 变量名也可以和 global 变量名相同,没有影响。
使用方法
1、设置流程变量 2、通过 UEL 表达式使用流程变量 1)可以在 assignee 处设置 UEL 表达式,表达式的值为任务的负责人比如: ${assignee}, assignee 就是一个流程 变量名称。 Activiti 获取 UEL 表达式的值 ,即流程变量 assignee 的值 ,将 assignee 的值作为任务的负责人进行任务分配 2)可以在连线上设置 UEL 表达式,决定流程走向 比如: ${price>=10000}和${price<10000}: price 就是一个流程变量名称, uel 表达式结果类型为布尔类型
全局变量使用
场景
员工创建请假申请单,由部门经理审核,部门经理审核通过后请假 3 天及以下由人事经理直接审核, 3 天以上先由总经理审核,总经理审核通过再由人事经理存档。
流程定义 设置条件
设置流程变量
启动时设置
// 启动流程时设置流程变量,作用域为全局 @Test public void startProcessInstance() { // 流程定义key String processDefinitionKey = ""; Holiday holiday = new Holiday(); holiday.setNum(3); // 定义流程变量 Map<String, Object> variables = new HashMap<String, Object>(); //变量名是num,变量值是holiday.getNum(),变量名也可以是一个对象 variables.put("num", holiday.getNum()); RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables); System.out.println("流程实例id:"+processInstance.getProcessInstanceId()); }
任务办理时设置
在完成任务时设置流程变量,该流程变量只有在该任务完成后其它结点才可使用该变量,它的作用域是整个流程实例,如果设置的流程变量的 key 在流程实例中已存在相同的名字则后设置的变量替换前边设置的变量。 // 办理任务时设置流程变量 @Test public void completTask() { //任务id String taskId = ""; TaskService taskService = processEngine.getTaskService(); Holiday holiday = new Holiday(); holiday.setNum(4); // 定义流程变量 Map<String, Object> variables = new HashMap<String, Object>(); //变量名是holiday,变量值是holiday对象 variables.put("holiday", holiday); taskService.complete(taskId, variables); }
通过当前流程实例设置
//通过流程实例 id 设置全局变量,该流程实例必须未执行完成。 public void setGlobalVariableByExecutionId(){ //当前流程实例执行 id,通常设置为当前执行的流程实例 String executionId="2601"; RuntimeService runtimeService = processEngine.getRuntimeService(); Holiday holiday = new Holiday(); holiday.setNum(3); //通过流程实例 id设置流程变量 runtimeService.setVariable(executionId, "holiday", holiday); //一次设置多个值 //runtimeService.setVariables(executionId, variables) }
通过当前任务设置
@Test public void setGlobalVariableByTaskId(){ //当前待办任务id String taskId="1404"; TaskService taskService = processEngine.getTaskService(); Holiday holiday = new Holiday(); holiday.setNum(3); //通过任务设置流程变量 taskService.setVariable(taskId, "holiday", holiday); //一次设置多个值 //taskService.setVariables(taskId, variables) }
注意事项
1、 如果 UEL 表达式中流程变量名不存在则报错。 2、 如果 UEL 表达式中流程变量值为空 NULL,流程不按 UEL 表达式去执行,而流程结束 。 3、 如果 UEL 表达式都不符合条件,流程结束 4、 如果连线不设置条件,会走 flow 序号小的那条线
操作数据库
设置流程变量会在当前执行流程变量表插入记录,同时也会在历史流程变量表也插入记录。
act_ru_variable
当前流程变量表 记录当前运行流程实例可使用的流程变量,包括 global 和 local 变量 Id_:主键 Type_:变量类型 Name_:变量名称 Execution_id_:所属流程实例执行 id, global 和 local 变量都存储 Proc_inst_id_:所属流程实例 id, global 和 local 变量都存储 Task_id_:所属任务 id, local 变量存储 Bytearray_: serializable 类型变量存储对应 act_ge_bytearray 表的 id Double_: double 类型变量值 Long_: long 类型变量值 Text_: text 类型变量值
act_hi_varinst
历史流程变量表 记录所有已创建的流程变量,包括 global 和 local 变量 字段意义参考当前流程变量表。
设置local流程变量
任务办理时设置
任务办理时设置 local 流程变量,当前运行的流程实例只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用,可以通过查询历史任务查询。 设置作用域为任务的 local 变量,每个任务可以设置同名的变量,互不影响。 // 办理任务时设置local流程变量 @Test public void completTask() { //任务id String taskId = ""; TaskService taskService = processEngine.getTaskService(); // 定义流程变量 Map<String, Object> variables = new HashMap<String, Object>(); Holiday holiday = new Holiday (); holiday.setNum(3); // 定义流程变量 Map<String, Object> variables = new HashMap<String, Object>(); //变量名是holiday,变量值是holiday对象 variables.put("holiday", holiday); // 设置local变量,作用域为该任务 taskService.setVariablesLocal(tasked, variables); taskService.complete(taskId); }
通过当前任务设置
任务 id 必须是当前待办任务 id, act_ru_task 中存在。 @Test public void setLocalVariableByTaskId(){ //当前待办任务id String taskId="1404"; TaskService taskService = processEngine.getTaskService(); Holiday holiday = new Holiday (); holiday.setNum(3); //通过任务设置流程变量 taskService.setVariableLocal(taskId, "holiday", holiday); //一次设置多个值 //taskService.setVariablesLocal(taskId, variables) }
组任务
Candidate-users 候选人
在流程定义中在任务结点的 assignee 固定设置任务负责人,在流程定义时将参与者固定设置在.bpmn 文件中,如果临时任务负责人变更则需要修改流程定义,系统可扩展性差。 针对这种情况可以给任务设置多个候选人,可以从候选人中选择参与者来完成任务。
设置候选人
办理组任务
流程
第一步:查询组任务 指定候选人,查询该候选人当前的待办任务。候选人不能办理任务。 第二步:拾取(claim)任务 该组任务的所有候选人都能拾取。 将候选人的组任务,变成个人任务。原来候选人就变成了该任务的负责人。 ***如果拾取后不想办理该任务? 需要将已经拾取的个人任务归还到组里边,将个人任务变成了组任务。 第三步:查询个人任务 查询方式同个人任务部分,根据 assignee 查询用户负责的个人任务。 第四步:办理个人任务
步骤
用户查询组任务
@Test public void findGroupTaskList() { // 流程定义key String processDefinitionKey = "holiday4"; // 任务候选人 String candidateUser = "zhangsan"; // 创建TaskService TaskService taskService = processEngine.getTaskService(); //查询组任务 List<Task> list = taskService.createTaskQuery()//.processDefinitionKey(processDefinitionKey) .taskCandidateUser(candidateUser)//根据候选人查询 .list(); for (Task task : list) { System.out.println("----------------------------"); System.out.println("流程实例id: " + task.getProcessInstanceId()); System.out.println("任务id: " + task.getId()); System.out.println("任务负责人: " + task.getAssignee()); System.out.println("任务名称: " + task.getName()); } }
用户拾取组任务
@Test public void claimTask(){ TaskService taskService = processEngine.getTaskService(); //要拾取的任务id String taskId = "6302"; //任务候选人id String userId = "lisi"; //拾取任务 //即使该用户不是候选人也能拾取(建议拾取时校验是否有资格) //校验该用户有没有拾取任务的资格 Task task = taskService.createTaskQuery().taskId(taskId) .taskCandidateUser(userId)//根据候选人查询 .singleResult(); if(task!=null){ taskService.claim(taskId, userId); System.out.println("任务拾取成功"); } }
查询代办任务
@Test public void findPersonalTaskList() { // 流程定义key String processDefinitionKey = "holiday4"; // 任务负责人 String assignee = "zhangsan"; // 创建TaskService TaskService taskService = processEngine.getTaskService(); List<Task> list = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey) .taskAssignee(assignee).list(); for (Task task : list) { System.out.println("----------------------------"); System.out.println(" 流 程 实 例 id : " + task.getProcessInstanceId()); System.out.println("任务id: " + task.getId()); System.out.println("任务负责人: " + task.getAssignee()); System.out.println("任务名称: " + task.getName()); } }
办理任务
说明:建议完成任务前校验该用户是否是该任务的负责人。 /**完成任务*/ @Test public void completeTask(){ //任务ID String taskId = "12304"; processEngine.getTaskService().complete(taskId); System.out.println("完成任务: "+taskId); }
归还任务
//如果个人不想办理该组任务,可以归还组任务,归还后该用户不再是该任务的负责人 // 归还组任务,由个人任务变为组任务,还可以进行任务交接 @Test public void setAssigneeToGroupTask() { // 查询任务使用TaskService TaskService taskService = processEngine.getTaskService(); // 当前待办任务 String taskId = "6004"; // 任务负责人 String userId = "zhangsan2"; // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务 Task task = taskService.createTaskQuery().taskId(taskId).taskAssignee(userId).singleResult(); if (task != null) { // 如果设置为null,归还组任务,该 任务没有负责人 taskService.setAssignee(taskId, null); } } //也可以通过 setAssignee 方法将任务委托给其它用户负责,注意被委托的用户可以不是候选人(建议不要这样使用)
任务交接
@Test public void setAssigneeToCandidateUser() { // 查询任务使用TaskService TaskService taskService = processEngine.getTaskService(); // 当前待办任务 String taskId = "6004"; // 任务负责人 String userId = "zhangsan2"; // 将此任务交给其它候选人办理该 任务 String candidateuser = "zhangsan"; // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务 Task task = taskService.createTaskQuery().taskId(taskId).taskAssignee(userId).singleResult(); if (task != null) { taskService.setAssignee(taskId, candidateuser); } }
操作数据表
act_ru_task
任务执行表,记录当前执行的任务,由于该任务当前是组任务,所有assignee 为空,当拾取任务后该字段就是拾取用户的 id
act_ru_identitylink
任务参与者,记录当前参考任务用户或组,当前任务如果设置了候选人,会向该表插入候选人记录,有几个候选就插入几个
act_hi_identitylink
向 act_ru_identitylink 插入记录的同时也会向历史表插入记录。
网关
排他网关
定义
使用
并行网关
定义
使用
包含网关
定义
使用