Skip to content

Commit d141d18

Browse files
committed
add flow map data & save event state
1 parent ae885ee commit d141d18

File tree

16 files changed

+270
-9
lines changed

16 files changed

+270
-9
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<groupId>com.codingapi.springboot</groupId>
1717
<artifactId>springboot-parent</artifactId>
18-
<version>2.10.1</version>
18+
<version>2.10.2</version>
1919

2020
<url>https://github.com/codingapi/springboot-framewrok</url>
2121
<name>springboot-parent</name>

springboot-starter-data-authorization/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<artifactId>springboot-parent</artifactId>
88
<groupId>com.codingapi.springboot</groupId>
9-
<version>2.10.1</version>
9+
<version>2.10.2</version>
1010
</parent>
1111

1212
<artifactId>springboot-starter-data-authorization</artifactId>

springboot-starter-data-fast/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<artifactId>springboot-parent</artifactId>
77
<groupId>com.codingapi.springboot</groupId>
8-
<version>2.10.1</version>
8+
<version>2.10.2</version>
99
</parent>
1010
<modelVersion>4.0.0</modelVersion>
1111

springboot-starter-flow/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<artifactId>springboot-parent</artifactId>
88
<groupId>com.codingapi.springboot</groupId>
9-
<version>2.10.1</version>
9+
<version>2.10.2</version>
1010
</parent>
1111

1212
<name>springboot-starter-flow</name>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.codingapi.springboot.flow.bind;
2+
3+
import com.alibaba.fastjson.JSONObject;
4+
5+
import java.util.HashMap;
6+
7+
/**
8+
* 流程绑定Map数据对象,用于分布式服务下的流程对象数据传递能力
9+
* 该对象中,将clazzName 当做了普通的key来使用,
10+
*/
11+
public class FlowMapBindData extends HashMap<String, Object> implements IBindData {
12+
13+
14+
/**
15+
* 获取类名称
16+
*
17+
* @return 类名称
18+
*/
19+
@Override
20+
public String getClazzName() {
21+
return (String) this.get(CLASS_NAME_KEY);
22+
}
23+
24+
/**
25+
* 转化为类对象
26+
*/
27+
@Override
28+
public <T> T toJavaObject(Class<T> clazz) {
29+
return JSONObject.parseObject(toJsonSnapshot(), clazz);
30+
}
31+
32+
public static FlowMapBindData fromJson(String json) {
33+
return JSONObject.parseObject(json, FlowMapBindData.class);
34+
}
35+
36+
public static FlowMapBindData fromObject(Object obj) {
37+
return JSONObject.parseObject(JSONObject.toJSONString(obj), FlowMapBindData.class);
38+
}
39+
40+
public static FlowMapBindData fromJson(JSONObject json) {
41+
return JSONObject.parseObject(json.toJSONString(), FlowMapBindData.class);
42+
}
43+
44+
public boolean match(String matchKey) {
45+
String className = this.getClazzName();
46+
return matchKey.equals(className);
47+
}
48+
}

springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/bind/IBindData.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
*/
88
public interface IBindData {
99

10+
String CLASS_NAME_KEY = "clazzName";
11+
1012
/**
1113
* 数据快照
1214
*
@@ -19,9 +21,27 @@ default String toJsonSnapshot() {
1921

2022
/**
2123
* 获取类名称
24+
*
2225
* @return 类名称
2326
*/
2427
default String getClazzName() {
2528
return this.getClass().getName();
2629
}
30+
31+
32+
/**
33+
* 类对象匹配
34+
*/
35+
default boolean match(String dataKey) {
36+
String className = this.getClazzName();
37+
return dataKey.equals(className);
38+
}
39+
40+
41+
/**
42+
* 转化为类对象
43+
*/
44+
default <T> T toJavaObject(Class<T> clazz) {
45+
return (T) this;
46+
}
2747
}

springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/event/FlowApprovalEvent.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class FlowApprovalEvent implements ISyncEvent {
3434
public static final int STATE_URGE = 8;
3535
// 抄送
3636
public static final int STATE_CIRCULATE = 9;
37+
// 保存
38+
public static final int STATE_SAVE = 10;
3739

3840

3941
private final int state;
@@ -52,8 +54,23 @@ public FlowApprovalEvent(int state, FlowRecord flowRecord, IFlowOperator operato
5254
}
5355

5456

55-
public boolean match(Class<?> bindDataClass) {
56-
return bindDataClass.isInstance(bindData);
57+
public boolean match(String matchKey) {
58+
return bindData.match(matchKey);
59+
}
60+
61+
/**
62+
* 匹配类名
63+
* 当前bingData下的clazzName变成了普通的key字段了,推荐使用match(String matchKey)方法
64+
* @param clazz 类名
65+
* @return 是否匹配
66+
*/
67+
@Deprecated
68+
public boolean match(Class<?> clazz) {
69+
return bindData.match(clazz.getName());
70+
}
71+
72+
public <T> T toJavaObject(Class<T> clazz) {
73+
return bindData.toJavaObject(clazz);
5774
}
5875

5976
public boolean isUrge() {
@@ -64,6 +81,10 @@ public boolean isTodo() {
6481
return state == STATE_TODO;
6582
}
6683

84+
public boolean isSave() {
85+
return state == STATE_SAVE;
86+
}
87+
6788
public boolean isCreate() {
6889
return state == STATE_CREATE;
6990
}

springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowSaveService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@
22

33
import com.codingapi.springboot.flow.bind.BindDataSnapshot;
44
import com.codingapi.springboot.flow.bind.IBindData;
5+
import com.codingapi.springboot.flow.domain.FlowWork;
56
import com.codingapi.springboot.flow.domain.Opinion;
7+
import com.codingapi.springboot.flow.event.FlowApprovalEvent;
68
import com.codingapi.springboot.flow.record.FlowRecord;
79
import com.codingapi.springboot.flow.repository.FlowBindDataRepository;
810
import com.codingapi.springboot.flow.repository.FlowProcessRepository;
911
import com.codingapi.springboot.flow.repository.FlowRecordRepository;
1012
import com.codingapi.springboot.flow.repository.FlowWorkRepository;
1113
import com.codingapi.springboot.flow.service.FlowRecordVerifyService;
1214
import com.codingapi.springboot.flow.user.IFlowOperator;
15+
import com.codingapi.springboot.framework.event.EventPusher;
1316
import lombok.AllArgsConstructor;
1417
import org.springframework.transaction.annotation.Transactional;
1518

@@ -48,6 +51,15 @@ public void save(long recordId, IFlowOperator currentOperator, IBindData bindDat
4851

4952
flowRecord.setOpinion(opinion);
5053
flowRecordRepository.update(flowRecord);
54+
55+
FlowWork flowWork = flowRecordVerifyService.getFlowWork();
56+
57+
EventPusher.push(new FlowApprovalEvent(FlowApprovalEvent.STATE_SAVE,
58+
flowRecord,
59+
flowRecord.getCurrentOperator(),
60+
flowWork,
61+
snapshot.toBindData()),
62+
true);
5163
}
5264

5365
}

springboot-starter-flow/src/main/java/com/codingapi/springboot/flow/service/impl/FlowStartService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ public FlowResult startFlow() {
189189
for (FlowRecord record : records) {
190190
this.pushEvent(FlowApprovalEvent.STATE_CREATE, record);
191191
this.pushEvent(FlowApprovalEvent.STATE_TODO, record);
192+
this.pushEvent(FlowApprovalEvent.STATE_SAVE, record);
192193
}
193194
// 当前的审批记录
194195
return new FlowResult(flowWork, records);

springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/flow/Leave.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package com.codingapi.springboot.flow.flow;
22

33
import com.codingapi.springboot.flow.bind.IBindData;
4+
import lombok.AllArgsConstructor;
45
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
57
import lombok.Setter;
68

79
@Setter
810
@Getter
11+
@AllArgsConstructor
12+
@NoArgsConstructor
913
public class Leave implements IBindData {
1014

1115
private long id;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.codingapi.springboot.flow.flow;
2+
3+
import lombok.Getter;
4+
import lombok.Setter;
5+
6+
@Setter
7+
@Getter
8+
public class Leave2 {
9+
10+
private long id;
11+
private String title;
12+
private int days;
13+
14+
public Leave2(String title) {
15+
this(title,0);
16+
}
17+
18+
public Leave2(String title, int days) {
19+
this.title = title;
20+
this.days = days;
21+
}
22+
23+
}

springboot-starter-flow/src/test/java/com/codingapi/springboot/flow/repository/LeaveRepository.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.codingapi.springboot.flow.repository;
22

33
import com.codingapi.springboot.flow.flow.Leave;
4+
import com.codingapi.springboot.flow.flow.Leave2;
45

56
import java.util.ArrayList;
67
import java.util.List;
@@ -15,4 +16,8 @@ public void save(Leave leave) {
1516
leave.setId(cache.size());
1617
}
1718
}
19+
public void save(Leave2 leave2) {
20+
Leave leave = new Leave(leave2.getId(), leave2.getTitle(), leave2.getDays());
21+
this.save(leave);
22+
}
1823
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.codingapi.springboot.flow.test;
2+
3+
import com.codingapi.springboot.flow.bind.BindDataSnapshot;
4+
import com.codingapi.springboot.flow.bind.FlowMapBindData;
5+
import com.codingapi.springboot.flow.build.FlowWorkBuilder;
6+
import com.codingapi.springboot.flow.domain.FlowWork;
7+
import com.codingapi.springboot.flow.domain.Opinion;
8+
import com.codingapi.springboot.flow.em.ApprovalType;
9+
import com.codingapi.springboot.flow.flow.Leave2;
10+
import com.codingapi.springboot.flow.matcher.OperatorMatcher;
11+
import com.codingapi.springboot.flow.pojo.FlowDetail;
12+
import com.codingapi.springboot.flow.record.FlowRecord;
13+
import com.codingapi.springboot.flow.repository.*;
14+
import com.codingapi.springboot.flow.service.FlowService;
15+
import com.codingapi.springboot.flow.user.User;
16+
import org.junit.jupiter.api.Test;
17+
import org.springframework.data.domain.PageRequest;
18+
19+
import java.util.List;
20+
21+
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
23+
24+
public class FlowMapTest {
25+
26+
private final UserRepository userRepository = new UserRepository();
27+
private final FlowWorkRepository flowWorkRepository = new FlowWorkRepositoryImpl();
28+
private final FlowRecordRepositoryImpl flowRecordRepository = new FlowRecordRepositoryImpl();
29+
private final FlowBindDataRepositoryImpl flowBindDataRepository = new FlowBindDataRepositoryImpl();
30+
private final LeaveRepository leaveRepository = new LeaveRepository();
31+
private final FlowBackupRepository flowBackupRepository = new FlowBackupRepositoryImpl();
32+
private final FlowProcessRepository flowProcessRepository = new FlowProcessRepositoryImpl(flowBackupRepository, userRepository);
33+
private final FlowService flowService = new FlowService(flowWorkRepository, flowRecordRepository, flowBindDataRepository, userRepository, flowProcessRepository, flowBackupRepository);
34+
35+
/**
36+
* map数据绑定对象测试
37+
*/
38+
@Test
39+
void mapFlowTest() {
40+
PageRequest pageRequest = PageRequest.of(0, 1000);
41+
42+
User user = new User("张飞");
43+
userRepository.save(user);
44+
45+
User dept = new User("刘备");
46+
userRepository.save(dept);
47+
48+
User boss = new User("诸葛亮");
49+
userRepository.save(boss);
50+
51+
FlowWork flowWork = FlowWorkBuilder.builder(user)
52+
.title("请假流程")
53+
.nodes()
54+
.node("开始节点", "start", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
55+
.node("部门领导审批", "dept", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(dept.getUserId()))
56+
.node("总经理审批", "manager", "default", ApprovalType.UN_SIGN, OperatorMatcher.specifyOperatorMatcher(boss.getUserId()))
57+
.node("结束节点", "over", "default", ApprovalType.UN_SIGN, OperatorMatcher.anyOperatorMatcher())
58+
.relations()
59+
.relation("部门领导审批", "start", "dept")
60+
.relation("总经理审批", "dept", "manager")
61+
.relation("结束节点", "manager", "over")
62+
.build();
63+
64+
flowWorkRepository.save(flowWork);
65+
66+
String workCode = flowWork.getCode();
67+
68+
Leave2 leave = new Leave2("我要出去看看");
69+
FlowMapBindData bindData = FlowMapBindData.fromObject(leave);
70+
leaveRepository.save(leave);
71+
72+
// 创建流程
73+
flowService.startFlow(workCode, user, bindData, "发起流程");
74+
75+
// 查看我的待办
76+
List<FlowRecord> userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent();
77+
assertEquals(1, userTodos.size());
78+
79+
// 提交流程
80+
FlowRecord userTodo = userTodos.get(0);
81+
// 保存流程
82+
leave.setTitle("我要出去看看~~");
83+
bindData = FlowMapBindData.fromObject(leave);
84+
flowService.save(userTodo.getId(), user, bindData, "暂存");
85+
86+
// 查看流程详情
87+
FlowDetail flowDetail = flowService.detail(userTodo.getId(), user);
88+
assertEquals("我要出去看看~~", (flowDetail.getBindData().toJavaObject(Leave2.class)).getTitle());
89+
assertTrue(flowDetail.getFlowRecord().isRead());
90+
91+
92+
flowService.submitFlow(userTodo.getId(), user, bindData, Opinion.pass("同意"));
93+
94+
// 查看部门经理的待办
95+
List<FlowRecord> deptTodos = flowRecordRepository.findTodoByOperatorId(dept.getUserId(), pageRequest).getContent();
96+
assertEquals(1, deptTodos.size());
97+
98+
// 提交部门经理的审批
99+
FlowRecord deptTodo = deptTodos.get(0);
100+
flowService.submitFlow(deptTodo.getId(), dept, bindData, Opinion.pass("同意"));
101+
102+
// 查看总经理的待办
103+
List<FlowRecord> bossTodos = flowRecordRepository.findTodoByOperatorId(boss.getUserId(), pageRequest).getContent();
104+
assertEquals(1, bossTodos.size());
105+
106+
// 提交总经理的审批
107+
FlowRecord bossTodo = bossTodos.get(0);
108+
flowService.submitFlow(bossTodo.getId(), boss, bindData, Opinion.pass("同意"));
109+
110+
// 查看所有流程
111+
List<FlowRecord> records = flowRecordRepository.findAll(pageRequest).getContent();
112+
assertEquals(3, records.size());
113+
114+
userTodos = flowRecordRepository.findTodoByOperatorId(user.getUserId(), pageRequest).getContent();
115+
assertEquals(0, userTodos.size());
116+
117+
118+
records = flowRecordRepository.findAll(pageRequest).getContent();
119+
assertEquals(3, records.size());
120+
// 查看所有流程是否都已经结束
121+
assertTrue(records.stream().allMatch(FlowRecord::isFinish));
122+
123+
List<BindDataSnapshot> snapshots = flowBindDataRepository.findAll();
124+
assertEquals(4, snapshots.size());
125+
126+
}
127+
}

0 commit comments

Comments
 (0)