增加formily json schema生成
This commit is contained in:
parent
72178f3393
commit
5cd9f4c4d3
@ -1,141 +1,114 @@
|
|||||||
package com.qqchen.deploy.backend.deploy.dto.variables.build;
|
package com.qqchen.deploy.backend.deploy.dto.variables.build;
|
||||||
|
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.CodeEditorConfig;
|
import com.qqchen.deploy.backend.framework.annotation.formily.*;
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaProperty;
|
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSource;
|
|
||||||
import com.qqchen.deploy.backend.workflow.annotation.SchemaPropertyDataSourceParam;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jenkins构建变量
|
* Jenkins构建变量
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
|
@FormilyForm(name = "Jenkins构建配置")
|
||||||
public class JenkinsBaseBuildVariables {
|
public class JenkinsBaseBuildVariables {
|
||||||
|
|
||||||
@SchemaProperty(
|
@FormilyField(
|
||||||
title = "绑定三方Jenkins系统",
|
title = "绑定三方Jenkins系统",
|
||||||
description = "请选择三方Jenkins系统",
|
type = "string",
|
||||||
required = true,
|
component = "Select",
|
||||||
dataSource = @SchemaPropertyDataSource(
|
props = @FormilyComponentProps(
|
||||||
type = "api",
|
api = "/api/v1/external-system/list?type=JENKINS",
|
||||||
url = "/api/v1/external-system/list?type=JENKINS",
|
labelField = "name",
|
||||||
valueField = "id",
|
valueField = "id",
|
||||||
labelField = "name"
|
showSearch = true,
|
||||||
|
allowClear = true,
|
||||||
|
placeholder = "请选择Jenkins系统"
|
||||||
),
|
),
|
||||||
order = 2
|
validators = {
|
||||||
|
@FormilyValidator(
|
||||||
|
required = true,
|
||||||
|
message = "请选择Jenkins系统"
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
private String externalSystemId;
|
private String externalSystemId;
|
||||||
|
|
||||||
|
@FormilyField(
|
||||||
@SchemaProperty(
|
|
||||||
title = "绑定Jenkins视图",
|
title = "绑定Jenkins视图",
|
||||||
description = "Jenkins视图",
|
type = "string",
|
||||||
required = true,
|
component = "Select",
|
||||||
dataSource = @SchemaPropertyDataSource(
|
props = @FormilyComponentProps(
|
||||||
type = "api",
|
|
||||||
url = "/api/v1/jenkins-view/list",
|
|
||||||
valueField = "id",
|
|
||||||
labelField = "viewName",
|
labelField = "viewName",
|
||||||
dependsOn = {"externalSystemId"},
|
valueField = "id",
|
||||||
params = {
|
showSearch = true,
|
||||||
@SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${externalSystemId}")
|
allowClear = true,
|
||||||
}
|
placeholder = "请选择Jenkins视图"
|
||||||
),
|
),
|
||||||
order = 3
|
validators = {
|
||||||
|
@FormilyValidator(
|
||||||
|
required = true,
|
||||||
|
message = "请选择Jenkins视图"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
reactions = {
|
||||||
|
@FormilyReaction(
|
||||||
|
dependencies = {"externalSystemId"},
|
||||||
|
state = "dataSource",
|
||||||
|
value = "{{$fetch('/api/v1/jenkins-view/list?externalSystemId=' + $deps.externalSystemId).then(data => data.data)}}"
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
private String viewId;
|
private String viewId;
|
||||||
|
|
||||||
|
@FormilyField(
|
||||||
@SchemaProperty(
|
|
||||||
title = "绑定Jenkins任务",
|
title = "绑定Jenkins任务",
|
||||||
description = "Jenkins任务",
|
type = "string",
|
||||||
required = true,
|
component = "Select",
|
||||||
dataSource = @SchemaPropertyDataSource(
|
props = @FormilyComponentProps(
|
||||||
type = "api",
|
|
||||||
url = "/api/v1/jenkins-job/list",
|
|
||||||
valueField = "id",
|
|
||||||
labelField = "jobName",
|
labelField = "jobName",
|
||||||
dependsOn = {"externalSystemId", "viewId"},
|
valueField = "id",
|
||||||
params = {
|
showSearch = true,
|
||||||
@SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${externalSystemId}"),
|
allowClear = true,
|
||||||
@SchemaPropertyDataSourceParam(name = "viewId", value = "${viewId}")
|
placeholder = "请选择Jenkins任务"
|
||||||
}
|
|
||||||
),
|
),
|
||||||
order = 4
|
validators = {
|
||||||
|
@FormilyValidator(
|
||||||
|
required = true,
|
||||||
|
message = "请选择Jenkins任务"
|
||||||
|
)
|
||||||
|
},
|
||||||
|
reactions = {
|
||||||
|
@FormilyReaction(
|
||||||
|
dependencies = {"externalSystemId", "viewId"},
|
||||||
|
state = "dataSource",
|
||||||
|
value = "{{$fetch('/api/v1/jenkins-job/list?externalSystemId=' + $deps.externalSystemId + '&viewId=' + $deps.viewId).then(data => data.data)}}"
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
private String jobId;
|
private String jobId;
|
||||||
|
|
||||||
|
@FormilyField(
|
||||||
@SchemaProperty(
|
|
||||||
title = "Pipeline script",
|
title = "Pipeline script",
|
||||||
description = "流水线脚本",
|
type = "string",
|
||||||
required = true,
|
component = "MonacoEditor",
|
||||||
format = "monaco-editor", // 使用 Monaco Editor
|
props = @FormilyComponentProps(
|
||||||
defaultValue = "#!/bin/bash\n\necho \"Hello World\"",
|
editor = @FormilyEditorProps(
|
||||||
codeEditor = @CodeEditorConfig(
|
language = "groovy",
|
||||||
language = "groovy",
|
theme = "vs-dark",
|
||||||
theme = "vs-dark",
|
minimap = false,
|
||||||
minimap = false,
|
lineNumbers = true,
|
||||||
lineNumbers = true,
|
wordWrap = true,
|
||||||
wordWrap = true,
|
fontSize = 14,
|
||||||
fontSize = 14,
|
tabSize = 4,
|
||||||
tabSize = 2,
|
automaticLayout = true,
|
||||||
autoComplete = true,
|
folding = true,
|
||||||
folding = true
|
placeholder = "请输入Pipeline脚本"
|
||||||
|
)
|
||||||
),
|
),
|
||||||
order = 5
|
validators = {
|
||||||
|
@FormilyValidator(
|
||||||
|
required = true,
|
||||||
|
message = "请输入Pipeline脚本"
|
||||||
|
)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
private String script;
|
private String script;
|
||||||
//
|
|
||||||
// @SchemaProperty(
|
|
||||||
// title = "绑定三方Git系统",
|
|
||||||
// description = "请选择三方Git系统",
|
|
||||||
// required = true,
|
|
||||||
// dataSource = @SchemaPropertyDataSource(
|
|
||||||
// type = "api",
|
|
||||||
// url = "/api/v1/external-system/list?type=GIT",
|
|
||||||
// valueField = "id",
|
|
||||||
// labelField = "name"
|
|
||||||
// ),
|
|
||||||
// order = 6
|
|
||||||
// )
|
|
||||||
// private String gitExternalSystemId;
|
|
||||||
//
|
|
||||||
// @SchemaProperty(
|
|
||||||
// title = "绑定Git项目",
|
|
||||||
// description = "绑定Git项目",
|
|
||||||
// required = true,
|
|
||||||
// dataSource = @SchemaPropertyDataSource(
|
|
||||||
// type = "api",
|
|
||||||
// url = "/api/v1/repository-project/list",
|
|
||||||
// valueField = "repoProjectId",
|
|
||||||
// labelField = "name",
|
|
||||||
// dependsOn = {"gitExternalSystemId"},
|
|
||||||
// params = {
|
|
||||||
// @SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${gitExternalSystemId}")
|
|
||||||
// }
|
|
||||||
// ),
|
|
||||||
// order = 7
|
|
||||||
// )
|
|
||||||
// private String repoProjectId;
|
|
||||||
//
|
|
||||||
// @SchemaProperty(
|
|
||||||
// title = "绑定代码分支",
|
|
||||||
// description = "请选择代码分支",
|
|
||||||
// required = true,
|
|
||||||
// dataSource = @SchemaPropertyDataSource(
|
|
||||||
// type = "api",
|
|
||||||
// url = "/api/v1/repository-branch/list",
|
|
||||||
// valueField = "name",
|
|
||||||
// labelField = "name",
|
|
||||||
// dependsOn = {"gitExternalSystemId", "repoProjectId"},
|
|
||||||
// params = {
|
|
||||||
// @SchemaPropertyDataSourceParam(name = "externalSystemId", value = "${gitExternalSystemId}"),
|
|
||||||
// @SchemaPropertyDataSourceParam(name = "repoProjectId", value = "${repoProjectId}")
|
|
||||||
// }
|
|
||||||
// ),
|
|
||||||
// order = 8
|
|
||||||
// )
|
|
||||||
// private String branch;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.qqchen.deploy.backend.deploy.dto.variables.build;
|
package com.qqchen.deploy.backend.deploy.dto.variables.build;
|
||||||
|
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.formily.FormilyForm;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.qqchen.deploy.backend.deploy.service.impl;
|
package com.qqchen.deploy.backend.deploy.service.impl;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.qqchen.deploy.backend.deploy.converter.ApplicationConverter;
|
import com.qqchen.deploy.backend.deploy.converter.ApplicationConverter;
|
||||||
import com.qqchen.deploy.backend.deploy.converter.DeployLogConverter;
|
import com.qqchen.deploy.backend.deploy.converter.DeployLogConverter;
|
||||||
@ -20,6 +21,7 @@ import com.qqchen.deploy.backend.deploy.repository.IDeployLogRepository;
|
|||||||
import com.qqchen.deploy.backend.deploy.repository.IEnvironmentRepository;
|
import com.qqchen.deploy.backend.deploy.repository.IEnvironmentRepository;
|
||||||
import com.qqchen.deploy.backend.deploy.service.IDeployAppConfigService;
|
import com.qqchen.deploy.backend.deploy.service.IDeployAppConfigService;
|
||||||
import com.qqchen.deploy.backend.deploy.service.IDeployLogService;
|
import com.qqchen.deploy.backend.deploy.service.IDeployLogService;
|
||||||
|
import com.qqchen.deploy.backend.framework.annotation.formily.FormilySchemaFactory;
|
||||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||||
import com.qqchen.deploy.backend.workflow.converter.WorkflowDefinitionConverter;
|
import com.qqchen.deploy.backend.workflow.converter.WorkflowDefinitionConverter;
|
||||||
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
|
import com.qqchen.deploy.backend.workflow.dto.WorkflowInstanceDTO;
|
||||||
@ -40,7 +42,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import static com.qqchen.deploy.backend.workflow.util.GenerateSchemaUtils.generateSchema;
|
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -129,7 +130,9 @@ public class DeployAppConfigServiceImpl extends BaseServiceImpl<DeployAppConfig,
|
|||||||
definedDTO.setName(buildType.getName());
|
definedDTO.setName(buildType.getName());
|
||||||
definedDTO.setBuildType(buildType);
|
definedDTO.setBuildType(buildType);
|
||||||
definedDTO.setLanguageType(languages[i]);
|
definedDTO.setLanguageType(languages[i]);
|
||||||
definedDTO.setBuildVariablesSchema(generateSchema(buildVariablesClasses[i]));
|
// 使用新的FormilySchemaFactory生成Schema
|
||||||
|
JsonNode schema = FormilySchemaFactory.generateSchema(buildVariablesClasses[i]);
|
||||||
|
definedDTO.setBuildVariablesSchema(schema);
|
||||||
result.add(definedDTO);
|
result.add(definedDTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +174,8 @@ public class DeployAppConfigServiceImpl extends BaseServiceImpl<DeployAppConfig,
|
|||||||
@Override
|
@Override
|
||||||
public DeployAppConfigDTO create(DeployAppConfigDTO dto) {
|
public DeployAppConfigDTO create(DeployAppConfigDTO dto) {
|
||||||
DeployAppConfig entity = converter.toEntity(dto);
|
DeployAppConfig entity = converter.toEntity(dto);
|
||||||
entity.setFormVariablesSchema(generateSchema(dto.getBuildType().getFormVariablesSchema()));
|
// 使用新的FormilySchemaFactory生成Schema
|
||||||
|
entity.setFormVariablesSchema(FormilySchemaFactory.generateSchema(dto.getBuildType().getFormVariablesSchema()));
|
||||||
this.repository.save(entity);
|
this.repository.save(entity);
|
||||||
return converter.toDto(entity);
|
return converter.toDto(entity);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,9 @@ package com.qqchen.deploy.backend.framework.annotation.formily;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
|
||||||
@Target({})
|
@Target({ElementType.FIELD})
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
public @interface FormilyComponentProps {
|
public @interface FormilyComponentProps {
|
||||||
String api() default ""; // 数据源API
|
String api() default ""; // 数据源API
|
||||||
@ -16,4 +17,7 @@ public @interface FormilyComponentProps {
|
|||||||
String mode() default ""; // 模式(single/multiple等)
|
String mode() default ""; // 模式(single/multiple等)
|
||||||
String[] enum_() default {}; // 枚举值
|
String[] enum_() default {}; // 枚举值
|
||||||
String[] enumNames() default {}; // 枚举显示值
|
String[] enumNames() default {}; // 枚举显示值
|
||||||
|
|
||||||
|
// 编辑器属性
|
||||||
|
FormilyEditorProps editor() default @FormilyEditorProps; // 编辑器配置
|
||||||
}
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.qqchen.deploy.backend.framework.annotation.formily;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface FormilyEditorProps {
|
||||||
|
/**
|
||||||
|
* 编辑器语言
|
||||||
|
*/
|
||||||
|
String language() default "plaintext";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑器主题
|
||||||
|
*/
|
||||||
|
String theme() default "vs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用小地图
|
||||||
|
*/
|
||||||
|
boolean minimap() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否显示行号
|
||||||
|
*/
|
||||||
|
boolean lineNumbers() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动换行
|
||||||
|
*/
|
||||||
|
boolean wordWrap() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字体大小
|
||||||
|
*/
|
||||||
|
int fontSize() default 14;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tab大小
|
||||||
|
*/
|
||||||
|
int tabSize() default 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否自动布局
|
||||||
|
*/
|
||||||
|
boolean automaticLayout() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用代码折叠
|
||||||
|
*/
|
||||||
|
boolean folding() default true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 占位符文本
|
||||||
|
*/
|
||||||
|
String placeholder() default "";
|
||||||
|
}
|
||||||
@ -6,7 +6,9 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
|
|||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class FormilySchemaFactory {
|
public class FormilySchemaFactory {
|
||||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
@ -17,11 +19,23 @@ public class FormilySchemaFactory {
|
|||||||
* @return Formily JSON Schema
|
* @return Formily JSON Schema
|
||||||
*/
|
*/
|
||||||
public static JsonNode generateSchema(Class<?> clazz) {
|
public static JsonNode generateSchema(Class<?> clazz) {
|
||||||
FormilyForm formDef = clazz.getAnnotation(FormilyForm.class);
|
if (clazz == null) {
|
||||||
if (formDef == null) {
|
throw new IllegalArgumentException("Class cannot be null");
|
||||||
throw new IllegalArgumentException("Class must be annotated with @FormilyForm");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有字段,包括父类的字段
|
||||||
|
List<Field> allFields = getAllFields(clazz);
|
||||||
|
if (allFields.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("No fields found in class: " + clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取最近的带有FormilyForm注解的类(可能是父类)
|
||||||
|
Class<?> formClass = findNearestFormClass(clazz);
|
||||||
|
if (formClass == null) {
|
||||||
|
throw new IllegalArgumentException("No @FormilyForm annotation found in class hierarchy: " + clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
FormilyForm formDef = formClass.getAnnotation(FormilyForm.class);
|
||||||
ObjectNode schema = objectMapper.createObjectNode();
|
ObjectNode schema = objectMapper.createObjectNode();
|
||||||
schema.put("type", "object");
|
schema.put("type", "object");
|
||||||
schema.put("name", formDef.name());
|
schema.put("name", formDef.name());
|
||||||
@ -30,17 +44,58 @@ public class FormilySchemaFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ObjectNode properties = schema.putObject("properties");
|
ObjectNode properties = schema.putObject("properties");
|
||||||
|
boolean hasFields = false;
|
||||||
|
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
for (Field field : allFields) {
|
||||||
FormilyField fieldDef = field.getAnnotation(FormilyField.class);
|
FormilyField fieldDef = field.getAnnotation(FormilyField.class);
|
||||||
if (fieldDef != null) {
|
if (fieldDef != null) {
|
||||||
properties.set(field.getName(), generateFieldSchema(fieldDef));
|
properties.set(field.getName(), generateFieldSchema(fieldDef));
|
||||||
|
hasFields = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!hasFields) {
|
||||||
|
throw new IllegalArgumentException("No @FormilyField annotations found in class hierarchy: " + clazz.getName());
|
||||||
|
}
|
||||||
|
|
||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取类的所有字段,包括父类的字段
|
||||||
|
* @param clazz 要获取字段的类
|
||||||
|
* @return 所有字段的列表
|
||||||
|
*/
|
||||||
|
private static List<Field> getAllFields(Class<?> clazz) {
|
||||||
|
List<Field> fields = new ArrayList<>();
|
||||||
|
Class<?> currentClass = clazz;
|
||||||
|
|
||||||
|
while (currentClass != null && currentClass != Object.class) {
|
||||||
|
fields.addAll(Arrays.asList(currentClass.getDeclaredFields()));
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找最近的带有FormilyForm注解的类
|
||||||
|
* @param clazz 要查找的类
|
||||||
|
* @return 带有FormilyForm注解的最近的类,如果没有找到则返回null
|
||||||
|
*/
|
||||||
|
private static Class<?> findNearestFormClass(Class<?> clazz) {
|
||||||
|
Class<?> currentClass = clazz;
|
||||||
|
|
||||||
|
while (currentClass != null && currentClass != Object.class) {
|
||||||
|
if (currentClass.isAnnotationPresent(FormilyForm.class)) {
|
||||||
|
return currentClass;
|
||||||
|
}
|
||||||
|
currentClass = currentClass.getSuperclass();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static JsonNode generateFieldSchema(FormilyField field) {
|
private static JsonNode generateFieldSchema(FormilyField field) {
|
||||||
ObjectNode fieldSchema = objectMapper.createObjectNode();
|
ObjectNode fieldSchema = objectMapper.createObjectNode();
|
||||||
|
|
||||||
@ -56,7 +111,7 @@ public class FormilySchemaFactory {
|
|||||||
fieldSchema.put("x-component", field.component());
|
fieldSchema.put("x-component", field.component());
|
||||||
|
|
||||||
// 组件属性配置
|
// 组件属性配置
|
||||||
ObjectNode componentProps = generateComponentProps(field.props());
|
ObjectNode componentProps = generateComponentProps(field.props(), field.component());
|
||||||
if (componentProps.size() > 0) {
|
if (componentProps.size() > 0) {
|
||||||
fieldSchema.set("x-component-props", componentProps);
|
fieldSchema.set("x-component-props", componentProps);
|
||||||
}
|
}
|
||||||
@ -91,37 +146,64 @@ public class FormilySchemaFactory {
|
|||||||
return fieldSchema;
|
return fieldSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ObjectNode generateComponentProps(FormilyComponentProps props) {
|
private static ObjectNode generateComponentProps(FormilyComponentProps props, String componentType) {
|
||||||
ObjectNode node = objectMapper.createObjectNode();
|
ObjectNode node = objectMapper.createObjectNode();
|
||||||
|
|
||||||
if (!props.api().isEmpty()) {
|
// Select组件属性
|
||||||
node.put("api", props.api());
|
if ("Select".equals(componentType)) {
|
||||||
|
if (!props.api().isEmpty()) {
|
||||||
|
node.put("api", props.api());
|
||||||
|
}
|
||||||
|
if (!props.labelField().equals("label")) {
|
||||||
|
node.put("labelField", props.labelField());
|
||||||
|
}
|
||||||
|
if (!props.valueField().equals("value")) {
|
||||||
|
node.put("valueField", props.valueField());
|
||||||
|
}
|
||||||
|
if (props.allowClear()) {
|
||||||
|
node.put("allowClear", true);
|
||||||
|
}
|
||||||
|
if (props.showSearch()) {
|
||||||
|
node.put("showSearch", true);
|
||||||
|
}
|
||||||
|
if (!props.placeholder().isEmpty()) {
|
||||||
|
node.put("placeholder", props.placeholder());
|
||||||
|
}
|
||||||
|
if (!props.mode().isEmpty()) {
|
||||||
|
node.put("mode", props.mode());
|
||||||
|
}
|
||||||
|
if (props.enum_().length > 0) {
|
||||||
|
ArrayNode enumValues = node.putArray("enum");
|
||||||
|
Arrays.stream(props.enum_()).forEach(enumValues::add);
|
||||||
|
}
|
||||||
|
if (props.enumNames().length > 0) {
|
||||||
|
ArrayNode enumNames = node.putArray("enumNames");
|
||||||
|
Arrays.stream(props.enumNames()).forEach(enumNames::add);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!props.labelField().equals("label")) {
|
|
||||||
node.put("labelField", props.labelField());
|
// MonacoEditor组件属性
|
||||||
}
|
if ("MonacoEditor".equals(componentType)) {
|
||||||
if (!props.valueField().equals("value")) {
|
FormilyEditorProps editorProps = props.editor();
|
||||||
node.put("valueField", props.valueField());
|
if (editorProps != null) {
|
||||||
}
|
if (!editorProps.placeholder().isEmpty()) {
|
||||||
if (props.allowClear()) {
|
node.put("placeholder", editorProps.placeholder());
|
||||||
node.put("allowClear", true);
|
}
|
||||||
}
|
|
||||||
if (props.showSearch()) {
|
ObjectNode options = node.putObject("options");
|
||||||
node.put("showSearch", true);
|
options.put("language", editorProps.language());
|
||||||
}
|
options.put("theme", editorProps.theme());
|
||||||
if (!props.placeholder().isEmpty()) {
|
|
||||||
node.put("placeholder", props.placeholder());
|
ObjectNode minimap = options.putObject("minimap");
|
||||||
}
|
minimap.put("enabled", editorProps.minimap());
|
||||||
if (!props.mode().isEmpty()) {
|
|
||||||
node.put("mode", props.mode());
|
options.put("lineNumbers", editorProps.lineNumbers() ? "on" : "off");
|
||||||
}
|
options.put("wordWrap", editorProps.wordWrap() ? "on" : "off");
|
||||||
if (props.enum_().length > 0) {
|
options.put("fontSize", editorProps.fontSize());
|
||||||
ArrayNode enumValues = node.putArray("enum");
|
options.put("tabSize", editorProps.tabSize());
|
||||||
Arrays.stream(props.enum_()).forEach(enumValues::add);
|
options.put("automaticLayout", editorProps.automaticLayout());
|
||||||
}
|
options.put("folding", editorProps.folding());
|
||||||
if (props.enumNames().length > 0) {
|
}
|
||||||
ArrayNode enumNames = node.putArray("enumNames");
|
|
||||||
Arrays.stream(props.enumNames()).forEach(enumNames::add);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
|||||||
@ -42,7 +42,7 @@ public class FormilySchemaFactoryTest {
|
|||||||
|
|
||||||
JsonNode fulfillB = reactionB.get("fulfill");
|
JsonNode fulfillB = reactionB.get("fulfill");
|
||||||
JsonNode stateB = fulfillB.get("state");
|
JsonNode stateB = fulfillB.get("state");
|
||||||
assertEquals("{{$fetch('/api/options/B?a=' + $deps.a).then(data => data.data)}}",
|
assertEquals("{{$fetch('/api/v1/jenkins-view/list?externalSystemId=' + $deps.a).then(data => data.data)}}",
|
||||||
stateB.get("dataSource").asText());
|
stateB.get("dataSource").asText());
|
||||||
|
|
||||||
// 验证字段C的联动
|
// 验证字段C的联动
|
||||||
@ -57,8 +57,28 @@ public class FormilySchemaFactoryTest {
|
|||||||
|
|
||||||
JsonNode fulfillC = reactionC.get("fulfill");
|
JsonNode fulfillC = reactionC.get("fulfill");
|
||||||
JsonNode stateC = fulfillC.get("state");
|
JsonNode stateC = fulfillC.get("state");
|
||||||
assertEquals("{{$fetch('/api/options/C?a=' + $deps.a + '&b=' + $deps.b).then(data => data.data)}}",
|
assertEquals("{{$fetch('/api/v1/jenkins-job/list?externalSystemId=' + $deps.a + '&viewId=' + $deps.b).then(data => data.data)}}",
|
||||||
stateC.get("dataSource").asText());
|
stateC.get("dataSource").asText());
|
||||||
|
|
||||||
|
// 验证编辑器字段
|
||||||
|
JsonNode fieldScript = schema.get("properties").get("script");
|
||||||
|
assertEquals("string", fieldScript.get("type").asText());
|
||||||
|
assertEquals("Pipeline script", fieldScript.get("title").asText());
|
||||||
|
assertEquals("MonacoEditor", fieldScript.get("x-component").asText());
|
||||||
|
|
||||||
|
// 验证编辑器属性
|
||||||
|
JsonNode scriptProps = fieldScript.get("x-component-props");
|
||||||
|
JsonNode options = scriptProps.get("options");
|
||||||
|
assertEquals("groovy", options.get("language").asText());
|
||||||
|
assertEquals("vs-dark", options.get("theme").asText());
|
||||||
|
assertFalse(options.get("minimap").get("enabled").asBoolean());
|
||||||
|
assertEquals("on", options.get("lineNumbers").asText());
|
||||||
|
assertEquals("on", options.get("wordWrap").asText());
|
||||||
|
assertEquals(14, options.get("fontSize").asInt());
|
||||||
|
assertEquals(4, options.get("tabSize").asInt());
|
||||||
|
assertTrue(options.get("automaticLayout").asBoolean());
|
||||||
|
assertTrue(options.get("folding").asBoolean());
|
||||||
|
assertEquals("请输入Pipeline脚本", scriptProps.get("placeholder").asText());
|
||||||
|
|
||||||
// 打印生成的Schema以便查看
|
// 打印生成的Schema以便查看
|
||||||
System.out.println(schema.toPrettyString());
|
System.out.println(schema.toPrettyString());
|
||||||
@ -89,7 +109,7 @@ class TestForm {
|
|||||||
title = "选择B",
|
title = "选择B",
|
||||||
component = "Select",
|
component = "Select",
|
||||||
props = @FormilyComponentProps(
|
props = @FormilyComponentProps(
|
||||||
labelField = "name",
|
labelField = "viewName",
|
||||||
valueField = "id"
|
valueField = "id"
|
||||||
),
|
),
|
||||||
validators = {
|
validators = {
|
||||||
@ -102,7 +122,7 @@ class TestForm {
|
|||||||
@FormilyReaction(
|
@FormilyReaction(
|
||||||
dependencies = {"a"},
|
dependencies = {"a"},
|
||||||
state = "dataSource",
|
state = "dataSource",
|
||||||
value = "{{$fetch('/api/options/B?a=' + $deps.a).then(data => data.data)}}"
|
value = "{{$fetch('/api/v1/jenkins-view/list?externalSystemId=' + $deps.a).then(data => data.data)}}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -112,7 +132,7 @@ class TestForm {
|
|||||||
title = "选择C",
|
title = "选择C",
|
||||||
component = "Select",
|
component = "Select",
|
||||||
props = @FormilyComponentProps(
|
props = @FormilyComponentProps(
|
||||||
labelField = "name",
|
labelField = "jobName",
|
||||||
valueField = "id"
|
valueField = "id"
|
||||||
),
|
),
|
||||||
validators = {
|
validators = {
|
||||||
@ -125,9 +145,36 @@ class TestForm {
|
|||||||
@FormilyReaction(
|
@FormilyReaction(
|
||||||
dependencies = {"a", "b"},
|
dependencies = {"a", "b"},
|
||||||
state = "dataSource",
|
state = "dataSource",
|
||||||
value = "{{$fetch('/api/options/C?a=' + $deps.a + '&b=' + $deps.b).then(data => data.data)}}"
|
value = "{{$fetch('/api/v1/jenkins-job/list?externalSystemId=' + $deps.a + '&viewId=' + $deps.b).then(data => data.data)}}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
private String c;
|
private String c;
|
||||||
|
|
||||||
|
@FormilyField(
|
||||||
|
title = "Pipeline script",
|
||||||
|
type = "string",
|
||||||
|
component = "MonacoEditor",
|
||||||
|
props = @FormilyComponentProps(
|
||||||
|
editor = @FormilyEditorProps(
|
||||||
|
language = "groovy",
|
||||||
|
theme = "vs-dark",
|
||||||
|
minimap = false,
|
||||||
|
lineNumbers = true,
|
||||||
|
wordWrap = true,
|
||||||
|
fontSize = 14,
|
||||||
|
tabSize = 4,
|
||||||
|
automaticLayout = true,
|
||||||
|
folding = true,
|
||||||
|
placeholder = "请输入Pipeline脚本"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
validators = {
|
||||||
|
@FormilyValidator(
|
||||||
|
required = true,
|
||||||
|
message = "请输入Pipeline脚本"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
private String script;
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user