反序列化问题。

This commit is contained in:
dengqichen 2024-12-17 18:24:30 +08:00
parent 99bee5f162
commit a2b26591a5
10 changed files with 187 additions and 7 deletions

View File

@ -5,12 +5,14 @@ import com.qqchen.deploy.backend.framework.controller.BaseController;
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowExecutionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowHistoricalInstancesDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceStartRequest;
import com.qqchen.deploy.backend.workflow.dto.WorkflowTemplateWithInstancesDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.query.WorkflowDefinitionQuery;
import com.qqchen.deploy.backend.workflow.query.WorkflowHistoricalInstancesQuery;
import com.qqchen.deploy.backend.workflow.query.WorkflowInstanceQuery;
import com.qqchen.deploy.backend.workflow.service.IWorkflowDefinitionService;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
@ -64,6 +66,11 @@ public class WorkflowInstanceApiController extends BaseController<WorkflowInstan
return Response.success(workflowInstanceService.findTemplatesWithRecentInstances(query));
}
@Operation(summary = "分页查询历史实例")
@GetMapping("/historical-instances")
public Response<Page<WorkflowHistoricalInstancesDTO>> historicalInstances(@RequestBody WorkflowHistoricalInstancesQuery query) {
return Response.success(workflowInstanceService.historicalInstances(query));
}
@Override
protected void exportData(HttpServletResponse response, List<WorkflowInstanceDTO> data) {

View File

@ -0,0 +1,16 @@
//package com.qqchen.deploy.backend.workflow.converter;
//
//import com.qqchen.deploy.backend.framework.converter.BaseConverter;
//import com.qqchen.deploy.backend.workflow.dto.WorkflowHistoricalInstancesDTO;
//import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
//import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
//import org.mapstruct.Mapper;
//
///**
// * 工作流定义转换器
// */
//@Mapper
//public interface WorkflowHistoricalInstancesConverter {
//
// WorkflowHistoricalInstancesDTO toDTO(WorkflowInstance workflowInstance);
//}

View File

@ -2,14 +2,24 @@ package com.qqchen.deploy.backend.workflow.converter;
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowHistoricalInstancesDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import org.mapstruct.Mapper;
import org.mapstruct.Named;
/**
* 工作流定义转换器
*/
@Mapper(config = BaseConverter.class)
public interface WorkflowInstanceConverter extends BaseConverter<WorkflowInstance, WorkflowInstanceDTO> {
@Override
@Named("toDto")
WorkflowInstanceDTO toDto(WorkflowInstance entity);
@Named("toHistoricalDto")
WorkflowHistoricalInstancesDTO toWorkflowHistoricalInstancesDTO(WorkflowInstance workflowInstance);
}

View File

@ -0,0 +1,14 @@
package com.qqchen.deploy.backend.workflow.dto;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class WorkflowHistoricalInstancesDTO extends WorkflowInstanceDTO {
private List<WorkflowNodeInstanceDTO> stages;
}

View File

@ -0,0 +1,17 @@
package com.qqchen.deploy.backend.workflow.query;
import com.qqchen.deploy.backend.framework.annotation.QueryField;
import com.qqchen.deploy.backend.framework.enums.QueryType;
import com.qqchen.deploy.backend.framework.query.BaseQuery;
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
public class WorkflowHistoricalInstancesQuery extends BaseQuery {
@QueryField(field = "workflowDefinitionId", type = QueryType.EQUAL)
private Long workflowDefinitionId;
}

View File

@ -2,6 +2,8 @@ package com.qqchen.deploy.backend.workflow.repository;
import com.qqchen.deploy.backend.framework.repository.IBaseRepository;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@ -22,4 +24,7 @@ public interface IWorkflowInstanceRepository extends IBaseRepository<WorkflowIns
List<WorkflowInstance> findByBusinessKey(String businessKey);
List<WorkflowInstance> findTop1ByWorkflowDefinitionIdOrderByCreateTimeDesc(Long workflowDefinitionId);
Page<WorkflowInstance> findByWorkflowDefinitionId(Long workflowDefinitionId, Pageable pageable);
}

View File

@ -16,4 +16,6 @@ public interface IWorkflowNodeInstanceRepository extends IBaseRepository<Workflo
WorkflowNodeInstance findByNodeId(String nodeId);
WorkflowNodeInstance findByProcessInstanceIdAndNodeId(String processInstanceId, String nodeId);
List<WorkflowNodeInstance> findByWorkflowInstanceId(Long workflowInstanceId);
}

View File

@ -1,12 +1,14 @@
package com.qqchen.deploy.backend.workflow.service;
import com.qqchen.deploy.backend.framework.service.IBaseService;
import com.qqchen.deploy.backend.workflow.dto.WorkflowHistoricalInstancesDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceStartRequest;
import com.qqchen.deploy.backend.workflow.dto.WorkflowTemplateWithInstancesDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.query.WorkflowDefinitionQuery;
import com.qqchen.deploy.backend.workflow.query.WorkflowHistoricalInstancesQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.data.domain.Page;
@ -62,4 +64,5 @@ public interface IWorkflowInstanceService extends IBaseService<WorkflowInstance,
Page<WorkflowTemplateWithInstancesDTO> findTemplatesWithRecentInstances(WorkflowDefinitionQuery query);
Page<WorkflowHistoricalInstancesDTO> historicalInstances(WorkflowHistoricalInstancesQuery query);
}

View File

@ -4,33 +4,39 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.workflow.converter.WorkflowInstanceConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowDefinitionDTO;
import com.qqchen.deploy.backend.workflow.converter.WorkflowNodeInstanceConverter;
import com.qqchen.deploy.backend.workflow.dto.WorkflowHistoricalInstancesDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceStartRequest;
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeInstanceDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowTemplateWithInstancesDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowDefinition;
import com.qqchen.deploy.backend.workflow.entity.WorkflowInstance;
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeInstance;
import com.qqchen.deploy.backend.workflow.enums.WorkflowInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.enums.WorkflowNodeInstanceStatusEnums;
import com.qqchen.deploy.backend.workflow.enums.WorkflowStatusEnums;
import com.qqchen.deploy.backend.workflow.query.WorkflowDefinitionQuery;
import com.qqchen.deploy.backend.workflow.query.WorkflowHistoricalInstancesQuery;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowDefinitionRepository;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowInstanceRepository;
import com.qqchen.deploy.backend.workflow.service.IWorkflowDefinitionService;
import com.qqchen.deploy.backend.workflow.repository.IWorkflowNodeInstanceRepository;
import com.qqchen.deploy.backend.workflow.service.IWorkflowInstanceService;
import com.qqchen.deploy.backend.workflow.util.FlowableUtils;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -62,6 +68,15 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
@Resource
private WorkflowInstanceConverter workflowInstanceConverter;
@Resource
private IWorkflowNodeInstanceRepository workflowNodeInstanceRepository;
@Resource
private RepositoryService repositoryService;
@Resource
private WorkflowNodeInstanceConverter workflowNodeInstanceConverter;
@Override
public WorkflowInstanceDTO createWorkflowInstance(Long workflowDefinitionId, String businessKey, ProcessInstance processInstance) {
WorkflowInstance workflowInstance = new WorkflowInstance();
@ -194,6 +209,39 @@ public class WorkflowInstanceServiceImpl extends BaseServiceImpl<WorkflowInstanc
return new PageImpl<>(result, definitionPage.getPageable(), definitionPage.getTotalElements());
}
@Override
public Page<WorkflowHistoricalInstancesDTO> historicalInstances(WorkflowHistoricalInstancesQuery query) {
Pageable pageable = PageRequest.of(query.getPageNum(), query.getPageSize());
Page<WorkflowInstance> workflowInstances = workflowInstanceRepository.findByWorkflowDefinitionId(query.getWorkflowDefinitionId(), pageable);
List<WorkflowHistoricalInstancesDTO> result = new ArrayList<>();
workflowInstances.getContent().stream().map(workflowInstance -> {
WorkflowHistoricalInstancesDTO workflowHistoricalInstancesDTO = workflowInstanceConverter.toWorkflowHistoricalInstancesDTO(workflowInstance);
BpmnModel bpmnModel = repositoryService.getBpmnModel(workflowInstance.getProcessDefinitionId());
Process process = bpmnModel.getMainProcess();
//排序
List<FlowElement> flowElements = FlowableUtils.sortFlowElements(process);
List<WorkflowNodeInstance> nodeInstances = workflowNodeInstanceRepository.findByWorkflowInstanceId(41L);
Map<String, WorkflowNodeInstance> nodeWorkflowNodeInstance = nodeInstances.stream().collect(Collectors.toMap(WorkflowNodeInstance::getNodeId, nodeInstance -> nodeInstance));
List<WorkflowNodeInstance> nodeResult = new ArrayList<>();
flowElements.forEach(v -> {
WorkflowNodeInstance workflowNodeInstance = nodeWorkflowNodeInstance.get(v.getId());
if (Objects.isNull(workflowNodeInstance)) {
WorkflowNodeInstance empty = new WorkflowNodeInstance();
empty.setStatus(WorkflowNodeInstanceStatusEnums.NOT_STARTED);
empty.setNodeId(v.getId());
empty.setNodeId(v.getName());
nodeResult.add(empty);
} else {
nodeResult.add(workflowNodeInstance);
}
});
workflowHistoricalInstancesDTO.setStages(workflowNodeInstanceConverter.toDtoList(nodeResult));
result.add(workflowHistoricalInstancesDTO);
return result;
}).collect(toList());
return new PageImpl<>(result, workflowInstances.getPageable(), workflowInstances.getTotalElements());
}
// private WorkflowInstanceDTO.ActivityInstance convertToActivityInstance(HistoricActivityInstance hai) {
// WorkflowInstanceDTO.ActivityInstance ai = new WorkflowInstanceDTO.ActivityInstance();
// ai.setId(hai.getId());

View File

@ -0,0 +1,58 @@
package com.qqchen.deploy.backend.workflow.util;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.StartEvent;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
public class FlowableUtils {
public static List<FlowElement> sortFlowElements(Process process) {
List<FlowElement> sortedElements = new ArrayList<>();
Queue<FlowElement> queue = new LinkedList<>();
Set<String> visited = new HashSet<>();
// 1. 找到开始节点
FlowElement startEvent = process.getFlowElements().stream()
.filter(element -> element instanceof StartEvent)
.findFirst()
.orElseThrow(() -> new RuntimeException("No start event found"));
// 2. 从开始节点开始遍历
queue.offer(startEvent);
visited.add(startEvent.getId());
while (!queue.isEmpty()) {
FlowElement current = queue.poll();
sortedElements.add(current);
// 3. 获取当前节点的所有出口连线
List<SequenceFlow> outgoingFlows = process.getFlowElements().stream()
.filter(element -> element instanceof SequenceFlow)
.map(element -> (SequenceFlow) element)
.filter(flow -> flow.getSourceRef().equals(current.getId()))
.collect(Collectors.toList());
// 4. 按连线顺序添加下一个节点
for (SequenceFlow flow : outgoingFlows) {
FlowElement nextElement = process.getFlowElement(flow.getTargetRef());
if (nextElement != null && !visited.contains(nextElement.getId())) {
queue.offer(nextElement);
visited.add(nextElement.getId());
}
}
}
return sortedElements;
}
}