增加生成后端服务代码。
This commit is contained in:
parent
197439a381
commit
332f27fac1
@ -52,6 +52,16 @@ public interface IJenkinsServiceIntegration extends IExternalSystemIntegration {
|
|||||||
*/
|
*/
|
||||||
JenkinsBuildStatus getBuildStatus(ExternalSystem externalSystem, String jobName, Integer buildNumber);
|
JenkinsBuildStatus getBuildStatus(ExternalSystem externalSystem, String jobName, Integer buildNumber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取构建详细信息
|
||||||
|
*
|
||||||
|
* @param externalSystem Jenkins系统配置
|
||||||
|
* @param jobName 任务名称
|
||||||
|
* @param buildNumber 构建编号
|
||||||
|
* @return 构建详细信息
|
||||||
|
*/
|
||||||
|
JenkinsBuildResponse getBuildDetails(ExternalSystem externalSystem, String jobName, Integer buildNumber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询所有视图
|
* 查询所有视图
|
||||||
*
|
*
|
||||||
|
|||||||
@ -419,6 +419,56 @@ public class JenkinsServiceIntegrationImpl implements IJenkinsServiceIntegration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JenkinsBuildResponse getBuildDetails(ExternalSystem externalSystem, String jobName, Integer buildNumber) {
|
||||||
|
try {
|
||||||
|
// 构建 tree 参数,只获取我们需要的字段
|
||||||
|
String treeQuery = "number,url,result,duration,timestamp,building," +
|
||||||
|
"changeSets[items[commitId,author,message]]," +
|
||||||
|
"artifacts[fileName,relativePath,displayPath]";
|
||||||
|
|
||||||
|
String url = UriComponentsBuilder.fromHttpUrl(externalSystem.getUrl())
|
||||||
|
.path("/job/")
|
||||||
|
.path(jobName)
|
||||||
|
.path("/")
|
||||||
|
.path(buildNumber.toString())
|
||||||
|
.path("/api/json")
|
||||||
|
.queryParam("tree", treeQuery)
|
||||||
|
.build()
|
||||||
|
.toUriString();
|
||||||
|
|
||||||
|
HttpEntity<String> entity = new HttpEntity<>(createHeaders(externalSystem));
|
||||||
|
ResponseEntity<String> response = restTemplate.exchange(
|
||||||
|
url,
|
||||||
|
HttpMethod.GET,
|
||||||
|
entity,
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
|
||||||
|
// 打印原始响应用于调试
|
||||||
|
log.info("Jenkins build details raw response: {}", response.getBody());
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
JenkinsBuildResponse buildResponse = mapper.readValue(response.getBody(), JenkinsBuildResponse.class);
|
||||||
|
|
||||||
|
// 清理URL,移除基础URL部分
|
||||||
|
if (buildResponse.getUrl() != null) {
|
||||||
|
String baseUrl = StringUtils.removeEnd(externalSystem.getUrl(), "/");
|
||||||
|
buildResponse.setUrl(buildResponse.getUrl().replace(baseUrl, ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buildResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("Failed to get build details: empty response");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to get build details: job={}, buildNumber={}, error={}",
|
||||||
|
jobName, buildNumber, e.getMessage(), e);
|
||||||
|
throw new RuntimeException("获取Jenkins构建详情失败: " + jobName + "#" + buildNumber, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String extractQueueId(String location) {
|
private String extractQueueId(String location) {
|
||||||
// location格式: http://jenkins-url/queue/item/12345/
|
// location格式: http://jenkins-url/queue/item/12345/
|
||||||
return location.replaceAll(".*/item/(\\d+)/.*", "$1");
|
return location.replaceAll(".*/item/(\\d+)/.*", "$1");
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import com.qqchen.deploy.backend.deploy.repository.IJenkinsJobRepository;
|
|||||||
import com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants;
|
import com.qqchen.deploy.backend.workflow.constants.WorkFlowConstants;
|
||||||
import com.qqchen.deploy.backend.workflow.dto.inputmapping.JenkinsBuildInputMapping;
|
import com.qqchen.deploy.backend.workflow.dto.inputmapping.JenkinsBuildInputMapping;
|
||||||
import com.qqchen.deploy.backend.workflow.dto.outputs.JenkinsBuildOutputs;
|
import com.qqchen.deploy.backend.workflow.dto.outputs.JenkinsBuildOutputs;
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeExecutionStatusEnum;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.engine.delegate.BpmnError;
|
import org.flowable.engine.delegate.BpmnError;
|
||||||
@ -49,31 +50,79 @@ public class JenkinsBuildDelegate extends BaseNodeDelegate<JenkinsBuildInputMapp
|
|||||||
Map<String, Object> configs,
|
Map<String, Object> configs,
|
||||||
JenkinsBuildInputMapping input
|
JenkinsBuildInputMapping input
|
||||||
) {
|
) {
|
||||||
log.info("Jenkins Build - serverId: {}, project: {}",
|
log.info("Jenkins Build - serverId: {}, jobName: {}",
|
||||||
input.getJenkinsServerId(), input.getProject());
|
input.getJenkinsServerId(), input.getProject());
|
||||||
|
|
||||||
// 1. 获取外部系统和Jenkins Job
|
// 1. 获取外部系统
|
||||||
ExternalSystem externalSystem = externalSystemRepository.findById(input.getJenkinsServerId().longValue())
|
ExternalSystem externalSystem = externalSystemRepository.findById(input.getJenkinsServerId().longValue())
|
||||||
.orElseThrow(() -> new RuntimeException("Jenkins服务器不存在: " + input.getJenkinsServerId()));
|
.orElseThrow(() -> new RuntimeException("Jenkins服务器不存在: " + input.getJenkinsServerId()));
|
||||||
|
|
||||||
// 2. 触发构建(这里简化处理,实际需要根据project获取jenkinsJob)
|
String jobName = input.getProject();
|
||||||
// TODO: 根据input.getProject()查找对应的JenkinsJob
|
|
||||||
|
// 2. 触发构建
|
||||||
Map<String, String> parameters = new HashMap<>();
|
Map<String, String> parameters = new HashMap<>();
|
||||||
// parameters.put("PROJECT", input.getProject());
|
// 可以根据需要添加构建参数
|
||||||
|
// parameters.put("BRANCH", "main");
|
||||||
|
|
||||||
// String queueId = jenkinsServiceIntegration.buildWithParameters(
|
String queueId = jenkinsServiceIntegration.buildWithParameters(
|
||||||
// externalSystem, input.getProject(), parameters);
|
externalSystem, jobName, parameters);
|
||||||
// JenkinsQueueBuildInfoResponse buildInfo = waitForBuildToStart(queueId);
|
|
||||||
// JenkinsBuildStatus status = pollBuildStatus(externalSystem, input.getProject(), buildInfo.getBuildNumber());
|
|
||||||
|
|
||||||
// 3. 构造输出结果
|
// 3. 等待构建从队列中开始
|
||||||
|
JenkinsQueueBuildInfoResponse buildInfo = waitForBuildToStart(queueId);
|
||||||
|
|
||||||
|
// 4. 轮询构建状态直到完成
|
||||||
|
// 注意:如果构建失败或被取消,pollBuildStatus 会抛出 BpmnError,触发错误边界事件
|
||||||
|
// 只有成功时才会返回到这里
|
||||||
|
JenkinsBuildStatus buildStatus = pollBuildStatus(externalSystem, jobName, buildInfo.getBuildNumber());
|
||||||
|
|
||||||
|
// 5. 获取构建详细信息(包括 duration, changeSets, artifacts)
|
||||||
|
com.qqchen.deploy.backend.deploy.integration.response.JenkinsBuildResponse buildDetails =
|
||||||
|
jenkinsServiceIntegration.getBuildDetails(externalSystem, jobName, buildInfo.getBuildNumber());
|
||||||
|
|
||||||
|
// 打印调试信息
|
||||||
|
log.info("Build details - changeSets: {}, artifacts: {}",
|
||||||
|
buildDetails.getChangeSets(), buildDetails.getArtifacts());
|
||||||
|
|
||||||
|
// 6. 构造输出结果(执行到这里说明构建成功)
|
||||||
JenkinsBuildOutputs outputs = new JenkinsBuildOutputs();
|
JenkinsBuildOutputs outputs = new JenkinsBuildOutputs();
|
||||||
outputs.setBuildStatus("SUCCESS"); // TODO: 从实际构建状态获取
|
|
||||||
outputs.setBuildNumber(123); // TODO: 从buildInfo获取
|
// 设置统一的执行状态为成功
|
||||||
outputs.setBuildUrl("http://jenkins.example.com/job/" + input.getProject() + "/123/");
|
outputs.setStatus(NodeExecutionStatusEnum.SUCCESS);
|
||||||
outputs.setGitCommitId("a3f5e8d2c4b1a5e9f2d3e7b8c9d1a2f3e4b5c6d7");
|
|
||||||
outputs.setBuildDuration(120);
|
// 设置 Jenkins 特有字段
|
||||||
outputs.setArtifactUrl("http://jenkins.example.com/job/" + input.getProject() + "/123/artifact/target/app.jar");
|
outputs.setBuildStatus(buildStatus.name());
|
||||||
|
outputs.setBuildNumber(buildInfo.getBuildNumber());
|
||||||
|
outputs.setBuildUrl(buildInfo.getBuildUrl());
|
||||||
|
|
||||||
|
// 从构建详情中提取信息
|
||||||
|
outputs.setBuildDuration(buildDetails.getDuration() != null ? buildDetails.getDuration().intValue() : 0);
|
||||||
|
|
||||||
|
// 提取 Git Commit ID(从 changeSets 中获取第一个)
|
||||||
|
if (buildDetails.getChangeSets() != null && !buildDetails.getChangeSets().isEmpty()) {
|
||||||
|
log.info("Found {} changeSets", buildDetails.getChangeSets().size());
|
||||||
|
var changeSet = buildDetails.getChangeSets().get(0);
|
||||||
|
if (changeSet.getItems() != null && !changeSet.getItems().isEmpty()) {
|
||||||
|
log.info("Found {} items in changeSet", changeSet.getItems().size());
|
||||||
|
outputs.setGitCommitId(changeSet.getItems().get(0).getCommitId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.warn("No changeSets found in build details");
|
||||||
|
}
|
||||||
|
if (outputs.getGitCommitId() == null) {
|
||||||
|
outputs.setGitCommitId("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取构建制品URL(如果有多个制品,拼接成逗号分隔的列表)
|
||||||
|
if (buildDetails.getArtifacts() != null && !buildDetails.getArtifacts().isEmpty()) {
|
||||||
|
log.info("Found {} artifacts", buildDetails.getArtifacts().size());
|
||||||
|
String artifactUrls = buildDetails.getArtifacts().stream()
|
||||||
|
.map(artifact -> buildInfo.getBuildUrl() + "artifact/" + artifact.getRelativePath())
|
||||||
|
.collect(java.util.stream.Collectors.joining(","));
|
||||||
|
outputs.setArtifactUrl(artifactUrls);
|
||||||
|
} else {
|
||||||
|
log.warn("No artifacts found in build details");
|
||||||
|
outputs.setArtifactUrl("");
|
||||||
|
}
|
||||||
|
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
@ -101,7 +150,7 @@ public class JenkinsBuildDelegate extends BaseNodeDelegate<JenkinsBuildInputMapp
|
|||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Build did not start within %d seconds", MAX_QUEUE_POLLS * QUEUE_POLL_INTERVAL));
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Build did not start within %d seconds", MAX_QUEUE_POLLS * QUEUE_POLL_INTERVAL));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pollBuildStatus(ExternalSystem externalSystem, String jobName, Integer buildNumber) {
|
private JenkinsBuildStatus pollBuildStatus(ExternalSystem externalSystem, String jobName, Integer buildNumber) {
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (attempts < MAX_BUILD_POLLS) {
|
while (attempts < MAX_BUILD_POLLS) {
|
||||||
try {
|
try {
|
||||||
@ -114,27 +163,34 @@ public class JenkinsBuildDelegate extends BaseNodeDelegate<JenkinsBuildInputMapp
|
|||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
// 构建成功,返回继续流程
|
// 构建成功,返回状态
|
||||||
return;
|
log.info("Jenkins build succeeded: job={}, buildNumber={}", jobName, buildNumber);
|
||||||
|
return status;
|
||||||
case FAILURE:
|
case FAILURE:
|
||||||
// 构建失败,抛出错误
|
// 构建失败,抛出错误(触发边界事件)
|
||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Jenkins build failed: job=%s, buildNumber=%d", jobName, buildNumber));
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR,
|
||||||
|
String.format("Jenkins build failed: job=%s, buildNumber=%d", jobName, buildNumber));
|
||||||
case ABORTED:
|
case ABORTED:
|
||||||
// 构建被取消,抛出错误
|
// 构建被取消,抛出错误(触发边界事件)
|
||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Jenkins build was aborted: job=%s, buildNumber=%d", jobName, buildNumber));
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR,
|
||||||
|
String.format("Jenkins build was aborted: job=%s, buildNumber=%d", jobName, buildNumber));
|
||||||
case IN_PROGRESS:
|
case IN_PROGRESS:
|
||||||
// 继续轮询
|
// 继续轮询
|
||||||
attempts++;
|
attempts++;
|
||||||
break;
|
break;
|
||||||
case NOT_FOUND:
|
case NOT_FOUND:
|
||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Jenkins build not found: job=%s, buildNumber=%d", jobName, buildNumber));
|
// 构建记录丢失,抛出系统异常
|
||||||
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR,
|
||||||
|
String.format("Jenkins build not found: job=%s, buildNumber=%d", jobName, buildNumber));
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, "Build status polling was interrupted");
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, "Build status polling was interrupted");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 超过最大轮询次数,视为超时
|
// 超过最大轮询次数,视为超时(系统异常)
|
||||||
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR, String.format("Jenkins build timed out after %d minutes: job=%s, buildNumber=%d", MAX_BUILD_POLLS * BUILD_POLL_INTERVAL / 60, jobName, buildNumber));
|
throw new BpmnError(WorkFlowConstants.WORKFLOW_EXEC_ERROR,
|
||||||
|
String.format("Jenkins build timed out after %d minutes: job=%s, buildNumber=%d",
|
||||||
|
MAX_BUILD_POLLS * BUILD_POLL_INTERVAL / 60, jobName, buildNumber));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,13 +46,15 @@ public class NotificationNodeDelegate extends BaseNodeDelegate<NotificationInput
|
|||||||
|
|
||||||
// 3. 返回成功结果
|
// 3. 返回成功结果
|
||||||
NotificationOutputs outputs = new NotificationOutputs();
|
NotificationOutputs outputs = new NotificationOutputs();
|
||||||
outputs.setStatus("SUCCESS");
|
outputs.setStatus(com.qqchen.deploy.backend.workflow.enums.NodeExecutionStatusEnum.SUCCESS);
|
||||||
|
outputs.setMessage("通知发送成功");
|
||||||
return outputs;
|
return outputs;
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to send notification", e);
|
log.error("Failed to send notification", e);
|
||||||
NotificationOutputs outputs = new NotificationOutputs();
|
NotificationOutputs outputs = new NotificationOutputs();
|
||||||
outputs.setStatus("FAILURE");
|
outputs.setStatus(com.qqchen.deploy.backend.workflow.enums.NodeExecutionStatusEnum.FAILURE);
|
||||||
|
outputs.setMessage("通知发送失败: " + e.getMessage());
|
||||||
return outputs;
|
return outputs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批节点输出
|
* 审批节点输出
|
||||||
@ -9,7 +10,8 @@ import lombok.Data;
|
|||||||
* @since 2025-10-22
|
* @since 2025-10-22
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ApprovalOutputs {
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class ApprovalOutputs extends BaseNodeOutputs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审批结果
|
* 审批结果
|
||||||
|
|||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.workflow.enums.NodeExecutionStatusEnum;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点输出基类
|
||||||
|
* 所有节点输出类的公共父类,包含统一的执行状态字段
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-10-22
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class BaseNodeOutputs {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点执行状态
|
||||||
|
* 用于流程条件判断,所有节点统一使用此字段
|
||||||
|
*/
|
||||||
|
private NodeExecutionStatusEnum status;
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jenkins构建节点输出
|
* Jenkins构建节点输出
|
||||||
@ -9,7 +10,8 @@ import lombok.Data;
|
|||||||
* @since 2025-10-22
|
* @since 2025-10-22
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class JenkinsBuildOutputs {
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class JenkinsBuildOutputs extends BaseNodeOutputs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建编号
|
* 构建编号
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通知节点输出
|
* 通知节点输出
|
||||||
@ -9,11 +10,12 @@ import lombok.Data;
|
|||||||
* @since 2025-10-22
|
* @since 2025-10-22
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class NotificationOutputs {
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class NotificationOutputs extends BaseNodeOutputs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行状态
|
* 通知发送结果详细信息
|
||||||
*/
|
*/
|
||||||
private String status;
|
private String message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
package com.qqchen.deploy.backend.workflow.dto.outputs;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shell脚本节点输出
|
* Shell脚本节点输出
|
||||||
@ -9,7 +10,8 @@ import lombok.Data;
|
|||||||
* @since 2025-10-22
|
* @since 2025-10-22
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ShellOutputs {
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class ShellOutputs extends BaseNodeOutputs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退出码
|
* 退出码
|
||||||
|
|||||||
@ -0,0 +1,51 @@
|
|||||||
|
package com.qqchen.deploy.backend.workflow.enums;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonValue;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点执行状态枚举
|
||||||
|
* 所有工作流节点的统一执行状态
|
||||||
|
*
|
||||||
|
* @author qqchen
|
||||||
|
* @since 2025-10-22
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum NodeExecutionStatusEnum {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行成功
|
||||||
|
*/
|
||||||
|
SUCCESS("SUCCESS", "执行成功"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行失败
|
||||||
|
*/
|
||||||
|
FAILURE("FAILURE", "执行失败");
|
||||||
|
|
||||||
|
@JsonValue
|
||||||
|
private final String code;
|
||||||
|
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
NodeExecutionStatusEnum(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据编码获取枚举
|
||||||
|
*
|
||||||
|
* @param code 状态编码
|
||||||
|
* @return 枚举实例
|
||||||
|
*/
|
||||||
|
public static NodeExecutionStatusEnum fromCode(String code) {
|
||||||
|
for (NodeExecutionStatusEnum status : values()) {
|
||||||
|
if (status.code.equals(code)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown NodeExecutionStatus code: " + code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user