Browse Source

流程模块

24282 2 years ago
parent
commit
a3aa6f1d31
53 changed files with 1524 additions and 23 deletions
  1. 2 2
      hx-file/pom.xml
  2. 2 2
      hx-file/src/main/java/com/fjhx/file/entity/ObsFile.java
  3. 28 11
      hx-file/src/main/java/com/fjhx/file/util/ObsFileUtil.java
  4. 3 3
      hx-file/src/test/java/Main.java
  5. 7 0
      hx-flow/pom.xml
  6. 0 0
      hx-flow/src/main/java/com/fjhx/flow/a-json/FlowInfoApi.json
  7. 89 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowDefinitionController.java
  8. 22 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowDefinitionNodeController.java
  9. 19 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowExampleController.java
  10. 19 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowExampleDetailController.java
  11. 66 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowInfoController.java
  12. 29 0
      hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowProcessController.java
  13. 33 0
      hx-flow/src/main/java/com/fjhx/flow/core/FlowBean.java
  14. 34 0
      hx-flow/src/main/java/com/fjhx/flow/core/FlowDelegate.java
  15. 19 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowDefinitionDto.java
  16. 17 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowInfoDto.java
  17. 17 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowInfoSelectDto.java
  18. 24 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/InitiateDto.java
  19. 50 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowDefinition.java
  20. 61 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowDefinitionNode.java
  21. 47 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowExample.java
  22. 46 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowExampleDetail.java
  23. 36 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowInfo.java
  24. 17 0
      hx-flow/src/main/java/com/fjhx/flow/entity/flow/vo/FlowInfoVo.java
  25. 39 0
      hx-flow/src/main/java/com/fjhx/flow/enums/FlowStatus.java
  26. 39 0
      hx-flow/src/main/java/com/fjhx/flow/enums/HandleType.java
  27. 44 0
      hx-flow/src/main/java/com/fjhx/flow/enums/NodeTypeEnum.java
  28. 17 0
      hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowDefinitionMapper.java
  29. 17 0
      hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowDefinitionNodeMapper.java
  30. 17 0
      hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowExampleDetailMapper.java
  31. 17 0
      hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowExampleMapper.java
  32. 26 0
      hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowInfoMapper.java
  33. 16 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowDefinitionNodeService.java
  34. 28 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowDefinitionService.java
  35. 17 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowExampleDetailService.java
  36. 17 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowExampleService.java
  37. 41 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowInfoService.java
  38. 9 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowProcessService.java
  39. 21 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowDefinitionNodeServiceImpl.java
  40. 53 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowDefinitionServiceImpl.java
  41. 21 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowExampleDetailServiceImpl.java
  42. 21 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowExampleServiceImpl.java
  43. 46 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowInfoServiceImpl.java
  44. 225 0
      hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowProcessServiceImpl.java
  45. 4 0
      hx-flow/src/main/resources/mapper/flow/FlowDefinitionMapper.xml
  46. 4 0
      hx-flow/src/main/resources/mapper/flow/FlowDefinitionNodeMapper.xml
  47. 4 0
      hx-flow/src/main/resources/mapper/flow/FlowExampleDetailMapper.xml
  48. 4 0
      hx-flow/src/main/resources/mapper/flow/FlowExampleMapper.xml
  49. 14 0
      hx-flow/src/main/resources/mapper/flow/FlowInfoMapper.xml
  50. 19 0
      hx-tenant/src/main/java/com/fjhx/tenant/controller/tenant/RoleTenantController.java
  51. 30 4
      hx-tenant/src/main/java/com/fjhx/tenant/controller/tenant/TenantInfoController.java
  52. 26 0
      ruoyi-common/src/main/java/com/ruoyi/common/constant/StatusConstant.java
  53. 1 1
      ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml

+ 2 - 2
hx-file/pom.xml

@@ -39,8 +39,8 @@
 
         <dependency>
             <groupId>com.fly</groupId>
-            <artifactId>my-generator</artifactId>
-            <version>1.0.0</version>
+            <artifactId>fly-generator</artifactId>
+            <version>1.0.hx</version>
             <scope>test</scope>
         </dependency>
 

+ 2 - 2
hx-file/src/main/java/com/fjhx/file/entity/ObsFile.java

@@ -13,8 +13,8 @@ public class ObsFile {
     private Long id;
 
     /**
-     * 文件链接
+     * 文件名称
      */
-    private String fileUrl;
+    private String fileName;
 
 }

+ 28 - 11
hx-file/src/main/java/com/fjhx/file/util/ObsFileUtil.java

@@ -2,9 +2,11 @@ package com.fjhx.file.util;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
 import com.fjhx.file.entity.FileInfo;
 import com.fjhx.file.entity.ObsFile;
 import com.fjhx.file.service.FileInfoService;
+import com.ruoyi.common.constant.DatasourceConstant;
 import com.ruoyi.common.core.domain.BaseIdPo;
 
 import java.util.List;
@@ -13,7 +15,7 @@ import java.util.stream.Collectors;
 public class ObsFileUtil {
 
     private static final FileInfoService fileInfoService = SpringUtil.getBean(FileInfoService.class);
-    private static int defaultFileType = 0;
+    private static final int defaultFileType = 0;
 
     /**
      * 保存文件
@@ -22,7 +24,10 @@ public class ObsFileUtil {
      * @param businessId   业务id
      * @param businessType 业务文件类型
      */
-    private void saveFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
+    public static void saveFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
+        // 切换到从库
+        DynamicDataSourceContextHolder.push(DatasourceConstant.SLAVE_NAME);
+
         if (obsFileList.size() == 0) {
             return;
         }
@@ -33,6 +38,8 @@ public class ObsFileUtil {
             fileInfo.setBusinessType(businessType);
         }
         fileInfoService.updateBatchById(fileInfoList);
+
+        DynamicDataSourceContextHolder.clear();
     }
 
     /**
@@ -41,8 +48,8 @@ public class ObsFileUtil {
      * @param obsFileList 文件列表
      * @param businessId  业务id
      */
-    private void saveFile(List<ObsFile> obsFileList, Long businessId) {
-        this.saveFile(obsFileList, businessId, defaultFileType);
+    public static void saveFile(List<ObsFile> obsFileList, Long businessId) {
+        saveFile(obsFileList, businessId, defaultFileType);
     }
 
     /**
@@ -52,7 +59,9 @@ public class ObsFileUtil {
      * @param businessId   业务id
      * @param businessType 业务文件类型
      */
-    private void editFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
+    public static void editFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
+        DynamicDataSourceContextHolder.push(DatasourceConstant.SLAVE_NAME);
+
         if (obsFileList.size() == 0) {
             return;
         }
@@ -62,7 +71,8 @@ public class ObsFileUtil {
         fileInfoService.remove(q -> q.notIn(BaseIdPo::getId, obsFileId).eq(FileInfo::getBusinessId, businessId));
 
         // 更新在此列表的文件
-        this.saveFile(obsFileList, businessId, businessType);
+        saveFile(obsFileList, businessId, businessType);
+        DynamicDataSourceContextHolder.clear();
     }
 
     /**
@@ -71,8 +81,8 @@ public class ObsFileUtil {
      * @param obsFileList 文件列表
      * @param businessId  业务id
      */
-    private void editFile(List<ObsFile> obsFileList, Long businessId) {
-        this.editFile(obsFileList, businessId, defaultFileType);
+    public static void editFile(List<ObsFile> obsFileList, Long businessId) {
+        editFile(obsFileList, businessId, defaultFileType);
     }
 
     /**
@@ -81,8 +91,13 @@ public class ObsFileUtil {
      * @param businessId   业务id
      * @param businessType 业务文件类型
      */
-    private void removeFile(Long businessId, Integer businessType) {
-        fileInfoService.remove(q -> q.eq(FileInfo::getBusinessId, businessId).eq(FileInfo::getBusinessType, businessType));
+    public static void removeFile(Long businessId, Integer businessType) {
+        DynamicDataSourceContextHolder.push(DatasourceConstant.SLAVE_NAME);
+        fileInfoService.remove(q -> q
+                .eq(FileInfo::getBusinessId, businessId)
+                .eq(FileInfo::getBusinessType, businessType));
+
+        DynamicDataSourceContextHolder.clear();
     }
 
     /**
@@ -90,8 +105,10 @@ public class ObsFileUtil {
      *
      * @param businessId 业务id
      */
-    private void removeFile(Long businessId) {
+    public static void removeFile(Long businessId) {
+        DynamicDataSourceContextHolder.push(DatasourceConstant.SLAVE_NAME);
         fileInfoService.remove(q -> q.eq(FileInfo::getBusinessId, businessId));
+        DynamicDataSourceContextHolder.clear();
     }
 
 }

+ 3 - 3
hx-file/src/test/java/Main.java

@@ -4,12 +4,12 @@ public class Main {
 
     public static void main(String[] args) {
         GeneratorApplication.builder()
-                .url("jdbc:mysql://36.134.91.96:17330/ry_test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
+                .url("jdbc:mysql://36.134.91.96:17330/winfaster_slave?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true")
                 .username("fjhx2012mysql")
                 .password("3PN-Mzn#vnP&q6d")
                 .port(9989)
-                .module("fly-file")
-                .parent("com.fjhx.file")
+                .module("hx-flow")
+                .parent("com.fjhx.flow")
                 .superServiceClass("com.ruoyi.common.core.service.BaseService")
                 .build();
     }

+ 7 - 0
hx-flow/pom.xml

@@ -25,6 +25,13 @@
             <artifactId>ruoyi-framework</artifactId>
         </dependency>
 
+        <!--el表达式计算-->
+        <dependency>
+            <groupId>com.googlecode.aviator</groupId>
+            <artifactId>aviator</artifactId>
+            <version>5.3.3</version>
+        </dependency>
+
     </dependencies>
 
 </project>

File diff suppressed because it is too large
+ 0 - 0
hx-flow/src/main/java/com/fjhx/flow/a-json/FlowInfoApi.json


+ 89 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowDefinitionController.java

@@ -0,0 +1,89 @@
+package com.fjhx.flow.controller.flow;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.fjhx.flow.entity.flow.dto.FlowDefinitionDto;
+import com.fjhx.flow.entity.flow.po.FlowDefinition;
+import com.fjhx.flow.service.flow.FlowDefinitionService;
+import com.ruoyi.common.constant.DatasourceConstant;
+import com.ruoyi.common.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.expression.MapAccessor;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.common.TemplateParserContext;
+import org.springframework.expression.spel.standard.SpelExpression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * <p>
+ * 流程定义 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@DS(DatasourceConstant.SLAVE_NAME)
+@RestController
+@RequestMapping("/flowDefinition")
+public class FlowDefinitionController {
+
+    @Autowired
+    private FlowDefinitionService flowDefinitionService;
+
+    /**
+     * 添加租户流程
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody FlowDefinition flowDefinition) {
+        flowDefinitionService.add(flowDefinition);
+    }
+
+    /**
+     * 添加租户流程版本
+     */
+    @PostMapping("/addVersion")
+    public void addVersion(@RequestBody FlowDefinitionDto dto) {
+        flowDefinitionService.addVersion(dto);
+    }
+
+    // public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
+    //     Method method = FlowDefinitionDto.class.getMethod("send");
+    //     method.invoke(FlowDefinitionDto.class.newInstance());
+    // }
+
+    // public static void main(String[] args) {
+    //     String skipExpress = "${admin == admin2}";
+    //     HashMap<String, Object> map = new HashMap<>();
+    //     map.put("admin", "ad");
+    //     map.put("admin2", "ad");
+    //     System.out.println(expressionParsing(skipExpress,map));
+    // }
+    //
+    // public static Boolean expressionParsing(String skipExpress, Map<String, Object> map) {
+    //     if (StringUtils.isBlank(skipExpress) && map.isEmpty()) {
+    //         return false;
+    //     }
+    //     ExpressionParser parser = new SpelExpressionParser();
+    //     StandardEvaluationContext context = new StandardEvaluationContext();
+    //
+    //     TemplateParserContext templateParserContext = new TemplateParserContext("${", "}");
+    //     MapAccessor propertyAccessor = new MapAccessor();
+    //     context.setVariables(map);
+    //     context.setPropertyAccessors(Collections.singletonList(propertyAccessor));
+    //
+    //     SpelExpression expression = (SpelExpression) parser.parseExpression(skipExpress, templateParserContext);
+    //     expression.setEvaluationContext(context);
+    //     return Boolean.TRUE.equals(expression.getValue(map, boolean.class));
+    // }
+
+
+}

+ 22 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowDefinitionNodeController.java

@@ -0,0 +1,22 @@
+package com.fjhx.flow.controller.flow;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.ruoyi.common.constant.DatasourceConstant;
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * <p>
+ * 流程节点定义 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+@DS(DatasourceConstant.SLAVE_NAME)
+@RestController
+@RequestMapping("/flowDefinitionNode")
+public class FlowDefinitionNodeController {
+
+
+}

+ 19 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowExampleController.java

@@ -0,0 +1,19 @@
+package com.fjhx.flow.controller.flow;
+
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * <p>
+ * 流程实例 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+@RestController
+@RequestMapping("/flowExample")
+public class FlowExampleController {
+
+
+}

+ 19 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowExampleDetailController.java

@@ -0,0 +1,19 @@
+package com.fjhx.flow.controller.flow;
+
+import org.springframework.web.bind.annotation.*;
+
+
+/**
+ * <p>
+ * 流程实例明细 前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+@RestController
+@RequestMapping("/flowExampleDetail")
+public class FlowExampleDetailController {
+
+
+}

+ 66 - 0
hx-flow/src/main/java/com/fjhx/flow/controller/flow/FlowInfoController.java

@@ -0,0 +1,66 @@
+package com.fjhx.flow.controller.flow;
+
+import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.flow.entity.flow.dto.FlowInfoDto;
+import com.fjhx.flow.entity.flow.dto.FlowInfoSelectDto;
+import com.fjhx.flow.entity.flow.vo.FlowInfoVo;
+import com.fjhx.flow.service.flow.FlowInfoService;
+import com.ruoyi.common.constant.DatasourceConstant;
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * <p>
+ * 流程信息 前端控制器
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@DS(DatasourceConstant.SLAVE_NAME)
+@RestController
+@RequestMapping("/flowInfo")
+public class FlowInfoController {
+
+    @Autowired
+    private FlowInfoService flowInfoService;
+
+    /**
+     * 流程信息分页
+     */
+    @PostMapping("/page")
+    public Page<FlowInfoVo> page(@RequestBody FlowInfoSelectDto dto) {
+        return flowInfoService.getPage(dto);
+    }
+
+    /**
+     * 流程信息新增
+     */
+    @PostMapping("/add")
+    public void add(@RequestBody FlowInfoDto flowInfoDto) {
+        flowInfoService.add(flowInfoDto);
+    }
+
+    /**
+     * 流程信息编辑
+     */
+    @PostMapping("/edit")
+    public void edit(@RequestBody FlowInfoDto flowInfoDto) {
+        flowInfoService.edit(flowInfoDto);
+    }
+
+    /**
+     * 流程信息删除
+     */
+    @PostMapping("/delete")
+    public void delete(@RequestBody BaseSelectDto dto) {
+        flowInfoService.delete(dto.getId());
+    }
+
+}

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

@@ -0,0 +1,29 @@
+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.service.flow.FlowProcessService;
+import com.ruoyi.common.constant.DatasourceConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@DS(DatasourceConstant.SLAVE_NAME)
+@RestController
+@RequestMapping("/flowProcess")
+public class FlowProcessController {
+
+    @Autowired
+    private FlowProcessService flowProcessService;
+
+    /**
+     * 发起流程
+     */
+    @PostMapping("/initiate")
+    public void initiate(@RequestBody InitiateDto dto) {
+        flowProcessService.initiate(dto);
+    }
+
+}

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

@@ -0,0 +1,33 @@
+package com.fjhx.flow.core;
+
+import com.ruoyi.common.exception.ServiceException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FlowBean {
+
+    /**
+     * 流程定义map
+     */
+    protected static final Map<String, Class<? extends FlowDelegate>> map = new HashMap<>();
+
+    /**
+     * 添加流程bean
+     *
+     * @param flowKey 流程标识
+     * @param cls     流程实现类
+     */
+    public static void addBean(String flowKey, Class<? extends FlowDelegate> cls) {
+        map.put(flowKey, cls);
+    }
+
+    public static Class<? extends FlowDelegate> getBean(String flowKey) {
+        Class<? extends FlowDelegate> bean = map.get(flowKey);
+        if (bean == null) {
+            throw new ServiceException("未添加流程bean");
+        }
+        return bean;
+    }
+
+}

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

@@ -0,0 +1,34 @@
+package com.fjhx.flow.core;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class FlowDelegate {
+
+    private final Map<String, String> templateMap = new HashMap<>();
+
+    public void initTemplateMap() {
+
+    }
+
+    public Map<String, String> getTemplateMap() {
+        return templateMap;
+    }
+
+    /**
+     * 开始流程实现类
+     *
+     * @param flowId 流程id
+     * @param data   流程入参
+     * @return 业务id
+     */
+    public abstract Long start(Long flowId, JSONObject data);
+
+    /**
+     * 结束流程实现类
+     */
+    public abstract void end();
+
+}

+ 19 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowDefinitionDto.java

@@ -0,0 +1,19 @@
+package com.fjhx.flow.entity.flow.dto;
+
+import com.fjhx.flow.entity.flow.po.FlowDefinition;
+import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+@Getter
+@Setter
+public class FlowDefinitionDto extends FlowDefinition {
+
+    /**
+     * 流程节点列表
+     */
+    private List<FlowDefinitionNode> flowDefinitionNodeList;
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowInfoDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.entity.flow.dto;
+
+import com.fjhx.flow.entity.flow.po.FlowInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 流程信息新增编辑入参实体
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+public class FlowInfoDto extends FlowInfo {
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowInfoSelectDto.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.entity.flow.dto;
+
+import com.ruoyi.common.core.domain.BaseSelectDto;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 流程信息列表查询入参实体
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+public class FlowInfoSelectDto extends BaseSelectDto {
+
+}

+ 24 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/InitiateDto.java

@@ -0,0 +1,24 @@
+package com.fjhx.flow.entity.flow.dto;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+
+@Getter
+@Setter
+public class InitiateDto {
+
+    /**
+     * 流程标识
+     */
+    @NotBlank(message = "流程标识不能为空")
+    private String flowKey;
+
+    /**
+     * 提交数据
+     */
+    private JSONObject data;
+
+}

+ 50 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowDefinition.java

@@ -0,0 +1,50 @@
+package com.fjhx.flow.entity.flow.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 流程定义
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+@TableName("flow_definition")
+public class FlowDefinition extends BaseIdPo {
+
+    /**
+     * 流程id
+     */
+    private Long flowInfoId;
+
+    /**
+     * 流程标识
+     */
+    private String flowKey;
+
+    /**
+     * 标题模板
+     */
+    private String titleTemplate;
+
+    /**
+     * 版本号
+     */
+    private Integer versionNumber;
+
+    /**
+     * 是否当前版本
+     */
+    private Integer currentVersion;
+
+    private String nodeObject;
+
+    private String lineObject;
+
+}

+ 61 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowDefinitionNode.java

@@ -0,0 +1,61 @@
+package com.fjhx.flow.entity.flow.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 流程节点定义
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+@TableName("flow_definition_node")
+public class FlowDefinitionNode extends BaseIdPo {
+
+    /**
+     * 流程定义id
+     */
+    private Long flowDefinitionId;
+
+    /**
+     * 节点名称
+     */
+    private String nodeName;
+
+    /**
+     * 节点类型 1开始 2审核 3审批 4办理 5分支 99结束
+     */
+    private Integer nodeType;
+
+    /**
+     * 跳转条件
+     */
+    private String jumpCondition;
+
+    /**
+     * 父节点id
+     */
+    private Long parentId;
+
+    /**
+     * 处理方法
+     */
+    private String handlingMethod;
+
+    /**
+     * 发起 / 处理对象类型(1用户 2角色 3部门)
+     */
+    private Byte handleObjectType;
+
+    /**
+     * 指定对象id集合
+     */
+    private String handleObjectIdSet;
+
+}

+ 47 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowExample.java

@@ -0,0 +1,47 @@
+package com.fjhx.flow.entity.flow.po;
+
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 流程实例
+ * </p>
+ *
+ * @author
+ * @since 2023-03-16
+ */
+@Getter
+@Setter
+@TableName("flow_example")
+public class FlowExample extends BasePo {
+
+    /**
+     * 标题
+     */
+    private String title;
+
+    /**
+     * 流程定义id
+     */
+    private Long definitionId;
+
+    /**
+     * 流程所在节点id
+     */
+    private Long defintionNodeId;
+
+    /**
+     * 业务id
+     */
+    private Long businessId;
+
+    /**
+     * 状态 1进行中 2已通过 3已驳回
+     */
+    private Integer status;
+
+}

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

@@ -0,0 +1,46 @@
+package com.fjhx.flow.entity.flow.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BasePo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 流程实例明细
+ * </p>
+ *
+ * @author
+ * @since 2023-03-16
+ */
+@Getter
+@Setter
+@TableName("flow_example_detail")
+public class FlowExampleDetail extends BasePo {
+
+    /**
+     * 流程实例id
+     */
+    private Long flowExampleId;
+
+    /**
+     * 流程节点id
+     */
+    private Long flowDefinitionNodeId;
+
+    /**
+     * 流程节点类型
+     */
+    private Integer flowDefinitionNodeType;
+
+    /**
+     * 处理类型 1跳转下一节点 2返回上一节点 3结束流程
+     */
+    private Integer handleType;
+
+    /**
+     * 处理意见
+     */
+    private String handleRemark;
+
+}

+ 36 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/po/FlowInfo.java

@@ -0,0 +1,36 @@
+package com.fjhx.flow.entity.flow.po;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ruoyi.common.core.domain.BaseIdPo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 流程信息
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+@TableName("flow_info")
+public class FlowInfo extends BaseIdPo {
+
+    /**
+     * 分类名称
+     */
+    private String classifyName;
+
+    /**
+     * 流程名称
+     */
+    private String flowName;
+
+    /**
+     * 流程标识
+     */
+    private String flowKey;
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/entity/flow/vo/FlowInfoVo.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.entity.flow.vo;
+
+import com.fjhx.flow.entity.flow.po.FlowInfo;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 流程信息列表查询返回值实体
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+@Getter
+@Setter
+public class FlowInfoVo extends FlowInfo {
+
+}

+ 39 - 0
hx-flow/src/main/java/com/fjhx/flow/enums/FlowStatus.java

@@ -0,0 +1,39 @@
+package com.fjhx.flow.enums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum FlowStatus {
+
+    IN_PROGRESS(1, "进行中"),
+    HAVE_PASSED(2, "已通过"),
+    REJECTED(3, "已驳回"),
+    ;
+
+    private final Integer key;
+
+    private final String value;
+
+    private static final Map<Integer, FlowStatus> map = new HashMap<>();
+
+    static {
+        for (FlowStatus value : FlowStatus.values()) {
+            map.put(value.getKey(), value);
+        }
+    }
+
+    public static FlowStatus getEnum(Integer key) {
+        FlowStatus flowStatus = map.get(key);
+        if (flowStatus == null) {
+            throw new ServiceException("未知流程状态");
+        }
+        return flowStatus;
+    }
+
+}

+ 39 - 0
hx-flow/src/main/java/com/fjhx/flow/enums/HandleType.java

@@ -0,0 +1,39 @@
+package com.fjhx.flow.enums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum HandleType {
+
+    NEXT(1, "跳转下一节点"),
+    PREVIOUS(2, "返回上一节点"),
+    OVER(3, "结束流程"),
+    ;
+
+    private final Integer key;
+
+    private final String value;
+
+    private static final Map<Integer, HandleType> map = new HashMap<>();
+
+    static {
+        for (HandleType value : HandleType.values()) {
+            map.put(value.getKey(), value);
+        }
+    }
+
+    public static HandleType getEnum(Integer key) {
+        HandleType handleType = map.get(key);
+        if (handleType == null) {
+            throw new ServiceException("未知处理方法");
+        }
+        return handleType;
+    }
+
+}

+ 44 - 0
hx-flow/src/main/java/com/fjhx/flow/enums/NodeTypeEnum.java

@@ -0,0 +1,44 @@
+package com.fjhx.flow.enums;
+
+import com.ruoyi.common.exception.ServiceException;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Getter
+@AllArgsConstructor
+public enum NodeTypeEnum {
+
+    START(1, "开始"),
+    // 通过/不通过,通过后向下一节点流转,不通过则退回上一节点
+    EXAMINED(2, "审核"),
+    // 同意/驳回,同意后向下一节点流转,驳回则以驳回状态结束本流程
+    APPROVAL(3, "审批"),
+    // 办理,办理后向下一节点流转
+    HANDLE(4, "办理"),
+    BRANCH(5, "分支"),
+    END(99, "结束");
+
+    private final Integer key;
+
+    private final String value;
+
+    private static final Map<Integer, NodeTypeEnum> map = new HashMap<>();
+
+    static {
+        for (NodeTypeEnum value : NodeTypeEnum.values()) {
+            map.put(value.getKey(), value);
+        }
+    }
+
+    public static NodeTypeEnum getEnum(Integer key) {
+        NodeTypeEnum nodeTypeEnum = map.get(key);
+        if (nodeTypeEnum == null) {
+            throw new ServiceException("未知节点类型");
+        }
+        return nodeTypeEnum;
+    }
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowDefinitionMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.mapper.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowDefinition;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+
+/**
+ * <p>
+ * 流程定义 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+public interface FlowDefinitionMapper extends BaseMapper<FlowDefinition> {
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowDefinitionNodeMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.mapper.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+
+/**
+ * <p>
+ * 流程节点定义 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+public interface FlowDefinitionNodeMapper extends BaseMapper<FlowDefinitionNode> {
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowExampleDetailMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.mapper.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowExampleDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+
+/**
+ * <p>
+ * 流程实例明细 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+public interface FlowExampleDetailMapper extends BaseMapper<FlowExampleDetail> {
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowExampleMapper.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.mapper.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowExample;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+
+/**
+ * <p>
+ * 流程实例 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+public interface FlowExampleMapper extends BaseMapper<FlowExample> {
+
+}

+ 26 - 0
hx-flow/src/main/java/com/fjhx/flow/mapper/flow/FlowInfoMapper.java

@@ -0,0 +1,26 @@
+package com.fjhx.flow.mapper.flow;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.flow.entity.flow.po.FlowInfo;
+import com.fjhx.flow.entity.flow.vo.FlowInfoVo;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * <p>
+ * 流程信息 Mapper 接口
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+public interface FlowInfoMapper extends BaseMapper<FlowInfo> {
+
+    /**
+     * 流程信息分页
+     */
+    Page<FlowInfoVo> getPage(@Param("page") Page<Object> page, @Param("ew") IWrapper<FlowInfo> wrapper);
+
+}

+ 16 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowDefinitionNodeService.java

@@ -0,0 +1,16 @@
+package com.fjhx.flow.service.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
+import com.ruoyi.common.core.service.BaseService;
+
+/**
+ * <p>
+ * 流程节点定义 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+public interface FlowDefinitionNodeService extends BaseService<FlowDefinitionNode> {
+
+}

+ 28 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowDefinitionService.java

@@ -0,0 +1,28 @@
+package com.fjhx.flow.service.flow;
+
+import com.fjhx.flow.entity.flow.dto.FlowDefinitionDto;
+import com.fjhx.flow.entity.flow.po.FlowDefinition;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 流程定义 服务类
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+public interface FlowDefinitionService extends BaseService<FlowDefinition> {
+
+    /**
+     * 添加租户流程
+     */
+    void add(FlowDefinition flowDefinition);
+
+    /**
+     * 添加租户流程版本
+     */
+    void addVersion(FlowDefinitionDto dto);
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowExampleDetailService.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.service.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowExampleDetail;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 流程实例明细 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+public interface FlowExampleDetailService extends BaseService<FlowExampleDetail> {
+
+}

+ 17 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowExampleService.java

@@ -0,0 +1,17 @@
+package com.fjhx.flow.service.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowExample;
+import com.ruoyi.common.core.service.BaseService;
+
+
+/**
+ * <p>
+ * 流程实例 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+public interface FlowExampleService extends BaseService<FlowExample> {
+
+}

+ 41 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/FlowInfoService.java

@@ -0,0 +1,41 @@
+package com.fjhx.flow.service.flow;
+
+import com.fjhx.flow.entity.flow.po.FlowInfo;
+import com.ruoyi.common.core.service.BaseService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fjhx.flow.entity.flow.vo.FlowInfoVo;
+import com.fjhx.flow.entity.flow.dto.FlowInfoSelectDto;
+import com.fjhx.flow.entity.flow.dto.FlowInfoDto;
+
+
+/**
+ * <p>
+ * 流程信息 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+public interface FlowInfoService extends BaseService<FlowInfo> {
+
+    /**
+     * 流程信息分页
+     */
+    Page<FlowInfoVo> getPage(FlowInfoSelectDto dto);
+
+    /**
+     * 流程信息新增
+     */
+    void add(FlowInfoDto flowInfoDto);
+
+    /**
+     * 流程信息编辑
+     */
+    void edit(FlowInfoDto flowInfoDto);
+
+    /**
+     * 流程信息删除
+     */
+    void delete(Long id);
+
+}

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

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

+ 21 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowDefinitionNodeServiceImpl.java

@@ -0,0 +1,21 @@
+package com.fjhx.flow.service.flow.impl;
+
+import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
+import com.fjhx.flow.mapper.flow.FlowDefinitionNodeMapper;
+import com.fjhx.flow.service.flow.FlowDefinitionNodeService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * <p>
+ * 流程节点定义 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-15
+ */
+@Service
+public class FlowDefinitionNodeServiceImpl extends ServiceImpl<FlowDefinitionNodeMapper, FlowDefinitionNode> implements FlowDefinitionNodeService {
+
+}

+ 53 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowDefinitionServiceImpl.java

@@ -0,0 +1,53 @@
+package com.fjhx.flow.service.flow.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.flow.entity.flow.dto.FlowDefinitionDto;
+import com.fjhx.flow.entity.flow.po.FlowDefinition;
+import com.fjhx.flow.entity.flow.po.FlowDefinitionNode;
+import com.fjhx.flow.mapper.flow.FlowDefinitionMapper;
+import com.fjhx.flow.service.flow.FlowDefinitionService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * <p>
+ * 流程定义 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Service
+public class FlowDefinitionServiceImpl extends ServiceImpl<FlowDefinitionMapper, FlowDefinition> implements FlowDefinitionService {
+
+    @Override
+    public void add(FlowDefinition flowDefinition) {
+        // todo 判断是否已添加
+        this.save(flowDefinition);
+    }
+
+    @Override
+    public void addVersion(FlowDefinitionDto dto) {
+        // todo 判断是否已添加
+        this.save(dto);
+
+        List<FlowDefinitionNode> flowDefinitionNodeList = dto.getFlowDefinitionNodeList();
+
+        for (FlowDefinitionNode flowDefinitionNode : flowDefinitionNodeList) {
+            Long oldId = flowDefinitionNode.getId();
+            long newId = IdWorker.getId();
+            flowDefinitionNode.setId(newId);
+
+            for (FlowDefinitionNode item : flowDefinitionNodeList) {
+                if (item.getParentId().equals(oldId)) {
+                    item.setParentId(newId);
+                }
+            }
+        }
+
+    }
+
+}

+ 21 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowExampleDetailServiceImpl.java

@@ -0,0 +1,21 @@
+package com.fjhx.flow.service.flow.impl;
+
+import com.fjhx.flow.entity.flow.po.FlowExampleDetail;
+import com.fjhx.flow.mapper.flow.FlowExampleDetailMapper;
+import com.fjhx.flow.service.flow.FlowExampleDetailService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * <p>
+ * 流程实例明细 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+@Service
+public class FlowExampleDetailServiceImpl extends ServiceImpl<FlowExampleDetailMapper, FlowExampleDetail> implements FlowExampleDetailService {
+
+}

+ 21 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowExampleServiceImpl.java

@@ -0,0 +1,21 @@
+package com.fjhx.flow.service.flow.impl;
+
+import com.fjhx.flow.entity.flow.po.FlowExample;
+import com.fjhx.flow.mapper.flow.FlowExampleMapper;
+import com.fjhx.flow.service.flow.FlowExampleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * <p>
+ * 流程实例 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-03-16
+ */
+@Service
+public class FlowExampleServiceImpl extends ServiceImpl<FlowExampleMapper, FlowExample> implements FlowExampleService {
+
+}

+ 46 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowInfoServiceImpl.java

@@ -0,0 +1,46 @@
+package com.fjhx.flow.service.flow.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fjhx.flow.entity.flow.dto.FlowInfoDto;
+import com.fjhx.flow.entity.flow.dto.FlowInfoSelectDto;
+import com.fjhx.flow.entity.flow.po.FlowInfo;
+import com.fjhx.flow.entity.flow.vo.FlowInfoVo;
+import com.fjhx.flow.mapper.flow.FlowInfoMapper;
+import com.fjhx.flow.service.flow.FlowInfoService;
+import com.ruoyi.common.utils.wrapper.IWrapper;
+import org.springframework.stereotype.Service;
+
+
+/**
+ * <p>
+ * 流程信息 服务实现类
+ * </p>
+ *
+ * @author
+ * @since 2023-03-15
+ */
+@Service
+public class FlowInfoServiceImpl extends ServiceImpl<FlowInfoMapper, FlowInfo> implements FlowInfoService {
+
+    public Page<FlowInfoVo> getPage(FlowInfoSelectDto dto) {
+        IWrapper<FlowInfo> wrapper = getWrapper();
+        wrapper.orderByDesc("fi", FlowInfo::getId);
+        Page<FlowInfoVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
+        return page;
+    }
+
+    public void add(FlowInfoDto flowInfoDto) {
+        this.save(flowInfoDto);
+    }
+
+    public void edit(FlowInfoDto flowInfoDto) {
+        flowInfoDto.setFlowKey(null);
+        this.updateById(flowInfoDto);
+    }
+
+    public void delete(Long id) {
+        this.removeById(id);
+    }
+
+}

+ 225 - 0
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowProcessServiceImpl.java

@@ -0,0 +1,225 @@
+package com.fjhx.flow.service.flow.impl;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
+import com.baomidou.mybatisplus.core.toolkit.IdWorker;
+import com.fjhx.flow.core.FlowBean;
+import com.fjhx.flow.core.FlowDelegate;
+import com.fjhx.flow.entity.flow.dto.InitiateDto;
+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.NodeTypeEnum;
+import com.fjhx.flow.service.flow.*;
+import com.googlecode.aviator.AviatorEvaluator;
+import com.googlecode.aviator.Expression;
+import com.ruoyi.common.constant.DatasourceConstant;
+import com.ruoyi.common.constant.StatusConstant;
+import com.ruoyi.common.exception.ServiceException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.TransactionStatus;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class FlowProcessServiceImpl implements FlowProcessService {
+
+    @Autowired
+    private FlowDefinitionService flowDefinitionService;
+
+    @Autowired
+    private FlowDefinitionNodeService flowDefinitionNodeService;
+
+    @Autowired
+    private FlowExampleService flowExampleService;
+
+    @Autowired
+    private FlowExampleDetailService flowExampleDetailService;
+
+    @Autowired
+    private PlatformTransactionManager platformTransactionManager;
+
+    @Autowired
+    private TransactionDefinition transactionDefinition;
+
+    @Override
+    public void initiate(InitiateDto dto) {
+
+        // 找到代码定义的流程bean
+        Class<? extends FlowDelegate> flowDelegateCls = FlowBean.getBean(dto.getFlowKey());
+
+        // 实例化bean
+        FlowDelegate flowDelegate;
+        try {
+            flowDelegate = flowDelegateCls.newInstance();
+            flowDelegate.initTemplateMap();
+        } catch (InstantiationException e) {
+            throw new ServiceException("实例化异常");
+        } catch (IllegalAccessException e) {
+            throw new ServiceException("非法访问异常");
+        }
+
+        // 查找流程定义
+        FlowDefinition flowDefinition = flowDefinitionService.getOne(q -> q
+                .eq(FlowDefinition::getFlowKey, dto.getFlowKey())
+                .eq(FlowDefinition::getCurrentVersion, StatusConstant.YES));
+
+        if (flowDefinition == null) {
+            throw new ServiceException("没有找到可用流程");
+        }
+
+        // 流程节点列表
+        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()))
+                .findFirst().orElse(null);
+
+        if (startNode == null) {
+            throw new ServiceException("没有找到开始节点");
+        }
+
+        // 寻找下一节点
+        FlowDefinitionNode nextUserNode = getNextUserNode(startNode, parentNodeMap);
+
+        // 开启一个事务
+        TransactionStatus transaction = platformTransactionManager.getTransaction(transactionDefinition);
+
+        try {
+            // 生成流程id
+            long flowId = IdWorker.getId();
+
+            // 切换到主库执行流程开始节点逻辑
+            DynamicDataSourceContextHolder.push(DatasourceConstant.MASTER_NAME);
+
+            FlowExample flowExample = new FlowExample();
+            List<FlowExampleDetail> flowExampleDetailList = new ArrayList<>();
+
+            // 执行开始流程方法
+            Long businessId = flowDelegate.start(flowId, dto.getData());
+
+            FlowExampleDetail startExampleDetail = new FlowExampleDetail();
+            startExampleDetail.setFlowExampleId(flowId);
+            startExampleDetail.setFlowDefinitionNodeId(startNode.getId());
+            startExampleDetail.setFlowDefinitionNodeType(startNode.getNodeType());
+            startExampleDetail.setHandleType(HandleType.NEXT.getKey());
+            flowExampleDetailList.add(startExampleDetail);
+
+            // 如果下个节点是结束节点
+            if (NodeTypeEnum.END.equals(NodeTypeEnum.getEnum(nextUserNode.getNodeType()))) {
+                // todo 走非默认方法
+
+                // 执行流程结束方法
+                flowDelegate.end();
+
+                // 流程已通过
+                flowExample.setStatus(FlowStatus.HAVE_PASSED.getKey());
+
+                // 结束流程
+                FlowExampleDetail endExampleDetail = new FlowExampleDetail();
+                startExampleDetail.setFlowExampleId(flowId);
+                startExampleDetail.setFlowDefinitionNodeId(nextUserNode.getId());
+                startExampleDetail.setFlowDefinitionNodeType(nextUserNode.getNodeType());
+                startExampleDetail.setHandleType(HandleType.OVER.getKey());
+                flowExampleDetailList.add(endExampleDetail);
+            } else {
+                // 流程进行中
+                flowExample.setStatus(FlowStatus.IN_PROGRESS.getKey());
+            }
+
+            // 切换到从库执行流程信息保存
+            DynamicDataSourceContextHolder.push(DatasourceConstant.SLAVE_NAME);
+
+            flowExample.setTitle(getTitle(flowDelegate.getTemplateMap()));
+            flowExample.setDefinitionId(flowDefinition.getId());
+            flowExample.setDefintionNodeId(nextUserNode.getId());
+            flowExample.setBusinessId(businessId);
+            flowExampleService.save(flowExample);
+            flowExampleDetailService.saveBatch(flowExampleDetailList);
+
+            // 提交事务
+            platformTransactionManager.commit(transaction);
+        } catch (Exception e) {
+            // 回滚事务
+            platformTransactionManager.rollback(transaction);
+        }
+
+    }
+
+    /**
+     * 查找下一个用户执行节点
+     *
+     * @param currentNode   当前节点
+     * @param parentNodeMap 父节点map
+     * @return 用户节点
+     */
+    private FlowDefinitionNode getNextUserNode(FlowDefinitionNode currentNode, Map<Long, List<FlowDefinitionNode>> parentNodeMap) {
+
+        // 查找下个节点
+        List<FlowDefinitionNode> nextNodeList = parentNodeMap.get(currentNode.getId());
+
+        // 如果不为分支,返回此节点
+        if (!NodeTypeEnum.BRANCH.equals(NodeTypeEnum.getEnum(currentNode.getNodeType()))) {
+
+            if (nextNodeList.size() != 1) {
+                throw new ServiceException("流程定义错误");
+            }
+
+            return nextNodeList.get(0);
+        }
+
+        for (FlowDefinitionNode flowDefinitionNode : nextNodeList) {
+            String handlingMethod = flowDefinitionNode.getHandlingMethod();
+            if (StrUtil.isBlank(handlingMethod)) {
+                throw new ServiceException("未配置分支流转表达式");
+            }
+
+        }
+
+        // todo 如果为分支,判断分支走向
+        return nextNodeList.get(0);
+    }
+
+    private String getTitle(Map<String, String> map) {
+        return "";
+    }
+
+    /**
+     * 校验el表达式
+     *
+     * @param map
+     * @param expression
+     * @return
+     */
+    public static boolean expressionResult(Map<String, Object> map, String expression) {
+        Expression exp = AviatorEvaluator.compile(expression);
+        final Object execute = exp.execute(map);
+        return Boolean.parseBoolean(String.valueOf(execute));
+    }
+
+
+    public static void main(String[] args) {
+        HashMap<Object, Object> map1 = new HashMap<>();
+        map1.put("test2", "2");
+
+        HashMap<String, Object> map = new HashMap<>();
+        map.put("admin", new Date());
+        map.put("admin2", DateUtil.offsetDay(new Date(), 1));
+        System.out.println(expressionResult(map, "admin < admin2"));
+    }
+
+}

+ 4 - 0
hx-flow/src/main/resources/mapper/flow/FlowDefinitionMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.flow.mapper.flow.FlowDefinitionMapper">
+</mapper>

+ 4 - 0
hx-flow/src/main/resources/mapper/flow/FlowDefinitionNodeMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.flow.mapper.flow.FlowDefinitionNodeMapper">
+</mapper>

+ 4 - 0
hx-flow/src/main/resources/mapper/flow/FlowExampleDetailMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.flow.mapper.flow.FlowExampleDetailMapper">
+</mapper>

+ 4 - 0
hx-flow/src/main/resources/mapper/flow/FlowExampleMapper.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.flow.mapper.flow.FlowExampleMapper">
+</mapper>

+ 14 - 0
hx-flow/src/main/resources/mapper/flow/FlowInfoMapper.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fjhx.flow.mapper.flow.FlowInfoMapper">
+    <select id="getPage" resultType="com.fjhx.flow.entity.flow.vo.FlowInfoVo">
+        select
+            fi.id,
+            fi.classify_name,
+            fi.flow_name,
+            fi.flow_key
+        from flow_info fi
+            ${ew.customSqlSegment}
+    </select>
+
+</mapper>

+ 19 - 0
hx-tenant/src/main/java/com/fjhx/tenant/controller/tenant/RoleTenantController.java

@@ -6,15 +6,19 @@ import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.annotation.TenantIgnore;
 import com.ruoyi.common.constant.DatasourceConstant;
 import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysMenu;
 import com.ruoyi.common.core.domain.entity.SysRole;
 import com.ruoyi.common.core.domain.entity.SysUser;
 import com.ruoyi.common.core.domain.model.LoginUser;
 import com.ruoyi.common.core.page.TableDataInfo;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.framework.web.service.SysPermissionService;
 import com.ruoyi.framework.web.service.TokenService;
+import com.ruoyi.system.service.ISysMenuService;
 import com.ruoyi.system.service.ISysRoleService;
 import com.ruoyi.system.service.ISysUserService;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,6 +45,9 @@ public class RoleTenantController extends BaseController {
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private ISysMenuService menuService;
+
     /**
      * 角色分页
      */
@@ -115,4 +122,16 @@ public class RoleTenantController extends BaseController {
         roleService.deleteRoleByIds(roleIds);
     }
 
+    /**
+     * 加载对应角色菜单列表树
+     */
+    @GetMapping(value = "/roleMenuTreeSelect/{roleId}")
+    public AjaxResult roleMenuTreeSelect(@PathVariable("roleId") Long roleId) {
+        List<SysMenu> menus = menuService.selectMenuList(SecurityUtils.getUserId());
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
+        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
+        return ajax;
+    }
+
 }

+ 30 - 4
hx-tenant/src/main/java/com/fjhx/tenant/controller/tenant/TenantInfoController.java

@@ -1,6 +1,7 @@
 package com.fjhx.tenant.controller.tenant;
 
 import com.baomidou.dynamic.datasource.annotation.DS;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.fjhx.tenant.entity.tenant.dto.BindingMenuDto;
 import com.fjhx.tenant.entity.tenant.dto.TenantInfoDto;
@@ -10,13 +11,16 @@ import com.fjhx.tenant.entity.tenant.vo.TenantInfoVo;
 import com.fjhx.tenant.service.tenant.TenantInfoService;
 import com.ruoyi.common.annotation.TenantIgnore;
 import com.ruoyi.common.constant.DatasourceConstant;
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.core.domain.BaseSelectDto;
+import com.ruoyi.common.core.domain.entity.SysMenu;
+import com.ruoyi.common.core.domain.entity.SysRole;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.system.service.ISysMenuService;
+import com.ruoyi.system.service.ISysRoleService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
 
@@ -38,6 +42,12 @@ public class TenantInfoController {
     @Autowired
     private TenantInfoService tenantInfoService;
 
+    @Autowired
+    private ISysMenuService menuService;
+
+    @Autowired
+    private ISysRoleService sysRoleService;
+
     /**
      * 租户表分页
      */
@@ -94,4 +104,20 @@ public class TenantInfoController {
         tenantInfoService.bindingMenu(dto);
     }
 
+    /**
+     * 加载对应角色菜单列表树
+     */
+    @GetMapping(value = "/roleMenuTreeSelect/{tenantId}")
+    public AjaxResult roleMenuTreeSelect(@PathVariable("tenantId") String tenantId) {
+
+        SysRole sysRole = sysRoleService.getOne(Wrappers.<SysRole>lambdaQuery()
+                .eq(SysRole::getTenantId, tenantId).eq(SysRole::getRoleKey, "admin"));
+        
+        List<SysMenu> menus = menuService.selectMenuList(SecurityUtils.getUserId());
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("checkedKeys", menuService.selectMenuListByRoleId(sysRole.getRoleId()));
+        ajax.put("menus", menuService.buildMenuTreeSelect(menus));
+        return ajax;
+    }
+
 }

+ 26 - 0
ruoyi-common/src/main/java/com/ruoyi/common/constant/StatusConstant.java

@@ -0,0 +1,26 @@
+package com.ruoyi.common.constant;
+
+/**
+ * 通用状态常量
+ */
+public interface StatusConstant {
+
+    /**
+     * 是否
+     */
+    Integer YES = 1;
+    Integer NO = 0;
+
+    /**
+     * 启用 禁用
+     */
+    Integer ENABLE = 1;
+    Integer DISABLE = 0;
+
+    /**
+     * 删除 未删除
+     */
+    Integer NOT_DELETED = 0;
+    Integer DELETED = 1;
+
+}

+ 1 - 1
ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml

@@ -23,7 +23,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	
 	<sql id="selectRoleVo">
 	    select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly,
-            r.status, r.del_flag, r.create_time, r.remark 
+            r.status, r.del_flag, r.create_time, r.remark, r.tenant_id
         from sys_role r
 	        left join sys_user_role ur on ur.role_id = r.role_id
 	        left join sys_user u on u.user_id = ur.user_id

Some files were not shown because too many files changed in this diff