From 0e96074dacb8983c3dd89db51742fb62828647f1 Mon Sep 17 00:00:00 2001 From: gssong <1742057357@qq.com> Date: Sun, 15 Dec 2024 14:11:01 +0800 Subject: [PATCH] =?UTF-8?q?update=20=E8=B0=83=E6=95=B4=E5=B9=B6=E8=A1=8C?= =?UTF-8?q?=E7=8E=AF=E8=8A=82=E6=92=A4=E9=94=80=E9=94=99=E8=AF=AF=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8A=9E=E7=90=86=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/enums/BusinessStatusEnum.java | 79 +++++++++++++++++++ .../service/impl/FlwInstanceServiceImpl.java | 55 +++++++++---- .../service/impl/FlwTaskServiceImpl.java | 38 ++++++--- .../impl/WfTaskAssigneeServiceImpl.java | 1 - .../dromara/workflow/utils/WorkflowUtils.java | 4 +- 5 files changed, 148 insertions(+), 29 deletions(-) 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 2053bea47..b941760ca 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 @@ -3,6 +3,7 @@ package org.dromara.common.core.enums; import cn.hutool.core.util.StrUtil; import lombok.AllArgsConstructor; import lombok.Getter; +import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.utils.StringUtils; import java.util.ArrayList; @@ -141,4 +142,82 @@ public enum BusinessStatusEnum { return list; } + /** + * 启动流程校验 + * + * @param status 状态 + */ + public static void checkStartStatus(String status) { + if (WAITING.getStatus().equals(status)) { + throw new ServiceException("该单据已提交过申请,正在审批中!"); + } else if (FINISH.getStatus().equals(status)) { + throw new ServiceException("该单据已完成申请!"); + } else if (INVALID.getStatus().equals(status)) { + throw new ServiceException("该单据已作废!"); + } else if (TERMINATION.getStatus().equals(status)) { + throw new ServiceException("该单据已终止!"); + } else if (StringUtils.isBlank(status)) { + throw new ServiceException("流程状态为空!"); + } + } + + /** + * 撤销流程校验 + * + * @param status 状态 + */ + public static void checkCancelStatus(String status) { + if (CANCEL.getStatus().equals(status)) { + throw new ServiceException("该单据已撤销!"); + } else if (FINISH.getStatus().equals(status)) { + throw new ServiceException("该单据已完成申请!"); + } else if (INVALID.getStatus().equals(status)) { + throw new ServiceException("该单据已作废!"); + } else if (TERMINATION.getStatus().equals(status)) { + throw new ServiceException("该单据已终止!"); + } else if (BACK.getStatus().equals(status)) { + throw new ServiceException("该单据已退回!"); + } else if (StringUtils.isBlank(status)) { + throw new ServiceException("流程状态为空!"); + } + } + + /** + * 驳回流程校验 + * + * @param status 状态 + */ + public static void checkBackStatus(String status) { + if (BACK.getStatus().equals(status)) { + throw new ServiceException("该单据已退回!"); + } else if (FINISH.getStatus().equals(status)) { + throw new ServiceException("该单据已完成申请!"); + } else if (INVALID.getStatus().equals(status)) { + throw new ServiceException("该单据已作废!"); + } else if (TERMINATION.getStatus().equals(status)) { + throw new ServiceException("该单据已终止!"); + } else if (CANCEL.getStatus().equals(status)) { + throw new ServiceException("该单据已撤销!"); + } else if (StringUtils.isBlank(status)) { + throw new ServiceException("流程状态为空!"); + } + } + + /** + * 作废,终止流程校验 + * + * @param status 状态 + */ + public static void checkInvalidStatus(String status) { + if (FINISH.getStatus().equals(status)) { + throw new ServiceException("该单据已完成申请!"); + } else if (INVALID.getStatus().equals(status)) { + throw new ServiceException("该单据已作废!"); + } else if (TERMINATION.getStatus().equals(status)) { + throw new ServiceException("该单据已终止!"); + } else if (StringUtils.isBlank(status)) { + throw new ServiceException("流程状态为空!"); + } + } + } 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 8095defeb..9a02d164b 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 @@ -20,22 +20,20 @@ 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.entity.*; import org.dromara.warm.flow.core.enums.NodeType; import org.dromara.warm.flow.core.enums.SkipType; +import org.dromara.warm.flow.core.enums.UserType; import org.dromara.warm.flow.core.service.DefService; import org.dromara.warm.flow.core.service.InsService; import org.dromara.warm.flow.core.service.NodeService; import org.dromara.warm.flow.core.service.TaskService; import org.dromara.warm.flow.core.utils.AssertUtil; import org.dromara.warm.flow.orm.entity.*; -import org.dromara.warm.flow.orm.mapper.FlowDefinitionMapper; import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper; import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper; import org.dromara.warm.flow.orm.mapper.FlowNodeMapper; +import org.dromara.warm.flow.orm.mapper.FlowTaskMapper; import org.dromara.workflow.common.enums.TaskStatusEnum; import org.dromara.workflow.domain.bo.FlowCancelBo; import org.dromara.workflow.domain.bo.FlowInstanceBo; @@ -46,6 +44,7 @@ import org.dromara.workflow.domain.vo.VariableVo; import org.dromara.workflow.mapper.FlwInstanceMapper; import org.dromara.workflow.service.IFlwInstanceService; import org.dromara.workflow.service.IFlwTaskService; +import org.dromara.workflow.utils.WorkflowUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -65,9 +64,9 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { private final InsService insService; private final DefService defService; private final FlowHisTaskMapper flowHisTaskMapper; + private final FlowTaskMapper flowTaskMapper; private final FlowInstanceMapper flowInstanceMapper; private final FlwInstanceMapper flwInstanceMapper; - private final FlowDefinitionMapper flowDefinitionMapper; private final TaskService taskService; private final FlowNodeMapper flowNodeMapper; private final NodeService nodeService; @@ -198,21 +197,44 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { if (definition == null) { throw new ServiceException(ExceptionCons.NOT_FOUNT_DEF); } + BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus()); 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); Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null); AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE); Node nextNode = nodeService.getNextNode(definition.getId(), startNode.getNodeCode(), null, SkipType.NONE.getKey()); - 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()); - flowParams.ignore(true); - taskService.skip(list.get(0).getId(), flowParams); + for (Task task : list) { + 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()); + flowParams.ignore(true); + taskService.skip(task.getId(), flowParams); + } + //判断申请人节点是否有多个,只保留一个 + List currentTaskList = taskService.list(FlowFactory.newTask().setInstanceId(instance.getId())); + if (CollUtil.isNotEmpty(currentTaskList)) { + Task task = currentTaskList.get(0); + if (currentTaskList.size() > 1) { + currentTaskList.remove(0); + List taskIds = StreamUtils.toList(currentTaskList, Task::getId); + WorkflowUtils.userService.deleteByTaskIds(taskIds); + flowTaskMapper.deleteByIds(taskIds); + } + //如果为空增加一个申请人 + List userList = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(task.getId())); + if (CollUtil.isEmpty(userList)) { + FlowUser flowUser = new FlowUser(); + flowUser.setAssociated(task.getId()); + flowUser.setProcessedBy(LoginHelper.getUserIdStr()); + flowUser.setType(UserType.APPROVAL.getKey()); + WorkflowUtils.userService.save(flowUser); + } + } + } catch (Exception e) { log.error("撤销失败: {}", e.getMessage(), e); throw new ServiceException(e.getMessage()); @@ -257,6 +279,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { for (FlowHisTaskVo flowHisTaskVo : flowHisTaskVos) { flowHisTaskVo.setFlowStatus(TaskStatusEnum.WAITING.getStatus()); flowHisTaskVo.setUpdateTime(null); + flowHisTaskVo.setRunDuration(null); List allUser = flwTaskService.currentTaskAllUser(flowHisTaskVo.getId()); if (CollUtil.isNotEmpty(allUser)) { String join = StreamUtils.join(allUser, e -> String.valueOf(e.getUserId())); @@ -390,6 +413,10 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService { @Transactional(rollbackFor = Exception.class) public boolean processInvalid(FlowInvalidBo bo) { try { + Instance instance = insService.getById(bo.getId()); + if (instance != null) { + BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); + } List flowTaskList = flwTaskService.selectByInstId(bo.getId()); for (FlowTask flowTask : flowTaskList) { FlowParams flowParams = new FlowParams(); 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 aaf5bf4da..f63c87bad 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 @@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.dto.UserDTO; import org.dromara.common.core.enums.BusinessStatusEnum; import org.dromara.common.core.exception.ServiceException; +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; @@ -75,7 +76,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService { private final HisTaskService hisTaskService; private final IdentifierGenerator identifierGenerator; private final NodeService nodeService; - private final org.dromara.common.core.service.UserService sysUserService = SpringUtils.getBean(org.dromara.common.core.service.UserService.class); /** * 启动任务 @@ -98,6 +98,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { FlowInstance flowInstance = flowInstanceMapper.selectOne(new LambdaQueryWrapper<>(FlowInstance.class) .eq(FlowInstance::getBusinessId, businessKey)); if (flowInstance != null) { + BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus()); List taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId())); return Map.of(PROCESS_INSTANCE_ID, taskList.get(0).getInstanceId(), TASK_ID, taskList.get(0).getId()); } @@ -152,7 +153,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { flowParams.hisTaskExt(completeTaskBo.getFileId()); // 执行任务跳转,并根据返回的处理人设置下一步处理人 setHandler(taskService.skip(taskId, flowParams), flowTask, wfCopyList); - //消息通知 + // 消息通知 WorkflowUtils.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice); return true; } catch (Exception e) { @@ -180,18 +181,18 @@ public class FlwTaskServiceImpl implements IFlwTaskService { // 遍历任务列表,处理每个任务的办理人 for (FlowTask flowTask : flowTasks) { // 获取与当前任务关联的用户列表 - List associatedUsers = userService.getByAssociateds(Collections.singletonList(flowTask.getId())); + List associatedUsers = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(flowTask.getId())); if (CollUtil.isNotEmpty(associatedUsers)) { userList.addAll(WorkflowUtils.buildUser(associatedUsers, flowTask.getId())); } } // 批量删除现有任务的办理人记录 if (CollUtil.isNotEmpty(flowTasks)) { - userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + WorkflowUtils.userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); } // 确保要保存的 userList 不为空 if (CollUtil.isNotEmpty(userList)) { - userService.saveBatch(userList); + WorkflowUtils.userService.saveBatch(userList); } } @@ -232,7 +233,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { return flowUser; }).collect(Collectors.toList()); // 批量保存抄送人员 - userService.saveBatch(userList); + WorkflowUtils.userService.saveBatch(userList); } /** @@ -350,6 +351,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (CollUtil.isEmpty(flowTasks)) { throw new ServiceException("任务不存在!"); } + Instance inst = insService.getById(flowTasks.get(0).getInstanceId()); + BusinessStatusEnum.checkBackStatus(inst.getFlowStatus()); Long definitionId = flowTasks.get(0).getDefinitionId(); Definition definition = defService.getById(definitionId); List flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<>(FlowSkip.class).eq(FlowSkip::getDefinitionId, definitionId)); @@ -415,11 +418,20 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Transactional(rollbackFor = Exception.class) public boolean terminationTask(FlowTerminationBo bo) { try { + Long taskId = bo.getTaskId(); + Task task = taskService.getById(taskId); + if (task == null) { + throw new ServiceException("任务不存在!"); + } + Instance instance = insService.getById(task.getInstanceId()); + if (instance != null) { + BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); + } FlowParams flowParams = new FlowParams(); flowParams.message(bo.getComment()); flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); - taskService.termination(bo.getTaskId(), flowParams); + taskService.termination(taskId, flowParams); return true; } catch (Exception e) { log.error(e.getMessage(), e); @@ -598,7 +610,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { List flowTasks = selectByIdList(taskIdList); // 批量删除现有任务的办理人记录 if (CollUtil.isNotEmpty(flowTasks)) { - userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + WorkflowUtils.userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); List userList = flowTasks.stream() .map(flowTask -> { FlowUser flowUser = new FlowUser(); @@ -609,7 +621,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { }) .collect(Collectors.toList()); if (CollUtil.isNotEmpty(userList)) { - userService.saveBatch(userList); + WorkflowUtils.userService.saveBatch(userList); } } } catch (Exception e) { @@ -628,12 +640,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { public Map> currentTaskAllUser(List taskIdList) { Map> map = new HashMap<>(); // 获取与当前任务关联的用户列表 - List associatedUsers = userService.getByAssociateds(taskIdList); + List associatedUsers = WorkflowUtils.userService.getByAssociateds(taskIdList); Map> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated); for (Map.Entry> entry : listMap.entrySet()) { List value = entry.getValue(); if (CollUtil.isNotEmpty(value)) { - List userDTOS = sysUserService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy()))); + List userDTOS = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy()))); map.put(entry.getKey(), userDTOS); } } @@ -648,10 +660,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override public List currentTaskAllUser(Long taskId) { // 获取与当前任务关联的用户列表 - List userList = userService.getByAssociateds(Collections.singletonList(taskId)); + List userList = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(taskId)); if (CollUtil.isEmpty(userList)) { return Collections.emptyList(); } - return sysUserService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy()))); + return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy()))); } } diff --git a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java index 68c3660ae..77b82ebd0 100644 --- a/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java +++ b/ruoyi-modules/ruoyi-workflow/src/main/java/org/dromara/workflow/service/impl/WfTaskAssigneeServiceImpl.java @@ -151,7 +151,6 @@ public class WfTaskAssigneeServiceImpl implements IWfTaskAssigneeService, Handle case ROLE -> userService.selectUsersByRoleIds(ids); case DEPT -> userService.selectUsersByDeptIds(ids); case POST -> userService.selectUsersByPostIds(ids); - default -> Collections.emptyList(); }; } 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 0c5a0ad90..fa92c0259 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 @@ -13,6 +13,7 @@ import org.dromara.common.sse.dto.SseMessageDto; import org.dromara.common.sse.utils.SseMessageUtils; import org.dromara.warm.flow.core.entity.Task; import org.dromara.warm.flow.core.entity.User; +import org.dromara.warm.flow.core.service.UserService; import org.dromara.warm.flow.orm.entity.FlowTask; import org.dromara.warm.flow.orm.entity.FlowUser; import org.dromara.workflow.common.enums.MessageTypeEnum; @@ -31,6 +32,7 @@ import java.util.*; public class WorkflowUtils { public static final IWfTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IWfTaskAssigneeService.class); public static final IFlwTaskService iFlwTaskService = SpringUtils.getBean(IFlwTaskService.class); + public static final UserService userService = SpringUtils.getBean(UserService.class); /** * 构建工作流用户 @@ -77,7 +79,7 @@ public class WorkflowUtils { List userList = new ArrayList<>(); List list = iFlwTaskService.selectByInstId(instId); if (StringUtils.isBlank(message)) { - message = "有新的【" + flowName + "】单据已经提交至您的待办,请您及时处理。"; + message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。"; } for (Task task : list) { List users = iFlwTaskService.currentTaskAllUser(task.getId());