Skip to content

Commit 768b218

Browse files
authored
Merge pull request #161 from codingapi/dev
feat: 流程表单仅校验必填字段,多余字段原值保留
2 parents 16d7bf3 + 59e0f15 commit 768b218

9 files changed

Lines changed: 140 additions & 13 deletions

File tree

flow-engine-example/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>com.codingapi.flow</groupId>
88
<artifactId>flow-engine-parent</artifactId>
9-
<version>0.0.50</version>
9+
<version>0.0.51</version>
1010
<relativePath>../pom.xml</relativePath>
1111
</parent>
1212

flow-engine-framework/pom.xml

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

1212
<name>flow-engine-framework</name>

flow-engine-framework/src/main/java/com/codingapi/flow/form/FormData.java

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

3-
import com.codingapi.flow.exception.FlowValidationException;
43
import lombok.Getter;
54

65
import java.util.*;
@@ -75,7 +74,9 @@ public void reset(Map<String, Object> data) {
7574

7675
for (String key : data.keySet()) {
7776
Object value = data.get(key);
78-
if (value instanceof Collection<?>) {
77+
// 仅当 key 是已定义的子表单时,集合数据才按子表单解析;
78+
// 其余字段(含表单定义之外的多余字段,如附件列表)一律按原值保留。
79+
if (value instanceof Collection<?> && flowForm.isSubForm(key)) {
7980
Collection<Map<String, Object>> list = (Collection<Map<String, Object>>) value;
8081
for (Map<String, Object> item : list) {
8182
DataBody body = this.addSubDataBody(key);
@@ -144,10 +145,7 @@ public void reset() {
144145
*/
145146
public DataBody set(String key, Object value) {
146147
String id = flowForm.getCode() + "." + key;
147-
DataType type = this.fieldTypes.get(id);
148-
if (type == null) {
149-
throw FlowValidationException.fieldNotFound(key);
150-
}
148+
// 表单元数据中未定义的字段不做校验,按原值保留一并存储
151149
this.data.put(id, value);
152150
return this;
153151
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package com.codingapi.flow.service;
2+
3+
import com.codingapi.flow.action.IFlowAction;
4+
import com.codingapi.flow.builder.FormFieldPermissionsBuilder;
5+
import com.codingapi.flow.builder.NodeStrategyBuilder;
6+
import com.codingapi.flow.context.GatewayContext;
7+
import com.codingapi.flow.factory.MyFlowServiceFactory;
8+
import com.codingapi.flow.form.DataType;
9+
import com.codingapi.flow.form.FlowForm;
10+
import com.codingapi.flow.form.FlowFormBuilder;
11+
import com.codingapi.flow.form.permission.PermissionType;
12+
import com.codingapi.flow.node.nodes.ApprovalNode;
13+
import com.codingapi.flow.node.nodes.EndNode;
14+
import com.codingapi.flow.node.nodes.StartNode;
15+
import com.codingapi.flow.pojo.request.FlowCreateRequest;
16+
import com.codingapi.flow.record.FlowRecord;
17+
import com.codingapi.flow.script.factory.FlowGroovyScriptFactory;
18+
import com.codingapi.flow.strategy.node.FormFieldPermissionStrategy;
19+
import com.codingapi.flow.strategy.node.OperatorLoadStrategy;
20+
import com.codingapi.flow.user.User;
21+
import com.codingapi.flow.workflow.Workflow;
22+
import com.codingapi.flow.workflow.WorkflowBuilder;
23+
import org.junit.jupiter.api.Test;
24+
25+
import java.util.HashMap;
26+
import java.util.List;
27+
import java.util.Map;
28+
29+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
30+
import static org.junit.jupiter.api.Assertions.assertEquals;
31+
32+
/**
33+
* 流程提交携带表单定义之外多余字段的测试。
34+
* <p>
35+
* 表单只定义了必填字段(name/days/reason),提交时额外携带了表单未定义的
36+
* 标量字段(remark)与列表字段(attachments)。期望:
37+
* 1. 只校验必填字段,多余字段不报错;
38+
* 2. 多余字段按原值一并保留并持久化到流程记录中。
39+
*/
40+
class FlowExtraFormDataServiceTest {
41+
42+
private final MyFlowServiceFactory factory = new MyFlowServiceFactory();
43+
44+
@Test
45+
void submitWithExtraFormData() {
46+
User user = new User(1, "user");
47+
User boss = new User(2, "boss");
48+
factory.userGateway.save(user);
49+
factory.userGateway.save(boss);
50+
51+
GatewayContext.getInstance().setFlowOperatorGateway(factory.userGateway);
52+
53+
FlowForm form = FlowFormBuilder.builder()
54+
.name("请假流程")
55+
.code("leave")
56+
.addField("请假人", "name", DataType.STRING)
57+
.addField("请假天数", "days", DataType.INTEGER)
58+
.addField("请假事由", "reason", DataType.STRING)
59+
.build();
60+
61+
StartNode startNode = StartNode
62+
.builder()
63+
.strategies(NodeStrategyBuilder.builder()
64+
.addStrategy(new FormFieldPermissionStrategy(FormFieldPermissionsBuilder.builder()
65+
.addPermission("leave", "name", PermissionType.WRITE)
66+
.addPermission("leave", "days", PermissionType.WRITE)
67+
.addPermission("leave", "reason", PermissionType.WRITE)
68+
.build()))
69+
.build())
70+
.build();
71+
72+
ApprovalNode bossNode = ApprovalNode.builder()
73+
.name("老板审批")
74+
.strategies(NodeStrategyBuilder.builder()
75+
.addStrategy(new FormFieldPermissionStrategy(FormFieldPermissionsBuilder.builder()
76+
.addPermission("leave", "name", PermissionType.WRITE)
77+
.addPermission("leave", "days", PermissionType.WRITE)
78+
.addPermission("leave", "reason", PermissionType.WRITE)
79+
.build()))
80+
.addStrategy(new OperatorLoadStrategy(FlowGroovyScriptFactory.createOperatorLoadScript("def run(request){return [2]}").getKey()))
81+
.build()
82+
)
83+
.build();
84+
85+
EndNode endNode = EndNode.builder().build();
86+
Workflow workflow = WorkflowBuilder.builder()
87+
.title("请假流程")
88+
.code("leave")
89+
.createdOperator(user)
90+
.form(form)
91+
.addNode(startNode)
92+
.addNode(bossNode)
93+
.addNode(endNode)
94+
.build();
95+
96+
factory.workflowService.saveWorkflow(workflow);
97+
98+
// 提交数据:必填字段 + 表单未定义的多余字段(标量 remark、列表 attachments)
99+
List<String> attachments = List.of("a.png", "b.pdf", "c.docx");
100+
Map<String, Object> data = new HashMap<>();
101+
data.put("name", "lorne");
102+
data.put("days", 1);
103+
data.put("reason", "leave");
104+
data.put("remark", "额外备注");
105+
data.put("attachments", attachments);
106+
107+
List<IFlowAction> startActions = startNode.actionManager().getActions();
108+
109+
FlowCreateRequest userCreateRequest = new FlowCreateRequest();
110+
userCreateRequest.setWorkCode(workflow.getCode());
111+
userCreateRequest.setFormData(data);
112+
userCreateRequest.setActionId(startActions.get(0).id());
113+
userCreateRequest.setOperatorId(user.getUserId());
114+
115+
// 多余字段不应触发校验异常
116+
assertDoesNotThrow(() -> factory.flowService.create(userCreateRequest));
117+
118+
List<FlowRecord> userRecordList = factory.flowRecordRepository.findTodoByOperator(user.getUserId());
119+
assertEquals(1, userRecordList.size());
120+
121+
// 多余字段按原值保留并持久化
122+
Map<String, Object> savedFormData = userRecordList.get(0).getFormData();
123+
assertEquals("lorne", savedFormData.get("name"));
124+
assertEquals(1, savedFormData.get("days"));
125+
assertEquals("leave", savedFormData.get("reason"));
126+
assertEquals("额外备注", savedFormData.get("remark"));
127+
assertEquals(attachments, savedFormData.get("attachments"));
128+
}
129+
}

flow-engine-starter-api/pom.xml

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

1212
<name>flow-engine-starter-api</name>

flow-engine-starter-infra/pom.xml

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

1212
<name>flow-engine-starter-infra</name>

flow-engine-starter-query/pom.xml

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

1212
<name>flow-engine-starter-query</name>

flow-engine-starter/pom.xml

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

1212
<name>flow-engine-starter</name>

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111
<groupId>com.codingapi.flow</groupId>
1212
<artifactId>flow-engine-parent</artifactId>
13-
<version>0.0.50</version>
13+
<version>0.0.51</version>
1414
<packaging>pom</packaging>
1515

1616
<url>https://github.com/codingapi/flow-engine</url>

0 commit comments

Comments
 (0)