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 index c91a3cde..ec62610e 100644 --- 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 @@ -17,8 +17,15 @@ public class WorkflowNodeTypeDefinedDTO { @Schema(description = "节点名称") private String nodeName; - @Schema(description = "节点属性JSON SCHEMA") + @Schema(description = "节点属性变量JSON SCHEMA") private JsonNode panelVariablesSchema; + @Schema(description = "节点环境变量JSON SCHEMA") private JsonNode localVariablesSchema; + + @Schema(description = "节点表单变量JSON SCHEMA") + private JsonNode formVariablesSchema; + + @Schema(description = "自定义节点UI JSON SCHEMA") + private JsonNode uiVariables; } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseDeployNodeFormVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseDeployNodeFormVariables.java new file mode 100644 index 00000000..6af54ba7 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseDeployNodeFormVariables.java @@ -0,0 +1,19 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.fromVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +/** + * 事件节点基础配置 + */ +@Data +public class BaseDeployNodeFormVariables { + + @SchemaProperty( + title = "禅道ID", + description = "真实的禅道ID", + required = true + ) + private String zentaoId; + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseNodeFormVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseNodeFormVariables.java new file mode 100644 index 00000000..daf74492 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/BaseNodeFormVariables.java @@ -0,0 +1,19 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.fromVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +/** + * 事件节点基础配置 + */ +@Data +public class BaseNodeFormVariables { + + @SchemaProperty( + title = "委派者", + description = "委派者", + required = true + ) + private String delegate; + +} diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/ScriptNodeFormVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/ScriptNodeFormVariables.java new file mode 100644 index 00000000..cee98075 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/fromVariables/ScriptNodeFormVariables.java @@ -0,0 +1,10 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.fromVariables; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class ScriptNodeFormVariables extends BaseDeployNodeFormVariables { + +} 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 8b8e60b8..291d2103 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,11 +1,10 @@ package com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables; -import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.BaseNodePanelVariables; import lombok.Data; import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) -public class ScriptNodeLocalVariables extends BaseNodePanelVariables { +public class ScriptNodeLocalVariables extends BaseNodeLocalVariables { } 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 index 8c640186..821f3336 100644 --- 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 @@ -1,8 +1,6 @@ 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; @@ -13,7 +11,6 @@ import java.util.List; */ @Data @EqualsAndHashCode(callSuper = true) -@NodeTypeLocalVariablesBind(type = NodeTypeEnums.SCRIPT_TASK) public class ScriptNodePanelVariables extends BaseNodePanelVariables { diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Attrs.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Attrs.java new file mode 100644 index 00000000..d88b1350 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Attrs.java @@ -0,0 +1,15 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Attrs { + + @SchemaProperty( + title = "圆形配置", + description = "端口的圆形样式配置", + required = true + ) + private Circle circle; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Circle.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Circle.java new file mode 100644 index 00000000..17e375bf --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Circle.java @@ -0,0 +1,31 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Circle { + @SchemaProperty( + title = "半径", + description = "圆的半径", + required = true, + defaultValue = "4" + ) + private Integer r; + + @SchemaProperty( + title = "填充颜色", + description = "圆的填充颜色", + required = true, + defaultValue = "#ffffff" + ) + private String fill; + + @SchemaProperty( + title = "边框颜色", + description = "圆的边框颜色", + required = true, + defaultValue = "#1890ff" + ) + private String stroke; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Groups.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Groups.java new file mode 100644 index 00000000..b1f19b73 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Groups.java @@ -0,0 +1,22 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Groups { + + @SchemaProperty( + title = "输入端口", + description = "节点的输入端口配置", + required = true + ) + private Port in; + + @SchemaProperty( + title = "输出端口", + description = "节点的输出端口配置", + required = true + ) + private Port out; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/NodeUiVariables.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/NodeUiVariables.java new file mode 100644 index 00000000..941c0006 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/NodeUiVariables.java @@ -0,0 +1,36 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class NodeUiVariables { + + @SchemaProperty( + title = "节点大小", + required = true + ) + private Size size; + + @SchemaProperty( + title = "节点端口", + required = true + ) + private Ports ports; + + @SchemaProperty( + title = "节点形状", + description = "节点的形状类型", + required = true, + enumValues = {"rect", "circle", "diamond"}, + enumNames = {"矩形", "圆形", "菱形"}, + defaultValue = "rect" + ) + private String shape; + + @SchemaProperty( + title = "节点样式", + required = true + ) + private Style style; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Port.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Port.java new file mode 100644 index 00000000..0a827998 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Port.java @@ -0,0 +1,24 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Port { + + @SchemaProperty( + title = "端口属性", + description = "端口的样式属性", + required = true + ) + private Attrs attrs; + + @SchemaProperty( + title = "端口位置", + description = "端口在节点上的位置", + required = true, + enumValues = {"left", "right", "top", "bottom"}, + enumNames = {"左侧", "右侧", "顶部", "底部"} + ) + private String position; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Ports.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Ports.java new file mode 100644 index 00000000..0427d083 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Ports.java @@ -0,0 +1,16 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Ports { + + @SchemaProperty( + title = "端口组", + description = "节点的端口组配置", + required = true + ) + private Groups groups; + +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Size.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Size.java new file mode 100644 index 00000000..413c9630 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Size.java @@ -0,0 +1,24 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Size { + + @SchemaProperty( + title = "宽度", + description = "节点的宽度", + required = true, + defaultValue = "120" + ) + private Integer width; + + @SchemaProperty( + title = "高度", + description = "节点的高度", + required = true, + defaultValue = "60" + ) + private Integer height; +} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Style.java b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Style.java new file mode 100644 index 00000000..fbda50a0 --- /dev/null +++ b/backend/src/main/java/com/qqchen/deploy/backend/workflow/dto/definition/node/uiVariables/Style.java @@ -0,0 +1,48 @@ +package com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables; + +import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty; +import lombok.Data; + +@Data +public class Style { + + @SchemaProperty( + title = "填充颜色", + description = "节点的填充颜色", + required = true, + defaultValue = "#ffffff" + ) + private String fill; + + @SchemaProperty( + title = "图标", + description = "节点的图标", + required = true, + defaultValue = "code" + ) + private String icon; + + @SchemaProperty( + title = "边框颜色", + description = "节点的边框颜色", + required = true, + defaultValue = "#1890ff" + ) + private String stroke; + + @SchemaProperty( + title = "图标颜色", + description = "节点图标的颜色", + required = true, + defaultValue = "#1890ff" + ) + private String iconColor; + + @SchemaProperty( + title = "边框宽度", + description = "节点边框的宽度", + required = true, + defaultValue = "2" + ) + private Integer strokeWidth; +} \ 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 49739c7c..5278d11e 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,10 +1,12 @@ package com.qqchen.deploy.backend.workflow.enums; import com.fasterxml.jackson.annotation.JsonValue; +import com.qqchen.deploy.backend.workflow.dto.definition.node.fromVariables.ScriptNodeFormVariables; 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.node.uiVariables.NodeUiVariables; import com.qqchen.deploy.backend.workflow.dto.definition.workflow.WorkflowNodeGraph; import lombok.Getter; @@ -29,6 +31,8 @@ public enum NodeTypeEnums { "开始节点", // 节点显示名称 null, StartNodePanelVariables.class, + null, + NodeUiVariables.class, BpmnNodeTypeEnums.START_EVENT, NodeCategoryEnums.EVENT, "工作流的起点", // 节点简要描述 @@ -51,6 +55,8 @@ public enum NodeTypeEnums { "结束节点", null, EndNodePanelVariables.class, + null, + NodeUiVariables.class, BpmnNodeTypeEnums.END_EVENT, NodeCategoryEnums.EVENT, "工作流的终点", @@ -65,6 +71,8 @@ public enum NodeTypeEnums { "脚本任务", ScriptNodeLocalVariables.class, ScriptNodePanelVariables.class, + ScriptNodeFormVariables.class, + NodeUiVariables.class, BpmnNodeTypeEnums.SERVICE_TASK, NodeCategoryEnums.TASK, "脚本执行任务", @@ -217,6 +225,10 @@ public enum NodeTypeEnums { private final Class panelVariables; + private final Class formVariables; + + private final Class uiVariables; + private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型 private final NodeCategoryEnums category; //分类 @@ -230,6 +242,8 @@ public enum NodeTypeEnums { String name, Class localVariables, Class panelVariables, + Class formVariables, + Class uiVariables, BpmnNodeTypeEnums bpmnType, NodeCategoryEnums category, String description, @@ -238,6 +252,8 @@ public enum NodeTypeEnums { this.name = name; this.localVariables = localVariables; this.panelVariables = panelVariables; + this.formVariables = formVariables; + this.uiVariables = uiVariables; this.bpmnType = bpmnType; this.category = category; this.description = description; 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 d54d77b7..17238425 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 @@ -100,93 +100,29 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl 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"); - } - } + Class panelVariables = nodeType.getPanelVariables(); + if (panelVariables != null) { + definedDTO.setPanelVariablesSchema(generateSchema(panelVariables)); + } + Class localVariables = nodeType.getLocalVariables(); + if (localVariables != null) { + definedDTO.setLocalVariablesSchema(generateSchema(localVariables)); } - // 添加required字段 - if (!required.isEmpty()) { - ArrayNode requiredNode = schema.putArray("required"); - required.forEach(requiredNode::add); + Class formVariables = nodeType.getFormVariables(); + if (formVariables != null) { + definedDTO.setFormVariablesSchema(generateSchema(formVariables)); + } + + Class uiVariables = nodeType.getUiVariables(); + if (formVariables != null) { + definedDTO.setUiVariables(generateSchema(uiVariables)); } - definedDTO.setPanelVariablesSchema(schema); result.add(definedDTO); - } catch (Exception e) { log.error("Error processing node type: " + nodeType, e); } @@ -195,6 +131,95 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl cls) { + ObjectMapper mapper = new ObjectMapper(); + ObjectNode schema = mapper.createObjectNode(); + schema.put("type", "object"); + + // 处理属性 + ObjectNode properties = schema.putObject("properties"); + List required = new ArrayList<>(); + + // 获取所有字段,包括父类的字段 + List allFields = getAllFields(cls); + + // 遍历所有字段 + for (Field field : allFields) { + SchemaProperty annotation = field.getAnnotation(SchemaProperty.class); + if (annotation != null) { + ObjectNode property = properties.putObject(field.getName()); + + // 设置基本属性 + String jsonType = getJsonSchemaType(field.getType()); + property.put("type", jsonType); + + // 从注解中获取属性 + 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"); + } + + // 处理嵌套对象 + if (property.get("type").asText().equals("object") + && !Map.class.isAssignableFrom(field.getType()) + && !field.getType().getName().startsWith("java.")) { + ObjectNode nestedSchema = generateSchema(field.getType()); + if (nestedSchema.has("properties")) { + property.set("properties", nestedSchema.get("properties")); + } + if (nestedSchema.has("required")) { + property.set("required", nestedSchema.get("required")); + } + } + } + } + + // 添加required字段 + if (!required.isEmpty()) { + ArrayNode requiredNode = schema.putArray("required"); + required.forEach(requiredNode::add); + } + return schema; + } + /** * 获取类的所有字段,包括父类的字段 */ @@ -206,7 +231,7 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl