目录
Flowable
表结构概览:
数据库
(1)Flowable的所有数据库表都以ACT_开头。第二部分是说明表用途的两字符标示符。服务API的命名也大略符合这个规则。
(2)ACT_RE_: 'RE’代表repository。带有这个前缀的表包含“静态”信息,例如流程定义与流程资源(图片、规则等)。
(3)ACT_RU_: 'RU’代表runtime。这些表存储运行时信息,例如流程实例(process instance)、用户任务(user task)、变量(variable)、作业(job)等。Flowable只在流程实例运行中保存运行时数据,并在流程实例结束时删除记录。这样保证运行时表小和快。
(4)ACT_HI_: 'HI’代表history。这些表存储历史数据,例如已完成的流程实例、变量、任务等。
(5)ACT_GE_: 通用数据。在多处使用。
1)通用数据表(2个)
- act_ge_bytearray:二进制数据表,如流程定义、流程模板、流程图的字节流文件;
- act_ge_property:属性数据表(不常用);
2)历史表(8个,HistoryService接口操作的表)
- act_hi_actinst:历史节点表,存放流程实例运转的各个节点信息(包含开始、结束等非任务节点);
- act_hi_attachment:历史附件表,存放历史节点上传的附件信息(不常用);
- act_hi_comment:历史意见表;
- act_hi_detail:历史详情表,存储节点运转的一些信息(不常用);
- act_hi_identitylink:历史流程人员表,存储流程各节点候选、办理人员信息,常用于查询某人或部门的已办任务;
- act_hi_procinst:历史流程实例表,存储流程实例历史数据(包含正在运行的流程实例);
- act_hi_taskinst:历史流程任务表,存储历史任务节点;
- act_hi_varinst:流程历史变量表,存储流程历史节点的变量信息;
3)用户相关表(4个,IdentityService接口操作的表)
- act_id_group:用户组信息表,对应节点选定候选组信息;
- act_id_info:用户扩展信息表,存储用户扩展信息;
- act_id_membership:用户与用户组关系表;
- act_id_user:用户信息表,对应节点选定办理人或候选人信息;
4)流程定义、流程模板相关表(3个,RepositoryService接口操作的表)
- act_re_deployment:部属信息表,存储流程定义、模板部署信息;
- act_re_procdef:流程定义信息表,存储流程定义相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;
- act_re_model:流程模板信息表,存储流程模板相关描述信息,但其真正内容存储在act_ge_bytearray表中,以字节形式存储;
5)流程运行时表(6个,RuntimeService接口操作的表)
-
act_ru_task:运行时流程任务节点表,存储运行中流程的任务节点信息,重要,常用于查询人员或部门的待办任务时使用;
-
act_ru_event_subscr:监听信息表,不常用;
-
act_ru_execution:运行时流程执行实例表,记录运行中流程运行的各个分支信息(当没有子流程时,其数据与act_ru_task表数据是一一对应的);
-
act_ru_identitylink:运行时流程人员表,重要,常用于查询人员或部门的待办任务时使用;
-
act_ru_job:运行时定时任务数据表,存储流程的定时任务信息;
-
act_ru_variable:运行时流程变量数据表,存储运行中的流程各节点的变量信息;
-
流程引擎API与服务
引擎API是与Flowable交互的最常用手段。总入口点是ProcessEngine。
-
RepositoryService很可能是使用Flowable引擎要用的第一个服务。这个服务提供了管理与控制部署(deployments)与流程定义(process - definitions)的操作。管理静态信息。
-
RuntimeService用于启动流程定义的新流程实例。
-
IdentityService很简单。它用于管理(创建,更新,删除,查询……)组与用户。
-
FormService是可选服务。也就是说Flowable没有它也能很好地运行,而不必牺牲任何功能。
-
HistoryService暴露Flowable引擎收集的所有历史数据。要提供查询历史数据的能力。
-
ManagementService通常在用Flowable编写用户应用时不需要使用。它可以读取数据库表与表原始数据的信息,也提供了对作业(job)的查询与管理操作。
-
DynamicBpmnService可用于修改流程定义中的部分内容,而不需要重新部署它。例如可以修改流程定义中一个用户任务的办理人设置,或者修改一个服务任务中的类名。
接下来使用之前的请假流程图,上代码:
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
/**
* TestFlowable
*
* @Author
* @Date: 2021/10/17 23:35
* @Version 1.0
*/
@Slf4j
public class TestFlowable {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private org.flowable.engine.TaskService taskService;
@Autowired
private org.flowable.engine.IdentityService identityService;
public void createDeploymentZip() {
/*
* @Date: 2021/10/17 23:38
* Step 1: 部署xml(压缩到zip形式,直接xml需要配置相对路径,麻烦,暂不用)
*/
try {
File zipTemp = new File("f:/leave_approval.bpmn20.zip");
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipTemp));
Deployment deployment = repositoryService
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
log.info("部署成功:{}", deployment.getId());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/*
* @Date: 2021/10/17 23:40
* Step 2: 查询部署的流程定义
*/
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").list();
List<ProcessDefinition> pages = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
/*
* @Date: 2021/10/17 23:40
* Step 3: 启动流程,创建实例
*/
String processDefinitionKey = "leave_approval";//流程定义的key,对应请假的流程图
String businessKey = "schoolleave";//业务代码,根据自己的业务用
Map<String, Object> variablesDefinition = new HashMap<>();//流程变量,可以自定义扩充
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variablesDefinition);
log.info("启动成功:{}", processInstance.getId());
/*
* @Date: 2021/10/17 23:40
* Step 4: 查询指定流程所有启动的实例列表
* 列表,或 分页 删除
*/
List<Execution> executions = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").list();
List<Execution> executionPages = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
// runtimeService.deleteProcessInstance(processInstanceId, deleteReason); //删除实例
/*
* @Date: 2021/10/17 23:40
* Step 5: 学生查询可以操作的任务,并完成任务
*/
String candidateGroup = "stu_group"; //候选组 xml文件里面的 flowable:candidateGroups="stu_group"
List<Task> taskList = taskService.createTaskQuery().taskCandidateGroup(candidateGroup).orderByTaskCreateTime().desc().list();
for (Task task : taskList) {
// 申领任务
taskService.claim(task.getId(), "my");
// 完成
taskService.complete(task.getId());
}
/*
* @Date: 2021/10/17 23:40
* Step 6: 老师查询可以操作的任务,并完成任务
*/
String candidateGroupTe = "te_group"; //候选组 xml文件里面的 flowable:candidateGroups="te_group"
List<Task> taskListTe = taskService.createTaskQuery().taskCandidateGroup(candidateGroupTe).orderByTaskCreateTime().desc().list();
for (Task task : taskListTe) {
// 申领任务
taskService.claim(task.getId(), "myte");
// 完成
Map<String, Object> variables = new HashMap<>();
variables.put("command","agree"); //携带变量,用于网关流程的条件判定,这里的条件是同意
taskService.complete(task.getId(), variables);
}
/*
* @Date: 2021/10/18 0:17
* Step 7: 历史查询,因为一旦流程执行完毕,活动的数据都会被清空,上面查询的接口都查不到数据,但是提供历史查询接口
*/
// 历史流程实例
List<HistoricProcessInstance> historicProcessList = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave_approval").list();
// 历史任务
List<HistoricTaskInstance> historicTaskList = historyService.createHistoricTaskInstanceQuery().processDefinitionKey("leave_approval").list();
// 实例历史变量 , 任务历史变量
// historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId);
// historyService.createHistoricVariableInstanceQuery().taskId(taskId);
// *****************************************************分隔符********************************************************************
// *****************************************************分隔符********************************************************************
// 可能还需要的API
// 移动任务,人为跳转任务
// runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
// .moveActivityIdTo(currentActivityTaskId, newActivityTaskId).changeState();
// 如果在数据库配置了分组和用户,还会用到
List<User> users = identityService.createUserQuery().list(); //用户查询,用户id对应xml 里面配置的用户
List<Group> groups = identityService.createGroupQuery().list(); //分组查询,分组id对应xml 里面配置的分组 如 stu_group,te_group 在表里是id的值
// 另外,每个查询后面都可以拼条件,内置恁多查询,包括模糊查询,大小比较都有
}
}
流程数据复制:流程分类和流程模型(发布前)
---------------------- 流程分类、模型定义(未部署) 复制到测试环境 start ----------------------------------------------------------
-- 1. wf_category
SELECT category_id,category_name,code,remark,del_flag,create_by,create_time,update_by,update_time FROM wf_category order by category_id desc ;
-- 2. 模型定义: 依赖外键 ACT_GE_BYTEARRAY
-- 2-2 ACT_RE_MODEL
SELECT RES.* from ACT_RE_MODEL RES WHERE RES.VERSION_ = (select max(VERSION_) from ACT_RE_MODEL where KEY_ = RES.KEY_) order by RES.CREATE_TIME_ desc ;
-- 2-1 act_re_model#editor_source_value_id_`
select * from ACT_GE_BYTEARRAY where ID_ = '540307134837423298' ;
---------------------- 流程分类、模型定义(未部署) 复制到测试环境 end ----------------------------------------------------------
删除流程数据:慎重
---------------------- 删除我的待办 start ----------------------------------------------------------
-- 1. 查看进行中的流程实例
select * from act_ru_execution where start_time_ <= '2024-03-14 18:50:07' ;
-- 2. 进行中的任务
select * from act_ru_task
where proc_inst_id_ in (
select proc_inst_id_ from act_ru_execution where start_time_ <= '2024-03-14 18:50:07' ) ;
-- 3. act_ru_identitylink
select * from act_ru_identitylink
where task_id_ in (select id_ from act_ru_task
where proc_inst_id_ in (
select proc_inst_id_ from act_ru_execution where start_time_ <= '2024-03-14 18:50:07' )) ;
SELECT RES.* from ACT_RE_MODEL RES WHERE RES.VERSION_ = (select max(VERSION_) from ACT_RE_MODEL where KEY_ = RES.KEY_) order by RES.CREATE_TIME_ desc ;
-- 4. 流程变量 依赖act_ru_identitylink
select * from act_ru_variable
where proc_inst_id_ in (
select proc_inst_id_ from act_ru_execution where start_time_ <= '2024-03-14 18:50:07' ) ;
--5. 最后 act_ru_execution
select proc_inst_id_ from act_ru_execution where start_time_ <= '2024-03-14 18:50:07' )
---------------------- 删除我的待办 end ----------------------------------------------------------
---------------------- 删除我的已办 start ----------------------------------------------------------
-- 1. 查看我的已办任务 中的流程实例# proc_inst_id_
select * from ACT_HI_TASKINST RES WHERE RES.start_TIME_ <= '2024-03-14 18:50:07' ;
--2.
delete from act_hi_identitylink WHERE proc_inst_id_ in (
select proc_inst_id_ from ACT_HI_TASKINST RES WHERE RES.start_TIME_ <= '2024-03-14 18:50:07' );
---------------------- 删除我的已办 end----------------------------------------------------------
概念
流程定义,插入:act_re_procdef 和 act_ge_bytearray
流程部署,插入:act_re_develop
-
一个自定义的业务流程,跟踪
-
通过 RES.VERSION_ = (select max(VERSION_) 全局搜索 找到了 ProcessDefinition.xml 中
传参 是通过 ProcessDefinitionQueryImpl 传的, 其实就相当于是一个 domain 类 : , 取个奇怪的名字唬人
工作流分类:
参考: link
网关图标 :
一、会签流程
- 适用场景
会签是一种联合审批的特殊审批节点,可理解为一种多人投票机制,一个任务需要多个人同时处理,然后汇总多个人的意见,决定流程下一步该如何执行。流程设计时,若会签审批节点中设置多个参与人,流程运行时,会签节点任务需要多人共同处理,然后汇总多人的处理意见,决定会签节点的处理结果。
例如:员工发起采购申请,需经过多名领导共同审批后,才决定是否可以采购,只要其中1名领导不同意,便退回申请人。
- 具体规则
会签分并行会签和顺序会签两种:
(1)并行会签
指同一个审批节点同时设置多个人,如ABC三人,三人会同时收到待办,需全部同意之后,审批才可到下一审批节点。
(2)顺序会签
指同一个审批设置多个人,如ABC三人,三人按顺序人依次收到待办,即A先审批,A提交后B才能审批,需全部同意之后,审批才可下一审批节点。
- 设置方法
二、或签流程
- 适用场景
一个流程审批节点里有多个处理人,任意一个人处理后就能进入下一个节点。
例如:员工发起采购申请,提交给多名领导审批,只要有一名领导同意即可提交到下一节点。
- 具体规则
指同一个审批节点设置多个人,如ABC三人,三人会同时收到审批待办,只要其中任意一人审批即可到下一审批节点。
- 设置方法
分支流程
- 适用场景
分支流程的适用场景:流程中某个节点后有多个分支节点,根据不同条件执行不同的分支,即不同的数据会走不同的流程路径。
例如:请假申请,可根据请假天数走不同的审批路径,3天以内请假由人力资源审批,超过3天的请假由公司领导审批。
- 具体规则
(1)分支流程使用【排他网关】,连接在【排他网关】后面的线条,有分流作用,点击线条可设置流转条件。
(2)上一节点点击【提交】后,根据【排他网关】设置按顺序判断所有分支流转条件,出现满足流转条件时,就进入相应的分支节点。
(3)如果不设置,表示无条件限制,会直接进入该节点;如果设置了流转条件,则只有满足条件才会进入该节点;如果所有条件都不满足,则会流转到设置的默认访问;如果有多个条件满足,则会按设置的条件顺序判断,直到出现第一个满足的条件,就进入该节点。
- 设置方法
四、并行流程
- 适用场景
并行流程适用场景:流程中某个节点后有多个节点需要并行执行,节点的处理人需同时收到流程待办,各自处理待办,当所有分支线上的节点都执行后,流程才进入到下一个节点。
例如:员工提交请假申请,同时送部门经理和人力资源部审批,需要部门经理和人力资源全部审批通过后,才算流程审批通过。
- 具体规则
连接在【并行网关】后面的线条,才有并流作用;
上一节点点击【提交】后,无论线条是否设置条件,都自动进入所有的分支节点。当所有分支都执行后,才进入这些分支同时连接的下一个节点;
- 设置方法
第二步:源码及表结构对应关系
https://tkjohn.github.io/flowable-userguide/
第三步 部署一次流程
第四步 启动一个流程实例
关注其中4张表:
- act_ru_execution 运行时 流程执行实例
- act_ru_identitylink 运行时 流程实例关联用户表,结点流转 insert (多条)
- act_ru_task 运行时 流程实例关联的任务,结点流转 update (一个实例,维持一条)
- act_ru_variable 运行时 流程实例关联变量
act_ru_execution
act_ru_identitylink #proc_inst_id => act_ru_execution (ID_)
流转到下一结点后,插入新的记录:当前任务表任务结点处理人
IdentitylinkType 常量类 流程实例 用户常量类
3. act_ru_task 运行时 流程实例关联的任务
流转后下一个结点后,act_ru_task 表数据是更新,当前流程实例,处理到的结点;
原先的任务数据 进入 act_hi_task ;
流程流转过程# act_ru_task 是更新,不是新增: 7508 -> 10003 总经理审批
-
act_ru_variable 运行时 流程实例关联变量
-
act_hi_xxxx 上面四个
-
可以添加流程变量
第六步 流程监听器与任务监听器
首先创建流程监听器和任务监听器的实体类,个人比较喜欢使用Delegate Expression方式,其他两种方式也可以
流程监听器
package org.mpc.final_activiti;
import java.io.Serializable;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
/**
*
* 可以使用 CLASS ,EXPRESSION,DELEGATE EXPRESSSION三种方式来创建监听器,这里使用第三种方式,其他两种方式和
* 在servicetask中的使用方式相同
*
* */
public class ExectuionListenerDemo implements Serializable, ExecutionListener {
/**
* @Fields serialVersionUID : TODO(用一句话描述这个变量表示什么)
*/
private static final long serialVersionUID = 8513750196548027535L;
private Expression message;
public Expression getMessage() {
return message;
}
public void setMessage(Expression message) {
this.message = message;
}
@Override
public void notify(DelegateExecution execution) throws Exception {
System.out.println("流程监听器" + message.getValue(execution));
}
}
任务监听器
package org.mpc.final_activiti;
import java.io.Serializable;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.TaskListener;
/**
*
* 任务监听器,实现TaskListener接口
*
* */
public class TaskListenerDemo implements Serializable, TaskListener {
private Expression arg;
public Expression getArg() {
return arg;
}
public void setArg(Expression arg) {
this.arg = arg;
}
@Override
public void notify(DelegateTask delegateTask) {
System.out.println("任务监听器:" + arg.getValue(delegateTask));
}
}
这两个监听器只是简单的表明了自己的身份,并打印出在流程中注入给他们的值
接着是流程定义图
展示一下配置结果的xml文件,特别注意一下加注释的地方
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="myProcess" name="My process" isExecutable="true">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程启动]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
<startEvent id="startevent1" name="Start"></startEvent>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[排他网关开始]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[排他网关结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</exclusiveGateway>
<sequenceFlow id="flow3" sourceRef="startevent1" targetRef="exclusivegateway1"></sequenceFlow>
<userTask id="usertask2" name="User Task" activiti:assignee="${user}">
<extensionElements>
<activiti:taskListener event="create" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[任务启动]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="assignment" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[分配人员]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<activiti:taskListener event="complete" delegateExpression="${mytaskListener}">
<activiti:field name="arg">
<activiti:string><![CDATA[任务完成]]></activiti:string>
</activiti:field>
</activiti:taskListener>
<!-- 在可视化工具中无法给usertask加上流程监听器,但是,我们在xml中可以自己敲进去· -->
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程启动任务]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[流程关闭任务]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<!-- ........................................................................................................................................ -->
</extensionElements>
</userTask>
<sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="usertask2">
<extensionElements>
<activiti:executionListener event="take" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[从排他网关到用户任务,好长的一段路]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</sequenceFlow>
<intermediateThrowEvent id="noneintermediatethrowevent1" name="NoneThrowEvent">
<extensionElements>
<activiti:executionListener event="start" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[中间事件开始]]></activiti:string>
</activiti:field>
</activiti:executionListener>
<activiti:executionListener event="end" delegateExpression="${myprocessListener}">
<activiti:field name="message">
<activiti:string><![CDATA[中间事件结束]]></activiti:string>
</activiti:field>
</activiti:executionListener>
</extensionElements>
</intermediateThrowEvent>
<sequenceFlow id="flow5" sourceRef="usertask2" targetRef="noneintermediatethrowevent1"></sequenceFlow>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow6" sourceRef="noneintermediatethrowevent1" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
<bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="160.0" y="180.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="240.0" y="130.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="325.0" y="123.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="noneintermediatethrowevent1" id="BPMNShape_noneintermediatethrowevent1">
<omgdc:Bounds height="35.0" width="35.0" x="475.0" y="133.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="555.0" y="133.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="195.0" y="197.0"></omgdi:waypoint>
<omgdi:waypoint x="260.0" y="170.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="280.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="325.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5">
<omgdi:waypoint x="430.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="475.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="510.0" y="150.0"></omgdi:waypoint>
<omgdi:waypoint x="555.0" y="150.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
第七步 候选人组和抢单-拾取任务
3-1. 抢单后,不想做了,归还到任务池,否则别人也没法抢
3-2. 抢单后,不想做了,不归还到任务池,直接交接给指定人
- 候选人组
删除流程数据
-
我的申请
select * from ACT_HI_PROCINST RES where RES.id_ = 531206205654712100 -
我的待办
SELECT RES.* from ACT_RU_TASK RES WHERE RES.SUSPENSION_STATE_ = 1 and (RES.ASSIGNEE_ = ‘197’ or ( RES.ASSIGNEE_ is null and exists(select LINK.ID_ from ACT_RU_IDENTITYLINK LINK where LINK.TASK_ID_ = RES.ID_ and LINK.TYPE_ = ‘candidate’ and (LINK.USER_ID_ = ‘197’ or ( LINK.GROUP_ID_ IN ( ‘ROLE1004’ , ‘DEPT1071’ ) ) )))) order by RES.CREATE_TIME_ desc LIMIT 10 OFFSET 0 ;