版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/answer100answer/article/details/88355126
文章目录
1. 介绍
流程概念
![](https://img-blog.csdnimg.cn/20190308171545409.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Fuc3dlcjEwMGFuc3dlcg==,size_16,color_FFFFFF,t_70)
![](https://img-blog.csdnimg.cn/20190308213944277.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2Fuc3dlcjEwMGFuc3dlcg==,size_16,color_FFFFFF,t_70)
初识
1.https://github.com/Activiti/Activiti/releases/ 页面下载release版本,如activiti-6.0.0.zip
2.将activiti-app.war
和activiti-admin.war
两个war包复制到tomcat/webapp/下,并启动tomcat。
3.访问:http://localhost:8080/activiti-app/#/ admin test 登录进入activiti-app页面
实战体验
目标:设计二级审批流程。3个用户参与协同完成流程。
过程1:创建流程
- 创建用户:点击
identity management
–>user
–>create user
,创建3个用户:
- 创建流程:点击
kickStart app
–>process
–>create process
- 配置节点:为leader审批、hr审批节点指定
assignments
,users为已经建的对应的leader、hr用户,保存。 - 创建模块并发布:点击
app
–>create app
,创建一个模块,选中已建的流程,保存勾选Publish
。
过程2:发起流程并审批
- 使用已经创建的whb用户登录。
- 进入审批模块启动刚才创建的流程。
- 分别使用leader、hr账号登录。complete审批。
- 审批结束后,当前页面无法再看到。登录 http://localhost:8080/activiti-admin/ 页面。修改actions,端口8080(tomcat端口),密码test(和app页面一直),check通过才行。通过该页面中的导航,可以找到刚才的流程。
2. 二级审批流程入门工程
流程模型:
1.创建流程生成bpmn文件:
- eclipse离线安装activiti designer插件。
- new other–>Activiti Diagram
- 画如上图所示流程图,在properties中填写id和name。
- 定义【填写审批信息】中的from:
- 定义【主管审批】form:
- 定义【HR审批】form:
对于每一个网关节点,需要判断前一个From中的关键字段。通过el表达式局决定走哪一个分支。
- 【填写信息】后的网关gateway1,确认申请后,将会走主管审批,否则直接结束。关键字段是form中填写的submitType。通过分支main config:
通过分支:
${submitType == "y" || submitType == "Y"}
拒绝分支:
${submitType == "n" || submitType == "N"}
- 后边的gateway2、gateway3同理。
至此,bpmn文件生成完毕。
2.引入依赖
<?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>
<groupId>cn.whbing</groupId>
<artifactId>activiti-test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>5.22.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- log-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<!-- log-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.176</version>
</dependency>
</dependencies>
</project>
说明:
(1)依赖activiti-engine
(2)单元测试junit
(3)logback:这里仅仅引入logback,不需再slf
(4)h2内置数据库依赖
文件结构:
简化log输出,可以在resource/下放置logback.xml配置。
logback.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="30 second">
<property name="log.dir" value="logs" />
<property name="encoding" value="UTF-8" />
<property name="plain" value="%msg%n" />
<property name="std" value="%d{HH:mm:ss.SSS}[%thread][%-5level]%msg" />
<!-- 这里临时定义了简单方式 -->
<!-- 控制台打印 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${plain}</pattern>
<charset>${encoding}</charset>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${log.dir}/file.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.dir}/file.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${plain}</pattern>
<charset>${encoding}</charset>
</encoder>
</appender>
<logger name="cn.whbing.activiti">
<level value="debug"/>
</logger>
<logger name="root">
<level value="error"/>
</logger>
<!-- Logger 根目录 -->
<root>
<appender-ref ref="stdout" />
<appender-ref ref="file" />
</root>
</configuration>
可以直接编写DemoMain进行测试:
DemoMain
:
public class DemoMain {
private static final Logger log = LoggerFactory.getLogger(DemoMain.class);
public static void main(String[] args) throws Exception{
log.info("启动程序");
//1.创建流程引擎
ProcessEngineConfiguration cfg = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
ProcessEngine engine = cfg.buildProcessEngine();
String name = engine.getName();
String version = ProcessEngine.VERSION;
log.info("流程引擎名称:{},版本:{}",name,version);
//2.部署流程定义文件
RepositoryService repositoryService = engine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("diagrams/Second_Approve.bpmn").deploy();
String deployId = deployment.getId();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
log.info("流程定义文件:{},流程ID:{}",processDefinition.getName(),processDefinition.getId());
//3.启动运行流程
RuntimeService runtimeService = engine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
log.info("启动流程:{}",processInstance.getProcessDefinitionKey());
//4.处理流程任务
Scanner scanner = new Scanner(System.in);
while (processInstance != null && !processInstance.isEnded()){
TaskService taskServer = engine.getTaskService();
long count = taskServer.createTaskQuery().count();
log.info("taskCount:{}",count);
List<Task> tasks = taskServer.createTaskQuery().list();
for (Task task : tasks) {
log.info("待处理任务:{}",task.getName());
FormService formService = engine.getFormService();
TaskFormData taskFormData = formService.getTaskFormData(task.getId());
List<FormProperty> formProperties = taskFormData.getFormProperties();
Map<String,Object> variables = Maps.newHashMap();
String line = null;
for (FormProperty formProperty : formProperties) {
if(StringFormType.class.isInstance(formProperty.getType())){
System.out.println("请输入"+formProperty.getName()+":");
line = scanner.nextLine();
log.info("你输入的内容为:{}",line);
variables.put(formProperty.getId(),line);
}else if(DateFormType.class.isInstance(formProperty.getType())){
System.out.println("请输入"+formProperty.getName()+"(格式 yyyy-MM-dd)"+":");
line = scanner.nextLine();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = simpleDateFormat.parse(line);
variables.put(formProperty.getId(),line);
}else {
log.info("类型不支持");
}
log.info("你输入的内容为:{}",line);
}
taskServer.complete(task.getId(),variables);
//更新processInstance
processInstance = engine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult();
}
log.info("待处理任务数量:{}",tasks.size());
}
scanner.close();
//流程结束
log.info("流程结束");
}
}
直接运行:
启动程序
流程引擎名称:default,版本:5.22.0.0
流程定义文件:二级审批流程,流程ID:second_approve:1:4
启动流程:second_approve
taskCount:1
待处理任务:用户填写信息
请输入申请信息:
加薪
你输入的内容为:加薪
你输入的内容为:加薪
请输入申请人姓名:
whb
你输入的内容为:whb
你输入的内容为:whb
请输入申请时间(格式 yyyy-MM-dd):
2019-03-10
你输入的内容为:2019-03-10
请输入确认申请:
y
你输入的内容为:y
你输入的内容为:y
待处理任务数量:1
taskCount:1
待处理任务:领导审批
请输入领导审批:
y
你输入的内容为:y
你输入的内容为:y
请输入领导备注:
通过
你输入的内容为:通过
你输入的内容为:通过
待处理任务数量:1
taskCount:1
待处理任务:HR审批
请输入HR审批:
n
你输入的内容为:n
你输入的内容为:n
请输入HR备注:
不通过
你输入的内容为:不通过
你输入的内容为:不通过
待处理任务数量:1
taskCount:1
待处理任务:用户填写信息