Skip to content

Commit 360bef9

Browse files
committed
refactor: approval flow unit test
1 parent 2d9023f commit 360bef9

8 files changed

Lines changed: 524 additions & 33 deletions

File tree

backend/crm/src/main/java/cn/cordys/crm/approval/domain/ApprovalNodeApprover.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package cn.cordys.crm.approval.domain;
22

3+
import cn.cordys.crm.approval.constants.EmptyApproverActionEnum;
4+
import cn.cordys.crm.approval.constants.MultiApproverModeEnum;
35
import io.swagger.v3.oas.annotations.media.Schema;
46
import jakarta.persistence.Table;
7+
import jakarta.validation.constraints.NotBlank;
58
import lombok.Data;
69

710
@Data
@@ -14,15 +17,19 @@ public class ApprovalNodeApprover {
1417
@Schema(description = "流程ID")
1518
private String flowId;
1619

20+
@NotBlank
1721
@Schema(description = "审批类型:MANUAL/AUTO_PASS/AUTO_REJECT")
18-
private String approvalType;
22+
private String approvalType = EmptyApproverActionEnum.AUTO_PASS.name();
1923

24+
@NotBlank
2025
@Schema(description = "多人审批方式:ALL/ANY/SEQUENTIAL")
21-
private String multiApproverMode;
26+
private String multiApproverMode = MultiApproverModeEnum.ALL.name();
2227

28+
@NotBlank
2329
@Schema(description = "审批人为空时动作")
24-
private String emptyApproverAction;
30+
private String emptyApproverAction = EmptyApproverActionEnum.AUTO_PASS.name();
2531

32+
@NotBlank
2633
@Schema(description = "审批人与提交人相同时动作")
2734
private String sameSubmitterAction;
2835

@@ -33,10 +40,10 @@ public class ApprovalNodeApprover {
3340
private String approver;
3441

3542
@Schema(description = "审批通过后配置(JSON格式)")
36-
private String passUpdateConfig;
43+
private String passPostConfig;
3744

3845
@Schema(description = "审批驳回后配置(JSON格式)")
39-
private String rejectUpdateConfig;
46+
private String rejectPostConfig;
4047

4148
@Schema(description = "字段权限配置(JSON格式)")
4249
private String fieldPermissions;

backend/crm/src/main/java/cn/cordys/crm/approval/dto/request/ApprovalFlowUpdateRequest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public class ApprovalFlowUpdateRequest {
1616
@Schema(description = "审批流ID")
1717
private String id;
1818

19-
@NotBlank
2019
@Schema(description = "流程名称")
2120
private String name;
2221

backend/crm/src/main/java/cn/cordys/crm/approval/dto/request/ApprovalNodeApproverRequest.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import cn.cordys.crm.approval.dto.ApproverConfigDTO;
1010
import cn.cordys.crm.approval.dto.FieldPermissionDTO;
1111
import io.swagger.v3.oas.annotations.media.Schema;
12+
import jakarta.validation.constraints.NotBlank;
1213
import lombok.Data;
1314
import lombok.EqualsAndHashCode;
1415

@@ -19,21 +20,25 @@
1920
@Schema(description = "审批人节点请求")
2021
public class ApprovalNodeApproverRequest extends ApprovalNodeRequest {
2122

23+
@NotBlank
2224
@EnumValue(enumClass = ApprovalTypeEnum.class)
2325
@Schema(description = "审批类型:MANUAL/AUTO_PASS/AUTO_REJECT")
24-
private String approvalType;
26+
private String approvalType = EmptyApproverActionEnum.AUTO_PASS.name();
2527

28+
@NotBlank
2629
@EnumValue(enumClass = MultiApproverModeEnum.class)
2730
@Schema(description = "多人审批方式:ALL/ANY/SEQUENTIAL")
28-
private String multiApproverMode;
31+
private String multiApproverMode = MultiApproverModeEnum.ALL.name();
2932

33+
@NotBlank
3034
@EnumValue(enumClass = EmptyApproverActionEnum.class)
3135
@Schema(description = "审批人为空时动作")
32-
private String emptyApproverAction;
36+
private String emptyApproverAction = EmptyApproverActionEnum.AUTO_PASS.name();
3337

38+
@NotBlank
3439
@EnumValue(enumClass = SameSubmitterActionEnum.class)
3540
@Schema(description = "审批人与提交人相同时动作")
36-
private String sameSubmitterAction;
41+
private String sameSubmitterAction = SameSubmitterActionEnum.SKIP.name();
3742

3843
@Schema(description = "抄送人列表")
3944
private List<ApproverConfigDTO> cc;

backend/crm/src/main/java/cn/cordys/crm/approval/dto/request/ApprovalNodeRequest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,22 @@
22

33
import cn.cordys.common.constants.EnumValue;
44
import cn.cordys.crm.approval.constants.ApprovalNodeTypeEnum;
5-
import com.fasterxml.jackson.annotation.JsonTypeInfo;
65
import com.fasterxml.jackson.annotation.JsonSubTypes;
6+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
77
import io.swagger.v3.oas.annotations.media.Schema;
88
import jakarta.validation.constraints.NotBlank;
99
import lombok.Data;
1010

1111
import java.util.List;
1212

1313
@Data
14-
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "nodeType")
14+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "nodeType", visible = true)
1515
@JsonSubTypes({
1616
@JsonSubTypes.Type(value = ApprovalNodeApproverRequest.class, name = "APPROVER"),
17-
@JsonSubTypes.Type(value = ApprovalNodeConditionRequest.class, name = "CONDITION")
17+
@JsonSubTypes.Type(value = ApprovalNodeConditionRequest.class, name = "CONDITION"),
18+
@JsonSubTypes.Type(value = ApprovalNodeRequest.class, name = "START"),
19+
@JsonSubTypes.Type(value = ApprovalNodeRequest.class, name = "END"),
20+
@JsonSubTypes.Type(value = ApprovalNodeRequest.class, name = "DEFAULT"),
1821
})
1922
public class ApprovalNodeRequest {
2023

backend/crm/src/main/java/cn/cordys/crm/approval/dto/response/ApprovalNodeResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import java.util.List;
99

1010
@Data
11-
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "nodeType")
11+
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "nodeType", visible = true)
1212
@JsonSubTypes({
1313
@JsonSubTypes.Type(value = ApprovalNodeApproverResponse.class, name = "APPROVER"),
1414
@JsonSubTypes.Type(value = ApprovalNodeConditionResponse.class, name = "CONDITION"),

backend/crm/src/main/java/cn/cordys/crm/approval/service/ApprovalFlowService.java

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,11 @@ private void parseApproverNodeFields(ApprovalNodeApprover approverNode, Approval
357357
if (StringUtils.isNotBlank(approverNode.getApprover())) {
358358
response.setApprover(JSON.parseArray(approverNode.getApprover(), ApproverConfigDTO.class));
359359
}
360-
if (StringUtils.isNotBlank(approverNode.getPassUpdateConfig())) {
361-
response.setPassPostConfig(JSON.parseObject(approverNode.getPassUpdateConfig(), ApprovalPostConfigDTO.class));
360+
if (StringUtils.isNotBlank(approverNode.getPassPostConfig())) {
361+
response.setPassPostConfig(JSON.parseObject(approverNode.getPassPostConfig(), ApprovalPostConfigDTO.class));
362362
}
363-
if (StringUtils.isNotBlank(approverNode.getRejectUpdateConfig())) {
364-
response.setRejectPostConfig(JSON.parseObject(approverNode.getRejectUpdateConfig(), ApprovalPostConfigDTO.class));
363+
if (StringUtils.isNotBlank(approverNode.getRejectPostConfig())) {
364+
response.setRejectPostConfig(JSON.parseObject(approverNode.getRejectPostConfig(), ApprovalPostConfigDTO.class));
365365
}
366366
if (StringUtils.isNotBlank(approverNode.getFieldPermissions())) {
367367
response.setFieldPermissions(JSON.parseArray(approverNode.getFieldPermissions(), FieldPermissionDTO.class));
@@ -431,36 +431,63 @@ private void buildChildren(ApprovalNodeResponse node, Map<String, List<String>>
431431
}
432432
}
433433

434+
/**
435+
* 批量保存节点配置
436+
* 先递归收集所有节点信息,然后批量插入,提高性能
437+
*/
434438
private void saveNodes(List<ApprovalNodeRequest> nodes, String flowId, String userId) {
439+
// 用于收集节点、连接和配置信息
440+
List<ApprovalNode> allNodes = new ArrayList<>();
441+
List<ApprovalNodeLink> allLinks = new ArrayList<>();
442+
List<ApprovalNodeApprover> allApproverNodes = new ArrayList<>();
443+
List<ApprovalNodeCondition> allConditionNodes = new ArrayList<>();
444+
445+
// 递归收集所有节点信息
435446
for (ApprovalNodeRequest nodeRequest : nodes) {
436-
saveNode(nodeRequest, flowId, userId, null);
447+
collectNodeInfo(nodeRequest, flowId, userId, null, allNodes, allLinks, allApproverNodes, allConditionNodes);
448+
}
449+
450+
// 批量插入
451+
if (CollectionUtils.isNotEmpty(allNodes)) {
452+
approvalNodeMapper.batchInsert(allNodes);
453+
}
454+
if (CollectionUtils.isNotEmpty(allLinks)) {
455+
approvalNodeLinkMapper.batchInsert(allLinks);
456+
}
457+
if (CollectionUtils.isNotEmpty(allApproverNodes)) {
458+
approvalNodeApproverMapper.batchInsert(allApproverNodes);
459+
}
460+
if (CollectionUtils.isNotEmpty(allConditionNodes)) {
461+
approvalNodeConditionMapper.batchInsert(allConditionNodes);
437462
}
438463
}
439464

440465
/**
441-
* 递归保存节点及其子节点
466+
* 递归收集节点信息到列表中
442467
*/
443-
private void saveNode(ApprovalNodeRequest nodeRequest, String flowId, String userId, String parentId) {
468+
private void collectNodeInfo(ApprovalNodeRequest nodeRequest, String flowId, String userId, String parentId,
469+
List<ApprovalNode> allNodes, List<ApprovalNodeLink> allLinks,
470+
List<ApprovalNodeApprover> allApproverNodes, List<ApprovalNodeCondition> allConditionNodes) {
444471
String nodeId = StringUtils.isNotBlank(nodeRequest.getId()) ? nodeRequest.getId() : IDGenerator.nextStr();
445472

446-
// 保存节点基本信息
473+
// 收集节点基本信息
447474
ApprovalNode node = BeanUtils.copyBean(new ApprovalNode(), nodeRequest);
448475
node.setId(nodeId);
449476
node.setFlowId(flowId);
450-
approvalNodeMapper.insert(node);
477+
allNodes.add(node);
451478

452-
// 保存节点连接(如果有父节点)
479+
// 收集节点连接信息(如果有父节点)
453480
if (StringUtils.isNotBlank(parentId)) {
454481
ApprovalNodeLink link = new ApprovalNodeLink();
455482
link.setId(IDGenerator.nextStr());
456483
link.setFlowId(flowId);
457484
link.setFromNodeId(parentId);
458485
link.setToNodeId(nodeId);
459486
link.setSort(nodeRequest.getSort());
460-
approvalNodeLinkMapper.insert(link);
487+
allLinks.add(link);
461488
}
462489

463-
// 保存审批人节点配置
490+
// 收集审批人节点配置
464491
if (nodeRequest instanceof ApprovalNodeApproverRequest) {
465492
ApprovalNodeApproverRequest approverRequest = (ApprovalNodeApproverRequest) nodeRequest;
466493
ApprovalNodeApprover approverNode = BeanUtils.copyBean(new ApprovalNodeApprover(), approverRequest,
@@ -469,26 +496,26 @@ private void saveNode(ApprovalNodeRequest nodeRequest, String flowId, String use
469496
approverNode.setFlowId(flowId);
470497
approverNode.setCc(JSON.toJSONString(approverRequest.getCc()));
471498
approverNode.setApprover(JSON.toJSONString(approverRequest.getApprover()));
472-
approverNode.setPassUpdateConfig(JSON.toJSONString(approverRequest.getPassPostConfig()));
473-
approverNode.setRejectUpdateConfig(JSON.toJSONString(approverRequest.getRejectPostConfig()));
499+
approverNode.setPassPostConfig(JSON.toJSONString(approverRequest.getPassPostConfig()));
500+
approverNode.setRejectPostConfig(JSON.toJSONString(approverRequest.getRejectPostConfig()));
474501
approverNode.setFieldPermissions(JSON.toJSONString(approverRequest.getFieldPermissions()));
475-
approvalNodeApproverMapper.insert(approverNode);
502+
allApproverNodes.add(approverNode);
476503
}
477-
// 保存条件节点配置
504+
// 收集条件节点配置
478505
else if (nodeRequest instanceof ApprovalNodeConditionRequest) {
479506
ApprovalNodeConditionRequest conditionRequest = (ApprovalNodeConditionRequest) nodeRequest;
480507
ApprovalNodeCondition conditionNode = BeanUtils.copyBean(new ApprovalNodeCondition(), conditionRequest,
481508
"rules");
482509
conditionNode.setId(nodeId);
483510
conditionNode.setFlowId(flowId);
484511
conditionNode.setConditionConfig(JSON.toJSONString(conditionRequest.getConditionConfig()));
485-
approvalNodeConditionMapper.insert(conditionNode);
512+
allConditionNodes.add(conditionNode);
486513
}
487514

488-
// 递归保存子节点
515+
// 递归收集子节点
489516
if (CollectionUtils.isNotEmpty(nodeRequest.getChildren())) {
490517
for (ApprovalNodeRequest childRequest : nodeRequest.getChildren()) {
491-
saveNode(childRequest, flowId, userId, nodeId);
518+
collectNodeInfo(childRequest, flowId, userId, nodeId, allNodes, allLinks, allApproverNodes, allConditionNodes);
492519
}
493520
}
494521
}

backend/crm/src/main/resources/migration/1.7.0/ddl/V1.7.0_2__ga_ddl.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ CREATE TABLE approval_flow(
1818
`update_time` BIGINT NOT NULL COMMENT '更新时间' ,
1919
`create_user` VARCHAR(32) NOT NULL COMMENT '创建人' ,
2020
`update_user` VARCHAR(32) NOT NULL COMMENT '更新人' ,
21+
`organization_id` VARCHAR(32) NOT NULL COMMENT '组织id' ,
2122
PRIMARY KEY (id)
2223
) COMMENT = '审批流表'
2324
ENGINE = InnoDB

0 commit comments

Comments
 (0)