添加通知管理功能

This commit is contained in:
dengqichen 2025-10-22 20:25:30 +08:00
parent 3140456ee0
commit 9c8065dd53

View File

@ -1,6 +1,7 @@
package com.qqchen.deploy.backend.workflow.util;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants;
import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowDefinitionGraphEdge;
import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowDefinitionGraph;
@ -31,6 +32,8 @@ import java.util.Map;
@Component
public class BpmnConverter {
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* 将工作流定义图转换为Flowable XML
*
@ -144,8 +147,8 @@ public class BpmnConverter {
element.setName(node.getNodeName());
}
// 步骤2.5配置节点的特定属性
configureFlowElement(element, node, process);
// 步骤2.5配置节点的特定属性传递原始节点ID和sanitized ID
configureFlowElement(element, node, process, validId);
// 步骤2.6将节点添加到流程中
process.addFlowElement(element);
@ -155,8 +158,15 @@ public class BpmnConverter {
}
}
/**
* 直接使用前端生成的节点 ID
* 前端已经生成了符合 NCName 规范的 ID sid_265bc83e_9e7f_4acf_bd25_cf04c868a5da
*
* @param id 前端生成的节点 ID
* @return 节点 ID直接返回
*/
private String sanitizeId(String id) {
return "NODE_" + id.replaceAll("[^a-zA-Z0-9-_.]", "_");
return id;
}
/**
@ -165,14 +175,15 @@ public class BpmnConverter {
* @param element 流程节点元素
* @param node 工作流节点定义
* @param process 当前流程
* @param validId sanitized 后的节点 ID
*/
private void configureFlowElement(FlowElement element, WorkflowDefinitionGraphNode node, Process process) {
private void configureFlowElement(FlowElement element, WorkflowDefinitionGraphNode node, Process process, String validId) {
// 步骤1配置执行监听器
Map<String, List<ExtensionElement>> extensionElements = configureExecutionListeners(element);
// 步骤2根据节点类型进行特定配置
if (element instanceof ServiceTask) {
configureServiceTask((ServiceTask) element, node, process, extensionElements);
configureServiceTask((ServiceTask) element, node, process, extensionElements, validId);
} else {
element.setExtensionElements(extensionElements);
}
@ -229,20 +240,50 @@ public class BpmnConverter {
* @param node 工作流节点定义
* @param process 当前流程
* @param extensionElements 扩展元素
* @param validId sanitized 后的节点 ID
*/
private void configureServiceTask(ServiceTask serviceTask, WorkflowDefinitionGraphNode node, Process process, Map<String, List<ExtensionElement>> extensionElements) {
// if (node.getPanelVariables() != null && node.getPanelVariables().has("delegate")) {
// String delegate = node.getPanelVariables().get("delegate").asText();
// serviceTask.setImplementationType("delegateExpression");
// serviceTask.setImplementation(delegate);
// }
private void configureServiceTask(ServiceTask serviceTask, WorkflowDefinitionGraphNode node, Process process, Map<String, List<ExtensionElement>> extensionElements, String validId) {
// 设置 delegateExpression根据节点类型映射
String delegateExpression = getDelegateExpression(node.getNodeCode());
if (delegateExpression != null && !delegateExpression.isEmpty()) {
serviceTask.setImplementationType("delegateExpression");
serviceTask.setImplementation(delegateExpression);
}
addExecutionVariables(extensionElements, node);
// 添加 field 字段nodeId, configs, inputMapping
addExecutionVariables(extensionElements, node, validId);
// 添加重试策略
addRetryStrategy(extensionElements);
serviceTask.setExtensionElements(extensionElements);
addErrorBoundaryEventHandler(process, serviceTask);
}
/**
* 根据节点类型获取对应的 delegateExpression
*
* @param nodeCode 节点类型编码
* @return delegateExpression 字符串
*/
private String getDelegateExpression(String nodeCode) {
switch (nodeCode) {
case "JENKINS_BUILD":
return "${jenkinsBuildDelegate}";
case "NOTIFICATION":
return "${notificationDelegate}";
case "SCRIPT_NODE":
return "${shellDelegate}";
case "APPROVAL_NODE":
return "${approvalDelegate}";
case "DEPLOY_NODE":
return "${deployDelegate}";
default:
log.warn("未知的节点类型: {}, 将不设置 delegateExpression", nodeCode);
return null;
}
}
/**
* 创建扩展属性
*
@ -258,65 +299,67 @@ public class BpmnConverter {
}
/**
* 添加执行实例级变量
* 添加执行实例级变量field 字段
*
* @param extensionElements 扩展元素
* @param node 工作流节点定义
* @param validId sanitized 后的节点 ID
*/
private void addExecutionVariables(Map<String, List<ExtensionElement>> extensionElements, WorkflowDefinitionGraphNode node) {
// 添加panelVariables变量
// if (node.getPanelVariables() != null) {
// ExtensionElement fieldElement = new ExtensionElement();
// fieldElement.setName("field");
// fieldElement.setNamespace("http://flowable.org/bpmn");
// fieldElement.setNamespacePrefix("flowable");
//
// // 创建field的子元素string
// ExtensionElement stringElement = new ExtensionElement();
// stringElement.setName("string");
// stringElement.setNamespace("http://flowable.org/bpmn");
// stringElement.setNamespacePrefix("flowable");
// // 直接设置JSON内容不使用CDATA
// stringElement.setElementText(node.getPanelVariables().toString());
//
// // 设置field的name属性
// Map<String, List<ExtensionAttribute>> fieldAttributes = new HashMap<>();
// fieldAttributes.put("name", Collections.singletonList(createAttribute("name", "panelVariables")));
// fieldElement.setAttributes(fieldAttributes);
//
// // 添加string子元素到field
// fieldElement.addChildElement(stringElement);
//
// // 添加field到extensionElements
// extensionElements.computeIfAbsent("field", k -> new ArrayList<>()).add(fieldElement);
// }
private void addExecutionVariables(Map<String, List<ExtensionElement>> extensionElements, WorkflowDefinitionGraphNode node, String validId) {
try {
// 1. 添加 nodeId field
extensionElements.computeIfAbsent("field", k -> new ArrayList<>())
.add(createFieldElement("nodeId", validId));
// 添加localVariables变量
// if (node.getLocalVariables() != null) {
// ExtensionElement fieldElement = new ExtensionElement();
// fieldElement.setName("field");
// fieldElement.setNamespace("http://flowable.org/bpmn");
// fieldElement.setNamespacePrefix("flowable");
//
// // 创建field的子元素string
// ExtensionElement stringElement = new ExtensionElement();
// stringElement.setName("string");
// stringElement.setNamespace("http://flowable.org/bpmn");
// stringElement.setNamespacePrefix("flowable");
// // 直接设置JSON内容不使用CDATA
// stringElement.setElementText(node.getLocalVariables().toString());
//
// // 设置field的name属性
// Map<String, List<ExtensionAttribute>> fieldAttributes = new HashMap<>();
// fieldAttributes.put("name", Collections.singletonList(createAttribute("name", "localVariables")));
// fieldElement.setAttributes(fieldAttributes);
//
// // 添加string子元素到field
// fieldElement.addChildElement(stringElement);
//
// // 添加field到extensionElements
// extensionElements.computeIfAbsent("field", k -> new ArrayList<>()).add(fieldElement);
// }
// 2. 添加 configs field
if (node.getConfigs() != null) {
String configsJson = objectMapper.writeValueAsString(node.getConfigs());
extensionElements.computeIfAbsent("field", k -> new ArrayList<>())
.add(createFieldElement("configs", configsJson));
}
// 3. 添加 inputMapping field
if (node.getInputMapping() != null) {
String inputMappingJson = objectMapper.writeValueAsString(node.getInputMapping());
extensionElements.computeIfAbsent("field", k -> new ArrayList<>())
.add(createFieldElement("inputMapping", inputMappingJson));
}
} catch (Exception e) {
log.error("添加执行变量失败: {}", node.getNodeName(), e);
throw new RuntimeException("添加执行变量失败: " + e.getMessage(), e);
}
}
/**
* 创建 field 扩展元素
*
* @param fieldName 字段名
* @param fieldValue 字段值
* @return field 扩展元素
*/
private ExtensionElement createFieldElement(String fieldName, String fieldValue) {
// 创建 field 元素
ExtensionElement fieldElement = new ExtensionElement();
fieldElement.setName("field");
fieldElement.setNamespace("http://flowable.org/bpmn");
fieldElement.setNamespacePrefix("flowable");
// 设置 field name 属性
Map<String, List<ExtensionAttribute>> fieldAttributes = new HashMap<>();
fieldAttributes.put("name", Collections.singletonList(createAttribute("name", fieldName)));
fieldElement.setAttributes(fieldAttributes);
// 创建 string 子元素
ExtensionElement stringElement = new ExtensionElement();
stringElement.setName("string");
stringElement.setNamespace("http://flowable.org/bpmn");
stringElement.setNamespacePrefix("flowable");
stringElement.setElementText(fieldValue);
// 添加 string 子元素到 field
fieldElement.addChildElement(stringElement);
return fieldElement;
}
/**
@ -494,8 +537,8 @@ public class BpmnConverter {
log.debug("转换连线: from {} to {}", edge.getFrom(), edge.getTo());
SequenceFlow flow = new SequenceFlow();
String flowId = "FLOW_" + edge.getId().replaceAll("[^a-zA-Z0-9-_.]", "_");
flow.setId(flowId);
// 直接使用前端生成的 edge ID前端已经生成了 eid_ 开头的 ID
flow.setId(edge.getId());
flow.setName(edge.getName());
flow.setSourceRef(idMapping.get(edge.getFrom()));
flow.setTargetRef(idMapping.get(edge.getTo()));
@ -508,13 +551,6 @@ public class BpmnConverter {
}
}
// // 添加 take 事件监听器
// Map<String, List<ExtensionElement>> extensionElements = new HashMap<>();
// List<ExtensionElement> executionListeners = new ArrayList<>();
// executionListeners.add(createExecutionListener("take", "${sequenceFlowTakeListener}"));
// extensionElements.put("executionListener", executionListeners);
// flow.setExtensionElements(extensionElements);
process.addFlowElement(flow);
}
}