diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/annotation/NodeTypeLocalVariablesBind.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/annotation/NodeTypeLocalVariablesBind.java new file mode 100644 index 00000000..9c01fe52 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/annotation/NodeTypeLocalVariablesBind.java @@ -0,0 +1,17 @@ +package com.qqchen.deploy.backend.workflow.annotation; + + +import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface NodeTypeLocalVariablesBind { + + + NodeTypeEnums type(); +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/api/WorkflowNodeDefinitionApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/api/WorkflowNodeDefinitionApiController.java index 56c4e7ec..3f3d0183 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/api/WorkflowNodeDefinitionApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/api/WorkflowNodeDefinitionApiController.java @@ -2,7 +2,9 @@ package com.qqchen.deploy.backend.workflow.api; import com.qqchen.deploy.backend.framework.api.Response; import com.qqchen.deploy.backend.framework.controller.BaseController; +import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionCreateDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO; +import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO; import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; import com.qqchen.deploy.backend.workflow.query.WorkflowNodeDefinitionQuery; @@ -25,10 +27,18 @@ import java.util.List; @RequestMapping("/api/v1/workflow/node-definition") @Tag(name = "工作流节点定义管理", description = "工作流节点定义管理相关接口") public class WorkflowNodeDefinitionApiController extends BaseController { - + @Resource private IWorkflowNodeDefinitionService workflowNodeDefinitionService; - + + + @Operation(summary = "根据节点类型获取节点定义") + @GetMapping("/defined") + public Response> defined() { + return Response.success(workflowNodeDefinitionService.defined()); + } + + @Operation(summary = "根据节点类型获取节点定义") @GetMapping("/type/{type}") public Response getByType( @@ -36,7 +46,7 @@ public class WorkflowNodeDefinitionApiController extends BaseController> listByCategory( @@ -44,13 +54,13 @@ public class WorkflowNodeDefinitionApiController extends BaseController> listAllEnabled() { return Response.success(workflowNodeDefinitionService.listAllEnabled()); } - + @Operation(summary = "启用节点定义") @PostMapping("/{id}/enable") public Response enable( @@ -59,7 +69,7 @@ public class WorkflowNodeDefinitionApiController extends BaseController disable( @@ -68,7 +78,7 @@ public class WorkflowNodeDefinitionApiController extends BaseController data) { // 暂不支持导出 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionCreateDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionCreateDTO.java new file mode 100644 index 00000000..3fec3748 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionCreateDTO.java @@ -0,0 +1,19 @@ +package com.qqchen.deploy.backend.workflow.dto; + +import com.fasterxml.jackson.databind.JsonNode; +import com.qqchen.deploy.backend.framework.dto.BaseDTO; +import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; +import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 工作流节点定义DTO + */ +@Data +@Schema(description = "工作流节点创建") +@EqualsAndHashCode(callSuper = true) +public class WorkflowNodeDefinitionCreateDTO extends WorkflowNodeDefinitionDTO { + +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionDTO.java index 2a9e454f..8b254b54 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionDTO.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeDefinitionDTO.java @@ -2,7 +2,9 @@ package com.qqchen.deploy.backend.workflow.dto; import com.fasterxml.jackson.databind.JsonNode; import com.qqchen.deploy.backend.framework.dto.BaseDTO; +import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; +import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -14,28 +16,31 @@ import lombok.EqualsAndHashCode; @Schema(description = "工作流节点定义") @EqualsAndHashCode(callSuper = true) public class WorkflowNodeDefinitionDTO extends BaseDTO { - + @Schema(description = "节点类型编码") - private String type; - + private NodeTypeEnums nodeType; + + @Schema(description = "节点编码") + private String nodeCode; + @Schema(description = "节点名称") - private String name; - + private String nodeName; + @Schema(description = "节点描述") private String description; - + @Schema(description = "节点分类") private NodeCategoryEnums category; - - @Schema(description = "Flowable配置JSON") - private JsonNode flowableConfig; - - @Schema(description = "X6图形配置JSON") - private JsonNode graphConfig; - @Schema(description = "排序号") - private Integer orderNum; - + @Schema(description = "节点UI") + private WorkflowNodeGraph graphVariables; + + @Schema(description = "节点属性d") + private JsonNode localVariables; + + @Schema(description = "节点表单") + private JsonNode fromVariables; + @Schema(description = "是否启用") private Boolean enabled; } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeTypeDefinedDTO.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeTypeDefinedDTO.java new file mode 100644 index 00000000..c91a3cde --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/WorkflowNodeTypeDefinedDTO.java @@ -0,0 +1,24 @@ +package com.qqchen.deploy.backend.workflow.dto; + +import com.fasterxml.jackson.databind.JsonNode; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * 工作流节点定义DTO + */ +@Data +@Schema(description = "工作流节点定义") +public class WorkflowNodeTypeDefinedDTO { + + @Schema(description = "节点编码") + private String nodeCode; + + @Schema(description = "节点名称") + private String nodeName; + + @Schema(description = "节点属性JSON SCHEMA") + private JsonNode panelVariablesSchema; + + private JsonNode localVariablesSchema; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/NodeDefinitionContainer.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/NodeDefinitionContainer.java deleted file mode 100644 index 9e12f3e2..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/NodeDefinitionContainer.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node; - -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.BaseEventNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.BaseNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.EndNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.StartNodeLocalVariables; -import lombok.Data; - -public class NodeDefinitionContainer extends BaseEventNodeLocalVariables { - - - - private BaseNodeLocalVariables - - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseEventNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseEventNodeLocalVariables.java deleted file mode 100644 index 2276a63f..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseEventNodeLocalVariables.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; - -import lombok.Data; - -/** - * 事件节点基础配置 - */ -@Data -public abstract class BaseEventNodeLocalVariables extends BaseNodeLocalVariables { - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseNodeLocalVariables.java index fb2e522b..8b5a06d8 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseNodeLocalVariables.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseNodeLocalVariables.java @@ -10,28 +10,10 @@ import lombok.Data; public class BaseNodeLocalVariables { @SchemaProperty( - title = "节点Code", - description = "工作流节点的Code", + title = "委派者", + description = "委派者", required = true ) - private String code; + private String delegate; - /** - * 节点名称 - */ - @SchemaProperty( - title = "节点名称", - description = "工作流节点的显示名称", - required = true - ) - private String name; - - /** - * 节点描述 - */ - @SchemaProperty( - title = "节点描述", - description = "工作流节点的详细描述" - ) - private String description; } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseTaskNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseTaskNodeLocalVariables.java deleted file mode 100644 index b0b7182b..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/BaseTaskNodeLocalVariables.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; - -import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; -import lombok.Data; - -/** - * 基础节点配置 - */ -@Data -public class BaseTaskNodeLocalVariables extends BaseNodeLocalVariables { - - @SchemaProperty( - title = "执行委派者", - description = "执行委派者", - required = true, - defaultValue = "${shellTaskDelegate}" - ) - private String delegate; - -// /** -// * 任务优先级(0-100) -// */ -// @SchemaProperty( -// title = "任务优先级", -// description = "工作流节点的任务优先级", -// minimum = 0, -// maximum = 100 -// ) -// private Integer priority; -// -// /** -// * 超时时间(秒) -// */ -// @SchemaProperty( -// title = "超时时间", -// description = "任务执行的最大时间(秒)", -// minimum = 1, -// maximum = 3600, -// defaultValue = "300" -// ) -// private Integer timeoutDuration; -// -// /** -// * 超时处理策略 -// */ -// @SchemaProperty( -// title = "超时处理策略", -// description = "任务超时后的处理策略", -// enumValues = {"FAIL", "CONTINUE", "RETRY"}, -// enumNames = {"失败", "继续", "重试"}, -// defaultValue = "FAIL" -// ) -// private String timeoutStrategy; -// -// /** -// * 重试次数 -// */ -// @SchemaProperty( -// title = "重试次数", -// description = "任务失败后的重试次数", -// minimum = 0, -// maximum = 10, -// defaultValue = "0" -// ) -// private Integer retryTimes; -// -// /** -// * 重试间隔(秒) -// */ -// @SchemaProperty( -// title = "重试间隔", -// description = "两次重试之间的等待时间(秒)", -// minimum = 1, -// maximum = 3600, -// defaultValue = "60" -// ) -// private Integer retryInterval; -// -// /** -// * 重试策略 -// */ -// @SchemaProperty( -// title = "重试策略", -// description = "任务重试的策略", -// enumValues = {"FIXED", "EXPONENTIAL"}, -// enumNames = {"固定间隔", "指数退避"}, -// defaultValue = "FIXED" -// ) -// private String retryStrategy; -// -// -// /** -// * 是否异步 -// */ -// @SchemaProperty( -// title = "是否异步", -// description = "节点是否以异步方式执行", -// defaultValue = "false" -// ) -// private Boolean async; -// -// /** -// * 是否独占 -// */ -// @SchemaProperty( -// title = "是否独占", -// description = "节点是否以独占方式执行", -// defaultValue = "true" -// ) -// private Boolean exclusive; -// -// /** -// * 文档说明 -// */ -// @SchemaProperty( -// title = "文档说明", -// description = "节点的详细文档说明" -// ) -// private String documentation; -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/EndNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/EndNodeLocalVariables.java deleted file mode 100644 index 13d4f8b1..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/EndNodeLocalVariables.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 结束节点配置 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class EndNodeLocalVariables extends BaseEventNodeLocalVariables { - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/GitCloneLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/GitCloneLocalVariables.java deleted file mode 100644 index a827f050..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/GitCloneLocalVariables.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; - -import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import java.util.Map; - -/** - * Git Clone任务配置 - * 继承TaskConfig以获取通用的任务配置(优先级、超时、重试等) - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class GitCloneLocalVariables extends BaseTaskNodeLocalVariables { - /** - * 仓库URL - */ - @SchemaProperty( - title = "仓库URL", - description = "Git仓库的URL地址", - required = true - ) - private String repositoryUrl; - - /** - * 分支或标签 - */ - @SchemaProperty( - title = "分支或标签", - description = "要克隆的分支、标签或提交ID", - defaultValue = "main" - ) - private String ref; - - /** - * 目标目录 - */ - @SchemaProperty( - title = "目标目录", - description = "代码克隆到的目标目录", - required = true - ) - private String targetDirectory; - - /** - * 是否递归克隆子模块 - */ - @SchemaProperty( - title = "递归克隆子模块", - description = "是否递归克隆Git子模块", - defaultValue = "false" - ) - private Boolean recursive; - - /** - * 克隆深度(0表示完整克隆) - */ - @SchemaProperty( - title = "克隆深度", - description = "克隆的历史深度,0表示完整克隆", - defaultValue = "1", - minimum = 0 - ) - private Integer depth; - - /** - * 身份验证类型(NONE, SSH_KEY, USERNAME_PASSWORD) - */ - @SchemaProperty( - title = "身份验证类型", - description = "Git仓库的身份验证方式", - enumValues = {"NONE", "SSH_KEY", "USERNAME_PASSWORD"}, - enumNames = {"无验证", "SSH密钥", "用户名密码"}, - defaultValue = "NONE" - ) - private String authenticationType; - - /** - * SSH私钥(当authenticationType为SSH_KEY时使用) - */ - @SchemaProperty( - title = "SSH私钥", - description = "SSH私钥内容(当身份验证类型为SSH密钥时使用)", - format = "textarea" - ) - private String sshPrivateKey; - - /** - * 用户名(当authenticationType为USERNAME_PASSWORD时使用) - */ - @SchemaProperty( - title = "用户名", - description = "Git仓库的用户名(当身份验证类型为用户名密码时使用)" - ) - private String username; - - /** - * 密码或令牌(当authenticationType为USERNAME_PASSWORD时使用) - */ - @SchemaProperty( - title = "密码或令牌", - description = "Git仓库的密码或访问令牌(当身份验证类型为用户名密码时使用)" - ) - private String password; - - /** - * Git配置 - */ - @SchemaProperty( - title = "Git配置", - description = "额外的Git配置选项" - ) - private Map gitConfig; - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/ScriptNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/ScriptNodeLocalVariables.java index 77c30972..8b8e60b8 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/ScriptNodeLocalVariables.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/ScriptNodeLocalVariables.java @@ -1,90 +1,11 @@ package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; -import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.BaseNodePanelVariables; import lombok.Data; import lombok.EqualsAndHashCode; -import java.util.List; -import java.util.Map; - -/** - * 脚本执行器配置 - */ @Data @EqualsAndHashCode(callSuper = true) -public class ScriptNodeLocalVariables extends BaseTaskNodeLocalVariables { - - - /** - * 脚本内容 - */ - @SchemaProperty( - title = "脚本内容", - description = "需要执行的脚本内容,例如:\n#!/bin/bash\necho \"开始执行脚本\"\nls -la\necho \"脚本执行完成\"", - format = "textarea", - required = true - ) - private String script; - - /** - * 脚本语言 - */ - @SchemaProperty( - title = "脚本语言", - description = "脚本语言类型", - required = true, - enumValues = {"shell", "python", "javascript", "groovy"}, - enumNames = {"Shell脚本 (已支持)", "Python脚本 (开发中)", "JavaScript脚本 (开发中)", "Groovy脚本 (开发中)"}, - defaultValue = "shell" - ) - private String language; - - /** - * 解释器路径 - */ - @SchemaProperty( - title = "解释器路径", - description = "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3", - required = true - ) - private String interpreter; - - /** - * 工作目录 - */ - @SchemaProperty( - title = "工作目录", - description = "脚本执行的工作目录", - defaultValue = "/tmp" - ) - private String workingDirectory; - - /** - * 环境变量 - */ - @SchemaProperty( - title = "环境变量", - description = "脚本执行时的环境变量" - ) - private Map environment; - - /** - * 成功退出码 - */ - @SchemaProperty( - title = "成功退出码", - description = "脚本执行成功时的退出码", - defaultValue = "0" - ) - private Integer successExitCode; - - /** - * 支持的脚本语言列表 - */ - @SchemaProperty( - title = "支持的脚本语言", - enumValues = {"shell", "python", "javascript", "groovy"} - ) - private List supportedLanguages; +public class ScriptNodeLocalVariables extends BaseNodePanelVariables { } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/StartNodeLocalVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/StartNodeLocalVariables.java deleted file mode 100644 index b292efe1..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/StartNodeLocalVariables.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -/** - * 开始节点配置 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class StartNodeLocalVariables extends BaseEventNodeLocalVariables { - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ConditionalGatewayConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ConditionalGatewayConfig.java deleted file mode 100644 index a2fb2ef4..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ConditionalGatewayConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.demo; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.List; - -/** - * 基于条件的网关配置基类 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public abstract class ConditionalGatewayConfig extends GatewayConfig { - /** - * 条件分支列表 - */ - private List branches; - - /** - * 默认分支节点ID - */ - private String defaultNodeId; - - @Data - public static class ConditionalBranch { - /** - * 分支名称 - */ - private String name; - - /** - * 条件表达式 - */ - private String condition; - - /** - * 目标节点ID - */ - private String targetNodeId; - - /** - * 分支描述 - */ - private String description; - } -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ExclusiveGatewayConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ExclusiveGatewayConfig.java deleted file mode 100644 index 87dc5c37..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ExclusiveGatewayConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.demo; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; - -import java.util.Collections; -import java.util.List; - -/** - * 排他网关配置 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class ExclusiveGatewayConfig extends ConditionalGatewayConfig { - private final ExpressionParser expressionParser = new SpelExpressionParser(); - - @Override - public List getNextNodeIds(String context) { - return null; - } - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/GatewayConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/GatewayConfig.java deleted file mode 100644 index f69d1fc2..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/GatewayConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.demo; - -import com.fasterxml.jackson.annotation.JsonSubTypes; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import lombok.Data; - -import java.util.List; - -/** - * 网关配置基类 - */ -@Data -@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") -@JsonSubTypes({ - @JsonSubTypes.Type(value = ExclusiveGatewayConfig.class, name = "EXCLUSIVE"), - @JsonSubTypes.Type(value = ParallelGatewayConfig.class, name = "PARALLEL"), - @JsonSubTypes.Type(value = InclusiveGatewayConfig.class, name = "INCLUSIVE") -}) -public abstract class GatewayConfig { - - /** - * 网关名称 - */ - private String name; - - /** - * 网关描述 - */ - private String description; - - /** - * 获取下一个节点IDs - */ - public abstract List getNextNodeIds(String context); -} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/InclusiveGatewayConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/InclusiveGatewayConfig.java deleted file mode 100644 index c419f09c..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/InclusiveGatewayConfig.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.demo; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.spel.standard.SpelExpressionParser; - -import java.util.List; - -/** - * 包容网关配置 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class InclusiveGatewayConfig extends ConditionalGatewayConfig { - - private final ExpressionParser expressionParser = new SpelExpressionParser(); - - @Override - public List getNextNodeIds(String context) { - return null; - } -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ParallelGatewayConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ParallelGatewayConfig.java deleted file mode 100644 index 05bacc9f..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/localVariables/demo/ParallelGatewayConfig.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.demo; - -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.List; -/** - * 并行网关配置 - */ -@Data -@EqualsAndHashCode(callSuper = true) -public class ParallelGatewayConfig extends GatewayConfig { - - @Override - public List getNextNodeIds(String context) { - return null; - } - -} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/BaseNodePanelVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/BaseNodePanelVariables.java new file mode 100644 index 00000000..065f8f56 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/BaseNodePanelVariables.java @@ -0,0 +1,37 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +/** + * 事件节点基础配置 + */ +@Data +public class BaseNodePanelVariables { + + @SchemaProperty( + title = "节点编码", + description = "工作流节点的编码", + required = true + ) + private String code; + + /** + * 节点名称 + */ + @SchemaProperty( + title = "节点名称", + description = "工作流节点的显示名称", + required = true + ) + private String name; + + /** + * 节点描述 + */ + @SchemaProperty( + title = "节点描述", + description = "工作流节点的详细描述" + ) + private String description; +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/EndNodePanelVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/EndNodePanelVariables.java new file mode 100644 index 00000000..536845a0 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/EndNodePanelVariables.java @@ -0,0 +1,13 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 结束节点配置 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class EndNodePanelVariables extends BaseNodePanelVariables { + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/GitCloneNodePanelVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/GitCloneNodePanelVariables.java new file mode 100644 index 00000000..871fb8cf --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/GitCloneNodePanelVariables.java @@ -0,0 +1,14 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * Git Clone任务配置 + * 继承TaskConfig以获取通用的任务配置(优先级、超时、重试等) + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class GitCloneNodePanelVariables extends BaseNodePanelVariables { + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/ScriptNodePanelVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/ScriptNodePanelVariables.java new file mode 100644 index 00000000..8c640186 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/ScriptNodePanelVariables.java @@ -0,0 +1,69 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; + +import com.qqchen.deploy.backend.workflow.annotation.NodeTypeLocalVariablesBind; +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * 脚本执行器配置 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NodeTypeLocalVariablesBind(type = NodeTypeEnums.SCRIPT_TASK) +public class ScriptNodePanelVariables extends BaseNodePanelVariables { + + + @SchemaProperty( + title = "脚本代码", + description = "脚本代码", + required = true + ) + private String script; + + /** + * 脚本语言 + */ + @SchemaProperty( + title = "脚本语言", + description = "脚本语言类型", + required = true, + enumValues = {"shell", "python", "javascript", "groovy"}, + enumNames = {"Shell脚本 (已支持)", "Python脚本 (开发中)", "JavaScript脚本 (开发中)", "Groovy脚本 (开发中)"}, + defaultValue = "shell" + ) + private String language; + + /** + * 解释器路径 + */ + @SchemaProperty( + title = "解释器路径", + description = "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3", + required = true + ) + private String interpreter; + + /** + * 成功退出码 + */ + @SchemaProperty( + title = "成功标识", + description = "脚本执行成功时的标识", + required = true + ) + private Integer successExitCode; + + /** + * 支持的脚本语言列表 + */ + @SchemaProperty( + title = "支持的脚本语言", + enumValues = {"shell", "python", "javascript", "groovy"} + ) + private List supportedLanguages; + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/StartNodePanelVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/StartNodePanelVariables.java new file mode 100644 index 00000000..53993092 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/panelVariables/StartNodePanelVariables.java @@ -0,0 +1,13 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 开始节点配置 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class StartNodePanelVariables extends BaseNodePanelVariables { + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowDefinitionNode.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowDefinitionNode.java index 57ab8356..847aa0af 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowDefinitionNode.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowDefinitionNode.java @@ -36,8 +36,9 @@ public class WorkflowDefinitionNode { private WorkflowNodeGraph graph; + /** * 节点配置 */ - private Map config; + private Map localVariables; } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowNodeGraph.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowNodeGraph.java index c1faf688..b782f915 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowNodeGraph.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/workflow/WorkflowNodeGraph.java @@ -89,7 +89,7 @@ public class WorkflowNodeGraph { */ @Data public static class Position { - + private int x; private int y; @@ -186,6 +186,8 @@ public class WorkflowNodeGraph { private String stroke; + private boolean magnet; + public PortCircle() { // 默认构造函数 } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/entity/WorkflowNodeDefinition.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/entity/WorkflowNodeDefinition.java index 85b679b3..22be89ba 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/entity/WorkflowNodeDefinition.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/entity/WorkflowNodeDefinition.java @@ -3,8 +3,10 @@ package com.qqchen.deploy.backend.workflow.entity; import com.fasterxml.jackson.databind.JsonNode; import com.qqchen.deploy.backend.framework.annotation.LogicDelete; import com.qqchen.deploy.backend.framework.domain.Entity; +import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; import com.vladmihalcea.hibernate.type.json.JsonType; +import io.swagger.v3.oas.annotations.media.Schema; import jakarta.persistence.Column; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; @@ -24,68 +26,35 @@ import org.hibernate.annotations.Type; @LogicDelete public class WorkflowNodeDefinition extends Entity { - /** - * 节点类型编码(如:userTask, serviceTask, shellTask 等) - * 对应 Flowable 中的节点类型 - */ - @Column(nullable = false, unique = true) - private String type; + @Column(name = "node_type", nullable = false) + private String nodeType; - /** - * 节点名称 - */ - @Column(nullable = false) - private String name; + @Column(name = "node_code", nullable = false) + private String nodeCode; + + @Column(name = "node_name", nullable = false) + private String nodeName; - /** - * 节点描述 - */ private String description; - /** - * 节点分类 - */ @Enumerated(EnumType.STRING) @Column(nullable = false) private NodeCategoryEnums category; - /** - * Flowable 配置 JSON - * 包含: - * - delegateExpression: 委托表达式 - * - class: 实现类 - * - expression: 表达式 - * - listeners: 监听器配置 - * - 其他 Flowable 特定配置 - */ + @Type(JsonType.class) - @Column(columnDefinition = "text") - private JsonNode flowableConfig; + @Column(name = "graph_variables", columnDefinition = "text", nullable = false) + private WorkflowNodeGraph graphVariables; + - /** - * X6 图形配置 JSON - * 包含: - * - shape: 节点形状 - * - width: 宽度 - * - height: 高度 - * - ports: 连接点 - * - icon: 图标 - * - color: 颜色 - * - 其他 X6 特定配置 - */ @Type(JsonType.class) - @Column(columnDefinition = "text", nullable = false) - private JsonNode graphConfig; + @Column(name = "local_variables", columnDefinition = "text", nullable = false) + private JsonNode localVariables; - /** - * 排序号 - */ - @Column(nullable = false) - private Integer orderNum = 0; + @Type(JsonType.class) + @Column(name = "from_variables", columnDefinition = "text", nullable = false) + private JsonNode fromVariables; - /** - * 是否启用 - */ @Column(nullable = false) private Boolean enabled = true; } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java index ee3b02ed..49739c7c 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/enums/NodeTypeEnums.java @@ -1,6 +1,10 @@ package com.qqchen.deploy.backend.workflow.enums; import com.fasterxml.jackson.annotation.JsonValue; +import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.ScriptNodeLocalVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.EndNodePanelVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.ScriptNodePanelVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.StartNodePanelVariables; import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph; import lombok.Getter; @@ -23,6 +27,8 @@ public enum NodeTypeEnums { START_EVENT( "START_EVENT", // 节点类型编码 "开始节点", // 节点显示名称 + null, + StartNodePanelVariables.class, BpmnNodeTypeEnums.START_EVENT, NodeCategoryEnums.EVENT, "工作流的起点", // 节点简要描述 @@ -43,6 +49,8 @@ public enum NodeTypeEnums { END_EVENT( "END_EVENT", "结束节点", + null, + EndNodePanelVariables.class, BpmnNodeTypeEnums.END_EVENT, NodeCategoryEnums.EVENT, "工作流的终点", @@ -55,6 +63,8 @@ public enum NodeTypeEnums { SCRIPT_TASK( "SCRIPT_TASK", "脚本任务", + ScriptNodeLocalVariables.class, + ScriptNodePanelVariables.class, BpmnNodeTypeEnums.SERVICE_TASK, NodeCategoryEnums.TASK, "脚本执行任务", @@ -203,6 +213,10 @@ public enum NodeTypeEnums { private final String name; // 节点显示名称 + private final Class localVariables; + + private final Class panelVariables; + private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型 private final NodeCategoryEnums category; //分类 @@ -214,12 +228,16 @@ public enum NodeTypeEnums { NodeTypeEnums( String code, String name, + Class localVariables, + Class panelVariables, BpmnNodeTypeEnums bpmnType, NodeCategoryEnums category, String description, WorkflowNodeGraph uiConfig) { this.code = code; this.name = name; + this.localVariables = localVariables; + this.panelVariables = panelVariables; this.bpmnType = bpmnType; this.category = category; this.description = description; diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeDefinitionRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeDefinitionRepository.java index dfef55af..5bab8c26 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeDefinitionRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/repository/IWorkflowNodeDefinitionRepository.java @@ -13,20 +13,20 @@ public interface IWorkflowNodeDefinitionRepository extends IBaseRepository findByEnabledTrueOrderByOrderNumAsc(); + List findByEnabledTrue(); /** * 根据分类查询启用的节点定义 */ - List findByEnabledTrueAndCategoryOrderByOrderNumAsc(String category); + List findByEnabledTrueAndCategory(String category); /** * 根据类型查询节点定义 */ - Optional findByTypeAndEnabledTrue(String type); + Optional findByNodeTypeAndEnabledTrue(String type); /** * 检查类型是否存在 */ - boolean existsByTypeAndDeletedFalse(String type); + boolean existsByNodeTypeAndDeletedFalse(String type); } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/IWorkflowNodeDefinitionService.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/IWorkflowNodeDefinitionService.java index b440b542..1ea6b0fe 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/IWorkflowNodeDefinitionService.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/IWorkflowNodeDefinitionService.java @@ -1,7 +1,9 @@ package com.qqchen.deploy.backend.workflow.service; import com.qqchen.deploy.backend.framework.service.IBaseService; +import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionCreateDTO; import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO; +import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO; import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; @@ -11,7 +13,8 @@ import java.util.List; * 工作流节点定义服务接口 */ public interface IWorkflowNodeDefinitionService extends IBaseService { - + + /** * 根据节点类型获取节点定义 * @@ -48,4 +51,7 @@ public interface IWorkflowNodeDefinitionService extends IBaseService defined(); + +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowNodeDefinitionServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowNodeDefinitionServiceImpl.java index 01ae9617..d54d77b7 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowNodeDefinitionServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/service/impl/WorkflowNodeDefinitionServiceImpl.java @@ -1,9 +1,12 @@ package com.qqchen.deploy.backend.workflow.service.impl; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO; +import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO; import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; +import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; import com.qqchen.deploy.backend.workflow.repository.IWorkflowNodeDefinitionRepository; import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeDefinitionService; import jakarta.annotation.Resource; @@ -11,61 +14,222 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.lang.reflect.Field; +import java.util.Map; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; + /** * 工作流节点定义服务实现 */ @Slf4j @Service public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl implements IWorkflowNodeDefinitionService { - + @Resource private IWorkflowNodeDefinitionRepository workflowNodeDefinitionRepository; - + + @Override + public WorkflowNodeDefinitionDTO create(WorkflowNodeDefinitionDTO dto) { +// return super.create(dto); + + NodeTypeEnums nodeTypeEnums = NodeTypeEnums.fromValue(dto.getNodeType().getCode()); + + System.out.println(dto); + + return null; + } + @Override public WorkflowNodeDefinitionDTO getByType(String type) { - return workflowNodeDefinitionRepository.findByTypeAndEnabledTrue(type) + return workflowNodeDefinitionRepository.findByNodeTypeAndEnabledTrue(type) .map(super.converter::toDto) .orElse(null); } - + @Override public List listByCategory(NodeCategoryEnums category) { - return workflowNodeDefinitionRepository.findByEnabledTrueAndCategoryOrderByOrderNumAsc(category.name()) + return workflowNodeDefinitionRepository.findByEnabledTrueAndCategory(category.name()) .stream() .map(super.converter::toDto) .collect(Collectors.toList()); } - + @Override public List listAllEnabled() { - return workflowNodeDefinitionRepository.findByEnabledTrueOrderByOrderNumAsc() + return workflowNodeDefinitionRepository.findByEnabledTrue() .stream() .map(super.converter::toDto) .collect(Collectors.toList()); } - + @Override @Transactional(rollbackFor = Exception.class) public void enable(Long id) { WorkflowNodeDefinition definition = workflowNodeDefinitionRepository.findById(id) .orElseThrow(() -> new RuntimeException("Node definition not found: " + id)); - + definition.setEnabled(true); workflowNodeDefinitionRepository.save(definition); log.info("Enabled node definition: {}", id); } - + @Override @Transactional(rollbackFor = Exception.class) public void disable(Long id) { WorkflowNodeDefinition definition = workflowNodeDefinitionRepository.findById(id) .orElseThrow(() -> new RuntimeException("Node definition not found: " + id)); - + definition.setEnabled(false); workflowNodeDefinitionRepository.save(definition); log.info("Disabled node definition: {}", id); } -} \ No newline at end of file + + @Override + public List defined() { + List result = new ArrayList<>(); + + // 遍历所有节点类型 + for (NodeTypeEnums nodeType : NodeTypeEnums.values()) { + try { + // 获取localVariables类型 + Class panelVariables = nodeType.getPanelVariables(); + if (panelVariables == null) { + continue; + } + + // 创建结果对象 + WorkflowNodeTypeDefinedDTO definedDTO = new WorkflowNodeTypeDefinedDTO(); + definedDTO.setNodeCode(nodeType.getCode()); + definedDTO.setNodeName(nodeType.getName()); + + // 生成schema + ObjectMapper mapper = new ObjectMapper(); + ObjectNode schema = mapper.createObjectNode(); + schema.put("type", "object"); + + // 处理属性 + ObjectNode properties = schema.putObject("properties"); + List required = new ArrayList<>(); + + // 获取所有字段,包括父类的字段 + List allFields = getAllFields(panelVariables); + + // 遍历所有字段 + for (Field field : allFields) { + SchemaProperty annotation = field.getAnnotation(SchemaProperty.class); + if (annotation != null) { + ObjectNode property = properties.putObject(field.getName()); + + // 设置基本属性 + property.put("type", getJsonSchemaType(field.getType())); + + // 从注解中获取属性 + if (!annotation.title().isEmpty()) { + property.put("title", annotation.title()); + } + if (!annotation.description().isEmpty()) { + property.put("description", annotation.description()); + } + if (!annotation.format().isEmpty()) { + property.put("format", annotation.format()); + } + if (annotation.required()) { + required.add(field.getName()); + } + if (annotation.defaultValue().length() > 0) { + property.put("default", annotation.defaultValue()); + } + + // 处理枚举 + if (annotation.enumValues().length > 0) { + ArrayNode enumNode = property.putArray("enum"); + for (String value : annotation.enumValues()) { + enumNode.add(value); + } + + if (annotation.enumNames().length > 0) { + ArrayNode enumNamesNode = property.putArray("enumNames"); + for (String name : annotation.enumNames()) { + enumNamesNode.add(name); + } + } + } + + // 处理数组类型 + if (List.class.isAssignableFrom(field.getType())) { + ObjectNode items = property.putObject("items"); + items.put("type", "string"); + } + + // 处理Map类型 + if (Map.class.isAssignableFrom(field.getType())) { + ObjectNode additionalProperties = property.putObject("additionalProperties"); + additionalProperties.put("type", "string"); + } + } + } + + // 添加required字段 + if (!required.isEmpty()) { + ArrayNode requiredNode = schema.putArray("required"); + required.forEach(requiredNode::add); + } + + definedDTO.setPanelVariablesSchema(schema); + result.add(definedDTO); + + } catch (Exception e) { + log.error("Error processing node type: " + nodeType, e); + } + } + + return result; + } + + /** + * 获取类的所有字段,包括父类的字段 + */ + private List getAllFields(Class clazz) { + List fields = new ArrayList<>(); + Class currentClass = clazz; + + // 遍历类的继承层次 + while (currentClass != null && !currentClass.equals(Object.class)) { + // 添加当前类的字段 + fields.addAll(Arrays.asList(currentClass.getDeclaredFields())); + // 获取父类 + currentClass = currentClass.getSuperclass(); + } + + return fields; + } + + private String getJsonSchemaType(Class type) { + if (String.class.equals(type)) { + return "string"; + } else if (Integer.class.equals(type) || int.class.equals(type) + || Long.class.equals(type) || long.class.equals(type)) { + return "integer"; + } else if (Double.class.equals(type) || double.class.equals(type) + || Float.class.equals(type) || float.class.equals(type)) { + return "number"; + } else if (Boolean.class.equals(type) || boolean.class.equals(type)) { + return "boolean"; + } else if (List.class.isAssignableFrom(type)) { + return "array"; + } else if (Map.class.isAssignableFrom(type)) { + return "object"; + } else { + return "object"; + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java index a610a85d..d07a9cfb 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/BpmnConverter.java @@ -139,7 +139,7 @@ public class BpmnConverter { if (element instanceof ServiceTask) { ServiceTask serviceTask = (ServiceTask) element; // 设置委托表达式 - String delegate = (String) node.getConfig().get("delegate"); + String delegate = (String) node.getLocalVariables().get("delegate"); serviceTask.setImplementationType("delegateExpression"); serviceTask.setImplementation(delegate); @@ -156,7 +156,7 @@ public class BpmnConverter { // 添加字段注入 List fieldExtensions = new ArrayList<>(); - node.getConfig().forEach((key, value) -> { + node.getLocalVariables().forEach((key, value) -> { if (value != null && !"delegate".equals(key)) { FieldExtension fieldExtension = new FieldExtension(); fieldExtension.setFieldName(key); diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/SchemaGenerator.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/SchemaGenerator.java index 8d5a5fed..7955a0ef 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/SchemaGenerator.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/util/SchemaGenerator.java @@ -5,10 +5,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.BaseNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.EndNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.ScriptNodeLocalVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.StartNodeLocalVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.BaseNodePanelVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.EndNodePanelVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.ScriptNodePanelVariables; +import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.StartNodePanelVariables; import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph; import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; @@ -31,11 +31,11 @@ public class SchemaGenerator { private static Class getConfigClassForNodeType(NodeTypeEnums nodeType) { switch (nodeType) { case START_EVENT: - return StartNodeLocalVariables.class; + return StartNodePanelVariables.class; case END_EVENT: - return EndNodeLocalVariables.class; + return EndNodePanelVariables.class; case SCRIPT_TASK: - return ScriptNodeLocalVariables.class; + return ScriptNodePanelVariables.class; // 其他节点类型的配置类 // case USER_TASK: // case SERVICE_TASK: @@ -46,7 +46,7 @@ public class SchemaGenerator { // TODO: 为其他节点类型添加对应的配置类 // return BaseNodeConfig.class; default: - return BaseNodeLocalVariables.class; + return BaseNodePanelVariables.class; } } diff --git a/backend/src/main/resources/db/migration/V1.0.0__init_schema.sql b/backend/src/main/resources/db/migration/V1.0.0__init_schema.sql index 7f61d246..7ce374b3 100644 --- a/backend/src/main/resources/db/migration/V1.0.0__init_schema.sql +++ b/backend/src/main/resources/db/migration/V1.0.0__init_schema.sql @@ -440,23 +440,28 @@ CREATE TABLE workflow_definition -- 创建工作流节点定义表 CREATE TABLE workflow_node_definition ( - id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', - type VARCHAR(50) NOT NULL COMMENT '节点类型编码', - name VARCHAR(100) NOT NULL COMMENT '节点名称', - description VARCHAR(500) COMMENT '节点描述', - category VARCHAR(50) NOT NULL COMMENT '节点分类', - graph_config JSON NOT NULL COMMENT 'X6图形配置JSON', - order_num INT NOT NULL DEFAULT 0 COMMENT '排序号', - enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用', - create_time DATETIME NOT NULL COMMENT '创建时间', - create_by VARCHAR(50) NOT NULL COMMENT '创建人', - update_time DATETIME NOT NULL COMMENT '更新时间', - update_by VARCHAR(50) NOT NULL COMMENT '更新人', - version INT NOT NULL DEFAULT 1 COMMENT '版本号', - deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除', + id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', + node_type VARCHAR(50) NOT NULL COMMENT '节点类型', + node_code VARCHAR(50) NOT NULL COMMENT '节点编码', + node_name VARCHAR(100) NOT NULL COMMENT '节点名称', + description VARCHAR(500) COMMENT '节点描述', + category VARCHAR(50) NOT NULL COMMENT '节点分类', + graph_variables JSON NOT NULL COMMENT '节点UI', + local_variables JSON NOT NULL COMMENT '节点属性', + from_variables JSON COMMENT '节点表单', + enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用', + + create_time DATETIME NOT NULL COMMENT '创建时间', + create_by VARCHAR(50) NOT NULL COMMENT '创建人', + update_time DATETIME NOT NULL COMMENT '更新时间', + update_by VARCHAR(50) NOT NULL COMMENT '更新人', + version INT NOT NULL DEFAULT 1 COMMENT '版本号', + deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除', PRIMARY KEY (id), - UNIQUE KEY uk_type (TYPE) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表'; + UNIQUE KEY uk_node_type (node_type) +) ENGINE = InnoDB + DEFAULT CHARSET = utf8mb4 + COLLATE = utf8mb4_unicode_ci COMMENT ='工作流节点定义表'; -- 工作流实例表 CREATE TABLE workflow_instance diff --git a/backend/src/main/resources/db/migration/V1.0.1__init_data.sql b/backend/src/main/resources/db/migration/V1.0.1__init_data.sql index d3f68c00..8f2ce930 100644 --- a/backend/src/main/resources/db/migration/V1.0.1__init_data.sql +++ b/backend/src/main/resources/db/migration/V1.0.1__init_data.sql @@ -571,250 +571,250 @@ INSERT INTO workflow_definition ( -- -------------------------------------------------------------------------------------- -- 初始化工作流节点定义数据 -- -------------------------------------------------------------------------------------- -INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) -VALUES -(1, NOW(), - 'system', - NOW(), - 'system', 'START_EVENT', '开始节点', '工作流的起点', 'EVENT', '{ - "code": "START_EVENT", - "name": "开始节点", - "description": "工作流的起点", - "details": { - "description": "标记流程的开始位置,可以定义流程启动条件和初始化流程变量", - "features": ["标记流程的开始位置", "定义流程启动条件", "初始化流程变量"], - "scenarios": ["用户手动启动流程", "定时触发流程", "外部系统调用启动"] - }, - "configSchema": { - "type": "object", - "properties": { - "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, - "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, - "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} - }, - "required": ["code", "name"] - }, - "uiSchema": { - "shape": "circle", - "size": {"width": 40, "height": 40}, - "style": { - "fill": "#e8f7ff", - "stroke": "#1890ff", - "strokeWidth": 2, - "icon": "play-circle", - "iconColor": "#1890ff" - }, - "ports": { - "groups": { - "out": { - "position": "right", - "attrs": { - "circle": { - "r": 4, - "fill": "#ffffff", - "stroke": "#1890ff" - } - } - } - } - } - } -}', 1); -INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) -VALUES -(2, NOW(), - 'system', - NOW(), - 'system', 'END_EVENT', '结束节点', '工作流的终点', 'EVENT', '{ - "code": "END_EVENT", - "name": "结束节点", - "description": "工作流的终点", - "details": { - "description": "标记流程的结束位置,可以定义流程结束时的清理操作和设置返回值", - "features": ["标记流程的结束位置", "定义结束时清理操作", "设置流程结果和返回值"], - "scenarios": ["流程正常结束", "流程异常终止", "需要返回处理结果"] - }, - "configSchema": { - "type": "object", - "properties": { - "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, - "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, - "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} - }, - "required": ["code", "name"] - }, - "uiSchema": { - "shape": "circle", - "size": {"width": 40, "height": 40}, - "style": { - "fill": "#fff1f0", - "stroke": "#ff4d4f", - "strokeWidth": 2, - "icon": "stop", - "iconColor": "#ff4d4f" - }, - "ports": { - "groups": { - "in": { - "position": "left", - "attrs": { - "circle": { - "r": 4, - "fill": "#ffffff", - "stroke": "#1890ff" - } - } - } - } - } - } -}', 1); - -INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) -VALUES -(5, NOW(), - 'system', - NOW(), - 'system', 'SCRIPT_TASK', '脚本任务', '脚本执行任务', 'TASK', '{ - "code": "SCRIPT_TASK", - "name": "脚本任务", - "details": { - "description": "脚本执行任务", - "features": [], - "scenarios": [] - }, - "configSchema": { - "type": "object", - "properties": { - "code": { - "type": "string", - "title": "节点Code", - "description": "工作流节点的Code" - }, - "name": { - "type": "string", - "title": "节点名称", - "description": "工作流节点的显示名称" - }, - "description": { - "type": "string", - "title": "节点描述", - "description": "工作流节点的详细描述" - }, - "script": { - "type": "string", - "title": "脚本内容", - "description": "需要执行的脚本内容,例如:\\n#!/bin/bash\\necho \\\"开始执行脚本\\\"\\nls -la\\necho \\\"脚本执行完成\\\"", - "format": "textarea" - }, - "language": { - "type": "string", - "title": "脚本语言", - "description": "脚本语言类型", - "default": "shell", - "enum": [ - "shell", - "python", - "javascript", - "groovy" - ], - "enumNames": [ - "Shell脚本 (已支持)", - "Python脚本 (开发中)", - "JavaScript脚本 (开发中)", - "Groovy脚本 (开发中)" - ] - }, - "interpreter": { - "type": "string", - "title": "解释器路径", - "description": "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3" - }, - "workingDirectory": { - "type": "string", - "title": "工作目录", - "description": "脚本执行的工作目录", - "default": "/tmp" - }, - "environment": { - "type": "object", - "title": "环境变量", - "description": "脚本执行时的环境变量", - "additionalProperties": { - "type": "string" - } - }, - "successExitCode": { - "type": "integer", - "title": "成功退出码", - "description": "脚本执行成功时的退出码", - "default": 0 - }, - "supportedLanguages": { - "type": "array", - "title": "支持的脚本语言", - "enum": [ - "shell", - "python", - "javascript", - "groovy" - ], - "items": { - "type": "string" - } - }, - "delegate": { - "type": "string", - "title": "执行委派者", - "description": "执行委派者", - "default": "${shellTaskDelegate}" - } - }, - "required": [ - "code", - "name", - "script", - "language", - "interpreter", - "delegate" - ] - }, - "uiSchema": { - "shape": "rect", - "size": { - "width": 120, - "height": 60 - }, - "style": { - "fill": "#ffffff", - "stroke": "#1890ff", - "strokeWidth": 2, - "icon": "code", - "iconColor": "#1890ff" - }, - "ports": { - "groups": { - "in": { - "position": "left", - "attrs": { - "circle": { - "r": 4, - "fill": "#ffffff", - "stroke": "#1890ff" - } - } - }, - "out": { - "position": "right", - "attrs": { - "circle": { - "r": 4, - "fill": "#ffffff", - "stroke": "#1890ff" - } - } - } - } - } - } -}', 1); \ No newline at end of file +# INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) +# VALUES +# (1, NOW(), +# 'system', +# NOW(), +# 'system', 'START_EVENT', '开始节点', '工作流的起点', 'EVENT', '{ +# "code": "START_EVENT", +# "name": "开始节点", +# "description": "工作流的起点", +# "details": { +# "description": "标记流程的开始位置,可以定义流程启动条件和初始化流程变量", +# "features": ["标记流程的开始位置", "定义流程启动条件", "初始化流程变量"], +# "scenarios": ["用户手动启动流程", "定时触发流程", "外部系统调用启动"] +# }, +# "configSchema": { +# "type": "object", +# "properties": { +# "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, +# "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, +# "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} +# }, +# "required": ["code", "name"] +# }, +# "uiSchema": { +# "shape": "circle", +# "size": {"width": 40, "height": 40}, +# "style": { +# "fill": "#e8f7ff", +# "stroke": "#1890ff", +# "strokeWidth": 2, +# "icon": "play-circle", +# "iconColor": "#1890ff" +# }, +# "ports": { +# "groups": { +# "out": { +# "position": "right", +# "attrs": { +# "circle": { +# "r": 4, +# "fill": "#ffffff", +# "stroke": "#1890ff" +# } +# } +# } +# } +# } +# } +# }', 1); +# INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) +# VALUES +# (2, NOW(), +# 'system', +# NOW(), +# 'system', 'END_EVENT', '结束节点', '工作流的终点', 'EVENT', '{ +# "code": "END_EVENT", +# "name": "结束节点", +# "description": "工作流的终点", +# "details": { +# "description": "标记流程的结束位置,可以定义流程结束时的清理操作和设置返回值", +# "features": ["标记流程的结束位置", "定义结束时清理操作", "设置流程结果和返回值"], +# "scenarios": ["流程正常结束", "流程异常终止", "需要返回处理结果"] +# }, +# "configSchema": { +# "type": "object", +# "properties": { +# "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, +# "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, +# "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} +# }, +# "required": ["code", "name"] +# }, +# "uiSchema": { +# "shape": "circle", +# "size": {"width": 40, "height": 40}, +# "style": { +# "fill": "#fff1f0", +# "stroke": "#ff4d4f", +# "strokeWidth": 2, +# "icon": "stop", +# "iconColor": "#ff4d4f" +# }, +# "ports": { +# "groups": { +# "in": { +# "position": "left", +# "attrs": { +# "circle": { +# "r": 4, +# "fill": "#ffffff", +# "stroke": "#1890ff" +# } +# } +# } +# } +# } +# } +# }', 1); +# +# INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) +# VALUES +# (5, NOW(), +# 'system', +# NOW(), +# 'system', 'SCRIPT_TASK', '脚本任务', '脚本执行任务', 'TASK', '{ +# "code": "SCRIPT_TASK", +# "name": "脚本任务", +# "details": { +# "description": "脚本执行任务", +# "features": [], +# "scenarios": [] +# }, +# "configSchema": { +# "type": "object", +# "properties": { +# "code": { +# "type": "string", +# "title": "节点Code", +# "description": "工作流节点的Code" +# }, +# "name": { +# "type": "string", +# "title": "节点名称", +# "description": "工作流节点的显示名称" +# }, +# "description": { +# "type": "string", +# "title": "节点描述", +# "description": "工作流节点的详细描述" +# }, +# "script": { +# "type": "string", +# "title": "脚本内容", +# "description": "需要执行的脚本内容,例如:\\n#!/bin/bash\\necho \\\"开始执行脚本\\\"\\nls -la\\necho \\\"脚本执行完成\\\"", +# "format": "textarea" +# }, +# "language": { +# "type": "string", +# "title": "脚本语言", +# "description": "脚本语言类型", +# "default": "shell", +# "enum": [ +# "shell", +# "python", +# "javascript", +# "groovy" +# ], +# "enumNames": [ +# "Shell脚本 (已支持)", +# "Python脚本 (开发中)", +# "JavaScript脚本 (开发中)", +# "Groovy脚本 (开发中)" +# ] +# }, +# "interpreter": { +# "type": "string", +# "title": "解释器路径", +# "description": "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3" +# }, +# "workingDirectory": { +# "type": "string", +# "title": "工作目录", +# "description": "脚本执行的工作目录", +# "default": "/tmp" +# }, +# "environment": { +# "type": "object", +# "title": "环境变量", +# "description": "脚本执行时的环境变量", +# "additionalProperties": { +# "type": "string" +# } +# }, +# "successExitCode": { +# "type": "integer", +# "title": "成功退出码", +# "description": "脚本执行成功时的退出码", +# "default": 0 +# }, +# "supportedLanguages": { +# "type": "array", +# "title": "支持的脚本语言", +# "enum": [ +# "shell", +# "python", +# "javascript", +# "groovy" +# ], +# "items": { +# "type": "string" +# } +# }, +# "delegate": { +# "type": "string", +# "title": "执行委派者", +# "description": "执行委派者", +# "default": "${shellTaskDelegate}" +# } +# }, +# "required": [ +# "code", +# "name", +# "script", +# "language", +# "interpreter", +# "delegate" +# ] +# }, +# "uiSchema": { +# "shape": "rect", +# "size": { +# "width": 120, +# "height": 60 +# }, +# "style": { +# "fill": "#ffffff", +# "stroke": "#1890ff", +# "strokeWidth": 2, +# "icon": "code", +# "iconColor": "#1890ff" +# }, +# "ports": { +# "groups": { +# "in": { +# "position": "left", +# "attrs": { +# "circle": { +# "r": 4, +# "fill": "#ffffff", +# "stroke": "#1890ff" +# } +# } +# }, +# "out": { +# "position": "right", +# "attrs": { +# "circle": { +# "r": 4, +# "fill": "#ffffff", +# "stroke": "#1890ff" +# } +# } +# } +# } +# } +# } +# }', 1); \ No newline at end of file