From 86aa539ad9c9fc36a8ce32b4c404b0bc5beae470 Mon Sep 17 00:00:00 2001 From: lbw Date: Wed, 9 Aug 2023 15:57:51 +0800 Subject: [PATCH] =?UTF-8?q?:recycle:=20Refactoring=20code.=20=E9=80=82?= =?UTF-8?q?=E9=85=8D=E6=9C=80=E6=96=B0=20flowable=20=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E6=B5=81=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/constant/SecurityConstants.java | 5 + .../engine/expression/ExpressionHandler.java | 26 +- .../NodeExpressionStrategyFactory.java | 11 +- .../impl/InputNodeConditionStrategy.java | 6 + .../SingleSelectNodeConditionStrategy.java | 11 +- .../listeners/ApprovalCreateListener.java | 2 +- .../listeners/FlowProcessEventListener.java | 2 - .../AssignUserSelfSelectStrategyImpl.java | 5 +- .../engine/service/ApproveServiceTask.java | 63 +++ .../flow/engine/service/CopyServiceTask.java | 2 +- .../pigx/flow/engine/utils/ModelUtil.java | 448 +++++++++++------- .../pigx/flow/task/constant/NodeTypeEnum.java | 16 +- .../constant/ProcessInstanceConstant.java | 2 + .../flow/task/constant/SecurityConstants.java | 41 -- .../pig4cloud/pigx/flow/task/dto/Node.java | 2 + .../pig4cloud/pigx/flow/task/dto/Refuse.java | 12 + .../pigx/flow/task/dto/SelectValue.java | 17 + .../pigx/flow/task/utils/NodeUtil.java | 21 + .../task/service/impl/TaskServiceImpl.java | 14 +- 19 files changed, 466 insertions(+), 240 deletions(-) create mode 100644 pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/ApproveServiceTask.java delete mode 100644 pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/SecurityConstants.java create mode 100644 pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Refuse.java create mode 100644 pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/SelectValue.java diff --git a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java index f32e9e02a..33e0c783b 100644 --- a/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java +++ b/pigx-common/pigx-common-core/src/main/java/com/pig4cloud/pigx/common/core/constant/SecurityConstants.java @@ -85,6 +85,11 @@ public interface SecurityConstants { */ String FROM = "from"; + /** + * 请求header + */ + String HEADER_FROM_IN = FROM + "=" + FROM_IN; + /** * OAUTH URL */ diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/ExpressionHandler.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/ExpressionHandler.java index 4061dbfa7..5e6def6ab 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/ExpressionHandler.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/ExpressionHandler.java @@ -16,6 +16,7 @@ import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.flow.task.constant.NodeUserTypeEnum; import com.pig4cloud.pigx.flow.task.dto.NodeUser; +import com.pig4cloud.pigx.flow.task.dto.SelectValue; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -161,18 +162,37 @@ public class ExpressionHandler { } /** - * 判断字符数组包含 + * 单选处理 * @param key 表单key * @param array 条件值 * @return */ - public boolean stringContain(String key, DelegateExecution execution, String... array) { + public boolean singleSelectHandler(String key, DelegateExecution execution, String... array) { Object value = execution.getVariable(key); if (value == null) { return false; } - return ArrayUtil.contains(array, value.toString()); + List list = Convert.toList(SelectValue.class, value); + if (CollUtil.isEmpty(list)) { + return false; + } + return ArrayUtil.contains(array, list.get(0).getKey()); + } + + /** + * 字符串判断包含 + * @param key 表单key + * @param param 参数 + * @return + */ + public boolean stringContain(String key, String param, DelegateExecution execution) { + Object value = execution.getVariable(key); + + if (value == null) { + return false; + } + return StrUtil.contains(value.toString(), param); } /** diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/NodeExpressionStrategyFactory.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/NodeExpressionStrategyFactory.java index 20d5b617d..150766156 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/NodeExpressionStrategyFactory.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/NodeExpressionStrategyFactory.java @@ -75,21 +75,14 @@ public class NodeExpressionStrategyFactory { return "${(" + join + ")}"; } - /** - * 处理默认分支表达式 - * @param branchs 所有分支 - * @return - */ - public static String handleDefaultBranch(List branchs) { + public static String handleDefaultBranch(List branchs, int currentIndex) { List expList = new ArrayList<>(); - int size = branchs.size(); - int index = 1; for (Node branch : branchs) { - if (index == size) { + if (index == currentIndex + 1) { continue; } diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/InputNodeConditionStrategy.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/InputNodeConditionStrategy.java index 8a230c165..6176f80b6 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/InputNodeConditionStrategy.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/InputNodeConditionStrategy.java @@ -24,6 +24,12 @@ public class InputNodeConditionStrategy implements NodeConditionStrategy { if (StrUtil.equals(compare, "==")) { return StrUtil.format("(expressionHandler.stringEqual(\"{}\",\"{}\",execution))", id, value); } + if (StrUtil.equals(compare, "contain")) { + return StrUtil.format("(expressionHandler.stringContain(\"{}\",\"{}\",execution))", id, value); + } + if (StrUtil.equals(compare, "notcontain")) { + return StrUtil.format("(!expressionHandler.stringContain(\"{}\",\"{}\",execution))", id, value); + } if (StrUtil.equals(compare, "!=")) { return StrUtil.format("(!expressionHandler.stringEqual(\"{}\",\"{}\",execution))", id, value); } diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/SingleSelectNodeConditionStrategy.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/SingleSelectNodeConditionStrategy.java index 75e3fb082..7b4496b0b 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/SingleSelectNodeConditionStrategy.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/expression/condition/impl/SingleSelectNodeConditionStrategy.java @@ -5,6 +5,7 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.StrUtil; import com.pig4cloud.pigx.flow.engine.expression.condition.NodeConditionStrategy; import com.pig4cloud.pigx.flow.task.dto.Condition; +import com.pig4cloud.pigx.flow.task.dto.SelectValue; import org.springframework.stereotype.Component; import java.util.List; @@ -25,22 +26,22 @@ public class SingleSelectNodeConditionStrategy implements NodeConditionStrategy String id = condition.getKey(); Object value = condition.getValue(); - List list = Convert.toList(value); + List list = Convert.toList(SelectValue.class, value); StringBuilder sb = new StringBuilder(); - for (Object o : list) { - sb.append(",\"").append(o.toString()).append("\""); + for (SelectValue o : list) { + sb.append(",\"").append(o.getKey()).append("\""); } String string = sb.toString(); if (CollUtil.isNotEmpty(list)) { string = string.substring(1); } if (compare.equals("in")) { - return StrUtil.format("(expressionHandler.stringContain(\"{}\", execution,{}))", id, string); + return StrUtil.format("(expressionHandler.singleSelectHandler(\"{}\", execution,{}))", id, string); } - return StrUtil.format("(!expressionHandler.stringContain(\"{}\", execution,{}))", id, string); + return StrUtil.format("(!expressionHandler.singleSelectHandler(\"{}\", execution,{}))", id, string); } diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/ApprovalCreateListener.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/ApprovalCreateListener.java index 04766081d..5fbdc3989 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/ApprovalCreateListener.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/ApprovalCreateListener.java @@ -77,7 +77,7 @@ public class ApprovalCreateListener implements TaskListener { taskService.setAssignee(taskEntity.getId(), nodeUser.getId().toString()); } - if (StrUtil.equals(handler, ProcessInstanceConstant.USER_TASK_NOBODY_HANDLER_TO_END)) { + if (StrUtil.equals(handler, ProcessInstanceConstant.USER_TASK_NOBODY_HANDLER_TO_REFUSE)) { // 结束 Dict param = Dict.create().set(StrUtil.format("{}_approve_condition", nodeId), false); taskService.complete(taskEntity.getId(), param); diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/FlowProcessEventListener.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/FlowProcessEventListener.java index 092f0dbaa..d3a91fbc5 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/FlowProcessEventListener.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/listeners/FlowProcessEventListener.java @@ -115,9 +115,7 @@ public class FlowProcessEventListener implements FlowableEventListener { processNodeRecordParamDto.setFlowId(flowId); processNodeRecordParamDto.setExecutionId(flowableActivityEvent.getExecutionId()); processNodeRecordParamDto.setProcessInstanceId(processInstanceId); - // processNodeRecordParamDto.setData(JSON.toJSONString(processVariables)); processNodeRecordParamDto.setNodeId(activityId); - // processNodeRecordParamDto.setNodeType(nodeDto.getType()); processNodeRecordParamDto.setNodeName(activityName); remoteFlowTaskService.endNodeEvent(processNodeRecordParamDto); diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/node/impl/AssignUserSelfSelectStrategyImpl.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/node/impl/AssignUserSelfSelectStrategyImpl.java index 06bd400b2..310545158 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/node/impl/AssignUserSelfSelectStrategyImpl.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/node/impl/AssignUserSelfSelectStrategyImpl.java @@ -29,6 +29,7 @@ import java.util.Map; public class AssignUserSelfSelectStrategyImpl implements AssignUserStrategy { private final ObjectMapper objectMapper; + @SneakyThrows @Override public List handle(Node node, NodeUser rootUser, Map variables) { @@ -41,7 +42,9 @@ public class AssignUserSelfSelectStrategyImpl implements AssignUserStrategy { return assignList; } - List nodeUserDtos = objectMapper.readValue(objectMapper.writeValueAsString(variable),new TypeReference<>() {}); + List nodeUserDtos = objectMapper.readValue(objectMapper.writeValueAsString(variable), + new TypeReference<>() { + }); List collect = nodeUserDtos.stream().map(NodeUser::getId).toList(); diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/ApproveServiceTask.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/ApproveServiceTask.java new file mode 100644 index 000000000..eb62a2436 --- /dev/null +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/ApproveServiceTask.java @@ -0,0 +1,63 @@ +package com.pig4cloud.pigx.flow.engine.service; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowTaskService; +import com.pig4cloud.pigx.flow.task.dto.Node; +import com.pig4cloud.pigx.flow.task.dto.Refuse; +import lombok.extern.slf4j.Slf4j; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.delegate.JavaDelegate; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityImpl; + +/** + * 审批任务处理器--java服务任务 + */ +@Slf4j +public class ApproveServiceTask implements JavaDelegate { + + @Override + public void execute(DelegateExecution execution) { + + ExecutionEntityImpl entity = (ExecutionEntityImpl) execution; + String nodeIdO = entity.getActivityId(); + String flowId = entity.getProcessDefinitionKey(); + String processInstanceId = entity.getProcessInstanceId(); + + String nodeId = StrUtil.subAfter(nodeIdO, "approve_service_task_", true); + + Boolean approve = execution.getVariable(StrUtil.format("{}_approve_condition", nodeId), Boolean.class); + + if (approve != null) { + + RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class); + + if (!approve) { + // 跳转 + RemoteFlowTaskService remoteFlowTaskService = SpringUtil.getBean(RemoteFlowTaskService.class); + Node node = remoteFlowTaskService.queryNodeOriData(flowId, nodeId).getData(); + Refuse refuse = node.getRefuse(); + if (refuse != null) { + String handler = refuse.getHandler(); + if (StrUtil.equals(handler, "TO_NODE")) { + runtimeService.createChangeActivityStateBuilder() + .processInstanceId(processInstanceId) + .moveActivityIdTo(nodeIdO, refuse.getNodeId()) + .changeState(); + } + else { + runtimeService.createChangeActivityStateBuilder() + .processInstanceId(processInstanceId) + .moveActivityIdTo(nodeIdO, "end") + .changeState(); + } + } + + } + + } + + } + +} diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/CopyServiceTask.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/CopyServiceTask.java index 907f7cf65..72f9e5c38 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/CopyServiceTask.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/service/CopyServiceTask.java @@ -87,7 +87,7 @@ public class CopyServiceTask implements JavaDelegate { processCopyDto.setFlowId(flowId); processCopyDto.setProcessInstanceId(execution.getProcessInstanceId()); processCopyDto.setNodeId(nodeId); - processCopyDto.setNodeName(entity.getActivityName()); + processCopyDto.setNodeName(node.getName()); processCopyDto.setFormData(objectMapper.writeValueAsString(variables)); processCopyDto.setUserId(Long.parseLong(userIds)); remoteFlowTaskService.saveCC(processCopyDto); diff --git a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/utils/ModelUtil.java b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/utils/ModelUtil.java index c83172d97..476461487 100644 --- a/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/utils/ModelUtil.java +++ b/pigx-flow/pigx-flow-engine/pigx-flow-engine-biz/src/main/java/com/pig4cloud/pigx/flow/engine/utils/ModelUtil.java @@ -8,6 +8,7 @@ import cn.hutool.json.JSONUtil; import com.pig4cloud.pigx.flow.engine.expression.condition.NodeExpressionStrategyFactory; import com.pig4cloud.pigx.flow.engine.listeners.ApprovalCreateListener; import com.pig4cloud.pigx.flow.engine.listeners.FlowProcessEventListener; +import com.pig4cloud.pigx.flow.engine.service.ApproveServiceTask; import com.pig4cloud.pigx.flow.engine.service.CopyServiceTask; import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowTaskService; import com.pig4cloud.pigx.flow.task.constant.NodeTypeEnum; @@ -20,77 +21,73 @@ import org.flowable.bpmn.model.Process; import org.flowable.bpmn.model.*; import java.util.ArrayList; -import java.util.Collections; import java.util.List; -import java.util.Objects; /** * 模型工具类 处理模型构建相关的 */ @Slf4j public class ModelUtil { - /** - * 构建BPMN流程模型 - * @param nodeDto 前端传过来的节点数据 - * @param processName 流程名称 - * @param flowId 流程定义ID - * @return 流程模型对象 + * 构建模型 + * + * @param nodeDto 前端传输节点 + * @return */ public static BpmnModel buildBpmnModel(Node nodeDto, String processName, String flowId) { BpmnModel bpmnModel = new BpmnModel(); - bpmnModel.setTargetNamespace("MODEL"); + bpmnModel.setTargetNamespace("pig"); Process process = new Process(); process.setId(flowId); process.setName(processName); - // 流程监听器 + //流程监听器 ArrayList eventListeners = new ArrayList<>(); { - // 流程实例监听器 + //流程实例监听器 EventListener eventListener = new EventListener(); eventListener.setImplementationType("class"); eventListener.setImplementation(FlowProcessEventListener.class.getCanonicalName()); + eventListeners.add(eventListener); } process.setEventListeners(eventListeners); - // 构建结束节点 + NodeUtil.addEndNode(nodeDto); - Node endNodeDto = new Node(); - endNodeDto.setId(StrUtil.format("end")); - endNodeDto.setHeadId(endNodeDto.getId()); - endNodeDto.setName("endNode"); - // 构建节点 - EndEvent endEvent = buildEndNode(endNodeDto, false); - process.addFlowElement(endEvent); - // 创建所有的节点 + //创建所有的节点 buildAllNode(process, nodeDto, flowId); - // 创建所有的内部节点连接线 + //创建所有的内部节点连接线 buildAllNodeInnerSequence(process, nodeDto, flowId); - // 创建节点间连线 - buildAllNodeOuterSequence(process, nodeDto, endNodeDto); + //创建节点间连线 + buildAllNodeOuterSequence(process, nodeDto, null); + //处理分支和下级连线 + bpmnModel.addProcess(process); return bpmnModel; } + /** - * 递归构建所有节点 - * @param process 流程对象 - * @param nodeDto 当前节点数据 - * @param flowId 流程定义ID + * 先创建所有的节点 + * + * @param process + * @param nodeDto + * @param flowId */ public static void buildAllNode(Process process, Node nodeDto, String flowId) { if (!NodeUtil.isNode(nodeDto)) { return; } + + List flowElementList = buildNode(nodeDto, flowId); for (FlowElement flowElement : flowElementList) { if (process.getFlowElement(flowElement.getId()) == null) { @@ -98,169 +95,198 @@ public class ModelUtil { } } - // 子节点 + //子节点 Node children = nodeDto.getChildren(); - if (Objects.equals(nodeDto.getType(), NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue()) - || Objects.equals(nodeDto.getType(), NodeTypeEnum.PARALLEL_GATEWAY.getValue())) { - // 条件分支 + if (NodeTypeEnum.getByValue(nodeDto.getType()).getBranch()) { + + //条件分支 List branchs = nodeDto.getConditionNodes(); for (Node branch : branchs) { - buildAllNode(process, branch.getChildren(), flowId); + buildAllNode(process, branch.getChildren(), + flowId); + } if (NodeUtil.isNode(children)) { buildAllNode(process, children, flowId); } - } - else { + } else { if (NodeUtil.isNode(children)) { buildAllNode(process, children, flowId); } } + } /** - * 递归构建节点内部的顺序流 - * @param process 流程对象 - * @param nodeDto 当前节点数据 - * @param flowId 流程定义ID + * 先创建所有的内部节点连接线 + * + * @param process + * @param nodeDto + * @param flowId */ public static void buildAllNodeInnerSequence(Process process, Node nodeDto, String flowId) { if (!NodeUtil.isNode(nodeDto)) { return; } - // 画内部线 + + //画内部线 List flowList = buildInnerSequenceFlow(nodeDto, flowId); for (SequenceFlow sequenceFlow : flowList) { process.addFlowElement(sequenceFlow); } - // 子节点 + //子节点 Node children = nodeDto.getChildren(); - if (nodeDto.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue() - || nodeDto.getType() == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) { - // 条件分支 + if (NodeTypeEnum.getByValue(nodeDto.getType()).getBranch() ) { + //条件分支 List branchs = nodeDto.getConditionNodes(); for (Node branch : branchs) { - buildAllNodeInnerSequence(process, branch.getChildren(), flowId); + buildAllNodeInnerSequence(process, branch.getChildren(), + flowId); + } if (NodeUtil.isNode(children)) { buildAllNodeInnerSequence(process, children, flowId); } - } - else { + } else { if (NodeUtil.isNode(children)) { buildAllNodeInnerSequence(process, children, flowId); } } + } + /** - * 递归构建节点之间的顺序流 - * @param process 流程对象 - * @param nodeDto 当前节点数据 - * @param nextNodeDto 下一个节点数据 + * 递归创建节点间连线 + * + * @param process 流程 + * @param nodeDto 节点对象 + * @param nextId */ - public static void buildAllNodeOuterSequence(Process process, Node nodeDto, Node nextNodeDto) { + public static void buildAllNodeOuterSequence(Process process, Node nodeDto, String nextId) { + if (!NodeUtil.isNode(nodeDto)) { return; } - // 子节点 + //子节点 Node children = nodeDto.getChildren(); - if (nodeDto.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue() - || nodeDto.getType() == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) { - // 条件分支 + if (NodeTypeEnum.getByValue(nodeDto.getType()).getBranch() ) { +// children = children.getChildren(); + //条件分支 List branchs = nodeDto.getConditionNodes(); int ord = 1; int size = branchs.size(); for (Node branch : branchs) { - buildAllNodeOuterSequence(process, branch.getChildren(), - NodeUtil.isNode(children) ? children : nextNodeDto); + + + buildAllNodeOuterSequence(process, branch.getChildren(), nodeDto.getTailId()); String expression = null; - if (nodeDto.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue()) { + if (nodeDto.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue() ) { if (ord == size) { - expression = NodeExpressionStrategyFactory.handleDefaultBranch(branchs); - } - else { + expression = NodeExpressionStrategyFactory.handleDefaultBranch(branchs, ord - 1); + } else if (nodeDto.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue() && ord > 1) { + expression = NodeExpressionStrategyFactory.handleDefaultBranch(branchs, ord - 1); + } else { expression = NodeExpressionStrategyFactory.handle(branch); } } - // 添加连线 + + //添加连线 if (!NodeUtil.isNode(branch.getChildren())) { - // 当前分支 没有其他节点了 所有就是网关和网关后面节点直接连线 - List sequenceFlowList = buildSequenceFlow( - NodeUtil.isNode(children) ? children : nextNodeDto, nodeDto, expression); - for (SequenceFlow sequenceFlow : sequenceFlowList) { - process.addFlowElement(sequenceFlow); - } - } - else { - // 当前节点 就是网关和第一个节点(非EMPTY节点)连线 - List sequenceFlowList = buildSequenceFlow(branch.getChildren(), nodeDto, expression); - for (SequenceFlow sequenceFlow : sequenceFlowList) { - process.addFlowElement(sequenceFlow); - } + //当前分支 没有其他节点了 所有就是网关和网关后面节点直接连线 + + SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeDto.getId(), nodeDto.getTailId(), + expression, + StrUtil.format("{}->{}", nodeDto.getName(), nodeDto.getName()) + ); + process.addFlowElement(sequenceFlow); + } else { + + SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeDto.getId(), branch.getChildren().getHeadId(), + expression, + StrUtil.format("{}->{}", nodeDto.getName(), branch.getChildren().getName()) + ); + process.addFlowElement(sequenceFlow); } ord++; } - if (NodeUtil.isNode(children)) { - buildAllNodeOuterSequence(process, children, nextNodeDto); - } + //分支结尾的合并分支节点-》下一个节点 + if (children != null && StrUtil.isNotBlank(children.getHeadId()) && StrUtil.isNotBlank(nodeDto.getTailId())) { - } - else { - // 添加连线 - List sequenceFlowList = buildSequenceFlow(children, nodeDto, ""); - for (SequenceFlow sequenceFlow : sequenceFlowList) { + SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeDto.getTailId(), children.getHeadId(), + "", + StrUtil.format("{}->{}", nodeDto.getName(), children.getName()) + ); + process.addFlowElement(sequenceFlow); + + } else if (StrUtil.isAllNotBlank(nodeDto.getTailId(), nextId)) { + SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeDto.getTailId(), nextId, + "", + StrUtil.format("{}->{}", nodeDto.getName(), nextId) + ); process.addFlowElement(sequenceFlow); } + + + buildAllNodeOuterSequence(process, children, nextId); + + + } else { + //添加连线 if (NodeUtil.isNode(children)) { - buildAllNodeOuterSequence(process, children, nextNodeDto); - } - else { - List sequenceFlowList1 = buildSequenceFlow(nextNodeDto, nodeDto, ""); - for (SequenceFlow sequenceFlow : sequenceFlowList1) { + List sequenceFlowList = buildSequenceFlow(children, nodeDto, ""); + for (SequenceFlow sequenceFlow : sequenceFlowList) { process.addFlowElement(sequenceFlow); } + buildAllNodeOuterSequence(process, children, nextId); + } else if (nodeDto.getType() != NodeTypeEnum.END.getValue().intValue()) { + SequenceFlow seq = buildSingleSequenceFlow(nodeDto.getTailId(), nextId, "", StrUtil.format("{}->{}", + nodeDto.getName(), nextId)); + + process.addFlowElement(seq); + } } } + /** - * 构建单个节点对象 - * @param node 节点数据 - * @param flowId 流程定义ID - * @return 流程元素列表 + * 构建节点 + * + * @param node 前端传输节点 + * @param flowId + * @return */ private static List buildNode(Node node, String flowId) { List flowElementList = new ArrayList<>(); - if (!NodeUtil.isNode(node)) { return flowElementList; } - // 设置节点的连线头节点 + //设置节点的连线头节点 node.setHeadId(node.getId()); - // 设置节点的连线尾节点 + //设置节点的连线尾节点 node.setTailId(node.getId()); node.setName(StrUtil.format("{}[{}]", node.getName(), RandomUtil.randomNumbers(5))); - // 存储节点数据 + //存储节点数据 RemoteFlowTaskService remoteFlowTaskService = SpringUtil.getBean(RemoteFlowTaskService.class); ProcessNodeDataDto processNodeDataDto = new ProcessNodeDataDto(); processNodeDataDto.setFlowId(flowId); @@ -268,105 +294,125 @@ public class ModelUtil { processNodeDataDto.setData(JSONUtil.toJsonStr(node)); remoteFlowTaskService.saveNodeOriData(processNodeDataDto); - // 开始 + //开始 if (node.getType() == NodeTypeEnum.ROOT.getValue().intValue()) { flowElementList.addAll(buildStartNode(node)); } - // 审批 + //结束 + if (node.getType() == NodeTypeEnum.END.getValue().intValue()) { + flowElementList.add(buildEndNode(node, false)); + } + + //审批 if (node.getType() == NodeTypeEnum.APPROVAL.getValue().intValue()) { + flowElementList.addAll(buildApproveNode(node)); } - // 抄送 + //抄送 if (node.getType() == NodeTypeEnum.CC.getValue().intValue()) { - flowElementList.add(buildCCNode(node)); } - // 条件分支 + //条件分支 if (node.getType() == NodeTypeEnum.EXCLUSIVE_GATEWAY.getValue().intValue()) { - - flowElementList.add(buildExclusiveGatewayNode(node)); + flowElementList.addAll(buildInclusiveGatewayNode(node)); } - // 并行分支 + //并行分支 if (node.getType() == NodeTypeEnum.PARALLEL_GATEWAY.getValue().intValue()) { - flowElementList.addAll(buildParallelGatewayNode(node)); } + return flowElementList; } /** - * 构建开始节点 添加一个自动完成任务的用户任务节点 + * 构建开始节点 + * 添加一个自动完成任务的用户任务节点 + * * @param node 前端传输节点 * @return */ private static List buildStartNode(Node node) { + List flowElementList = new ArrayList<>(); + + StartEvent startEvent = new StartEvent(); startEvent.setId(node.getId()); startEvent.setName(node.getName()); - List flowElementList = new ArrayList<>(); flowElementList.add(startEvent); + + + return flowElementList; } /** * 构建审批节点 + * * @param node * @return */ private static List buildApproveNode(Node node) { List flowElementList = new ArrayList<>(); + node.setTailId(StrUtil.format("approve_service_task_{}", node.getId())); - node.setTailId(StrUtil.format("approve_gateway_{}", node.getId())); - // 创建了任务执行监听器 - // 先执行指派人 后创建 - // https://tkjohn.github.io/flowable-userguide/#eventDispatcher + //创建了任务执行监听器 + //先执行指派人 后创建 + //https://tkjohn.github.io/flowable-userguide/#eventDispatcher FlowableListener createListener = new FlowableListener(); createListener.setImplementation(ApprovalCreateListener.class.getCanonicalName()); createListener.setImplementationType("class"); createListener.setEvent("create"); + UserTask userTask = buildUserTask(node, createListener); flowElementList.add(userTask); - Node exclusiveNode = new Node(); - exclusiveNode.setId(StrUtil.format("approve_gateway_{}", node.getId())); - exclusiveNode.setName("审批-排他网关"); - flowElementList.add(buildExclusiveGatewayNode(exclusiveNode)); - // 创建结束节点 - Node endNode = new Node(); - endNode.setId(StrUtil.format("approve_end_{}", node.getId())); - endNode.setName("审批-结束节点"); - EndEvent endEvent = buildEndNode(endNode, false); - flowElementList.add(endEvent); + + ServiceTask serviceTask = new ServiceTask(); + serviceTask.setId(StrUtil.format("approve_service_task_{}", node.getId())); + serviceTask.setName(StrUtil.format("{}_服务任务", node.getName())); + serviceTask.setImplementationType("class"); + serviceTask.setImplementation(ApproveServiceTask.class.getCanonicalName()); + serviceTask.setAsynchronous(false); + + + + flowElementList.add(serviceTask); + { - // 执行人处理 + + //执行人处理 String inputDataItem = "${multiInstanceHandler.resolveAssignee(execution)}"; - // 串行 + + //串行 boolean isSequential = true; Integer multipleMode = node.getMultipleMode(); - // 多人 + //多人 if ((multipleMode == ProcessInstanceConstant.MULTIPLE_MODE_AL_SAME)) { - // 并行会签 + //并行会签 isSequential = false; } - // 串行会签 + if ((multipleMode == ProcessInstanceConstant.MULTIPLE_MODE_ALL_SORT)) { + + //串行会签 + } if ((multipleMode == ProcessInstanceConstant.MULTIPLE_MODE_ONE)) { - // 或签 + //或签 isSequential = false; } @@ -385,8 +431,11 @@ public class ModelUtil { return flowElementList; } + + /** * 创建用户任务 + * * @param node 前端传输节点 * @return */ @@ -397,7 +446,11 @@ public class ModelUtil { if (flowableListeners != null) { List taskListeners = new ArrayList<>(); - Collections.addAll(taskListeners, flowableListeners); + + for (FlowableListener flowableListener : flowableListeners) { + taskListeners.add(flowableListener); + + } userTask.setTaskListeners(taskListeners); } @@ -405,26 +458,31 @@ public class ModelUtil { } /** - * 构建排他网关 + * 构建简单的包容网关 + * * @param node * @return */ - private static FlowElement buildExclusiveGatewayNode(Node node) { + private static FlowElement buildSimpleExclusiveGatewayNode(Node node) { + + ExclusiveGateway exclusiveGateway = new ExclusiveGateway(); exclusiveGateway.setId(node.getId()); exclusiveGateway.setName(node.getName()); + return exclusiveGateway; } + /** * 构建并行网关 + * * @param node * @return */ private static List buildParallelGatewayNode(Node node) { - // node.setTailId(StrUtil.format("{}_merge_gateway", node.getId())); - + node.setTailId(StrUtil.format("{}_merge_gateway", node.getId())); List flowElementList = new ArrayList<>(); ParallelGateway inclusiveGateway = new ParallelGateway(); @@ -432,7 +490,7 @@ public class ModelUtil { inclusiveGateway.setName(node.getName()); flowElementList.add(inclusiveGateway); - // 合并网关 + //合并网关 ParallelGateway parallelGateway = new ParallelGateway(); parallelGateway.setId(StrUtil.format("{}_merge_gateway", node.getId())); parallelGateway.setName(StrUtil.format("{}_合并网关", node.getName())); @@ -441,9 +499,36 @@ public class ModelUtil { return flowElementList; } + /** + * 构建包容网关 + * + * @param node + * @return + */ + private static List buildInclusiveGatewayNode(Node node) { + + node.setTailId(StrUtil.format("{}_merge_gateway", node.getId())); + + List flowElementList = new ArrayList<>(); + + InclusiveGateway inclusiveGateway = new InclusiveGateway(); + inclusiveGateway.setId(node.getId()); + inclusiveGateway.setName(node.getName()); + flowElementList.add(inclusiveGateway); + + //合并网关 + InclusiveGateway gateway = new InclusiveGateway(); + gateway.setId(StrUtil.format("{}_merge_gateway", node.getId())); + gateway.setName(StrUtil.format("{}_合并网关", node.getName())); + flowElementList.add(gateway); + + return flowElementList; + } + /** * 构建结束节点 - * @param node 前端传输节点 + * + * @param node 前端传输节点 * @param terminateAll * @return */ @@ -452,6 +537,7 @@ public class ModelUtil { endEvent.setId(node.getId()); endEvent.setName(node.getName()); + List definitionList = new ArrayList<>(); TerminateEventDefinition definition = new TerminateEventDefinition(); definition.setTerminateAll(terminateAll); @@ -463,14 +549,16 @@ public class ModelUtil { /** * 创建连接线 - * @param node 子级节点 + * + * @param node 子级节点 * @param parentNode 父级节点 * @param expression * @return 所有连接线 */ - private static List buildSequenceFlow(Node node, Node parentNode, String expression) { + private static List buildSequenceFlow(Node node, Node parentNode, String expression + ) { List sequenceFlowList = new ArrayList<>(); - // 没有子级了 + //没有子级了 if (!NodeUtil.isNode(node)) { return sequenceFlowList; } @@ -481,14 +569,19 @@ public class ModelUtil { return sequenceFlowList; } - SequenceFlow sequenceFlow = buildSingleSequenceFlow(parentNode.getTailId(), node.getHeadId(), expression); + + SequenceFlow sequenceFlow = buildSingleSequenceFlow(parentNode.getTailId(), node.getHeadId(), expression, + StrUtil.format("{}->{}", parentNode.getName(), node.getName()) + ); sequenceFlowList.add(sequenceFlow); + return sequenceFlowList; } /** * 生成扩展数据 + * * @param key * @param val * @return @@ -503,6 +596,7 @@ public class ModelUtil { /** * 创建抄送节点 + * * @param node * @return */ @@ -511,85 +605,93 @@ public class ModelUtil { ServiceTask serviceTask = new ServiceTask(); serviceTask.setId(node.getId()); serviceTask.setName(node.getName()); + serviceTask.setAsynchronous(false); serviceTask.setImplementationType("class"); serviceTask.setImplementation(CopyServiceTask.class.getCanonicalName()); + + ExtensionElement e = new ExtensionElement(); + { + + + e.setName("flowable:failedJobRetryTimeCycle"); + //上面的例子会让作业执行器重试5次,并在每次重试前等待1分钟。 + e.setElementText("R5/PT1M"); + + } + + serviceTask.addExtensionElement(e); return serviceTask; } + + /** * 创建连接线 - * @param node 父级节点 + * + * @param node 父级节点 * @param flowId * @return 所有连接线 */ - private static List buildInnerSequenceFlow(Node node, String flowId) { - List sequenceFlowList = new ArrayList<>(); + private static List buildInnerSequenceFlow(Node node, String flowId + ) { + + List sequenceFlowList = new ArrayList<>(); if (!NodeUtil.isNode(node)) { return sequenceFlowList; } + String nodeId = node.getId(); if (StrUtil.hasBlank(nodeId)) { return sequenceFlowList; } - boolean parentIsGateway = false; - Node prevNode = null; - if (StrUtil.isNotBlank(node.getParentId())) { - // 判断父级是否是包容或者并行网关 - RemoteFlowTaskService remoteFlowTaskService = SpringUtil.getBean(RemoteFlowTaskService.class); - prevNode = remoteFlowTaskService.queryNodeOriData(flowId, node.getParentId()).getData(); - if (prevNode != null) { - parentIsGateway = (Objects.equals(prevNode.getType(), NodeTypeEnum.PARALLEL_GATEWAY.getValue())); - } - - } - - if (parentIsGateway) { - String headId = node.getHeadId(); - node.setHeadId(StrUtil.format("{}_merge_gateway", prevNode.getId())); - { - SequenceFlow sequenceFlow = buildSingleSequenceFlow(node.getHeadId(), headId, "${12==12}"); - sequenceFlowList.add(sequenceFlow); - } - - } if (node.getType() == NodeTypeEnum.APPROVAL.getValue().intValue()) { - String gatewayId = StrUtil.format("approve_gateway_{}", nodeId); - String endId = StrUtil.format("approve_end_{}", nodeId); + + String gatewayId = StrUtil.format("approve_service_task_{}", nodeId); + { - SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeId, gatewayId, "${12==12}"); + SequenceFlow sequenceFlow = buildSingleSequenceFlow(nodeId, gatewayId, "${12==12}", null); sequenceFlowList.add(sequenceFlow); } - { - SequenceFlow sequenceFlow = buildSingleSequenceFlow(gatewayId, endId, - StrUtil.format("${!var:get({}_approve_condition)}", nodeId)); - sequenceFlowList.add(sequenceFlow); - } } + + + + return sequenceFlowList; } /** * 创建单个连接线 - * @param pId 父级id - * @param childId 子级id + * + * @param pId 父级id + * @param childId 子级id * @param expression 表达式 + * @param name * @return */ - private static SequenceFlow buildSingleSequenceFlow(String pId, String childId, String expression) { + private static SequenceFlow buildSingleSequenceFlow(String pId, String childId, String expression, String name) { + if (StrUtil.hasBlank(pId, childId)) { + return null; + } SequenceFlow sequenceFlow = new SequenceFlow(pId, childId); sequenceFlow.setConditionExpression(expression); sequenceFlow.setName(StrUtil.format("{}|{}", pId, childId)); + sequenceFlow.setName(StrUtil.format("连线[{}]", RandomUtil.randomString(5))); + if (StrUtil.isNotBlank(name)) { + sequenceFlow.setName(name); + } sequenceFlow.setId(StrUtil.format("sq-id-{}-{}", IdUtil.fastSimpleUUID(), RandomUtil.randomInt(1, 10000000))); return sequenceFlow; } + } diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/NodeTypeEnum.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/NodeTypeEnum.java index ac98964dd..d441cedd8 100644 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/NodeTypeEnum.java +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/NodeTypeEnum.java @@ -2,26 +2,36 @@ package com.pig4cloud.pigx.flow.task.constant; import lombok.Getter; +import java.util.Arrays; + /** * 节点枚举 */ @Getter public enum NodeTypeEnum { - ROOT("根节点", 0), + ROOT("根节点", 0, false), END("结束节点", -1, false), - APPROVAL("审批节点", 1), CC("抄送节点", 2), EXCLUSIVE_GATEWAY("条件分支", 4), PARALLEL_GATEWAY("并行分支", 5), EMPTY("空", 3) + APPROVAL("审批节点", 1, false), CC("抄送节点", 2, false), EXCLUSIVE_GATEWAY("条件分支", 4, true), + + PARALLEL_GATEWAY("并行分支", 5, true), EMPTY("空", 3, false), ; - NodeTypeEnum(String name, Integer value) { + public static NodeTypeEnum getByValue(int value) { + return Arrays.stream(NodeTypeEnum.values()).filter(w -> w.getValue() == value).findAny().orElse(null); + } + NodeTypeEnum(String name, Integer value, Boolean branch) { this.name = name; this.value = value; + this.branch = branch; } private String name; private Integer value; + private Boolean branch; + } diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/ProcessInstanceConstant.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/ProcessInstanceConstant.java index ead06f338..9ec61d0f9 100644 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/ProcessInstanceConstant.java +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/ProcessInstanceConstant.java @@ -27,6 +27,8 @@ public class ProcessInstanceConstant { */ public static final String USER_TASK_NOBODY_HANDLER_TO_END = "TO_END"; + public static final String USER_TASK_NOBODY_HANDLER_TO_REFUSE = "TO_REFUSE"; + /** * 拒绝之后 结束流程 */ diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/SecurityConstants.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/SecurityConstants.java deleted file mode 100644 index b20ddb881..000000000 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/constant/SecurityConstants.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.pig4cloud.pigx.flow.task.constant; - -/** - * Security 常量 - * - * @author haoxr - * @since 2023/03/24 - */ -public interface SecurityConstants { - - /** - * 登录接口路径 - */ - String LOGIN_PATH = "/api/v1/auth/login"; - - /** - * Token 前缀 - */ - String TOKEN_PREFIX = "Bearer "; - - /** - * 请求头Token的Key - */ - String TOKEN_KEY = "Authorization"; - - /** - * 验证码缓存前缀 - */ - String VERIFY_CODE_CACHE_PREFIX = "AUTH:VERIFY_CODE:"; - - /** - * 用户权限集合缓存前缀 - */ - String USER_PERMS_CACHE_PREFIX = "AUTH:USER_PERMS:"; - - /** - * 黑名单Token缓存前缀 - */ - String BLACK_TOKEN_CACHE_PREFIX = "AUTH:BLACK_TOKEN:"; - -} diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Node.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Node.java index c0ebe2125..54ae18d38 100644 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Node.java +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Node.java @@ -53,4 +53,6 @@ public class Node { private List conditionList; + private Refuse refuse; + } diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Refuse.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Refuse.java new file mode 100644 index 000000000..216310ed9 --- /dev/null +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/Refuse.java @@ -0,0 +1,12 @@ +package com.pig4cloud.pigx.flow.task.dto; + +import lombok.Data; + +@Data +public class Refuse { + + private String handler; + + private String nodeId; + +} diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/SelectValue.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/SelectValue.java new file mode 100644 index 000000000..890d27e9d --- /dev/null +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/dto/SelectValue.java @@ -0,0 +1,17 @@ +package com.pig4cloud.pigx.flow.task.dto; + +import lombok.Data; + +/** + * @author Huijun Zhao + * @description + * @date 2023-07-28 10:36 + */ +@Data +public class SelectValue { + + private String key; + + private String value; + +} diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/utils/NodeUtil.java b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/utils/NodeUtil.java index 0aa21dc78..bdb3e7253 100644 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/utils/NodeUtil.java +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-api/src/main/java/com/pig4cloud/pigx/flow/task/utils/NodeUtil.java @@ -18,6 +18,27 @@ public class NodeUtil { return childNode != null && StrUtil.isNotBlank(childNode.getId()); } + /** + * 添加结束节点 + * @param node + */ + public static void addEndNode(Node node) { + + Node children = node.getChildren(); + if (isNode(children)) { + addEndNode(children); + } + else { + Node end = new Node(); + end.setId("end"); + end.setType(NodeTypeEnum.END.getValue()); + end.setName("结束节点"); + end.setParentId(node.getId()); + node.setChildren(end); + } + + } + /** * 需要发起人选择用户的节点 * @param node diff --git a/pigx-flow/pigx-flow-task/pigx-flow-task-biz/src/main/java/com/pig4cloud/pigx/flow/task/service/impl/TaskServiceImpl.java b/pigx-flow/pigx-flow-task/pigx-flow-task-biz/src/main/java/com/pig4cloud/pigx/flow/task/service/impl/TaskServiceImpl.java index 0bf246a7a..835f70623 100644 --- a/pigx-flow/pigx-flow-task/pigx-flow-task-biz/src/main/java/com/pig4cloud/pigx/flow/task/service/impl/TaskServiceImpl.java +++ b/pigx-flow/pigx-flow-task/pigx-flow-task-biz/src/main/java/com/pig4cloud/pigx/flow/task/service/impl/TaskServiceImpl.java @@ -14,10 +14,12 @@ import com.pig4cloud.pigx.flow.task.api.feign.RemoteFlowEngineService; import com.pig4cloud.pigx.flow.task.constant.FormTypeEnum; import com.pig4cloud.pigx.flow.task.constant.NodeStatusEnum; import com.pig4cloud.pigx.flow.task.constant.ProcessInstanceConstant; +import com.pig4cloud.pigx.flow.task.dto.IndexPageStatistics; import com.pig4cloud.pigx.flow.task.dto.Node; import com.pig4cloud.pigx.flow.task.dto.TaskParamDto; import com.pig4cloud.pigx.flow.task.dto.TaskResultDto; import com.pig4cloud.pigx.flow.task.entity.Process; +import com.pig4cloud.pigx.flow.task.entity.ProcessCopy; import com.pig4cloud.pigx.flow.task.entity.ProcessInstanceRecord; import com.pig4cloud.pigx.flow.task.entity.ProcessNodeRecordAssignUser; import com.pig4cloud.pigx.flow.task.service.*; @@ -42,6 +44,8 @@ public class TaskServiceImpl implements ITaskService { private final IProcessService processService; + private final IProcessCopyService processCopyService; + private final IProcessNodeDataService nodeDataService; private final IProcessNodeRecordAssignUserService processNodeRecordAssignUserService; @@ -56,7 +60,15 @@ public class TaskServiceImpl implements ITaskService { */ @Override public R queryTaskData() { - return flowEngineService.querySimpleData(SecurityUtils.getUser().getId()); + R indexPageStatisticsR = flowEngineService + .querySimpleData(SecurityUtils.getUser().getId()); + + // 获取抄送任务 + Long copyCount = processCopyService.lambdaQuery() + .eq(ProcessCopy::getUserId, SecurityUtils.getUser().getId()) + .count(); + indexPageStatisticsR.getData().setCopyNum(copyCount); + return indexPageStatisticsR; } /**