From ae584d54a63306840172add6da2643cf93d6a234 Mon Sep 17 00:00:00 2001
From: 疯狂的狮子Li <15040126243@163.com>
Date: 星期一, 13 一月 2025 14:08:15 +0800
Subject: [PATCH] !635 合并 warmflow 功能分支 * update 优化 工作流设计器支持token传输 只需要放行token头获取即可 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化 无需多余set变量 * update 优化 避免重复处理 * update 优化 实体类隔离 * add 增加流程启动,办理接口 * update 调整流程驳回 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update warmflow 1.3.7 * update 增加 warmflow oracle pg sqlserver sql脚本文件 * update 增加 warmflow oracle pg sqlserver sql脚本文件 * add 新增workflow不同的sql语句 * add 新增添加租户同步默认流程定义 * update 优化 流程列表查询 删除无用mapper * update 导入流程 支持并发多文件上传 * update 调整流程定义查询 * update 优化 统一书写格式 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化发布事件增加租户ID * update 调整驳回记录 * Revert "update 获取用户简略信息,祖级部门列表,部门负责人等" * update 获取用户简略信息,祖级部门列表,部门负责人等 * update 更新warm-flow版本到v1.3.6-m1 * update 更新注释信息 * fix 临时修复 warm参数读取问题 * update warm-flow 1.3.4 => 1.3.5 优化流程图导入 * update 更新warm-flow版本到v1.3.5 2024-12-20 * update 增加抄送人名称 * update 我的抄送增加申请人以及更新时间 * update 优化监听事件注释 * update 优化流程分类名称翻译回显 * fix 修改根据流程分类id查询 * update 新增流程分类id查询 * fix 修复抄送错误 * fix 修复错误判空 * fix 修复错误判空 * update 新增删除流程事件 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整sql书写顺序 * fix 修复 抄送缺数据问题 与 已完成任务数据取错问题 * update 新增根据业务id查询流程实例详细信息 * update 调整变量参数 * update 调整分类接口 * update 统一业务id参数 * update 调整返回参数 * update 增加业务id通用查询条件 * update 优化代码 修复bug * update 优化新增流程分类判断 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整驳回 * update 优化错误注释 * update 优化流程分类sql语句 * update 调整驳回 * update 删除流程分类状态 * update 增加流程定义防重 * [fix] * update 优化代码 修复bug * update 优化流程定义增加类别树查询 * update 新增翻译根据流程分类ID查询流程分类名称 * update 根据分页对象构建表格分页数据对象 * update 优化流程定义列表名称 * update 优化流程分类校验 * update 导入流程 支持自定义类别 * update 流程案例 增加表单路径 * update 流程定义查询返回表单路径 * update 优化任务业务层 * fix 修复 请假天数不准确问题 * update 优化驳回 撤销 * update 删除类别查询权限 通用查询不需要加权限 * fix 修复 变量名修改错误 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 调整驳回 * update 表名类名统一命名 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 挑战者驳回 撤销 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * fix 修复会签 票签撤销问题 * update 调整并行环节撤销错误 增加办理校验 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 优化获取办理人 * update 优化 workflow模块增加doc依赖输出接口文档 * Revert "update 优化 删除无用方法" * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * update 调整代办人查询错误 增加示例 * update 优化 重构代码 * update 优化 重构代码 * update 优化 将工作流消息推送改为sse * add 添加模型 * update 调整审批记录 * update 调整请假案例 * fix 修复流程定义查询错误 * update 调整流程实例查询错误 * update 调整获取当前登录任务实例 * add 添加消息发送 * update 调整办理监听 * [add] * [fix] * update 重构 将工作流查询逻辑封装为单独的service类 * [update] * [add] * 办理附件提交 * 申请人查询修改 * update 回退优化 删除无用方法 * update 优化任务办理人翻译实现 * update 优化任务分配人枚举 * update 优化 删除无用方法 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * [add] * update 优化全局任务办理监听 * update 删除无用引入 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化激活/挂起取反逻辑 * !614 style workflow xml 格式 * style workflow xml 格式 * !612 fix FlwInstanceMapper xml错误 * fix FlwInstanceMapper xml错误 * update 优化 后端代码 * update 优化接口请求路径 * update 调整已办排序 * add 添加任务作废 * update 调整任务办理操作 * update 调整加签,减签校验 * update 调整加签 * add 添加获取当前任务的办理人接口 * add 添加任务查询会签,票签比例 * update 调整任务,实例查询 * update 调整任务委托,转办,优化部分代码等 * update 调整流程定义视图 * add 添加任务,流程实例常用查询接口 * Merge branch 'dev' into warm-flow-future * update 优化工作流常量使用 * update 优化流程记录运行时长获取 * update 优化任务管理控制层 * update 回复业务状态枚举 * update 优化业务状态枚举 * update 调整昵称翻译 * update 调整修改办理人接口 * update 调整流程全局监听,调整任务办理人批量修改,优化代码 * update 优化查询可驳回节点 * update 优化添加抄送人 * update 优化增加人员类型枚举,删除无用常量 * update 优化请假天数工具类,删除缓存,加锁处理,可以采用外部传参的形式处理redis部分 * update 优化请假天数计算 * update 优化任务完成时间处理 * update 优化任务办理人获取 * update 优化任务操作,委派、转办、加签、减签、修改办理人等 * add 新增warm-flow-all.sql * del 删除多余SQL * del 删除无用vo * del 删除表单管理信息 * del 删除节点配置信息 * update 优化节点类型常量获取 * update 优化权限办理人获取 * update 优化权限办理人获取判断 * update 提交等待新版本待优化的开始监听信息 * update 新增获取部门负责人 * add 新增分派办理人监听器 * update 优化或者字符串用户ID * update 用户前缀去掉 * update 调整流程实例状态查询 * add 添加流程撤销 * add 添加流程抄送 * add 新增办理人权限处理器 * update 升级warm-flow1.3.4 * Merge branch 'dev' into warm-flow-future * update 调整流程定义复制 * update 调整流程启动设置启动人变量 * update 调整流程定义删除 * update 调整流程定义导入 * update 调整工作流任务,流程定义等查询 * update 调整工作流人员翻译查询 * update 调整转办,加签等参数 * update 调整流程办理设置办理人 * update 调整流程设计保存 * update 调整流程状态,移除过时方法,调整查询办理人 * update 补充工作流请求增加鉴权 * update 工作流请求增加鉴权 * update 新增流程完成监听器 * update 新增流程启动监听器 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 更新warm-flow版本 * update 优化workflow表sql格式 * update 优化,增加岗位权限判空处理 * update 当前用户所有权限岗位ID改为从token获取 * update 当前用户所有权限增加岗位ID权限 * update 更新通过岗位ID查询用户 * update 优化激活/挂起流程定义判断 * Revert "add 新增异常处理器和工作流封装包" * add 新增异常处理器和工作流封装包 * update 优化待办任务查询以及任务流转 * update 优化工作流工具,避免多次获取请求 * fix 修改无效标识 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 查询部门并返回任务指派的列表根据部门树搜索 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化任务办理人分组 * update 优化任务办理人查询 * update 优化任务办理人查询 * update 优化任务办理人 * update 完善任务办理人 * add 新增角色办理人 * !596 优化工作流代码逻辑 * update 优化工作流工具冗余代码 * update 优化工作流代码逻辑 * update 调整办理 驳回 终止等状态 * update 调整流程定义查询 * 解决冲突提交 warmflow代码 * update 升级warm-flow到1.3.0 调整流程办理 ,驳回,终止等 添加自定义监听 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整流程xml查询 * update 调整驳回 * update 升级warm-flow * update 调整任务办理设置办理人 * 调整转办,委托参数 * update warm-flow 1.2.4 => 1.2.7 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整抄送错误 * 添加已办,未办 * Merge branch 'warm-flow-future' of https://gitee.com/dromara/RuoYi-Vue… * add 添加我发起的单据接口 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 调整流程实例,待办查询 * remove 删除无用校验 * add 添加待办人查询 * Merge branch 'dev' into warm-flow-future * update 调整字段错误,流程导入 * add 添加流程激活/挂起接口 升级warm-flow到1.2.4 * add 添加历史流程定义查询 调整流程发布 * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * Merge remote-tracking branch 'origin/dev' into warm-flow-future * update 优化 TenantSpringCacheManager 处理逻辑 * fix 修复 一级缓存key未区分租户问题 * update 优化 角色权限判断 * update 更新 readme * update 优化 增加删除标志位常量优化查询代码 * fix 修复 登出无法正确删除对应的租户数据问题 * update 优化 sse 拦截网络中断io异常 * fix 修复 登录错误锁定不区分租户问题 * update 优化 sse 关闭连接各种异常问题 * update 优化 监控使用独立web依赖 * fix 修复 代码生成 错误匹配表名问题 * update 优化 适配 anyline 新改动 * update anyline 8.7.2-20240728 * update 脱敏策略优化增加密码 * add 新增 更多脱敏策略 * update 优化oss查询代码 * update 优化 sse发送消息 增加token有效期判断 * fix 修复 登出后重新登录 sse推送报错问题 * fix 修复 代码生成 数据源切换问题 * update anyline 8.7.2-20240726 * fix 修复 代码生成 表结构缓存问题 * update snailjob 1.1.0 => 1.1.1 * fix 修复 代码生成 表结构缓存问题 * update 优化 sse 自动装配 * 初始化添加warm-flow

---
 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java |  363 +++++++++++++++++++--------------------------------
 1 files changed, 137 insertions(+), 226 deletions(-)

diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
index d7c4472..0bf8f42 100644
--- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
+++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/utils/WorkflowUtils.java
@@ -2,43 +2,42 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
-import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.dromara.common.core.domain.dto.RoleDTO;
 import org.dromara.common.core.domain.dto.UserDTO;
-import org.dromara.common.core.service.UserService;
 import org.dromara.common.core.utils.SpringUtils;
 import org.dromara.common.core.utils.StreamUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mail.utils.MailUtils;
-import org.dromara.common.satoken.utils.LoginHelper;
-import org.dromara.common.tenant.helper.TenantHelper;
-import org.dromara.common.websocket.dto.WebSocketMessageDto;
-import org.dromara.common.websocket.utils.WebSocketUtils;
-import org.dromara.workflow.common.constant.FlowConstant;
+import org.dromara.common.sse.dto.SseMessageDto;
+import org.dromara.common.sse.utils.SseMessageUtils;
+import org.dromara.warm.flow.core.constant.ExceptionCons;
+import org.dromara.warm.flow.core.dto.FlowParams;
+import org.dromara.warm.flow.core.entity.Node;
+import org.dromara.warm.flow.core.entity.Task;
+import org.dromara.warm.flow.core.entity.User;
+import org.dromara.warm.flow.core.enums.NodeType;
+import org.dromara.warm.flow.core.enums.SkipType;
+import org.dromara.warm.flow.core.service.NodeService;
+import org.dromara.warm.flow.core.service.TaskService;
+import org.dromara.warm.flow.core.service.UserService;
+import org.dromara.warm.flow.core.utils.AssertUtil;
+import org.dromara.warm.flow.orm.entity.FlowNode;
+import org.dromara.warm.flow.orm.entity.FlowTask;
+import org.dromara.warm.flow.orm.entity.FlowUser;
+import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
+import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
 import org.dromara.workflow.common.enums.MessageTypeEnum;
-import org.dromara.workflow.common.enums.TaskStatusEnum;
-import org.dromara.workflow.domain.ActHiTaskinst;
-import org.dromara.workflow.domain.vo.MultiInstanceVo;
-import org.dromara.workflow.domain.vo.ParticipantVo;
-import org.dromara.workflow.flowable.cmd.UpdateHiTaskInstCmd;
-import org.dromara.workflow.mapper.ActHiTaskinstMapper;
-import org.flowable.bpmn.model.BpmnModel;
-import org.flowable.bpmn.model.FlowNode;
-import org.flowable.common.engine.api.delegate.Expression;
-import org.flowable.engine.ProcessEngine;
-import org.flowable.engine.history.HistoricProcessInstance;
-import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior;
-import org.flowable.engine.impl.bpmn.behavior.SequentialMultiInstanceBehavior;
-import org.flowable.identitylink.api.history.HistoricIdentityLink;
-import org.flowable.task.api.Task;
-import org.flowable.task.api.TaskQuery;
-import org.flowable.task.api.history.HistoricTaskInstance;
-import org.flowable.task.service.impl.persistence.entity.TaskEntity;
+import org.dromara.workflow.service.IFlwTaskAssigneeService;
+import org.dromara.workflow.service.IFlwTaskService;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
 
 /**
  * 宸ヤ綔娴佸伐鍏�
@@ -48,220 +47,84 @@
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public class WorkflowUtils {
 
-    private static final ProcessEngine PROCESS_ENGINE = SpringUtils.getBean(ProcessEngine.class);
-    private static final ActHiTaskinstMapper ACT_HI_TASKINST_MAPPER = SpringUtils.getBean(ActHiTaskinstMapper.class);
+    private static final IFlwTaskAssigneeService TASK_ASSIGNEE_SERVICE = SpringUtils.getBean(IFlwTaskAssigneeService.class);
+    private static final IFlwTaskService FLW_TASK_SERVICE = SpringUtils.getBean(IFlwTaskService.class);
+    private static final FlowNodeMapper FLOW_NODE_MAPPER = SpringUtils.getBean(FlowNodeMapper.class);
+    private static final FlowTaskMapper FLOW_TASK_MAPPER = SpringUtils.getBean(FlowTaskMapper.class);
+    private static final UserService USER_SERVICE = SpringUtils.getBean(UserService.class);
+    private static final TaskService TASK_SERVICE = SpringUtils.getBean(TaskService.class);
+    private static final NodeService NODE_SERVICE = SpringUtils.getBean(NodeService.class);
 
     /**
-     * 鍒涘缓涓�涓柊浠诲姟
-     *
-     * @param currentTask 鍙傛暟
+     * 鑾峰彇宸ヤ綔娴佺敤鎴穝ervice
      */
-    public static TaskEntity createNewTask(Task currentTask) {
-        TaskEntity task = null;
-        if (ObjectUtil.isNotEmpty(currentTask)) {
-            task = (TaskEntity) PROCESS_ENGINE.getTaskService().newTask();
-            task.setCategory(currentTask.getCategory());
-            task.setDescription(currentTask.getDescription());
-            task.setAssignee(currentTask.getAssignee());
-            task.setName(currentTask.getName());
-            task.setProcessDefinitionId(currentTask.getProcessDefinitionId());
-            task.setProcessInstanceId(currentTask.getProcessInstanceId());
-            task.setTaskDefinitionKey(currentTask.getTaskDefinitionKey());
-            task.setPriority(currentTask.getPriority());
-            task.setCreateTime(new Date());
-            task.setTenantId(TenantHelper.getTenantId());
-            PROCESS_ENGINE.getTaskService().saveTask(task);
-        }
-        if (ObjectUtil.isNotNull(task)) {
-            UpdateHiTaskInstCmd updateHiTaskInstCmd = new UpdateHiTaskInstCmd(Collections.singletonList(task.getId()), task.getProcessDefinitionId(), task.getProcessInstanceId());
-            PROCESS_ENGINE.getManagementService().executeCommand(updateHiTaskInstCmd);
-        }
-        return task;
+    public static UserService getFlowUserService() {
+        return USER_SERVICE;
     }
 
     /**
-     * 鎶勯�佷换鍔�
+     * 鏋勫缓宸ヤ綔娴佺敤鎴�
      *
-     * @param parentTaskList 鐖剁骇浠诲姟
-     * @param userIds        浜哄憳id
+     * @param userList 鍔炵悊鐢ㄦ埛
+     * @param taskId   浠诲姟ID
+     * @return 鐢ㄦ埛
      */
-    public static void createCopyTask(List<Task> parentTaskList, List<Long> userIds) {
-        List<Task> list = new ArrayList<>();
-        String tenantId = TenantHelper.getTenantId();
-        for (Task parentTask : parentTaskList) {
-            for (Long userId : userIds) {
-                TaskEntity newTask = (TaskEntity) PROCESS_ENGINE.getTaskService().newTask();
-                newTask.setParentTaskId(parentTask.getId());
-                newTask.setAssignee(userId.toString());
-                newTask.setName("銆愭妱閫併��-" + parentTask.getName());
-                newTask.setProcessDefinitionId(parentTask.getProcessDefinitionId());
-                newTask.setProcessInstanceId(parentTask.getProcessInstanceId());
-                newTask.setTaskDefinitionKey(parentTask.getTaskDefinitionKey());
-                newTask.setTenantId(tenantId);
-                list.add(newTask);
+    public static Set<User> buildUser(List<User> userList, Long taskId) {
+        if (CollUtil.isEmpty(userList)) {
+            return Set.of();
+        }
+        Set<User> list = new HashSet<>();
+        Set<String> processedBySet = new HashSet<>();
+        for (User user : userList) {
+            // 鏍规嵁 processedBy 鍓嶇紑鍒ゆ柇澶勭悊浜虹被鍨嬶紝鍒嗗埆鑾峰彇鐢ㄦ埛鍒楄〃
+            List<UserDTO> users = TASK_ASSIGNEE_SERVICE.fetchUsersByStorageId(user.getProcessedBy());
+            // 杞崲涓� FlowUser 骞舵坊鍔犲埌缁撴灉闆嗗悎
+            if (CollUtil.isNotEmpty(users)) {
+                users.forEach(dto -> {
+                    String processedBy = String.valueOf(dto.getUserId());
+                    if (!processedBySet.contains(processedBy)) {
+                        FlowUser flowUser = new FlowUser();
+                        flowUser.setType(user.getType());
+                        flowUser.setProcessedBy(processedBy);
+                        flowUser.setAssociated(taskId);
+                        list.add(flowUser);
+                        processedBySet.add(processedBy);
+                    }
+                });
             }
         }
-        PROCESS_ENGINE.getTaskService().bulkSaveTasks(list);
-        if (CollUtil.isNotEmpty(list) && CollUtil.isNotEmpty(parentTaskList)) {
-            String processInstanceId = parentTaskList.get(0).getProcessInstanceId();
-            String processDefinitionId = parentTaskList.get(0).getProcessDefinitionId();
-            List<String> taskIds = StreamUtils.toList(list, Task::getId);
-            ActHiTaskinst actHiTaskinst = new ActHiTaskinst();
-            actHiTaskinst.setProcDefId(processDefinitionId);
-            actHiTaskinst.setProcInstId(processInstanceId);
-            actHiTaskinst.setScopeType(TaskStatusEnum.COPY.getStatus());
-            actHiTaskinst.setTenantId(tenantId);
-            LambdaUpdateWrapper<ActHiTaskinst> updateWrapper = new LambdaUpdateWrapper<>();
-            updateWrapper.in(ActHiTaskinst::getId, taskIds);
-            ACT_HI_TASKINST_MAPPER.update(actHiTaskinst, updateWrapper);
-            for (Task task : list) {
-                PROCESS_ENGINE.getTaskService().addComment(task.getId(), task.getProcessInstanceId(), TaskStatusEnum.COPY.getStatus(), StrUtil.EMPTY);
-            }
-        }
-    }
-
-    /**
-     * 鑾峰彇褰撳墠浠诲姟鍙備笌鑰�
-     *
-     * @param taskId 浠诲姟id
-     */
-    public static ParticipantVo getCurrentTaskParticipant(String taskId, UserService userService) {
-        ParticipantVo participantVo = new ParticipantVo();
-        List<HistoricIdentityLink> linksForTask = PROCESS_ENGINE.getHistoryService().getHistoricIdentityLinksForTask(taskId);
-        Task task = QueryUtils.taskQuery().taskId(taskId).singleResult();
-        if (task != null && CollUtil.isNotEmpty(linksForTask)) {
-            List<HistoricIdentityLink> groupList = StreamUtils.filter(linksForTask, e -> StringUtils.isNotBlank(e.getGroupId()));
-            if (CollUtil.isNotEmpty(groupList)) {
-                List<Long> groupIds = StreamUtils.toList(groupList, e -> Long.valueOf(e.getGroupId()));
-                List<Long> userIds = userService.selectUserIdsByRoleIds(groupIds);
-                if (CollUtil.isNotEmpty(userIds)) {
-                    participantVo.setGroupIds(groupIds);
-                    List<UserDTO> userList = userService.selectListByIds(userIds);
-                    if (CollUtil.isNotEmpty(userList)) {
-                        List<Long> userIdList = StreamUtils.toList(userList, UserDTO::getUserId);
-                        List<String> nickNames = StreamUtils.toList(userList, UserDTO::getNickName);
-                        participantVo.setCandidate(userIdList);
-                        participantVo.setCandidateName(nickNames);
-                        participantVo.setClaim(!StringUtils.isBlank(task.getAssignee()));
-                    }
-                }
-            } else {
-                List<HistoricIdentityLink> candidateList = StreamUtils.filter(linksForTask, e -> FlowConstant.CANDIDATE.equals(e.getType()));
-                List<Long> userIdList = new ArrayList<>();
-                for (HistoricIdentityLink historicIdentityLink : linksForTask) {
-                    try {
-                        userIdList.add(Long.valueOf(historicIdentityLink.getUserId()));
-                    } catch (NumberFormatException ignored) {
-
-                    }
-                }
-                List<UserDTO> userList = userService.selectListByIds(userIdList);
-                if (CollUtil.isNotEmpty(userList)) {
-                    List<Long> userIds = StreamUtils.toList(userList, UserDTO::getUserId);
-                    List<String> nickNames = StreamUtils.toList(userList, UserDTO::getNickName);
-                    participantVo.setCandidate(userIds);
-                    participantVo.setCandidateName(nickNames);
-                    // 鍒ゆ柇褰撳墠浠诲姟鏄惁鍏锋湁澶氫釜鍔炵悊浜�
-                    if (CollUtil.isNotEmpty(candidateList) && candidateList.size() > 1) {
-                        // 濡傛灉 assignee 瀛樺湪锛屽垯璁剧疆褰撳墠浠诲姟宸茬粡琚棰�
-                        participantVo.setClaim(StringUtils.isNotBlank(task.getAssignee()));
-                    }
-                }
-            }
-        }
-        return participantVo;
-    }
-
-    /**
-     * 鍒ゆ柇褰撳墠鑺傜偣鏄惁涓轰細绛捐妭鐐�
-     *
-     * @param processDefinitionId 娴佺▼瀹氫箟id
-     * @param taskDefinitionKey   娴佺▼瀹氫箟id
-     */
-    public static MultiInstanceVo isMultiInstance(String processDefinitionId, String taskDefinitionKey) {
-        BpmnModel bpmnModel = PROCESS_ENGINE.getRepositoryService().getBpmnModel(processDefinitionId);
-        FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(taskDefinitionKey);
-        MultiInstanceVo multiInstanceVo = new MultiInstanceVo();
-        //鍒ゆ柇鏄惁涓哄苟琛屼細绛捐妭鐐�
-        if (flowNode.getBehavior() instanceof ParallelMultiInstanceBehavior behavior && behavior.getCollectionExpression() != null) {
-            Expression collectionExpression = behavior.getCollectionExpression();
-            String assigneeList = collectionExpression.getExpressionText();
-            String assignee = behavior.getCollectionElementVariable();
-            multiInstanceVo.setType(behavior);
-            multiInstanceVo.setAssignee(assignee);
-            multiInstanceVo.setAssigneeList(assigneeList);
-            return multiInstanceVo;
-            //鍒ゆ柇鏄惁涓轰覆琛屼細绛捐妭鐐�
-        } else if (flowNode.getBehavior() instanceof SequentialMultiInstanceBehavior behavior && behavior.getCollectionExpression() != null) {
-            Expression collectionExpression = behavior.getCollectionExpression();
-            String assigneeList = collectionExpression.getExpressionText();
-            String assignee = behavior.getCollectionElementVariable();
-            multiInstanceVo.setType(behavior);
-            multiInstanceVo.setAssignee(assignee);
-            multiInstanceVo.setAssigneeList(assigneeList);
-            return multiInstanceVo;
-        }
-        return null;
-    }
-
-    /**
-     * 鑾峰彇褰撳墠娴佺▼鐘舵��
-     *
-     * @param taskId 浠诲姟id
-     */
-    public static String getBusinessStatusByTaskId(String taskId) {
-        HistoricTaskInstance historicTaskInstance = QueryUtils.hisTaskInstanceQuery().taskId(taskId).singleResult();
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisInstanceQuery(historicTaskInstance.getProcessInstanceId()).singleResult();
-        return historicProcessInstance.getBusinessStatus();
-    }
-
-    /**
-     * 鑾峰彇褰撳墠娴佺▼鐘舵��
-     *
-     * @param businessKey 涓氬姟id
-     */
-    public static String getBusinessStatus(String businessKey) {
-        HistoricProcessInstance historicProcessInstance = QueryUtils.hisBusinessKeyQuery(businessKey).singleResult();
-        return historicProcessInstance.getBusinessStatus();
+        return list;
     }
 
     /**
      * 鍙戦�佹秷鎭�
      *
-     * @param list        浠诲姟
-     * @param name        娴佺▼鍚嶇О
+     * @param flowName    娴佺▼瀹氫箟鍚嶇О
      * @param messageType 娑堟伅绫诲瀷
      * @param message     娑堟伅鍐呭锛屼负绌哄垯鍙戦�侀粯璁ら厤缃殑娑堟伅鍐呭
      */
-    public static void sendMessage(List<Task> list, String name, List<String> messageType, String message, UserService userService) {
-        Set<Long> userIds = new HashSet<>();
+    public static void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
+        List<UserDTO> userList = new ArrayList<>();
+        List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instId);
         if (StringUtils.isBlank(message)) {
-            message = "鏈夋柊鐨勩��" + name + "銆戝崟鎹凡缁忔彁浜よ嚦鎮ㄧ殑寰呭姙锛岃鎮ㄥ強鏃跺鐞嗐��";
+            message = "鏈夋柊鐨勩��" + flowName + "銆戝崟鎹凡缁忔彁浜よ嚦鎮紝璇锋偍鍙婃椂澶勭悊銆�";
         }
-        for (Task t : list) {
-            ParticipantVo taskParticipant = WorkflowUtils.getCurrentTaskParticipant(t.getId(), userService);
-            if (CollUtil.isNotEmpty(taskParticipant.getGroupIds())) {
-                List<Long> userIdList = userService.selectUserIdsByRoleIds(taskParticipant.getGroupIds());
-                if (CollUtil.isNotEmpty(userIdList)) {
-                    userIds.addAll(userIdList);
-                }
-            }
-            List<Long> candidate = taskParticipant.getCandidate();
-            if (CollUtil.isNotEmpty(candidate)) {
-                userIds.addAll(candidate);
+        for (Task task : list) {
+            List<UserDTO> users = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
+            if (CollUtil.isNotEmpty(users)) {
+                userList.addAll(users);
             }
         }
-        if (CollUtil.isNotEmpty(userIds)) {
-            List<UserDTO> userList = userService.selectListByIds(new ArrayList<>(userIds));
+        if (CollUtil.isNotEmpty(userList)) {
             for (String code : messageType) {
                 MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code);
                 if (ObjectUtil.isNotEmpty(messageTypeEnum)) {
                     switch (messageTypeEnum) {
                         case SYSTEM_MESSAGE:
-                            WebSocketMessageDto dto = new WebSocketMessageDto();
-                            dto.setSessionKeys(new ArrayList<>(userIds));
+                            SseMessageDto dto = new SseMessageDto();
+                            dto.setUserIds(StreamUtils.toList(userList, UserDTO::getUserId).stream().distinct().collect(Collectors.toList()));
                             dto.setMessage(message);
-                            WebSocketUtils.publishMessage(dto);
+                            SseMessageUtils.publishMessage(dto);
                             break;
                         case EMAIL_MESSAGE:
                             MailUtils.sendText(StreamUtils.join(userList, UserDTO::getEmail), "鍗曟嵁瀹℃壒鎻愰啋", message);
@@ -269,6 +132,8 @@
                         case SMS_MESSAGE:
                             //todo 鐭俊鍙戦��
                             break;
+                        default:
+                            throw new IllegalStateException("Unexpected value: " + messageTypeEnum);
                     }
                 }
             }
@@ -276,20 +141,66 @@
     }
 
     /**
-     * 鏍规嵁浠诲姟id鏌ヨ 褰撳墠鐢ㄦ埛鐨勪换鍔★紝妫�鏌� 褰撳墠浜哄憳 鏄惁鏄 taskId 鐨勫姙鐞嗕汉
+     * 椹冲洖
      *
-     * @param taskId 浠诲姟id
-     * @return 缁撴灉
+     * @param message        瀹℃壒鎰忚
+     * @param instanceId     娴佺▼瀹炰緥id
+     * @param targetNodeCode 鐩爣鑺傜偣
+     * @param flowStatus     娴佺▼鐘舵��
+     * @param flowHisStatus  鑺傜偣鎿嶄綔鐘舵��
      */
-    public static Task getTaskByCurrentUser(String taskId) {
-        TaskQuery taskQuery = QueryUtils.taskQuery();
-        taskQuery.taskId(taskId).taskCandidateOrAssigned(String.valueOf(LoginHelper.getUserId()));
-
-        List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
-        if (CollUtil.isNotEmpty(roles)) {
-            List<String> groupIds = StreamUtils.toList(roles, e -> String.valueOf(e.getRoleId()));
-            taskQuery.taskCandidateGroupIn(groupIds);
+    public static void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
+        List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instanceId);
+        if (CollUtil.isNotEmpty(list)) {
+            List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
+            if (list.size() == tasks.size()) {
+                return;
+            }
         }
-        return taskQuery.singleResult();
+        for (FlowTask task : list) {
+            List<UserDTO> userList = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
+            FlowParams flowParams = FlowParams.build();
+            flowParams.nodeCode(targetNodeCode);
+            flowParams.message(message);
+            flowParams.skipType(SkipType.PASS.getKey());
+            flowParams.flowStatus(flowStatus).hisStatus(flowHisStatus);
+            flowParams.ignore(true);
+            //瑙e喅浼氱娌℃潈闄愰棶棰�
+            if (CollUtil.isNotEmpty(userList)) {
+                flowParams.handler(userList.get(0).getUserId().toString());
+            }
+            TASK_SERVICE.skip(task.getId(), flowParams);
+        }
+        //瑙e喅浼氱澶氫汉瀹℃壒闂
+        backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
+    }
+
+    /**
+     * 鐢宠浜鸿妭鐐圭紪鐮�
+     *
+     * @param definitionId 娴佺▼瀹氫箟id
+     * @return 鐢宠浜鸿妭鐐圭紪鐮�
+     */
+    public static String applyNodeCode(Long definitionId) {
+        //鑾峰彇宸插彂甯冪殑娴佺▼鑺傜偣
+        List<FlowNode> flowNodes = FLOW_NODE_MAPPER.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
+        AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
+        Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
+        AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
+        Node nextNode = NODE_SERVICE.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.NONE.getKey());
+        return nextNode.getNodeCode();
+    }
+
+    /**
+     * 鍒犻櫎杩愯涓殑浠诲姟
+     *
+     * @param taskIds 浠诲姟id
+     */
+    public static void deleteRunTask(List<Long> taskIds) {
+        if (CollUtil.isEmpty(taskIds)) {
+            return;
+        }
+        USER_SERVICE.deleteByTaskIds(taskIds);
+        FLOW_TASK_MAPPER.deleteByIds(taskIds);
     }
 }

--
Gitblit v1.9.3