diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilyField.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilyField.java index 6b5fc76f..1acfe13c 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilyField.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilyField.java @@ -12,6 +12,7 @@ public @interface FormilyField { String title(); // 字段标题 String description() default ""; // 字段描述 String type() default "string"; // 字段类型(string/number/boolean/array/object/map) + int order() default Integer.MAX_VALUE; // 字段顺序,值越小越靠前 // 组件属性 String component() default "Input"; // 组件类型 diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactory.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactory.java index 7bbee25f..3ba74f08 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactory.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactory.java @@ -9,6 +9,7 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; public class FormilySchemaFactory { private static final ObjectMapper objectMapper = new ObjectMapper(); @@ -46,12 +47,20 @@ public class FormilySchemaFactory { ObjectNode properties = schema.putObject("properties"); boolean hasFields = false; - for (Field field : allFields) { + // 将字段按order排序 + List sortedFields = allFields.stream() + .filter(field -> field.isAnnotationPresent(FormilyField.class)) + .sorted((f1, f2) -> { + FormilyField a1 = f1.getAnnotation(FormilyField.class); + FormilyField a2 = f2.getAnnotation(FormilyField.class); + return Integer.compare(a1.order(), a2.order()); + }) + .collect(Collectors.toList()); + + for (Field field : sortedFields) { FormilyField fieldDef = field.getAnnotation(FormilyField.class); - if (fieldDef != null) { - properties.set(field.getName(), generateFieldSchema(fieldDef)); - hasFields = true; - } + properties.set(field.getName(), generateFieldSchema(fieldDef)); + hasFields = true; } if (!hasFields) { diff --git a/backend/src/test/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactoryTest.java b/backend/src/test/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactoryTest.java index 954d3e76..6dec17de 100644 --- a/backend/src/test/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactoryTest.java +++ b/backend/src/test/java/com/qqchen/deploy/backend/framework/annotation/formily/FormilySchemaFactoryTest.java @@ -4,6 +4,10 @@ import com.fasterxml.jackson.databind.JsonNode; import org.junit.jupiter.api.Test; import java.util.Map; +import java.util.Iterator; +import java.util.List; +import java.util.Arrays; +import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.*; @@ -18,6 +22,14 @@ public class FormilySchemaFactoryTest { assertEquals("测试表单", schema.get("name").asText()); assertTrue(schema.has("properties")); + // 验证字段顺序 + Iterator fieldNames = schema.get("properties").fieldNames(); + List actualOrder = new ArrayList<>(); + fieldNames.forEachRemaining(actualOrder::add); + + List expectedOrder = Arrays.asList("a", "b", "c", "envVars", "script"); + assertEquals(expectedOrder, actualOrder, "字段顺序应该按照order排序"); + // 验证字段A JsonNode fieldA = schema.get("properties").get("a"); assertEquals("string", fieldA.get("type").asText()); @@ -136,6 +148,7 @@ class TestForm { @FormilyField( title = "选择A", component = "Select", + order = 1, props = @FormilyComponentProps( api = "/api/options/A", labelField = "name", @@ -154,6 +167,7 @@ class TestForm { @FormilyField( title = "选择B", component = "Select", + order = 2, props = @FormilyComponentProps( labelField = "viewName", valueField = "id" @@ -177,6 +191,7 @@ class TestForm { @FormilyField( title = "选择C", component = "Select", + order = 3, props = @FormilyComponentProps( labelField = "jobName", valueField = "id" @@ -197,10 +212,31 @@ class TestForm { ) private String c; + @FormilyField( + title = "环境变量", + type = "map", + order = 4, + mapConfig = @FormilyMapConfig( + keyTitle = "变量名", + valueTitle = "变量值", + keyComponent = "Select", + valueComponent = "Input", + keyProps = @FormilyComponentProps( + api = "/api/v1/env-vars/keys", + showSearch = true, + allowClear = true + ), + addText = "添加环境变量", + allowCustomKey = true + ) + ) + private Map envVars; + @FormilyField( title = "Pipeline script", type = "string", component = "MonacoEditor", + order = 5, props = @FormilyComponentProps( editor = @FormilyEditorProps( language = "groovy", @@ -223,23 +259,4 @@ class TestForm { } ) private String script; - - @FormilyField( - title = "环境变量", - type = "map", - mapConfig = @FormilyMapConfig( - keyTitle = "变量名", - valueTitle = "变量值", - keyComponent = "Select", - valueComponent = "Input", - keyProps = @FormilyComponentProps( - api = "/api/v1/env-vars/keys", - showSearch = true, - allowClear = true - ), - addText = "添加环境变量", - allowCustomKey = true - ) - ) - private Map envVars; } \ No newline at end of file