Browse Source

流程添加 动态用户并行处理

yzc 1 year ago
parent
commit
79044a1081

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

@@ -8,7 +8,9 @@ import com.fjhx.flow.enums.NodeTypeEnum;
 import com.ruoyi.common.utils.SecurityUtils;
 import lombok.extern.slf4j.Slf4j;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 @Slf4j
@@ -129,4 +131,12 @@ public abstract class FlowDelegate {
 
     }
 
+    /**
+     *
+     * @return
+     */
+    public List<Long> getHandlingUserList(Long flowId, JSONObject submitData){
+        return new ArrayList<>();
+    }
+
 }

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

@@ -111,7 +111,7 @@ public class FlowJumpContext {
     /**
      * 跳转节点处理用户id
      */
-    private Long jumpHandleUserId;
+    private String jumpHandleUserId;
 
     /**
      * 流程当前状态

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

@@ -7,6 +7,7 @@ import com.fjhx.flow.enums.NodeTypeEnum;
 import lombok.Setter;
 import org.springframework.core.NamedThreadLocal;
 
+import java.util.List;
 import java.util.Map;
 
 @Setter
@@ -52,13 +53,18 @@ public class FlowThreadLocalUtil {
     /**
      * 下个节点审批用户id
      */
-    private Long nextHandleUserId;
+    private String nextHandleUserId;
 
     /**
      * 当前节点状态
      */
     private NodeTypeEnum currentNodeTypeEnum;
 
+    /**
+     * 并行用户列表
+     */
+    private List<Long> dynamicUserIds;
+
 
     public static Long getFlowId() {
         return FLOW_HOLDER.get().flowId;
@@ -88,7 +94,7 @@ public class FlowThreadLocalUtil {
         return FLOW_HOLDER.get().flowStatusEnum;
     }
 
-    public static Long getNextHandleUserId() {
+    public static String getNextHandleUserId() {
         return FLOW_HOLDER.get().nextHandleUserId;
     }
 
@@ -106,4 +112,7 @@ public class FlowThreadLocalUtil {
         FLOW_HOLDER.remove();
     }
 
+    public static List<Long> getDynamicUserIds() {
+        return FLOW_HOLDER.get().dynamicUserIds;
+    }
 }

+ 1 - 1
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/FlowResult.java

@@ -32,7 +32,7 @@ public class FlowResult {
     /**
      * 用户id
      */
-    private Long userId;
+    private String userId;
 
     /**
      * 已审批节点列表

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

@@ -26,7 +26,7 @@ public class InitiateDto {
     /**
      * 下级节点审批人
      */
-    private Long handleUserId;
+    private String handleUserId;
 
     /**
      * 提交数据

+ 6 - 1
hx-flow/src/main/java/com/fjhx/flow/entity/flow/dto/JumpDto.java

@@ -19,6 +19,11 @@ public class JumpDto {
     private Long flowId;
 
     /**
+     * 流程标识
+     */
+    private String flowKey;
+
+    /**
      * 处理类型:
      * 1跳转下一节点
      * 2返回上一节点
@@ -37,7 +42,7 @@ public class JumpDto {
     /**
      * 下级节点审批人
      */
-    private Long handleUserId;
+    private String handleUserId;
 
     /**
      * 处理备注

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

@@ -43,7 +43,7 @@ public class FlowExample extends BasePo {
     /**
      * 节点处理人id
      */
-    private Long handleUserId;
+    private String handleUserId;
 
     /**
      * 业务id

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

@@ -16,6 +16,7 @@ public enum HandleObjectTypeEnum {
     DEPT_DIRECTOR(3, "部门总监"),
     POST(4, "岗位"),
     ROLE(5, "角色"),
+    PARALLEL(6, "动态用户"),
     ;
 
     private final Integer key;

+ 15 - 7
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowExampleServiceImpl.java

@@ -71,7 +71,8 @@ public class FlowExampleServiceImpl extends ServiceImpl<FlowExampleMapper, FlowE
 
         IWrapper<FlowExample> wrapper = getWrapper()
                 .lt("fe", FlowExample::getStatus, 2)
-                .eq("fe", FlowExample::getHandleUserId, SecurityUtils.getUserId());
+//                .eq("fe", FlowExample::getHandleUserId, SecurityUtils.getUserId())
+                .apply("FIND_IN_SET( {0}, fe.handle_user_id )",SecurityUtils.getUserId());
 
         return doSelectExample(dto, wrapper);
     }
@@ -251,9 +252,12 @@ public class FlowExampleServiceImpl extends ServiceImpl<FlowExampleMapper, FlowE
 
         Integer status = flowExample.getStatus();
 
+        List<Long> handleUserIds = Arrays.stream(flowExample.getHandleUserId().split(",")).map(Long::valueOf).collect(Collectors.toList());
         if (FlowStatusEnum.PASS.getKey().equals(status)
                 || FlowStatusEnum.REJECT.getKey().equals(status)
-                || !Objects.equals(flowExample.getHandleUserId(), SecurityUtils.getUserId())) {
+//                || !Objects.equals(flowExample.getHandleUserId(), SecurityUtils.getUserId())
+                || !handleUserIds.contains(SecurityUtils.getUserId())
+        ) {
             return buttonInfoList;
         }
 
@@ -377,11 +381,15 @@ public class FlowExampleServiceImpl extends ServiceImpl<FlowExampleMapper, FlowE
             return;
         }
 
-        ApprovalRecordVo.Record record = new ApprovalRecordVo.Record();
-        record.setStatus(2);
-        record.setNodeId(flowExample.getDefinitionNodeId());
-        record.setProcessedUserId(flowExample.getHandleUserId());
-        recordList.add(record);
+        String handleUserIds = flowExample.getHandleUserId();
+        String[] split = handleUserIds.split(",");
+        for (String handleUserId : split) {
+            ApprovalRecordVo.Record record = new ApprovalRecordVo.Record();
+            record.setStatus(2);
+            record.setNodeId(flowExample.getDefinitionNodeId());
+            record.setProcessedUserId(Long.valueOf(handleUserId));
+            recordList.add(record);
+        }
     }
 
     /**

+ 90 - 32
hx-flow/src/main/java/com/fjhx/flow/service/flow/impl/FlowProcessServiceImpl.java

@@ -5,7 +5,6 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -41,7 +40,6 @@ import org.springframework.stereotype.Service;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.sql.Wrapper;
 import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
@@ -113,6 +111,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         flowThreadLocal.setFlowId(flowId);
         flowThreadLocal.setHandleTypeEnum(HandleTypeEnum.SKIP_TO_NEXT);
         flowThreadLocal.setCurrentNodeTypeEnum(NodeTypeEnum.START);
+        flowThreadLocal.setDynamicUserIds(flowDelegate.getHandlingUserList(flowId, dto.getData()));
 
         // 寻找下一节点
         FlowDefinitionNode nextUserNode = getNextUserNode(startNode, flowDefinitionNodeList);
@@ -211,6 +210,9 @@ public class FlowProcessServiceImpl implements FlowProcessService {
     @DSTransactional
     @Override
     public FlowResult jump(JumpDto dto) {
+        // 获取流程委托对象
+        FlowDelegate flowDelegate = FlowBean.getBean(dto.getFlowKey());
+
         FlowJumpContext context = new FlowJumpContext(dto);
         FlowThreadLocalUtil flowThreadLocal = FlowThreadLocalUtil.create();
 
@@ -222,6 +224,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         flowThreadLocal.setCurrentData(dto.getData());
         flowThreadLocal.setFlowId(dto.getFlowId());
         flowThreadLocal.setBusinessId(context.getFlowExample().getBusinessId());
+        flowThreadLocal.setDynamicUserIds(flowDelegate.getHandlingUserList(dto.getFlowId(), startData));
 
         FlowResult flowResult;
 
@@ -316,6 +319,19 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
         // 寻找跳转节点
         FlowDefinitionNode jumpNode = getNextUserNode(context.getCurrentNode(), context.getFlowDefinitionNodeList());
+
+        //如果当前节点是动态并行节点
+        if (HandleObjectTypeEnum.PARALLEL.getKey().equals(context.getCurrentNode().getHandleObjectType())) {
+            String jumpHandleUserId = context.getFlowExample().getHandleUserId();
+            List<Long> collect = Arrays.stream(jumpHandleUserId.split(",")).map(item -> Long.valueOf(item)).collect(Collectors.toList());
+            collect.remove(SecurityUtils.getUserId());
+            if (ObjectUtil.isNotEmpty(collect)) {
+                jumpHandleUserId = collect.stream().map(item -> String.valueOf(item)).collect(Collectors.joining(","));
+                jumpNode = context.getCurrentNode();
+            }
+            context.setJumpHandleUserId(jumpHandleUserId);
+        }
+
         context.setJumpNode(jumpNode);
 
         // 如果下一节点为结束节点
@@ -369,7 +385,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             // 流程未发起
             context.setFlowStatus(FlowStatusEnum.READY_START);
             // 流程节点处理人为流程发起人
-            context.setJumpHandleUserId(context.getFlowExample().getCreateUser());
+            context.setJumpHandleUserId(String.valueOf(context.getFlowExample().getCreateUser()));
             return new FlowResult(true);
         }
 
@@ -389,7 +405,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         // 流程未发起
         context.setFlowStatus(FlowStatusEnum.READY_START);
         // 赋值发起人为节点审批人
-        context.setJumpHandleUserId(context.getFlowExample().getCreateUser());
+        context.setJumpHandleUserId(String.valueOf(context.getFlowExample().getCreateUser()));
 
         for (FlowDefinitionNode flowDefinitionNode : context.getFlowDefinitionNodeList()) {
             if (NodeTypeEnum.START.getKey().equals(flowDefinitionNode.getNodeType())) {
@@ -419,8 +435,8 @@ public class FlowProcessServiceImpl implements FlowProcessService {
     }
 
     private FlowResult transfer(FlowJumpContext context, JumpDto dto) {
-        Long handleUserId = dto.getHandleUserId();
-        if (ObjectUtil.isEmpty(handleUserId)){
+        String handleUserId = dto.getHandleUserId();
+        if (ObjectUtil.isEmpty(handleUserId)) {
             List<SysUser> userList = sysUserService.list(Wrappers.<SysUser>query().eq("company_id", SecurityUtils.getCompanyId()));
 
             FlowResult flowResult = new FlowResult();
@@ -433,8 +449,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         FlowResult flowResult = getHandleUser(context.getCurrentNode(), context.getJumpHandleUserId());
         // 流程进行中
         context.setFlowStatus(FlowStatusEnum.IN_PROGRESS);
-        // 赋值流程节点审批人为加签用户
-        context.setJumpHandleUserId(handleUserId);
+
+        //如果当前节点是动态并行节点
+        if (HandleObjectTypeEnum.PARALLEL.getKey().equals(context.getCurrentNode().getHandleObjectType())) {
+            String jumpHandleUserId = context.getJumpHandleUserId();
+            List<Long> collect = Arrays.stream(jumpHandleUserId.split(",")).map(item -> Long.valueOf(item)).collect(Collectors.toList());
+            collect.remove(SecurityUtils.getUserId());
+            //添加加签用户
+            collect.add(Long.valueOf(jumpHandleUserId));
+            if (ObjectUtil.isNotEmpty(collect)) {
+                jumpHandleUserId = collect.stream().map(item -> String.valueOf(item)).collect(Collectors.joining(","));
+            }
+            context.setJumpHandleUserId(jumpHandleUserId);
+        } else {
+            // 赋值流程节点审批人为加签用户
+            context.setJumpHandleUserId(handleUserId);
+        }
+
+
         context.setJumpNode(context.getCurrentNode());
         return flowResult;
     }
@@ -456,7 +488,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             List<FlowDefinitionNode> flowDefinitionNodeList = flowDefinitionNodeService.list(
                     q -> q.eq(FlowDefinitionNode::getFlowDefinitionId, flowExample.getDefinitionId())
                             .in(FlowDefinitionNode::getId, flowNodeIds)
-                            .ne(FlowDefinitionNode::getId,currentNode.getId())
+                            .ne(FlowDefinitionNode::getId, currentNode.getId())
             );
 
             FlowResult flowResult = new FlowResult();
@@ -482,7 +514,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
             // 流程未发起
             context.setFlowStatus(FlowStatusEnum.READY_START);
             // 流程节点处理人为流程发起人
-            context.setJumpHandleUserId(context.getFlowExample().getCreateUser());
+            context.setJumpHandleUserId(String.valueOf(context.getFlowExample().getCreateUser()));
             return new FlowResult(true);
         }
 
@@ -747,19 +779,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
      * @param node 处理节点
      * @return 处理用户
      */
-    private FlowResult getHandleUser(FlowDefinitionNode node, Long handleUserId) {
+    private FlowResult getHandleUser(FlowDefinitionNode node, String handleUserId) {
         FlowResult flowResult = new FlowResult();
 
-        if (handleUserId != null) {
+        if (ObjectUtil.isNotEmpty(handleUserId)) {
             flowResult.setSuccess(true);
             flowResult.setUserId(handleUserId);
             return flowResult;
         }
 
         Integer handleObjectType = node.getHandleObjectType();
-        List<Long> handleObjectIds = Arrays.asList(node.getHandleObjectId().split(",")).stream()
-                .map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
-        Long handleObjectId = handleObjectIds.get(0);
+        List<Long> handleObjectIds = new ArrayList<>();
+        Long handleObjectId = null;
+        String handleObjectIdStr = node.getHandleObjectId();
+        if (ObjectUtil.isNotEmpty(handleObjectIdStr)) {
+            handleObjectIds = Arrays.asList(handleObjectIdStr.split(",")).stream()
+                    .map(Long::valueOf).collect(Collectors.toList());
+            handleObjectId = handleObjectIds.get(0);
+        }
 
         HandleObjectTypeEnum handleObjectTypeEnum = HandleObjectTypeEnum.getEnum(handleObjectType);
 
@@ -767,7 +804,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
 
             case USER:
                 flowResult.setSuccess(true);
-                flowResult.setUserId(handleObjectId);
+                flowResult.setUserId(String.valueOf(handleObjectId));
                 return flowResult;
 
             case DETP_LEADER:
@@ -782,7 +819,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                     if (leaderId == null) {
                         throw new ServiceException("流程节点处理人异常:没有找到节点处理部门负责人");
                     }
-                    flowResult.setUserId(leaderId);
+                    flowResult.setUserId(String.valueOf(leaderId));
                 }
                 // 部门总监
                 else {
@@ -790,7 +827,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                     if (directorId == null) {
                         throw new ServiceException("流程节点处理人异常:没有找到节点处理部门总监");
                     }
-                    flowResult.setUserId(directorId);
+                    flowResult.setUserId(String.valueOf(directorId));
                 }
                 flowResult.setSuccess(true);
                 return flowResult;
@@ -802,7 +839,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                 }
                 if (postUserList.size() == 1) {
                     flowResult.setSuccess(true);
-                    flowResult.setUserId(postUserList.get(0).getUserId());
+                    flowResult.setUserId(String.valueOf(postUserList.get(0).getUserId()));
                     return flowResult;
                 }
                 flowResult.setSuccess(false);
@@ -816,12 +853,21 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                 }
                 if (roleUserList.size() == 1) {
                     flowResult.setSuccess(true);
-                    flowResult.setUserId(roleUserList.get(0).getUserId());
+                    flowResult.setUserId(String.valueOf(roleUserList.get(0).getUserId()));
                     return flowResult;
                 }
                 flowResult.setSuccess(false);
                 flowResult.setUserList(roleUserList);
                 return flowResult;
+            case PARALLEL:
+                flowResult.setSuccess(true);
+                List<Long> dynamicUserIds = FlowThreadLocalUtil.getDynamicUserIds();
+                if (ObjectUtil.isEmpty(dynamicUserIds)) {
+                    throw new ServiceException("动态用户列表为空!");
+                }
+                String dynamicUserIdsStr = dynamicUserIds.stream().map(String::valueOf).collect(Collectors.joining(","));
+                flowResult.setUserId(dynamicUserIdsStr);
+                return flowResult;
 
             default:
                 throw new ServiceException("未知用户处理类型:" + handleObjectType);
@@ -837,20 +883,24 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         businessData.put("flowId", flowId);
         businessData.put("flowKey", flowDefinition.getFlowKey());
 
-        Long pushUserId;
+        List<Long> pushUserIds = new ArrayList<>();
         String title;
         if (NodeTypeEnum.END.equals(nextNodeType)) {
             FlowInfo flowInfo = flowInfoService.getById(flowDefinition.getFlowInfoId());
             String flowName = flowInfo == null ? StringPool.EMPTY : flowInfo.getFlowName();
 
-            pushUserId = SecurityUtils.getUserId();
+            pushUserIds.add(SecurityUtils.getUserId());
             title = StrUtil.format("您于【{}】发起的【{}】已经审批通过。", DateUtil.formatDateTime(new Date()), flowName);
         } else {
-            pushUserId = flowExample.getHandleUserId();
+            for (String s : flowExample.getHandleUserId().split(",")) {
+                pushUserIds.add(Long.valueOf(s));
+            }
             title = "您有一条新的待审批事项,请及时处理。";
         }
 
-        WebSocketPush.byUser(PushTypeEnum.MESSAGE, pushUserId, title, 0, businessData);
+        for (Long pushUserId : pushUserIds) {
+            WebSocketPush.byUser(PushTypeEnum.MESSAGE, pushUserId, title, 0, businessData);
+        }
     }
 
     /**
@@ -868,7 +918,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         FlowStatusEnum flowStatusEnum = context.getFlowStatus();
         FlowDefinitionNode jumpNode = context.getJumpNode();
         FlowDefinitionNode currentNode = context.getCurrentNode();
-        Long jumpHandleUserId = context.getJumpHandleUserId();
+        String jumpHandleUserId = context.getJumpHandleUserId();
 
         Map<String, Object> businessData = new HashMap<>();
         businessData.put("flowId", flowExample.getId());
@@ -878,7 +928,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
         String flowName = flowInfo == null ? StringPool.EMPTY : flowInfo.getFlowName();
 
         String title;
-        Long pushUserId;
+        List<Long> pushUserIds = new ArrayList<>();
 
         switch (handleTypeEnum) {
             // 跳转下一节点
@@ -890,12 +940,14 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                     title = StrUtil.format("您于【{}】发起的【{}】已经审批通过。",
                             DateUtil.formatDateTime(flowExample.getCreateTime()),
                             flowName);
-                    pushUserId = flowExample.getCreateUser();
+                    pushUserIds.add(flowExample.getCreateUser());
                 }
                 // 如果下一节点不为结束节点
                 else {
                     title = "您有一条新的待审批事项,请及时处理。";
-                    pushUserId = jumpHandleUserId;
+                    for (String s : jumpHandleUserId.split(",")) {
+                        pushUserIds.add(Long.valueOf(s));
+                    }
                 }
                 break;
 
@@ -905,7 +957,7 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                         DateUtil.formatDateTime(flowExample.getCreateTime()),
                         flowName,
                         currentNode.getNodeName());
-                pushUserId = flowExample.getCreateUser();
+                pushUserIds.add(flowExample.getCreateUser());
                 break;
 
             // 退回上一节点
@@ -922,7 +974,9 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                         DateUtil.formatDateTime(flowExampleDetail.getCreateTime()),
                         flowName);
 
-                pushUserId = jumpHandleUserId;
+                for (String s : jumpHandleUserId.split(",")) {
+                    pushUserIds.add(Long.valueOf(s));
+                }
                 break;
 
             // 退回到发起人
@@ -931,14 +985,18 @@ public class FlowProcessServiceImpl implements FlowProcessService {
                         DateUtil.formatDateTime(flowExample.getCreateTime()),
                         flowName);
 
-                pushUserId = jumpHandleUserId;
+                for (String s : jumpHandleUserId.split(",")) {
+                    pushUserIds.add(Long.valueOf(s));
+                }
                 break;
 
             default:
                 throw new ServiceException("未知流程跳转类型");
         }
 
-        WebSocketPush.byUser(PushTypeEnum.MESSAGE, pushUserId, title, 0, businessData);
+        for (Long pushUserId : pushUserIds) {
+            WebSocketPush.byUser(PushTypeEnum.MESSAGE, pushUserId, title, 0, businessData);
+        }
     }
 
     // public static void main(String[] args) {