反序列化问题。

This commit is contained in:
dengqichen 2024-12-19 13:31:25 +08:00
parent 3c6bf11cad
commit 9357117174
34 changed files with 755 additions and 904 deletions

View File

@ -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();
}

View File

@ -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.api.Response;
import com.qqchen.deploy.backend.framework.controller.BaseController; 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.WorkflowNodeDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition; import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
import com.qqchen.deploy.backend.workflow.query.WorkflowNodeDefinitionQuery; import com.qqchen.deploy.backend.workflow.query.WorkflowNodeDefinitionQuery;
@ -29,6 +31,14 @@ public class WorkflowNodeDefinitionApiController extends BaseController<Workflow
@Resource @Resource
private IWorkflowNodeDefinitionService workflowNodeDefinitionService; private IWorkflowNodeDefinitionService workflowNodeDefinitionService;
@Operation(summary = "根据节点类型获取节点定义")
@GetMapping("/defined")
public Response<List<WorkflowNodeTypeDefinedDTO>> defined() {
return Response.success(workflowNodeDefinitionService.defined());
}
@Operation(summary = "根据节点类型获取节点定义") @Operation(summary = "根据节点类型获取节点定义")
@GetMapping("/type/{type}") @GetMapping("/type/{type}")
public Response<WorkflowNodeDefinitionDTO> getByType( public Response<WorkflowNodeDefinitionDTO> getByType(

View File

@ -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 {
}

View File

@ -2,7 +2,9 @@ package com.qqchen.deploy.backend.workflow.dto;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.qqchen.deploy.backend.framework.dto.BaseDTO; 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.NodeCategoryEnums;
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -16,10 +18,13 @@ import lombok.EqualsAndHashCode;
public class WorkflowNodeDefinitionDTO extends BaseDTO { public class WorkflowNodeDefinitionDTO extends BaseDTO {
@Schema(description = "节点类型编码") @Schema(description = "节点类型编码")
private String type; private NodeTypeEnums nodeType;
@Schema(description = "节点编码")
private String nodeCode;
@Schema(description = "节点名称") @Schema(description = "节点名称")
private String name; private String nodeName;
@Schema(description = "节点描述") @Schema(description = "节点描述")
private String description; private String description;
@ -27,14 +32,14 @@ public class WorkflowNodeDefinitionDTO extends BaseDTO {
@Schema(description = "节点分类") @Schema(description = "节点分类")
private NodeCategoryEnums category; private NodeCategoryEnums category;
@Schema(description = "Flowable配置JSON") @Schema(description = "节点UI")
private JsonNode flowableConfig; private WorkflowNodeGraph graphVariables;
@Schema(description = "X6图形配置JSON") @Schema(description = "节点属性d")
private JsonNode graphConfig; private JsonNode localVariables;
@Schema(description = "排序号") @Schema(description = "节点表单")
private Integer orderNum; private JsonNode fromVariables;
@Schema(description = "是否启用") @Schema(description = "是否启用")
private Boolean enabled; private Boolean enabled;

View File

@ -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;
}

View File

@ -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
}

View File

@ -1,11 +0,0 @@
package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables;
import lombok.Data;
/**
* 事件节点基础配置
*/
@Data
public abstract class BaseEventNodeLocalVariables extends BaseNodeLocalVariables {
}

View File

@ -10,28 +10,10 @@ import lombok.Data;
public class BaseNodeLocalVariables { public class BaseNodeLocalVariables {
@SchemaProperty( @SchemaProperty(
title = "节点Code", title = "委派者",
description = "工作流节点的Code", description = "委派者",
required = true required = true
) )
private String code; private String delegate;
/**
* 节点名称
*/
@SchemaProperty(
title = "节点名称",
description = "工作流节点的显示名称",
required = true
)
private String name;
/**
* 节点描述
*/
@SchemaProperty(
title = "节点描述",
description = "工作流节点的详细描述"
)
private String description;
} }

View File

@ -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;
}

View File

@ -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 {
}

View File

@ -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<String, String> gitConfig;
}

View File

@ -1,90 +1,11 @@
package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; 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.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import java.util.List;
import java.util.Map;
/**
* 脚本执行器配置
*/
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class ScriptNodeLocalVariables extends BaseTaskNodeLocalVariables { public class ScriptNodeLocalVariables extends BaseNodePanelVariables {
/**
* 脚本内容
*/
@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<String, String> environment;
/**
* 成功退出码
*/
@SchemaProperty(
title = "成功退出码",
description = "脚本执行成功时的退出码",
defaultValue = "0"
)
private Integer successExitCode;
/**
* 支持的脚本语言列表
*/
@SchemaProperty(
title = "支持的脚本语言",
enumValues = {"shell", "python", "javascript", "groovy"}
)
private List<String> supportedLanguages;
} }

View File

@ -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 {
}

View File

@ -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<ConditionalBranch> branches;
/**
* 默认分支节点ID
*/
private String defaultNodeId;
@Data
public static class ConditionalBranch {
/**
* 分支名称
*/
private String name;
/**
* 条件表达式
*/
private String condition;
/**
* 目标节点ID
*/
private String targetNodeId;
/**
* 分支描述
*/
private String description;
}
}

View File

@ -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<String> getNextNodeIds(String context) {
return null;
}
}

View File

@ -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<String> getNextNodeIds(String context);
}

View File

@ -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<String> getNextNodeIds(String context) {
return null;
}
}

View File

@ -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<String> getNextNodeIds(String context) {
return null;
}
}

View File

@ -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;
}

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -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<String> supportedLanguages;
}

View File

@ -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 {
}

View File

@ -36,8 +36,9 @@ public class WorkflowDefinitionNode {
private WorkflowNodeGraph graph; private WorkflowNodeGraph graph;
/** /**
* 节点配置 * 节点配置
*/ */
private Map<String, Object> config; private Map<String, Object> localVariables;
} }

View File

@ -186,6 +186,8 @@ public class WorkflowNodeGraph {
private String stroke; private String stroke;
private boolean magnet;
public PortCircle() { public PortCircle() {
// 默认构造函数 // 默认构造函数
} }

View File

@ -3,8 +3,10 @@ package com.qqchen.deploy.backend.workflow.entity;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.qqchen.deploy.backend.framework.annotation.LogicDelete; import com.qqchen.deploy.backend.framework.annotation.LogicDelete;
import com.qqchen.deploy.backend.framework.domain.Entity; 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.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
import com.vladmihalcea.hibernate.type.json.JsonType; import com.vladmihalcea.hibernate.type.json.JsonType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.EnumType; import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated; import jakarta.persistence.Enumerated;
@ -24,68 +26,35 @@ import org.hibernate.annotations.Type;
@LogicDelete @LogicDelete
public class WorkflowNodeDefinition extends Entity<Long> { public class WorkflowNodeDefinition extends Entity<Long> {
/** @Column(name = "node_type", nullable = false)
* 节点类型编码userTask, serviceTask, shellTask private String nodeType;
* 对应 Flowable 中的节点类型
*/
@Column(nullable = false, unique = true)
private String type;
/** @Column(name = "node_code", nullable = false)
* 节点名称 private String nodeCode;
*/
@Column(nullable = false) @Column(name = "node_name", nullable = false)
private String name; private String nodeName;
/**
* 节点描述
*/
private String description; private String description;
/**
* 节点分类
*/
@Enumerated(EnumType.STRING) @Enumerated(EnumType.STRING)
@Column(nullable = false) @Column(nullable = false)
private NodeCategoryEnums category; private NodeCategoryEnums category;
/**
* Flowable 配置 JSON
* 包含
* - delegateExpression: 委托表达式
* - class: 实现类
* - expression: 表达式
* - listeners: 监听器配置
* - 其他 Flowable 特定配置
*/
@Type(JsonType.class) @Type(JsonType.class)
@Column(columnDefinition = "text") @Column(name = "graph_variables", columnDefinition = "text", nullable = false)
private JsonNode flowableConfig; private WorkflowNodeGraph graphVariables;
/**
* X6 图形配置 JSON
* 包含
* - shape: 节点形状
* - width: 宽度
* - height: 高度
* - ports: 连接点
* - icon: 图标
* - color: 颜色
* - 其他 X6 特定配置
*/
@Type(JsonType.class) @Type(JsonType.class)
@Column(columnDefinition = "text", nullable = false) @Column(name = "local_variables", columnDefinition = "text", nullable = false)
private JsonNode graphConfig; private JsonNode localVariables;
/** @Type(JsonType.class)
* 排序号 @Column(name = "from_variables", columnDefinition = "text", nullable = false)
*/ private JsonNode fromVariables;
@Column(nullable = false)
private Integer orderNum = 0;
/**
* 是否启用
*/
@Column(nullable = false) @Column(nullable = false)
private Boolean enabled = true; private Boolean enabled = true;
} }

View File

@ -1,6 +1,10 @@
package com.qqchen.deploy.backend.workflow.enums; package com.qqchen.deploy.backend.workflow.enums;
import com.fasterxml.jackson.annotation.JsonValue; 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 com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph;
import lombok.Getter; import lombok.Getter;
@ -23,6 +27,8 @@ public enum NodeTypeEnums {
START_EVENT( START_EVENT(
"START_EVENT", // 节点类型编码 "START_EVENT", // 节点类型编码
"开始节点", // 节点显示名称 "开始节点", // 节点显示名称
null,
StartNodePanelVariables.class,
BpmnNodeTypeEnums.START_EVENT, BpmnNodeTypeEnums.START_EVENT,
NodeCategoryEnums.EVENT, NodeCategoryEnums.EVENT,
"工作流的起点", // 节点简要描述 "工作流的起点", // 节点简要描述
@ -43,6 +49,8 @@ public enum NodeTypeEnums {
END_EVENT( END_EVENT(
"END_EVENT", "END_EVENT",
"结束节点", "结束节点",
null,
EndNodePanelVariables.class,
BpmnNodeTypeEnums.END_EVENT, BpmnNodeTypeEnums.END_EVENT,
NodeCategoryEnums.EVENT, NodeCategoryEnums.EVENT,
"工作流的终点", "工作流的终点",
@ -55,6 +63,8 @@ public enum NodeTypeEnums {
SCRIPT_TASK( SCRIPT_TASK(
"SCRIPT_TASK", "SCRIPT_TASK",
"脚本任务", "脚本任务",
ScriptNodeLocalVariables.class,
ScriptNodePanelVariables.class,
BpmnNodeTypeEnums.SERVICE_TASK, BpmnNodeTypeEnums.SERVICE_TASK,
NodeCategoryEnums.TASK, NodeCategoryEnums.TASK,
"脚本执行任务", "脚本执行任务",
@ -203,6 +213,10 @@ public enum NodeTypeEnums {
private final String name; // 节点显示名称 private final String name; // 节点显示名称
private final Class<?> localVariables;
private final Class<?> panelVariables;
private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型 private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型
private final NodeCategoryEnums category; //分类 private final NodeCategoryEnums category; //分类
@ -214,12 +228,16 @@ public enum NodeTypeEnums {
NodeTypeEnums( NodeTypeEnums(
String code, String code,
String name, String name,
Class<?> localVariables,
Class<?> panelVariables,
BpmnNodeTypeEnums bpmnType, BpmnNodeTypeEnums bpmnType,
NodeCategoryEnums category, NodeCategoryEnums category,
String description, String description,
WorkflowNodeGraph uiConfig) { WorkflowNodeGraph uiConfig) {
this.code = code; this.code = code;
this.name = name; this.name = name;
this.localVariables = localVariables;
this.panelVariables = panelVariables;
this.bpmnType = bpmnType; this.bpmnType = bpmnType;
this.category = category; this.category = category;
this.description = description; this.description = description;

View File

@ -13,20 +13,20 @@ public interface IWorkflowNodeDefinitionRepository extends IBaseRepository<Workf
/** /**
* 查询所有启用的节点定义按排序号排序 * 查询所有启用的节点定义按排序号排序
*/ */
List<WorkflowNodeDefinition> findByEnabledTrueOrderByOrderNumAsc(); List<WorkflowNodeDefinition> findByEnabledTrue();
/** /**
* 根据分类查询启用的节点定义 * 根据分类查询启用的节点定义
*/ */
List<WorkflowNodeDefinition> findByEnabledTrueAndCategoryOrderByOrderNumAsc(String category); List<WorkflowNodeDefinition> findByEnabledTrueAndCategory(String category);
/** /**
* 根据类型查询节点定义 * 根据类型查询节点定义
*/ */
Optional<WorkflowNodeDefinition> findByTypeAndEnabledTrue(String type); Optional<WorkflowNodeDefinition> findByNodeTypeAndEnabledTrue(String type);
/** /**
* 检查类型是否存在 * 检查类型是否存在
*/ */
boolean existsByTypeAndDeletedFalse(String type); boolean existsByNodeTypeAndDeletedFalse(String type);
} }

View File

@ -1,7 +1,9 @@
package com.qqchen.deploy.backend.workflow.service; package com.qqchen.deploy.backend.workflow.service;
import com.qqchen.deploy.backend.framework.service.IBaseService; 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.WorkflowNodeDefinitionDTO;
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeTypeDefinedDTO;
import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition; import com.qqchen.deploy.backend.workflow.entity.WorkflowNodeDefinition;
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums;
@ -12,6 +14,7 @@ import java.util.List;
*/ */
public interface IWorkflowNodeDefinitionService extends IBaseService<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO, Long> { public interface IWorkflowNodeDefinitionService extends IBaseService<WorkflowNodeDefinition, WorkflowNodeDefinitionDTO, Long> {
/** /**
* 根据节点类型获取节点定义 * 根据节点类型获取节点定义
* *
@ -48,4 +51,7 @@ public interface IWorkflowNodeDefinitionService extends IBaseService<WorkflowNod
* @param id 节点定义ID * @param id 节点定义ID
*/ */
void disable(Long id); void disable(Long id);
List<WorkflowNodeTypeDefinedDTO> defined();
} }

View File

@ -1,9 +1,12 @@
package com.qqchen.deploy.backend.workflow.service.impl; 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.framework.service.impl.BaseServiceImpl;
import com.qqchen.deploy.backend.workflow.dto.WorkflowNodeDefinitionDTO; 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.entity.WorkflowNodeDefinition;
import com.qqchen.deploy.backend.workflow.enums.NodeCategoryEnums; 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.repository.IWorkflowNodeDefinitionRepository;
import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeDefinitionService; import com.qqchen.deploy.backend.workflow.service.IWorkflowNodeDefinitionService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
@ -11,9 +14,19 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; 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;
/** /**
* 工作流节点定义服务实现 * 工作流节点定义服务实现
*/ */
@ -24,16 +37,27 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
@Resource @Resource
private IWorkflowNodeDefinitionRepository workflowNodeDefinitionRepository; 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 @Override
public WorkflowNodeDefinitionDTO getByType(String type) { public WorkflowNodeDefinitionDTO getByType(String type) {
return workflowNodeDefinitionRepository.findByTypeAndEnabledTrue(type) return workflowNodeDefinitionRepository.findByNodeTypeAndEnabledTrue(type)
.map(super.converter::toDto) .map(super.converter::toDto)
.orElse(null); .orElse(null);
} }
@Override @Override
public List<WorkflowNodeDefinitionDTO> listByCategory(NodeCategoryEnums category) { public List<WorkflowNodeDefinitionDTO> listByCategory(NodeCategoryEnums category) {
return workflowNodeDefinitionRepository.findByEnabledTrueAndCategoryOrderByOrderNumAsc(category.name()) return workflowNodeDefinitionRepository.findByEnabledTrueAndCategory(category.name())
.stream() .stream()
.map(super.converter::toDto) .map(super.converter::toDto)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -41,7 +65,7 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
@Override @Override
public List<WorkflowNodeDefinitionDTO> listAllEnabled() { public List<WorkflowNodeDefinitionDTO> listAllEnabled() {
return workflowNodeDefinitionRepository.findByEnabledTrueOrderByOrderNumAsc() return workflowNodeDefinitionRepository.findByEnabledTrue()
.stream() .stream()
.map(super.converter::toDto) .map(super.converter::toDto)
.collect(Collectors.toList()); .collect(Collectors.toList());
@ -68,4 +92,144 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
workflowNodeDefinitionRepository.save(definition); workflowNodeDefinitionRepository.save(definition);
log.info("Disabled node definition: {}", id); log.info("Disabled node definition: {}", id);
} }
@Override
public List<WorkflowNodeTypeDefinedDTO> defined() {
List<WorkflowNodeTypeDefinedDTO> 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<String> required = new ArrayList<>();
// 获取所有字段包括父类的字段
List<Field> 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<Field> getAllFields(Class<?> clazz) {
List<Field> 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";
}
}
} }

View File

@ -139,7 +139,7 @@ public class BpmnConverter {
if (element instanceof ServiceTask) { if (element instanceof ServiceTask) {
ServiceTask serviceTask = (ServiceTask) element; ServiceTask serviceTask = (ServiceTask) element;
// 设置委托表达式 // 设置委托表达式
String delegate = (String) node.getConfig().get("delegate"); String delegate = (String) node.getLocalVariables().get("delegate");
serviceTask.setImplementationType("delegateExpression"); serviceTask.setImplementationType("delegateExpression");
serviceTask.setImplementation(delegate); serviceTask.setImplementation(delegate);
@ -156,7 +156,7 @@ public class BpmnConverter {
// 添加字段注入 // 添加字段注入
List<FieldExtension> fieldExtensions = new ArrayList<>(); List<FieldExtension> fieldExtensions = new ArrayList<>();
node.getConfig().forEach((key, value) -> { node.getLocalVariables().forEach((key, value) -> {
if (value != null && !"delegate".equals(key)) { if (value != null && !"delegate".equals(key)) {
FieldExtension fieldExtension = new FieldExtension(); FieldExtension fieldExtension = new FieldExtension();
fieldExtension.setFieldName(key); fieldExtension.setFieldName(key);

View File

@ -5,10 +5,10 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.ObjectNode;
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; 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.panelVariables.BaseNodePanelVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.EndNodeLocalVariables; import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.EndNodePanelVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.ScriptNodeLocalVariables; import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.ScriptNodePanelVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.StartNodeLocalVariables; 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.dto.definition.workflow.WorkflowNodeGraph;
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums; import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
@ -31,11 +31,11 @@ public class SchemaGenerator {
private static Class<?> getConfigClassForNodeType(NodeTypeEnums nodeType) { private static Class<?> getConfigClassForNodeType(NodeTypeEnums nodeType) {
switch (nodeType) { switch (nodeType) {
case START_EVENT: case START_EVENT:
return StartNodeLocalVariables.class; return StartNodePanelVariables.class;
case END_EVENT: case END_EVENT:
return EndNodeLocalVariables.class; return EndNodePanelVariables.class;
case SCRIPT_TASK: case SCRIPT_TASK:
return ScriptNodeLocalVariables.class; return ScriptNodePanelVariables.class;
// 其他节点类型的配置类 // 其他节点类型的配置类
// case USER_TASK: // case USER_TASK:
// case SERVICE_TASK: // case SERVICE_TASK:
@ -46,7 +46,7 @@ public class SchemaGenerator {
// TODO: 为其他节点类型添加对应的配置类 // TODO: 为其他节点类型添加对应的配置类
// return BaseNodeConfig.class; // return BaseNodeConfig.class;
default: default:
return BaseNodeLocalVariables.class; return BaseNodePanelVariables.class;
} }
} }

View File

@ -441,13 +441,16 @@ CREATE TABLE workflow_definition
CREATE TABLE workflow_node_definition CREATE TABLE workflow_node_definition
( (
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID', id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
type VARCHAR(50) NOT NULL COMMENT '节点类型编码', node_type VARCHAR(50) NOT NULL COMMENT '节点类型',
name VARCHAR(100) NOT NULL COMMENT '节点名称', node_code VARCHAR(50) NOT NULL COMMENT '节点编码',
node_name VARCHAR(100) NOT NULL COMMENT '节点名称',
description VARCHAR(500) COMMENT '节点描述', description VARCHAR(500) COMMENT '节点描述',
category VARCHAR(50) NOT NULL COMMENT '节点分类', category VARCHAR(50) NOT NULL COMMENT '节点分类',
graph_config JSON NOT NULL COMMENT 'X6图形配置JSON', graph_variables JSON NOT NULL COMMENT '节点UI',
order_num INT NOT NULL DEFAULT 0 COMMENT '排序号', local_variables JSON NOT NULL COMMENT '节点属性',
from_variables JSON COMMENT '节点表单',
enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用', enabled BOOLEAN NOT NULL DEFAULT TRUE COMMENT '是否启用',
create_time DATETIME NOT NULL COMMENT '创建时间', create_time DATETIME NOT NULL COMMENT '创建时间',
create_by VARCHAR(50) NOT NULL COMMENT '创建人', create_by VARCHAR(50) NOT NULL COMMENT '创建人',
update_time DATETIME NOT NULL COMMENT '更新时间', update_time DATETIME NOT NULL COMMENT '更新时间',
@ -455,8 +458,10 @@ CREATE TABLE workflow_node_definition
version INT NOT NULL DEFAULT 1 COMMENT '版本号', version INT NOT NULL DEFAULT 1 COMMENT '版本号',
deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除', deleted BOOLEAN NOT NULL DEFAULT FALSE COMMENT '是否删除',
PRIMARY KEY (id), PRIMARY KEY (id),
UNIQUE KEY uk_type (TYPE) UNIQUE KEY uk_node_type (node_type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='工作流节点定义表'; ) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci COMMENT ='工作流节点定义表';
-- 工作流实例表 -- 工作流实例表
CREATE TABLE workflow_instance CREATE TABLE workflow_instance

View File

@ -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) # INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled)
VALUES # VALUES
(1, NOW(), # (1, NOW(),
'system', # 'system',
NOW(), # NOW(),
'system', 'START_EVENT', '开始节点', '工作流的起点', 'EVENT', '{ # 'system', 'START_EVENT', '开始节点', '工作流的起点', 'EVENT', '{
"code": "START_EVENT", # "code": "START_EVENT",
"name": "开始节点", # "name": "开始节点",
"description": "工作流的起点", # "description": "工作流的起点",
"details": { # "details": {
"description": "标记流程的开始位置,可以定义流程启动条件和初始化流程变量", # "description": "标记流程的开始位置,可以定义流程启动条件和初始化流程变量",
"features": ["标记流程的开始位置", "定义流程启动条件", "初始化流程变量"], # "features": ["标记流程的开始位置", "定义流程启动条件", "初始化流程变量"],
"scenarios": ["用户手动启动流程", "定时触发流程", "外部系统调用启动"] # "scenarios": ["用户手动启动流程", "定时触发流程", "外部系统调用启动"]
}, # },
"configSchema": { # "configSchema": {
"type": "object", # "type": "object",
"properties": { # "properties": {
"code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, # "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"},
"name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, # "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"},
"description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} # "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"}
}, # },
"required": ["code", "name"] # "required": ["code", "name"]
}, # },
"uiSchema": { # "uiSchema": {
"shape": "circle", # "shape": "circle",
"size": {"width": 40, "height": 40}, # "size": {"width": 40, "height": 40},
"style": { # "style": {
"fill": "#e8f7ff", # "fill": "#e8f7ff",
"stroke": "#1890ff", # "stroke": "#1890ff",
"strokeWidth": 2, # "strokeWidth": 2,
"icon": "play-circle", # "icon": "play-circle",
"iconColor": "#1890ff" # "iconColor": "#1890ff"
}, # },
"ports": { # "ports": {
"groups": { # "groups": {
"out": { # "out": {
"position": "right", # "position": "right",
"attrs": { # "attrs": {
"circle": { # "circle": {
"r": 4, # "r": 4,
"fill": "#ffffff", # "fill": "#ffffff",
"stroke": "#1890ff" # "stroke": "#1890ff"
} # }
} # }
} # }
} # }
} # }
} # }
}', 1); # }', 1);
INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) # INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled)
VALUES # VALUES
(2, NOW(), # (2, NOW(),
'system', # 'system',
NOW(), # NOW(),
'system', 'END_EVENT', '结束节点', '工作流的终点', 'EVENT', '{ # 'system', 'END_EVENT', '结束节点', '工作流的终点', 'EVENT', '{
"code": "END_EVENT", # "code": "END_EVENT",
"name": "结束节点", # "name": "结束节点",
"description": "工作流的终点", # "description": "工作流的终点",
"details": { # "details": {
"description": "标记流程的结束位置,可以定义流程结束时的清理操作和设置返回值", # "description": "标记流程的结束位置,可以定义流程结束时的清理操作和设置返回值",
"features": ["标记流程的结束位置", "定义结束时清理操作", "设置流程结果和返回值"], # "features": ["标记流程的结束位置", "定义结束时清理操作", "设置流程结果和返回值"],
"scenarios": ["流程正常结束", "流程异常终止", "需要返回处理结果"] # "scenarios": ["流程正常结束", "流程异常终止", "需要返回处理结果"]
}, # },
"configSchema": { # "configSchema": {
"type": "object", # "type": "object",
"properties": { # "properties": {
"code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"}, # "code": {"type": "string", "title": "节点Code", "description": "工作流节点的Code"},
"name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"}, # "name": {"type": "string", "title": "节点名称", "description": "工作流节点的显示名称"},
"description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"} # "description": {"type": "string", "title": "节点描述", "description": "工作流节点的详细描述"}
}, # },
"required": ["code", "name"] # "required": ["code", "name"]
}, # },
"uiSchema": { # "uiSchema": {
"shape": "circle", # "shape": "circle",
"size": {"width": 40, "height": 40}, # "size": {"width": 40, "height": 40},
"style": { # "style": {
"fill": "#fff1f0", # "fill": "#fff1f0",
"stroke": "#ff4d4f", # "stroke": "#ff4d4f",
"strokeWidth": 2, # "strokeWidth": 2,
"icon": "stop", # "icon": "stop",
"iconColor": "#ff4d4f" # "iconColor": "#ff4d4f"
}, # },
"ports": { # "ports": {
"groups": { # "groups": {
"in": { # "in": {
"position": "left", # "position": "left",
"attrs": { # "attrs": {
"circle": { # "circle": {
"r": 4, # "r": 4,
"fill": "#ffffff", # "fill": "#ffffff",
"stroke": "#1890ff" # "stroke": "#1890ff"
} # }
} # }
} # }
} # }
} # }
} # }
}', 1); # }', 1);
#
INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled) # INSERT INTO workflow_node_definition (id, create_time, create_by, update_time, update_by, type, name, description, category, graph_config, enabled)
VALUES # VALUES
(5, NOW(), # (5, NOW(),
'system', # 'system',
NOW(), # NOW(),
'system', 'SCRIPT_TASK', '脚本任务', '脚本执行任务', 'TASK', '{ # 'system', 'SCRIPT_TASK', '脚本任务', '脚本执行任务', 'TASK', '{
"code": "SCRIPT_TASK", # "code": "SCRIPT_TASK",
"name": "脚本任务", # "name": "脚本任务",
"details": { # "details": {
"description": "脚本执行任务", # "description": "脚本执行任务",
"features": [], # "features": [],
"scenarios": [] # "scenarios": []
}, # },
"configSchema": { # "configSchema": {
"type": "object", # "type": "object",
"properties": { # "properties": {
"code": { # "code": {
"type": "string", # "type": "string",
"title": "节点Code", # "title": "节点Code",
"description": "工作流节点的Code" # "description": "工作流节点的Code"
}, # },
"name": { # "name": {
"type": "string", # "type": "string",
"title": "节点名称", # "title": "节点名称",
"description": "工作流节点的显示名称" # "description": "工作流节点的显示名称"
}, # },
"description": { # "description": {
"type": "string", # "type": "string",
"title": "节点描述", # "title": "节点描述",
"description": "工作流节点的详细描述" # "description": "工作流节点的详细描述"
}, # },
"script": { # "script": {
"type": "string", # "type": "string",
"title": "脚本内容", # "title": "脚本内容",
"description": "需要执行的脚本内容,例如:\\n#!/bin/bash\\necho \\\"\\\"\\nls -la\\necho \\\"\\\"", # "description": "需要执行的脚本内容,例如:\\n#!/bin/bash\\necho \\\"开始执行脚本\\\"\\nls -la\\necho \\\"脚本执行完成\\\"",
"format": "textarea" # "format": "textarea"
}, # },
"language": { # "language": {
"type": "string", # "type": "string",
"title": "脚本语言", # "title": "脚本语言",
"description": "脚本语言类型", # "description": "脚本语言类型",
"default": "shell", # "default": "shell",
"enum": [ # "enum": [
"shell", # "shell",
"python", # "python",
"javascript", # "javascript",
"groovy" # "groovy"
], # ],
"enumNames": [ # "enumNames": [
"Shell脚本 (已支持)", # "Shell脚本 (已支持)",
"Python脚本 (开发中)", # "Python脚本 (开发中)",
"JavaScript脚本 (开发中)", # "JavaScript脚本 (开发中)",
"Groovy脚本 (开发中)" # "Groovy脚本 (开发中)"
] # ]
}, # },
"interpreter": { # "interpreter": {
"type": "string", # "type": "string",
"title": "解释器路径", # "title": "解释器路径",
"description": "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3" # "description": "脚本解释器的路径,例如:/bin/bash, /usr/bin/python3"
}, # },
"workingDirectory": { # "workingDirectory": {
"type": "string", # "type": "string",
"title": "工作目录", # "title": "工作目录",
"description": "脚本执行的工作目录", # "description": "脚本执行的工作目录",
"default": "/tmp" # "default": "/tmp"
}, # },
"environment": { # "environment": {
"type": "object", # "type": "object",
"title": "环境变量", # "title": "环境变量",
"description": "脚本执行时的环境变量", # "description": "脚本执行时的环境变量",
"additionalProperties": { # "additionalProperties": {
"type": "string" # "type": "string"
} # }
}, # },
"successExitCode": { # "successExitCode": {
"type": "integer", # "type": "integer",
"title": "成功退出码", # "title": "成功退出码",
"description": "脚本执行成功时的退出码", # "description": "脚本执行成功时的退出码",
"default": 0 # "default": 0
}, # },
"supportedLanguages": { # "supportedLanguages": {
"type": "array", # "type": "array",
"title": "支持的脚本语言", # "title": "支持的脚本语言",
"enum": [ # "enum": [
"shell", # "shell",
"python", # "python",
"javascript", # "javascript",
"groovy" # "groovy"
], # ],
"items": { # "items": {
"type": "string" # "type": "string"
} # }
}, # },
"delegate": { # "delegate": {
"type": "string", # "type": "string",
"title": "执行委派者", # "title": "执行委派者",
"description": "执行委派者", # "description": "执行委派者",
"default": "${shellTaskDelegate}" # "default": "${shellTaskDelegate}"
} # }
}, # },
"required": [ # "required": [
"code", # "code",
"name", # "name",
"script", # "script",
"language", # "language",
"interpreter", # "interpreter",
"delegate" # "delegate"
] # ]
}, # },
"uiSchema": { # "uiSchema": {
"shape": "rect", # "shape": "rect",
"size": { # "size": {
"width": 120, # "width": 120,
"height": 60 # "height": 60
}, # },
"style": { # "style": {
"fill": "#ffffff", # "fill": "#ffffff",
"stroke": "#1890ff", # "stroke": "#1890ff",
"strokeWidth": 2, # "strokeWidth": 2,
"icon": "code", # "icon": "code",
"iconColor": "#1890ff" # "iconColor": "#1890ff"
}, # },
"ports": { # "ports": {
"groups": { # "groups": {
"in": { # "in": {
"position": "left", # "position": "left",
"attrs": { # "attrs": {
"circle": { # "circle": {
"r": 4, # "r": 4,
"fill": "#ffffff", # "fill": "#ffffff",
"stroke": "#1890ff" # "stroke": "#1890ff"
} # }
} # }
}, # },
"out": { # "out": {
"position": "right", # "position": "right",
"attrs": { # "attrs": {
"circle": { # "circle": {
"r": 4, # "r": 4,
"fill": "#ffffff", # "fill": "#ffffff",
"stroke": "#1890ff" # "stroke": "#1890ff"
} # }
} # }
} # }
} # }
} # }
} # }
}', 1); # }', 1);