依赖

1
2
3
4
5
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>

数据库配置

activiti需要很多表存储流程信息(activiti会自动创建),直接使用spring数据源配置

1
2
3
4
5
6
7
8
9
10
11
12
spring:
application:
name: acitiviti
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&allowMultiQueries=true
driver-class-name: com.mysql.cj.jdbc.Driver
activiti:
database-schema-update: true
history-level: full
db-history-used: true

activiti配置类(各种Service)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@Configuration
public class ActivitiConfiguration {
@Autowired
private DataSource dataSource;
@Autowired
private PlatformTransactionManager platformTransactionManager;

@Autowired
private ProcessEngineFactoryBean processEngine;

@Bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(){
SpringProcessEngineConfiguration spec = new SpringProcessEngineConfiguration();
spec.setDataSource(dataSource);
spec.setTransactionManager(platformTransactionManager);
spec.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
Resource[] resources = null;
// 启动自动部署流程
try {
resources = new PathMatchingResourcePatternResolver().getResources("classpath*:bafy.bpmn");
} catch (IOException e) {
e.printStackTrace();
}
spec.setDeploymentResources(resources);
return spec;
}


/**
* Activiti 中每一个不同版本的业务流程的定义都需要使用一些定义文件,部署文件和支持数据 ( 例如 BPMN2.0 XML 文件,表单定义文件,流程定义图像文件等 ),
* 这些文件都存储在 Activiti 内建的 Repository 中。Repository Service 提供了对 repository 的存取服务
* @return
* @throws Exception
*/
@Bean
public RepositoryService repositoryService() throws Exception{
return processEngine.getObject().getRepositoryService();
}
/**
* 在 Activiti 中,每当一个流程定义被启动一次之后,都会生成一个相应的流程对象实例。Runtime Service 提供了启动流程、查询流程实例、设置获取流程实例变量等功能。
* 此外它还提供了对流程部署,流程定义和流程实例的存取服务
* @return
* @throws Exception
*/
@Bean
public RuntimeService runtimeService() throws Exception{
return processEngine.getObject().getRuntimeService();
}
/**
* Activiti 中业务流程定义中的每一个执行节点被称为一个 Task,对流程中的数据存取,状态变更等操作均需要在 Task 中完成。Task Service 提供了对用户 Task 和
* Form 相关的操作。它提供了运行时任务查询、领取、完成、删除以及变量设置等功能
* @return
* @throws Exception
*/
@Bean
public TaskService taskService() throws Exception{
return processEngine.getObject().getTaskService();
}
/**
* 用于获取正在运行或已经完成的流程实例的信息,与 Runtime Service 中获取的流程信息不同,历史信息包含已经持久化存储的永久信息,并已经被针对查询优化
* @return
* @throws Exception
*/
@Bean
public HistoryService historyService() throws Exception{
return processEngine.getObject().getHistoryService();
}

/**
* 用于获取组任务相关记录
* @return
* @throws Exception
*/
@Bean
public IdentityService identityService() throws Exception {
return processEngine.getObject().getIdentityService();
}
}

流程配置xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1659861584170" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" expressionLanguage="http://www.w3.org/1999/XPath" id="_1659861584170" name="test" targetNamespace="http://sourceforge.net/bpmn/definitions/_1659861584170" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="askForLeave" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_2" name="StartEvent"/>
<userTask activiti:assignee="${worker}" activiti:exclusive="true" id="_3" name="项目经理审批"/>
<userTask activiti:assignee="${worker}" activiti:exclusive="true" id="_4" name="部门经理审批">
<multiInstanceLoopCharacteristics activiti:collection="workers" activiti:elementVariable="worker" isSequential="false">
<completionCondition>${nrOfCompletedInstances/nrOfInstances >= 0.5}</completionCondition>
</multiInstanceLoopCharacteristics>
</userTask>
<userTask activiti:assignee="${worker}" activiti:exclusive="true" id="_5" name="总经理审批"/>
<endEvent id="_6" name="EndEvent"/>
<sequenceFlow id="_7" sourceRef="_2" targetRef="_3"/>
<sequenceFlow id="_8" sourceRef="_3" targetRef="_4"/>
<sequenceFlow id="_9" sourceRef="_4" targetRef="_5"/>
<sequenceFlow id="_10" sourceRef="_5" targetRef="_6"/>
</process>
<bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="askForLeave">
<bpmndi:BPMNShape bpmnElement="_2" id="Shape-_2">
<dc:Bounds height="32.0" width="32.0" x="130.0" y="10.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_3" id="Shape-_3">
<dc:Bounds height="55.0" width="85.0" x="100.0" y="115.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_4" id="Shape-_4">
<dc:Bounds height="55.0" width="85.0" x="100.0" y="235.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_5" id="Shape-_5">
<dc:Bounds height="55.0" width="85.0" x="100.0" y="340.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="_6" id="Shape-_6">
<dc:Bounds height="32.0" width="32.0" x="125.0" y="445.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_7" id="BPMNEdge__7" sourceElement="_2" targetElement="_3">
<di:waypoint x="146.0" y="42.0"/>
<di:waypoint x="146.0" y="115.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="_3" targetElement="_4">
<di:waypoint x="142.5" y="170.0"/>
<di:waypoint x="142.5" y="235.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="_4" targetElement="_5">
<di:waypoint x="142.5" y="290.0"/>
<di:waypoint x="142.5" y="340.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="_5" targetElement="_6">
<di:waypoint x="141.0" y="395.0"/>
<di:waypoint x="141.0" y="445.0"/>
<bpmndi:BPMNLabel>
<dc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
@Slf4j
@RestController
@RequestMapping("/askForLeave")
public class askForLeaveController {

@Autowired
private RuntimeService runtimeService;

@Autowired
private TaskService taskService;

private final RepositoryService repositoryService;

public askForLeaveController(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
repositoryService.createDeployment()
.name("请假申请流程")
.addClasspathResource("processes/test.bpmn20.xml")
.addClasspathResource("processes/test.bpmn20.png")
.deploy();
}


@GetMapping("/submit")
public void submit(String username) {
Map map = CollUtil.newHashMap();
map.put("worker", "zhangsan");
//"askForLeave"是流程定义id(processDefinitionKey),即xml文件中<process>标签的id,可通过xml配置,每修改一次xml并重启,则会对流程定义(processDefinition)生成一个新的版本,可在act_re_procdef表中查看
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("askForLeave", username, map);
log.info("processInstance is: {}", processInstance);
}

@GetMapping("/projectManager")
public List<Map> projectManager(String username) {
List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(username).taskAssignee("zhangsan").list();
Map map = CollUtil.newHashMap();
map.put("workers", CollUtil.newArrayList("lisi", "wangwu"));
//总经理审批的处理人不能放到部门经理去设置,可能是因为部门经理审批是个会签
map.put("worker", "zhaoliu");
for (Task task : tasks) {
taskService.complete(task.getId(), map);
}
return toMap(tasks);
}

@GetMapping("/departmentManagerLisi")
public List<Map> departmentManagerLisi(String username) {
List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(username).taskAssignee("lisi").list();
Map map = CollUtil.newHashMap();
for (Task task : tasks) {
taskService.complete(task.getId(), map);
}
return toMap(tasks);
}

@GetMapping("/departmentManagerWangwu")
public List<Map> departmentManagerWangwu(String username) {
List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(username).taskAssignee("wangwu").list();
Map map = CollUtil.newHashMap();
for (Task task : tasks) {
taskService.complete(task.getId(), map);
}
return toMap(tasks);
}

@GetMapping("/generalManager")
public List<Map> generalManager(String username) {
List<Task> tasks = taskService.createTaskQuery().processInstanceBusinessKey(username).taskAssignee("zhaoliu").list();
for (Task task : tasks) {
taskService.complete(task.getId());
}
return toMap(tasks);
}

/**
* 由于task是接口,无法直接返回给前端,通过map转换一下
* @param list
* @return
*/
public List<Map> toMap(List<Task> list) {
List<Map> result = CollUtil.newArrayList();
for (Task task : list) {
Map map = CollUtil.newHashMap();
map.put("user", task.getAssignee());
map.put("name", task.getName());
result.add(map);
}
return result;
}
}

本站总访问量:次本站总访问数:人
本站由 Peng Tong 使用 Stellar 1.29.1 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。