反序列化问题。

This commit is contained in:
dengqichen 2024-12-19 14:53:48 +08:00
parent 9357117174
commit 846019211e
16 changed files with 394 additions and 86 deletions

View File

@ -17,8 +17,15 @@ public class WorkflowNodeTypeDefinedDTO {
@Schema(description = "节点名称") @Schema(description = "节点名称")
private String nodeName; private String nodeName;
@Schema(description = "节点属性JSON SCHEMA") @Schema(description = "节点属性变量JSON SCHEMA")
private JsonNode panelVariablesSchema; private JsonNode panelVariablesSchema;
@Schema(description = "节点环境变量JSON SCHEMA")
private JsonNode localVariablesSchema; private JsonNode localVariablesSchema;
@Schema(description = "节点表单变量JSON SCHEMA")
private JsonNode formVariablesSchema;
@Schema(description = "自定义节点UI JSON SCHEMA")
private JsonNode uiVariables;
} }

View File

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

View File

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

View File

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

View File

@ -1,11 +1,10 @@
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.dto.definition.node.panelVariables.BaseNodePanelVariables;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class ScriptNodeLocalVariables extends BaseNodePanelVariables { public class ScriptNodeLocalVariables extends BaseNodeLocalVariables {
} }

View File

@ -1,8 +1,6 @@
package com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables; 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.annotation.SchemaProperty;
import com.qqchen.deploy.backend.workflow.enums.NodeTypeEnums;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -13,7 +11,6 @@ import java.util.List;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@NodeTypeLocalVariablesBind(type = NodeTypeEnums.SCRIPT_TASK)
public class ScriptNodePanelVariables extends BaseNodePanelVariables { public class ScriptNodePanelVariables extends BaseNodePanelVariables {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,10 +1,12 @@
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.fromVariables.ScriptNodeFormVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.localVariables.ScriptNodeLocalVariables; 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.EndNodePanelVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.panelVariables.ScriptNodePanelVariables; 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.panelVariables.StartNodePanelVariables;
import com.qqchen.deploy.backend.workflow.dto.definition.node.uiVariables.NodeUiVariables;
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;
@ -29,6 +31,8 @@ public enum NodeTypeEnums {
"开始节点", // 节点显示名称 "开始节点", // 节点显示名称
null, null,
StartNodePanelVariables.class, StartNodePanelVariables.class,
null,
NodeUiVariables.class,
BpmnNodeTypeEnums.START_EVENT, BpmnNodeTypeEnums.START_EVENT,
NodeCategoryEnums.EVENT, NodeCategoryEnums.EVENT,
"工作流的起点", // 节点简要描述 "工作流的起点", // 节点简要描述
@ -51,6 +55,8 @@ public enum NodeTypeEnums {
"结束节点", "结束节点",
null, null,
EndNodePanelVariables.class, EndNodePanelVariables.class,
null,
NodeUiVariables.class,
BpmnNodeTypeEnums.END_EVENT, BpmnNodeTypeEnums.END_EVENT,
NodeCategoryEnums.EVENT, NodeCategoryEnums.EVENT,
"工作流的终点", "工作流的终点",
@ -65,6 +71,8 @@ public enum NodeTypeEnums {
"脚本任务", "脚本任务",
ScriptNodeLocalVariables.class, ScriptNodeLocalVariables.class,
ScriptNodePanelVariables.class, ScriptNodePanelVariables.class,
ScriptNodeFormVariables.class,
NodeUiVariables.class,
BpmnNodeTypeEnums.SERVICE_TASK, BpmnNodeTypeEnums.SERVICE_TASK,
NodeCategoryEnums.TASK, NodeCategoryEnums.TASK,
"脚本执行任务", "脚本执行任务",
@ -217,6 +225,10 @@ public enum NodeTypeEnums {
private final Class<?> panelVariables; private final Class<?> panelVariables;
private final Class<?> formVariables;
private final Class<?> uiVariables;
private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型 private final BpmnNodeTypeEnums bpmnType; // 对应的BPMN类型
private final NodeCategoryEnums category; //分类 private final NodeCategoryEnums category; //分类
@ -230,6 +242,8 @@ public enum NodeTypeEnums {
String name, String name,
Class<?> localVariables, Class<?> localVariables,
Class<?> panelVariables, Class<?> panelVariables,
Class<?> formVariables,
Class<?> uiVariables,
BpmnNodeTypeEnums bpmnType, BpmnNodeTypeEnums bpmnType,
NodeCategoryEnums category, NodeCategoryEnums category,
String description, String description,
@ -238,6 +252,8 @@ public enum NodeTypeEnums {
this.name = name; this.name = name;
this.localVariables = localVariables; this.localVariables = localVariables;
this.panelVariables = panelVariables; this.panelVariables = panelVariables;
this.formVariables = formVariables;
this.uiVariables = uiVariables;
this.bpmnType = bpmnType; this.bpmnType = bpmnType;
this.category = category; this.category = category;
this.description = description; this.description = description;

View File

@ -100,18 +100,38 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
// 遍历所有节点类型 // 遍历所有节点类型
for (NodeTypeEnums nodeType : NodeTypeEnums.values()) { for (NodeTypeEnums nodeType : NodeTypeEnums.values()) {
try { try {
// 获取localVariables类型
Class<?> panelVariables = nodeType.getPanelVariables();
if (panelVariables == null) {
continue;
}
// 创建结果对象
WorkflowNodeTypeDefinedDTO definedDTO = new WorkflowNodeTypeDefinedDTO(); WorkflowNodeTypeDefinedDTO definedDTO = new WorkflowNodeTypeDefinedDTO();
definedDTO.setNodeCode(nodeType.getCode()); definedDTO.setNodeCode(nodeType.getCode());
definedDTO.setNodeName(nodeType.getName()); definedDTO.setNodeName(nodeType.getName());
Class<?> panelVariables = nodeType.getPanelVariables();
if (panelVariables != null) {
definedDTO.setPanelVariablesSchema(generateSchema(panelVariables));
}
Class<?> localVariables = nodeType.getLocalVariables();
if (localVariables != null) {
definedDTO.setLocalVariablesSchema(generateSchema(localVariables));
}
// 生成schema Class<?> formVariables = nodeType.getFormVariables();
if (formVariables != null) {
definedDTO.setFormVariablesSchema(generateSchema(formVariables));
}
Class<?> uiVariables = nodeType.getUiVariables();
if (formVariables != null) {
definedDTO.setUiVariables(generateSchema(uiVariables));
}
result.add(definedDTO);
} catch (Exception e) {
log.error("Error processing node type: " + nodeType, e);
}
}
return result;
}
private ObjectNode generateSchema(Class<?> cls) {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
ObjectNode schema = mapper.createObjectNode(); ObjectNode schema = mapper.createObjectNode();
schema.put("type", "object"); schema.put("type", "object");
@ -121,7 +141,7 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
List<String> required = new ArrayList<>(); List<String> required = new ArrayList<>();
// 获取所有字段包括父类的字段 // 获取所有字段包括父类的字段
List<Field> allFields = getAllFields(panelVariables); List<Field> allFields = getAllFields(cls);
// 遍历所有字段 // 遍历所有字段
for (Field field : allFields) { for (Field field : allFields) {
@ -130,7 +150,8 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
ObjectNode property = properties.putObject(field.getName()); ObjectNode property = properties.putObject(field.getName());
// 设置基本属性 // 设置基本属性
property.put("type", getJsonSchemaType(field.getType())); String jsonType = getJsonSchemaType(field.getType());
property.put("type", jsonType);
// 从注解中获取属性 // 从注解中获取属性
if (!annotation.title().isEmpty()) { if (!annotation.title().isEmpty()) {
@ -175,6 +196,19 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
ObjectNode additionalProperties = property.putObject("additionalProperties"); ObjectNode additionalProperties = property.putObject("additionalProperties");
additionalProperties.put("type", "string"); 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"));
}
}
} }
} }
@ -183,16 +217,7 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
ArrayNode requiredNode = schema.putArray("required"); ArrayNode requiredNode = schema.putArray("required");
required.forEach(requiredNode::add); required.forEach(requiredNode::add);
} }
return schema;
definedDTO.setPanelVariablesSchema(schema);
result.add(definedDTO);
} catch (Exception e) {
log.error("Error processing node type: " + nodeType, e);
}
}
return result;
} }
/** /**
@ -206,7 +231,7 @@ public class WorkflowNodeDefinitionServiceImpl extends BaseServiceImpl<WorkflowN
while (currentClass != null && !currentClass.equals(Object.class)) { while (currentClass != null && !currentClass.equals(Object.class)) {
// 添加当前类的字段 // 添加当前类的字段
fields.addAll(Arrays.asList(currentClass.getDeclaredFields())); fields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
// 获取 // 获取<EFBFBD><EFBFBD><EFBFBD>
currentClass = currentClass.getSuperclass(); currentClass = currentClass.getSuperclass();
} }