From 4ebf18a3a34312a4636684fec84d8fcf8b249e6b Mon Sep 17 00:00:00 2001 From: gssong <1742057357@qq.com> Date: Wed, 4 Dec 2024 22:13:50 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E8=B0=83=E6=95=B4=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E7=9B=91=E5=90=AC=EF=BC=8C=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E5=8A=9E=E7=90=86=E4=BA=BA=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/enums/BusinessStatusEnum.java | 10 ++ .../controller/FlwTaskController.java | 72 +------- .../listener/WorkflowAssignmentListener.java | 66 -------- .../listener/WorkflowFinishListener.java | 65 -------- .../listener/WorkflowGlobalListener.java | 71 ++++++++ .../listener/WorkflowStartListener.java | 61 ------- .../workflow/service/IFlwTaskService.java | 51 ++++++ .../service/impl/FlwInstanceServiceImpl.java | 15 +- .../service/impl/FlwTaskServiceImpl.java | 155 ++++++++++++++++-- script/bpmn/leaveFlow-serial1.xml | 2 +- 10 files changed, 291 insertions(+), 277 deletions(-) delete mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowAssignmentListener.java delete mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowFinishListener.java create mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java delete mode 100644 ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowStartListener.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java index adb82e5c0..7913ddefd 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/enums/BusinessStatusEnum.java @@ -90,6 +90,16 @@ public enum BusinessStatusEnum { return DRAFT.status.equals(status) || CANCEL.status.equals(status) || BACK.status.equals(status); } + /** + * 判断是否为撤销,退回,作废,终止 + * + * @param status status + * @return 结果 + */ + public static boolean initialState(String status) { + return CANCEL.status.equals(status) || BACK.status.equals(status) || INVALID.status.equals(status) || TERMINATION.status.equals(status); + } + /** * 运行中的实例状态 * diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java index b7f52c17c..86b7ea16c 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/controller/FlwTaskController.java @@ -172,80 +172,20 @@ public class FlwTaskController extends BaseController { @RepeatSubmit @PostMapping("/{taskOperation}") public R taskOperation(@Validated @RequestBody TaskOperationBo bo, @PathVariable String taskOperation) { - FlowParams flowParams = new FlowParams(); - flowParams.message(bo.getMessage()); - - // 根据操作类型构建 FlowParams - switch (taskOperation) { - case "delegateTask", "transferTask", "addSignature" -> { - ValidatorUtils.validate(bo, AddGroup.class); - flowParams.addHandlers(bo.getUserIdentifiers()); - } - case "reductionSignature" -> { - ValidatorUtils.validate(bo, EditGroup.class); - flowParams.reductionHandlers(bo.getAllUserIdentifiers()); - } - case "updateAssignee" -> { - ValidatorUtils.validate(bo, AddGroup.class); - flowParams.addHandlers(bo.getUserIdentifiers()); - flowParams.cooperateType(CooperateType.APPROVAL.getKey()); - flowParams.ignore(false); - flowParams.message("修改任务办理人"); - } - default -> { - return R.fail("Invalid operation type: " + taskOperation); - } - } - - Long taskId = bo.getTaskId(); - // 设置任务状态并执行对应的任务操作 - switch (taskOperation) { - //委派任务 - case "delegateTask" -> { - flowParams.hisStatus(TaskStatusEnum.DEPUTE.getStatus()); - return toAjax(taskService.depute(taskId, flowParams)); - } - //转办任务 - case "transferTask" -> { - flowParams.hisStatus(TaskStatusEnum.TRANSFER.getStatus()); - return toAjax(taskService.transfer(taskId, flowParams)); - } - //加签,增加办理人 - case "addSignature" -> { - flowParams.hisStatus(TaskStatusEnum.SIGN.getStatus()); - return toAjax(taskService.addSignature(taskId, flowParams)); - } - //减签,减少办理人 - case "reductionSignature" -> { - flowParams.hisStatus(TaskStatusEnum.SIGN_OFF.getStatus()); - return toAjax(taskService.reductionSignature(taskId, flowParams)); - } - //修改办理人 - case "updateAssignee" -> { - return toAjax(taskService.updateHandler(taskId, flowParams)); - } - default -> { - return R.fail("Invalid operation type: " + taskOperation); - } - } + return toAjax(flwTaskService.taskOperation(bo, taskOperation)); } /** * TODO 待删除的方法(用上面那个),修改任务办理人 * - * @param taskId 任务id - * @param userId 办理人id + * @param taskIdList 任务id + * @param userId 办理人id */ @Log(title = "任务管理", businessType = BusinessType.UPDATE) @RepeatSubmit() - @PutMapping("/updateAssignee/{taskId}/{userId}") - public R updateAssignee(@PathVariable Long taskId, @PathVariable String userId) { - FlowParams flowParams = new FlowParams(); - flowParams.addHandlers(Collections.singletonList(USER.getCode()+userId)); - flowParams.cooperateType(CooperateType.APPROVAL.getKey()); - flowParams.ignore(false); - flowParams.message("修改任务办理人"); - return toAjax(taskService.updateHandler(taskId, flowParams)); + @PutMapping("/updateAssignee/{userId}") + public R updateAssignee(@RequestBody List taskIdList, @PathVariable String userId) { + return toAjax(flwTaskService.updateAssignee(taskIdList, userId)); } /** diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowAssignmentListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowAssignmentListener.java deleted file mode 100644 index 967267c83..000000000 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowAssignmentListener.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.dromara.workflow.listener; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.domain.dto.UserDTO; -import org.dromara.common.core.utils.StringUtils; -import org.dromara.warm.flow.core.constant.FlowCons; -import org.dromara.warm.flow.core.entity.Instance; -import org.dromara.warm.flow.core.entity.Task; -import org.dromara.warm.flow.core.listener.Listener; -import org.dromara.warm.flow.core.listener.ListenerVariable; -import org.dromara.workflow.service.impl.WfTaskAssigneeServiceImpl; -import org.springframework.stereotype.Component; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -/** - * 分派办理人监听器,动态修改代办任务信息 - * - * @author AprilWind - */ -@RequiredArgsConstructor -@Component -@Slf4j -public class WorkflowAssignmentListener implements Listener { - - private final WfTaskAssigneeServiceImpl assigneeService; - - @Override - public void notify(ListenerVariable listenerVariable) { - log.info("分派办理人监听器开始执行......"); - List tasks = listenerVariable.getNextTasks(); - Instance instance = listenerVariable.getInstance(); - for (Task task : tasks) { - List permissionList = task.getPermissionList(); - // 记录待添加的权限项 - List toAddPermissions = new ArrayList<>(); - // 使用迭代器来避免直接删除元素 - Iterator iterator = permissionList.iterator(); - while (iterator.hasNext()) { - String permission = iterator.next(); - // 替换发起人审批权限 - if (StringUtils.isNotEmpty(permission) && permission.contains(FlowCons.WARMFLOWINITIATOR)) { - iterator.remove(); - permissionList.add(permission.replace(FlowCons.WARMFLOWINITIATOR, instance.getCreateBy())); - } else { - // 获取办理人 - List users = assigneeService.fetchUsersByStorageId(permission); - if (!users.isEmpty()) { - // 移除当前权限并替换成多个用户的权限 - iterator.remove(); - for (UserDTO user : users) { - toAddPermissions.add(String.valueOf(user.getUserId())); - } - } - } - } - // 添加新权限项 - permissionList.addAll(toAddPermissions); - } - log.info("分派办理人监听器执行结束......"); - } - -} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowFinishListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowFinishListener.java deleted file mode 100644 index 1617713f6..000000000 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowFinishListener.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.dromara.workflow.listener; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.domain.event.ProcessEvent; -import org.dromara.common.core.enums.BusinessStatusEnum; -import org.dromara.common.core.utils.SpringUtils; -import org.dromara.warm.flow.core.entity.Definition; -import org.dromara.warm.flow.core.entity.Instance; -import org.dromara.warm.flow.core.enums.FlowStatus; -import org.dromara.warm.flow.core.listener.Listener; -import org.dromara.warm.flow.core.listener.ListenerVariable; -import org.dromara.workflow.service.IFlwInstanceService; -import org.springframework.stereotype.Component; - -/** - * 流程完成监听器,用于处理流程结束时的业务逻辑 - *

- * 该监听器通常用于处理流程完成后的相关操作,如更新业务表、记录日志、通知等 - * 可以将业务逻辑放在此监听器中,也可以在业务代码中处理,或者使用局部监听器进行监听 - *

- *

- * 例如,当一个流程结束时,可能需要根据流程的状态更新业务表,执行后续的处理操作 - * 或者发送通知等。此监听器可以提供统一的处理入口 - *

- * - * @author AprilWind - */ -@RequiredArgsConstructor -@Component -@Slf4j -public class WorkflowFinishListener implements Listener { - - private final IFlwInstanceService iFlwInstanceService; - - /** - * 流程结束监听器,用于在流程结束后执行相关的业务逻辑 - *

- * 该方法会在流程完成后被触发,通常用于执行业务表的新增或更新操作 - * 或者其他与业务相关的操作(如通知发送、记录日志等) - *

- * - * @param listenerVariable 监听器变量,包含与当前流程相关的信息 - */ - @Override - public void notify(ListenerVariable listenerVariable) { - log.info("流程结束监听器"); - Instance instance = listenerVariable.getInstance(); - Definition definition = listenerVariable.getDefinition(); - ProcessEvent processEvent = new ProcessEvent(); - //检查流程是否已结束 - if (FlowStatus.isFinished(instance.getFlowStatus())) { - // 若流程已结束,更新状态为已完成 - iFlwInstanceService.updateStatus(instance.getId(), BusinessStatusEnum.FINISH.getStatus()); - // 流程结束监听,处理结束后的业务逻辑 - processEvent.setStatus(BusinessStatusEnum.FINISH.getStatus()); - processEvent.setSubmit(false); - processEvent.setFlowCode(definition.getFlowCode()); - processEvent.setBusinessKey(instance.getBusinessId()); - SpringUtils.context().publishEvent(processEvent); - } - log.info("流程结束监听器结束;{}", "流程完成处理"); - } - -} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java new file mode 100644 index 000000000..355bd2e67 --- /dev/null +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowGlobalListener.java @@ -0,0 +1,71 @@ +package org.dromara.workflow.listener; + +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.domain.event.ProcessEvent; +import org.dromara.common.core.enums.BusinessStatusEnum; +import org.dromara.common.core.utils.SpringUtils; +import org.dromara.warm.flow.core.dto.FlowParams; +import org.dromara.warm.flow.core.entity.Definition; +import org.dromara.warm.flow.core.entity.Instance; +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.warm.flow.orm.mapper.FlowTaskMapper; +import org.dromara.workflow.service.IFlwInstanceService; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 全局任务办理监听 + * + * @author may + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class WorkflowGlobalListener implements GlobalListener { + + private final FlowTaskMapper flowTaskMapper; + private final IFlwInstanceService flwInstanceService; + + @Override + public void finish(ListenerVariable listenerVariable) { + Instance instance = listenerVariable.getInstance(); + Definition definition = listenerVariable.getDefinition(); + FlowParams flowParams = listenerVariable.getFlowParams(); + //撤销,退回,作废,终止发送事件 + if (BusinessStatusEnum.initialState(flowParams.getFlowStatus())) { + publishProcessEvent(flowParams.getFlowStatus(), definition.getFlowCode(), instance.getBusinessId()); + log.info("流程监听器流程状态:{}", flowParams.getFlowStatus()); + } + List flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) + .eq(FlowTask::getInstanceId, instance.getId())); + if (CollUtil.isEmpty(flowTasks)) { + // 若流程已结束,更新状态为已完成并发送完成事件 + flwInstanceService.updateStatus(instance.getId(), BusinessStatusEnum.FINISH.getStatus()); + publishProcessEvent(BusinessStatusEnum.FINISH.getStatus(), definition.getFlowCode(), instance.getBusinessId()); + log.info("流程结束,流程状态:{}", BusinessStatusEnum.FINISH.getStatus()); + } + + } + + /** + * 发布事件 + * + * @param status 状态 + * @param flowCode 流程编码 + * @param businessId 业务id + */ + private void publishProcessEvent(String status, String flowCode, String businessId) { + ProcessEvent processEvent = new ProcessEvent(); + processEvent.setStatus(status); + processEvent.setSubmit(false); + processEvent.setFlowCode(flowCode); + processEvent.setBusinessKey(businessId); + SpringUtils.context().publishEvent(processEvent); + } +} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowStartListener.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowStartListener.java deleted file mode 100644 index 8171c1f59..000000000 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/listener/WorkflowStartListener.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.dromara.workflow.listener; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.common.core.domain.event.ProcessTaskEvent; -import org.dromara.common.core.service.DeptService; -import org.dromara.common.core.utils.SpringUtils; -import org.dromara.common.satoken.utils.LoginHelper; -import org.dromara.warm.flow.core.dto.FlowParams; -import org.dromara.warm.flow.core.entity.Task; -import org.dromara.warm.flow.core.listener.Listener; -import org.dromara.warm.flow.core.listener.ListenerVariable; -import org.springframework.stereotype.Component; - -import java.util.Map; - -/** - * 流程启动监听器,用于处理流程开始时的用户信息和权限设置 - *

- * 该监听器在流程启动阶段执行,主要任务是获取当前登录用户的信息,并为流程设置办理人ID及其相关权限 - * 它通过监听器变量从流程中获取参数,并设置当前用户的权限信息,如角色、岗位、用户ID和部门ID等 - * 该监听器可以避免重复编写相同的权限设置逻辑,简化流程的启动配置 - *

- * - * @author AprilWind - */ -@RequiredArgsConstructor -@Component -@Slf4j -public class WorkflowStartListener implements Listener { - - private final DeptService deptService; - - /** - * 全局开始监听器,用于在流程开始时,设置当前办理人的信息和权限 - *

- * 此方法通过监听器变量获取流程参数,获取当前登录用户,并设置当前办理人的ID和其权限信息 - * 该监听器可以用于流程的开始阶段,避免重复设置办理人信息和权限 - *

- * - * @param listenerVariable 监听器变量,包含流程参数等信息 - */ - @Override - public void notify(ListenerVariable listenerVariable) { - log.info("流程启动监听器"); - FlowParams flowParams = listenerVariable.getFlowParams(); - // 获取当前部门的负责人 - Long leader = deptService.selectDeptLeaderById(LoginHelper.getDeptId()); - flowParams.variable(Map.of("deptLeader", leader)); - Task task = listenerVariable.getTask(); - // 办理任务监听,记录任务执行信息 - ProcessTaskEvent processTaskEvent = new ProcessTaskEvent(); - processTaskEvent.setFlowCode(listenerVariable.getDefinition().getFlowCode()); - processTaskEvent.setNodeCode(task.getNodeCode()); - processTaskEvent.setTaskId(task.getId().toString()); - processTaskEvent.setBusinessKey(listenerVariable.getInstance().getBusinessId()); - SpringUtils.context().publishEvent(processTaskEvent); - log.info("流程启动监听器结束;{}", "开启流程完成"); - } - -} diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java index 758fd469e..ad7761c30 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/IFlwTaskService.java @@ -3,6 +3,7 @@ package org.dromara.workflow.service; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.warm.flow.core.entity.HisTask; +import org.dromara.warm.flow.orm.entity.FlowTask; import org.dromara.workflow.domain.bo.*; import org.dromara.workflow.domain.vo.FlowHisTaskVo; import org.dromara.workflow.domain.vo.FlowTaskVo; @@ -79,6 +80,15 @@ public interface IFlwTaskService { */ TableDataInfo getPageByTaskCopy(FlowTaskBo flowTaskBo, PageQuery pageQuery); + /** + * 修改任务办理人 + * + * @param taskIdList 任务id + * @param userId 用户id + * @return 结果 + */ + boolean updateAssignee(List taskIdList, String userId); + /** * 驳回审批 * @@ -102,4 +112,45 @@ public interface IFlwTaskService { * @return 结果 */ boolean terminationTask(FlowTerminationBo bo); + + /** + * 按照任务id查询任务 + * + * @param taskIdList 任务id + * @return 结果 + */ + List selectByIdList(List taskIdList); + + /** + * 按照任务id查询任务 + * + * @param taskId 任务id + * @return 结果 + */ + FlowTask selectByIdList(Long taskId); + + /** + * 按照实例id查询任务 + * + * @param instanceIdList 流程实例id + * @return 结果 + */ + List selectByInstIdList(List instanceIdList); + + /** + * 按照实例id查询任务 + * + * @param instanceId 流程实例id + * @return 结果 + */ + List selectByInstId(Long instanceId); + + /** + * 任务操作 + * + * @param bo 参数 + * @param taskOperation 操作类型,区分委派、转办、加签、减签、修改办理人 + * @return 结果 + */ + boolean taskOperation(TaskOperationBo bo, String taskOperation); } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java index 40b38de44..dff11f356 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwInstanceServiceImpl.java @@ -17,11 +17,13 @@ import org.dromara.common.core.utils.StringUtils; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.warm.flow.core.FlowFactory; import org.dromara.warm.flow.core.constant.ExceptionCons; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.Definition; import org.dromara.warm.flow.core.entity.Instance; import org.dromara.warm.flow.core.entity.Node; +import org.dromara.warm.flow.core.entity.Task; import org.dromara.warm.flow.core.enums.CooperateType; import org.dromara.warm.flow.core.enums.FlowStatus; import org.dromara.warm.flow.core.enums.NodeType; @@ -45,7 +47,6 @@ import org.dromara.workflow.domain.bo.FlowInstanceBo; import org.dromara.workflow.domain.vo.FlowHisTaskVo; import org.dromara.workflow.domain.vo.FlowInstanceVo; import org.dromara.workflow.domain.vo.VariableVo; -import org.dromara.workflow.handler.FlowProcessEventHandler; import org.dromara.workflow.mapper.FlwInstanceMapper; import org.dromara.workflow.service.IFlwInstanceService; import org.springframework.stereotype.Service; @@ -76,7 +77,6 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { private final TaskService taskService; private final FlowNodeMapper flowNodeMapper; private final NodeService nodeService; - private final FlowProcessEventHandler flowProcessEventHandler; /** * 分页查询正在运行的流程实例 @@ -165,6 +165,8 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { if (definition == null) { throw new ServiceException(ExceptionCons.NOT_FOUNT_DEF); } + List list = taskService.list(FlowFactory.newTask().setInstanceId(instance.getId())); + //获取已发布的流程节点 List flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper().eq(FlowNode::getDefinitionId, definition.getId())); AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE); @@ -174,13 +176,10 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { FlowParams flowParams = FlowParams.build(); flowParams.nodeCode(nextNode.getNodeCode()); flowParams.message(bo.getMessage()); + flowParams.skipType(SkipType.PASS.getKey()); flowParams.flowStatus(BusinessStatusEnum.CANCEL.getStatus()).hisStatus(TaskStatusEnum.CANCEL.getStatus()); - taskService.retrieve(instance.getId(), flowParams); - // 更新状态 - updateStatus(instance.getId(), BusinessStatusEnum.CANCEL.getStatus()); - //流程撤销监听 - flowProcessEventHandler.processHandler(definition.getFlowCode(), - bo.getBusinessId(), BusinessStatusEnum.CANCEL.getStatus(), false); + flowParams.ignore(true); + taskService.skip(list.get(0).getId(), flowParams); } catch (Exception e) { log.error("撤销失败: {}", e.getMessage(), e); throw new ServiceException(e.getMessage()); diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java index ccf67a619..a5fe14822 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/FlwTaskServiceImpl.java @@ -15,11 +15,15 @@ import org.dromara.common.core.service.AssigneeService; 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.core.utils.ValidatorUtils; +import org.dromara.common.core.validate.AddGroup; +import org.dromara.common.core.validate.EditGroup; import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.*; +import org.dromara.warm.flow.core.enums.CooperateType; import org.dromara.warm.flow.core.enums.NodeType; import org.dromara.warm.flow.core.enums.SkipType; import org.dromara.warm.flow.core.enums.UserType; @@ -160,7 +164,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService { flowParams.flowStatus(BusinessStatusEnum.WAITING.getStatus()).hisStatus(TaskStatusEnum.PASS.getStatus()); // 执行任务跳转,并根据返回的处理人设置下一步处理人 setHandler(taskService.skip(taskId, flowParams), flowTask, wfCopyList); - // 更新实例状态为待审核状态 iFlwInstanceService.updateStatus(ins.getId(), BusinessStatusEnum.WAITING.getStatus()); return true; @@ -196,7 +199,9 @@ public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService { } } // 批量删除现有任务的办理人记录 - userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + if (CollUtil.isNotEmpty(flowTasks)) { + userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + } // 确保要保存的 userList 不为空 if (CollUtil.isNotEmpty(userList)) { userService.saveBatch(userList); @@ -358,8 +363,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService { flowParams.nodeCode(bo.getNodeCode()); Instance instance = taskService.skip(taskId, flowParams); setHandler(instance, flowTasks.get(0), null); - flowProcessEventHandler.processHandler(definition.getFlowCode(), - instance.getBusinessId(), BusinessStatusEnum.BACK.getStatus(), false); return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -398,18 +401,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService { @Transactional(rollbackFor = Exception.class) public boolean terminationTask(FlowTerminationBo bo) { try { - FlowTask flowTask = flowTaskMapper.selectById(bo.getTaskId()); - Instance ins = insService.getById(flowTask.getInstanceId()); //流程定义 - Definition definition = defService.getById(flowTask.getDefinitionId()); FlowParams flowParams = new FlowParams(); flowParams.message(bo.getComment()); flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); taskService.termination(bo.getTaskId(), flowParams); - //流程终止监听 - flowProcessEventHandler.processHandler(definition.getFlowCode(), - ins.getBusinessId(), BusinessStatusEnum.TERMINATION.getStatus(), false); return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -452,4 +449,142 @@ public class FlwTaskServiceImpl implements IFlwTaskService, AssigneeService { return WorkflowUtils.getHandlerUser(userList); } + /** + * 按照任务id查询任务 + * + * @param taskIdList 任务id + */ + @Override + public List selectByIdList(List taskIdList) { + return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) + .in(FlowTask::getId, taskIdList)); + } + + /** + * 按照任务id查询任务 + * + * @param taskId 任务id + */ + @Override + public FlowTask selectByIdList(Long taskId) { + return flowTaskMapper.selectOne(new LambdaQueryWrapper<>(FlowTask.class) + .eq(FlowTask::getId, taskId)); + } + + /** + * 按照实例id查询任务 + * + * @param instanceIdList 流程实例id + */ + @Override + public List selectByInstIdList(List instanceIdList) { + return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) + .in(FlowTask::getInstanceId, instanceIdList)); + } + + /** + * 按照实例id查询任务 + * + * @param instanceId 流程实例id + */ + @Override + public List selectByInstId(Long instanceId) { + return flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) + .eq(FlowTask::getInstanceId, instanceId)); + } + + /** + * 任务操作 + * + * @param bo 参数 + * @param taskOperation 操作类型,区分委派、转办、加签、减签、修改办理人 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean taskOperation(TaskOperationBo bo, String taskOperation) { + FlowParams flowParams = new FlowParams(); + flowParams.message(bo.getMessage()); + + // 根据操作类型构建 FlowParams + switch (taskOperation) { + case "delegateTask", "transferTask", "addSignature" -> { + ValidatorUtils.validate(bo, AddGroup.class); + flowParams.addHandlers(bo.getUserIdentifiers()); + } + case "reductionSignature" -> { + ValidatorUtils.validate(bo, EditGroup.class); + flowParams.reductionHandlers(bo.getAllUserIdentifiers()); + } + default -> { + log.error("Invalid operation type:{} ", taskOperation); + throw new ServiceException("Invalid operation type " + taskOperation); + } + } + + Long taskId = bo.getTaskId(); + // 设置任务状态并执行对应的任务操作 + switch (taskOperation) { + //委派任务 + case "delegateTask" -> { + flowParams.hisStatus(TaskStatusEnum.DEPUTE.getStatus()); + return taskService.depute(taskId, flowParams); + } + //转办任务 + case "transferTask" -> { + flowParams.hisStatus(TaskStatusEnum.TRANSFER.getStatus()); + return taskService.transfer(taskId, flowParams); + } + //加签,增加办理人 + case "addSignature" -> { + flowParams.hisStatus(TaskStatusEnum.SIGN.getStatus()); + return taskService.addSignature(taskId, flowParams); + } + //减签,减少办理人 + case "reductionSignature" -> { + flowParams.hisStatus(TaskStatusEnum.SIGN_OFF.getStatus()); + return taskService.reductionSignature(taskId, flowParams); + } + default -> { + log.error("Invalid operation type:{} ", taskOperation); + throw new ServiceException("Invalid operation type " + taskOperation); + } + } + } + + /** + * 修改任务办理人(此方法将会批量修改所有任务的办理人) + * + * @param taskIdList 任务id + * @param userId 用户id + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateAssignee(List taskIdList, String userId) { + if (CollUtil.isEmpty(taskIdList)) { + return false; + } + try { + List flowTasks = selectByIdList(taskIdList); + // 批量删除现有任务的办理人记录 + if (CollUtil.isNotEmpty(flowTasks)) { + userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + } + List userList = flowTasks.stream() + .map(flowTask -> { + FlowUser flowUser = new FlowUser(); + flowUser.setType(UserType.APPROVAL.getKey()); + flowUser.setProcessedBy(userId); + flowUser.setAssociated(flowTask.getId()); + return flowUser; + }) + .collect(Collectors.toList()); + if (CollUtil.isNotEmpty(userList)) { + userService.saveBatch(userList); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); + } + return true; + } } diff --git a/script/bpmn/leaveFlow-serial1.xml b/script/bpmn/leaveFlow-serial1.xml index 5f51196ac..e4e16e8a4 100644 --- a/script/bpmn/leaveFlow-serial1.xml +++ b/script/bpmn/leaveFlow-serial1.xml @@ -28,7 +28,7 @@ 5 2 -