24282 2 жил өмнө
parent
commit
109207aa5e

+ 2 - 2
hx-flow/src/main/java/com/fjhx/flow/core/FlowDelegate.java

@@ -12,9 +12,9 @@ import java.util.Map;
 @Slf4j
 public abstract class FlowDelegate {
 
-    public Map<String, Object> initTemplateMap(JSONObject submitData, JSONObject startData) {
+    public Map<String, Object> initTemplateMap(JSONObject currentData, JSONObject startData) {
 
-        Map<String, Object> map = BeanUtil.beanToMap(submitData);
+        Map<String, Object> map = BeanUtil.beanToMap(currentData);
         map.put("startData", BeanUtil.beanToMap(startData));
         map.put("nickName", SecurityUtils.getLoginUser().getUser().getNickName());
         map.put("date", DateUtil.formatDate(new Date()));

+ 0 - 1
hx-flow/src/main/java/com/fjhx/flow/enums/FlowStatusEnum.java

@@ -15,7 +15,6 @@ public enum FlowStatusEnum {
     IN_PROGRESS(1, "进行中"),
     HAVE_PASSED(2, "已通过"),
     REJECTED(3, "已驳回"),
-    END_ERROR(9, "结束流程异常"),
     ;
 
     private final Integer key;

+ 126 - 137
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowProcessServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fjhx.flow.service.flow.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
 import com.alibaba.fastjson.JSONObject;
@@ -37,7 +38,6 @@ import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -85,10 +85,6 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(q -> q
                 .eq(FlowDefinitionNode::getFlowDefinitionId, flowDefinition.getId()));
 
-        // 父级节点map
-        Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
-                .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
-
         // 寻找开始节点
         FlowDefinitionNode startNode = flowDefinitionNodeList.stream()
                 .filter(item -> NodeTypeEnum.START.getKey().equals(item.getNodeType()))
@@ -109,7 +105,32 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         FlowThreadLocalUtil.setFlowId(flowId);
 
         // 寻找下一节点
-        FlowDefinitionNode nextUserNode = getNextUserNode(startNode, parentNodeMap);
+        FlowDefinitionNode nextUserNode = getNextUserNode(startNode, flowDefinitionNodeList);
+        NodeTypeEnum nextNodeType = NodeTypeEnum.getEnum(nextUserNode.getNodeType());
+
+        // 流程实例
+        FlowExample flowExample = new FlowExample();
+
+        // 赋值下一个节点处理用户id
+        if (!NodeTypeEnum.END.equals(nextNodeType)) {
+            // 前端没有返回下一节点处理人
+            if (dto.getHandleUserId() == null) {
+                FlowResult handleUser = getHandleUser(nextUserNode);
+                // 如果下一节点处理用户只有1人,赋值用户id
+                if (handleUser.getSuccess()) {
+                    flowExample.setHandleUserId(handleUser.getUserId());
+                }
+                // 如果下一节点处理用户有多人,则返回用户列表让用户选择下一节点处理人id
+                else {
+                    return handleUser;
+                }
+            }
+            // 前端返回下一节点处理人
+            else {
+                // 传入用户id
+                flowExample.setHandleUserId(dto.getHandleUserId());
+            }
+        }
 
         // 执行开始流程方法
         Long businessId;
@@ -122,15 +143,6 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
         List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
 
-        // 流程实例
-        FlowExample flowExample = new FlowExample();
-        flowExample.setTitle(StrUtil.format(flowDefinition.getTitleTemplate(), templateMap, true));
-        flowExample.setFlowKey(dto.getFlowKey());
-        flowExample.setDefinitionId(flowDefinition.getId());
-        flowExample.setDefinitionNodeId(nextUserNode.getId());
-        flowExample.setBusinessId(businessId);
-        flowExample.setStartData(dto.getData().toJSONString());
-
         // 开始节点明细
         FlowExampleDetail startExampleDetail = new FlowExampleDetail();
         startExampleDetail.setFlowExampleId(flowId);
@@ -141,7 +153,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         startExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
         flowExampleDetailList.add(startExampleDetail);
 
-        if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
+        if (NodeTypeEnum.END.equals(nextNodeType)) {
 
             // 赋值业务id到租户线程
             FlowThreadLocalUtil.setBusinessId(businessId);
@@ -155,7 +167,6 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
             endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
             endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
-            endExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
             flowExampleDetailList.add(endExampleDetail);
 
             // 流程已通过
@@ -166,23 +177,15 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             // 流程进行中
             flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
 
-            // 赋值下一个节点处理用户
-            if (dto.getHandleUserId() == null) {
-                FlowResult handleUser = getHandleUser(nextUserNode);
-                // 如果下一节点处理用户有多人,放回用户列表让用户选择
-                if (handleUser.getSuccess()) {
-                    // 如果下一节点处理用户只有1人,赋值用户id
-                    flowExample.setHandleUserId(handleUser.getUserId());
-                } else {
-                    return handleUser;
-                }
-            } else {
-                // 传入用户id
-                flowExample.setHandleUserId(dto.getHandleUserId());
-            }
-
         }
 
+        flowExample.setTitle(StrUtil.format(flowDefinition.getTitleTemplate(), templateMap, true));
+        flowExample.setFlowKey(dto.getFlowKey());
+        flowExample.setDefinitionId(flowDefinition.getId());
+        flowExample.setDefinitionNodeId(nextUserNode.getId());
+        flowExample.setBusinessId(businessId);
+        flowExample.setStartData(dto.getData().toJSONString());
+
         flowExampleService.save(flowExample);
         flowExampleDetailService.saveBatch(flowExampleDetailList);
 
@@ -197,17 +200,17 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         Long flowId = dto.getFlowId();
 
         FlowExample flowExample = flowExampleService.getById(flowId);
+
         if (flowExample == null) {
             throw new ServiceException("没有找到流程");
         }
 
-        if (!flowExample.getVersion().equals(dto.getVersion())) {
-            throw new ServiceException("流程已被处理");
+        if (flowExample.getStatus() > 1) {
+            throw new ServiceException("流程已结束");
         }
 
-        Integer status = flowExample.getStatus();
-        if (status > 1) {
-            throw new ServiceException("流程已结束");
+        if (ObjectUtil.notEqual(flowExample.getVersion(), dto.getVersion())) {
+            throw new ServiceException("流程已被处理");
         }
 
         // 找到代码定义的流程bean
@@ -221,9 +224,8 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                 .eq(FlowDefinitionNode::getFlowDefinitionId, flowExample.getDefinitionId()));
 
         // 获取当前审批节点
-        Long definitionNodeId = flowExample.getDefinitionNodeId();
         FlowDefinitionNode currentNode = flowDefinitionNodeList.stream()
-                .filter(item -> item.getId().equals(definitionNodeId))
+                .filter(item -> item.getId().equals(flowExample.getDefinitionNodeId()))
                 .findFirst().orElse(null);
 
         if (currentNode == null) {
@@ -234,83 +236,46 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         HandleTypeEnum handleTypeEnum = HandleTypeEnum.getEnum(dto.getHandleType());
 
         // 发起流程参数
-        JSONObject startDataJson = JSONObject.parseObject(flowExample.getStartData());
-        Map<String, Object> templateMap = flowDelegate.initTemplateMap(dto.getData(), startDataJson);
+        JSONObject startData = JSONObject.parseObject(flowExample.getStartData());
+        Map<String, Object> templateMap = flowDelegate.initTemplateMap(dto.getData(), startData);
         FlowThreadLocalUtil.setTemplateData(templateMap);
-        FlowThreadLocalUtil.setStartData(dto.getData());
+        FlowThreadLocalUtil.setStartData(startData);
         FlowThreadLocalUtil.setCurrentData(dto.getData());
         FlowThreadLocalUtil.setFlowId(flowId);
         FlowThreadLocalUtil.setBusinessId(flowExample.getBusinessId());
         FlowThreadLocalUtil.setHandleTypeEnum(handleTypeEnum);
 
-        // 执行当前节点方法
-        String handlingMethod = currentNode.getHandlingMethod();
-        if (StrUtil.isNotBlank(handlingMethod)) {
-            try {
-                invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
-            } catch (Exception e) {
-                log.error("跳转节点方法异常", e);
-                throw new ServiceException("跳转节点方法异常");
-            }
-        }
-
-        // 节点处理
-        List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
-        FlowExampleDetail nodeExampleDetail = new FlowExampleDetail();
-        nodeExampleDetail.setFlowExampleId(flowId);
-        nodeExampleDetail.setFlowDefinitionNodeId(currentNode.getId());
-        nodeExampleDetail.setFlowDefinitionNodeType(currentNode.getNodeType());
-        nodeExampleDetail.setHandleType(dto.getHandleType());
-        nodeExampleDetail.setHandleRemark(dto.getRemark());
-        nodeExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
-        flowExampleDetailList.add(nodeExampleDetail);
-
         // 跳转节点
-        FlowDefinitionNode jumpUserNode;
+        FlowDefinitionNode nextUserNode = null;
         switch (handleTypeEnum) {
             case NEXT:
 
-                // 父级节点map
-                Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
-                        .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
-
                 // 寻找下一节点
-                jumpUserNode = getNextUserNode(currentNode, parentNodeMap);
+                nextUserNode = getNextUserNode(currentNode, flowDefinitionNodeList);
 
                 // 赋值流程所在id
-                flowExample.setDefinitionNodeId(jumpUserNode.getId());
+                flowExample.setDefinitionNodeId(nextUserNode.getId());
 
                 // 如果下个节点是结束节点
-                if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
-
-                    // 执行结束方法
-                    invokeEndMethod(jumpUserNode, flowDelegateCls, flowDelegate);
-
-                    // 结束流程明细
-                    FlowExampleDetail endExampleDetail = new FlowExampleDetail();
-                    endExampleDetail.setFlowExampleId(flowId);
-                    endExampleDetail.setFlowDefinitionNodeId(jumpUserNode.getId());
-                    endExampleDetail.setFlowDefinitionNodeType(jumpUserNode.getNodeType());
-                    endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
-                    endExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
-                    flowExampleDetailList.add(endExampleDetail);
-
+                if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
                     // 流程已通过
                     flowExample.setStatus(FlowStatusEnum.HAVE_PASSED.getKey());
-
                 } else {
 
-                    // 赋值下一个节点处理用户
+                    // 前端没有返回下一节点处理人
                     if (dto.getHandleUserId() == null) {
-                        FlowResult handleUser = getHandleUser(jumpUserNode);
-                        // 如果下一节点处理用户有多人,放回用户列表让用户选择
+                        FlowResult handleUser = getHandleUser(nextUserNode);
+                        // 如果下一节点处理用户只有1人,赋值用户id
                         if (handleUser.getSuccess()) {
-                            // 如果下一节点处理用户只有1人,赋值用户id
                             flowExample.setHandleUserId(handleUser.getUserId());
-                        } else {
+                        }
+                        // 如果下一节点处理用户有多人,则返回用户列表让用户选择下一节点处理人id
+                        else {
                             return handleUser;
                         }
-                    } else {
+                    }
+                    // 前端返回下一节点处理人
+                    else {
                         // 传入用户id
                         flowExample.setHandleUserId(dto.getHandleUserId());
                     }
@@ -322,45 +287,20 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
             case PREVIOUS:
 
-                // 节点id对象map
-                Map<Long, FlowDefinitionNode> nodeMap = flowDefinitionNodeList.stream()
-                        .collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
-
                 // 查找上一个节点
-                jumpUserNode = getLastOneUserNode(currentNode, nodeMap);
+                FlowExampleDetail lastOneFlowExampleDetail = getLastOneUserNode(flowId);
 
                 // 赋值流程所在id
-                flowExample.setDefinitionNodeId(jumpUserNode.getId());
+                flowExample.setDefinitionNodeId(lastOneFlowExampleDetail.getFlowDefinitionNodeId());
+                flowExample.setHandleUserId(lastOneFlowExampleDetail.getCreateUser());
 
                 // 如果流程回退到开始节点
-                if (NodeTypeEnum.START.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
-
+                if (NodeTypeEnum.START.getKey().equals(lastOneFlowExampleDetail.getFlowDefinitionNodeType())) {
                     // 流程未发起
                     flowExample.setStatus(FlowStatusEnum.UNINITIATED.getKey());
-
-                    // 赋值处理人为发起人
-                    flowExample.setHandleUserId(flowExample.getCreateUser());
-
                 } else {
-
                     // 流程进行中
                     flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
-
-                    // 赋值下一个节点处理用户
-                    if (dto.getHandleUserId() == null) {
-                        FlowResult handleUser = getHandleUser(jumpUserNode);
-                        // 如果下一节点处理用户有多人,放回用户列表让用户选择
-                        if (handleUser.getSuccess()) {
-                            // 如果下一节点处理用户只有1人,赋值用户id
-                            flowExample.setHandleUserId(handleUser.getUserId());
-                        } else {
-                            return handleUser;
-                        }
-                    } else {
-                        // 传入用户id
-                        flowExample.setHandleUserId(dto.getHandleUserId());
-                    }
-
                 }
                 break;
 
@@ -373,7 +313,49 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
         }
 
-        flowExampleService.updateById(flowExample);
+        // 执行当前节点方法
+        String handlingMethod = currentNode.getHandlingMethod();
+        if (StrUtil.isNotBlank(handlingMethod)) {
+            try {
+                invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
+            } catch (Exception e) {
+                log.error("跳转节点方法异常", e);
+                throw new ServiceException("跳转节点方法异常");
+            }
+        }
+
+        // 节点处理明细
+        List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
+        FlowExampleDetail nodeExampleDetail = new FlowExampleDetail();
+        nodeExampleDetail.setFlowExampleId(flowId);
+        nodeExampleDetail.setFlowDefinitionNodeId(currentNode.getId());
+        nodeExampleDetail.setFlowDefinitionNodeType(currentNode.getNodeType());
+        nodeExampleDetail.setHandleType(dto.getHandleType());
+        nodeExampleDetail.setHandleRemark(dto.getRemark());
+        nodeExampleDetail.setSubmitData(JSONObject.toJSONString(dto));
+        flowExampleDetailList.add(nodeExampleDetail);
+
+        // 如果流程已结束
+        if (FlowStatusEnum.HAVE_PASSED.getKey().equals(flowExample.getStatus())) {
+
+            // 执行结束方法
+            invokeEndMethod(nextUserNode, flowDelegateCls, flowDelegate);
+
+            // 结束流程明细
+            FlowExampleDetail endExampleDetail = new FlowExampleDetail();
+            endExampleDetail.setFlowExampleId(flowId);
+            endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
+            endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
+            endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
+            flowExampleDetailList.add(endExampleDetail);
+
+        }
+
+        flowExample.setVersion(dto.getVersion());
+        boolean b = flowExampleService.updateById(flowExample);
+        if (!b) {
+            throw new ServiceException("流程已被处理");
+        }
         flowExampleDetailService.saveBatch(flowExampleDetailList);
 
         FlowResult flowResult = new FlowResult();
@@ -434,11 +416,14 @@ public class FlowProcessServiceImpl implements FlowProcessService {
     /**
      * 查找下一个用户执行节点
      *
-     * @param currentNode   当前节点
-     * @param parentNodeMap 父节点map
+     * @param currentNode            当前节点
+     * @param flowDefinitionNodeList 流程节点列表
      * @return 用户节点
      */
-    private FlowDefinitionNode getNextUserNode(FlowDefinitionNode currentNode, Map<Long, List<FlowDefinitionNode>> parentNodeMap) {
+    private FlowDefinitionNode getNextUserNode(FlowDefinitionNode currentNode, List<FlowDefinitionNode> flowDefinitionNodeList) {
+        // 父级节点map
+        Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
+                .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
         // 查找下个节点
         List<FlowDefinitionNode> nextNodeList = parentNodeMap.get(currentNode.getId());
         FlowDefinitionNode nextNode = null;
@@ -448,15 +433,15 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             for (FlowDefinitionNode flowDefinitionNode : nextNodeList) {
                 // 获取跳转条件
                 String jumpCondition = flowDefinitionNode.getJumpCondition();
-                // 跳转条件为空表示默认跳转
-                if (StrUtil.isBlank(jumpCondition)) {
-                    nextNode = flowDefinitionNode;
-                }
                 // 符合条件
                 if (expressionResult(FlowThreadLocalUtil.getTemplateData(), jumpCondition)) {
                     nextNode = flowDefinitionNode;
                     break;
                 }
+                // 跳转条件为空表示默认跳转
+                if (StrUtil.isBlank(jumpCondition)) {
+                    nextNode = flowDefinitionNode;
+                }
             }
             if (nextNode == null) {
                 throw new ServiceException("未识别到分支跳转节点");
@@ -472,7 +457,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         }
         // 如果下一节点为分支,递归找下一节点
         if (NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(nextNode.getNodeType()))) {
-            return getNextUserNode(nextNode, parentNodeMap);
+            return getNextUserNode(nextNode, flowDefinitionNodeList);
         }
         return nextNode;
     }
@@ -480,16 +465,20 @@ public class FlowProcessServiceImpl implements FlowProcessService {
     /**
      * 查找上一个节点
      *
-     * @param currentNode 当前节点
-     * @param nodeMap     id节点map
+     * @param flowExampleId 流程实例id
      * @return 用户节点
      */
-    private FlowDefinitionNode getLastOneUserNode(FlowDefinitionNode currentNode, Map<Long, FlowDefinitionNode> nodeMap) {
-        FlowDefinitionNode lastOneUserNode = nodeMap.get(currentNode.getParentId());
-        if (NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(lastOneUserNode.getNodeType()))) {
-            return getLastOneUserNode(lastOneUserNode, nodeMap);
+    private FlowExampleDetail getLastOneUserNode(Long flowExampleId) {
+        FlowExampleDetail flowExampleDetail = flowExampleDetailService.getOne(q -> q
+                .eq(FlowExampleDetail::getFlowExampleId, flowExampleId)
+                .orderByDesc(BaseIdPo::getId)
+                .last("limit 1,1"));
+
+        if (flowExampleDetail == null) {
+            throw new ServiceException("没有找到回退节点");
         }
-        return lastOneUserNode;
+
+        return flowExampleDetail;
     }
 
     /**