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