Merge branch 'refs/heads/1.3.1-SNAPSHOT' into 1.3.2-SNAPSHOT

# Conflicts:
#	workflow-engine-server/src/main/java/cn/axzo/workflow/server/controller/listener/process/MessagePushProcessEventListener.java
This commit is contained in:
wangli 2024-04-11 21:24:51 +08:00
commit 4ff4b1b401
13 changed files with 2216 additions and 1853 deletions

View File

@ -2,7 +2,7 @@ package cn.axzo.workflow.core.common.event;
import cn.axzo.workflow.core.repository.entity.ExtAxApiLog;
import cn.axzo.workflow.core.service.ExtAxApiLogService;
import com.alibaba.fastjson.JSON;
import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
@ -41,8 +41,8 @@ public class ApiLogListener implements ApplicationListener<ApiLogEvent> {
ExtAxApiLog apiLog = new ExtAxApiLog();
apiLog.setTraceId(event.getTraceId());
apiLog.setApiUrl(event.getApiUrl());
apiLog.setRequestBody(JSON.toJSONString(event.getRequestBody()));
apiLog.setResponseBody(JSON.toJSONString(event.getResponseBody()));
apiLog.setRequestBody(JSONUtil.toJsonStr(event.getRequestBody()));
apiLog.setResponseBody(JSONUtil.toJsonStr(event.getResponseBody()));
apiLog.setTakeTime(event.getTakeTime());
apiLog.setType(event.getType());
apiLogService.insert(apiLog);

View File

@ -197,7 +197,7 @@ public final class BpmnJsonConverterUtil {
mainProcess.addFlowElement(convertJsonToElement(EndEvent.class, mainProcess));
// 解析前端传入的模型设计 json
List<String> lastNodeIds = create(bpmnJsonNode, mainProcess, bpmnModel, START_EVENT_ID);
List<String> lastNodeIds = create(bpmnJsonNode, mainProcess, bpmnModel, null, START_EVENT_ID);
if (CollectionUtils.isEmpty(lastNodeIds)) {
throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "未找到链接结束节点的节点数据");
@ -405,10 +405,115 @@ public final class BpmnJsonConverterUtil {
* @return 创建的节点的 ID
*/
private static List<String> create(BpmnJsonNode bpmnJsonNode, Process mainProcess,
BpmnModel bpmnModel, String... preNodeIds) {
BpmnModel bpmnModel, BpmnJsonNode defaultConditionConnectNode, String... preNodeIds) {
// 设置来源节点
bpmnJsonNode.setIncoming(Lists.newArrayList(preNodeIds));
Class<? extends BaseElement> clz = chooseNodeClass(bpmnJsonNode);
// 根据 BpmnJsonNode 创建节点
FlowElement flowElement = convertJsonToElement(clz, bpmnJsonNode, mainProcess);
mainProcess.addFlowElement(flowElement);
connectPreNodes(bpmnJsonNode, mainProcess, preNodeIds);
// 只有网关才会涉及到 branch
List<String> branchLastNodeIds = new ArrayList<>();
if (!CollectionUtils.isEmpty(bpmnJsonNode.getBranches())) {
Gateway gateway = (Gateway) flowElement;
for (BpmnJsonNode branch : bpmnJsonNode.getBranches()) {
// branch == node_condition
BpmnJsonNode nextJsonNode =
(Objects.isNull(branch.getChildren()) || Objects.isNull(branch.getChildren().getType())
|| Objects.equals(NODE_EMPTY, branch.getChildren().getType()))
? bpmnJsonNode.getChildren() : branch.getChildren();
if (Objects.isNull(nextJsonNode) || Objects.isNull(nextJsonNode.getId()) ||
(Objects.equals(NODE_EMPTY, nextJsonNode.getType()) &&
(Objects.isNull(nextJsonNode.getChildren()) || Objects.isNull(nextJsonNode.getChildren().getId())))) {
BpmnJsonNode tempEndNode = new BpmnJsonNode();
tempEndNode.setIncoming(Lists.newArrayList(gateway.getId()));
if (Objects.isNull(defaultConditionConnectNode)) {
tempEndNode.setId(END_EVENT_ID);
} else {
if (Objects.equals(defaultConditionConnectNode.getType(), NODE_EMPTY) && Objects.nonNull(defaultConditionConnectNode.getChildren())) {
tempEndNode.setId(defaultConditionConnectNode.getChildren().getId());
} else {
tempEndNode.setId(defaultConditionConnectNode.getId());
}
defaultConditionConnectNode = null;
}
nextJsonNode = tempEndNode;
} else {
if (Objects.equals(NODE_EMPTY, nextJsonNode.getType()) && Objects.nonNull(nextJsonNode.getChildren())) {
nextJsonNode = nextJsonNode.getChildren();
}
nextJsonNode.setIncoming(Lists.newArrayList(gateway.getId()));
// node_condition 放入计算节点的上级属性中方便顺序流转换器对条件进行处理
nextJsonNode.setPreJsonNode(branch);
}
SequenceFlow sequenceFlow = (SequenceFlow) convertJsonToElement(SequenceFlow.class, nextJsonNode,
mainProcess);
mainProcess.addFlowElement(sequenceFlow);
// 设置网关默认流
if (Objects.nonNull(branch.getProperty()) && Boolean.TRUE.equals(branch.getProperty().getDefaultBranch())) {
// 如果是默认流, 以防止前端输入错误, 强制置空
sequenceFlow.setConditionExpression(null);
gateway.setDefaultFlow(sequenceFlow.getId());
}
if (Objects.nonNull(branch.getChildren()) && StringUtils.hasLength(branch.getChildren().getId())
&& !Objects.equals(NODE_EMPTY, branch.getChildren().getType())) {
branchLastNodeIds.addAll(create(branch.getChildren(), mainProcess, bpmnModel,
Objects.isNull(defaultConditionConnectNode) ? bpmnJsonNode.getChildren() : defaultConditionConnectNode));
}
}
}
// 开始处理下级节点
BpmnJsonNode children = bpmnJsonNode.getChildren();
if (Objects.isNull(children)
|| (Objects.equals(NODE_EMPTY, children.getType()) && (Objects.isNull(children.getChildren()) || Objects.isNull(children.getChildren().getId())))
|| !StringUtils.hasLength(children.getId())) {
if (CollectionUtils.isEmpty(branchLastNodeIds)) {
return Lists.newArrayList(flowElement.getId());
} else {
return branchLastNodeIds;
}
} else {
if (Objects.equals(NODE_EMPTY, children.getType())
&& Objects.nonNull(children.getChildren())
&& Objects.nonNull(children.getChildren().getId())) {
children = children.getChildren();
}
if (CollectionUtils.isEmpty(branchLastNodeIds)) {
return create(children, mainProcess, bpmnModel, defaultConditionConnectNode, flowElement.getId());
}
return create(children, mainProcess, bpmnModel, defaultConditionConnectNode, branchLastNodeIds.toArray(new String[0]));
}
}
private static void connectPreNodes(BpmnJsonNode bpmnJsonNode, Process mainProcess, String[] preNodeIds) {
// 连接当前节点与前一个节点
if (Lists.newArrayList(preNodeIds).isEmpty()) {
// first time entrance, do nothing.
} else if (Lists.newArrayList(preNodeIds).size() == 1 && !NODE_CONDITION.equals(bpmnJsonNode.getType())) {
bpmnJsonNode.setPreJsonNode(null);
mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess));
} else {
// 将网关分支的最末级节点 ID 关联到网关的 children 节点上网关协议转换才算闭环
Arrays.stream(preNodeIds).forEach(income -> {
bpmnJsonNode.setIncoming(Lists.newArrayList(income));
bpmnJsonNode.setPreJsonNode(null);
FlowElement sequenceFlow = convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess);
mainProcess.addFlowElement(sequenceFlow);
});
}
}
private static Class<? extends BaseElement> chooseNodeClass(BpmnJsonNode bpmnJsonNode) {
Class<? extends BaseElement> clz;
switch (bpmnJsonNode.getType()) {
case NODE_STARTER:
@ -445,92 +550,7 @@ public final class BpmnJsonConverterUtil {
clz = NotSupportConverter.NotSupportFlowElement.class;
break;
}
// 根据 BpmnJsonNode 创建节点
FlowElement flowElement = convertJsonToElement(clz, bpmnJsonNode, mainProcess);
mainProcess.addFlowElement(flowElement);
if (Lists.newArrayList(preNodeIds).isEmpty()) {
// first time entrance, do nothing.
} else if (Lists.newArrayList(preNodeIds).size() == 1 && !NODE_CONDITION.equals(bpmnJsonNode.getType())) {
bpmnJsonNode.setPreJsonNode(null);
mainProcess.addFlowElement(convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess));
} else {
// 将网关分支的最末级节点 ID 关联到网关的 children 节点上网关协议转换才算闭环
Arrays.stream(preNodeIds).forEach(income -> {
bpmnJsonNode.setIncoming(Lists.newArrayList(income));
bpmnJsonNode.setPreJsonNode(null);
FlowElement sequenceFlow = convertJsonToElement(SequenceFlow.class, bpmnJsonNode, mainProcess);
mainProcess.addFlowElement(sequenceFlow);
});
}
// 只有网关才会涉及到 branch
List<String> branchLastNodeIds = new ArrayList<>();
if (!CollectionUtils.isEmpty(bpmnJsonNode.getBranches())) {
Gateway gateway = (Gateway) flowElement;
for (BpmnJsonNode branch : bpmnJsonNode.getBranches()) {
// branch == node_condition
BpmnJsonNode nextJsonNode =
(Objects.isNull(branch.getChildren()) || Objects.isNull(branch.getChildren().getType())
|| Objects.equals(NODE_EMPTY, branch.getChildren().getType()))
? bpmnJsonNode.getChildren() : branch.getChildren();
if (Objects.isNull(nextJsonNode) || Objects.isNull(nextJsonNode.getId()) ||
(Objects.equals(NODE_EMPTY, nextJsonNode.getType()) &&
(Objects.isNull(nextJsonNode.getChildren()) || Objects.isNull(nextJsonNode.getChildren().getId())))) {
BpmnJsonNode tempEndNode = new BpmnJsonNode();
tempEndNode.setIncoming(Lists.newArrayList(gateway.getId()));
tempEndNode.setId(END_EVENT_ID);
nextJsonNode = tempEndNode;
} else {
if (Objects.equals(NODE_EMPTY, nextJsonNode.getType()) && Objects.nonNull(nextJsonNode.getChildren())) {
nextJsonNode = nextJsonNode.getChildren();
}
nextJsonNode.setIncoming(Lists.newArrayList(gateway.getId()));
// node_condition 放入计算节点的上级属性中方便顺序流转换器对条件进行处理
nextJsonNode.setPreJsonNode(branch);
}
SequenceFlow sequenceFlow = (SequenceFlow) convertJsonToElement(SequenceFlow.class, nextJsonNode,
mainProcess);
mainProcess.addFlowElement(sequenceFlow);
// 设置网关默认流
if (Objects.nonNull(branch.getProperty()) && Boolean.TRUE.equals(branch.getProperty().getDefaultBranch())) {
// 如果是默认流, 以防止前端输入错误, 强制置空
sequenceFlow.setConditionExpression(null);
gateway.setDefaultFlow(sequenceFlow.getId());
}
if (Objects.nonNull(branch.getChildren()) && StringUtils.hasLength(branch.getChildren().getId())
&& !Objects.equals(NODE_EMPTY, branch.getChildren().getType())) {
branchLastNodeIds.addAll(create(branch.getChildren(), mainProcess, bpmnModel));
}
}
}
// 开始处理下级节点
BpmnJsonNode children = bpmnJsonNode.getChildren();
if (Objects.isNull(children)
|| (Objects.equals(NODE_EMPTY, children.getType()) && (Objects.isNull(children.getChildren()) || Objects.isNull(children.getChildren().getId())))
|| !StringUtils.hasLength(children.getId())) {
if (CollectionUtils.isEmpty(branchLastNodeIds)) {
return Lists.newArrayList(flowElement.getId());
} else {
return branchLastNodeIds;
}
} else {
if (Objects.equals(NODE_EMPTY, children.getType())
&& Objects.nonNull(children.getChildren())
&& Objects.nonNull(children.getChildren().getId())) {
children = children.getChildren();
}
if (CollectionUtils.isEmpty(branchLastNodeIds)) {
return create(children, mainProcess, bpmnModel, flowElement.getId());
}
return create(children, mainProcess, bpmnModel, branchLastNodeIds.toArray(new String[0]));
}
return clz;
}
private static FlowElement convertJsonToElement(Class<? extends BaseElement> clz, Process process) {

View File

@ -13,6 +13,8 @@ import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import java.io.Serializable;
@ -36,6 +38,7 @@ import static cn.axzo.workflow.core.engine.cmd.helper.CustomTaskHelper.validTask
*/
public class CustomApproveTaskCmd implements Command<Void>, Serializable {
private static final Logger log = LoggerFactory.getLogger(CustomApproveTaskCmd.class);
private final String taskId;
private final String advice;
/**
@ -81,6 +84,9 @@ public class CustomApproveTaskCmd implements Command<Void>, Serializable {
HistoricTaskInstance historicTaskInstance = taskQuery.taskId(taskId).singleResult();
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (Objects.isNull(task)) {
log.info("任务不存在: {}", taskId);
}
validTask(historicTaskInstance, (TaskEntity) task, approver);
if (StringUtils.hasLength(advice)) {

View File

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Set;
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.CARBON_COPY;
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.CARBON_COPY_COMPLETE;
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.NOTICE;
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.PENDING_COMPLETE;
import static cn.axzo.workflow.core.engine.event.MessagePushEventType.PENDING_PUSH;
@ -41,6 +42,7 @@ public class EngineNoticeEventListener extends AbstractFlowableEventListener {
.add(PENDING_PUSH)
.add(PENDING_COMPLETE)
.add(CARBON_COPY)
.add(CARBON_COPY_COMPLETE)
.add(SMS)
.build();

View File

@ -73,6 +73,8 @@ import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.task.api.Task;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Nullable;
@ -352,6 +354,7 @@ public class BpmnProcessInstanceServiceImpl implements BpmnProcessInstanceServic
}
@Override
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
public Boolean abortProcessInstance(BpmnProcessInstanceAbortDTO dto) {
CommandExecutor commandExecutor = springProcessEngineConfiguration.getCommandExecutor();
commandExecutor.execute(new CustomAbortProcessInstanceCmd(dto.getProcessInstanceId(), dto.getTenantId(),

View File

@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Objects;
/**
* Api Log 表操服务实现
@ -22,6 +23,12 @@ public class ExtAxApiLogServiceImpl implements ExtAxApiLogService {
@Override
public Long insert(ExtAxApiLog apiLog) {
if (Objects.isNull(apiLog.getRequestBody())) {
apiLog.setRequestBody("");
}
if (Objects.isNull(apiLog.getResponseBody())) {
apiLog.setResponseBody("");
}
apiLogMapper.insert(apiLog);
return apiLog.getId();
}

View File

@ -0,0 +1,3 @@
alter table ext_ax_api_log
modify response_body longblob null comment '响应参数';

View File

@ -17,6 +17,7 @@ import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
@ -44,8 +45,10 @@ public class RepeatSubmitAspect {
private static final ThreadLocal<String> KEY_CACHE = new ThreadLocal<>();
private static final String REPEAT_SUBMIT_KEY = "global:repeat_submit:";
public RepeatSubmitAspect(RepeatSubmitResolver repeatSubmitResolver) {this.repeatSubmitResolver =
repeatSubmitResolver;}
public RepeatSubmitAspect(RepeatSubmitResolver repeatSubmitResolver) {
this.repeatSubmitResolver =
repeatSubmitResolver;
}
@Before("@annotation(repeatSubmit)")
public void doBefore(JoinPoint point, RepeatSubmit repeatSubmit) throws Throwable {
@ -108,8 +111,10 @@ public class RepeatSubmitAspect {
*/
@AfterThrowing(value = "@annotation(repeatSubmit)", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, RepeatSubmit repeatSubmit, Exception e) {
RedisUtils.deleteObject(KEY_CACHE.get());
KEY_CACHE.remove();
if (StringUtils.hasText(KEY_CACHE.get())) {
RedisUtils.deleteObject(KEY_CACHE.get());
KEY_CACHE.remove();
}
}
/**

View File

@ -108,7 +108,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onNotice(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getNotice())
|| !StringUtils.hasLength(event.getNoticeConfig().getNotice().getNoticeMessageId())
|| !StringUtils.hasText(event.getNoticeConfig().getNotice().getNoticeMessageId())
|| Objects.isNull(event.getAssigners())) {
return;
}
@ -132,7 +132,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onPendingPush(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getPending())
|| !StringUtils.hasLength(event.getNoticeConfig().getPending().getPendingMessageId())
|| !StringUtils.hasText(event.getNoticeConfig().getPending().getPendingMessageId())
|| Objects.isNull(event.getAssigners())) {
return;
}
@ -158,7 +158,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onPendingComplete(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getPending())
|| !StringUtils.hasLength(event.getNoticeConfig().getPending().getPendingMessageId())) {
|| !StringUtils.hasText(event.getNoticeConfig().getPending().getPendingMessageId())) {
return;
}
if (log.isDebugEnabled()) {
@ -182,7 +182,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onCarbonCopy(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getCarbonCopy())
|| !StringUtils.hasLength(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
|| !StringUtils.hasText(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
return;
}
if (log.isDebugEnabled()) {
@ -211,7 +211,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onCarbonCopyComplete(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getCarbonCopy())
|| !StringUtils.hasLength(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
|| !StringUtils.hasText(event.getNoticeConfig().getCarbonCopy().getCarbonCopyMessageId())) {
return;
}
if (log.isDebugEnabled()) {
@ -233,7 +233,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
public void onSms(MessagePushEvent event) {
if (Objects.isNull(event.getNoticeConfig())
|| Objects.isNull(event.getNoticeConfig().getSms())
|| !StringUtils.hasLength(event.getNoticeConfig().getSms().getSmsId())
|| !StringUtils.hasText(event.getNoticeConfig().getSms().getSmsId())
|| Objects.isNull(event.getAssigners())) {
return;
}
@ -280,7 +280,7 @@ public class RocketMqMessagePushEventListener extends AbstractBpmnEventListener
variables.put(VAR_PROCESS_END_TIME, sdf.format(processInstance.getEndTime()));
}
variables.put(VAR_PROCESS_RESULT, processInstance.getResult().getDesc());
if (StringUtils.hasLength(event.getTaskId())) {
if (StringUtils.hasText(event.getTaskId())) {
List<HistoricTaskInstance> tasks =
historyService.createHistoricTaskInstanceQuery().taskId(event.getTaskId()).list();
if (!CollectionUtils.isEmpty(tasks)) {

View File

@ -17,8 +17,13 @@ import org.flowable.engine.delegate.event.FlowableCancelledEvent;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Objects;
import java.util.Optional;
/**
@ -28,9 +33,11 @@ import java.util.Optional;
* @since 2023/7/10 18:22
*/
@Slf4j
//@Component
@Component
@RefreshScope
public class MessagePushProcessEventListener extends AbstractBpmnEventListener<ProcessOperationContext> implements BpmnProcessEventListener, Ordered {
@Value("${workflow.carbonCopyTemplateCode}")
private String carbonCopyTemplateCode;
@Override
public void onCancelled(FlowableCancelledEvent event) {
if (log.isDebugEnabled()) {
@ -84,15 +91,25 @@ public class MessagePushProcessEventListener extends AbstractBpmnEventListener<P
MessagePushEventImpl messagePushEvent =
MessagePushEventBuilder.createEvent(MessagePushEventType.PENDING_COMPLETE, null, noticeConfig,
event.getProcessInstanceId(), null, null);
MessagePushEventImpl carbonCopyCompleteEvent =
MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY_COMPLETE, null, noticeConfig,
event.getProcessInstanceId(), null, null);
if (log.isDebugEnabled()) {
log.debug("发送完成待办的消息: {}", JSON.toJSONString(messagePushEvent));
log.debug("发送完成抄送的消息: {}", JSON.toJSONString(carbonCopyCompleteEvent));
}
eventDispatcher.dispatchEvent(carbonCopyCompleteEvent, processEngineConfiguration.getEngineCfgKey());
eventDispatcher.dispatchEvent(messagePushEvent, processEngineConfiguration.getEngineCfgKey());
if (Objects.nonNull(noticeConfig.getCarbonCopy())) {
if (!StringUtils.hasText(noticeConfig.getCarbonCopy().getCarbonCopyMessageId())) {
noticeConfig.getCarbonCopy().setCarbonCopyMessageId(carbonCopyTemplateCode);
}
MessagePushEventImpl carbonCopyCompleteEvent =
MessagePushEventBuilder.createEvent(MessagePushEventType.CARBON_COPY_COMPLETE, null, noticeConfig,
event.getProcessInstanceId(), null, null);
eventDispatcher.dispatchEvent(carbonCopyCompleteEvent, processEngineConfiguration.getEngineCfgKey());
if (log.isDebugEnabled()) {
log.debug("发送完成抄送的消息: {}", JSON.toJSONString(carbonCopyCompleteEvent));
}
}
});
}

View File

@ -1,6 +1,7 @@
package cn.axzo.workflow.server.controller.web;
import cn.axzo.workflow.client.feign.bpmn.ProcessInstanceApi;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceQueryDTO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceVO;
import cn.axzo.workflow.common.model.response.bpmn.process.ProcessNodeDetailVO;
@ -11,8 +12,10 @@ import cn.azxo.framework.common.model.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
@ -22,9 +25,16 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static cn.axzo.workflow.common.enums.BpmnProcessInstanceResultEnum.PROCESSING;
/**
* 测试接口
* @author wangli
* @since 2023/10/10 13:59
*/
@ -41,9 +51,13 @@ public class TestController {
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ProcessInstanceApi processInstanceApi;
@Autowired
private BpmnProcessInstanceService bpmnProcessInstanceService;
@RepeatSubmit
@GetMapping("/test")
@ -82,4 +96,32 @@ public class TestController {
return processInstanceVO.getData().getName();
}
@GetMapping("/system/operation/batch/abort")
public CommonResponse<Boolean> systemOperation(Long timestamp) {
if (Objects.isNull(timestamp)) {
timestamp = 1706198400000L;
}
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
.processInstanceBusinessStatus(PROCESSING.getStatus())
.startedBefore(new Date(timestamp))
.unfinished()
.list();
log.info("待系统中止的流程实例数: {}", list.size());
ExecutorService executorService = Executors.newFixedThreadPool(3);
list.forEach(i -> {
executorService.submit(() -> {
try {
log.info("当前中止的流程: {}", i.getId());
BpmnProcessInstanceAbortDTO abort = new BpmnProcessInstanceAbortDTO();
abort.setProcessInstanceId(i.getId());
abort.setReason("系统超时中止");
bpmnProcessInstanceService.abortProcessInstance(abort);
} catch (Exception e) {
log.warn("系统批量中止流程: {}, 发生异常: {}", i.getId(), e.getMessage());
}
});
});
return CommonResponse.success(true);
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff