From 0c77f34dfb569ce745da071dd95ba714b322605b Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Sun, 23 Feb 2025 23:02:28 +0800 Subject: [PATCH 1/9] =?UTF-8?q?REQ-3626=20=E5=A2=9E=E5=8A=A0=E5=9B=9E?= =?UTF-8?q?=E9=80=80=E8=87=B3=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E9=80=9A?= =?UTF-8?q?=E7=94=A8=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/feign/bpmn/ProcessTaskApi.java | 9 ++ .../task/BpmnNodeBackSystemOperateDTO.java | 61 +++++++++ .../core/engine/cmd/CustomBackTaskCmd.java | 126 ++++++++++-------- .../engine/job/AsyncBackTaskJobHandler.java | 12 +- .../core/service/BpmnProcessTaskService.java | 12 +- .../impl/BpmnProcessTaskServiceImpl.java | 87 +++++++++--- .../web/bpmn/BpmnProcessTaskController.java | 13 ++ 7 files changed, 248 insertions(+), 72 deletions(-) create mode 100644 workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java index 52f72bb6e..485815d6b 100644 --- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java +++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java @@ -89,6 +89,15 @@ public interface ProcessTaskApi { @PostMapping("/api/process/task/back") CommonResponse backTask(@Validated @RequestBody BpmnTaskBackAuditDTO dto); + /** + * 用于系统内部操作,跳转到指定节点 + * @param dto 请求参数 + * @return 是否成功 + */ + @Operation(summary = "系统操作回退任务到指定节点") + @PostMapping("/system/back") + CommonResponse systemBackTask(@Validated @RequestBody BpmnNodeBackSystemOperateDTO dto); + /** * 驳回 * diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java new file mode 100644 index 000000000..4f800e7c4 --- /dev/null +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java @@ -0,0 +1,61 @@ +package cn.axzo.workflow.common.model.request.bpmn.task; + +import cn.axzo.workflow.common.constraint.AttachmentTypeValidator; +import cn.axzo.workflow.common.constraint.AttachmentValidator; +import cn.axzo.workflow.common.enums.AttachmentTypeEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.List; + +/** + * 审批节点退回模型 + * + */ +@ApiModel("审批节点退回模型") +@Data +@Accessors(chain = true) +@AllArgsConstructor +@NoArgsConstructor +public class BpmnNodeBackSystemOperateDTO implements Serializable { + + private static final long serialVersionUID = -4160538355403179298L; + + @ApiModelProperty(value = "流程实例id", required = true) + @NotBlank(message = "流程实例id不能为空") + private String processInstanceId; + + @ApiModelProperty(value = "当前流程节点id", required = true) + @NotBlank(message = "当前节点id不能为空") + private String currentActivityId; + + @ApiModelProperty(value = "目标流程节点id", required = true) + @NotBlank(message = "目标流程节点id不能为空") + private String toActivityId; + + @ApiModelProperty(value = "意见") + private String advice; + + @ApiModelProperty(value = "操作描述") + private String operationDesc; + + /** + * 附件列表 + */ + @ApiModelProperty(value = "附件列表") + @Size(max = 11, message = "附件数量超过限制") + @AttachmentValidator(types = { + @AttachmentTypeValidator(type = AttachmentTypeEnum.image, max = 5), + @AttachmentTypeValidator(type = AttachmentTypeEnum.file, max = 5), + @AttachmentTypeValidator(type = AttachmentTypeEnum.signature, max = 1)} + ) + private List attachmentList; + +} diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index ef456b038..f778ecf86 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -1,7 +1,8 @@ package cn.axzo.workflow.core.engine.cmd; -import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO; import cn.axzo.workflow.common.exception.WorkflowEngineException; +import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.utils.BpmnModelUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; @@ -15,26 +16,18 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.flowable.engine.impl.util.CommandContextUtil; import org.flowable.engine.impl.util.ProcessDefinitionUtil; import org.flowable.task.api.history.HistoricTaskInstance; -import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.flowable.task.service.TaskService; import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.util.StringUtils; import java.io.Serializable; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; -import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; -import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; -import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO; -import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE; -import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS; -import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment; -import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment; -import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask; +import static cn.axzo.workflow.common.constant.BpmnConstants.*; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED; +import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.*; /** * 回退命令 @@ -43,65 +36,94 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask public class CustomBackTaskCmd extends AbstractCommand implements Serializable { private static final long serialVersionUID = -1241290344311892346L; - private final BpmnTaskBackAuditDTO dto; + + private final List targetTaskIds; + private final String advice; + private final String operationDesc; + private final List attachmentList; + private final BpmnTaskDelegateAssigner approver; + private final String processInstanceId; + private final String currentActivityId; + private final String toActivityId; + private final boolean validateApprover; private static final String OPERATION_DESC = "回退至"; + public CustomBackTaskCmd(List targetTaskIds, + String advice, + String operationDesc, + List attachmentList, + BpmnTaskDelegateAssigner approver, + String processInstanceId, + String currentActivityId, + String toActivityId, + boolean validateApprover) { + this.targetTaskIds = targetTaskIds; + this.advice = advice; + this.operationDesc = operationDesc; + this.attachmentList = attachmentList; + this.approver = approver; + this.processInstanceId = processInstanceId; + this.currentActivityId = currentActivityId; + this.toActivityId = toActivityId; + this.validateApprover = validateApprover; + } + @Override public String paramToJsonString() { Map params = new HashMap<>(); - params.put("taskId", dto.getTaskId()); - params.put("advice", dto.getAdvice()); + params.put("targetTaskIds", JSON.toJSONString(this.targetTaskIds)); + params.put("advice", advice); params.put("operationDesc", OPERATION_DESC); - params.put("attachmentList", JSON.toJSONString(dto.getAttachmentList())); - params.put("approver", JSON.toJSONString(dto.getApprover())); - params.put("nodeTypes", JSON.toJSONString(dto.getNodeTypes())); + params.put("attachmentList", JSON.toJSONString(attachmentList)); + params.put("approver", JSON.toJSONString(approver)); + params.put("toActivityId", JSON.toJSONString(this.toActivityId)); + params.put("processInstanceId", JSON.toJSONString(this.processInstanceId)); + params.put("validateApprover", validateApprover); return JSON.toJSONString(params); } - public CustomBackTaskCmd(BpmnTaskBackAuditDTO dto) { - this.dto = dto; - } - @Override public Void execute(CommandContext commandContext) { ProcessEngineConfigurationImpl processEngineConfiguration = - CommandContextUtil.getProcessEngineConfiguration(commandContext); - HistoricTaskInstanceQuery taskQuery = - processEngineConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); + CommandContextUtil.getProcessEngineConfiguration(commandContext); + List taskList = processEngineConfiguration.getHistoryService() + .createHistoricTaskInstanceQuery() + .taskDefinitionId(currentActivityId) + .processInstanceId(processInstanceId) + .list(); TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); - - HistoricTaskInstance historicTaskInstance = taskQuery.taskId(dto.getTaskId()).singleResult(); - - TaskEntity task = taskService.getTask(dto.getTaskId()); - validTask(historicTaskInstance, task, dto.getApprover(), dto.getNodeTypes()); - - Process process = ProcessDefinitionUtil.getProcess(task.getProcessDefinitionId()); - FlowElement targetFlowElement = process.getFlowElement(dto.getToActivityId(), true); - if (Objects.isNull(targetFlowElement)) { - throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, dto.getToActivityId()); + if (validateApprover) { + taskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), approver, null)); } - FlowElement sourceFlowElement = process.getFlowElement(task.getTaskDefinitionKey(), true); + + String processDefinitionId = taskList.get(0).getProcessDefinitionId(); + Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); + FlowElement targetFlowElement = process.getFlowElement(toActivityId, true); + if (Objects.isNull(targetFlowElement)) { + throw new WorkflowEngineException(BACK_TARGET_ACTIVITY_NOT_EXISTS, toActivityId); + } + FlowElement sourceFlowElement = process.getFlowElement(currentActivityId, true); // 退回节点到当前节点不可达到,不允许退回 if (!BpmnModelUtils.isReachable(process, (FlowNode) targetFlowElement, (FlowNode) sourceFlowElement)) { - throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); + throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, toActivityId); } - batchAddAttachment(commandContext, task.getProcessInstanceId(), task, dto.getAttachmentList(), dto.getApprover()); - - Authentication.setAuthenticatedUserId(dto.getApprover().buildAssigneeId()); - addComment(commandContext, task, COMMENT_TYPE_ADVICE, dto.getAdvice()); - addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, OPERATION_DESC + targetFlowElement.getName()); - Authentication.setAuthenticatedUserId(null); - RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); - task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + dto.getTaskId(), BACKED.getStatus()); - + taskList.forEach(th -> { + TaskEntity task = taskService.getTask(th.getId()); + batchAddAttachment(commandContext, processInstanceId, task, attachmentList, approver); + Authentication.setAuthenticatedUserId(approver.buildAssigneeId()); + addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice); + addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, StringUtils.hasText(operationDesc) ? operationDesc : OPERATION_DESC + targetFlowElement.getName()); + Authentication.setAuthenticatedUserId(null); + task.setTransientVariable(TASK_COMPLETE_OPERATION_TYPE + task.getId(), BACKED.getStatus()); + }); // 移除回退到的指定节点的变量,让 EngineExecutionStartListener 重新计算该节点的人 - runtimeService.removeVariable(task.getProcessInstanceId(), INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + dto.getToActivityId()); + runtimeService.removeVariable(processInstanceId, INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO + toActivityId); runtimeService.createChangeActivityStateBuilder() - .processInstanceId(task.getProcessInstanceId()) - .moveActivityIdsToSingleActivityId(Collections.singletonList(task.getTaskDefinitionKey()), dto.getToActivityId()) - .changeState(); + .processInstanceId(processInstanceId) + .moveActivityIdsToSingleActivityId(Collections.singletonList(currentActivityId), toActivityId) + .changeState(); return null; } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java index ec466959c..b9bd5ae02 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java @@ -12,6 +12,7 @@ import org.flowable.job.service.impl.persistence.entity.JobEntity; import org.flowable.task.api.Task; import org.flowable.variable.api.delegate.VariableScope; +import java.util.Collections; import java.util.Objects; @Slf4j @@ -35,7 +36,16 @@ public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler i if (Objects.isNull(task)) { return; } - processEngineConfiguration.getCommandExecutor().execute(new CustomBackTaskCmd(dto)); + processEngineConfiguration.getCommandExecutor().execute(new CustomBackTaskCmd( + Collections.singletonList(dto.getTaskId()), + dto.getAdvice(), + dto.getOperationDesc(), + dto.getAttachmentList(), + dto.getApprover(), + task.getProcessInstanceId(), + task.getTaskDefinitionKey(), + dto.getToActivityId(), + true)); } } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java index 2c425cbe8..01cac8fde 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java @@ -29,11 +29,18 @@ public interface BpmnProcessTaskService { void approveTask(BpmnTaskAuditDTO taskAuditDTO); void approveTaskWithForm(BpmnTaskAuditWithFormDTO taskAuditDto); + /** * 回退 */ void backTask(BpmnTaskBackAuditDTO taskAuditDTO); + /** + * 用于系统内部回退操作 + * @param taskAuditDTO 请求参数 + */ + void systemBackTask(BpmnNodeBackSystemOperateDTO taskAuditDTO); + /** * 批量同意 * @@ -43,9 +50,10 @@ public interface BpmnProcessTaskService { /** * 回退到指定节点,可以回退节点选项 - * @param taskId 任务id + * @param processInstanceId 流程实例id + * @param currentActivityId 当前节点定义id */ - List getBackOptionalNodes(String taskId); + List getBackOptionalNodes(String processInstanceId, String currentActivityId); /** * 驳回 diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index 4b25aa2a5..b660667d8 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -5,14 +5,11 @@ import cn.axzo.workflow.common.enums.BpmnCountersignTypeEnum; import cn.axzo.workflow.common.enums.BpmnFlowNodeType; import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum; import cn.axzo.workflow.common.exception.WorkflowEngineException; -import cn.axzo.workflow.common.model.request.BpmnApproveConf; -import cn.axzo.workflow.common.model.request.bpmn.BpmnButtonConf; import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf; import cn.axzo.workflow.common.model.request.bpmn.task.*; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationItemResultVO; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; -import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO; import cn.axzo.workflow.common.model.response.bpmn.task.*; import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper; import cn.axzo.workflow.core.engine.cmd.*; @@ -20,14 +17,12 @@ import cn.axzo.workflow.core.engine.event.MessagePushEventBuilder; import cn.axzo.workflow.core.engine.event.MessagePushEventImpl; import cn.axzo.workflow.core.engine.event.MessagePushEventType; import cn.axzo.workflow.core.repository.entity.ExtAxHiTaskInst; -import cn.axzo.workflow.core.repository.entity.ExtAxProcessLog; import cn.axzo.workflow.core.service.BpmnProcessDefinitionService; import cn.axzo.workflow.core.service.BpmnProcessTaskService; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import cn.axzo.workflow.core.service.ExtAxProcessLogService; import cn.axzo.workflow.core.service.converter.*; import cn.hutool.core.collection.CollUtil; -import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; @@ -79,8 +74,6 @@ import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.*; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.countSql; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.sqlConnectors; import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet; -import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getButtonConfig; -import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getProcessApproveConf; @Service @Slf4j @@ -295,7 +288,11 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { @Override @Transactional(rollbackFor = Exception.class) public void backTask(BpmnTaskBackAuditDTO dto) { - List backOptionalNodes = getBackOptionalNodes(dto.getTaskId()); + Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(dto.getTaskId()).singleResult(); + if (task == null) { + throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS); + } + List backOptionalNodes = getBackOptionalNodes(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); if (CollectionUtils.isEmpty(backOptionalNodes)) { throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); } @@ -324,17 +321,73 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { if (Boolean.TRUE.equals(dto.getAsync())) { commandExecutor.execute(new CustomBackTaskAsyncCmd(dto)); } else { - commandExecutor.execute(new CustomBackTaskCmd(dto)); + commandExecutor.execute(new CustomBackTaskCmd(Collections.singletonList(dto.getTaskId()), + dto.getAdvice(), + dto.getOperationDesc(), + dto.getAttachmentList(), + dto.getApprover(), + task.getProcessInstanceId(), + task.getTaskDefinitionKey(), + dto.getToActivityId(), + true)); } } @Override - public List getBackOptionalNodes(String taskId) { - Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(taskId).singleResult(); - if (task == null) { - throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS); + public void systemBackTask(BpmnNodeBackSystemOperateDTO dto) { + //需要查询当前流程是否停留在当前节点 + //需要查询退回的节点是否可达 + //然后进行退回操作 + ProcessEngineConfigurationImpl pcConfiguration = CommandContextUtil.getProcessEngineConfiguration(); + HistoricTaskInstanceQuery taskQuery = pcConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); + List taskList = taskQuery.processInstanceId(dto.getProcessInstanceId()) + .taskDefinitionId(dto.getCurrentActivityId()) + .list(); + List valuableTasks; + if (CollectionUtils.isEmpty(taskList) || CollectionUtils.isEmpty((valuableTasks = taskList.stream() + .filter(t -> Objects.nonNull(t.getEndTime())) + .collect(Collectors.toList())))) { + throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE); } - String processInstanceId = task.getProcessInstanceId(); + List backOptionalNodes = getBackOptionalNodes(valuableTasks.get(0).getProcessInstanceId(), valuableTasks.get(0).getTaskDefinitionKey()); + if (CollectionUtils.isEmpty(backOptionalNodes)) { + throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); + } + List activityList = backOptionalNodes.stream().map(BpmnOptionalNodeDTO::getProcessActivityId).collect(Collectors.toList()); + if (!activityList.contains(dto.getToActivityId())) { + throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); + } + Optional instOpt = backOptionalNodes.stream() + .map(BpmnOptionalNodeDTO::getProcessInstanceId) + .filter(StringUtils::hasText) + .findAny(); + if (instOpt.isPresent()) { + ExtHiTaskSearchDTO searchDTO = new ExtHiTaskSearchDTO(); + searchDTO.setProcessInstanceId(instOpt.get()); + List extAxHiTaskInsts = extAxHiTaskInstService.queryList(searchDTO); + if (CollectionUtils.isNotEmpty(extAxHiTaskInsts)) { + long backOpeCount = extAxHiTaskInsts.stream() + .filter(ext -> BACKED.getStatus().equals(ext.getStatus())) + .count(); + if (backOpeCount > MAX_BACKED_OPERATE_COUNT) { + throw new WorkflowEngineException(REACHED_BACKED_MAXIMUM_NUM, String.valueOf(MAX_BACKED_OPERATE_COUNT)); + } + } + } + CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor(); + commandExecutor.execute(new CustomBackTaskCmd(valuableTasks.stream().map(TaskInfo::getId).collect(Collectors.toList()), + dto.getAdvice(), + dto.getOperationDesc(), + dto.getAttachmentList(), + null, + valuableTasks.get(0).getProcessInstanceId(), + dto.getToActivityId(), + dto.getCurrentActivityId(), + false)); + } + + @Override + public List getBackOptionalNodes(String processInstanceId, String currentActivityId) { //1.获取当前的流程实例 ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); if (processInstance == null) { @@ -393,7 +446,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { AtomicInteger index = new AtomicInteger(0); List resultList = valuableList .stream() - .filter(pair -> !task.getTaskDefinitionKey().equals(pair.getLeft())) //排除当前节点 + .filter(pair -> !currentActivityId.equals(pair.getLeft())) //排除当前节点 .map(pair -> flowElementMap.get(pair.getLeft())) .filter(flowElement -> { BpmnFlowNodeType currentNodeType = BpmnMetaParserHelper.getNodeType(flowElement).orElse(NODE_EMPTY); @@ -402,8 +455,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { .filter(flowElement -> !NODE_STARTER.getType().equals(flowElement.getId())) .map(flowElement -> BpmnOptionalNodeDTO .builder() - .processInstanceId(task.getProcessInstanceId()) - .processDefinitionId(task.getProcessDefinitionId()) + .processInstanceId(processInstanceId) + .processDefinitionId(processInstance.getProcessDefinitionId()) .processActivityId(flowElement.getId()) .processActivityName(flowElement.getName()) .processNodeDesc(flowElement.getName()) diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java index 6ff7fb92b..7c1781193 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java @@ -152,6 +152,19 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp return success(true); } + /** + * 回退到指定节点 + */ + @Operation(summary = "系统操作回退任务到指定节点") + @PostMapping("/system/back") + @RepeatSubmit + @Override + public CommonResponse systemBackTask(@Validated @RequestBody BpmnNodeBackSystemOperateDTO dto) { + log.info("系统回退 systemBackTask===>>>参数:{}", JSON.toJSONString(dto)); + bpmnProcessTaskService.systemBackTask(dto); + return success(true); + } + /** * 驳回 */ From 8f41522a0152eb408c9409f85852cfc7b96a8ff3 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Sun, 23 Feb 2025 23:05:42 +0800 Subject: [PATCH 2/9] =?UTF-8?q?REQ-3626=20=E4=BF=AE=E5=A4=8D=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/service/BpmnProcessTaskService.java | 6 ++++++ .../core/service/impl/BpmnProcessTaskServiceImpl.java | 9 +++++++++ .../controller/web/bpmn/BpmnProcessTaskController.java | 2 +- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java index 01cac8fde..94cbfdc4a 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/BpmnProcessTaskService.java @@ -48,6 +48,12 @@ public interface BpmnProcessTaskService { */ BatchOperationResultVO batchApproveTask(List taskAuditDTOS); + /** + * 回退到指定节点,可以回退节点选项 + * @param taskId 流程任务id + */ + List getBackOptionalNodesByTaskId(String taskId); + /** * 回退到指定节点,可以回退节点选项 * @param processInstanceId 流程实例id diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index b660667d8..07673fd9e 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -386,6 +386,15 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { false)); } + @Override + public List getBackOptionalNodesByTaskId(String taskId) { + Task task = processEngineConfiguration.getTaskService().createTaskQuery().taskId(taskId).singleResult(); + if (task == null) { + throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS); + } + return this.getBackOptionalNodes(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); + } + @Override public List getBackOptionalNodes(String processInstanceId, String currentActivityId) { //1.获取当前的流程实例 diff --git a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java index 7c1781193..4aece8c5b 100644 --- a/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java +++ b/workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/web/bpmn/BpmnProcessTaskController.java @@ -134,7 +134,7 @@ public class BpmnProcessTaskController extends BasicPopulateAvatarController imp @GetMapping("/back/optional/nodes") @Override public CommonResponse> getBackOptionalNodes(@RequestParam @NotBlank(message = "任务id不能为空") String taskId) { - List approveOptionalNodes = bpmnProcessTaskService.getBackOptionalNodes(taskId); + List approveOptionalNodes = bpmnProcessTaskService.getBackOptionalNodesByTaskId(taskId); return success(approveOptionalNodes); } From 57ae8b7cfd7d484ec9f8dc652a0b68cd184b6806 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 11:41:08 +0800 Subject: [PATCH 3/9] =?UTF-8?q?REQ-3626=20=E4=BF=AE=E5=A4=8D=E9=A9=B3?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/cmd/CustomBackTaskCmd.java | 22 +++- .../impl/BpmnProcessTaskServiceImpl.java | 117 +++++++++++++++--- 2 files changed, 113 insertions(+), 26 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index f778ecf86..ff3c343e5 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -21,13 +21,22 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.util.StringUtils; import java.io.Serializable; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS; -import static cn.axzo.workflow.common.constant.BpmnConstants.*; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO; +import static cn.axzo.workflow.common.constant.BpmnConstants.TASK_COMPLETE_OPERATION_TYPE; import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED; -import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.*; +import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.addComment; +import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.batchAddAttachment; +import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask; /** * 回退命令 @@ -89,14 +98,13 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ CommandContextUtil.getProcessEngineConfiguration(commandContext); List taskList = processEngineConfiguration.getHistoryService() .createHistoricTaskInstanceQuery() - .taskDefinitionId(currentActivityId) + .taskDefinitionKey(currentActivityId) .processInstanceId(processInstanceId) .list(); TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); if (validateApprover) { taskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), approver, null)); } - String processDefinitionId = taskList.get(0).getProcessDefinitionId(); Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); FlowElement targetFlowElement = process.getFlowElement(toActivityId, true); @@ -112,7 +120,9 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ taskList.forEach(th -> { TaskEntity task = taskService.getTask(th.getId()); batchAddAttachment(commandContext, processInstanceId, task, attachmentList, approver); - Authentication.setAuthenticatedUserId(approver.buildAssigneeId()); + if (approver != null) { + Authentication.setAuthenticatedUserId(approver.buildAssigneeId()); + } addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice); addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, StringUtils.hasText(operationDesc) ? operationDesc : OPERATION_DESC + targetFlowElement.getName()); Authentication.setAuthenticatedUserId(null); diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index 07673fd9e..a0d3cba5c 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -6,13 +6,45 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType; import cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum; import cn.axzo.workflow.common.exception.WorkflowEngineException; import cn.axzo.workflow.common.model.request.bpmn.BpmnNoticeConf; -import cn.axzo.workflow.common.model.request.bpmn.task.*; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnNodeBackSystemOperateDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnOptionalNodeDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCompleteDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnRobotTaskCreateDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAttachmentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditWithFormDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskBackAuditDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCommentDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskPageSearchDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskRemindDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO; +import cn.axzo.workflow.common.model.request.bpmn.task.ExtHiTaskSearchDTO; import cn.axzo.workflow.common.model.response.BpmPageResult; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationItemResultVO; import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO; -import cn.axzo.workflow.common.model.response.bpmn.task.*; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceGroupVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnHistoricTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskDonePageItemVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskInstanceVO; +import cn.axzo.workflow.common.model.response.bpmn.task.BpmnTaskTodoPageItemVO; import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper; -import cn.axzo.workflow.core.engine.cmd.*; +import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskWithFormAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomApproveTaskWithFormCmd; +import cn.axzo.workflow.core.engine.cmd.CustomBackTaskAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomBackTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomCommentTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomCompleteDummyTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomCountersignUserTaskAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomCountersignUserTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomCreateDummyTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomRejectionTaskAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomRejectionTaskCmd; +import cn.axzo.workflow.core.engine.cmd.CustomTransferUserTaskAsyncCmd; +import cn.axzo.workflow.core.engine.cmd.CustomTransferUserTaskCmd; import cn.axzo.workflow.core.engine.event.MessagePushEventBuilder; import cn.axzo.workflow.core.engine.event.MessagePushEventImpl; import cn.axzo.workflow.core.engine.event.MessagePushEventType; @@ -21,7 +53,11 @@ import cn.axzo.workflow.core.service.BpmnProcessDefinitionService; import cn.axzo.workflow.core.service.BpmnProcessTaskService; import cn.axzo.workflow.core.service.ExtAxHiTaskInstService; import cn.axzo.workflow.core.service.ExtAxProcessLogService; -import cn.axzo.workflow.core.service.converter.*; +import cn.axzo.workflow.core.service.converter.BpmnHistoricAttachmentConverter; +import cn.axzo.workflow.core.service.converter.BpmnHistoricTaskInstanceConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskDonePageItemConverter; +import cn.axzo.workflow.core.service.converter.BpmnTaskTodoPageItemConverter; import cn.hutool.core.collection.CollUtil; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; @@ -33,7 +69,11 @@ import org.flowable.bpmn.model.FlowElement; import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher; import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.common.engine.impl.interceptor.CommandExecutor; -import org.flowable.engine.*; +import org.flowable.engine.HistoryService; +import org.flowable.engine.ManagementService; +import org.flowable.engine.RepositoryService; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl; @@ -60,17 +100,51 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import javax.annotation.Resource; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; -import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.*; -import static cn.axzo.workflow.common.code.BpmnTaskRespCode.*; -import static cn.axzo.workflow.common.constant.BpmnConstants.*; -import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.*; -import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.*; +import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_ID_NOT_EXISTS; +import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS; +import static cn.axzo.workflow.common.code.BpmnInstanceRespCode.PROCESS_TASK_NOT_EXISTS; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.FIND_TASK_BY_PERSON_ID_ERROR; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.REACHED_BACKED_MAXIMUM_NUM; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_HAS_BEEN_COMPLETE; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_REMIND_ERROR_NOT_EXISTS; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_COMMENT_EXT; +import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT; +import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO; +import static cn.axzo.workflow.common.constant.BpmnConstants.MAX_BACKED_OPERATE_COUNT; +import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE; +import static cn.axzo.workflow.common.constant.BpmnConstants.OLD_INTERNAL_TASK_RELATION_ASSIGNEE_INFO_SNAPSHOT; +import static cn.axzo.workflow.common.constant.BpmnConstants.WORKFLOW_ENGINE_VERSION; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_BUSINESS; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_CARBON_COPY; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_EMPTY; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_STARTER; +import static cn.axzo.workflow.common.enums.BpmnFlowNodeType.NODE_TASK; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.APPROVED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.BACKED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.DELETED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.REJECTED; +import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.valueOfStatus; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.countSql; import static cn.axzo.workflow.common.util.BpmnNativeQueryUtil.sqlConnectors; import static cn.axzo.workflow.core.common.utils.BpmnCollectionUtils.convertSet; @@ -338,15 +412,18 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { //需要查询当前流程是否停留在当前节点 //需要查询退回的节点是否可达 //然后进行退回操作 - ProcessEngineConfigurationImpl pcConfiguration = CommandContextUtil.getProcessEngineConfiguration(); - HistoricTaskInstanceQuery taskQuery = pcConfiguration.getHistoryService().createHistoricTaskInstanceQuery(); - List taskList = taskQuery.processInstanceId(dto.getProcessInstanceId()) - .taskDefinitionId(dto.getCurrentActivityId()) + List taskList = processEngineConfiguration.getHistoryService() + .createHistoricTaskInstanceQuery() + .taskDefinitionKey(dto.getCurrentActivityId()) + .processInstanceId(dto.getProcessInstanceId()) .list(); - List valuableTasks; - if (CollectionUtils.isEmpty(taskList) || CollectionUtils.isEmpty((valuableTasks = taskList.stream() - .filter(t -> Objects.nonNull(t.getEndTime())) - .collect(Collectors.toList())))) { + if (CollectionUtils.isEmpty(taskList)) { + throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS); + } + List valuableTasks = taskList.stream() + .filter(t -> Objects.isNull(t.getEndTime())) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(valuableTasks)) { throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE); } List backOptionalNodes = getBackOptionalNodes(valuableTasks.get(0).getProcessInstanceId(), valuableTasks.get(0).getTaskDefinitionKey()); @@ -381,8 +458,8 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { dto.getAttachmentList(), null, valuableTasks.get(0).getProcessInstanceId(), - dto.getToActivityId(), dto.getCurrentActivityId(), + dto.getToActivityId(), false)); } From 1d4454731f7c6e795dbb3bdf94e71aa2b657362c Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 14:44:11 +0800 Subject: [PATCH 4/9] =?UTF-8?q?REQ-3626=20=E8=B0=83=E6=95=B4=E9=80=80?= =?UTF-8?q?=E5=9B=9E=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/cmd/CustomBackTaskCmd.java | 51 ++++++++++++------- .../engine/job/AsyncBackTaskJobHandler.java | 21 ++++---- .../impl/BpmnProcessTaskServiceImpl.java | 41 ++++++++------- 3 files changed, 66 insertions(+), 47 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index ff3c343e5..ca6675be0 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -5,6 +5,10 @@ import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.core.common.utils.BpmnModelUtils; import com.alibaba.fastjson.JSON; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.FlowElement; import org.flowable.bpmn.model.FlowNode; @@ -58,24 +62,19 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ private static final String OPERATION_DESC = "回退至"; - public CustomBackTaskCmd(List targetTaskIds, - String advice, - String operationDesc, - List attachmentList, - BpmnTaskDelegateAssigner approver, - String processInstanceId, - String currentActivityId, - String toActivityId, - boolean validateApprover) { - this.targetTaskIds = targetTaskIds; - this.advice = advice; - this.operationDesc = operationDesc; - this.attachmentList = attachmentList; - this.approver = approver; - this.processInstanceId = processInstanceId; - this.currentActivityId = currentActivityId; - this.toActivityId = toActivityId; - this.validateApprover = validateApprover; + public CustomBackTaskCmd(CustomBackParamsDto customBackParamsDto) { + if (customBackParamsDto == null) { + throw new NullPointerException("customBackParamsDto is null"); + } + this.targetTaskIds = customBackParamsDto.getTargetTaskIds(); + this.advice = customBackParamsDto.getAdvice(); + this.operationDesc = customBackParamsDto.getOperationDesc(); + this.attachmentList = customBackParamsDto.getAttachmentList(); + this.approver = customBackParamsDto.getApprover(); + this.processInstanceId = customBackParamsDto.getProcessInstanceId(); + this.currentActivityId = customBackParamsDto.getCurrentActivityId(); + this.toActivityId = customBackParamsDto.getToActivityId(); + this.validateApprover = customBackParamsDto.isValidateApprover(); } @Override @@ -137,4 +136,20 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ return null; } + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static final class CustomBackParamsDto { + private List targetTaskIds; + private String advice; + private String operationDesc; + private List attachmentList; + private BpmnTaskDelegateAssigner approver; + private String processInstanceId; + private String currentActivityId; + private String toActivityId; + private boolean validateApprover; + } + } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java index b9bd5ae02..56de64ec8 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java @@ -37,15 +37,16 @@ public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler i return; } processEngineConfiguration.getCommandExecutor().execute(new CustomBackTaskCmd( - Collections.singletonList(dto.getTaskId()), - dto.getAdvice(), - dto.getOperationDesc(), - dto.getAttachmentList(), - dto.getApprover(), - task.getProcessInstanceId(), - task.getTaskDefinitionKey(), - dto.getToActivityId(), - true)); + CustomBackTaskCmd.CustomBackParamsDto.builder() + .targetTaskIds(Collections.singletonList(dto.getTaskId())) + .advice(dto.getAdvice()) + .operationDesc(dto.getOperationDesc()) + .attachmentList(dto.getAttachmentList()) + .approver(dto.getApprover()) + .processInstanceId(task.getProcessInstanceId()) + .currentActivityId(task.getTaskDefinitionKey()) + .toActivityId(dto.getToActivityId()) + .validateApprover(true) + .build())); } - } diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index a0d3cba5c..ea29471d8 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -395,15 +395,17 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { if (Boolean.TRUE.equals(dto.getAsync())) { commandExecutor.execute(new CustomBackTaskAsyncCmd(dto)); } else { - commandExecutor.execute(new CustomBackTaskCmd(Collections.singletonList(dto.getTaskId()), - dto.getAdvice(), - dto.getOperationDesc(), - dto.getAttachmentList(), - dto.getApprover(), - task.getProcessInstanceId(), - task.getTaskDefinitionKey(), - dto.getToActivityId(), - true)); + commandExecutor.execute(new CustomBackTaskCmd(CustomBackTaskCmd.CustomBackParamsDto.builder() + .targetTaskIds(Collections.singletonList(dto.getTaskId())) + .advice(dto.getAdvice()) + .operationDesc(dto.getOperationDesc()) + .attachmentList(dto.getAttachmentList()) + .approver(dto.getApprover()) + .processInstanceId(task.getProcessInstanceId()) + .currentActivityId(task.getTaskDefinitionKey()) + .toActivityId(dto.getToActivityId()) + .validateApprover(true) + .build())); } } @@ -452,15 +454,16 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { } } CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor(); - commandExecutor.execute(new CustomBackTaskCmd(valuableTasks.stream().map(TaskInfo::getId).collect(Collectors.toList()), - dto.getAdvice(), - dto.getOperationDesc(), - dto.getAttachmentList(), - null, - valuableTasks.get(0).getProcessInstanceId(), - dto.getCurrentActivityId(), - dto.getToActivityId(), - false)); + commandExecutor.execute(new CustomBackTaskCmd(CustomBackTaskCmd.CustomBackParamsDto.builder() + .targetTaskIds(valuableTasks.stream().map(TaskInfo::getId).collect(Collectors.toList())) + .advice(dto.getAdvice()) + .operationDesc(dto.getOperationDesc()) + .attachmentList(dto.getAttachmentList()) + .approver(null) + .processInstanceId(valuableTasks.get(0).getProcessInstanceId()) + .currentActivityId(dto.getCurrentActivityId()) + .toActivityId(dto.getToActivityId()) + .build())); } @Override @@ -469,7 +472,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { if (task == null) { throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS); } - return this.getBackOptionalNodes(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); + return this.getBackOptionalNodes(task.getProcessInstanceId(), task.getTaskDefinitionKey()); } @Override From ab71c6788907da91d9a35465171e39df1fc7a967 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 14:57:02 +0800 Subject: [PATCH 5/9] =?UTF-8?q?REQ-3626=20=E4=BF=AE=E5=A4=8D=E9=80=80?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../workflow/core/service/impl/BpmnProcessTaskServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index ea29471d8..886fb7e56 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -366,7 +366,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { if (task == null) { throw new WorkflowEngineException(PROCESS_TASK_NOT_EXISTS); } - List backOptionalNodes = getBackOptionalNodes(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); + List backOptionalNodes = getBackOptionalNodes(task.getProcessInstanceId(), task.getTaskDefinitionKey()); if (CollectionUtils.isEmpty(backOptionalNodes)) { throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, dto.getToActivityId()); } From 477eb38925457e8a38cbeb845f74d1decd295291 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 15:58:54 +0800 Subject: [PATCH 6/9] =?UTF-8?q?REQ-3626=20=E4=B8=9A=E5=8A=A1=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E6=94=AF=E6=8C=81=E4=BC=A0=E9=99=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task/BpmnNodeBackSystemOperateDTO.java | 3 +++ .../core/engine/cmd/CustomBackTaskCmd.java | 19 ++++++++++--------- .../engine/job/AsyncBackTaskJobHandler.java | 2 +- .../impl/BpmnProcessTaskServiceImpl.java | 8 ++++++-- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java index 4f800e7c4..21ccdd2ea 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java @@ -46,6 +46,9 @@ public class BpmnNodeBackSystemOperateDTO implements Serializable { @ApiModelProperty(value = "操作描述") private String operationDesc; + @ApiModelProperty(value = "操作人") + private BpmnTaskDelegateAssigner operator; + /** * 附件列表 */ diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index ca6675be0..58b0056e3 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -54,7 +54,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ private final String advice; private final String operationDesc; private final List attachmentList; - private final BpmnTaskDelegateAssigner approver; + private final BpmnTaskDelegateAssigner operator; private final String processInstanceId; private final String currentActivityId; private final String toActivityId; @@ -66,11 +66,14 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ if (customBackParamsDto == null) { throw new NullPointerException("customBackParamsDto is null"); } + if (customBackParamsDto.getOperator() == null) { + throw new NullPointerException("operator is null"); + } this.targetTaskIds = customBackParamsDto.getTargetTaskIds(); this.advice = customBackParamsDto.getAdvice(); this.operationDesc = customBackParamsDto.getOperationDesc(); this.attachmentList = customBackParamsDto.getAttachmentList(); - this.approver = customBackParamsDto.getApprover(); + this.operator = customBackParamsDto.getOperator(); this.processInstanceId = customBackParamsDto.getProcessInstanceId(); this.currentActivityId = customBackParamsDto.getCurrentActivityId(); this.toActivityId = customBackParamsDto.getToActivityId(); @@ -84,7 +87,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ params.put("advice", advice); params.put("operationDesc", OPERATION_DESC); params.put("attachmentList", JSON.toJSONString(attachmentList)); - params.put("approver", JSON.toJSONString(approver)); + params.put("operator", JSON.toJSONString(operator)); params.put("toActivityId", JSON.toJSONString(this.toActivityId)); params.put("processInstanceId", JSON.toJSONString(this.processInstanceId)); params.put("validateApprover", validateApprover); @@ -102,7 +105,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ .list(); TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); if (validateApprover) { - taskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), approver, null)); + taskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), operator, null)); } String processDefinitionId = taskList.get(0).getProcessDefinitionId(); Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); @@ -118,10 +121,8 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); taskList.forEach(th -> { TaskEntity task = taskService.getTask(th.getId()); - batchAddAttachment(commandContext, processInstanceId, task, attachmentList, approver); - if (approver != null) { - Authentication.setAuthenticatedUserId(approver.buildAssigneeId()); - } + Authentication.setAuthenticatedUserId(operator.buildAssigneeId()); + batchAddAttachment(commandContext, processInstanceId, task, attachmentList, operator); addComment(commandContext, task, COMMENT_TYPE_ADVICE, advice); addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, StringUtils.hasText(operationDesc) ? operationDesc : OPERATION_DESC + targetFlowElement.getName()); Authentication.setAuthenticatedUserId(null); @@ -145,7 +146,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ private String advice; private String operationDesc; private List attachmentList; - private BpmnTaskDelegateAssigner approver; + private BpmnTaskDelegateAssigner operator; private String processInstanceId; private String currentActivityId; private String toActivityId; diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java index 56de64ec8..2c5b642e7 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/job/AsyncBackTaskJobHandler.java @@ -42,7 +42,7 @@ public class AsyncBackTaskJobHandler extends AbstractExecuteWithLockJobHandler i .advice(dto.getAdvice()) .operationDesc(dto.getOperationDesc()) .attachmentList(dto.getAttachmentList()) - .approver(dto.getApprover()) + .operator(dto.getApprover()) .processInstanceId(task.getProcessInstanceId()) .currentActivityId(task.getTaskDefinitionKey()) .toActivityId(dto.getToActivityId()) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index 886fb7e56..51097384f 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -400,7 +400,7 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { .advice(dto.getAdvice()) .operationDesc(dto.getOperationDesc()) .attachmentList(dto.getAttachmentList()) - .approver(dto.getApprover()) + .operator(dto.getApprover()) .processInstanceId(task.getProcessInstanceId()) .currentActivityId(task.getTaskDefinitionKey()) .toActivityId(dto.getToActivityId()) @@ -453,13 +453,17 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { } } } + BpmnTaskDelegateAssigner operator = dto.getOperator(); + if (operator == null) { + operator = new BpmnTaskDelegateAssigner("系统", "system", taskList.get(0).getTenantId()); + } CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor(); commandExecutor.execute(new CustomBackTaskCmd(CustomBackTaskCmd.CustomBackParamsDto.builder() .targetTaskIds(valuableTasks.stream().map(TaskInfo::getId).collect(Collectors.toList())) .advice(dto.getAdvice()) .operationDesc(dto.getOperationDesc()) .attachmentList(dto.getAttachmentList()) - .approver(null) + .operator(operator) .processInstanceId(valuableTasks.get(0).getProcessInstanceId()) .currentActivityId(dto.getCurrentActivityId()) .toActivityId(dto.getToActivityId()) From 29cc5bee1043912aee22d93eb393ed78e468d5d1 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 16:30:06 +0800 Subject: [PATCH 7/9] =?UTF-8?q?REQ-3626=20=E4=BF=AE=E5=A4=8D=E9=A9=B3?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/engine/cmd/CustomBackTaskCmd.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java index 58b0056e3..3a9b88a04 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomBackTaskCmd.java @@ -22,6 +22,7 @@ import org.flowable.engine.impl.util.ProcessDefinitionUtil; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.service.TaskService; import org.flowable.task.service.impl.persistence.entity.TaskEntity; +import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import java.io.Serializable; @@ -30,9 +31,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_NODE_CANNOT_REACHABLE; import static cn.axzo.workflow.common.code.BpmnTaskRespCode.BACK_TARGET_ACTIVITY_NOT_EXISTS; +import static cn.axzo.workflow.common.code.BpmnTaskRespCode.TASK_COMPLETE_FAIL_NOT_EXISTS; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE; import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC; import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_LIST_INFO; @@ -103,11 +106,25 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ .taskDefinitionKey(currentActivityId) .processInstanceId(processInstanceId) .list(); + List valueableTaskList = taskList.stream() + .filter(hi -> { + if (hi.getEndTime() != null) { + return false; + } + if (!CollectionUtils.isEmpty(targetTaskIds)) { + return targetTaskIds.contains(hi.getId()); + } + return true; + }) + .collect(Collectors.toList()); + if (CollectionUtils.isEmpty(valueableTaskList)) { + throw new WorkflowEngineException(TASK_COMPLETE_FAIL_NOT_EXISTS); + } TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService(); if (validateApprover) { - taskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), operator, null)); + valueableTaskList.forEach(hi -> validTask(hi, taskService.getTask(hi.getId()), operator, null)); } - String processDefinitionId = taskList.get(0).getProcessDefinitionId(); + String processDefinitionId = valueableTaskList.get(0).getProcessDefinitionId(); Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); FlowElement targetFlowElement = process.getFlowElement(toActivityId, true); if (Objects.isNull(targetFlowElement)) { @@ -119,7 +136,7 @@ public class CustomBackTaskCmd extends AbstractCommand implements Serializ throw new WorkflowEngineException(BACK_NODE_CANNOT_REACHABLE, toActivityId); } RuntimeService runtimeService = processEngineConfiguration.getRuntimeService(); - taskList.forEach(th -> { + valueableTaskList.forEach(th -> { TaskEntity task = taskService.getTask(th.getId()); Authentication.setAuthenticatedUserId(operator.buildAssigneeId()); batchAddAttachment(commandContext, processInstanceId, task, attachmentList, operator); From 492180901cfd7119894a27c2cb2ee67bf86816e1 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Mon, 24 Feb 2025 16:38:58 +0800 Subject: [PATCH 8/9] =?UTF-8?q?REQ-3626=20=E9=A9=B3=E5=9B=9E=E5=88=B0?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9=E6=94=AF=E6=8C=81=E6=8C=87?= =?UTF-8?q?=E5=AE=9A=E4=BB=BB=E5=8A=A1=E8=BF=9B=E8=A1=8C=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../request/bpmn/task/BpmnNodeBackSystemOperateDTO.java | 3 +++ .../core/service/impl/BpmnProcessTaskServiceImpl.java | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java index 21ccdd2ea..c01572e98 100644 --- a/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java +++ b/workflow-engine-common/src/main/java/cn/axzo/workflow/common/model/request/bpmn/task/BpmnNodeBackSystemOperateDTO.java @@ -40,6 +40,9 @@ public class BpmnNodeBackSystemOperateDTO implements Serializable { @NotBlank(message = "目标流程节点id不能为空") private String toActivityId; + @ApiModelProperty(value = "可以指定任务处理", required = true) + private List targetTaskIds; + @ApiModelProperty(value = "意见") private String advice; diff --git a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java index 51097384f..436fc77c9 100644 --- a/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java +++ b/workflow-engine-core/src/main/java/cn/axzo/workflow/core/service/impl/BpmnProcessTaskServiceImpl.java @@ -424,6 +424,12 @@ public class BpmnProcessTaskServiceImpl implements BpmnProcessTaskService { } List valuableTasks = taskList.stream() .filter(t -> Objects.isNull(t.getEndTime())) + .filter(t -> { + if (CollectionUtils.isNotEmpty(dto.getTargetTaskIds())) { + return dto.getTargetTaskIds().contains(t.getId()); + } + return true; + }) .collect(Collectors.toList()); if (CollectionUtils.isEmpty(valuableTasks)) { throw new WorkflowEngineException(TASK_HAS_BEEN_COMPLETE); From 648563b044f328d091c436abeec6cc21b7ef8384 Mon Sep 17 00:00:00 2001 From: yangqicheng Date: Wed, 26 Feb 2025 22:31:39 +0800 Subject: [PATCH 9/9] =?UTF-8?q?REQ-3626-=E4=BF=AE=E5=A4=8D=E9=A9=B3?= =?UTF-8?q?=E5=9B=9E=E5=88=B0=E6=8C=87=E5=AE=9A=E8=8A=82=E7=82=B9feign=20a?= =?UTF-8?q?pi=E5=9C=B0=E5=9D=80=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java index 485815d6b..a01f507c1 100644 --- a/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java +++ b/workflow-engine-api/src/main/java/cn/axzo/workflow/client/feign/bpmn/ProcessTaskApi.java @@ -95,7 +95,7 @@ public interface ProcessTaskApi { * @return 是否成功 */ @Operation(summary = "系统操作回退任务到指定节点") - @PostMapping("/system/back") + @PostMapping("/api/process/task/system/back") CommonResponse systemBackTask(@Validated @RequestBody BpmnNodeBackSystemOperateDTO dto); /**