目录


1.前言

完成这个功能之前,我负责公司的流程管理模板,在众多的解决方案当中,我选择了Activiti 原因有:

  1. 开源、免费
  2. 整合Springboot较容易

Springboot已经成为开发后端不可缺少的一部分,它是如此完美,如此优秀!

2.准备

1.官方文档:https://www.activiti.org/userguide/

2.下载一份官方准备的demo:https://www.activiti.org/get-started 选择5.X download

这里选择旧版本的原因是:新的版本会如果突然出现一些不知名的错误,或者是版本问题,会让你头皮发麻不知道怎么解决,网上新版本这一类的错误博客也很少,很浪费时间!

3.下载解压

打开wars文件夹,复制war文件包到tomcat,利用tomcat对war包进行一个解压,我们也可以不着急,可以登录官方的demo进行尝试一把

放置到tomcat启动后产生的文件夹

地址:htpp://localhost:你的端口号/activiti-explorer

用户名:kermit 密码:kermit

4.开始整合 mysql + activiti + thymeleaf

        <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>5.22.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

按照官网文档的指示,我们引入springboot-starter 依赖 就是这么方便

2.配置文件

spring.datasource.url=jdbc:mysql://localhost:3306/demo?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ##每次应用启动不检查Activiti数据表是否存在及版本号是否匹配 第一次设置为true 会自动创建表结构,之后即可设置为false 提高运行速度
spring.activiti.database-schema-update=true

3.复制文件

复制我们刚才放到tomcat解压后的文件,选择以下文件夹和文件复制到springboot static文件夹下

  • diagram-viewer 文件夹
  • editor-app 文件夹
  • modeler.html

4.加入控制器

复制这三个文件到任意包下,并且为这三个文件加入注解:@RequestMapping("/service")

5.修改配置文件

修改editor-app/app-cfg.js文件,修改其请求路径 和刚才修改的请求路径保持一致

6.剔除启动类里面的安全校验

@SpringBootApplication(exclude = {
org.activiti.spring.boot.SecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})

7.项目启动完毕,查看数据库

25张表结构创建完毕,我简单引用一下别人的博客内容如下:

u  ACT_GE_* : “GE”代表“General”(通用),用在各种情况下;

u  ACT_HI_* : “HI”代表“History”(历史),这些表中保存的都是历史数据,比如执行过的流程实例、变量、任务,等等。Activit默认提供了4种历史级别:

Ø  none: 不保存任何历史记录,可以提高系统性能;

Ø  activity:保存所有的流程实例、任务、活动信息;

Ø  audit:也是Activiti的默认级别,保存所有的流程实例、任务、活动、表单属性;

Ø  full:最完整的历史记录,除了包含audit级别的信息之外还能保存详细,例如:流程变量。

这位大神的链接地址:https://www.cnblogs.com/telwanggs/p/7491564.html 查看更详细的表结构介绍 

8.访问静态资源被拦截问题--》加入资源处理器

@Configuration
@EnableWebMvc
public class StaticResourceConfig implements WebMvcConfigurer { @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
} }

开始流程代码以及逻辑

1.首先是创建模型

创建模型呢可谓是流程管理的第一项,创建一个模型,我们呢需要在这个模型上进行流程图的设计与修改,首先把模型创建好

这里只展示部分代码,展示主要的功能,其他的具体内容,在文章尾部clone项目后进行查看

@RequestMapping("createModel")
public String createModel(HttpServletRequest request, HttpServletResponse response){

String name = "请假流程";
String description = "这是一个请假流程";

String id = null;
try {
Model model = repositoryService.newModel();
String key = name;
//版本号
String revision = "1";
ObjectNode modelNode = objectMapper.createObjectNode();
modelNode.put(ModelDataJsonConstants.MODEL_NAME, name);
modelNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
modelNode.put(ModelDataJsonConstants.MODEL_REVISION, revision);

model.setName(name);
model.setKey(key);
//模型分类 结合自己的业务逻辑
//model.setCategory(category);

model.setMetaInfo(modelNode.toString());

repositoryService.saveModel(model);
id = model.getId();

//完善ModelEditorSource
ObjectNode editorNode = objectMapper.createObjectNode();
editorNode.put("id", "canvas");
editorNode.put("resourceId", "canvas");
ObjectNode stencilSetNode = objectMapper.createObjectNode();
stencilSetNode.put("namespace",
"http://b3mn.org/stencilset/bpmn2.0#");
editorNode.put("stencilset", stencilSetNode);
repositoryService.addModelEditorSource(id, editorNode.toString().getBytes("utf-8"));

response.sendRedirect(request.getContextPath() + "/static/modeler.html?modelId=" + id);
} catch (Exception e) {
e.printStackTrace();
}

return "index";
}

PS 模型建好了肯定要进行画模型 我对流程设计器进行了汉化,这样操作起来方便多了 我简单画一个

一个最简单的请假流程 开始---》人事部审批----》总经理审批------》结束

这张图表示在这个流程开始时候需要填写的一些表单属性 这些都是可以动态加载的!

任务派遣:就表示的意思是:这个任务到底是指派给谁去执行? 我这里指派给张三去执行 当有人提交这个流程的时候 提交的内容填写完 就会有一个信息到张三这儿!

2.模型创建完毕,需要把模型发布为可用的流程定义(Process definition) 需要进行部署

@RequestMapping("deploymentModel")
@ResponseBody
public JSONObject deploymentModel(String id) throws Exception {

//获取模型
Model modelData = repositoryService.getModel(id);
byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

if (bytes == null) {
return JsonUtil.getFailJson("模型数据为空,请先设计流程并成功保存,再进行发布。");
}
JsonNode modelNode = modelNode = new ObjectMapper().readTree(bytes);

BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
if (model.getProcesses().size() == 0) {
return JsonUtil.getFailJson("数据模型不符要求,请至少设计一条主线流程。");
}
byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);

//发布流程
String processName = modelData.getName() + ".bpmn20.xml";
Deployment deployment = repositoryService.createDeployment()
.name(modelData.getName())
.addString(processName, new String(bpmnBytes, "UTF-8"))
.deploy();
modelData.setDeploymentId(deployment.getId());
repositoryService.saveModel(modelData);
return JsonUtil.getSuccessJson("流程发布成功");
}

 1 @RequestMapping("deploymentModel")
2 @ResponseBody
3 public JSONObject deploymentModel(String id) throws Exception {
4
5 //获取模型
6 Model modelData = repositoryService.getModel(id);
7 byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());
8
9 if (bytes == null) {
10 return JsonUtil.getFailJson("模型数据为空,请先设计流程并成功保存,再进行发布。");
11 }
12 JsonNode modelNode = modelNode = new ObjectMapper().readTree(bytes);
13
14 BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
15 if (model.getProcesses().size() == 0) {
16 return JsonUtil.getFailJson("数据模型不符要求,请至少设计一条主线流程。");
17 }
18 byte[] bpmnBytes = new BpmnXMLConverter().convertToXML(model);
19
20 //发布流程
21 String processName = modelData.getName() + ".bpmn20.xml";
22 Deployment deployment = repositoryService.createDeployment()
23 .name(modelData.getName())
24 .addString(processName, new String(bpmnBytes, "UTF-8"))
25 .deploy();
26 modelData.setDeploymentId(deployment.getId());
27 repositoryService.saveModel(modelData);
28 return JsonUtil.getSuccessJson("流程发布成功");
29 }

部署后的流程定义会显示部署ID  这个时候 模板就变成了流程定义

记住这个单词 后面用到的地方特别多!!!!

这里给解释一下这两个词的意思

  • 流程定义:可以理解为画好的流程,已经发布过的,可以拿来用的一个模板
  • 流程实例:流程实例是流程定义由某个用户启动后,它存在于系统当中,它是一个实例;

3.发布后的模型称之为流程定义,开启流程操作

开启流程的时候 我们需要一个页面展示这个流程需要填写的字段等 然后提交进行流程的下一步操作

启动一个流程,这里加载的是我们在画流程图时候输入的表单,这里的提交人就是当前登录的用户(我这里没有整合安全框架 随便写了一个做测试!)

审核人界面进行审批/驳回(暂时未有这个功能)

这里是派遣给张三的任务,刚才提交的任务现在到张三的下面 进行一个审核,然后把这个任务提交到下一级(总经理审核)

这里需要张三进行流程的审批。我们填写表单后,进行提交,现在打开总经理(李四)的任务列表,发现有一个需要待处理的任务!

这里我们既可以看到人事部审核的意见,也可以看到流程开始时候用户提交的内容。流程图也做了相应的更新。

写在最后

作为一个刚接触流程的小白,第一次打开这个流程啥都不懂,也慢慢摸索一些,从网上关于流程Activiti的资料很少。

总的来说就是:

  • 杂乱,没有一个较好的学习资料可以参考
  • 这一方面的博客/文章较少

推荐学习:http://www.agilebpm.cn/

这是博主最近才接触到的一个国内的流程开源版本,总体来说比国外这款Activiti好用,简洁 Api较多,简易

也不能说Activiti人家不好,就是说白了有点复杂,小白一下子上手不了,推荐从这款开源版本开始学习

参考:

https://www.cnblogs.com/zhouyun-yx/p/10410274.html

https://blog.csdn.net/sdufexsh/article/details/83111965#%E8%8E%B7%E5%8F%96UserTask%E4%B8%8A%E5%AE%9A%E4%B9%89%E7%9A%84%E5%8A%A8%E6%80%81%E8%A1%A8%E5%8D%95

https://www.jianshu.com/p/701056e672a4

https://www.cnblogs.com/telwanggs/p/7491564.html

错误解决:

class path resource [processes/] cannot be resolved to URL because it does not exist

解决方案:创建这个processes文件夹到resources下 随便丢个文件进去

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy

解决方案:剔除启动校验问题,向上看第六点

Could not write PNG file because no WriteAdapter is availble

解决方案:

依赖文件引入缺少问题 引入一下即可

<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-codec</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-css</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svg-dom</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
<version>1.7</version>
</dependency>

代码实例开源:

码云:https://gitee.com/mrc1999/activiti

原文链接:https://www.cnblogs.com/ChromeT/p/11261101.html

Springboot 整合Activiti流程设计器 完成一个简单的请假流程的更多相关文章

  1. 流程设计器jQuery + svg/vml(Demo3 - 添加流程结点)

    经过前面的准备工作,终于把设计器的主要UI界面搭建好了,接下来到添加流程结点,效果如下图 代码:GoFlow_03.zip 演示地址:Demo 微信演示公众号: 另:Silverlight版 Silv ...

  2. 2-1. Creating a Simple Model 使用图形界面设计器创建一个简单的模型

    一.创建新项目 二.添加模型文件 三.添加完后,在设计面板空白处右击,创建一个实体 实体集(B) 这里的名称会是对应的数据库表名称!!! ,开始不知道这是什么,生成后才知道表名是这个,以后注意点就行. ...

  3. activiti工作流的web流程设计器整合视频教程 SSM和独立部署

    本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...

  4. activiti工作流的web流程设计器整合视频教程 SSM 和 独立部署

    本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...

  5. activiti工作流的web流程设计器整合视频教程

    本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...

  6. activiti web流程设计器 工作流的 整合视频教程 SSM和独立部署

    本视频为activiti工作流的web流程设计器整合视频教程 整合Acitiviti在线流程设计器(Activiti-Modeler 5.21.0 官方流程设计器) 本视频共讲了两种整合方式 1. 流 ...

  7. 可视化流程设计——流程设计器演示(基于Silverlight)

    上一篇文章<通用流程设计>对鄙人写的通用流程做了一定的介绍,并奉上了相关源码.但一个好的流程设计必少不了流程设计器的支持,本文将针对<通用流程设计>中的流程的设计器做一个简单的 ...

  8. Eclipse安装Activiti插件(流程设计器)

    Eclipse安装Activiti插件(流程设计器) 一.安装步骤: 1,打开Eclipse的 Help -> Install New Software,填上插件地址: Name:Activit ...

  9. 01--安装Activiti流程设计器eclipse插件

    Activiti1 安装流程设计器eclipse插件 Name:Activiti BPMN 2.0 designer(随便起个名字) Location: http://activiti.org/des ...

随机推荐

  1. 【LG5444】[APIO2019]奇怪装置

    [LG5444][APIO2019]奇怪装置 题面 洛谷 题目大意: 给定\(A,B\),对于\(\forall t\in \mathbb N\),有二元组\((x,y)=((t+\lfloor\fr ...

  2. iptables 表和链的对应关系

    filter表 主要用于对数据包进行过滤,根据具体的规则决定是否放行该数据包(如DROP.ACCEPT.REJECT.LOG).filter 表对应的内核模块为iptable_filter,包含三个规 ...

  3. 导出OpenID为txt文件的方法

    导出OpenID为txt文件的方法 public function export(){ $shop = M("Shop"); $arr = $shop->field('ope ...

  4. 【Activiti学习之三】Activiti API(二)

    环境 JDK 1.8 MySQL 5.6 Tomcat 7 Eclipse-Luna activiti 6.0 一.流程定义1.中止与激活流程定义 package com.wjy.pd; import ...

  5. .NET 微服务 1. Docker 容器简介和选择

    容器特点 1. 容器可以将应用程序的依赖性和配置(抽象为 Mainfest 文件并部署)打包成一个容器镜像,可以让多次部署操作中的环境保持一致 2. 可以让IT人员很少或者不做修改就可以跨环境部署软件 ...

  6. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time

    Tomcat在启动是提示: INFO [localhost-startStop-1] org.apache.jasper.servlet.TldScanner.scanJars At least on ...

  7. Linux基础(01)开发环境的搭建

    内核源码下载 : https://blog.csdn.net/u011375704/article/details/81866427 1.在虚拟机安装Ubuntu 14.04版本 (安装时设置好用户名 ...

  8. 用ab每隔30分钟并发一次休息10分钟

    linux脚本监控程序运行情况(重启程序)主要有两种情况:一种是一个可执行文件:如shell脚本文件:另一种是使用python打开的多个程序.第一种:它的进程名字由路径名字和程序名字组成,比如:我有个 ...

  9. css伪类:before及:after除了插入文字内容还能做点儿啥?画图

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/11181416.html 1.什么时候用伪类:before和:after? 结合实际开发情况,说一 ...

  10. C#读写调整修改设置UVC摄像头画面-逆光对比

    有时,我们需要在C#代码中对摄像头的逆光对比进行读和写,并立即生效.如何实现呢? 建立基于SharpCamera的项目 首先,请根据之前的一篇博文 点击这里 中的说明,建立基于SharpCamera的 ...