https://gitee.com/luozijing123/JooLun-wx开源项目中集成了activity和Flowable 工作流,能够快速开始从页面建立一个流程,完成对应节点的任务,流程全程自动化和可视化,体验较好,下面来看看项目中是如何集成的以及Flowable流程是如何工作的。activity流程经对比缺陷较多,暂时不研究。源项目在线体验地址http://dashboard.yudao.iocoder.cn/login?redirect=%2Findex。
不了解的floweable的可以看看相关资料,这里主要介绍开源项目为主。
根据流程规范bpmn2.0构建流程图,建立bpmn模型,对应ACT_RE_MODEL 表,存储bpmn.xml到ACT_GE_BYTEARRAY 表,形成模型存储对象对象,后续绑定流程规则,部署流程,流程任务。都是依据bpmn保存的模型对象而来。项目中对应的流程设计页面如下,可亲自体验设计流程,导出bpmn.xml的流程图。
流程设计完后开始部署流程以及发起流程任务,在ACT_RU_EXECUTION表中创建新的流程id,ACT_RU_TASK表记录当前的任务状态以及任务处理人,它们都是基于ACT_RE_PROCDEF 一开始定义的流程图,以及相应的流程规则等。在整个流程实施过程中,对于各个不同的任务参与者都是可视化的。
新建了一个单独的模块yudao-spring-boot-starter-flowable承载flowerable的引入,作用时设置的flowerable引擎的用户上下文org.flowable.common.engine.impl.identity.Authentication;设置用户ID
cn.iocoder.boot
yudao-common
cn.iocoder.boot
yudao-spring-boot-starter-security
org.flowable
flowable-spring-boot-starter-basic
org.flowable
flowable-spring-boot-starter-actuator
具体的Flowable 二次开发放在yudao-module-bpm-impl-flowable中,引入上述模块,即可使用Flowable 功能。
项目中对flowerable进行了配置,实现流程变更、任务变更的时候的监听器,以及根据任务分配的规则在任务创建时进行任务分配。监听器在项目中主要作用时更新对应的业务拓展表。
package cn.iocoder.yudao.module.bpm.framework.flowable.config;
import java.util.List;
/**
* BPM 模块的 Flowable 配置类
*
* @author jason
*/
@Configuration
public class BpmFlowableConfiguration {
/**
* BPM 模块的 ProcessEngineConfigurationConfigurer 实现类:
*
* 1. 设置各种监听器
* 2. 设置自定义的 ActivityBehaviorFactory 实现
*/
@Bean
public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> bpmProcessEngineConfigurationConfigurer(
ObjectProvider<FlowableEventListener> listeners,
BpmActivityBehaviorFactory bpmActivityBehaviorFactory) {
return configuration -> {
// 注册监听器,例如说 BpmActivitiEventListener
configuration.setEventListeners(ListUtil.toList(listeners.iterator()));
// 设置 ActivityBehaviorFactory 实现类,用于流程任务的审核人的自定义
configuration.setActivityBehaviorFactory(bpmActivityBehaviorFactory);
};
}
@Bean
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService,
BpmUserGroupService userGroupService,
PermissionApi permissionApi,
DeptApi deptApi,
AdminUserApi adminUserApi,
List<BpmTaskAssignScript> scripts) {
BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
bpmActivityBehaviorFactory.setUserGroupService(userGroupService);
bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi);
bpmActivityBehaviorFactory.setPermissionApi(permissionApi);
bpmActivityBehaviorFactory.setDeptApi(deptApi);
bpmActivityBehaviorFactory.setScripts(scripts);
return bpmActivityBehaviorFactory;
}
}
项目中,对应Flowable 的api建立了不同controller来开放功能,包括model的增删查改,流程的创建,增删查改,部署以及任务的查看、审批等。都是基于原有Flowable 功能做的。较大区别是增加了任务自动分配审批角色的功能,在流程定义中,可以给不同的任务分配审批人,建立分配规则,映射相应符合规则的账号,同时规则业能自定义,在代码中实现规则的寻找。这样不用人工输入确定审批人,确实比较方面。
项目中介绍的具体步骤如下:
* 自定义的流程任务的 assignee 负责人的分配
* 第一步,获得对应的分配规则;
* 第二步,根据分配规则,计算出分配任务的候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
* 第三步,随机选择一个候选人,则选择作为 assignee 负责人。
*
对应不同分配规则策略,包含角色、部门、一级领导、自定义脚本等
Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) {
Set<Long> assigneeUserIds = null;
if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule);
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) {
assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule);
}
// 移除被禁用的用户
removeDisableUsers(assigneeUserIds);
// 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
if (CollUtil.isEmpty(assigneeUserIds)) {
log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]",
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule));
throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
}
return assigneeUserIds;
}
开源项目实现的Flowable 结合前端使用体验还是不错的,二次开发使用起来的说明也较为不错,不过还有许多Flowable 的功能没有进行整合暴露出来,许多功能特性很难了解到。