优化flowable流程和节点状态查询
This commit is contained in:
@@ -79,17 +79,6 @@ public class ProcessController implements IFlowableFeignClient {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流程定义节点详细信息(直接传流程定义ID)
|
||||
*/
|
||||
@GetMapping("/listNodesByProcessDefinitionId")
|
||||
public SdmResponse<List<NodeStructureInfo>> listNodesByProcessDefinitionId(
|
||||
@RequestParam String processDefinitionId) {
|
||||
|
||||
return processService.getNodesByProcessDefinitionId(processDefinitionId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除所有流程部署
|
||||
*/
|
||||
@@ -142,8 +131,8 @@ public class ProcessController implements IFlowableFeignClient {
|
||||
* 根据流程实例 ID 查询流程状态以及节点状态
|
||||
*/
|
||||
@GetMapping("/getProcessAndNodeDetailByInstanceId")
|
||||
public SdmResponse<ProcessInstanceDetailResponse> getProcessAndNodeDetailByInstanceId(@RequestParam String processInstanceId) {
|
||||
return processService.getProcessAndNodeDetailByInstanceId(processInstanceId);
|
||||
public SdmResponse<ProcessInstanceDetailResponse> getProcessAndNodeDetailByInstanceId(@RequestParam String processDefinitionId,@RequestParam(required = false) String processInstanceId) {
|
||||
return processService.getProcessAndNodeDetailByInstanceId(processDefinitionId,processInstanceId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,64 +108,6 @@ public class ProcessService {
|
||||
return SdmResponse.success(resp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程定义ID获取节点信息
|
||||
*/
|
||||
public SdmResponse<List<NodeStructureInfo>> getNodesByProcessDefinitionId(String processDefinitionId) {
|
||||
List<FlowNode> orderedNodes = getOrderedFlowNodes(processDefinitionId);
|
||||
return SdmResponse.success(orderedNodes.stream()
|
||||
.map(this::buildNodeStructureInfo)
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
private NodeStructureInfo buildNodeStructureInfo(FlowNode node) {
|
||||
NodeStructureInfo info = new NodeStructureInfo();
|
||||
info.setId(node.getId());
|
||||
info.setName(node.getName() != null ? node.getName() : "");
|
||||
info.setType(node.getClass().getSimpleName());
|
||||
|
||||
// 后续节点
|
||||
info.setNextNodeIds(
|
||||
node.getOutgoingFlows().stream()
|
||||
.map(SequenceFlow::getTargetRef)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
// 扩展属性
|
||||
if (node.getExtensionElements() != null) {
|
||||
List<ExtensionElement> extList = node.getExtensionElements().get(FlowableConfig.EXECUTECONFIG);
|
||||
if (extList != null && !extList.isEmpty()) {
|
||||
info.setExecuteConfig(extList.get(0).getElementText());
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
// 将 extensionElements 转成可阅读的 map
|
||||
private Object parseExtensionElements(Map<String, List<ExtensionElement>> extMap) {
|
||||
if (extMap == null || extMap.isEmpty()) return Collections.emptyMap();
|
||||
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
|
||||
extMap.forEach((key, extList) -> {
|
||||
List<Map<String, Object>> values = new ArrayList<>();
|
||||
|
||||
for (ExtensionElement ext : extList) {
|
||||
Map<String, Object> item = new LinkedHashMap<>();
|
||||
item.put("name", ext.getName());
|
||||
item.put("namespace", ext.getNamespacePrefix());
|
||||
item.put("elementText", ext.getElementText());
|
||||
item.put("attributes", ext.getAttributes());
|
||||
|
||||
values.add(item);
|
||||
}
|
||||
|
||||
result.put(key, values);
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public void deleteAllDeployments() {
|
||||
repositoryService.createDeploymentQuery()
|
||||
@@ -199,7 +141,7 @@ public class ProcessService {
|
||||
/**
|
||||
* 查询流程实例及所有节点的详细状态(返回结构化 DTO)
|
||||
*/
|
||||
public SdmResponse<ProcessInstanceDetailResponse> getProcessAndNodeDetailByInstanceId(String processInstanceId) {
|
||||
public SdmResponse<ProcessInstanceDetailResponse> getProcessAndNodeDetailByInstanceId(String processDefinitionId,String processInstanceId) {
|
||||
ProcessInstanceInfo processInfo = buildProcessInstanceInfo(processInstanceId);
|
||||
List<NodeDetailInfo> nodes = buildNodeDetails(processInstanceId, processInfo.getProcessDefinitionId());
|
||||
|
||||
@@ -267,6 +209,54 @@ public class ProcessService {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程定义 ID,按流程执行顺序(BFS)返回所有可达的 FlowNode
|
||||
*/
|
||||
private List<FlowNode> getOrderedFlowNodes(String processDefinitionId) {
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
if (bpmnModel == null || bpmnModel.getMainProcess() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Process process = bpmnModel.getMainProcess();
|
||||
|
||||
// 找开始事件
|
||||
StartEvent startEvent = process.findFlowElementsOfType(StartEvent.class, false)
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (startEvent == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// BFS 遍历
|
||||
List<FlowNode> orderedNodes = new ArrayList<>();
|
||||
Queue<FlowNode> queue = new LinkedList<>();
|
||||
Set<String> visited = new HashSet<>();
|
||||
|
||||
queue.offer(startEvent);
|
||||
visited.add(startEvent.getId());
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
FlowNode current = queue.poll();
|
||||
orderedNodes.add(current);
|
||||
|
||||
// 对 outgoingFlows 排序可选(保证并行分支顺序稳定)
|
||||
current.getOutgoingFlows().stream()
|
||||
.sorted(Comparator.comparing(SequenceFlow::getId)) // 可选:提升顺序稳定性
|
||||
.forEach(flow -> {
|
||||
String targetRef = flow.getTargetRef();
|
||||
FlowElement element = process.getFlowElement(targetRef);
|
||||
if (element instanceof FlowNode && visited.add(targetRef)) {
|
||||
queue.offer((FlowNode) element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return orderedNodes;
|
||||
}
|
||||
|
||||
// --- 判断流程是否运行中 ---
|
||||
private boolean isProcessRunning(String processInstanceId) {
|
||||
return runtimeService.createProcessInstanceQuery()
|
||||
@@ -315,6 +305,31 @@ public class ProcessService {
|
||||
return detail;
|
||||
}
|
||||
|
||||
private NodeStructureInfo buildNodeStructureInfo(FlowNode node) {
|
||||
NodeStructureInfo info = new NodeStructureInfo();
|
||||
info.setId(node.getId());
|
||||
info.setName(node.getName() != null ? node.getName() : "");
|
||||
info.setType(node.getClass().getSimpleName());
|
||||
|
||||
// 后续节点
|
||||
info.setNextNodeIds(
|
||||
node.getOutgoingFlows().stream()
|
||||
.map(SequenceFlow::getTargetRef)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
// 扩展属性
|
||||
if (node.getExtensionElements() != null) {
|
||||
List<ExtensionElement> extList = node.getExtensionElements().get(FlowableConfig.EXECUTECONFIG);
|
||||
if (extList != null && !extList.isEmpty()) {
|
||||
info.setExecuteConfig(extList.get(0).getElementText());
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
// --- 工具方法:格式化耗时(毫秒 → 可读字符串)---
|
||||
private String formatDuration(long millis) {
|
||||
long seconds = millis / 1000;
|
||||
@@ -328,53 +343,7 @@ public class ProcessService {
|
||||
return String.format("%ds", seconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据流程定义 ID,按流程执行顺序(BFS)返回所有可达的 FlowNode
|
||||
*/
|
||||
private List<FlowNode> getOrderedFlowNodes(String processDefinitionId) {
|
||||
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
|
||||
if (bpmnModel == null || bpmnModel.getMainProcess() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
Process process = bpmnModel.getMainProcess();
|
||||
|
||||
// 找开始事件
|
||||
StartEvent startEvent = process.findFlowElementsOfType(StartEvent.class, false)
|
||||
.stream()
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (startEvent == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// BFS 遍历
|
||||
List<FlowNode> orderedNodes = new ArrayList<>();
|
||||
Queue<FlowNode> queue = new LinkedList<>();
|
||||
Set<String> visited = new HashSet<>();
|
||||
|
||||
queue.offer(startEvent);
|
||||
visited.add(startEvent.getId());
|
||||
|
||||
while (!queue.isEmpty()) {
|
||||
FlowNode current = queue.poll();
|
||||
orderedNodes.add(current);
|
||||
|
||||
// 对 outgoingFlows 排序可选(保证并行分支顺序稳定)
|
||||
current.getOutgoingFlows().stream()
|
||||
.sorted(Comparator.comparing(SequenceFlow::getId)) // 可选:提升顺序稳定性
|
||||
.forEach(flow -> {
|
||||
String targetRef = flow.getTargetRef();
|
||||
FlowElement element = process.getFlowElement(targetRef);
|
||||
if (element instanceof FlowNode && visited.add(targetRef)) {
|
||||
queue.offer((FlowNode) element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return orderedNodes;
|
||||
}
|
||||
|
||||
public void continueServiceTask(@RequestBody CompleteTaskReq req) {
|
||||
log.info("开始继续服务任务处理, 请求参数: {}", req);
|
||||
|
||||
Reference in New Issue
Block a user