【工作流】Spring Boot 项目与 Camunda 的整合
【一】Camunda 和主流流程引擎的对比
官网:https://camunda.com/
中文网站:http://camunda-cn.shaochenfeng.com/
【二】概念介绍
【1】Camunda 概念:
(1)流程(PROCESS): 通过工具建模最终生成的BPMN文件,里面有整个流程的定义
(2)流程实例(Instance):流程启动后的实例
(3)流程变量(Variables):流程任务之间传递的参数
(4)任务(TASK):流程中定义的每一个节点
(5)流程部署:将之前流程定义的.bpmn文件部署到工作流平台
【2】BPMN 概念
【三】环境准备
提前安装Java1.8以上的JRE或JDK
【1】安装流程设计器CamundaModeler【画图工具】
CamundaModeler是官方提供的一个流程设计器,用于编辑流程图和其他模型【表单】,也就是一个流程图的绘图工具。
注意:下载解压以后安装到非中文目录中,否则路径可以访问失败
(1)下载安装
(1)下载地址:https://camunda.com/download/modeler/
下载并解压
(2)安装
启动页面如下,Modeler支持Camunda7与Camunda8,在这里我们可以根据自己需求开展BPMN、DMN建模。
【2】CamundaModeler如何设计
(1)模型分类
选择不同的模型,例如BPMN,DMN, CMMN,它们展示的画布界面是不一样的
(1)BPMN(Business Process Model and Notation)
这是一种图形表示法,用于在业务流程模型中指定业务流程的业务步骤。BPMN的目标是支持业务流程的管理,无论是那些流程已经被自动化,还是尚未被自动化。BPMN创建了一个标准化的桥梁,通过公共视觉语言填补了业务策略与业务实施之间的鸿沟。
(2)DMN(Decision Model and Notation)
这是一种标准化的模型和表示法,用于定义和管理业务决策。DMN的目标是使决策模型变得更加透明和可理解,同时也能够自动化决策过程。
(3)Form
在Camunda中,表单用于在业务流程中收集和显示数据。Camunda支持两种类型的表单:生成的表单和自定义表单。生成的表单是由Camunda自动创建的,基于流程变量的类型和结构。自定义表单则允许开发人员自定义表单的外观和行为。
(2)事件分类(Event)
(3)活动分类(Activity)
活动是工作或任务的一个通用术语,一个活动可以是一个任务,还可以是一个当前流程的子处理流程;其次,你还可以为活动指定不听的类型
只介绍最常用的两种
(1)用户任务 (User Task)具体来说就是需要手动执行的任务,即需要我们写完业务代码后,调用代码 taskService.complete(taskId, variables); 才会完成的任务
(2)系统任务(Service Task)系统会自动帮我们完成的任务
(4)网关分类(GateWay)
网关用来处理决策,有几种常用的网关
分为这么几类,会根据我们传入的流程变量及设定的条件走
(1)排他网关(exclusive gateway)
这个网关只会走一个,我们走到这个网关时,会从上到下找第一个符合条件的任务往下走
(2)并行网关(Parallel Gateway)
这个网关不需要设置条件,会走所有的任务
(3)包含网关(Inclusive Gateway)
这个网关会走一个或者多个符合条件的任务
如上图包含网关,需要在网关的连线初设置表达式 condition,参数来自于流程变量
两个参数:switch2d 、 switch3d
如果 都为true,则走任务1,3
如果 switch2d 为true switch3d为false,则只走任务1
如果 switch3d 为true switch2d为false,则只走任务3
如果都为false,则直接走网关,然后结束
(5)表单传参(Form)
(6)监听器
(6)指派任务处理人
【3】安装web应用CamundaBPM【管理平台】
(1)介绍
Camunda BPM Run 是一个用于部署、运行和管理 Camunda BPM 平台的独立程序。它集成了 Camunda 引擎和 Web 应用程序,提供了一个方便的方式来启动和管理 Camunda BPM 平台。
具体来说,Camunda BPM Run 有以下作用:
(1)部署和管理 Camunda BPM 平台:Camunda BPM Run 提供了一个独立的运行时环境,您可以使用它来部署和管理 Camunda BPM 平台。它集成了 Camunda 引擎、Camunda Web 应用程序和数据库,使您可以方便地启动和配置整个平台。
(2)运行工作流和流程引擎:Camunda BPM Run 提供了一个工作流引擎,可以执行和管理业务流程。您可以使用 Camunda Modeler 创建和编辑 BPMN 流程模型,然后将其部署到 Camunda BPM Run 中进行执行。Camunda BPM Run 提供了任务管理、流程实例跟踪、变量管理等功能,使您可以轻松地追踪和管理工作流的执行状态。
(3)提供 Web 应用界面:Camunda BPM Run 包含一个集成了 Camunda Web 应用程序的 Web 服务器。通过该界面,您可以轻松地管理和监控流程的执行,查看任务列表、处理用户任务、查看流程实例的状态等。Web 应用程序还提供了一个用户任务表单引擎,可以定义和渲染用户任务的表单。
(4)支持扩展和集成:Camunda BPM Run 允许您利用 Camunda 引擎的扩展能力,通过编写插件或自定义扩展来满足特定的需求。它还提供了一些集成选项,可以与其他系统进行集成,例如数据库、消息队列和外部服务。
总之,Camunda BPM Run 提供了一个独立的运行时环境,使您可以轻松地部署、运行和管理 Camunda BPM 平台。它集成了 Camunda 引擎和 Web 应用程序,提供了丰富的功能和界面,支持管理工作流、流程实例和用户任务,并支持扩展和集成以满足特定需求。
(2)下载启动
(1)下载地址:https://downloads.camunda.cloud/release/camunda-bpm/run/7.17/
7.17支持jdk1.8,7.20不支持
(2)启动 Camunda BPM
进入解压后的目录,找到 bin 文件夹,使用以下命令启动 Camunda BPM:
cd /Library/Java/AllenCamunda/camunda-bpm-run-7.17.0
sh start.sh
(3)进入页面
账号密码:都是demo
(3)配置本地mysql数据库
(1)建库
连接本地mysql,为Camunda平台创建一个数据库模式,名称为camunda
(2)导入SQL脚本
将camunda 自带的40张数据库表初始化到本地mysql的库里,执行创建所有必需的表和默认索引的SQL DDL脚本。这些脚本可以在configuration/sql/create文件夹中找到。共2个脚本,都需要导入。
(3)配置数据源
找到安装目录下的camunda-bpm-run-7.15.0\configuration\default.yml文件,修改datasource的配置为mysql,将JDBC URL和登录凭据添加到配置文件中,如下:
url: jdbc:mysql://127.0.0.1:3306/camunda715?characterEncoding=UTF-8&useUnicode=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: root
(4)替换数据库驱动包
找到安装目录下的camunda-bpm-run-7.15.0\configuration\ userlib下,删除h2的驱动包,放置mysql的驱动包。
(5)重新启动camunda
关闭应用。然后启动
(6)登录验证
启动完成后,登录http://127.0.0.1:8080/camunda/app/admin/default/#/login,输入demo/demo账号登录
查看数据库act_id_user表,一条默认数据已经初始化了,说明camunda已经连接mysql成功了。
【四】基本案例
【1】入门案例
(1)绘制流程图
选择BPMN diagram
然后保存bpmn文件
(2)外置任务创建
基于java实现
(1)Maven引入相关依赖。
<properties>
<camunda.external-task-client.version>7.17.0</camunda.external-task-client.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-external-task-client</artifactId>
<version>${camunda.external-task-client.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
(2)创建外部主题订阅类
主题名应与上面创建的模板中配置的相同。
package com.zeeboomdog.camundatest.IntroductionDemo;
import java.util.logging.Logger;
import java.awt.Desktop;
import java.net.URI;
import org.camunda.bpm.client.ExternalTaskClient;
/**
* 主题任务订阅
*/
public class ChargeCardWorker {
private final static Logger LOGGER = Logger.getLogger(ChargeCardWorker.class.getName());
public static void main(String[] args) {
ExternalTaskClient client = ExternalTaskClient.create()
.baseUrl("http://localhost:8080/engine-rest")//web应用
.asyncResponseTimeout(10000)//超时时间
.build();
// 订阅外部主题任务
client.subscribe("charge-card")
.lockDuration(1000) // 超时时间 默认:20s
.handler((externalTask, externalTaskService) -> {
try {
// 业务逻辑
businessFun();
// 取得流程信息
String item = externalTask.getVariable("item");
Integer amount = externalTask.getVariable("amount");
// 完成以后打开这个页面
Desktop.getDesktop().browse(new URI("https://docs.camunda.org/get-started/quick-start/complete"));
} catch (Exception e) {
e.printStackTrace();
}
// Complete the task
externalTaskService.complete(externalTask);
}).open();
}
/**
* 业务逻辑方法
*/
private static void businessFun() {
// do nothing
}
}
(3)流程部署操作
部署成功后,可在Camunda中的cockpit查看
(4)发起流程
使用postman发起请求到BPM,触发请求,后台就会根据配置的流程完成
调用成功以后就会打开代码的配置页面:https://docs.camunda.org/get-started/quick-start/complete
【2】用户任务案例
(1)添加审批节点
Assignee表示处理人,现在使用默认的用户demo,groups指的是群组,users表示的是多个审批人
(2)配置表单
(3)部署流程
deploy部署,然后到camunda平台的cockpit查看,确认流程已经创建
进入tasklist,点击start process启动流程,选择要启动的流程
填写流程里配置的key,没有就不写,然后把流程form配置的3个参数加上,点击start
底部出现以下提示就表示启动成功
点击all tasks刷新一下,就能看到新启动的任务了
点击任务看一下,就能看到表单的参数信息,还有处理的历史记录history,还有diagram是流程信息(高亮的部分就是当前正处于的节点)
点击complete就代表对此节点进行审批,但是还没有配置网关,所以没法无论是否勾选同意都会走到刷卡的节点,接着看下一个案例
(4)测试流程
【3】网关任务实例
使用排他网关
判断付款金额的网关判断条件
付款审批的网关判断条件
【4】梳理最终的逻辑
(1)首先发起付款
(2)节点判断金额大小,决定是直接刷卡付款还是走审批
(3)如果是走付款审批,就会给指定的审批人创建任务,并把申请的参数发给审批人,审批人在后台进行审批
(4)如果审批同意,就会走到刷卡付款,触发项目里的外置任务进行付款,最终返回付款完成
(5)如果审批不同意,就会返回付款失败
【五】原理解析
【1】库表设计
(1)介绍
Camunda bpm流程引擎的数据库由多个表组成,表名都以ACT开头,第二部分是说明表用途的两字符标识。笔者在工作中用的Camunda7.11版本共47张表。体验环境:http://www.yunchengxc.com
(1)ACT_RE_: 'RE’表示流程资源存储,这个前缀的表包含了流程定义和流程静态资源(图片,规则等),共5张表。
(2)ACT_RU_: 'RU’表示流程运行时。 这些运行时的表,包含流程实例,任务,变量,Job等运行中的数据。 Camunda只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录, 这样运行时表的数据量最小,可以最快运行。共15张表。
(3)ACT_ID_: 'ID’表示组织用户信息,比如用户,组等,共6张表。
(4)ACT_HI_: 'HI’表示流程历史记录。 这些表包含历史数据,比如历史流程实例,变量,任务等,共18张表。
(5)ACT_GE_*: ‘GE’表示流程通用数据, 用于不同场景下,共3张表。
数据表的清单如下
在这里插入代码片
流程资源存储 act_re_case_def CMMN案例管理模型定义表
流程资源存储 act_re_decision_def DMN决策模型定义表
流程资源存储 act_re_decision_req_def 待确定
流程资源存储 act_re_deployment 流程部署表
流程资源存储 act_re_procdef BPMN流程模型定义表
流程运行时 act_ru_authorization 流程运行时收取表
流程运行时 act_ru_batch 流程执行批处理表
流程运行时 act_ru_case_execution CMMN案例运行执行表
流程运行时 act_ru_case_sentry_part 待确定
流程运行时 act_ru_event_subscr 流程事件订阅表
流程运行时 act_ru_execution BPMN流程运行时记录表
流程运行时 act_ru_ext_task 流程任务消息执行表
流程运行时 act_ru_filter 流程定义查询配置表
流程运行时 act_ru_identitylink 运行时流程人员表
流程运行时 act_ru_incident 运行时异常事件表
流程运行时 act_ru_job 流程运行时作业表
流程运行时 act_ru_jobdef 流程作业定义表
流程运行时 act_ru_meter_log 流程运行时度量日志表
流程运行时 act_ru_task 流程运行时任务表
流程运行时 act_ru_variable 流程运行时变量表
组织用户信息 act_id_group 群组信息表
组织用户信息 act_id_info 用户扩展信息表
组织用户信息 act_id_membership 用户群组关系表
组织用户信息 act_id_tenant 租户信息表
组织用户信息 act_id_tenant_member 用户租户关系表
组织用户信息 act_id_user 用户信息表
流程历史记录 act_hi_actinst 历史的活动实例表
流程历史记录 act_hi_attachment 历史的流程附件表
流程历史记录 act_hi_batch 历史的批处理记录表
流程历史记录 act_hi_caseactinst 历史的CMMN活动实例表
流程历史记录 act_hi_caseinst 历史的CMMN实例表
流程历史记录 act_hi_comment 历史的流程审批意见表
流程历史记录 act_hi_dec_in 历史的DMN变量输入表
流程历史记录 act_hi_dec_out 历史的DMN变量输出表
流程历史记录 act_hi_decinst 历史的DMN实例表
流程历史记录 act_hi_detail 历史的流程运行时变量详情记录表
流程历史记录 act_hi_ext_task_log 历史的流程任务消息执行表
流程历史记录 act_hi_identitylink 历史的流程运行过程中用户关系
流程历史记录 act_hi_incident 历史的流程异常事件记录表
流程历史记录 act_hi_job_log 历史的流程作业记录表
流程历史记录 act_hi_op_log 待确定
流程历史记录 act_hi_procinst 历史的流程实例
流程历史记录 act_hi_taskinst 历史的任务实例
流程历史记录 act_hi_varinst 历史的流程变量记录表
流程通用数据 act_ge_bytearray 流程引擎二进制数据表
流程通用数据 act_ge_property 流程引擎属性配置表
流程通用数据 act_ge_schema_log 数据库脚本执行日志表
(2)表之间的关系
流程引擎的最核心表是流程定义、流程执行、流程任务、流程变量和事件订阅表。它们之间的关系见下面的UML模型。
(1)BPMN流程引擎
BPMN引擎共20张表,它们的实体定义和表关系如下:
BPMN引擎数据库表说明:
(2)DMN决策引擎
DMN引擎数据库表说明:
(3)CMMN案例引擎
CMMN(案例)引擎共5张表,其中待办任务和变量表,复用流程引擎的ACT_RU_TASK和ACT_RU_VARLABLE表。
CMMN(案例)引擎数据库表说明:
(4)实例历史记录表
camunda流程实例历史记录表共18张表,为了允许不同的配置并使表更加灵活,历史表不包含外键约束。
流程实例历史记录数据库表说明:
(5)组织用户身份表
用户身份数据库表说明:
(3)核心表介绍
由于Camunda的表比较多,其中一部分是企业版功能需要的,比如批量操作功能、流程监控预警功能等,还有一部分是CMMN案例管理模型和DMN决策模型相关的表,本文仅介绍跟BPMN流程引擎相关的表。
【2】BPM流程引擎封装的接口
Camunda 7.17 流程引擎封装了多个核心服务接口,这些接口涵盖了流程定义、流程实例、任务、历史数据、用户与组管理以及管理监控等多个方面。以下为你详细介绍各主要接口、其参数作用和返回值。
(1)RepositoryService:管理流程定义和部署相关操作
该接口主要用于管理流程定义和部署相关操作。
(1)DeploymentBuilder createDeployment()
参数:无。
作用:创建一个新的部署构建器,用于构建一个部署对象,可添加流程定义文件、资源等。
返回值:DeploymentBuilder 对象,通过该对象可进一步配置部署信息。
(2)ProcessDefinitionQuery createProcessDefinitionQuery()
参数:无。
作用:创建一个流程定义查询对象,可用于根据各种条件筛选流程定义。
返回值:ProcessDefinitionQuery 对象,用于后续链式调用设置查询条件。
(3)DeploymentQuery createDeploymentQuery()
参数:无。
作用:创建一个部署查询对象,用于根据条件查询部署信息。
返回值:DeploymentQuery 对象,可用于链式设置查询条件。
(4)void deleteDeployment(String deploymentId, boolean cascade)
参数:
deploymentId:要删除的部署的唯一标识符。
cascade:布尔值,若为 true,则会级联删除该部署下的所有流程实例、历史数据等;若为 false,仅删除部署本身。
作用:删除指定的部署。
返回值:无。
(2)RuntimeService:管理流程实例的运行时操作
此接口用于管理流程实例的运行时操作。
(1)启动流程实例相关接口
(1)ProcessInstance startProcessInstanceByKey(String processDefinitionKey)
参数:
processDefinitionKey:流程定义的键,是在 BPMN 文件中定义的流程定义的唯一标识,用于区分不同的流程定义。例如在 BPMN 文件里 <process id="myProcess"> ,myProcess 就是这个流程定义的键。
作用:根据流程定义的键启动一个新的流程实例。系统会根据该键找到对应的最新版本的流程定义,并创建一个新的流程实例开始执行。
返回值:ProcessInstance 对象,该对象包含了新启动的流程实例的相关信息,如流程实例 ID、业务键、所属的流程定义 ID 等。
(2)ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey)
参数:
processDefinitionKey:流程定义的键,作用同上。
businessKey:业务键,用于关联业务系统中的业务数据,是业务系统中业务对象的唯一标识。例如在一个订单处理流程中,业务键可以是订单号。
作用:根据流程定义的键启动一个新的流程实例,并关联一个业务键。这样在后续的操作中可以通过业务键来查询和管理相关的流程实例。
返回值:ProcessInstance 对象,包含新启动流程实例的详细信息。
(3)ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables)
参数:
processDefinitionKey:流程定义的键。
variables:一个包含流程实例启动时所需变量的映射。这些变量可以在流程执行过程中被使用,例如可以传递一些初始数据,像订单金额、客户信息等。
作用:根据流程定义的键启动一个新的流程实例,并传入初始变量。这些变量会在流程实例的整个生命周期内可用。
返回值:ProcessInstance 对象,包含新启动流程实例的详细信息。
(2)查询流程实例相关接口
ProcessInstanceQuery createProcessInstanceQuery()
参数:无。
作用:创建一个流程实例查询对象,用于根据各种条件筛选和查询流程实例。通过这个查询对象可以链式调用其他方法来设置不同的查询条件。
返回值:ProcessInstanceQuery 对象,后续可以通过该对象的方法设置查询条件,如按流程实例 ID、业务键、流程定义 ID 等进行查询。
(3)管理流程实例相关接口
void deleteProcessInstance(String processInstanceId, String deleteReason)
参数:
processInstanceId:要删除的流程实例的唯一标识符。
deleteReason:删除流程实例的原因描述,该描述会被记录到历史数据中,方便后续审计和查看。
作用:删除指定的流程实例。删除后,该流程实例将不再存在于运行时环境中,但相关的历史数据可能仍然保留。
返回值:无。
(4)其他
(1)ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables)
参数:
processDefinitionId:流程定义的唯一标识符。
variables:一个包含流程实例启动时所需变量的映射,可为空。
作用:根据流程定义的 ID 启动一个新的流程实例,并传入初始变量。
返回值:ProcessInstance 对象,代表新启动的流程实例。
(3)TaskService:管理用户任务
该接口主要用于管理用户任务。
主要方法及参数、返回值
(1)查询任务相关接口
TaskQuery createTaskQuery()
参数:无。
作用:创建一个任务查询对象,用于根据各种条件筛选和查询任务。可以通过该对象的链式调用方法设置查询条件,如按任务 ID、任务负责人、任务所属流程实例等进行查询。
返回值:TaskQuery 对象,用于后续设置查询条件并执行查询操作。
(2)认领和分配任务相关接口
(1)void claim(String taskId, String userId)
参数:
taskId:要认领的任务的唯一标识符。
userId:认领任务的用户的唯一标识符。
作用:将指定任务认领给指定用户。认领后,该任务就属于该用户,其他用户无法再认领该任务。
返回值:无。
(2)void setAssignee(String taskId, String userId)
参数:
taskId:要分配的任务的唯一标识符。
userId:要分配给的用户的唯一标识符。
作用:将指定任务分配给指定用户。与 claim 方法不同的是,setAssignee 可以直接分配任务,不需要任务处于可认领状态。
返回值:无。
(3)完成任务相关接口
(1)void complete(String taskId)
参数:
taskId:要完成的任务的唯一标识符。
作用:完成指定任务。任务完成后,流程会继续向下执行到下一个节点。
返回值:无。
(2)void complete(String taskId, Map<String, Object> variables)
参数:
taskId:要完成的任务的唯一标识符。
variables:一个包含任务完成时所需变量的映射。这些变量可以影响流程后续的执行逻辑,例如根据变量的值决定流程的分支走向。
作用:完成指定任务,并传入相关变量。任务完成后,流程会继续向下执行,同时这些变量会在后续流程中可用。
返回值:无。
(4)HistoryService:查询和管理流程引擎产生的历史数据
此接口用于查询和管理流程引擎产生的历史数据。
主要方法及参数、返回值
(1)HistoricProcessInstanceQuery createHistoricProcessInstanceQuery()
参数:无。
作用:创建一个历史流程实例查询对象,用于根据条件查询历史流程实例。
返回值:HistoricProcessInstanceQuery 对象,可用于链式设置查询条件。
(2)HistoricTaskInstanceQuery createHistoricTaskInstanceQuery()
参数:无。
作用:创建一个历史任务实例查询对象,用于根据条件查询历史任务实例。
返回值:HistoricTaskInstanceQuery 对象,可用于链式设置查询条件。
(3)HistoricVariableInstanceQuery createHistoricVariableInstanceQuery()
参数:无。
作用:创建一个历史变量实例查询对象,用于根据条件查询历史变量实例。
返回值:HistoricVariableInstanceQuery 对象,可用于链式设置查询条件。
(5)IdentityService:管理用户和组信息
该接口用于管理用户和组信息。
主要方法及参数、返回值
(1)User createUser()
参数:无。
作用:创建一个新的用户对象,后续可对该对象设置用户信息。
返回值:User 对象,代表新创建的用户。
(2)Group createGroup()
参数:无。
作用:创建一个新的组对象,后续可对该对象设置组信息。
返回值:Group 对象,代表新创建的组。
(3)UserQuery createUserQuery()
参数:无。
作用:创建一个用户查询对象,用于根据条件查询用户。
返回值:UserQuery 对象,可用于链式设置查询条件。
(4)GroupQuery createGroupQuery()
参数:无。
作用:创建一个组查询对象,用于根据条件查询组。
返回值:GroupQuery 对象,可用于链式设置查询条件。
(6)ManagementService:管理和监控流程引擎
该接口提供了一些管理和监控流程引擎的功能。
主要方法及参数、返回值
(1)JobQuery createJobQuery()
参数:无。
作用:创建一个作业查询对象,用于根据条件查询作业。
返回值:JobQuery 对象,可用于链式设置查询条件。
(2)void executeCommand(Command<T> command)
参数:
command:实现了 Command 接口的自定义命令对象。
作用:执行一个自定义的命令。
返回值:命令执行的结果,类型取决于 Command 接口的泛型 T。
(7)示例代码
以下是一个简单的示例,展示如何使用部分接口:
import org.camunda.bpm.engine.*;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CamundaExample {
public static void main(String[] args) {
// 获取流程引擎实例
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 获取服务接口
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
// 启动流程实例
Map<String, Object> variables = new HashMap<>();
variables.put("inputVariable", "exampleValue");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess", variables);
// 查询任务
List<Task> tasks = taskService.createTaskQuery()
.processInstanceId(processInstance.getId())
.list();
// 认领并完成任务
if (!tasks.isEmpty()) {
Task task = tasks.get(0);
taskService.claim(task.getId(), "testUser");
Map<String, Object> taskVariables = new HashMap<>();
taskVariables.put("outputVariable", "resultValue");
taskService.complete(task.getId(), taskVariables);
}
// HistoryService 示例
// 查询历史流程实例
HistoricProcessInstanceQuery historicProcessInstanceQuery = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
List<org.camunda.bpm.engine.history.HistoricProcessInstance> historicInstances = historicProcessInstanceQuery.processDefinitionKey(processDefinitionKey).list();
// 关闭流程引擎
processEngine.close();
}
}
【3】流程逻辑
【六】Spring Boot 项目整合 Camunda 的搭建流程
springboot项目整合camunda7.17,将camunda的数据源改成mysql并完成创建表初始化,添加pom依赖,配置yml,并且设计bpmn,使用mvc架构实现用户审批请假流程,请假必须给出请假人工号、请假开始时间、请假结束时间、请假天数、工作交接人、请假原因等信息,根据员工工号查出员工的所有上级,然后要求3天以内上级领导审批,3天以上职能上级审批,最终都要经过行政上级审批,每一层审批都可以选择通过或拒绝,给出完整可用的案例和代码架构
【1】创建 Spring Boot 项目
可以使用 Spring Initializr(https://start.spring.io/)来创建一个基础的 Spring Boot 项目,添加以下依赖:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>camunda-leave-approval</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.15</version>
</parent>
<dependencies>
<!-- Camunda Spring Boot Starter -->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>7.17.0</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
【2】配置数据库和Camunda
在 src/main/resources 目录下创建或修改 application.yml 文件,配置 MySQL 数据源和 Camunda 相关信息:
spring:
datasource:
url: jdbc:mysql://localhost:3306/camunda_leave_approval?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
camunda.bpm:
admin-user:
id: demo
password: demo
firstName: Demo
lastName: User
filter:
create: All tasks
Camunda 会在启动时根据配置自动创建所需的数据库表。
【3】创建 BPMN 流程定义文件
使用 Camunda Modeler 设计请假审批流程,以下是对应的 BPMN XML 代码(保存为 leave_approval.bpmn 并放在 src/main/resources/processes 目录下):
(1)启动事件:添加一个起始事件表示请假流程开始。
(2)员工提交请假申请:添加一个用户任务,员工在此任务中输入请假时间和原因。
(3)天数判断网关:使用排他网关根据请假天数判断是由上级领导审批还是职能上级审批。
(4)上级领导审批:当请假天数小于等于 3 天,进入此用户任务,审批人可选择通过或拒绝。
(5)职能上级审批:当请假天数大于 3 天,进入此用户任务,审批人可选择通过或拒绝。
(6)行政上级审批:无论前面审批结果如何,最终都进入此用户任务进行审批。
(7)结束事件:根据最终审批结果,流程结束。
<?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:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
id="Definitions_0"
targetNamespace="http://bpmn.io/schema/bpmn">
<process id="leaveApprovalProcess" name="Leave Approval Process" isExecutable="true">
<startEvent id="StartEvent_1"></startEvent>
<userTask id="SubmitLeaveRequest" name="Submit Leave Request">
<extensionElements>
<camunda:formData>
<camunda:formField id="employeeId" label="Employee ID" type="string"></camunda:formField>
<camunda:formField id="startDate" label="Start Date" type="date"></camunda:formField>
<camunda:formField id="endDate" label="End Date" type="date"></camunda:formField>
<camunda:formField id="leaveDays" label="Leave Days" type="long"></camunda:formField>
<camunda:formField id="handoverPerson" label="Handover Person" type="string"></camunda:formField>
<camunda:formField id="leaveReason" label="Leave Reason" type="string"></camunda:formField>
</camunda:formData>
</extensionElements>
</userTask>
<exclusiveGateway id="ExclusiveGateway_1" name="Check Leave Days"></exclusiveGateway>
<userTask id="SupervisorApproval" name="Supervisor Approval">
<extensionElements>
<camunda:formData>
<camunda:formField id="approvalResult" label="Approval Result" type="string">
<camunda:value id="approved" name="Approved"></camunda:value>
<camunda:value id="rejected" name="Rejected"></camunda:value>
</camunda:formField>
</camunda:formData>
</extensionElements>
</userTask>
<userTask id="FunctionalSupervisorApproval" name="Functional Supervisor Approval">
<extensionElements>
<camunda:formData>
<camunda:formField id="approvalResult" label="Approval Result" type="string">
<camunda:value id="approved" name="Approved"></camunda:value>
<camunda:value id="rejected" name="Rejected"></camunda:value>
</camunda:formField>
</camunda:formData>
</extensionElements>
</userTask>
<userTask id="AdministrativeApproval" name="Administrative Approval">
<extensionElements>
<camunda:formData>
<camunda:formField id="approvalResult" label="Approval Result" type="string">
<camunda:value id="approved" name="Approved"></camunda:value>
<camunda:value id="rejected" name="Rejected"></camunda:value>
</camunda:formField>
</camunda:formData>
</extensionElements>
</userTask>
<endEvent id="EndEvent_1"></endEvent>
<endEvent id="EndEvent_2"></endEvent>
<sequenceFlow id="Flow_09m4z8h" sourceRef="StartEvent_1" targetRef="SubmitLeaveRequest"></sequenceFlow>
<sequenceFlow id="Flow_112x5n4" sourceRef="SubmitLeaveRequest" targetRef="ExclusiveGateway_1"></sequenceFlow>
<sequenceFlow id="Flow_00479m7" sourceRef="ExclusiveGateway_1" targetRef="SupervisorApproval">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${leaveDays <= 3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_03y4x5a" sourceRef="ExclusiveGateway_1" targetRef="FunctionalSupervisorApproval">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${leaveDays > 3}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_070m4pz" sourceRef="SupervisorApproval" targetRef="AdministrativeApproval"></sequenceFlow>
<sequenceFlow id="Flow_094639c" sourceRef="FunctionalSupervisorApproval" targetRef="AdministrativeApproval"></sequenceFlow>
<sequenceFlow id="Flow_1abcdef" sourceRef="AdministrativeApproval" targetRef="EndEvent_1">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalResult == 'approved'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="Flow_2abcdef" sourceRef="AdministrativeApproval" targetRef="EndEvent_2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${approvalResult == 'rejected'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<!-- 图形布局信息,可忽略 -->
</bpmndi:BPMNDiagram>
</definitions>
【6】请假审批流程
(1)项目结构
src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── camundaleaveapproval
│ │ ├── controller
│ │ │ └── LeaveApprovalController.java
│ │ ├── entity
│ │ │ └── LeaveRequest.java
│ │ ├── service
│ │ │ ├── EmployeeService.java
│ │ │ ├── LeaveApprovalService.java
│ │ │ └── impl
│ │ │ ├── EmployeeServiceImpl.java
│ │ │ └── LeaveApprovalServiceImpl.java
│ │ └── CamundaLeaveApprovalApplication.java
│ └── resources
│ ├── application.yml
│ └── processes
│ └── leave_approval.bpmn
└── test
└── java
└── com
└── example
└── camundaleaveapproval
└── CamundaLeaveApprovalApplicationTests.java
(2)实体类
package com.example.camundaleaveapproval.entity;
import lombok.Data;
import java.util.Date;
@Data
public class LeaveRequest {
private String employeeId;
private Date startDate;
private Date endDate;
private int leaveDays;
private String handoverPerson;
private String leaveReason;
}
(3)服务层接口
package com.example.camundaleaveapproval.service;
import com.example.camundaleaveapproval.entity.LeaveRequest;
public interface LeaveApprovalService {
void startLeaveApprovalProcess(LeaveRequest leaveRequest);
}
(4)服务层实现类
package com.example.camundaleaveapproval.service.impl;
import com.example.camundaleaveapproval.entity.LeaveRequest;
import com.example.camundaleaveapproval.service.LeaveApprovalService;
import org.camunda.bpm.engine.RuntimeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class LeaveApprovalServiceImpl implements LeaveApprovalService {
@Autowired
private RuntimeService runtimeService;
@Override
public void startLeaveApprovalProcess(LeaveRequest leaveRequest) {
Map<String, Object> variables = new HashMap<>();
variables.put("employeeId", leaveRequest.getEmployeeId());
variables.put("startDate", leaveRequest.getStartDate());
variables.put("endDate", leaveRequest.getEndDate());
variables.put("leaveDays", leaveRequest.getLeaveDays());
variables.put("handoverPerson", leaveRequest.getHandoverPerson());
variables.put("leaveReason", leaveRequest.getLeaveReason());
runtimeService.startProcessInstanceByKey("leaveApprovalProcess", variables);
}
}
(5)控制器类
package com.example.camundaleaveapproval.controller;
import com.example.camundaleaveapproval.entity.LeaveRequest;
import com.example.camundaleaveapproval.service.LeaveApprovalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/leave")
public class LeaveApprovalController {
@Autowired
private LeaveApprovalService leaveApprovalService;
@PostMapping("/submit")
public String submitLeaveRequest(@RequestBody LeaveRequest leaveRequest) {
leaveApprovalService.startLeaveApprovalProcess(leaveRequest);
return "Leave request submitted successfully.";
}
}
(6)员工上级查询逻辑
package com.example.camundaleaveapproval.service;
import java.util.ArrayList;
import java.util.List;
public interface EmployeeService {
List<String> getSupervisors(String employeeId);
}
package com.example.camundaleaveapproval.service.impl;
import com.example.camundaleaveapproval.service.EmployeeService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class EmployeeServiceImpl implements EmployeeService {
@Override
public List<String> getSupervisors(String employeeId) {
List<String> supervisors = new ArrayList<>();
// 这里可以实现从数据库查询上级信息的逻辑
supervisors.add("Supervisor1");
supervisors.add("FunctionalSupervisor1");
supervisors.add("AdministrativeSupervisor1");
return supervisors;
}
}
(7)测试流程
(1)发起申请
可以使用 Postman 等工具发送 POST 请求到 http://localhost:8080/leave/submit,请求体示例如下:
{
"employeeId": "123",
"startDate": "2024-10-01",
"endDate": "2024-10-05",
"leaveDays": 5,
"handoverPerson": "John",
"leaveReason": "Family event"
}
(2)审批人登录到CamundaBPM进行审批
登录 Camunda Cockpit(http://localhost:8080/camunda/app/cockpit/default/)使用用户名 demo 和密码 demo 查看流程执行情况,并在 Camunda Tasklist 中完成各个审批任务。
【七】springboot整合Camunda测试实例项目
git地址:https://gitee.com/allensun03/learn_camunda
【八】审批流程案例【待完成】
【1】创建本地camunda项目
当前项目只包含流程的业务代码,最终打成jar包供其他项目调用,实现代码的解耦
项目结构使用ddd分层
【2】添加pom依赖
本项目是父子module的微服务项目,需要管理父子module的pom依赖
(1)父级pom
进行全局的依赖管理,注意Camunda的版本是7.15
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzyatop.framework.boot</groupId>
<artifactId>damp-boot-parent</artifactId>
<version>2.7.18-20241119</version>
</parent>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda</artifactId>
<version>${damp-base-camunda.version}</version>
<packaging>pom</packaging>
<modules>
<module>api</module>
<module>application</module>
<module>domain</module>
<module>infrastructure</module>
<module>sdk</module>
</modules>
<!-- 版本号配置 -->
<properties>
<damp-base-camunda.version>4.7.0-SNAPSHOT</damp-base-camunda.version>
<camunda.version>7.15.0</camunda.version>
<camunda-spin.version>1.10.0</camunda-spin.version>
<groovy-jsr223.version>4.0.13</groovy-jsr223.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-engine</artifactId>
<version>${camunda.version}</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
<version>${camunda.version}</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-engine-plugin-spin</artifactId>
<version>${camunda.version}</version>
</dependency>
<dependency>
<groupId>org.camunda.spin</groupId>
<artifactId>camunda-spin-core</artifactId>
<version>${camunda-spin.version}</version>
</dependency>
<dependency>
<groupId>org.camunda.spin</groupId>
<artifactId>camunda-spin-dataformat-json-jackson</artifactId>
<version>${camunda-spin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
</dependency>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-application</artifactId>
<version>${damp-base-camunda.version}</version>
</dependency>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-domain</artifactId>
<version>${damp-base-camunda.version}</version>
</dependency>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-infrastructure</artifactId>
<version>${damp-base-camunda.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 依赖 -->
<dependencies>
<dependency>
<groupId>com.hzyatop.framework.cloud</groupId>
<artifactId>damp-cloud-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.hzyatop.framework</groupId>
<artifactId>damp-commons</artifactId>
</dependency>
<!-- easyexcel -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
(2)api层
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda</artifactId>
<version>${damp-base-camunda.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>damp-base-camunda-api</artifactId>
<description>接口</description>
<dependencies>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-infrastructure</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>com/**</include>
</includes>
<!--<!– 不打包资源文件(配置文件和依赖包分开) –>-->
<excludes>
<exclude>**/*.xml</exclude>
<exclude>**/*.properties</exclude>
<exclude>**/*.yml</exclude>
</excludes>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>timestamp-property</id>
<goals>
<goal>timestamp-property</goal>
</goals>
<configuration>
<name>build.time</name>
<timeZone>GMT+8</timeZone>
<pattern>yyyyMMddHHmmss</pattern>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>${project.parent.artifactId}-${build.time}</finalName>
<descriptors>
<descriptor>assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
(3)application层
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda</artifactId>
<version>${damp-base-camunda.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>damp-base-camunda-application</artifactId>
<dependencies>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-domain</artifactId>
</dependency>
</dependencies>
</project>
(4)domain层
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda</artifactId>
<version>${damp-base-camunda.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>damp-base-camunda-domain</artifactId>
<description>领域</description>
<dependencies>
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-engine</artifactId>
</dependency>
</dependencies>
</project>
(5)infrastructure层
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda</artifactId>
<version>${damp-base-camunda.version}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>damp-base-camunda-infrastructure</artifactId>
<description>基础设施</description>
<dependencies>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-application</artifactId>
</dependency>
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-domain</artifactId>
</dependency>
<!-- camunda -->
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId>
</dependency>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-jsr223</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.camunda.bpm</groupId>
<artifactId>camunda-engine-plugin-spin</artifactId>
</dependency>
<dependency>
<groupId>org.camunda.spin</groupId>
<artifactId>camunda-spin-core</artifactId>
</dependency>
<dependency>
<groupId>org.camunda.spin</groupId>
<artifactId>camunda-spin-dataformat-json-jackson</artifactId>
</dependency>
</dependencies>
</project>
【3】添加配置信息
通过springCloud实现的微服务,使用Nacos实现注册中心和配置管理
damp-base-camunda-api.yml
damp:
db:
schema: damp_base_camunda
type: mysql
camunda:
bpm:
# 配置账户密码来访问Camunda自带的管理界面
admin-user:
id: admin
password: admin@Yatop
first-name: admin
#禁止自动部署resources下面的bpmn文件
auto-deployment-enabled: false
#指定数据库类型
database:
type: ${damp.db.type}
yt:
auth:
excludes: # [默认] 不开启鉴权路径
- /4.2.0/approve_user
app:
token: 2a9b01494d5d422cb11eca265902b241
【4】建表
除了Camunda基本的表以外,还有额外新增的表
(1)业务流程定义关系
CREATE TABLE `yatop_procdef` (
`ID` bigint NOT NULL COMMENT '主键',
`MOD_MENU_CD` varchar(40) DEFAULT NULL COMMENT '模块菜单编号',
`PROC_DEF_KEY` varchar(255) DEFAULT NULL COMMENT '流程定义key',
`PROC_DEF_NM` varchar(255) DEFAULT NULL COMMENT '流程定义名',
`PROC_DEPLOY_ID` varchar(64) DEFAULT NULL COMMENT '流程部署ID',
`PROC_DEF_VER` int DEFAULT NULL COMMENT '部署版本',
`STATUS` char(1) DEFAULT NULL COMMENT '流程状态',
`TENANT_ID` bigint DEFAULT NULL COMMENT '租户ID',
`CRT_USER_ID` bigint DEFAULT NULL COMMENT '创建人',
`UPD_USER_ID` bigint DEFAULT NULL COMMENT '更新人',
`CRT_DT_TM` datetime DEFAULT NULL COMMENT '创建时间',
`UPD_DT_TM` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`ID`),
UNIQUE KEY `YATOP_PROCDEF_UK` (`PROC_DEF_KEY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='业务流程定义关系';
(2)业务-流程定义关系表
-- uat1_damp_base_camunda.yatop_procdef_biz definition
CREATE TABLE `yatop_procdef_biz` (
`ID` bigint NOT NULL COMMENT '主键',
`MODULE` varchar(32) DEFAULT NULL COMMENT '所属业务模块',
`BIZ_NAME` varchar(256) DEFAULT NULL COMMENT '业务名称',
`BIZ_TYPE` varchar(20) DEFAULT NULL COMMENT '业务类型',
`PROC_DEF_KEY` varchar(255) DEFAULT NULL COMMENT '流程key',
`DEPLOYMENT_ID` varchar(64) DEFAULT NULL COMMENT '部署ID',
`VERSION` int DEFAULT NULL COMMENT '部署版本',
`STATE` int DEFAULT NULL COMMENT '状态',
`CRT_USER_ID` bigint DEFAULT NULL COMMENT '创建人',
`UPD_USER_ID` bigint DEFAULT NULL COMMENT '更新人',
`CRT_DT_TM` datetime DEFAULT NULL COMMENT '创建时间',
`UPD_DT_TM` datetime DEFAULT NULL COMMENT '更新时间',
`TENANT_ID` bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='业务-流程定义关系表';
(3)业务-流程实例关联表
-- uat1_damp_base_camunda.yatop_procinst_biz_relation definition
CREATE TABLE `yatop_procinst_biz_relation` (
`ID` bigint NOT NULL COMMENT '主键',
`MODULE` varchar(32) DEFAULT NULL COMMENT '所属业务模块',
`BIZ_NO` varchar(128) DEFAULT NULL COMMENT '业务编码',
`BIZ_NAME` varchar(256) DEFAULT NULL COMMENT '业务名称',
`BIZ_TYPE` varchar(64) DEFAULT NULL COMMENT '业务类型',
`BIZ_PRIORITY` int NOT NULL COMMENT '任务优先级',
`BIZ_EXTEND_INFO` varchar(500) DEFAULT NULL COMMENT '业务扩展信息',
`PROC_DEF_KEY` varchar(255) DEFAULT NULL COMMENT '流程定义key',
`PROC_INST_ID` varchar(64) DEFAULT NULL COMMENT '审核流程实例id',
`SUBMITTER_ID` bigint DEFAULT NULL COMMENT '审核提交人id',
`SUBMITTER_NAME` varchar(64) DEFAULT NULL COMMENT '审核提交人',
`PROC_STATE` varchar(50) DEFAULT NULL COMMENT '审核状态',
`START_DT_TM` datetime DEFAULT NULL COMMENT '开始时间',
`CHECK_DT_TM` datetime DEFAULT NULL COMMENT '审核时间',
`STATE` int DEFAULT NULL COMMENT '状态',
`CRT_USER_ID` bigint DEFAULT NULL COMMENT '创建人',
`UPD_USER_ID` bigint DEFAULT NULL COMMENT '更新人',
`CRT_DT_TM` datetime DEFAULT NULL COMMENT '创建时间',
`UPD_DT_TM` datetime DEFAULT NULL COMMENT '更新时间',
`TENANT_ID` bigint DEFAULT NULL COMMENT '租户ID',
PRIMARY KEY (`ID`),
UNIQUE KEY `INDEX_PROC_INST_ID` (`PROC_INST_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='业务-流程实例关联表';
【5】Camunda流程引擎接口二开
(1)application层
提供两类接口
(1)ProscessApi负责处理流程信息
(2)TaskApi负责处理任务信息
(2)domain层
(3)infrastruture层
在这里插入代码片
【6】在其他项目中引入使用
某项目中要使用工作流审批,则引入本项目的依赖
<dependency>
<groupId>com.hzyatop.damp.camunda</groupId>
<artifactId>damp-base-camunda-sdk</artifactId>
<version>4.7.0-SNAPSHOT</version>
</dependency>
【7】流程配置页面
通过自建的表process来存储业务流程的基本信息,查询自建表process得到本项目的全部流程
发布流程
下线申请流程
使用申请流程
取消使用申请流程