Commit 1684706e9aa70df8675b4b6bba212b7f5541d078

Authored by jason
1 parent 76d89067

feat: [BPM 工作流] 增加跳过表达式判断。

yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/definition/vo/model/simple/BpmSimpleModelNodeVO.java
... ... @@ -71,6 +71,9 @@ public class BpmSimpleModelNodeVO {
71 71 @Schema(description = "是否填写审批意见", example = "false")
72 72 private Boolean reasonRequire;
73 73  
  74 + @Schema(description = "跳过表达式", example = "{true}")
  75 + private String skipExpression; // 用于审批节点
  76 +
74 77 /**
75 78 * 审批节点拒绝处理
76 79 */
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskStatusEnum.java
... ... @@ -13,7 +13,7 @@ import lombok.Getter;
13 13 @Getter
14 14 @AllArgsConstructor
15 15 public enum BpmTaskStatusEnum {
16   -
  16 + SKIP(-2, "跳过"),
17 17 NOT_START(-1, "未开始"),
18 18 RUNNING(1, "审批中"),
19 19 APPROVE(2, "审批通过"),
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/BpmnModelUtils.java
... ... @@ -800,9 +800,10 @@ public class BpmnModelUtils {
800 800 || currentElement instanceof EndEvent
801 801 || currentElement instanceof UserTask
802 802 || currentElement instanceof ServiceTask) {
803   - // 添加元素
  803 + // 添加节点
804 804 FlowNode flowNode = (FlowNode) currentElement;
805 805 resultElements.add(flowNode);
  806 +
806 807 // 遍历子节点
807 808 flowNode.getOutgoingFlows().forEach(
808 809 nextElement -> simulateNextFlowElements(nextElement.getTargetFlowElement(), variables, resultElements, visitElements));
... ... @@ -836,6 +837,31 @@ public class BpmnModelUtils {
836 837 }
837 838  
838 839 /**
  840 + * 判断是否跳过此节点
  841 + *
  842 + * @param flowNode 节点
  843 + * @param variables 流程变量
  844 + */
  845 + public static boolean isSkipNode(FlowElement flowNode, Map<String, Object> variables) {
  846 + // 1. 检查节点是否有跳过表达式(支持多种任务节点类型)
  847 + String skipExpression = null;
  848 + if (flowNode instanceof UserTask) {
  849 + skipExpression = ((UserTask) flowNode).getSkipExpression();
  850 + } else if (flowNode instanceof ServiceTask) {
  851 + skipExpression = ((ServiceTask) flowNode).getSkipExpression();
  852 + } else if (flowNode instanceof ScriptTask) {
  853 + skipExpression = ((ScriptTask) flowNode).getSkipExpression();
  854 + }
  855 +
  856 + if (StrUtil.isEmpty(skipExpression)) {
  857 + return false;
  858 + }
  859 +
  860 + // 2. 计算跳过表达式的值
  861 + return evalConditionExpress(variables, skipExpression);
  862 + }
  863 +
  864 + /**
839 865 * 根据当前节点,获取下一个节点
840 866 *
841 867 * @param currentElement 当前节点
... ... @@ -997,7 +1023,7 @@ public class BpmnModelUtils {
997 1023 * @return 是否满足条件
998 1024 */
999 1025 public static boolean evalConditionExpress(Map<String, Object> variables, String expression) {
1000   - if (expression == null) {
  1026 + if (StrUtil.isEmpty(expression)) {
1001 1027 return Boolean.FALSE;
1002 1028 }
1003 1029 // 如果 variables 为空,则创建一个的原因?可能 expression 的计算,不依赖于 variables
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/util/SimpleModelUtils.java
... ... @@ -464,9 +464,15 @@ public class SimpleModelUtils {
464 464 addReasonRequire(node.getReasonRequire(), userTask);
465 465 // 节点类型
466 466 addNodeType(node.getType(), userTask);
  467 + // 添加跳过表达式
  468 + if (StrUtil.isNotEmpty(node.getSkipExpression())) {
  469 + userTask.setSkipExpression(node.getSkipExpression());
  470 + }
467 471 return userTask;
468 472 }
469 473  
  474 +
  475 +
470 476 private void addUserTaskListener(BpmSimpleModelNodeVO node, UserTask userTask) {
471 477 List<FlowableListener> flowableListeners = new ArrayList<>(3);
472 478 if (node.getTaskCreateListener() != null
... ... @@ -967,7 +973,7 @@ public class SimpleModelUtils {
967 973 || nodeType == BpmSimpleModelNodeTypeEnum.COPY_NODE
968 974 || nodeType == BpmSimpleModelNodeTypeEnum.CHILD_PROCESS
969 975 || nodeType == BpmSimpleModelNodeTypeEnum.END_NODE) {
970   - // 添加元素
  976 + // 添加此节点
971 977 resultNodes.add(currentNode);
972 978 }
973 979  
... ... @@ -1013,6 +1019,16 @@ public class SimpleModelUtils {
1013 1019 simulateNextNode(currentNode.getChildNode(), variables, resultNodes);
1014 1020 }
1015 1021  
  1022 + /**
  1023 + * 根据跳过表达式,判断是否跳过此节点。
  1024 + */
  1025 + public static boolean isSkipNode(BpmSimpleModelNodeVO currentNode, Map<String, Object> variables) {
  1026 + if (StrUtil.isEmpty(currentNode.getSkipExpression())) {
  1027 + return false;
  1028 + }
  1029 + return BpmnModelUtils.evalConditionExpress(variables, currentNode.getSkipExpression());
  1030 + }
  1031 +
1016 1032 public static boolean evalConditionExpress(Map<String, Object> variables, BpmSimpleModelNodeVO.ConditionSetting conditionSetting) {
1017 1033 return BpmnModelUtils.evalConditionExpress(variables, buildConditionExpression(conditionSetting));
1018 1034 }
... ...
yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java
... ... @@ -398,7 +398,7 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
398 398 ? BpmSimpleModelNodeTypeEnum.START_USER_NODE.getType()
399 399 : ObjUtil.defaultIfNull(parseNodeType(flowNode), // 目的:解决“办理节点”的识别
400 400 BpmSimpleModelNodeTypeEnum.APPROVE_NODE.getType()))
401   - .setStatus(FlowableUtils.getTaskStatus(task))
  401 + .setStatus(getEndActivityNodeStatus(task))
402 402 .setCandidateStrategy(BpmnModelUtils.parseCandidateStrategy(flowNode))
403 403 .setStartTime(DateUtils.of(task.getCreateTime())).setEndTime(DateUtils.of(task.getEndTime()))
404 404 .setTasks(singletonList(BpmProcessInstanceConvert.INSTANCE.buildApprovalTaskInfo(task)));
... ... @@ -462,6 +462,15 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
462 462 return approvalNodes;
463 463 }
464 464  
  465 +
  466 + /**
  467 + * 获取结束节点的状态
  468 + */
  469 + private Integer getEndActivityNodeStatus(HistoricTaskInstance task) {
  470 + Integer status = FlowableUtils.getTaskStatus(task);
  471 + return status == null ? BpmTaskStatusEnum.SKIP.getStatus() : status; // 结束节点未获取到状态,为跳过状态
  472 + }
  473 +
465 474 /**
466 475 * 获得【进行中】的活动节点们
467 476 */
... ... @@ -565,10 +574,14 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
565 574 if (runActivityIds.contains(node.getId())) {
566 575 return null;
567 576 }
568   -
  577 + Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
  578 + // 如果节点被跳过。设置状态为跳过
  579 + if (SimpleModelUtils.isSkipNode(node, processVariables)) {
  580 + status = BpmTaskStatusEnum.SKIP.getStatus();
  581 + }
569 582 ActivityNode activityNode = new ActivityNode().setId(node.getId()).setName(node.getName())
570 583 .setNodeType(node.getType()).setCandidateStrategy(node.getCandidateStrategy())
571   - .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
  584 + .setStatus(status);
572 585  
573 586 // 1. 开始节点/审批节点
574 587 if (ObjectUtils.equalsAny(node.getType(),
... ... @@ -608,8 +621,13 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
608 621 if (runActivityIds.contains(node.getId())) {
609 622 return null;
610 623 }
  624 + Integer status = BpmTaskStatusEnum.NOT_START.getStatus();
  625 + // 如果节点被跳过,状态设置为跳过
  626 + if(BpmnModelUtils.isSkipNode(node, processVariables)){
  627 + status = BpmTaskStatusEnum.SKIP.getStatus();
  628 + }
611 629 ActivityNode activityNode = new ActivityNode().setId(node.getId())
612   - .setStatus(BpmTaskStatusEnum.NOT_START.getStatus());
  630 + .setStatus(status);
613 631  
614 632 // 1. 开始节点
615 633 if (node instanceof StartEvent) {
... ...