系列文章目录
第一章 springboot+Activiti7整合实践 (一)
前言
之前的文章以公司基础框架搭建了activiti7工作流,并生成了数据库表,本次在此基础上,添加模型定义功能,主要介绍后端内容,前端采用的芋道的界面,故只贴出关键代码逻辑,有兴趣的可以去参考一下。
一、完成功能介绍
(1) 模型查询和添加
(2)设计流程
本章节主要完成以上功能,我们一步一步来实现。
此功能整体逻辑借用芋道设计的思想,设计流程图时不设置用户任务的代办人等信息,而是采用单独的功能,未每一个用户任务节点设置代办人逻辑,这个后面细说,
二、功能实现
1.工作流关键类介绍
ProcessEngine 流程引擎:最核心的类,其他类对象都由此类生成,第一章的配置信息,其实配置的就是是流程引擎,由配置类产生,介绍一下编程方式。
ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource);
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName); // 配置不同的bean id
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream);
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName);
以上几个方法是产生ProcessEngineConfiguration对象的不同方式,ProcessEngineConfiguration对象再调用buildProcessEngine()后, 就会创建一个ProcessEngine引擎对象,一切都围绕的这个对象展开。
这里只介绍第一个方式,默认会读取classpath目录下的 activiti.cfg.xml文件来生成ProcessEngineConfiguration,我们暂时使用的是springboot自动装配的方式生成的对象,
起点类是:ProcessEngineAutoConfiguration,大家可以记录一下这里,后面涉及到规则分配时,会进行改造,目前只做介绍。
有兴趣的可以阅读以下文章:
service对象
各个Service | 作用 |
RepositoryService | 管理流程定义 |
RuntimeService | 执行管理,包括启动、推进、删除流程实例等操作 |
TaskService | 任务管理 |
HistoryService | 历史管理(执行完的数据的管理) |
IdentityService | 组织机构管理(未用到) |
FormService | 一个可选服务,任务表单管理(未用到) |
ManagerService | 引擎管理(未用到) |
以上使用到的service都由引擎对象产生,
由于是springboot项目,直接使用spring的依赖注入即可,如:
2.模型定义服务类
主要服务方法为创建和查询,用到RepositoryService流程定义类,涉及查询和添加方法,涉及的数库表为act_re_model,以下贴出表和代码。
表中主要字段介绍:
KEY_:唯一标识,创建模型,以此为不重复凭据,发布和启动项目时,也以此字段指定使用哪个模型。
REV_:版本号,从1递增,每个模型可发布多次,同一个key_每发布一次,版本号+1。
DEPLOYMENT_ID_:发布id,对应act_re_deployment表的主键id,发布后才会产生数据,模型定义阶段为空,这里强调一下概念,模型定义是定义工作流的流程,未发布的情况下,是不生效的。
其他字段有兴趣可自行了解,多做数据就都知道了,写多了反而记不住重要的。
/**
* 根据key获得Model定义
* */
private Model getModelByKey(String key) {
return repositoryService.createModelQuery().modelKey(key).singleResult();
}
根据key获得model定义。
/**
* 添加模型定义
* */
@Transactional(rollbackFor = Exception.class)
public String createModel(BpmModelCreateReqVO createReqVO, String bpmnXml) {
// 校验流程标识已经存在
Model keyModel = getModelByKey(createReqVO.getKey());
if (keyModel != null) {
throw new RuntimeException("流程标识已存在");
}
// 创建流程定义
Model model = repositoryService.newModel();
copy(model, createReqVO);
// 保存流程定义
repositoryService.saveModel(model);
// 保存 BPMN XML
saveModelBpmnXml(model, bpmnXml);
return model.getId();
}
添加模型定义
/**
* 保存bpmnXml字符串
* */
private void saveModelBpmnXml(Model model, String bpmnXml) {
if (StrUtil.isEmpty(bpmnXml)) {
return;
}
repositoryService.addModelEditorSource(model.getId(), StrUtil.utf8Bytes(bpmnXml));
}
保存bpmnXML,这个是什么呢?就是前端绘制的流程图,其实绘制生成的是一堆xml代码,到这里我们暂时没有绘制流程图,传参数时会传null,所以实际不会执行,等设计流程时才会使用到。
/**
* 模型分页查询
* */
public Page<BpmModelVO> selectModelList(ProcessDefinitionDTO processDefinition, Integer page, Integer size) {
Page<BpmModelVO> list = new Page<>();
ModelQuery modelQuery = repositoryService.createModelQuery();
if (StringUtils.isNotBlank(processDefinition.getName())) {
modelQuery.modelNameLike("%" + processDefinition.getName() + "%");
}
if (StringUtils.isNotBlank(processDefinition.getKey())) {
modelQuery.modelKey(processDefinition.getKey());
}
// 执行查询
List<Model> models = modelQuery.orderByCreateTime().desc()
.listPage((page - 1) * size, size);
// 获得 Deployment Map
Set<String> deploymentIds = new HashSet<>();
models.forEach(model -> CollectionUtils.addIfNotNull(deploymentIds, model.getDeploymentId()));
Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds);
// 获得 ProcessDefinition Map
List<ProcessDefinition> processDefinitions = getProcessDefinitionListByDeploymentIds(deploymentIds);
Map<String, ProcessDefinition> processDefinitionMap = CollectionUtils.convertMap(processDefinitions, ProcessDefinition::getDeploymentId);
for(int i=0;i<models.size();i++){
BpmModelVO bpmModelVO = new BpmModelVO();
Model model = models.get(i);
bpmModelVO.setModel(model);
if(StringUtil.isNotEmpty(model.getDeploymentId())){
Deployment deployment = deploymentMap.get(model.getDeploymentId());
ProcessDefinition processDefinition1 = processDefinitionMap.get(model.getDeploymentId());
bpmModelVO.setVersion(""+processDefinition1.getVersion());
bpmModelVO.setDeploymentTime(deployment.getDeploymentTime());
bpmModelVO.setDeploymentId(deployment.getId());
bpmModelVO.setProcessDefinitionId(processDefinition1.getId());
if(processDefinition1.isSuspended()){
bpmModelVO.setSuspendState(SuspendStateEnum.SUSPEND.getKey());
}else{
bpmModelVO.setSuspendState(SuspendStateEnum.NORMAL.getKey());
}
}
list.add(bpmModelVO);
}
return list;
}
这里的主要思路是通过repositoryService对象,查询所有符合搜索条件的model定义,因为列表还需要展示发布相关信息,如以下四个字段,未部署的情况下是没有值的,这两句关键代码也仅仅是为了查询出发布信息,和流程定义信息,这里我们暂时是没有值的,如列表第一行显示信息。
Map<String, Deployment> deploymentMap = getDeploymentMap(deploymentIds); // 获得 ProcessDefinition Map List<ProcessDefinition> processDefinitions = getProcessDefinitionListByDeploymentIds(deploymentIds);
总结
这里功能实现,想讲的很多,但涉及很多知识点贯穿,建议大家实践前,还需对activiti工作流有一个初步的使用,我就是现在测试类里,用测试方法,发布流程、启动、运行之后,才开始整体集合页面开发的。