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 5186bffea..ca28737c9 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 @@ -5,8 +5,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; -import com.baomidou.lock.annotation.Lock4j; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; @@ -31,7 +29,6 @@ import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.warm.flow.core.FlowEngine; import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.entity.*; -import org.dromara.warm.flow.core.enums.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; @@ -63,6 +60,7 @@ import org.dromara.workflow.service.IFlwTaskService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.util.*; import static org.dromara.workflow.common.constant.FlowConstant.*; @@ -103,7 +101,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService { */ @Override @Transactional(rollbackFor = Exception.class) - @Lock4j(keys = {"#startProcessBo.flowCode + #startProcessBo.businessId"}) public StartProcessReturnDTO startWorkFlow(StartProcessBo startProcessBo) { String businessId = startProcessBo.getBusinessId(); if (StringUtils.isBlank(businessId)) { @@ -140,9 +137,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService { // 将流程定义内的扩展参数设置到变量中 Definition definition = FlowEngine.defService().getPublishByFlowCode(startProcessBo.getFlowCode()); - if (ObjectUtil.isNull(definition)) { - throw new ServiceException("流程【" + startProcessBo.getFlowCode() + "】未发布,请先在流程设计器中发布流程定义"); - } Dict dict = JsonUtils.parseMap(definition.getExt()); boolean autoPass = !ObjectUtil.isNull(dict) && dict.getBool(FlowConstant.AUTO_PASS); variables.put(FlowConstant.AUTO_PASS, autoPass); @@ -152,7 +146,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService { .flowCode(startProcessBo.getFlowCode()) .variable(startProcessBo.getVariables()) .flowStatus(BusinessStatusEnum.DRAFT.getStatus()); - Instance instance = insService.start(businessId, flowParams); + Instance instance; + try { + instance = insService.start(businessId, flowParams); + } catch (Exception e) { + throw new ServiceException(e.getMessage()); + } // 保存流程实例业务信息 this.buildFlowInstanceBizExt(instance, bizExt); // 申请人执行流程 @@ -198,49 +197,53 @@ public class FlwTaskServiceImpl implements IFlwTaskService { */ @Override @Transactional(rollbackFor = Exception.class) - @Lock4j(keys = {"#completeTaskBo.taskId"}) public boolean completeTask(CompleteTaskBo completeTaskBo) { - // 获取任务ID并查询对应的流程任务和实例信息 - Long taskId = completeTaskBo.getTaskId(); - List messageType = completeTaskBo.getMessageType(); - String notice = completeTaskBo.getNotice(); - // 获取抄送人 - List flowCopyList = completeTaskBo.getFlowCopyList(); - // 设置抄送人 - Map variables = completeTaskBo.getVariables(); - variables.put(FlowConstant.FLOW_COPY_LIST, flowCopyList); - // 消息类型 - variables.put(FlowConstant.MESSAGE_TYPE, messageType); - // 消息通知 - variables.put(FlowConstant.MESSAGE_NOTICE, notice); + try { + // 获取任务ID并查询对应的流程任务和实例信息 + Long taskId = completeTaskBo.getTaskId(); + List messageType = completeTaskBo.getMessageType(); + String notice = completeTaskBo.getNotice(); + // 获取抄送人 + List flowCopyList = completeTaskBo.getFlowCopyList(); + // 设置抄送人 + Map variables = completeTaskBo.getVariables(); + variables.put(FlowConstant.FLOW_COPY_LIST, flowCopyList); + // 消息类型 + variables.put(FlowConstant.MESSAGE_TYPE, messageType); + // 消息通知 + variables.put(FlowConstant.MESSAGE_NOTICE, notice); - FlowTask flowTask = flowTaskMapper.selectById(taskId); - if (ObjectUtil.isNull(flowTask)) { - throw new ServiceException("流程任务不存在或任务已审批!"); + FlowTask flowTask = flowTaskMapper.selectById(taskId); + if (ObjectUtil.isNull(flowTask)) { + throw new ServiceException("流程任务不存在或任务已审批!"); + } + Instance ins = insService.getById(flowTask.getInstanceId()); + // 检查流程状态是否为草稿、已撤销或已退回状态,若是则执行流程提交监听 + if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) { + variables.put(FlowConstant.SUBMIT, true); + } + // 设置弹窗处理人 + Map assigneeMap = setPopAssigneeMap(completeTaskBo.getAssigneeMap(), ins.getVariableMap()); + if (CollUtil.isNotEmpty(assigneeMap)) { + variables.putAll(assigneeMap); + } + // 构建流程参数,包括变量、跳转类型、消息、处理人、权限等信息 + FlowParams flowParams = FlowParams.build() + .handler(completeTaskBo.getHandler()) + .variable(variables) + .skipType(SkipType.PASS.getKey()) + .message(completeTaskBo.getMessage()) + .flowStatus(BusinessStatusEnum.WAITING.getStatus()) + .hisStatus(TaskStatusEnum.PASS.getStatus()) + .hisTaskExt(completeTaskBo.getFileId()); + Boolean autoPass = Convert.toBool(variables.getOrDefault(AUTO_PASS, false)); + skipTask(taskId, flowParams, flowTask.getInstanceId(), autoPass); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); } - Instance ins = insService.getById(flowTask.getInstanceId()); - // 检查流程状态是否为草稿、已撤销或已退回状态,若是则执行流程提交监听 - if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) { - variables.put(FlowConstant.SUBMIT, true); - } - // 设置弹窗处理人 - Map assigneeMap = setPopAssigneeMap(completeTaskBo.getAssigneeMap(), ins.getVariableMap()); - if (CollUtil.isNotEmpty(assigneeMap)) { - variables.putAll(assigneeMap); - } - // 构建流程参数,包括变量、跳转类型、消息、处理人、权限等信息 - FlowParams flowParams = FlowParams.build() - .handler(completeTaskBo.getHandler()) - .variable(variables) - .skipType(SkipType.PASS.getKey()) - .message(completeTaskBo.getMessage()) - .flowStatus(BusinessStatusEnum.WAITING.getStatus()) - .hisStatus(TaskStatusEnum.PASS.getStatus()) - .hisTaskExt(completeTaskBo.getFileId()); - Boolean autoPass = Convert.toBool(variables.getOrDefault(AUTO_PASS, false)); - skipTask(taskId, flowParams, flowTask.getInstanceId(), autoPass); - return true; } /** @@ -302,12 +305,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService { List variableUserIds = Arrays.asList(userIds.split(StringUtils.SEPARATOR)); hashSet.addAll(popUserIds); hashSet.addAll(variableUserIds); - map.put(TaskStatusEnum.PASS.getStatus() + StrUtil.COLON + entry.getKey(), StringUtils.joinComma(hashSet)); - map.put(TaskStatusEnum.BACK.getStatus() + StrUtil.COLON + entry.getKey(), StringUtils.joinComma(hashSet)); + map.put(entry.getKey(), StringUtils.joinComma(hashSet)); } } else { - map.put(TaskStatusEnum.PASS.getStatus() + StrUtil.COLON + entry.getKey(), entry.getValue()); - map.put(TaskStatusEnum.BACK.getStatus() + StrUtil.COLON + entry.getKey(), entry.getValue()); + map.put(entry.getKey(), entry.getValue()); } } return map; @@ -446,19 +447,15 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } private QueryWrapper buildQueryWrapper(FlowTaskBo flowTaskBo) { - Map params = flowTaskBo.getParams(); QueryWrapper wrapper = Wrappers.query(); wrapper.like(StringUtils.isNotBlank(flowTaskBo.getNodeName()), "t.node_name", flowTaskBo.getNodeName()); wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowName()), "t.flow_name", flowTaskBo.getFlowName()); wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowCode()), "t.flow_code", flowTaskBo.getFlowCode()); - wrapper.like(StringUtils.isNotBlank(flowTaskBo.getFlowStatus()), "t.flow_status", flowTaskBo.getFlowStatus()); wrapper.in(CollUtil.isNotEmpty(flowTaskBo.getCreateByIds()), "t.create_by", flowTaskBo.getCreateByIds()); if (StringUtils.isNotBlank(flowTaskBo.getCategory())) { List categoryIds = flwCategoryMapper.selectCategoryIdsByParentId(Convert.toLong(flowTaskBo.getCategory())); wrapper.in("t.category", StreamUtils.toList(categoryIds, Convert::toStr)); } - wrapper.between(params.get("beginTime") != null && params.get("endTime") != null, - "t.create_time", params.get("beginTime"), params.get("endTime")); wrapper.orderByDesc("t.create_time").orderByDesc("t.update_time"); return wrapper; } @@ -471,35 +468,40 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override @Transactional(rollbackFor = Exception.class) public boolean backProcess(BackProcessBo bo) { - Long taskId = bo.getTaskId(); - String notice = bo.getNotice(); - List messageType = bo.getMessageType(); - String message = bo.getMessage(); - FlowTask task = flowTaskMapper.selectById(taskId); - if (ObjectUtil.isNull(task)) { - throw new ServiceException("任务不存在!"); + try { + Long taskId = bo.getTaskId(); + String notice = bo.getNotice(); + List messageType = bo.getMessageType(); + String message = bo.getMessage(); + FlowTask task = flowTaskMapper.selectById(taskId); + if (ObjectUtil.isNull(task)) { + throw new ServiceException("任务不存在!"); + } + Instance inst = insService.getById(task.getInstanceId()); + BusinessStatusEnum.checkBackStatus(inst.getFlowStatus()); + Long definitionId = task.getDefinitionId(); + String applyNodeCode = flwCommonService.applyNodeCode(definitionId); + + Map variable = new HashMap<>(); + // 消息类型 + variable.put(FlowConstant.MESSAGE_TYPE, messageType); + // 消息通知 + variable.put(FlowConstant.MESSAGE_NOTICE, notice); + + FlowParams flowParams = FlowParams.build() + .nodeCode(bo.getNodeCode()) + .variable(variable) + .message(message) + .skipType(SkipType.REJECT.getKey()) + .flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus()) + .hisStatus(TaskStatusEnum.BACK.getStatus()) + .hisTaskExt(bo.getFileId()); + taskService.skip(task.getId(), flowParams); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); } - Instance inst = insService.getById(task.getInstanceId()); - BusinessStatusEnum.checkBackStatus(inst.getFlowStatus()); - Long definitionId = task.getDefinitionId(); - String applyNodeCode = flwCommonService.applyNodeCode(definitionId); - - Map variable = new HashMap<>(); - // 消息类型 - variable.put(FlowConstant.MESSAGE_TYPE, messageType); - // 消息通知 - variable.put(FlowConstant.MESSAGE_NOTICE, notice); - - FlowParams flowParams = FlowParams.build() - .nodeCode(bo.getNodeCode()) - .variable(variable) - .message(message) - .skipType(SkipType.REJECT.getKey()) - .flowStatus(applyNodeCode.equals(bo.getNodeCode()) ? TaskStatusEnum.BACK.getStatus() : TaskStatusEnum.WAITING.getStatus()) - .hisStatus(TaskStatusEnum.BACK.getStatus()) - .hisTaskExt(bo.getFileId()); - taskService.skip(task.getId(), flowParams); - return true; } /** @@ -527,20 +529,19 @@ public class FlwTaskServiceImpl implements IFlwTaskService { } //获取可驳回的前置节点 List nodes = nodeService.previousNodeList(task.getDefinitionId(), nowNodeCode); - List taskList = hisTaskService.getByInsId(task.getInstanceId()); - + List hisTaskList = hisTaskService.getByInsId(task.getInstanceId()); Map nodeMap = StreamUtils.toIdentityMap(nodes, Node::getNodeCode); + Set added = new HashSet<>(); List backNodeList = new ArrayList<>(); - for (HisTask hisTask : taskList) { + for (HisTask hisTask : hisTaskList) { Node nodeValue = nodeMap.get(hisTask.getNodeCode()); - if (nodeValue != null) { + if (nodeValue != null && NodeType.BETWEEN.getKey().equals(nodeValue.getNodeType()) && added.add(nodeValue.getNodeCode())) { backNodeList.add(nodeValue); } } if (CollUtil.isNotEmpty(backNodeList)) { - List prefixOrSuffixNodes = StreamUtils.filter(backNodeList, e -> NodeType.BETWEEN.getKey().equals(e.getNodeType())); - Collections.reverse(prefixOrSuffixNodes); - return prefixOrSuffixNodes; + Collections.reverse(backNodeList); + return backNodeList; } return nodes; } @@ -553,21 +554,26 @@ public class FlwTaskServiceImpl implements IFlwTaskService { @Override @Transactional(rollbackFor = Exception.class) public boolean terminationTask(FlowTerminationBo bo) { - Long taskId = bo.getTaskId(); - Task task = taskService.getById(taskId); - if (task == null) { - throw new ServiceException("任务不存在!"); + try { + Long taskId = bo.getTaskId(); + Task task = taskService.getById(taskId); + if (task == null) { + throw new ServiceException("任务不存在!"); + } + Instance instance = insService.getById(task.getInstanceId()); + if (ObjectUtil.isNotNull(instance)) { + BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); + } + FlowParams flowParams = FlowParams.build() + .message(bo.getComment()) + .flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) + .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); + taskService.termination(taskId, flowParams); + return true; + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); } - Instance instance = insService.getById(task.getInstanceId()); - if (ObjectUtil.isNotNull(instance)) { - BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus()); - } - FlowParams flowParams = FlowParams.build() - .message(bo.getComment()) - .flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) - .hisStatus(TaskStatusEnum.TERMINATION.getStatus()); - taskService.termination(taskId, flowParams); - return true; } /** @@ -744,7 +750,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService { Task task = taskService.getById(taskId); FlowNode flowNode = getByNodeCode(task.getNodeCode(), task.getDefinitionId()); if (ADD_SIGNATURE.equals(taskOperation) || REDUCTION_SIGNATURE.equals(taskOperation)) { - if (!CooperateType.isCountersign(flowNode.getNodeRatio())) { + if (flowNode.getNodeRatio().compareTo(BigDecimal.ZERO) == 0) { throw new ServiceException(task.getNodeName() + "不是会签节点!"); } } @@ -789,18 +795,23 @@ public class FlwTaskServiceImpl implements IFlwTaskService { if (CollUtil.isEmpty(taskIdList)) { return false; } - List flowTasks = this.selectByIdList(taskIdList); - // 批量删除现有任务的办理人记录 - if (CollUtil.isNotEmpty(flowTasks)) { - FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); - List userList = StreamUtils.toList(flowTasks, flowTask -> - new FlowUser() - .setType(TaskAssigneeType.APPROVER.getCode()) - .setProcessedBy(userId) - .setAssociated(flowTask.getId())); - if (CollUtil.isNotEmpty(userList)) { - FlowEngine.userService().saveBatch(userList); + try { + List flowTasks = this.selectByIdList(taskIdList); + // 批量删除现有任务的办理人记录 + if (CollUtil.isNotEmpty(flowTasks)) { + FlowEngine.userService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); + List userList = StreamUtils.toList(flowTasks, flowTask -> + new FlowUser() + .setType(TaskAssigneeType.APPROVER.getCode()) + .setProcessedBy(userId) + .setAssociated(flowTask.getId())); + if (CollUtil.isNotEmpty(userList)) { + FlowEngine.userService().saveBatch(userList); + } } + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); } return true; } @@ -840,16 +851,21 @@ public class FlwTaskServiceImpl implements IFlwTaskService { */ @Override public boolean urgeTask(FlowUrgeTaskBo bo) { - if (CollUtil.isEmpty(bo.getTaskIdList())) { - return false; + try { + if (CollUtil.isEmpty(bo.getTaskIdList())) { + return false; + } + List userList = this.currentTaskAllUser(bo.getTaskIdList()); + if (CollUtil.isEmpty(userList)) { + return false; + } + List messageType = bo.getMessageType(); + String message = bo.getMessage(); + flwCommonService.sendMessage(messageType, message, "单据审批提醒", userList); + } catch (Exception e) { + log.error(e.getMessage(), e); + throw new ServiceException(e.getMessage()); } - List userList = this.currentTaskAllUser(bo.getTaskIdList()); - if (CollUtil.isEmpty(userList)) { - return false; - } - List messageType = bo.getMessageType(); - String message = bo.getMessage(); - flwCommonService.sendMessage(messageType, message, "单据审批提醒", userList); return true; } }