瀏覽代碼

update 升级 warm-flow1.7.0 -> 1.7.2

疯狂的狮子Li 1 年之前
父節點
當前提交
21d00dfcc9

+ 1 - 1
pom.xml

@@ -55,7 +55,7 @@
         <!-- 面向运行时的D-ORM依赖 -->
         <anyline.version>8.7.2-20250101</anyline.version>
         <!-- 工作流配置 -->
-        <warm-flow.version>1.7.0</warm-flow.version>
+        <warm-flow.version>1.7.2</warm-flow.version>
         <!-- mq配置 -->
         <rocketmq.version>2.3.0</rocketmq.version>
 

+ 15 - 0
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/common/ConditionalOnEnable.java

@@ -7,6 +7,21 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * 自定义条件注解,用于基于配置启用或禁用特定功能
+ * <p>
+ * 该注解只会在配置文件中 `warm-flow.enabled=true` 时,标注了此注解的类或方法才会被 Spring 容器加载
+ * <p>
+ * 示例配置:
+ * <pre>
+ * warm-flow:
+ *   enabled: true  # 设置为 true 时,启用工作流功能
+ * </pre>
+ * <p>
+ * 使用此注解时,可以动态控制工作流功能是否启用,而不需要修改代码逻辑
+ *
+ * @author Lion Li
+ */
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ ElementType.TYPE, ElementType.METHOD })
 @ConditionalOnProperty(value = "warm-flow.enabled", havingValue = "true")

+ 51 - 0
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java

@@ -14,7 +14,10 @@ import org.dromara.warm.flow.core.listener.GlobalListener;
 import org.dromara.warm.flow.core.listener.ListenerVariable;
 import org.dromara.warm.flow.orm.entity.FlowTask;
 import org.dromara.workflow.common.ConditionalOnEnable;
+import org.dromara.workflow.common.enums.TaskStatusEnum;
+import org.dromara.workflow.domain.bo.FlowCopyBo;
 import org.dromara.workflow.handler.FlowProcessEventHandler;
+import org.dromara.workflow.service.IFlwCommonService;
 import org.dromara.workflow.service.IFlwInstanceService;
 import org.dromara.workflow.service.IFlwTaskService;
 import org.springframework.stereotype.Component;
@@ -37,6 +40,7 @@ public class WorkflowGlobalListener implements GlobalListener {
     private final IFlwTaskService taskService;
     private final IFlwInstanceService instanceService;
     private final FlowProcessEventHandler flowProcessEventHandler;
+    private final IFlwCommonService flwCommonService;
 
     /**
      * 创建监听器,任务创建时执行
@@ -70,6 +74,32 @@ public class WorkflowGlobalListener implements GlobalListener {
      */
     @Override
     public void assignment(ListenerVariable listenerVariable) {
+        Map<String, Object> variable = listenerVariable.getVariable();
+        List<Task> nextTasks = listenerVariable.getNextTasks();
+        FlowParams flowParams = listenerVariable.getFlowParams();
+        Definition definition = listenerVariable.getDefinition();
+        Instance instance = listenerVariable.getInstance();
+        String applyNodeCode = flwCommonService.applyNodeCode(definition.getId());
+        for (Task flowTask : nextTasks) {
+            // 如果办理或者退回并行存在需要指定办理人,则直接覆盖办理人
+            if (variable.containsKey(flowTask.getNodeCode()) && (TaskStatusEnum.PASS.getStatus().equals(flowParams.getHisStatus())
+                || TaskStatusEnum.BACK.getStatus().equals(flowParams.getHisStatus()))) {
+                String userIds = variable.get(flowTask.getNodeCode()).toString();
+                flowTask.setPermissionList(List.of(userIds.split(StringUtils.SEPARATOR)));
+                variable.remove(flowTask.getNodeCode());
+            } else {
+                // 否则把所有的角色或者部门转成对应的用户
+                List<String> permissionList = flowTask.getPermissionList();
+                if (CollUtil.isNotEmpty(permissionList)) {
+                    List<String> newUserList = flwCommonService.buildUser(permissionList);
+                    flowTask.setPermissionList(newUserList);
+                }
+            }
+            // 如果是申请节点,则把启动人添加到办理人
+            if (flowTask.getNodeCode().equals(applyNodeCode)) {
+                flowTask.setPermissionList(List.of(instance.getCreateBy()));
+            }
+        }
     }
 
     /**
@@ -98,6 +128,27 @@ public class WorkflowGlobalListener implements GlobalListener {
         if (StringUtils.isNotBlank(status)) {
             flowProcessEventHandler.processHandler(definition.getFlowCode(), instance, status, params, false);
         }
+
+        // 只有办理或者退回的时候才执行消息通知和抄送
+        if (TaskStatusEnum.PASS.getStatus().equals(flowParams.getHisStatus())
+            || TaskStatusEnum.BACK.getStatus().equals(flowParams.getHisStatus())) {
+            Task task = listenerVariable.getTask();
+            Map<String, Object> variable = listenerVariable.getVariable();
+            List<FlowCopyBo> flowCopyList = (List<FlowCopyBo>) variable.get("flowCopyList");
+            List<String> messageType = (List<String>) variable.get("messageType");
+            String notice = (String) variable.get("notice");
+
+            // 添加抄送人
+            taskService.setCopy(task, flowCopyList);
+            variable.remove("flowCopyList");
+
+            // 消息通知
+            if (CollUtil.isNotEmpty(messageType)) {
+                flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
+                variable.remove("messageType");
+                variable.remove("notice");
+            }
+        }
     }
 
     /**

+ 2 - 31
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwCommonService.java

@@ -1,12 +1,6 @@
 package org.dromara.workflow.service;
 
-import org.dromara.warm.flow.core.entity.Instance;
-import org.dromara.warm.flow.core.entity.User;
-import org.dromara.warm.flow.core.service.UserService;
-
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * 通用 工作流服务
@@ -15,28 +9,13 @@ import java.util.Set;
  */
 public interface IFlwCommonService {
 
-    /**
-     * 获取工作流用户service
-     */
-    UserService getFlowUserService();
-
-    /**
-     * 构建工作流用户
-     *
-     * @param userList 办理用户
-     * @param taskId   任务ID
-     * @return 用户
-     */
-    Set<User> buildUser(List<User> userList, Long taskId);
-
     /**
      * 构建工作流用户
      *
-     * @param userIdList 办理用户
-     * @param taskId     任务ID
+     * @param permissionList 办理用户
      * @return 用户
      */
-    Set<User> buildFlowUser(List<String> userIdList, Long taskId);
+    List<String> buildUser(List<String> permissionList);
 
     /**
      * 发送消息
@@ -55,12 +34,4 @@ public interface IFlwCommonService {
      */
     String applyNodeCode(Long definitionId);
 
-    /**
-     * 合并变量
-     *
-     * @param instance 流程实例
-     * @param variable 变量
-     */
-    void mergeVariable(Instance instance, Map<String, Object> variable);
-
 }

+ 9 - 0
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java

@@ -4,6 +4,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.api.domain.vo.RemoteUserVo;
 import org.dromara.warm.flow.core.entity.Node;
+import org.dromara.warm.flow.core.entity.Task;
 import org.dromara.warm.flow.orm.entity.FlowHisTask;
 import org.dromara.warm.flow.orm.entity.FlowNode;
 import org.dromara.warm.flow.orm.entity.FlowTask;
@@ -38,6 +39,14 @@ public interface IFlwTaskService {
      */
     boolean completeTask(CompleteTaskBo completeTaskBo);
 
+    /**
+     * 添加抄送人
+     *
+     * @param task         任务信息
+     * @param flowCopyList 抄送人
+     */
+    void setCopy(Task task, List<FlowCopyBo> flowCopyList);
+
     /**
      * 查询当前用户的待办任务
      *

+ 8 - 74
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwCommonServiceImpl.java

@@ -45,7 +45,6 @@ import java.util.stream.Collectors;
 @Service
 public class FlwCommonServiceImpl implements IFlwCommonService {
 
-    private final UserService userService;
     private final NodeService nodeService;
 
     @DubboReference
@@ -53,78 +52,22 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
     @DubboReference
     private RemoteMailService remoteMailService;
 
-    /**
-     * 获取工作流用户service
-     */
-    @Override
-    public UserService getFlowUserService() {
-        return userService;
-    }
-
     /**
      * 构建工作流用户
      *
-     * @param userList 办理用户
-     * @param taskId   任务ID
+     * @param permissionList 办理用户
      * @return 用户
      */
     @Override
-    public Set<User> buildUser(List<User> userList, Long taskId) {
-        if (CollUtil.isEmpty(userList)) {
-            return Set.of();
+    public List<String> buildUser(List<String> permissionList) {
+        if (CollUtil.isEmpty(permissionList)) {
+            return List.of();
         }
-        Set<User> list = new HashSet<>();
-        Set<String> processedBySet = new HashSet<>();
         IFlwTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IFlwTaskAssigneeService.class);
-        Map<String, List<User>> userListMap = StreamUtils.groupByKey(userList, User::getType);
-        for (Map.Entry<String, List<User>> entry : userListMap.entrySet()) {
-            List<User> entryValue = entry.getValue();
-            String processedBys = StreamUtils.join(entryValue, User::getProcessedBy);
-            // 根据 processedBy 前缀判断处理人类型,分别获取用户列表
-            List<RemoteUserVo> users = taskAssigneeService.fetchUsersByStorageIds(processedBys);
-            // 转换为 FlowUser 并添加到结果集合
-            if (CollUtil.isNotEmpty(users)) {
-                users.forEach(dto -> {
-                    String processedBy = String.valueOf(dto.getUserId());
-                    if (!processedBySet.contains(processedBy)) {
-                        FlowUser flowUser = new FlowUser();
-                        flowUser.setType(entry.getKey());
-                        flowUser.setProcessedBy(processedBy);
-                        flowUser.setAssociated(taskId);
-                        list.add(flowUser);
-                        processedBySet.add(processedBy);
-                    }
-                });
-            }
-        }
-        return list;
-    }
-
-    /**
-     * 构建工作流用户
-     *
-     * @param userIdList 办理用户
-     * @param taskId     任务ID
-     * @return 用户
-     */
-    @Override
-    public Set<User> buildFlowUser(List<String> userIdList, Long taskId) {
-        if (CollUtil.isEmpty(userIdList)) {
-            return Set.of();
-        }
-        Set<User> list = new HashSet<>();
-        Set<String> processedBySet = new HashSet<>();
-        for (String userId : userIdList) {
-            if (!processedBySet.contains(userId)) {
-                FlowUser flowUser = new FlowUser();
-                flowUser.setType(TaskAssigneeType.APPROVER.getCode());
-                flowUser.setProcessedBy(String.valueOf(userId));
-                flowUser.setAssociated(taskId);
-                list.add(flowUser);
-                processedBySet.add(String.valueOf(userId));
-            }
-        }
-        return list;
+        String processedBys = CollUtil.join(permissionList,  StringUtils.SEPARATOR);
+        // 根据 processedBy 前缀判断处理人类型,分别获取用户列表
+        List<RemoteUserVo> users = taskAssigneeService.fetchUsersByStorageIds(processedBys);
+        return StreamUtils.toList(users, userDTO -> String.valueOf(userDTO.getUserId()));
     }
 
     /**
@@ -184,13 +127,4 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
         return nextNode.getNodeCode();
     }
 
-    @Override
-    public void mergeVariable(Instance instance, Map<String, Object> variable) {
-        if (MapUtil.isNotEmpty(variable)) {
-            String variableStr = instance.getVariable();
-            Map<String, Object> deserialize = FlowEngine.jsonConvert.strToMap(variableStr);
-            deserialize.putAll(variable);
-            instance.setVariable(FlowEngine.jsonConvert.objToStr(deserialize));
-        }
-    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java

@@ -360,7 +360,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
     public void setVariable(Long instanceId, Map<String, Object> variable) {
         Instance instance = insService.getById(instanceId);
         if (instance != null) {
-            flwCommonService.mergeVariable(instance, variable);
+            taskService.mergeVariable(instance, variable);
             insService.updateById(instance);
         }
     }

+ 29 - 89
ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java

@@ -25,6 +25,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.system.api.RemoteUserService;
 import org.dromara.system.api.domain.vo.RemoteUserVo;
+import org.dromara.warm.flow.core.FlowEngine;
 import org.dromara.warm.flow.core.dto.FlowParams;
 import org.dromara.warm.flow.core.entity.*;
 import org.dromara.warm.flow.core.enums.NodeType;
@@ -115,7 +116,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
         if (ObjectUtil.isNotNull(flowInstance)) {
             BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
             List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
-            flwCommonService.mergeVariable(flowInstance, variables);
+            taskService.mergeVariable(flowInstance, variables);
             insService.updateById(flowInstance);
             RemoteStartProcessReturn dto = new RemoteStartProcessReturn();
             dto.setProcessInstanceId(taskList.get(0).getInstanceId());
@@ -158,6 +159,13 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
             String notice = completeTaskBo.getNotice();
             // 获取抄送人
             List<FlowCopyBo> flowCopyList = completeTaskBo.getFlowCopyList();
+            // 设置抄送人
+            completeTaskBo.getVariables().put("flowCopyList", flowCopyList);
+            // 消息类型
+            completeTaskBo.getVariables().put("messageType", messageType);
+            // 消息通知
+            completeTaskBo.getVariables().put("notice", notice);
+
             FlowTask flowTask = flowTaskMapper.selectById(taskId);
             if (ObjectUtil.isNull(flowTask)) {
                 throw new ServiceException("流程任务不存在或任务已审批!");
@@ -183,12 +191,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
                 .hisStatus(TaskStatusEnum.PASS.getStatus())
                 .hisTaskExt(completeTaskBo.getFileId());
             // 执行任务跳转,并根据返回的处理人设置下一步处理人
-            Instance instance = taskService.skip(taskId, flowParams);
-            this.setHandler(instance, flowTask, flowCopyList);
-            // 消息通知
-            flwCommonService.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
-            //设置下一环节处理人
-            setNextHandler(ins.getId(), completeTaskBo.getAssigneeMap());
+            taskService.skip(taskId, flowParams);
             return true;
         } catch (Exception e) {
             log.error(e.getMessage(), e);
@@ -196,33 +199,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
         }
     }
 
-    /**
-     * 设置下一环节处理人
-     *
-     * @param instanceId 实例ID
-     * @param assigneeMap 办理人
-     */
-    private void setNextHandler(Long instanceId, Map<String, Object> assigneeMap) {
-        if (CollUtil.isEmpty(assigneeMap)) {
-            return;
-        }
-        Instance inst = insService.getById(instanceId);
-        List<FlowTask> flowTaskList = selectByInstId(instanceId);
-        Map<String, Object> variableMap = inst.getVariableMap();
-        for (FlowTask task : flowTaskList) {
-            if (variableMap != null && variableMap.containsKey(task.getNodeCode())) {
-                String userIds = variableMap.get(task.getNodeCode()).toString();
-                // 批量删除现有任务的办理人记录
-                flwCommonService.getFlowUserService().deleteByTaskIds(List.of(task.getId()));
-                // 批量新增任务办理人记录
-                Set<User> users = flwCommonService.buildFlowUser(List.of(userIds.split(StringUtils.SEPARATOR)), task.getId());
-                flwCommonService.getFlowUserService().saveBatch(new ArrayList<>(users));
-                variableMap.remove(task.getNodeCode());
-            }
-        }
-        flwCommonService.mergeVariable(inst, variableMap);
-    }
-
     /**
      * 设置弹窗处理人
      *
@@ -254,54 +230,14 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
         return map;
     }
 
-    /**
-     * 设置办理人
-     *
-     * @param instance     实例
-     * @param task         (当前任务)未办理的任务
-     * @param flowCopyList 抄送人
-     */
-    private void setHandler(Instance instance, FlowTask task, List<FlowCopyBo> flowCopyList) {
-        if (ObjectUtil.isNull(instance)) {
-            return;
-        }
-        // 添加抄送人
-        this.setCopy(task, flowCopyList);
-        // 根据流程实例ID查询所有关联的任务
-        List<FlowTask> flowTasks = this.selectByInstId(instance.getId());
-        if (CollUtil.isEmpty(flowTasks)) {
-            return;
-        }
-        List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId);
-        // 获取与当前任务关联的用户列表
-        List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
-        if (CollUtil.isEmpty(associatedUsers)) {
-            return;
-        }
-        List<User> userList = new ArrayList<>();
-        // 遍历任务列表,处理每个任务的办理人
-        for (FlowTask flowTask : flowTasks) {
-            List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId()));
-            if (CollUtil.isNotEmpty(users)) {
-                userList.addAll(flwCommonService.buildUser(users, flowTask.getId()));
-            }
-        }
-        // 批量删除现有任务的办理人记录
-        flwCommonService.getFlowUserService().deleteByTaskIds(taskIdList);
-        // 确保要保存的 userList 不为空
-        if (CollUtil.isEmpty(userList)) {
-            return;
-        }
-        flwCommonService.getFlowUserService().saveBatch(userList);
-    }
-
     /**
      * 添加抄送人
      *
      * @param task         任务信息
      * @param flowCopyList 抄送人
      */
-    public void setCopy(FlowTask task, List<FlowCopyBo> flowCopyList) {
+    @Override
+    public void setCopy(Task task, List<FlowCopyBo> flowCopyList) {
         if (CollUtil.isEmpty(flowCopyList)) {
             return;
         }
@@ -332,7 +268,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
                 return flowUser;
             }).collect(Collectors.toList());
         // 批量保存抄送人员
-        flwCommonService.getFlowUserService().saveBatch(userList);
+        FlowEngine.userService().saveBatch(userList);
     }
 
     /**
@@ -459,21 +395,25 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
             Instance inst = insService.getById(task.getInstanceId());
             BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
             Long definitionId = task.getDefinitionId();
-            Definition definition = defService.getById(definitionId);
             String applyNodeCode = flwCommonService.applyNodeCode(definitionId);
+
+            Map<String, Object> variable = new HashMap<>();
+            // 设置抄送人
+            variable.put("flowCopyList", bo.getMessageType());
+            // 消息类型
+            variable.put("messageType", messageType);
+            // 消息通知
+            variable.put("notice", notice);
+
             FlowParams flowParams = FlowParams.build()
                 .nodeCode(bo.getNodeCode())
+                .variable(variable)
                 .message(message)
                 .skipType(SkipType.REJECT.getKey())
                 .flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus())
                 .hisStatus(TaskStatusEnum.BACK.getStatus())
                 .hisTaskExt(bo.getFileId());
             taskService.skip(task.getId(), flowParams);
-
-            Instance instance = insService.getById(inst.getId());
-            this.setHandler(instance, task, null);
-            // 消息通知
-            flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
             return true;
         } catch (Exception e) {
             log.error(e.getMessage(), e);
@@ -748,7 +688,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
             List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
             // 批量删除现有任务的办理人记录
             if (CollUtil.isNotEmpty(flowTasks)) {
-                flwCommonService.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
+                FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
                 List<User> userList = flowTasks.stream()
                     .map(flowTask -> {
                         FlowUser flowUser = new FlowUser();
@@ -759,7 +699,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
                     })
                     .collect(Collectors.toList());
                 if (CollUtil.isNotEmpty(userList)) {
-                    flwCommonService.getFlowUserService().saveBatch(userList);
+                    FlowEngine.userService().saveBatch(userList);
                 }
             }
         } catch (Exception e) {
@@ -778,13 +718,13 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
     public Map<Long, List<RemoteUserVo>> currentTaskAllUser(List<Long> taskIdList) {
         Map<Long, List<RemoteUserVo>> map = new HashMap<>();
         // 获取与当前任务关联的用户列表
-        List<User> associatedUsers = flwCommonService.getFlowUserService().getByAssociateds(taskIdList);
+        List<User> associatedUsers = FlowEngine.userService().getByAssociateds(taskIdList);
         Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
         for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
             List<User> value = entry.getValue();
             if (CollUtil.isNotEmpty(value)) {
-                List<RemoteUserVo> userDTOS = remoteUserService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
-                map.put(entry.getKey(), userDTOS);
+                List<RemoteUserVo> userDtoList = remoteUserService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
+                map.put(entry.getKey(), userDtoList);
             }
         }
         return map;
@@ -798,7 +738,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
     @Override
     public List<RemoteUserVo> currentTaskAllUser(Long taskId) {
         // 获取与当前任务关联的用户列表
-        List<User> userList = flwCommonService.getFlowUserService().getByAssociateds(Collections.singletonList(taskId));
+        List<User> userList = FlowEngine.userService().getByAssociateds(Collections.singletonList(taskId));
         if (CollUtil.isEmpty(userList)) {
             return Collections.emptyList();
         }