Activiti7工作流引擎:Hello World

Posted vbirdbest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Activiti7工作流引擎:Hello World相关的知识,希望对你有一定的参考价值。

一:工作流开发步骤

  1. 定义流程:使用IDEA插件actiBPM定义流程文件.bpmn
  2. 部署流程:将.bpmn文件保存到数据库中。
  3. 启动流程:启动工作流中的第一个任务节点,即提出申请。
  4. 办理流程:审批当前任务流程,完成最后一个任务就算结束工作流。

二:定义流程

New -> BpmnFile 创建.bpmn文件,设置Id属性(每个.bpmn文件都要设置不同的Id值),Name属性表示流程的名字或者每个任务节点的名字。将鼠标放在每个符号的中间就会有一个黑点此时就可以拖出一条顺序流Sequence Flow线来连接。

  • StartEvent:表示工作流的开始。
  • UserTask:表示每个任务节点。
  • EndEvent:表示工作流的结束。

    使用UEL表达式为每个UserTask指定负责人Assignee,也可以直接写死例如“张三”但通常都不会写死。

三:部署流程

部署流程就是将.bpmn文件保存到数据库中,.bpmn属于资源部署,所以使用RepositoryService。

@Test
public void delopyBpmn() 
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    Deployment deploy = processEngine.getRepositoryService()
            .createDeployment()
            .addClasspathResource("bpmn/offwork.bpmn")
            .name("请假流程")
            .deploy();
    // DeploymentEntity[id=1, name=请假流程]
    System.out.println(deploy);

流程定义部署表:每部署一次就会插入一条记录。

insert into ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_) 
values('1', '请假流程', null, null, '', '2021-12-08 20:20:27.382', null);


流程定义表:每部署一个新的.bpmn文件都会插入一条记录。流程定义文件中的Id值会保存到KEY_字段中。

-- 流程定义Process Definition
-- ACT_RE_PROCDEF.DEPLOYMENT_ID_ = ACT_RE_DEPLOYMENT.id
insert into ACT_RE_PROCDEF(ID_, REV_, CATEGORY_, NAME_, KEY_, VERSION_, DEPLOYMENT_ID_, 
RESOURCE_NAME_, DGRM_RESOURCE_NAME_, DESCRIPTION_, HAS_START_FORM_KEY_, 
HAS_GRAPHICAL_NOTATION_ , SUSPENSION_STATE_, TENANT_ID_, ENGINE_VERSION_) values 
('offwork:1:3', 1, 'http://www.activiti.org/test', '请假流程', 'offwork', 1, '1', 
'bpmn/offwork.bpmn', null, null, false, true, 1, '', null);


流程资源表:ACT_GE_BYTEARRAY.BYTES_字段的数据类型为longblob,存储的是二进制.bpmn文件。

-- ACT_GE_BYTEARRAY.DEPLOYMENT_ID_ = ACT_RE_DEPLOYMENT.id
insert into ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_, DEPLOYMENT_ID_, GENERATED_) values 
('2', 1, 'bpmn/offwork.bpmn', 'java.io.ByteArrayInputStream@3f07b12c(ByteArrayInputStream), 1', false, error);

六:查询流程定义

@Test
public void queryProcessDefinition() 
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    List<ProcessDefinition> processDefinitionList = processEngine.getRepositoryService()
            .createProcessDefinitionQuery()
            .processDefinitionKey("offwork")
            .list();

    for (ProcessDefinition processDefinition : processDefinitionList) 
        System.out.println("流程定义 id="+processDefinition.getId());
        System.out.println("流程定义 name="+processDefinition.getName());
        System.out.println("流程定义 key="+processDefinition.getKey());
        System.out.println("流程定义 Version="+processDefinition.getVersion());
        System.out.println("流程部署 Id ="+processDefinition.getDeploymentId());
    

SELECT 
	DISTINCT RES.*
FROM ACT_RE_PROCDEF RES
WHERE RES.KEY_ = 'offwork' order by RES.ID_ asc
LIMIT 2147483647 
OFFSET 0;

四:启动流程

启动流程实例时可以指定每个UserTask的负责人Assignee。

@Test
public void startProcessInstance() 
    Map<String, Object> assigneeMap = new HashMap<>();
    assigneeMap.put("apply", "张三");
    assigneeMap.put("pm", "傻经理");
    assigneeMap.put("hr", "狗人事");

	String businessKey = "1";

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    ProcessInstance processInstance = processEngine.getRuntimeService()
            .startProcessInstanceByKey("offwork", businessKey, assigneeMap);
    System.out.println(processInstance.getId());
    System.out.println(processInstance.getProcessInstanceId());
    System.out.println(processInstance.getProcessDefinitionId());

BusinessKey 业务Key

员工发起请假申请时一般都要填写请假开始时间、请假结束时间、请假理由等和具体业务相关的数据,Activiti的25张表只会保存审批流程相关的数据,不会保存具体业务的数据,具体业务的数据需要开发人员自己定义表结构,自己维护,但是Activiti提供了一个字段可以保存和业务相关的数据,这个字段叫ACT_RU_EXECUTION.BUSINESS_KEY_,通常我们会保存业务表的主键id,这样我们就可以通过BUSINESS_KEY_关联到员工的请假时间、请假原因等数据了。

流程定义ProcessDefinition和流程实例ProcessInstance

流程定义是定义.bpmn文件(相当于定义一个Java实体类文件Studeng.class),流程实例是根据流程定义文件发起一个具体的申请(相当于创建一个实例对象 Student zhangsan = new Student(“张三”))。

ACT_RU_VARIABLE:正在运行的变量表。

ACT_RU_EXECUTION

ACT_RU_TASK:正在运行的任务。

ACT_HI_TASKINST:历史任务实例表。

ACT_HI_PROCINST:历史流程实例表。

ACT_HI_IDENTITYLINK:流程的参与用户历史信息

四:查询正在进行的任务

@Test
public void testQueryRuTask() 
	// 查询哪个工作流下的哪个负责人对应的任务
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    List<Task> list = processEngine.getTaskService()
            .createTaskQuery()
            .processDefinitionKey("offwork")
            .taskAssignee("张三")
            .list();
    // [Task[id=2508, name=请假申请]]
    System.out.println(list);

SELECT 
	DISTINCT RES.*
FROM ACT_RU_TASK RES INNER JOIN ACT_RE_PROCDEF D ON RES.PROC_DEF_ID_ = D.ID_
WHERE RES.ASSIGNEE_ = '张三' and D.KEY_ = 'offwork' 
ORDER BY RES.ID_ ASC
LIMIT 2147483647 OFFSET 0;

五:办理(完成)流程

@Test
public void completeTask() 
	// insert into ACT_HI_TASKINST
	// insert into ACT_HI_ACTINST
	// insert into ACT_HI_IDENTITYLINK
	// insert into ACT_RU_TASK
	// insert into ACT_RU_IDENTITYLINK
	// delete from ACT_RU_TASK WHERE ID_ = '2508' and REV_ = 1;
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    TaskService taskService = processEngine.getTaskService();
    Task task = taskService
            .createTaskQuery()
            .processDefinitionKey("offwork")
            .taskAssignee("张三")
            .singleResult();
    taskService.complete(task.getId());

完成任务的核心逻辑:

  • delete当前完成的ACT_RU_TASK。
  • 将下一个任务insert到ACT_RU_TASK。
  • 保持当前操作的历史数据。

查询流程实例

流程在运行过程中可以查询流程实例的状态,当前运行结点等信息。

@Test
public void testQueryInstance() 
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    List<ProcessInstance> processInstances = processEngine.getRuntimeService()
            .createProcessInstanceQuery()
            .processDefinitionKey("offwork")
            .list();

    for (ProcessInstance processInstance : processInstances) 
        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());
    


SELECT 
	DISTINCT RES.* , 
	P.KEY_ as ProcessDefinitionKey, 
	P.ID_ as ProcessDefinitionId, 
	P.NAME_ as ProcessDefinitionName, 
	P.VERSION_ as ProcessDefinitionVersion, 
	P.DEPLOYMENT_ID_ as DeploymentId, 
	S.PROC_INST_ID_ AS PARENT_PROC_INST_ID_
 FROM ACT_RU_EXECUTION RES 
 INNER JOIN ACT_RE_PROCDEF P ON RES.PROC_DEF_ID_ = P.ID_ 
 LEFT JOIN ACT_RU_EXECUTION S ON RES.SUPER_EXEC_ = S.ID_
 WHERE RES.PARENT_ID_ is null and P.KEY_ = 'offwork' 
 ORDER BY RES.ID_ ASC
 LIMIT 2147483647 OFFSET 0;

七:删除部署

删除当前部署相关的各种数据。

// delete FROM ACT_RU_VARIABLE
// delete FROM ACT_GE_BYTEARRAY
// delete FROM ACT_RE_DEPLOYMENT
// delete FROM ACT_RU_IDENTITYLINK
// delete FROM ACT_RU_TASK
@Test
public void deleteDeployment() 
    String deploymentId = "1";
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    processEngine.getRepositoryService()
            .deleteDeployment(deploymentId, true);

七:查询历史活动

@Test
public void queryHistoryActivity() 
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    List<HistoricActivityInstance> activityInstanceList = processEngine.getHistoryService()
            .createHistoricActivityInstanceQuery()
            .processDefinitionId("offwork:1:3")
            .list();

    for (HistoricActivityInstance hi : activityInstanceList) 
        System.out.println(hi.getActivityId());
        System.out.println(hi.getActivityName());
        System.out.println(hi.getProcessDefinitionId());
        System.out.println(hi.getProcessInstanceId());
        System.out.println("<==========================>");
    

SELECT 
	RES.*
FROM ACT_HI_ACTINST RES
WHERE RES.PROC_DEF_ID_ = 'offwork:1:3' 
order by RES.ID_ asc
LIMIT 2147483647 OFFSET 0;

以上是关于Activiti7工作流引擎:Hello World的主要内容,如果未能解决你的问题,请参考以下文章

Activiti7工作流引擎:基础篇 Hello World

Activiti7工作流引擎:进阶篇 Activiti7与Spring整合

Activiti7工作流引擎:Activiti7自动生成表结构

Activiti7工作流引擎:进阶篇 SpringBoot整合工作流Activiti7

Activiti7工作流引擎:高阶篇 内嵌子流程 SubProcess

Activiti7工作流引擎:进阶篇 ProcessRuntime和TaskRuntime