开发专题
人工智能AI
机器学习ML
深度学习DL
关于大模型的一些基础内容
一些人工智能的架构图
使用ollama在本地启动运行大语言模型
在本地部署sd使用AI生图功能
AIGC入门教程
队列
RabbitMQ消息队列
redis+mq实现秒杀功能
非结构化存储OSS
使用minio进行数据存储
非结构化文档在线预览
使用kkfileView实现在线文档预览
OnlyOffice实现文档在线编辑
全文搜索
Elasticsearch构建全文搜索系统
windowns下使用Logstash7.6.2同步Mysql数据到ElasticSearch,并使用kibana进行检索
工作流Flowable应用
Flowable基础入门知识
Springboot+mybatisplus+flowable6.5.0 开发房产审批模块
人脸识别
虹软人脸识别应用
人脸识别基础入门知识
WebSocket在线聊天
Springboot+WebSocket+redis实现在线客服系统
WebSocket基础入门
信创产业
领域驱动DDD
定时任务quartz
流媒体
流媒体服务LALMAX的部署安装与使用
使用go2rtc+webrtc-streamer在网页上播放rtsp 的摄像头视频
RPA数字员工
使用盘匠设计器进行RPA项目的开发
RPA开发过程中的一些经验之谈
本文档使用 MrDoc 发布
-
+
首页
Flowable基础入门知识
> 使用flowable,实现房产的审批,根据新增和删除的不同,进行入审批级别也是不一样的。 其他技术使用包括:mybatis-plus vue ## 引入依赖 ~~~ <dependency> <groupId>org.flowable</groupId> <artifactId>flowable-spring-boot-starter</artifactId> <version>6.5.0</version> </dependency> ~~~ ## 部署flowable-ui 部署文法,百度搜索去。 部署完成的地址: http://10.168.1.184:8080/flowable-ui/ 账号密码:admin test ## 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:Flowable 相关的基本信息(不常用)。比如各个 module 使用的版本信息 ### 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:运行时流程变量数据表,存储运行中的流程各节点的变量信息; ## Flowable常用配置项 ~~~ # =================================================================== # Common Flowable Spring Boot Properties # 通用Flowable Spring Boot参数 # # This sample file is provided as a guideline. Do NOT copy it in its # entirety to your own application. ^^^ # 本示例文件只作为指导。请不要直接拷贝至你自己的应用中。 # =================================================================== # Core (Process) FlowableProperties # 核心(流程) flowable.check-process-definitions=true # 是否需要自动部署流程定义。 flowable.custom-mybatis-mappers= # 需要添加至引擎的自定义Mybatis映射的FQN。 flowable.custom-mybatis-x-m-l-mappers= # 需要添加至引擎的自定义Mybatis XML映射的路径。 flowable.database-schema= # 如果数据库返回的元数据不正确,可以在这里设置schema用于检测/生成表。 flowable.database-schema-update=true # 数据库schema更新策略。 flowable.db-history-used=true # 是否要使用db历史。 flowable.deployment-name=SpringBootAutoDeployment # 自动部署的名称。 flowable.history-level= # 要使用的历史级别。 flowable.process-definition-location-prefix=classpath*:/processes/ # 自动部署时查找流程的目录。 flowable.process-definition-location-suffixes=**.bpmn20.xml,**.bpmn # 'processDefinitionLocationPrefix'路径下需要部署的文件的后缀(扩展名)。 # Process FlowableProcessProperties # 流程 flowable.process.definition-cache-limit=-1 # 流程定义缓存中保存流程定义的最大数量。默认值为-1(缓存所有流程定义)。 flowable.process.enable-safe-xml=true # 在解析BPMN XML文件时进行额外检查。参见 https://www.flowable.org/docs/userguide/index.html#advanced.safe.bpmn.xml 。不幸的是,部分平台(JDK 6,JBoss)上无法使用这个功能,因此如果你所用的平台在XML解析时不支持StaxSource,需要禁用这个功能。 flowable.process.servlet.load-on-startup=-1 # 启动时加载Process servlet。 flowable.process.servlet.name=Flowable BPMN Rest API # Process servlet的名字。 flowable.process.servlet.path=/process-api # Process servelet的context path。 # Process Async Executor # 流程异步执行器 flowable.process.async-executor-activate=true # 是否启用异步执行器。 flowable.process.async.executor.async-job-lock-time-in-millis=300000 # 异步作业在被异步执行器取走后的锁定时间(以毫秒计)。在这段时间内,其它异步执行器不会尝试获取及锁定这个任务。 flowable.process.async.executor.default-async-job-acquire-wait-time-in-millis=10000 # 异步作业获取线程在进行下次获取查询前的等待时间(以毫秒计)。只在当次没有取到新的异步作业,或者只取到很少的异步作业时生效。默认值 = 10秒。 flowable.process.async.executor.default-queue-size-full-wait-time-in-millis=0 # 异步作业(包括定时器作业与异步执行)获取线程在队列满时,等待执行下次查询的等待时间(以毫秒计)。默认值为0(以向后兼容) flowable.process.async.executor.default-timer-job-acquire-wait-time-in-millis=10000 # 定时器作业获取线程在进行下次获取查询前的等待时间(以毫秒计)。只在当次没有取到新的定时器作业,或者只取到很少的定时器作业时生效。默认值 = 10秒。 flowable.process.async.executor.max-async-jobs-due-per-acquisition=1 # (译者补)单次查询的异步作业数量。默认值为1,以降低乐观锁异常的可能性。除非你知道自己在做什么,否则请不要修改这个值。 flowable.process.async.executor.retry-wait-time-in-millis=500 # ???(译者补不了了) flowable.process.async.executor.timer-lock-time-in-millis=300000 # 定时器作业在被异步执行器取走后的锁定时间(以毫秒计)。在这段时间内,其它异步执行器不会尝试获取及锁定这个任务。 # CMMN FlowableCmmnProperties flowable.cmmn.deploy-resources=true # 是否部署资源。默认值为'true'。 flowable.cmmn.deployment-name=SpringBootAutoDeployment # CMMN资源部署的名字。 flowable.cmmn.enable-safe-xml=true # 在解析CMMN XML文件时进行额外检查。参见 https://www.flowable.org/docs/userguide/index.html#advanced.safe.bpmn.xml 。不幸的是,部分平台(JDK 6,JBoss)上无法使用这个功能,因此如果你所用的平台在XML解析时不支持StaxSource,需要禁用这个功能。 flowable.cmmn.enabled=true # 是否启用CMMN引擎。 flowable.cmmn.resource-location=classpath*:/cases/ # CMMN资源的路径。 flowable.cmmn.resource-suffixes=**.cmmn,**.cmmn11,**.cmmn.xml,**.cmmn11.xml # 需要扫描的资源后缀名。 flowable.cmmn.servlet.load-on-startup=-1 # 启动时加载CMMN servlet。 flowable.cmmn.servlet.name=Flowable CMMN Rest API # CMMN servlet的名字。 flowable.cmmn.servlet.path=/cmmn-api # CMMN servlet的context path。 # CMMN Async Executor # CMMN异步执行器 flowable.cmmn.async-executor-activate=true # 是否启用异步执行器。 flowable.cmmn.async.executor.async-job-lock-time-in-millis=300000 # 异步作业在被异步执行器取走后的锁定时间(以毫秒计)。在这段时间内,其它异步执行器不会尝试获取及锁定这个任务。 flowable.cmmn.async.executor.default-async-job-acquire-wait-time-in-millis=10000 # 异步作业获取线程在进行下次获取查询前的等待时间(以毫秒计)。只在当次没有取到新的异步作业,或者只取到很少的异步作业时生效。默认值 = 10秒。 flowable.cmmn.async.executor.default-queue-size-full-wait-time-in-millis=0 # 异步作业(包括定时器作业与异步执行)获取线程在队列满时,等待执行下次查询的等待时间(以毫秒计)。默认值为0(以向后兼容) flowable.cmmn.async.executor.default-timer-job-acquire-wait-time-in-millis=1000 # 定时器作业获取线程在进行下次获取查询前的等待时间(以毫秒计)。只在当次没有取到新的定时器作业,或者只取到很少的定时器作业时生效。默认值 = 10秒。 flowable.cmmn.async.executor.max-async-jobs-due-per-acquisition=1 # (译者补)单次查询的异步作业数量。默认值为1,以降低乐观锁异常的可能性。除非你知道自己在做什么,否则请不要修改这个值。 flowable.cmmn.async.executor.retry-wait-time-in-millis=500 #(译者补不了了) flowable.cmmn.async.executor.timer-lock-time-in-millis=300000 # 定时器作业在被异步执行器取走后的锁定时间(以毫秒计)。在这段时间内,其它异步执行器不会尝试获取及锁定这个任务。 # Content FlowableContentProperties flowable.content.enabled=true # 是否启动Content引擎。 flowable.content.servlet.load-on-startup=-1 # 启动时加载Content servlet。 flowable.content.servlet.name=Flowable Content Rest API # Content servlet的名字。 flowable.content.servlet.path=/content-api # Content servlet的context path。 flowable.content.storage.create-root=true # 如果根路径不存在,是否需要创建? flowable.content.storage.root-folder= # 存储content文件(如上传的任务附件,或表单文件)的根路径。 # DMN FlowableDmnProperties flowable.dmn.deploy-resources=true # 是否部署资源。默认为'true'。 flowable.dmn.deployment-name=SpringBootAutoDeployment # DMN资源部署的名字。 flowable.dmn.enable-safe-xml=true # 在解析DMN XML文件时进行额外检查。参见 https://www.flowable.org/docs/userguide/index.html#advanced.safe.bpmn.xml 。不幸的是,部分平台(JDK 6,JBoss)上无法使用这个功能,因此如果你所用的平台在XML解析时不支持StaxSource,需要禁用这个功能。 flowable.dmn.enabled=true # 是否启用DMN引擎。 flowable.dmn.history-enabled=true # 是否启用DMN引擎的历史。 flowable.dmn.resource-location=classpath*:/dmn/ # DMN资源的路径。 flowable.dmn.resource-suffixes=**.dmn,**.dmn.xml,**.dmn11,**.dmn11.xml # 需要扫描的资源后缀名。 flowable.dmn.servlet.load-on-startup=-1 # 启动时加载DMN servlet。 flowable.dmn.servlet.name=Flowable DMN Rest API # DMN servlet的名字。 flowable.dmn.servlet.path=/dmn-api # DMN servlet的context path。 flowable.dmn.strict-mode=true # 如果希望避免抉择表命中策略检查导致失败,可以将本参数设置为false。如果检查发现了错误,会直接返回错误前一刻的中间结果。 # Form FlowableFormProperties flowable.form.deploy-resources=true # 是否部署资源。默认为'true'。 flowable.form.deployment-name=SpringBootAutoDeployment # Form资源部署的名字。 flowable.form.enabled=true # 是否启用Form引擎。 flowable.form.resource-location=classpath*:/forms/ # Form资源的路径。 flowable.form.resource-suffixes=**.form # 需要扫描的资源后缀名。 flowable.form.servlet.load-on-startup=-1 # 启动时加载Form servlet。 flowable.form.servlet.name=Flowable Form Rest API # Form servlet的名字。 flowable.form.servlet.path=/form-api # Form servlet的context path。 # IDM FlowableIdmProperties flowable.idm.enabled=true # 是否启用IDM引擎。 flowable.idm.password-encoder= # 使用的密码编码类型。 flowable.idm.servlet.load-on-startup=-1 # 启动时加载IDM servlet。 flowable.idm.servlet.name=Flowable IDM Rest API # IDM servlet的名字。 flowable.idm.servlet.path=/idm-api # IDM servlet的context path。 # IDM Ldap FlowableLdapProperties flowable.idm.ldap.attribute.email= # 用户email的属性名。 flowable.idm.ldap.attribute.first-name= # 用户名字的属性名。 flowable.idm.ldap.attribute.group-id= # 用户组ID的属性名。 flowable.idm.ldap.attribute.group-name= # 用户组名的属性名。 flowable.idm.ldap.attribute.group-type= # 用户组类型的属性名。 flowable.idm.ldap.attribute.last-name= # 用户姓的属性名。 flowable.idm.ldap.attribute.user-id= # 用户ID的属性名。 flowable.idm.ldap.base-dn= # 查找用户与组的DN(标志名称 distinguished name)。 flowable.idm.ldap.cache.group-size=-1 # 设置{@link org.flowable.ldap.LDAPGroupCache}的大小。这是LRU缓存,用于缓存用户及组,以避免每次都查询LDAP系统。 flowable.idm.ldap.custom-connection-parameters= # 用于设置所有没有专用setter的LDAP连接参数。查看 http://docs.oracle.com/javase/tutorial/jndi/ldap/jndi.html 介绍的自定义参数。参数包括配置链接池,安全设置,等等。 flowable.idm.ldap.enabled=false # 是否启用LDAP IDM 服务。 flowable.idm.ldap.group-base-dn= # 组查找的DN。 flowable.idm.ldap.initial-context-factory=com.sun.jndi.ldap.LdapCtxFactory # 初始化上下文工厂的类名。 flowable.idm.ldap.password= # 连接LDAP系统的密码。 flowable.idm.ldap.port=-1 # LDAP系统的端口。 flowable.idm.ldap.query.all-groups= # 查询所有组所用的语句。 flowable.idm.ldap.query.all-users= # 查询所有用户所用的语句。 flowable.idm.ldap.query.groups-for-user= # 按照指定用户查询所属组所用的语句 flowable.idm.ldap.query.user-by-full-name-like= # 按照给定全名查找用户所用的语句。 flowable.idm.ldap.query.user-by-id= # 按照userId查找用户所用的语句。 flowable.idm.ldap.search-time-limit=0 # 查询LDAP的超时时间(以毫秒计)。默认值为'0',即“一直等待”。 flowable.idm.ldap.security-authentication=simple # 连接LDAP系统所用的'java.naming.security.authentication'参数的值。 flowable.idm.ldap.server= # LDAP系统的主机名。如'ldap://localhost'。 flowable.idm.ldap.user= # 连接LDAP系统的用户ID。 flowable.idm.ldap.user-base-dn= # 查找用户的DN。 # Flowable Mail FlowableMailProperties flowable.mail.server.default-from=flowable@localhost # 发送邮件时使用的默认发信人地址。 flowable.mail.server.host=localhost # 邮件服务器。 flowable.mail.server.password= # 邮件服务器的登录密码。 flowable.mail.server.port=1025 # 邮件服务器的端口号。 flowable.mail.server.use-ssl=false # 是否使用SSL/TLS加密SMTP传输连接(即SMTPS/POPS)。 flowable.mail.server.use-tls=false # 使用或禁用STARTTLS加密。 flowable.mail.server.username= # 邮件服务器的登录用户名。如果为空,则不需要登录。 # Actuator management.endpoint.flowable.cache.time-to-live=0ms # 缓存响应的最大时间。 management.endpoint.flowable.enabled=true # 是否启用flowable端点。 ~~~ ## Flowable 常用API Flowable整体是通过ProcessEngine来操作的。即不管什么框架操作流程,都需要通过ProcessEngine这个类来处理。ProcessEngine是Flowable对外公开的门面。 类图如下:  关系图如下:  ### FormService 表单数据的管理。 ~~~ formService.getStartFormKey() 获取表单key formService.getRenderedStartForm()查询表单json(无数据) ~~~ ### RepositoryService 提供了在编辑和发布审批流程的 api。主要是模型管理和流程定义的业务 api。 ~~~ 1.提供了带条件的查询模型流程定义的api repositoryService.createXXXQuery() 例如: repositoryService.createModelQuery().list() 模型查询 repositoryService.createProcessDefinitionQuery().list() 流程定义查询 repositoryService.createXXXXQuery().XXXKey(XXX) (查询该key是否存在) 2.提供一大波模型与流程定义的通用方法 模型相关(【本人亲测这里获取模型貌似不行,有知道的联系我】) repositoryService.getModel() (获取模型) repositoryService.saveModel() (保存模型) repositoryService.deleteModel() (删除模型) repositoryService.createDeployment().deploy(); (部署模型) repositoryService.getModelEditorSource() (获得模型JSON数据的UTF8字符串) repositoryService.getModelEditorSourceExtra() (获取PNG格式图像) 3.流程定义相关 repositoryService.getProcessDefinition(ProcessDefinitionId); 获取流程定义具体信息 repositoryService.activateProcessDefinitionById() 激活流程定义 repositoryService.suspendProcessDefinitionById() 挂起流程定义 repositoryService.deleteDeployment() 删除流程定义 repositoryService.getProcessDiagram()获取流程定义图片流 repositoryService.getResourceAsStream()获取流程定义xml流 repositoryService.getBpmnModel(pde.getId()) 获取bpmn对象(当前进行到的那个节点的流程图使用) 4.流程定义授权相关 repositoryService.getIdentityLinksForProcessDefinition() 流程定义授权列表 repositoryService.addCandidateStarterGroup()新增组流程授权 repositoryService.addCandidateStarterUser()新增用户流程授权 repositoryService.deleteCandidateStarterGroup() 删除组流程授权 repositoryService.deleteCandidateStarterUser() 删除用户流程授权 ~~~ ### RuntimeService 处理正在运行的流程。 ~~~ runtimeService.createProcessInstanceBuilder().start() 发起流程 runtimeService.deleteProcessInstance() 删除正在运行的流程 runtimeService.suspendProcessInstanceById() 挂起流程定义 runtimeService.activateProcessInstanceById() 激活流程实例 runtimeService.getVariables(processInstanceId); 获取表单中填写的值 runtimeService.getActiveActivityIds(processInstanceId)获取以进行的流程图节点 (当前进行到的那个节点的流程图使用) runtimeService.createChangeActivityStateBuilder().moveExecutionsToSingleActivityId(executionIds, endId).changeState(); 终止流程 ~~~ ### HistoryService 在用户发起审批后,会生成流程实例。historyService 为处理流程实例的 api,但是其中包括了已经完成的和未完成的流程实例。 ~~~ historyService.createHistoricProcessInstanceQuery().list() 查询流程实例列表(历史流程,包括未完成的) historyService.createHistoricProcessInstanceQuery().list().foreach().getValue() 可以获取历史中表单的信息 historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); 根绝id查询流程实例 historyService.deleteHistoricProcessInstance() 删除历史流程 historyService.deleteHistoricTaskInstance(taskid); 删除任务实例 historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list() 流程实例节点列表 (当前进行到的那个节点的流程图使用) ~~~ > 如果处理正在运行的流程实例,请使用 RuntimeService。 ### TaskService 对流程实例的各个节点的审批处理。 ~~~ 流转的节点审批 taskService.createTaskQuery().list() 待办任务列表 taskService.createTaskQuery().taskId(taskId).singleResult(); 待办任务详情 taskService.saveTask(task); 修改任务 taskService.setAssignee() 设置审批人 taskService.addComment() 设置审批备注 taskService.complete() 完成当前审批 taskService.getProcessInstanceComments(processInstanceId); 查看任务详情(也就是都经过哪些人的审批,意见是什么) taskService.delegateTask(taskId, delegater); 委派任务 taskService.claim(taskId, userId);认领任务 taskService.unclaim(taskId); 取消认领 taskService.complete(taskId, completeVariables); 完成任务 任务授权 taskService.addGroupIdentityLink()新增组任务授权 taskService.addUserIdentityLink() 新增人员任务授权 taskService.deleteGroupIdentityLink() 删除组任务授权 taskService.deleteUserIdentityLink() 删除人员任务授权 ~~~ ### ManagementService 主要是执行自定义命令。 ~~~ managementService.executeCommand(new classA()) 执行classA的内部方法,classA要实现Command,重写execute方法 ~~~ 在自定义的方法中可以使用以下方法获取 repositoryService。 ~~~ ProcessEngineConfiguration processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); RepositoryService repositoryService = processEngineConfiguration.getRepositoryService(); ~~~ 也可以获取流程定义方法集合 。 ~~~ ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext); ProcessDefinitionEntityManager processDefinitionEntityManager = processEngineConfiguration.getProcessDefinitionEntityManager(); 如findById/findLatestProcessDefinitionByKey/findLatestProcessDefinitionByKeyAndTenantId等。 ~~~ ### IdentityService 用于身份信息获取和保存,这里主要是获取身份信息。 ~~~ identityService.createUserQuery().userId(userId).singleResult(); 获取审批用户的具体信息 identityService.createGroupQuery().groupId(groupId).singleResult(); 获取审批组的具体信息 ~~~ 举例说明: ## 学生请假流程图  student.bpmn20.xml ~~~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:flowable="http://flowable.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.flowable.org/processdef"> <process id="StudentLeave" name="学生请假流程" isExecutable="true"> <startEvent id="start" name="开始" flowable:formFieldValidation="true"></startEvent> <userTask id="apply" name="请假申请" flowable:assignee="${studentUser}" flowable:formFieldValidation="true"> <extensionElements> <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete> </extensionElements> </userTask> <userTask id="teacherPass" name="老师审批" flowable:candidateGroups="teacher" flowable:formFieldValidation="true"></userTask> <exclusiveGateway id="judgeTask" name="判断是否大于2天"></exclusiveGateway> <endEvent id="end" name="结束"></endEvent> <userTask id="principalPass" name="校长审批" flowable:candidateGroups="principal" flowable:formFieldValidation="true"></userTask> <sequenceFlow id="principalCheck" name="通过" sourceRef="principalPass" targetRef="end"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="principalNotPassFlow" name="驳回" sourceRef="principalPass" targetRef="apply"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="teacherPassFlow" name="通过" sourceRef="teacherPass" targetRef="judgeTask"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='通过'}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="teacherNotPassFlow" name="驳回" sourceRef="teacherPass" targetRef="apply"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${outcome=='驳回'}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="startFlow" sourceRef="start" name="流程开始" targetRef="apply"></sequenceFlow> <sequenceFlow id="applyFlow" sourceRef="apply" name="申请流程" targetRef="teacherPass"></sequenceFlow> <sequenceFlow id="judgeLess" name="小于2天" sourceRef="judgeTask" targetRef="end"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day <= 2}]]></conditionExpression> </sequenceFlow> <sequenceFlow id="judgeMore" name="大于2天" sourceRef="judgeTask" targetRef="principalPass"> <conditionExpression xsi:type="tFormalExpression"><![CDATA[${day > 2}]]></conditionExpression> </sequenceFlow> </process> <bpmndi:BPMNDiagram id="BPMNDiagram_StudentLeave"> <bpmndi:BPMNPlane bpmnElement="StudentLeave" id="BPMNPlane_StudentLeave"> <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start"> <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="apply" id="BPMNShape_apply"> <omgdc:Bounds height="80.0" width="100.00000000000003" x="229.9708609547486" y="138.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="teacherPass" id="BPMNShape_teacherPass"> <omgdc:Bounds height="80.0" width="99.99999999999994" x="436.9446358140222" y="138.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="judgeTask" id="BPMNShape_judgeTask"> <omgdc:Bounds height="40.0" width="40.0" x="645.0" y="158.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end"> <omgdc:Bounds height="28.0" width="28.0" x="795.0" y="164.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNShape bpmnElement="principalPass" id="BPMNShape_principalPass"> <omgdc:Bounds height="80.0" width="100.0" x="615.0" y="280.0"></omgdc:Bounds> </bpmndi:BPMNShape> <bpmndi:BPMNEdge bpmnElement="judgeLess" id="BPMNEdge_judgeLess"> <omgdi:waypoint x="684.5095911949685" y="178.43356643356645"></omgdi:waypoint> <omgdi:waypoint x="795.0000829380081" y="178.04860604497966"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="principalNotPassFlow" id="BPMNEdge_principalNotPassFlow"> <omgdi:waypoint x="615.0" y="320.0"></omgdi:waypoint> <omgdi:waypoint x="279.9708609547486" y="320.0"></omgdi:waypoint> <omgdi:waypoint x="279.9708609547486" y="217.95000000000002"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="judgeMore" id="BPMNEdge_judgeMore"> <omgdi:waypoint x="665.4326241134752" y="197.51043586109145"></omgdi:waypoint> <omgdi:waypoint x="665.1411660777385" y="280.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="teacherNotPassFlow" id="BPMNEdge_teacherNotPassFlow"> <omgdi:waypoint x="486.9446358140222" y="138.0"></omgdi:waypoint> <omgdi:waypoint x="486.9446358140222" y="98.8874737106014"></omgdi:waypoint> <omgdi:waypoint x="279.9708609547486" y="98.8874737106014"></omgdi:waypoint> <omgdi:waypoint x="279.9708609547486" y="138.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="principalCheck" id="BPMNEdge_principalCheck"> <omgdi:waypoint x="714.9499999999886" y="319.64664310954066"></omgdi:waypoint> <omgdi:waypoint x="806.5" y="319.0"></omgdi:waypoint> <omgdi:waypoint x="808.7518112709728" y="191.94785201600882"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="applyFlow" id="BPMNEdge_applyFlow"> <omgdi:waypoint x="329.9208609546613" y="178.0"></omgdi:waypoint> <omgdi:waypoint x="436.9446358140222" y="178.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="teacherPassFlow" id="BPMNEdge_teacherPassFlow"> <omgdi:waypoint x="536.8946358140222" y="178.0"></omgdi:waypoint> <omgdi:waypoint x="645.0" y="178.0"></omgdi:waypoint> </bpmndi:BPMNEdge> <bpmndi:BPMNEdge bpmnElement="startFlow" id="BPMNEdge_startFlow"> <omgdi:waypoint x="129.94999932842546" y="178.0"></omgdi:waypoint> <omgdi:waypoint x="229.970860954748" y="178.0"></omgdi:waypoint> </bpmndi:BPMNEdge> </bpmndi:BPMNPlane> </bpmndi:BPMNDiagram> </definitions> ~~~ ## 自动部署 复制到项目【resources/processes】目录下 ## 手动部署 ~~~ @Test void deploy(){ Deployment deployment = repositoryService.createDeployment() .addClasspathResource("student.bpmn20.xml") .name("学生请假流程").deploy(); System.out.println("deployment.getId() = " + deployment.getId()); System.out.println("deployment.getName() = " + deployment.getName()); } ~~~ ## 查看已部署的流程 ~~~ @Test public void testProcessDefinition() { List<ProcessDefinition> processList = repositoryService.createProcessDefinitionQuery().list(); for(ProcessDefinition processDefinition : processList){ log.info("ProcessDefinition name = {},deploymentId = {}", processDefinition.getName(), processDefinition.getDeploymentId()); } } ~~~ ## 测试刚刚的学生请假 ~~~ @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; @Test public void testFlow() { // 发起请假 Map<String, Object> map = new HashMap<>(); map.put("day", 2); map.put("studentUser", "小明"); ProcessInstance studentLeave = runtimeService.startProcessInstanceByKey("StudentLeave", map); Task task = taskService.createTaskQuery().processInstanceId(studentLeave.getId()).singleResult(); taskService.complete(task.getId()); // 老师审批 List<Task> teacherTaskList = taskService.createTaskQuery().taskCandidateGroup("teacher").list(); Map<String, Object> teacherMap = new HashMap<>(); teacherMap.put("outcome", "通过"); for (Task teacherTask : teacherTaskList) { taskService.complete(teacherTask.getId(), teacherMap); } // 校长审批 List<Task> principalTaskList = taskService.createTaskQuery().taskCandidateGroup("principal").list(); Map<String, Object> principalMap = new HashMap<>(); principalMap.put("outcome", "通过"); for (Task principalTask : principalTaskList) { taskService.complete(principalTask.getId(), principalMap); } // 查看历史 List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId(studentLeave.getId()) .finished() .orderByHistoricActivityInstanceEndTime().asc() .list(); for (HistoricActivityInstance activity : activities) { System.out.println(activity.getActivityName()); } } ~~~ ## 打印结果 ~~~ 开始 流程开始 请假申请 申请流程 老师审批 通过 判断是否大于2天 小于2天 结束 ~~~
superadmin
2023年11月22日 10:32
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码