如对activiti没大概了解和开发的话,请移步到使用IDEA对springboot+activiti开发之简单流程(一)
详细代码demo,在这里→https://download.youkuaiyun.com/download/qq_28582847/10344437
1.画工作流程图(这里直接上流程图代码)
<?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:activiti="http://activiti.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.activiti.org/test">
<process id="demo5" name="My process" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<serviceTask id="servicetask1" name="业户提交" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"tj")}"></serviceTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="servicetask1"></sequenceFlow>
<userTask id="usertask1" name="受理" activiti:candidateUsers="${activityDemoServiceImpl.findUsersForSL(execution)}"></userTask>
<sequenceFlow id="flow2" sourceRef="servicetask1" targetRef="usertask1"></sequenceFlow>
<exclusiveGateway id="exclusivegateway1" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow3" sourceRef="usertask1" targetRef="exclusivegateway1"></sequenceFlow>
<userTask id="usertask2" name="审批" activiti:candidateUsers="${activityDemoServiceImpl.findUsersForSP(execution)}"></userTask>
<sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="usertask2">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${sign=="true"}]]></conditionExpression>
</sequenceFlow>
<serviceTask id="servicetask2" name="已签发" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"yqf")}"></serviceTask>
<endEvent id="endevent1" name="End"></endEvent>
<sequenceFlow id="flow6" sourceRef="servicetask2" targetRef="endevent1"></sequenceFlow>
<serviceTask id="servicetask3" name="资料不全" activiti:async="true" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,"zlbq")}"></serviceTask>
<sequenceFlow id="flow8" sourceRef="exclusivegateway1" targetRef="servicetask3">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${sign=="false"}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow9" sourceRef="servicetask3" targetRef="endevent1"></sequenceFlow>
<exclusiveGateway id="exclusivegateway2" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow10" sourceRef="usertask2" targetRef="exclusivegateway2"></sequenceFlow>
<sequenceFlow id="flow11" sourceRef="exclusivegateway2" targetRef="servicetask2"></sequenceFlow>
<sequenceFlow id="flow12" sourceRef="exclusivegateway2" targetRef="servicetask3"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_demo5">
<bpmndi:BPMNPlane bpmnElement="demo5" id="BPMNPlane_demo5">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="120.0" y="220.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask1" id="BPMNShape_servicetask1">
<omgdc:Bounds height="55.0" width="105.0" x="200.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="350.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="BPMNShape_exclusivegateway1">
<omgdc:Bounds height="40.0" width="40.0" x="500.0" y="217.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="560.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask2" id="BPMNShape_servicetask2">
<omgdc:Bounds height="55.0" width="105.0" x="780.0" y="210.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="910.0" y="217.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="servicetask3" id="BPMNShape_servicetask3">
<omgdc:Bounds height="55.0" width="105.0" x="670.0" y="70.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="BPMNShape_exclusivegateway2">
<omgdc:Bounds height="40.0" width="40.0" x="702.0" y="217.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="155.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="200.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="305.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="350.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="455.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="500.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="540.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="560.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6">
<omgdi:waypoint x="885.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="910.0" y="234.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
<omgdi:waypoint x="520.0" y="217.0"></omgdi:waypoint>
<omgdi:waypoint x="520.0" y="97.0"></omgdi:waypoint>
<omgdi:waypoint x="670.0" y="97.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow9" id="BPMNEdge_flow9">
<omgdi:waypoint x="775.0" y="97.0"></omgdi:waypoint>
<omgdi:waypoint x="927.0" y="97.0"></omgdi:waypoint>
<omgdi:waypoint x="927.0" y="217.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
<omgdi:waypoint x="665.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="702.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
<omgdi:waypoint x="742.0" y="237.0"></omgdi:waypoint>
<omgdi:waypoint x="780.0" y="237.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
<omgdi:waypoint x="722.0" y="217.0"></omgdi:waypoint>
<omgdi:waypoint x="722.0" y="125.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
解析:
(1)从代码中我们可以看到一些像java类名和方法的字样,如<serviceTask id="servicetask2" name="已签发" activiti:expression="#{activityDemoServiceImpl.updateBizStatus(execution,'yqf')}"></serviceTask>这段代码就是进入该“已签发”流程节点时候,先进行调用activityDemoServiceImpl这个类中updateBizStatus方法。
(2) <sequenceFlow id="flow4" sourceRef="exclusivegateway1" targetRef="usertask2"><conditionExpression xsi:type="tFormalExpression"><![CDATA[${sign=="true"}]]></conditionExpression></sequenceFlow>这段代码意思是当你传入到后台 sign = "true"的时候,走flow4的这条线,从exclusivegateway1到usertask2节点。
2.搭建springboot+maven的项目
1)修改pom.xml文件,代码如下:
<?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>com.activiti</groupId>
<artifactId>MyActiviti</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional><!-- optional=true,依赖不会传递,该项目依赖devtools;之后依赖myboot项目的项目如果想要使用devtools,需要重新引入 -->
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2)在application.properties增加数据库连接(程序启动后,表都是系统自建)
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/activitiy?characterEncoding=utf8&useSSL=true
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
server.context-path=/workFlow
server.session.timeout=10
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8
server.port=8081
spring.activiti.check-process-definitions=false
3)将demo5.bpmn文件放入到resources/templates目录下
4)编写一个controller类
代码如下:
@RestController
@RequestMapping("/demo5")
public class Demo5Controller {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@RequestMapping("/firstDemo")
public void firstDemo() {
//根据bpmn文件部署流程
Deployment deployment = repositoryService.createDeployment().addClasspathResource("templates/demo5.bpmn").deploy();
//获取流程定义
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).singleResult();
System.out.println(processDefinition.getId()+";"+processDefinition.getKey());
//启动流程定义,返回流程实例(提供了多种方式)
//ProcessInstance pi = runtimeService.startProcessInstanceById(processDefinition.getId());
ProcessInstance pi = runtimeService.startProcessInstanceByKey("demo5");
System.out.println("流程创建成功,当前流程实例ID:"+pi.getId());
List<Task> resultTask = taskService.createTaskQuery().processDefinitionKey("demo5").taskCandidateOrAssigned("sly1").list();
System.out.println("任务列表:"+resultTask);
//在受理节点中,用户sly1表示通过该节点,进入下一个节点审批(true:通过,false:不通过)
taskService.claim(resultTask.get(0).getId(), "sly1");
Map<String,Object> vars = new HashMap<String,Object>();
vars.put("sign", "true");
taskService.complete(resultTask.get(0).getId(), vars);
Task task = taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();
System.out.println("当前节点:"+task.getName());
//在审批节点中,用户uspy2表示通过该节点,进入下个系统节点“签发”中
resultTask = taskService.createTaskQuery().processDefinitionKey("demo5").taskCandidateOrAssigned("uspy2").list();
taskService.claim(resultTask.get(0).getId(), "sly1");
Map<String,Object> vars2 = new HashMap<String,Object>();
vars2.put("sign", "true");
taskService.complete(resultTask.get(0).getId(), vars2);
}
}
5)编写一个service类
代码如下
@Service
public class ActivityDemoServiceImpl {
/**
* 更改业务流程状态#{ActivityDemoServiceImpl.updateBizStatus(execution,"tj")}
* @param execution
* @param status
*/
public void updateBizStatus(DelegateExecution execution, String status) {
String bizId = execution.getProcessBusinessKey();
//根据业务id自行处理业务表
System.out.println("业务表["+bizId+"]状态更改成功,状态更改为:"+status);
}
//流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}
public List<String> findUsersForSL(DelegateExecution execution){
//return Arrays.asList("sly1","sly2");
return Arrays.asList("sly1");
}
//流程节点权限用户列表${ActivityDemoServiceImpl.findUsers(execution,sign)}
public List<String> findUsersForSP(DelegateExecution execution){
return Arrays.asList("uspy2");
}
}
解析:findUserForSL方法中,主要内容是设置该流程节点的办理人"sly1"
5)启动application.java类,访问http://localhost:8081/workFlow/demo5/firstDemo,查看控制台