24282 преди 2 години
родител
ревизия
605af883e2

+ 6 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowProcessController.java

@@ -2,6 +2,7 @@ package com.fjhx.flow.controller.flow;
 
 import com.baomidou.dynamic.datasource.annotation.DS;
 import com.fjhx.flow.entity.flow.dto.InitiateDto;
+import com.fjhx.flow.entity.flow.dto.JumpDto;
 import com.fjhx.flow.service.flow.FlowProcessService;
 import com.ruoyi.common.constant.DatasourceConstant;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,4 +28,9 @@ public class FlowProcessController {
         flowProcessService.initiate(dto);
     }
 
+    @PostMapping("/jump")
+    public void jump(@Validated @RequestBody JumpDto dto) {
+        flowProcessService.jump(dto);
+    }
+
 }

+ 1 - 1
hx-flow/src/main/java/com/fjhx/flow/core/FlowBean.java

@@ -25,7 +25,7 @@ public class FlowBean {
     public static Class<? extends FlowDelegate> getBean(String flowKey) {
         Class<? extends FlowDelegate> bean = map.get(flowKey);
         if (bean == null) {
-            throw new ServiceException("没有找到流程bean");
+            throw new ServiceException("没有注册流程bean");
         }
         return bean;
     }

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

@@ -4,18 +4,22 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.common.utils.SecurityUtils;
+import lombok.extern.slf4j.Slf4j;
 
 import java.util.Date;
 import java.util.Map;
 
+@Slf4j
 public abstract class FlowDelegate {
 
-    public Map<String, Object> initTemplateMap(JSONObject submitData, Object startData) {
+    public Map<String, Object> initTemplateMap(JSONObject submitData, JSONObject startData) {
+
         Map<String, Object> map = BeanUtil.beanToMap(submitData);
+        map.put("startData", BeanUtil.beanToMap(startData));
         map.put("nickName", SecurityUtils.getLoginUser().getUser().getNickName());
         map.put("date", DateUtil.formatDate(new Date()));
         map.put("dateTime", DateUtil.formatDateTime(new Date()));
-        map.put("startData", BeanUtil.beanToMap(startData));
+
         return map;
     }
 
@@ -33,4 +37,11 @@ public abstract class FlowDelegate {
      */
     public abstract void end();
 
+    /**
+     * 驳回结束流程
+     */
+    public void rejected() {
+        log.warn("为实现驳回逻辑");
+    }
+
 }

+ 6 - 0
hx-flow/src/main/java/com/fjhx/flow/core/FlowThreadLocalData.java

@@ -1,6 +1,7 @@
 package com.fjhx.flow.core;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fjhx.flow.enums.HandleTypeEnum;
 import lombok.Getter;
 import lombok.Setter;
 
@@ -35,4 +36,9 @@ public class FlowThreadLocalData {
      */
     private Map<String, Object> templateData;
 
+    /**
+     * 处理类型
+     */
+    private HandleTypeEnum handleTypeEnum;
+
 }

+ 9 - 0
hx-flow/src/main/java/com/fjhx/flow/core/FlowThreadLocalUtil.java

@@ -1,6 +1,7 @@
 package com.fjhx.flow.core;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fjhx.flow.enums.HandleTypeEnum;
 import org.springframework.core.NamedThreadLocal;
 
 import java.util.Map;
@@ -49,6 +50,14 @@ public class FlowThreadLocalUtil {
         getData().setTemplateData(templateData);
     }
 
+    public static HandleTypeEnum getHandleTypeEnum() {
+        return getData().getHandleTypeEnum();
+    }
+
+    public static void setHandleTypeEnum(HandleTypeEnum handleTypeEnum) {
+        getData().setHandleTypeEnum(handleTypeEnum);
+    }
+
     private static FlowThreadLocalData getData() {
         FlowThreadLocalData flowThreadLocalData = FLOW_HOLDER.get();
         if (flowThreadLocalData == null) {

+ 41 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/JumpDto.java

@@ -0,0 +1,41 @@
+package com.fjhx.flow.entity.flow.dto;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+@Getter
+@Setter
+public class JumpDto {
+
+    /**
+     * 流程id
+     */
+    @NotNull(message = "流程id不能为空")
+    private Long flowId;
+
+    /**
+     * 处理类型:
+     * 1跳转下一节点
+     * 2返回上一节点
+     * 3结束流程
+     */
+    @NotNull(message = "跳转节点不能为空")
+    private Integer handleType;
+
+    @NotNull(message = "实例版本不能为空")
+    private Integer version;
+
+    /**
+     * 处理备注
+     */
+    private String remark;
+
+    /**
+     * 提交数据
+     */
+    private JSONObject data;
+
+}

+ 14 - 2
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowExample.java

@@ -2,6 +2,7 @@ package com.fjhx.flow.entity.flow.po;
 
 
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
 import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
 import lombok.Setter;
@@ -25,6 +26,11 @@ public class FlowExample extends BasePo {
     private String title;
 
     /**
+     * 流程标识
+     */
+    private String flowKey;
+
+    /**
      * 流程定义id
      */
     private Long definitionId;
@@ -32,7 +38,7 @@ public class FlowExample extends BasePo {
     /**
      * 流程所在节点id
      */
-    private Long defintionNodeId;
+    private Long definitionNodeId;
 
     /**
      * 业务id
@@ -40,7 +46,7 @@ public class FlowExample extends BasePo {
     private Long businessId;
 
     /**
-     * 状态 1进行中 2已通过 3已驳回
+     * 状态 0未发起 1进行中 2已通过 3已驳回
      */
     private Integer status;
 
@@ -49,4 +55,10 @@ public class FlowExample extends BasePo {
      */
     private String startData;
 
+    /**
+     * 实例版本
+     */
+    @Version
+    private Integer version;
+
 }

+ 7 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowExampleDetail.java

@@ -1,5 +1,7 @@
 package com.fjhx.flow.entity.flow.po;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.ruoyi.common.core.domain.BasePo;
 import lombok.Getter;
@@ -43,4 +45,9 @@ public class FlowExampleDetail extends BasePo {
      */
     private String handleRemark;
 
+    /**
+     * 提交参数
+     */
+    private String submitData;
+
 }

+ 8 - 7
hx-flow/src/main/java/com/fjhx/flow/enums/FlowStatus.java → hx-flow/src/main/java/com/fjhx/flow/enums/FlowStatusEnum.java

@@ -9,8 +9,9 @@ import java.util.Map;
 
 @Getter
 @AllArgsConstructor
-public enum FlowStatus {
+public enum FlowStatusEnum {
 
+    UNINITIATED(0, "未发起"),
     IN_PROGRESS(1, "进行中"),
     HAVE_PASSED(2, "已通过"),
     REJECTED(3, "已驳回"),
@@ -20,20 +21,20 @@ public enum FlowStatus {
 
     private final String value;
 
-    private static final Map<Integer, FlowStatus> map = new HashMap<>();
+    private static final Map<Integer, FlowStatusEnum> map = new HashMap<>();
 
     static {
-        for (FlowStatus value : FlowStatus.values()) {
+        for (FlowStatusEnum value : FlowStatusEnum.values()) {
             map.put(value.getKey(), value);
         }
     }
 
-    public static FlowStatus getEnum(Integer key) {
-        FlowStatus flowStatus = map.get(key);
-        if (flowStatus == null) {
+    public static FlowStatusEnum getEnum(Integer key) {
+        FlowStatusEnum flowStatusEnum = map.get(key);
+        if (flowStatusEnum == null) {
             throw new ServiceException("未知流程状态");
         }
-        return flowStatus;
+        return flowStatusEnum;
     }
 
 }

+ 7 - 7
hx-flow/src/main/java/com/fjhx/flow/enums/HandleType.java → hx-flow/src/main/java/com/fjhx/flow/enums/HandleTypeEnum.java

@@ -9,7 +9,7 @@ import java.util.Map;
 
 @Getter
 @AllArgsConstructor
-public enum HandleType {
+public enum HandleTypeEnum {
 
     NEXT(1, "跳转下一节点"),
     PREVIOUS(2, "返回上一节点"),
@@ -20,20 +20,20 @@ public enum HandleType {
 
     private final String value;
 
-    private static final Map<Integer, HandleType> map = new HashMap<>();
+    private static final Map<Integer, HandleTypeEnum> map = new HashMap<>();
 
     static {
-        for (HandleType value : HandleType.values()) {
+        for (HandleTypeEnum value : HandleTypeEnum.values()) {
             map.put(value.getKey(), value);
         }
     }
 
-    public static HandleType getEnum(Integer key) {
-        HandleType handleType = map.get(key);
-        if (handleType == null) {
+    public static HandleTypeEnum getEnum(Integer key) {
+        HandleTypeEnum handleTypeEnum = map.get(key);
+        if (handleTypeEnum == null) {
             throw new ServiceException("未知处理方法");
         }
-        return handleType;
+        return handleTypeEnum;
     }
 
 }

+ 3 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowProcessService.java

@@ -1,9 +1,12 @@
 package com.fjhx.flow.service.flow;
 
 import com.fjhx.flow.entity.flow.dto.InitiateDto;
+import com.fjhx.flow.entity.flow.dto.JumpDto;
 
 public interface FlowProcessService {
 
     void initiate(InitiateDto dto);
 
+    void jump(JumpDto dto);
+
 }

+ 230 - 39
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowProcessServiceImpl.java

@@ -2,22 +2,25 @@ package com.fjhx.flow.service.flow.impl;
 
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.spring.SpringUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.fjhx.flow.core.FlowBean;
 import com.fjhx.flow.core.FlowDelegate;
 import com.fjhx.flow.core.FlowThreadLocalUtil;
 import com.fjhx.flow.entity.flow.dto.InitiateDto;
+import com.fjhx.flow.entity.flow.dto.JumpDto;
 import com.fjhx.flow.entity.flow.po.FlowDefinition;
 import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
 import com.fjhx.flow.entity.flow.po.FlowExample;
 import com.fjhx.flow.entity.flow.po.FlowExampleDetail;
-import com.fjhx.flow.enums.FlowStatus;
-import com.fjhx.flow.enums.HandleType;
+import com.fjhx.flow.enums.FlowStatusEnum;
+import com.fjhx.flow.enums.HandleTypeEnum;
 import com.fjhx.flow.enums.NodeTypeEnum;
 import com.fjhx.flow.service.flow.*;
 import com.googlecode.aviator.AviatorEvaluator;
 import com.googlecode.aviator.Expression;
 import com.ruoyi.common.constant.StatusConstant;
+import com.ruoyi.common.core.domain.BaseIdPo;
 import com.ruoyi.common.exception.ServiceException;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,6 +33,7 @@ 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
@@ -60,15 +64,10 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         // 找到代码定义的流程bean
         Class<? extends FlowDelegate> flowDelegateCls = FlowBean.getBean(dto.getFlowKey());
 
-        // 实例化bean
-        FlowDelegate flowDelegate;
+        // 获取流程委托对象
+        FlowDelegate flowDelegate = getFlowDelegate(flowDelegateCls);
 
-        flowDelegate = SpringUtil.getBean(flowDelegateCls);
-        if (flowDelegate == null) {
-            throw new ServiceException("没有把流程bean注册到spring中");
-        }
-
-        // 查找流程定义
+        // 查找可用流程
         FlowDefinition flowDefinition = flowDefinitionService.getOne(q -> q
                 .eq(FlowDefinition::getFlowKey, dto.getFlowKey())
                 .eq(FlowDefinition::getCurrentVersion, StatusConstant.YES));
@@ -78,8 +77,8 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         }
 
         // 流程节点列表
-        List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService
-                .list(q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowDefinition.getId()));
+        List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(
+                q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowDefinition.getId()));
 
         // 父级节点map
         Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
@@ -127,43 +126,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             startExampleDetail.setFlowExampleId(flowId);
             startExampleDetail.setFlowDefinitionNodeId(startNode.getId());
             startExampleDetail.setFlowDefinitionNodeType(startNode.getNodeType());
-            startExampleDetail.setHandleType(HandleType.NEXT.getKey());
+            startExampleDetail.setHandleType(HandleTypeEnum.NEXT.getKey());
             flowExampleDetailList.add(startExampleDetail);
 
             // 如果下个节点是结束节点
             if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
-                // 走非默认方法
-                String handlingMethod = nextUserNode.getHandlingMethod();
-                if (StrUtil.isNotBlank(handlingMethod)) {
-                    try {
-                        Method method = flowDelegateCls.getMethod(handlingMethod);
-                        method.invoke(flowDelegate);
-                    } catch (Exception e) {
-                        throw new ServiceException("未找到指定处理方法:" + handlingMethod);
-                    }
-                } else {
-                    // 执行流程结束方法
-                    flowDelegate.end();
-                }
-
+                // 添加明细
+                flowExampleDetailList.add(executeEndFun(flowId, nextUserNode, flowDelegateCls, flowDelegate));
                 // 流程已通过
-                flowExample.setStatus(FlowStatus.HAVE_PASSED.getKey());
-
-                // 结束流程
-                FlowExampleDetail endExampleDetail = new FlowExampleDetail();
-                endExampleDetail.setFlowExampleId(flowId);
-                endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
-                endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
-                endExampleDetail.setHandleType(HandleType.OVER.getKey());
-                flowExampleDetailList.add(endExampleDetail);
+                flowExample.setStatus(FlowStatusEnum.HAVE_PASSED.getKey());
             } else {
                 // 流程进行中
-                flowExample.setStatus(FlowStatus.IN_PROGRESS.getKey());
+                flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
             }
 
             flowExample.setTitle(StrUtil.format(flowDefinition.getTitleTemplate(), templateMap, true));
+            flowExample.setFlowKey(dto.getFlowKey());
             flowExample.setDefinitionId(flowDefinition.getId());
-            flowExample.setDefintionNodeId(nextUserNode.getId());
+            flowExample.setDefinitionNodeId(nextUserNode.getId());
             flowExample.setBusinessId(businessId);
             flowExample.setStartData(dto.getData().toJSONString());
             flowExampleService.save(flowExample);
@@ -180,6 +160,202 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
     }
 
+    @Override
+    public void jump(JumpDto dto) {
+        Long flowId = dto.getFlowId();
+        FlowExample flowExample = flowExampleService.getById(flowId);
+        if (flowExample == null) {
+            throw new ServiceException("没有找到流程");
+        }
+
+        Integer status = flowExample.getStatus();
+        if (status > 1) {
+            throw new ServiceException("流程已结束");
+        }
+
+        // 找到代码定义的流程bean
+        Class<? extends FlowDelegate> flowDelegateCls = FlowBean.getBean(flowExample.getFlowKey());
+
+        // 获取流程委托对象
+        FlowDelegate flowDelegate = getFlowDelegate(flowDelegateCls);
+
+        // 流程节点列表
+        List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(
+                q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowExample.getDefinitionId()));
+
+        // 获取当前审批节点
+        Long definitionNodeId = flowExample.getDefinitionNodeId();
+        FlowDefinitionNode currentNode = flowDefinitionNodeList.stream()
+                .filter(item -> item.getId().equals(definitionNodeId)).findFirst().orElse(null);
+
+        if (currentNode == null) {
+            throw new ServiceException("没有找到当前审批节点");
+        }
+
+        // 查找跳转节点
+        HandleTypeEnum handleTypeEnum = HandleTypeEnum.getEnum(dto.getHandleType());
+
+        // 发起流程参数
+        JSONObject startDataJson = JSONObject.parseObject(flowExample.getStartData());
+        Map<String, Object> templateMap = flowDelegate.initTemplateMap(dto.getData(), startDataJson);
+        FlowThreadLocalUtil.setTemplateData(templateMap);
+        FlowThreadLocalUtil.setStartData(dto.getData());
+        FlowThreadLocalUtil.setCurrentData(dto.getData());
+        FlowThreadLocalUtil.setFlowId(flowId);
+        FlowThreadLocalUtil.setBusinessId(flowExample.getBusinessId());
+        FlowThreadLocalUtil.setHandleTypeEnum(handleTypeEnum);
+
+        // 流程实例明细列表
+        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(dto.getData().toJSONString());
+        flowExampleDetailList.add(nodeExampleDetail);
+
+        FlowDefinitionNode jumpUserNode = null;
+
+        switch (handleTypeEnum) {
+            case NEXT:
+                // 父级节点map
+                Map<Long, List<FlowDefinitionNode>> parentNodeMap = flowDefinitionNodeList.stream()
+                        .collect(Collectors.groupingBy(FlowDefinitionNode::getParentId));
+                // 寻找下一节点
+                jumpUserNode = getNextUserNode(currentNode, parentNodeMap);
+                // 赋值流程所在id
+                flowExample.setDefinitionNodeId(jumpUserNode.getId());
+                // 如果下个节点是结束节点
+                if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
+                    // 流程已通过
+                    flowExample.setStatus(FlowStatusEnum.HAVE_PASSED.getKey());
+                    // 结束流程
+                    FlowExampleDetail endExampleDetail = new FlowExampleDetail();
+                    endExampleDetail.setFlowExampleId(flowId);
+                    endExampleDetail.setFlowDefinitionNodeId(jumpUserNode.getId());
+                    endExampleDetail.setFlowDefinitionNodeType(jumpUserNode.getNodeType());
+                    endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
+                    flowExampleDetailList.add(endExampleDetail);
+                } else {
+                    // 流程进行中
+                    flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
+                }
+                break;
+            case PREVIOUS:
+                // 节点id对象map
+                Map<Long, FlowDefinitionNode> nodeMap = flowDefinitionNodeList.stream()
+                        .collect(Collectors.toMap(BaseIdPo::getId, Function.identity()));
+                // 查找上一个节点
+                jumpUserNode = getLastOneUserNode(currentNode, nodeMap);
+                // 赋值流程所在id
+                flowExample.setDefinitionNodeId(jumpUserNode.getId());
+                // 如果流程回退到开始节点
+                if (NodeTypeEnum.START.equals(NodeTypeEnum.getEnum(jumpUserNode.getNodeType()))) {
+                    // 流程进行中
+                    flowExample.setStatus(FlowStatusEnum.UNINITIATED.getKey());
+                } else {
+                    // 流程进行中
+                    flowExample.setStatus(FlowStatusEnum.IN_PROGRESS.getKey());
+                }
+                break;
+            case OVER:
+                flowExample.setStatus(FlowStatusEnum.REJECTED.getKey());
+                break;
+        }
+
+        // 开启一个事务
+        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
+
+        try {
+            flowExampleService.updateById(flowExample);
+            flowExampleDetailService.saveBatch(flowExampleDetailList);
+
+            if (jumpUserNode != null) {
+                String handlingMethod = jumpUserNode.getHandlingMethod();
+                if (StrUtil.isNotBlank(handlingMethod)) {
+                    invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
+                }
+            } else {
+                flowDelegate.rejected();
+            }
+
+            // 提交事务
+            platformTransactionManager.commit(transaction);
+        } catch (Exception e) {
+            // 提交事务
+            platformTransactionManager.rollback(transaction);
+            log.error("业务错误", e);
+            throw new ServiceException("业务代码错误");
+        }
+
+    }
+
+    /**
+     * 执行结束方法
+     *
+     * @param flowId          流程id
+     * @param nextUserNode    下个用户节点
+     * @param flowDelegateCls 流程代理class
+     * @param flowDelegate    流程代理对象
+     * @return 节点明细
+     */
+    private FlowExampleDetail executeEndFun(Long flowId, FlowDefinitionNode nextUserNode,
+                                            Class<? extends FlowDelegate> flowDelegateCls, FlowDelegate flowDelegate) {
+
+        // 走非默认方法
+        String handlingMethod = nextUserNode.getHandlingMethod();
+        if (StrUtil.isNotBlank(handlingMethod)) {
+            // 执行节点方法
+            invokeMethod(flowDelegateCls, flowDelegate, handlingMethod);
+        } else {
+            // 执行流程结束方法
+            flowDelegate.end();
+        }
+
+        // 结束流程
+        FlowExampleDetail endExampleDetail = new FlowExampleDetail();
+        endExampleDetail.setFlowExampleId(flowId);
+        endExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
+        endExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
+        endExampleDetail.setHandleType(HandleTypeEnum.OVER.getKey());
+        return endExampleDetail;
+    }
+
+    /**
+     * 执行节点方法
+     *
+     * @param flowDelegateCls 流程代理class
+     * @param flowDelegate    流程代理对象
+     * @param handlingMethod  流程执行方法名
+     */
+    private void invokeMethod(Class<? extends FlowDelegate> flowDelegateCls, FlowDelegate flowDelegate, String handlingMethod) {
+        try {
+            Method method = flowDelegateCls.getMethod(handlingMethod.trim());
+            method.invoke(flowDelegate);
+        } catch (Exception e) {
+            log.error("自定义处理方法异常:{}", handlingMethod, e);
+            throw new ServiceException("自定义处理方法异常:" + handlingMethod);
+        }
+    }
+
+    /**
+     * 获取流程委托对象
+     *
+     * @param flowDelegateCls 流程代理class
+     * @return 流程委托对象
+     */
+    private FlowDelegate getFlowDelegate(Class<? extends FlowDelegate> flowDelegateCls) {
+        FlowDelegate flowDelegate = SpringUtil.getBean(flowDelegateCls);
+        if (flowDelegate == null) {
+            throw new ServiceException("没有把流程bean加入到spring中");
+        }
+        return flowDelegate;
+    }
+
     /**
      * 查找下一个用户执行节点
      *
@@ -227,9 +403,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
     }
 
     /**
+     * 查找上一个节点
+     *
+     * @param currentNode 当前节点
+     * @param nodeMap     id节点map
+     * @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);
+        }
+        return lastOneUserNode;
+    }
+
+    /**
      * 校验el表达式
      */
-    public static boolean expressionResult(Map<String, Object> map, String expression) {
+    public boolean expressionResult(Map<String, Object> map, String expression) {
         Expression exp = AviatorEvaluator.compile(expression);
         Object execute = exp.execute(map);
         return Boolean.parseBoolean(String.valueOf(execute));

+ 15 - 9
ruoyi-admin/src/main/resources/application-dev.yml

@@ -2,19 +2,25 @@
 spring:
     datasource:
         dynamic:
-            primary: master
-            strict: false
+            strict: true
+            driver-class-name: com.mysql.cj.jdbc.Driver
             datasource:
-                master:
-                    driver-class-name: com.mysql.cj.jdbc.Driver
-                    url: jdbc:mysql://36.134.91.96:17330/winfaster_master?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                item:
+                    url: jdbc:mysql://36.134.91.96:17330/bytesailing_item?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: fjhx2012mysql
                     password: 3PN-Mzn#vnP&q6d
-                slave:
-                    url: jdbc:mysql://36.134.91.96:17330/winfaster_slave?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                supply:
+                    url: jdbc:mysql://36.134.91.96:17330/bytesailing_supply?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: fjhx2012mysql
+                    password: 3PN-Mzn#vnP&q6d
+                base:
+                    url: jdbc:mysql://36.134.91.96:17330/bytesailing_base?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
+                    username: fjhx2012mysql
+                    password: 3PN-Mzn#vnP&q6d
+                iot:
+                    url: jdbc:mysql://36.134.91.96:17330/bytesailing_iot?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
                     username: fjhx2012mysql
                     password: 3PN-Mzn#vnP&q6d
-
 
     # redis 配置
     redis:
@@ -37,4 +43,4 @@ spring:
                 # 连接池的最大数据库连接数
                 max-active: 8
                 # #连接池最大阻塞等待时间(使用负值表示没有限制)
-                max-wait: -1ms
+                max-wait: -1ms