Merge branch 'refs/heads/hotfix/improve-batch-operation' into feature/REQ-2596

# Conflicts:
#	workflow-engine-core/src/main/java/cn/axzo/workflow/core/conf/FlowableConfiguration.java
#	workflow-engine-core/src/main/java/cn/axzo/workflow/core/engine/cmd/CustomCarbonCopyUserSelectorCmd.java
This commit is contained in:
yangqicheng 2024-07-11 13:45:48 +08:00
commit ffd7170da8
43 changed files with 477 additions and 193 deletions

View File

@ -18,8 +18,8 @@ public enum AsyncJobRespCode implements IModuleRespCode {
JOB_NOT_EXISTS_PROC_INST_ID("003", "流程实例id为【{}】对应任务不存在"),
RESUME_JOB_REQUEST_PARAM_ERROR("004", "恢复任务请求参数错误jobId 和 procInstId 不能同时为空"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -30,13 +30,4 @@ public enum AsyncJobRespCode implements IModuleRespCode {
public String getProjectCode() {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -27,8 +27,8 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
TASK_CANT_COMMENT_INSTANCE_NOT_EXISTS("012", "流程实例【{}】不存在, 不能评论"),
RUNNING_INSTANCE_ONLY_FORECAST("013", "仅运行中的实例可以推测"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -40,12 +40,4 @@ public enum BpmnInstanceRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -20,8 +20,8 @@ public enum BpmnModelRespCode implements IModuleRespCode {
BPMN_BYTES_NOT_EXISTS("005", "模型定义内容字节码不存在"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -33,13 +33,5 @@ public enum BpmnModelRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -24,8 +24,8 @@ public enum BpmnProcessDefinitionRespCode implements IModuleRespCode {
PROCESS_DEFINITION_HAS_DIRTY_DATA("009", "流程定义KEY【{}】存在脏数据,当前模型没有流程定义内容"),
PROCESS_DEFINITION_IS_INVALID("010", "暂时无法发起,请先配置流程模型")
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -37,12 +37,4 @@ public enum BpmnProcessDefinitionRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -35,8 +35,8 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
TASK_TYPE_MISMATCH("020", "节点类型不匹配,当前节点类型:【{}】,指定节点类型:【{}】!"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -48,13 +48,4 @@ public enum BpmnTaskRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -21,8 +21,8 @@ public enum CategoryRespCode implements IModuleRespCode {
CATEGORY_CONFIG_EXISTS("006", "分类【{}】的【{}】配置中已存在重复数据"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -34,13 +34,5 @@ public enum CategoryRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -23,8 +23,8 @@ public enum ConvertorRespCode implements IModuleRespCode {
CONVERTOR_OPERATION_CHECKBOX_TYPE_ERROR("008", "条件节点(复选)运算符【{}】暂不支持"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -36,13 +36,4 @@ public enum ConvertorRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -18,10 +18,12 @@ public enum FlowableEngineRespCode implements IModuleRespCode {
ENGINE_USER_TASK_TYPE_NOT_SUPPORT("003", "审批指定方式暂不支持"),
ENGINE_USER_TASK_PARAM_ERROR("004", "构建后的查询审批人入参为空. 任务节点【nodeId:{}】, 该节点选择的\"审批人所在范围\"是:【{}】,请检查 cooperationOrg 参数"),
ENGINE_NOTICE_CUSTOM_FLOW_ELEMENT_ERROR("005", "查询通知目标用户前参数发生异常,未获取到 WorkspaceType"),
ENGINE_ASYNC_COMMAND_EXECUTION_ERROR("006", "引擎出现 SQL 相关异常, 异常信息:【{}】"),
ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP("007", "命令重试尝试【{}】次仍然失败,并出现异常, 将放弃"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -33,13 +35,4 @@ public enum FlowableEngineRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -17,8 +17,8 @@ public enum FormDefinitionRespCode implements IModuleRespCode {
FORM_DEFINITION_PARSER_ERROR("002", "表单定义内容解析出错"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -30,13 +30,4 @@ public enum FormDefinitionRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -17,8 +17,8 @@ public enum FormModelRespCode implements IModuleRespCode {
FORM_MODEL_ID_NOT_EXISTS("002", "表单模型ID【{}】不存在"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -30,13 +30,4 @@ public enum FormModelRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -21,8 +21,8 @@ public enum OtherRespCode implements IModuleRespCode {
MESSAGE_PUSH_EVENT_BUILD_ERROR("006", "不能使用 createEvent 函数创建`发送待办`的事件, 请调用 createPendingPushEvent 函数"),
;
private String code;
private String message;
private final String code;
private final String message;
@Override
public String getModuleCode() {
@ -34,12 +34,4 @@ public enum OtherRespCode implements IModuleRespCode {
return "998";
}
public void setCode(String code) {
this.code = code;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,24 @@
package cn.axzo.workflow.core.common.utils;
import org.slf4j.MDC;
import org.springframework.util.StringUtils;
import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID;
import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;
/**
* 获取 TraceId
*
* @author wangli
* @since 2024/7/3 10:14
*/
public final class TraceUtil {
private TraceUtil() {
}
public static String traceId() {
String xRequestId = MDC.get(X_REQUEST_ID);
return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC);
}
}

View File

@ -4,6 +4,7 @@ import cn.axzo.workflow.core.common.utils.SpringContentUtils;
import cn.axzo.workflow.core.engine.behavior.CustomActivityBehaviorFactory;
import cn.axzo.workflow.core.engine.cmd.CustomCommandContextFactory;
import cn.axzo.workflow.core.engine.id.BasedNacosSnowflakeIdGenerator;
import cn.axzo.workflow.core.engine.interceptor.CustomRetryInterceptor;
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler;
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
import cn.axzo.workflow.core.engine.job.AsyncBpmnProcessActivityJobHandler;
@ -37,6 +38,7 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.time.Duration;
import java.util.List;
@ -64,7 +66,8 @@ public class FlowableConfiguration {
BpmnProcessActivityService bpmnProcessActivityService,
List<JobProcessor> jobProcessors,
NacosServiceManager nacosServiceManager,
NacosDiscoveryProperties nacosDiscoveryProperties) {
NacosDiscoveryProperties nacosDiscoveryProperties,
StringRedisTemplate redisTemplate) {
return configuration -> {
configuration.setEnableHistoricTaskLogging(true);
configuration.setHistoryLevel(HistoryLevel.AUDIT);
@ -100,6 +103,9 @@ public class FlowableConfiguration {
new CustomWorkflowEngineExceptionHandler(),
new CustomAsyncRunnableExceptionExceptionHandler()));
configuration.setCommandContextFactory(new CustomCommandContextFactory());
configuration.setCustomPreCommandInterceptors(Lists.newArrayList(
new CustomRetryInterceptor()
));
};
}

View File

@ -0,0 +1,15 @@
package cn.axzo.workflow.core.engine.cmd;
import org.flowable.common.engine.impl.interceptor.Command;
/**
* TODO
*
* @author wangli
* @since 2024/7/1 13:59
*/
public abstract class AbstractCommand<T> implements Command<T> {
public abstract String paramToJsonString();
}

View File

@ -4,7 +4,7 @@ import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbo
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.job.AsyncAbortProcessInstanceHandler;
import cn.hutool.json.JSONUtil;
import org.flowable.common.engine.impl.interceptor.Command;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_ABORT;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serializable {
public class CustomAbortProcessInstanceAsyncCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnProcessInstanceAbortDTO dto;
@ -31,6 +31,11 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serial
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
String processInstanceId = dto.getProcessInstanceId();
@ -80,4 +85,5 @@ public class CustomAbortProcessInstanceAsyncCmd implements Command<Void>, Serial
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
}

View File

@ -4,6 +4,8 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
import liquibase.pro.packaged.V;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
@ -44,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir
* @author wangli
* @since 2024/1/2 18:19
*/
public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializable {
public class CustomAbortProcessInstanceCmd extends AbstractCommand<Void> implements Serializable {
private final String processInstanceId;
private final String tenantId;
private final String reason;
@ -58,6 +60,15 @@ public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializabl
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("tenantId", tenantId);
params.put("reason", reason);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -102,4 +113,5 @@ public class CustomAbortProcessInstanceCmd implements Command<Void>, Serializabl
runtimeService.setVariable(task.getProcessInstanceId(), TASK_COMPLETE_OPERATION_TYPE + task.getId(), ABORTED);
return null;
}
}

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.core.engine.job.AsyncApproveTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
@ -18,6 +19,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
@ -28,7 +31,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @author wangli
* @since 2024/1/4 15:50
*/
public class CustomApproveTaskAsyncCmd implements Command<Void>, Serializable {
public class CustomApproveTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskAsyncCmd.class);
private final BpmnTaskAuditDTO dto;
@ -37,6 +40,11 @@ public class CustomApproveTaskAsyncCmd implements Command<Void>, Serializable {
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =

View File

@ -4,12 +4,14 @@ import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.task.AttachmentDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.context.Context;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
@ -20,7 +22,9 @@ import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
@ -38,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @author wangli
* @since 2024/1/4 15:50
*/
public class CustomApproveTaskCmd implements Command<Void>, Serializable {
public class CustomApproveTaskCmd extends AbstractCommand<Void> implements Serializable {
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskCmd.class);
private final String taskId;
@ -62,6 +66,18 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
*/
private List<BpmnFlowNodeType> nodeTypes;
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("taskId", taskId);
params.put("advice", advice);
params.put("operationDesc", operationDesc);
params.put("attachmentList", JSON.toJSONString(attachmentList));
params.put("approver", JSON.toJSONString(approver));
params.put("nextApprover", JSON.toJSONString(nextApprover));
params.put("nodeTypes", JSON.toJSONString(nodeTypes));
return JSON.toJSONString(params);
}
public CustomApproveTaskCmd(BpmnTaskAuditDTO dto) {
this(dto, null);

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
@ -14,7 +15,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.HIDDEN_ASSIGNEE_ID;
@ -31,7 +34,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.ACTIVITY_CANT_S
* @author wangli
* @since 2023/12/22 13:51
*/
public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Serializable {
public class CustomBizSpecifyAssigneeToTaskCmd extends AbstractCommand<Boolean> implements Serializable {
private final String executionId;
private final List<BpmnTaskDelegateAssigner> addedAssigners;
@ -41,6 +44,14 @@ public class CustomBizSpecifyAssigneeToTaskCmd implements Command<Boolean>, Seri
this.addedAssigners = addedAssigners;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("executionId", executionId);
params.put("addedAssigners", addedAssigners);
return JSON.toJSONString(params);
}
@Override
public Boolean execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =

View File

@ -5,7 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.job.AsyncCancelProcessInstanceHandler;
import cn.hutool.json.JSONUtil;
import org.flowable.common.engine.impl.interceptor.Command;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
@ -23,7 +23,7 @@ import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INS
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_CANT_CANCEL;
import static cn.axzo.workflow.core.common.code.BpmnInstanceRespCode.PROCESS_INSTANCE_NOT_EXISTS;
public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Serializable {
public class CustomCancelProcessInstanceAsyncCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnProcessInstanceCancelDTO dto;
@ -31,6 +31,11 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Seria
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
String processInstanceId = dto.getProcessInstanceId(), tenantId = dto.getTenantId();
@ -81,4 +86,5 @@ public class CustomCancelProcessInstanceAsyncCmd implements Command<Void>, Seria
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
}

View File

@ -1,9 +1,11 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.framework.context.validation.SpringValidator;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.HistoryService;
@ -12,6 +14,7 @@ import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
@ -41,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.createVir
* @author wangli
* @since 2024/1/2 18:19
*/
public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializable {
public class CustomCancelProcessInstanceCmd extends AbstractCommand<Void> implements Serializable {
private final String processInstanceId;
private final String tenantId;
private final String reason;
@ -58,6 +61,16 @@ public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializab
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("tenantId", tenantId);
params.put("reason", reason);
params.put("initiator", initiator);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -102,4 +115,5 @@ public class CustomCancelProcessInstanceCmd implements Command<Void>, Serializab
addComment(commandContext, task, COMMENT_TYPE_OPERATION_DESC, "已撤回");
return null;
}
}

View File

@ -10,6 +10,7 @@ import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.CustomProperty;
import org.flowable.bpmn.model.ServiceTask;
import org.flowable.common.engine.impl.interceptor.Command;
@ -27,6 +28,7 @@ import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -34,6 +36,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.axzo.workflow.common.constant.BpmnConstants.CARBON_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_INITIATOR;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_TASK_RELATION_ASSIGNEE_INFO;
import static cn.axzo.workflow.common.constant.BpmnConstants.NO_ASSIGNEE;
@ -47,7 +50,8 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup
* @author wangli
* @since 18/03/2024 11:33
*/
public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
@Slf4j
public class CustomCarbonCopyUserSelectorCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
private static final long serialVersionUID = 1L;
private final String processInstanceId;
@ -85,6 +89,15 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
this.execution = execution;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("carbons", carbons);
params.put("serviceVersion", serviceVersion);
return JSON.toJSONString(params);
}
@Override
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
if (CollectionUtils.isEmpty(carbons)) {
@ -99,6 +112,17 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
} else {
executions.add((Execution) execution);
}
//流程为空表示已经执行完去历史版本获取
if (CollectionUtils.isEmpty(executions)) {
List<HistoricVariableInstance> hisVarInst = processEngineConfiguration.getHistoryService().createHistoricVariableInstanceQuery()
.processInstanceId(processInstanceId)
.variableName(INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + serviceTask.getId()).list();
if (!CollectionUtils.isEmpty(hisVarInst)) {
return (List<BpmnTaskDelegateAssigner>) hisVarInst.get(0).getValue();
}
log.warn("executions is empty,get historic task assigner list empty,processInstanceId: {},serviceTaskId: {}", processInstanceId, serviceTask.getId());
return Collections.emptyList();
}
List<BpmnTaskDelegateAssigner> assigners = new ArrayList<>();
carbons.forEach(carbon -> {
CarbonCopyObjectType carbonCopyObjectType = carbon.getCarbonCopyObjectType();
@ -212,5 +236,4 @@ public class CustomCarbonCopyUserSelectorCmd implements Command<List<BpmnTaskDel
return assigners;
}
}

View File

@ -7,6 +7,7 @@ import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.Command;
@ -27,7 +28,9 @@ import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_ADVICE;
@ -44,7 +47,7 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
* @author wangli
* @since 2023/12/26 16:14
*/
public class CustomCommentTaskCmd implements Command<Void>, Serializable {
public class CustomCommentTaskCmd extends AbstractCommand<Void> implements Serializable {
private final String processInstanceId;
private final BpmnTaskDelegateAssigner operator;
private final String comment;
@ -63,6 +66,17 @@ public class CustomCommentTaskCmd implements Command<Void>, Serializable {
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("operator", operator);
params.put("comment", comment);
params.put("commentExt", commentExt);
params.put("attachmentList", attachmentList);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =

View File

@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
@ -16,7 +17,9 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
@ -30,7 +33,7 @@ import static cn.axzo.workflow.core.common.code.BpmnTaskRespCode.DUMMY_TASK_NOT_
* @author wangli
* @since 2023/12/27 11:24
*/
public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
public class CustomCompleteDummyTaskCmd extends AbstractCommand<Void> implements Serializable {
private final String processInstanceId;
private final String taskId;
private final String flowNodeName;
@ -46,6 +49,16 @@ public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("taskId", taskId);
params.put("flowNodeName", flowNodeName);
params.put("operationDesc", operationDesc);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -93,4 +106,5 @@ public class CustomCompleteDummyTaskCmd implements Command<Void>, Serializable {
taskService.setOwner(i.getId(), null);
});
}
}

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskCountersignDTO;
import cn.axzo.workflow.core.engine.job.AsyncCountersignUserTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
@ -16,17 +17,24 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
public class CustomCountersignUserTaskAsyncCmd implements Command<Void>, Serializable {
public class CustomCountersignUserTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnTaskCountersignDTO dto;
public CustomCountersignUserTaskAsyncCmd(BpmnTaskCountersignDTO dto) {
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -66,4 +74,5 @@ public class CustomCountersignUserTaskAsyncCmd implements Command<Void>, Seriali
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
}

View File

@ -6,6 +6,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
@ -19,7 +20,9 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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;
@ -39,7 +42,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @since 2023/12/25 14:05
*/
@Slf4j
public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable {
public class CustomCountersignUserTaskCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnCountersignTypeEnum countersignType;
private final String originTaskId;
@ -62,6 +65,18 @@ public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("countersignType", countersignType.getType());
params.put("originTaskId", originTaskId);
params.put("originTaskAssignee", originTaskAssignee);
params.put("advice", advice);
params.put("attachmentList", JSON.toJSONString(attachmentList));
params.put("targetTaskAssigneeList", JSON.toJSONString(targetTaskAssigneeList));
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -139,4 +154,5 @@ public class CustomCountersignUserTaskCmd implements Command<Void>, Serializable
addComment(commandContext, virtualTask, COMMENT_TYPE_OPERATION_DESC, message.toString());
batchAddAttachment(commandContext, task.getProcessInstanceId(), task.getId(), attachmentList, originTaskAssignee);
}
}

View File

@ -5,6 +5,7 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.cfg.IdGenerator;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.Command;
@ -21,7 +22,9 @@ import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
@ -41,7 +44,7 @@ import static org.flowable.task.api.Task.DEFAULT_PRIORITY;
* @author wangli
* @since 2023/12/27 10:21
*/
public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
public class CustomCreateDummyTaskCmd extends AbstractCommand<String> implements Serializable {
private final String processInstanceId;
private final String flowNodeName;
private final String operationDesc;
@ -57,6 +60,16 @@ public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
this.extAxHiTaskInstService = extAxHiTaskInstService;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("flowNodeName", flowNodeName);
params.put("operationDesc", operationDesc);
params.put("operator", operator);
return JSON.toJSONString(params);
}
/**
* 在同一个实例下,不允许创建多个执行中的虚拟任务节点
*
@ -139,4 +152,5 @@ public class CustomCreateDummyTaskCmd implements Command<String>, Serializable {
});
}
}
}

View File

@ -19,7 +19,9 @@ import org.springframework.util.CollectionUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.axzo.workflow.common.constant.BpmnConstants.APPROVAL_ASSIGNER_LIMIT_NUMBER;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getApproverSpecify;
@ -32,7 +34,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.getLimite
* @since 2023/12/11 17:56
*/
@Slf4j
public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
public class CustomForecastUserTaskAssigneeCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
private final String processInstanceId;
private final UserTask userTask;
private final EngineExecutionStartListener engineExecutionStartListener;
@ -44,6 +46,13 @@ public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskD
this.engineExecutionStartListener = engineExecutionStartListener;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
return JSON.toJSONString(params);
}
@Override
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -83,4 +92,5 @@ public class CustomForecastUserTaskAssigneeCmd implements Command<List<BpmnTaskD
JSONUtil.toJsonStr(forecastAssigners));
return getLimitedElementList(forecastAssigners, APPROVAL_ASSIGNER_LIMIT_NUMBER);
}
}

View File

@ -23,6 +23,7 @@ import org.flowable.variable.api.history.HistoricVariableInstance;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -40,7 +41,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.removeDup
* @author wangli
* @since 2024/5/11 09:42
*/
public class CustomNoticeDestinationUserSelectorCmd implements Command<List<BpmnTaskDelegateAssigner>>, Serializable {
public class CustomNoticeDestinationUserSelectorCmd extends AbstractCommand<List<BpmnTaskDelegateAssigner>> implements Serializable {
private static final long serialVersionUID = 1L;
private final EngineExecutionStartListener engineExecutionStartListener;
private final BpmnHistoricTaskInstanceConverter historicTaskInstanceConverter;
@ -63,6 +64,17 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command<List<Bpmn
this.initiator = initiator;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("serviceVersion", serviceVersion);
params.put("workspaceType", workspaceType);
params.put("noticeProperty", noticeProperty);
params.put("processInstanceId", processInstanceId);
params.put("initiator", initiator);
return JSON.toJSONString(params);
}
@Override
public List<BpmnTaskDelegateAssigner> execute(CommandContext commandContext) {
if (!noticeProperty.getSendMessage()) {
@ -170,5 +182,4 @@ public class CustomNoticeDestinationUserSelectorCmd implements Command<List<Bpmn
return noticeFlowElement;
}
}

View File

@ -1,9 +1,10 @@
package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.core.engine.job.AsyncRejectTaskJobHandler;
import cn.hutool.json.JSONUtil;
import org.flowable.common.engine.impl.interceptor.Command;
import com.alibaba.fastjson.JSONObject;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
@ -25,13 +26,18 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @author wangli
* @since 2024/1/4 13:36
*/
public class CustomRejectionTaskAsyncCmd implements Command<Void>, Serializable {
public class CustomRejectionTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnTaskAuditDTO dto;
public CustomRejectionTaskAsyncCmd(BpmnTaskAuditDTO dto) {
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -69,4 +75,5 @@ public class CustomRejectionTaskAsyncCmd implements Command<Void>, Serializable
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
}

View File

@ -6,11 +6,12 @@ import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskAuditDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.engine.operation.DeleteProcessInstanceOperation;
import cn.axzo.workflow.core.service.ExtAxHiTaskInstService;
import org.flowable.common.engine.impl.interceptor.Command;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.context.Context;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
@ -21,6 +22,7 @@ import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static cn.axzo.workflow.common.constant.BpmnConstants.COMMENT_TYPE_OPERATION_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.INTERNAL_DELETE_PROCESS_FLAG;
@ -42,7 +44,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @author wangli
* @since 2024/1/4 13:36
*/
public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
public class CustomRejectionTaskCmd extends AbstractCommand<Void> implements Serializable {
private final String taskId;
private final String advice;
@ -60,6 +62,17 @@ public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
this.nodeTypes = dto.getNodeTypes();
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("taskId", taskId);
params.put("advice", advice);
params.put("attachmentList", attachmentList);
params.put("approver", approver);
params.put("nodeTypes", nodeTypes);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration =
@ -99,4 +112,5 @@ public class CustomRejectionTaskCmd implements Command<Void>, Serializable {
.planOperation(new DeleteProcessInstanceOperation(commandContext, task.getProcessInstanceId(),
extAxHiTaskInstService));
}
}

View File

@ -3,8 +3,8 @@ package cn.axzo.workflow.core.engine.cmd;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskTransferDTO;
import cn.axzo.workflow.core.engine.job.AsyncTransferUserTaskJobHandler;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.TaskService;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
@ -17,6 +17,8 @@ import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask;
import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTaskAssignerDuplicated;
@ -24,7 +26,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
/**
* 异步转交任务的命令执行器
*/
public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializable {
public class CustomTransferUserTaskAsyncCmd extends AbstractCommand<Void> implements Serializable {
private final BpmnTaskTransferDTO dto;
@ -32,6 +34,11 @@ public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializab
this.dto = dto;
}
@Override
public String paramToJsonString() {
return JSON.toJSONString(dto);
}
@Override
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
@ -65,4 +72,5 @@ public class CustomTransferUserTaskAsyncCmd implements Command<Void>, Serializab
jobService.createAsyncJob(job, false);
jobService.scheduleAsyncJob(job);
}
}

View File

@ -3,6 +3,7 @@ package cn.axzo.workflow.core.engine.cmd;
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.exception.WorkflowEngineException;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.common.engine.impl.interceptor.Command;
@ -18,7 +19,9 @@ import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@ -43,7 +46,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
* @author wangli
* @since 2023/12/22 10:22
*/
public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
public class CustomTransferUserTaskCmd extends AbstractCommand<Void> implements Serializable {
private final String originTaskId;
private final BpmnTaskDelegateAssigner originTaskAssignee;
@ -60,6 +63,16 @@ public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
this.targetTaskAssignee = targetTaskAssignee;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("originTaskId", originTaskId);
params.put("originTaskAssignee", originTaskAssignee);
params.put("advice", advice);
params.put("attachmentList", attachmentList);
params.put("targetTaskAssignee", targetTaskAssignee);
return JSON.toJSONString(params);
}
@Override
public Void execute(CommandContext commandContext) {
@ -125,4 +138,5 @@ public class CustomTransferUserTaskCmd implements Command<Void>, Serializable {
INTERNAL_ACTIVITY_RELATION_ASSIGNEE_LIST_INFO_SNAPSHOT + task.getTaskDefinitionKey(),
originAssingeeList);
}
}

View File

@ -0,0 +1,90 @@
package cn.axzo.workflow.core.engine.interceptor;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.TraceUtil;
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.PersistenceException;
import org.flowable.common.engine.impl.interceptor.AbstractCommandInterceptor;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandConfig;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP;
/**
* 基于 RetryInterceptor 的命令重试拦截器, 本意想用来处理多人同时操作同一个任务, 但会存在超过重试次数后,会丢弃原有的命令.
*
* @author wangli
* @since 2024/7/1 13:51
*/
@Slf4j
public class CustomRetryInterceptor extends AbstractCommandInterceptor {
protected int numOfRetries = 3;
protected int waitTimeInMs = 60;
protected int waitIncreaseFactor = 5;
@Override
public <T> T execute(CommandConfig config, Command<T> command, CommandExecutor commandExecutor) {
long waitTime = waitTimeInMs;
int failedAttempts = 0;
do {
if (failedAttempts > 0) {
log.warn("Waiting for {}ms before retrying the command.", waitTime);
waitBeforeRetry(waitTime);
waitTime *= waitIncreaseFactor;
}
try {
// try to execute the command
log.info("assignableFrom result: {}", AbstractCommand.class.isAssignableFrom(command.getClass()));
if (AbstractCommand.class.isAssignableFrom(command.getClass())) {
// 如果在以后,重试三次也不能解决的话, 可以利用这里的拿到的参数,重新自动构造CMD,并执行.
log.info("Executing command params: {} traceId:{} ", TraceUtil.traceId(),
((AbstractCommand<T>) command).paramToJsonString());
}
return next.execute(config, command, commandExecutor);
} catch (PersistenceException e) {
log.warn("Caught persistence exception: {}", e.getMessage(), e);
}
failedAttempts++;
} while (failedAttempts <= numOfRetries);
throw new WorkflowEngineException(ENGINE_ASYNC_COMMAND_EXECUTION_RETRY_GIVE_UP, String.valueOf(numOfRetries));
}
protected void waitBeforeRetry(long waitTime) {
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
log.warn("I am interrupted while waiting for a retry.");
}
}
public void setNumOfRetries(int numOfRetries) {
this.numOfRetries = numOfRetries;
}
public void setWaitIncreaseFactor(int waitIncreaseFactor) {
this.waitIncreaseFactor = waitIncreaseFactor;
}
public void setWaitTimeInMs(int waitTimeInMs) {
this.waitTimeInMs = waitTimeInMs;
}
public int getNumOfRetries() {
return numOfRetries;
}
public int getWaitIncreaseFactor() {
return waitIncreaseFactor;
}
public int getWaitTimeInMs() {
return waitTimeInMs;
}
}

View File

@ -19,15 +19,16 @@ public class CustomWorkflowEngineExceptionHandler implements AsyncRunnableExecut
@Override
public boolean handleException(JobServiceConfiguration jobServiceConfiguration, JobInfo job, Throwable e) {
Throwable rootCause = getRootCause(e);
if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) {
WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause;
if (Objects.equals(workflowEngineException.getCode(), "99806020")) {
log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}",
workflowEngineException.getCode(), rootCause.getMessage(), rootCause);
return true;
}
}
return false;
// if (rootCause.getClass().isAssignableFrom(WorkflowEngineException.class)) {
// WorkflowEngineException workflowEngineException = (WorkflowEngineException) rootCause;
// if (Objects.equals(workflowEngineException.getCode(), "99806020")) {
// log.info("AsyncApproveTaskJobHandler execute exception code: {} info: {}",
// workflowEngineException.getCode(), rootCause.getMessage(), rootCause);
// return true;
// }
// }
log.warn("Async Runnable Execution Exception: {}", rootCause.getMessage(), e);
return WorkflowEngineException.class.isAssignableFrom(rootCause.getClass());
}
private Throwable getRootCause(Throwable throwable) {

View File

@ -1,7 +1,9 @@
package cn.axzo.workflow.core.service.support;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
import cn.azxo.framework.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
@ -10,6 +12,8 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EXECUTION_LOST_ID_ERROR;
@ -20,7 +24,7 @@ import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_EX
* @author wangli
* @since 2023/10/9 19:30
*/
public class ExpressionConditionCmd implements Command<Boolean>, Serializable {
public class ExpressionConditionCmd extends AbstractCommand<Boolean> implements Serializable {
protected final RuntimeService runtimeService;
protected final ProcessEngineConfigurationImpl processEngineConfiguration;
protected final String processInstanceId;
@ -35,6 +39,14 @@ public class ExpressionConditionCmd implements Command<Boolean>, Serializable {
this.exp = exp;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("processInstanceId", processInstanceId);
params.put("exp", exp);
return JSON.toJSONString(params);
}
@Override
public Boolean execute(CommandContext commandContext) {
Expression expression = processEngineConfiguration.getExpressionManager().createExpression(this.exp);

View File

@ -1,5 +1,8 @@
package org.flowable.engine.impl.cmd;
import cn.axzo.workflow.core.engine.cmd.AbstractCommand;
import com.alibaba.fastjson.JSON;
import liquibase.pro.packaged.M;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
@ -22,6 +25,9 @@ import org.flowable.task.api.Task;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import java.io.InputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 覆盖 Flowable 自带的 CreateAttachmentCmd, 由于 Flowable 5 的实现导致异常需要覆盖
@ -29,7 +35,7 @@ import java.io.InputStream;
* @author Tom Baeyens
* @author Joram Barrez
*/
public class CreateAttachmentCmd implements Command<Attachment> {
public class CreateAttachmentCmd extends AbstractCommand<Attachment> implements Serializable {
protected String attachmentType;
protected String taskId;
@ -50,6 +56,19 @@ public class CreateAttachmentCmd implements Command<Attachment> {
this.url = url;
}
@Override
public String paramToJsonString() {
Map<String, Object> params = new HashMap<>();
params.put("attachmentType", attachmentType);
params.put("taskId", taskId);
params.put("processInstanceId", processInstanceId);
params.put("attachmentName", attachmentName);
params.put("attachmentDescription", attachmentDescription);
// params.put("content", content);
params.put("url", url);
return JSON.toJSONString(params);
}
@Override
public Attachment execute(CommandContext commandContext) {

View File

@ -95,10 +95,10 @@
<groupId>cn.axzo.maokai</groupId>
<artifactId>maokai-api</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.tyr</groupId>
<artifactId>tyr-api</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.axzo.tyr</groupId>-->
<!-- <artifactId>tyr-api</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.axzo.karma</groupId>
<artifactId>karma-api</artifactId>

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.server.common.aspectj;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.TraceUtil;
import cn.axzo.workflow.server.common.annotation.RepeatSubmit;
import cn.axzo.workflow.server.common.config.RepeatSubmitResolver;
import cn.axzo.workflow.server.common.util.RedisUtils;
@ -81,7 +82,7 @@ public class RepeatSubmitAspect implements Ordered {
String key = RedisUtils.getCacheObject(cacheRepeatKey);
if (key == null) {
RedisUtils.setCacheObject(cacheRepeatKey, "", Duration.ofMillis(interval));
RedisUtils.setCacheObject(cacheRepeatKey, TraceUtil.traceId(), Duration.ofMillis(interval));
KEY_CACHE.set(cacheRepeatKey);
} else {
log.warn("{}", repeatSubmit.message());

View File

@ -1,6 +1,5 @@
package cn.axzo.workflow.server.common.filter;
import cn.azxo.framework.common.constatns.Constants;
import cn.hutool.core.util.IdUtil;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
@ -9,6 +8,7 @@ import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static cn.axzo.workflow.common.constant.LogFieldConstants.X_REQUEST_ID;
import static cn.azxo.framework.common.constatns.Constants.CTX_LOG_ID_MDC;
/**
* Http接口日志记录
@ -44,18 +45,18 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered
} else {
MDC.put(X_REQUEST_ID, requestId);
}
String ctxLogId = request.getHeader(Constants.CTX_LOG_ID_MDC);
String ctxLogId = request.getHeader(CTX_LOG_ID_MDC);
if (Strings.isNullOrEmpty(ctxLogId)) {
MDC.put(Constants.CTX_LOG_ID_MDC, getTraceId());
MDC.put(CTX_LOG_ID_MDC, getTraceId());
} else {
MDC.put(Constants.CTX_LOG_ID_MDC, ctxLogId);
MDC.put(CTX_LOG_ID_MDC, ctxLogId);
}
try {
filterChain.doFilter(request, response);
} finally {
response.setHeader(Constants.CTX_LOG_ID_MDC, MDC.get(Constants.CTX_LOG_ID_MDC));
response.setHeader(X_REQUEST_ID, MDC.get(Constants.CTX_LOG_ID_MDC));
response.setHeader(CTX_LOG_ID_MDC, MDC.get(CTX_LOG_ID_MDC));
response.setHeader(X_REQUEST_ID, MDC.get(CTX_LOG_ID_MDC));
MDC.clear();
}
}
@ -64,4 +65,10 @@ public class HttpTraceLogFilter extends OncePerRequestFilter implements Ordered
String contextTraceId = TraceContext.traceId();
return Strings.isNullOrEmpty(contextTraceId) ? IdUtil.fastSimpleUUID() : contextTraceId;
}
public static String traceId() {
String xRequestId = MDC.get(X_REQUEST_ID);
return StringUtils.hasText(xRequestId) ? xRequestId : MDC.get(CTX_LOG_ID_MDC);
}
}

View File

@ -1,26 +0,0 @@
package cn.axzo.workflow.server.common.hook;
import org.springframework.context.SmartLifecycle;
/**
* TODO
*
* @author wangli
* @since 2024/6/6 14:35
*/
public class NacosShutdownHook implements SmartLifecycle {
@Override
public void start() {
}
@Override
public void stop() {
}
@Override
public boolean isRunning() {
return false;
}
}

View File

@ -135,7 +135,7 @@ public class RocketMqBpmActivityEventListener extends AbstractBpmnEventListener<
// 这个 ID 等于 ExecutionId
dto.setTriggerId(execution.getId());
dto.setActivityId(execution.getCurrentActivityId());
dto.setActivityName(((ExecutionEntityImpl) execution).getCurrentActivityName());
dto.setActivityName(execution.getCurrentFlowElement().getName());
ProcessInstance processInstance = getContext().getProcessInstance(() ->
runtimeService.createProcessInstanceQuery().processInstanceId(execution.getProcessInstanceId())
.includeProcessVariables().singleResult());

View File

@ -27,6 +27,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.cache.annotation.CachePut;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@ -268,7 +269,6 @@ public class BpmnProcessInstanceController implements ProcessInstanceApi {
@Operation(summary = "获取指定流程实例的流程变量")
@GetMapping("/cooperation-org")
@Override
@RepeatSubmit
public CommonResponse<Map<String, Object>> getProcessVariables(@NotBlank(message = "流程实例 ID 不能为空") @RequestParam String processInstanceId,
@Nullable String tenantId) {
HistoricProcessInstance processInstance = bpmnProcessInstanceService.getProcessInstance(processInstanceId,