From d3be8f06616f37517d8a24c149768d2418db2ac1 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Thu, 13 Aug 2026 20:49:46 +0800 Subject: [PATCH 01/12] =?UTF-8?q?refactor(core):=20=E5=B0=86=E5=85=B3?= =?UTF-8?q?=E7=B3=BB=E5=AD=97=E6=AE=B5=E9=87=8D=E5=91=BD=E5=90=8D=E4=B8=BA?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E5=BC=95=E7=94=A8=E5=AD=97=E6=AE=B5=E4=BB=A5?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E8=AF=AD=E4=B9=89=E6=B8=85=E6=99=B0=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 RelationField 重命名为 ModelRefField - 将 ModelRelation 注解重命名为 ModelRef - 将 ScalarType 中的 RELATION 类型重命名为 MODEL_REF - 更新所有相关字段、方法和变量名称以匹配新命名 - 修改测试资源文件中的类型定义以使用新命名约定 - 更新 Jackson 序列化配置以使用新的字段类型名称 --- flexmodel-engine/README.md | 2 +- .../java/dev/flexmodel/codegen/JavaType.java | 2 +- .../dev/flexmodel/codegen/ModelClass.java | 16 ++++---- .../dev/flexmodel/codegen/ModelField.java | 10 ++--- .../dev/flexmodel/codegen/PojoGenerator.java | 6 +-- .../src/test/resources/import.json | 20 +++++----- .../{ModelRelation.java => ModelRef.java} | 2 +- .../dev/flexmodel/model/EntityDefinition.java | 8 ++-- ...{RelationField.java => ModelRefField.java} | 18 ++++----- .../dev/flexmodel/model/field/ScalarType.java | 8 ++-- .../mongodb/MongoStatementBuilder.java | 4 +- .../flexmodel/parser/ASTNodeConverter.java | 23 +++++------ .../reflect/LazyLoadInterceptor.java | 10 ++--- .../dev/flexmodel/reflect/LazyObjProxy.java | 4 +- .../dev/flexmodel/service/BaseService.java | 40 +++++++++---------- .../dev/flexmodel/sql/SqlDataService.java | 4 +- .../dev/flexmodel/sql/SqlSchemaService.java | 10 ++--- .../flexmodel/sql/SqlStatementBuilder.java | 6 +-- .../supports/jackson/FlexmodelCoreModule.java | 4 +- .../jackson/LazyObjectSerializer.java | 4 +- .../supports/jackson/TypedFieldMixIn.java | 5 +-- .../src/test/resources/sample_input.json | 40 +++++++++---------- .../graphql/FlexmodelAbstractDataFetcher.java | 10 ++--- .../graphql/FlexmodelByIdDataFetcher.java | 10 ++--- .../graphql/FlexmodelListDataFetcher.java | 8 ++-- .../graphql/GraphQLSchemaGenerator.java | 19 +++++---- .../java/dev/flexmodel/graphql/Models.java | 4 +- .../src/test/resources/import.json | 32 +++++++-------- .../dev/flexmodel/AbstractSessionTests.java | 8 ++-- .../java/dev/flexmodel/entity/Classes.java | 4 +- .../java/dev/flexmodel/entity/Student.java | 4 +- flexmodel-sdks | 2 +- .../flexmodel/modeling/ModelingResource.java | 28 ++++++------- .../reachability-metadata.json | 2 +- .../serialization-config.json | 2 +- flexmodel-ui | 2 +- flexmodel-website | 2 +- 37 files changed, 187 insertions(+), 196 deletions(-) rename flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/{ModelRelation.java => ModelRef.java} (86%) rename flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/{RelationField.java => ModelRefField.java} (76%) diff --git a/flexmodel-engine/README.md b/flexmodel-engine/README.md index 6d37aa5..66d157f 100644 --- a/flexmodel-engine/README.md +++ b/flexmodel-engine/README.md @@ -85,7 +85,7 @@ try (Session session = sessionFactory.createSession("mySchema")) { { "objects": [ { - "type": "entity", + "type": "Entity", "name": "User", "comment": "用户表", "fields": [ diff --git a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/JavaType.java b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/JavaType.java index 8ad9f36..730d279 100644 --- a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/JavaType.java +++ b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/JavaType.java @@ -9,7 +9,7 @@ */ public enum JavaType { - RELATION(ScalarType.RELATION_TYPE, null, null, null), + MODEL_REF(ScalarType.MODEL_REF_TYPE, null, null, null), STRING(STRING_TYPE, null, "String", "String"), FLOAT(FLOAT_TYPE, null, "Double", "Double"), INT(INT_TYPE, null, "Integer", "Integer"), diff --git a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelClass.java b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelClass.java index fe2cb45..7cc6343 100644 --- a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelClass.java +++ b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelClass.java @@ -4,7 +4,7 @@ import dev.flexmodel.model.EntityDefinition; import dev.flexmodel.model.ModelDefinition; import dev.flexmodel.model.field.EnumRefField; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import java.util.ArrayList; @@ -19,7 +19,7 @@ public class ModelClass extends AbstractClass { private ModelField idField; private final List basicFields = new ArrayList<>(); private final List enumFields = new ArrayList<>(); - private final List relationFields = new ArrayList<>(); + private final List modelRefFields = new ArrayList<>(); private final List allFields = new ArrayList<>(); private ModelDefinition original; @@ -56,7 +56,7 @@ public static ModelClass buildModelClass(String replaceString, String packageNam .setComment(field.getComment()); switch (field) { - case RelationField relationField -> { + case ModelRefField relationField -> { String ftName = StringUtils.capitalize( StringUtils.snakeToCamel( replaceString != null ? @@ -68,13 +68,13 @@ public static ModelClass buildModelClass(String replaceString, String packageNam modelField.setTypePackage("java.util") .setFullTypeName("java.util.List") .setShortTypeName("List<" + ftName + ">") - .setRelationField(true); + .setModelRefField(true); } else { modelField.setTypePackage(null) .setFullTypeName(modelField.getTypePackage() + "." + ftName) .setShortTypeName(ftName) - .setRelationField(true); - modelClass.getRelationFields().add(modelField); + .setModelRefField(true); + modelClass.getModelRefFields().add(modelField); } } @@ -150,8 +150,8 @@ public List getEnumFields() { return enumFields; } - public List getRelationFields() { - return relationFields; + public List getModelRefFields() { + return modelRefFields; } public List getAllFields() { diff --git a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelField.java b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelField.java index eb1ceb6..ea9f28f 100644 --- a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelField.java +++ b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/ModelField.java @@ -18,7 +18,7 @@ public class ModelField { private String fullTypeName; private boolean identity; private boolean basicField; - private boolean relationField; + private boolean modelRefField; private boolean enumField; private Field original; @@ -103,8 +103,8 @@ public ModelField setBasicField(boolean basicField) { return this; } - public boolean isRelationField() { - return relationField; + public boolean isModelRefField() { + return modelRefField; } public boolean isEnumField() { @@ -116,8 +116,8 @@ public ModelField setEnumField(boolean enumField) { return this; } - public ModelField setRelationField(boolean relationField) { - this.relationField = relationField; + public ModelField setModelRefField(boolean relationField) { + this.modelRefField = relationField; return this; } diff --git a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/PojoGenerator.java b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/PojoGenerator.java index 44457e7..36f8290 100644 --- a/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/PojoGenerator.java +++ b/flexmodel-engine/flexmodel-codegen/src/main/java/dev/flexmodel/codegen/PojoGenerator.java @@ -56,9 +56,9 @@ public void writeModel(PrintWriter out, GenerationContext context) { out.println(" * " + field.getComment()); out.println(" */"); } - if (field.isRelationField()) { - out.println(" @ModelRelation"); - } + if (field.isModelRefField()) { + out.println(" @ModelRef"); + } out.println(" @ModelField(\"" + field.getOriginal().getName() + "\")"); out.println(" private " + field.getShortTypeName() + " " + field.getVariableName() + ";"); } diff --git a/flexmodel-engine/flexmodel-codegen/src/test/resources/import.json b/flexmodel-engine/flexmodel-codegen/src/test/resources/import.json index 87254f6..aec0a23 100644 --- a/flexmodel-engine/flexmodel-codegen/src/test/resources/import.json +++ b/flexmodel-engine/flexmodel-codegen/src/test/resources/import.json @@ -134,11 +134,11 @@ } ], "indexes": [], - "type": "entity" + "type": "Entity" }, { "name": "fs_datasource", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -198,7 +198,7 @@ }, { "name": "fs_api_log", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -258,7 +258,7 @@ ] }, { - "type": "entity", + "type": "Entity", "name": "Student", "fields": [ { @@ -315,7 +315,7 @@ }, { "name": "studentDetail", - "type": "Relation", + "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, @@ -329,7 +329,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "StudentDetail", "fields": [ { @@ -363,7 +363,7 @@ }, { "name": "LogLevel", - "type": "enum", + "type": "Enum", "elements": [ "DEBUG", "INFO", @@ -374,7 +374,7 @@ }, { "name": "UserGender", - "type": "enum", + "type": "Enum", "elements": [ "UNKNOWN", "MALE", @@ -384,7 +384,7 @@ }, { "name": "User_interest", - "type": "enum", + "type": "Enum", "elements": [ "chang", "tiao", @@ -490,4 +490,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRelation.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRef.java similarity index 86% rename from flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRelation.java rename to flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRef.java index ac0669b..a77d105 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRelation.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/annotation/ModelRef.java @@ -9,5 +9,5 @@ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) -public @interface ModelRelation { +public @interface ModelRef { } diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EntityDefinition.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EntityDefinition.java index 8ff587a..1577f15 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EntityDefinition.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EntityDefinition.java @@ -1,6 +1,6 @@ package dev.flexmodel.model; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import java.util.*; @@ -21,7 +21,7 @@ public EntityDefinition(String name) { @Override public String getType() { - return "entity"; + return "Entity"; } public String getComment() { @@ -58,9 +58,9 @@ public IndexDefinition getIndex(String name) { .orElse(null); } - public Optional findRelationByModelName(String modelName) { + public Optional findRelationByModelName(String modelName) { for (TypedField field : fields) { - if (field instanceof RelationField relationField) { + if (field instanceof ModelRefField relationField) { if (relationField.getFrom().equals(modelName)) { return Optional.of(relationField); } diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/RelationField.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ModelRefField.java similarity index 76% rename from flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/RelationField.java rename to flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ModelRefField.java index a8f7e7f..4fac5ae 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/RelationField.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ModelRefField.java @@ -5,7 +5,7 @@ /** * @author cjbi */ -public class RelationField extends TypedField { +public class ModelRefField extends TypedField { /** * 多选 @@ -28,15 +28,15 @@ public class RelationField extends TypedField { */ private boolean cascadeDelete; - public RelationField(String name) { - super(name, ScalarType.RELATION.getType()); + public ModelRefField(String name) { + super(name, ScalarType.MODEL_REF.getType()); } public boolean isCascadeDelete() { return cascadeDelete; } - public RelationField setCascadeDelete(boolean cascadeDelete) { + public ModelRefField setCascadeDelete(boolean cascadeDelete) { this.cascadeDelete = cascadeDelete; return this; } @@ -45,7 +45,7 @@ public String getFrom() { return from; } - public RelationField setFrom(String from) { + public ModelRefField setFrom(String from) { this.from = from; return this; } @@ -54,7 +54,7 @@ public String getLocalField() { return localField; } - public RelationField setLocalField(String localField) { + public ModelRefField setLocalField(String localField) { this.localField = localField; return this; } @@ -63,7 +63,7 @@ public String getForeignField() { return foreignField; } - public RelationField setForeignField(String foreignField) { + public ModelRefField setForeignField(String foreignField) { this.foreignField = foreignField; return this; } @@ -72,14 +72,14 @@ public boolean isMultiple() { return multiple; } - public RelationField setMultiple(boolean multiple) { + public ModelRefField setMultiple(boolean multiple) { this.multiple = multiple; return this; } @Override public boolean equals(Object o) { - if (!(o instanceof RelationField that)) return false; + if (!(o instanceof ModelRefField that)) return false; if (!super.equals(o)) return false; return isMultiple() == that.isMultiple() && isCascadeDelete() == that.isCascadeDelete() && diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ScalarType.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ScalarType.java index 57e50be..b6084f3 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ScalarType.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/ScalarType.java @@ -13,8 +13,8 @@ public enum ScalarType { DATE(ScalarType.DATE_TYPE), TIME(ScalarType.TIME_TYPE), JSON(ScalarType.JSON_TYPE), - ENUM(ScalarType.ENUM_TYPE), - RELATION(ScalarType.RELATION_TYPE); + ENUM_REF(ScalarType.ENUM_REF_TYPE), + MODEL_REF(ScalarType.MODEL_REF_TYPE); private final String type; @@ -27,8 +27,8 @@ public enum ScalarType { public static final String DATE_TYPE = "Date"; public static final String TIME_TYPE = "Time"; public static final String JSON_TYPE = "JSON"; - public static final String ENUM_TYPE = "EnumRef"; - public static final String RELATION_TYPE = "Relation"; + public static final String ENUM_REF_TYPE = "EnumRef"; + public static final String MODEL_REF_TYPE = "ModelRef"; ScalarType(String type) { this.type = type; diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoStatementBuilder.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoStatementBuilder.java index db10849..2dfd1b2 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoStatementBuilder.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoStatementBuilder.java @@ -5,7 +5,7 @@ import dev.flexmodel.ExpressionCalculatorException; import dev.flexmodel.model.ModelDefinition; import dev.flexmodel.model.field.Field; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.query.Direction; import dev.flexmodel.query.Query; import dev.flexmodel.service.BaseService; @@ -82,7 +82,7 @@ private Document createLookupDocument(List pipeline, ModelDefinition m private void addProjectionStage(List pipeline, ModelDefinition model, Query query) { Document project = new Document("_id", false); - Map relationFields = findRelationFields(model, query); + Map relationFields = findRelationFields(model, query); boolean hasAggFunc = false; Query.Projection projection = query.getProjection(); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/parser/ASTNodeConverter.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/parser/ASTNodeConverter.java index de42402..01d4a58 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/parser/ASTNodeConverter.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/parser/ASTNodeConverter.java @@ -6,7 +6,6 @@ import dev.flexmodel.model.SchemaObject; import dev.flexmodel.model.field.*; import dev.flexmodel.ModelImportBundle; -import dev.flexmodel.model.field.*; import dev.flexmodel.parser.impl.ModelParser; import dev.flexmodel.parser.impl.ParseException; import dev.flexmodel.query.Direction; @@ -112,17 +111,17 @@ public static EntityDefinition toSchemaEntity(ModelParser.Model idlModel) { ModelParser.Annotation relationAnno = idlField.annotations.stream() .filter(f -> f.name.equals("relation")).findFirst() .orElse(null); - boolean isRelationField = relationAnno != null; + boolean isModelRefField = relationAnno != null; String from = idlField.type.replace("[]", ""); boolean multiple = idlField.type.endsWith("[]"); - if (isRelationField) { - RelationField relationField = new RelationField(idlField.name); - relationField.setMultiple(multiple); - relationField.setFrom(from); - relationField.setLocalField((String) relationAnno.parameters.get("localField")); - relationField.setForeignField((String) relationAnno.parameters.get("foreignField")); - relationField.setCascadeDelete(Boolean.parseBoolean(Objects.toString(relationAnno.parameters.get("cascadeDelete")))); - field = relationField; + if (isModelRefField) { + ModelRefField modelRefField = new ModelRefField(idlField.name); + modelRefField.setMultiple(multiple); + modelRefField.setFrom(from); + modelRefField.setLocalField((String) relationAnno.parameters.get("localField")); + modelRefField.setForeignField((String) relationAnno.parameters.get("foreignField")); + modelRefField.setCascadeDelete(Boolean.parseBoolean(Objects.toString(relationAnno.parameters.get("cascadeDelete")))); + field = modelRefField; } else { field = new EnumRefField(idlField.name); ((EnumRefField) field).setFrom(from); @@ -273,7 +272,7 @@ public static ModelParser.Field fromSchemaField(TypedField field) { case DateField dateField -> addDefaultAnnotation(idlField, dateField.getDefaultValue()); case TimeField timeField -> addDefaultAnnotation(idlField, timeField.getDefaultValue()); case JSONField jsonField -> addDefaultAnnotation(idlField, jsonField.getDefaultValue()); - case RelationField relationField -> { + case ModelRefField relationField -> { ModelParser.Annotation relationAnno = new ModelParser.Annotation("relation"); relationAnno.parameters.put("localField", relationField.getLocalField()); relationAnno.parameters.put("foreignField", relationField.getForeignField()); @@ -319,7 +318,7 @@ public static ModelParser.Enumeration fromSchemaEnum(EnumDefinition schemaEnum) // 辅助方法 private static String getCorrespondingType(TypedField field) { - if (field instanceof RelationField relationField) { + if (field instanceof ModelRefField relationField) { return relationField.isMultiple() ? relationField.getFrom() + "[]" : relationField.getFrom(); } else if (field instanceof EnumRefField enumField) { return enumField.isMultiple() ? enumField.getFrom() + "[]" : enumField.getFrom(); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyLoadInterceptor.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyLoadInterceptor.java index 8208fae..47faa6d 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyLoadInterceptor.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyLoadInterceptor.java @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; import dev.flexmodel.JsonUtils; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.query.Expressions; import dev.flexmodel.session.AbstractSession; @@ -101,7 +101,7 @@ public Object intercept(@This Object proxy, @Origin Class clazz, @Origin Meth EntityDefinition entity = (EntityDefinition) session.schema().getModel(modelName); String fieldName = ReflectionUtils.getFieldNameFromGetter(method); TypedField field = entity.getField(fieldName); - if (field instanceof RelationField relationField) { + if (field instanceof ModelRefField relationField) { return handleRelationField(proxy, clazz, method, superCall, fieldName, relationField); } return superCall.call(); @@ -112,7 +112,7 @@ private Object handleRelationField(Object proxy, Method method, Callable superCall, String fieldName, - RelationField relationField) throws Exception { + ModelRefField relationField) throws Exception { Object id = resolveRelationIdentifier(relationField); if (id == null) { return superCall.call(); @@ -135,7 +135,7 @@ private Object handleRelationField(Object proxy, return loadedValue; } - private RelationLoadResult loadRelationValue(RelationField relationField, Method method, Object identifier) { + private RelationLoadResult loadRelationValue(ModelRefField relationField, Method method, Object identifier) { Object convertedIdentifier = castValueType(relationField.getFrom(), relationField.getForeignField(), identifier); if (relationField.isMultiple()) { Class elementType = resolveCollectionElementType(method); @@ -156,7 +156,7 @@ private RelationLoadResult loadRelationValue(RelationField relationField, Method return RelationLoadResult.loaded(proxyValue); } - private Object resolveRelationIdentifier(RelationField relationField) { + private Object resolveRelationIdentifier(ModelRefField relationField) { Object id = dataMap.get(relationField.getLocalField()); if (id == null) { id = dataMap.get(underscoreToCamelCase(relationField.getLocalField())); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyObjProxy.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyObjProxy.java index 5935a1d..8880e84 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyObjProxy.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/reflect/LazyObjProxy.java @@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory; import dev.flexmodel.JsonUtils; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.session.Session; import java.lang.reflect.Modifier; @@ -79,7 +79,7 @@ public static List createProxyList(List list, String modelName, Sessio private static String[] getLazyMethods(EntityDefinition entity) { List methodNames = new ArrayList<>(); entity.getFields().forEach(field -> { - if (field instanceof RelationField) { + if (field instanceof ModelRefField) { methodNames.add("get" + ReflectionUtils.toUpperCamelCase(field.getName())); } }); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/service/BaseService.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/service/BaseService.java index 612b403..0f1f556 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/service/BaseService.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/service/BaseService.java @@ -191,7 +191,7 @@ private void validateJoinConfiguration(Query.Join joinConfig, ModelDefinition ma */ private void autoFillRelationFields(Query.Join joinConfig, EntityDefinition entity) { try { - RelationField relationField = entity.findRelationByModelName(joinConfig.getFrom()) + ModelRefField relationField = entity.findRelationByModelName(joinConfig.getFrom()) .orElseThrow(() -> new SqlExecutionException("Relation field not found for model: " + joinConfig.getFrom())); String localFieldName = relationField.getLocalField() != null ? @@ -230,11 +230,11 @@ private void validateManualJoinFields(Query.Join joinConfig) { * @param query 查询对象 * @return 关联字段映射,key为字段别名,value为关联字段定义 */ - public Map findRelationFields(ModelDefinition model, Query query) { + public Map findRelationFields(ModelDefinition model, Query query) { log.debug("Finding relation fields for model: {}, hasProjection: {}, hasExpand: {}", model.getName(), hasProjectionFields(query), query != null && query.hasExpand()); - Map relationFieldMap = new HashMap<>(); + Map relationFieldMap = new HashMap<>(); if (!(model instanceof EntityDefinition entity)) { log.debug("Model is not EntityDefinition, returning empty relation field map"); @@ -261,15 +261,15 @@ public Map findRelationFields(ModelDefinition model, Quer * @param expand expand 字段列表 * @param relationFieldMap 关联字段映射 */ - private void findRelationFieldsFromExpand(EntityDefinition entity, List expand, Map relationFieldMap) { + private void findRelationFieldsFromExpand(EntityDefinition entity, List expand, Map relationFieldMap) { log.debug("Finding relation fields from expand list: {}", expand); for (String expandPath : expand) { // 取顶层字段名(classId.teacher -> classId) String topField = expandPath.contains(".") ? expandPath.split("\\.")[0] : expandPath; entity.getFields().stream() - .filter(f -> f.getName().equals(topField) && f instanceof RelationField) - .map(f -> (RelationField) f) + .filter(f -> f.getName().equals(topField) && f instanceof ModelRefField) + .map(f -> (ModelRefField) f) .findFirst() .ifPresent(relationField -> { relationFieldMap.put(topField, relationField); @@ -319,7 +319,7 @@ private boolean hasProjectionFields(Query query) { * @param query 查询对象 * @param relationFieldMap 关联字段映射 */ - private void findRelationFieldsFromProjection(EntityDefinition entity, Query query, Map relationFieldMap) { + private void findRelationFieldsFromProjection(EntityDefinition entity, Query query, Map relationFieldMap) { log.debug("Finding relation fields from projection, projection fields count: {}", query.getProjection().getFields().size()); @@ -331,8 +331,8 @@ private void findRelationFieldsFromProjection(EntityDefinition entity, Query que log.debug("Checking field: {} (alias: {})", queryField.getName(), fieldAlias); entity.getFields().stream() - .filter(field -> field.getName().equals(queryField.getName()) && field instanceof RelationField) - .map(field -> (RelationField) field) + .filter(field -> field.getName().equals(queryField.getName()) && field instanceof ModelRefField) + .map(field -> (ModelRefField) field) .findFirst() .ifPresent(relationField -> { relationFieldMap.put(fieldAlias, relationField); @@ -348,11 +348,11 @@ private void findRelationFieldsFromProjection(EntityDefinition entity, Query que * @param entity 实体定义 * @param relationFieldMap 关联字段映射 */ - private void findAllRelationFields(EntityDefinition entity, Map relationFieldMap) { + private void findAllRelationFields(EntityDefinition entity, Map relationFieldMap) { log.debug("Finding all relation fields for entity: {}", entity.getName()); for (Field field : entity.getFields()) { - if (field instanceof RelationField relationField) { + if (field instanceof ModelRefField relationField) { relationFieldMap.put(relationField.getName(), relationField); log.debug("Found relation field: {}", relationField.getName()); } @@ -369,7 +369,7 @@ private void findAllRelationFields(EntityDefinition entity, Map> findRelationDataList( BiFunction>> relationQueryFunction, - RelationField relationField, + ModelRefField relationField, Set foreignKeyValues) { log.debug("Finding relation data for field: {}, foreign key values count: {}", @@ -431,11 +431,11 @@ private void nestedQuery(List> parentDataList, log.debug("Processing nested query for model: {}, remaining depth: {}", model.getName(), remainingDepth.get()); - Map relationFieldMap = findRelationFields(model, query); + Map relationFieldMap = findRelationFields(model, query); relationFieldMap.entrySet().stream().forEach(entry -> { String relationFieldAlias = entry.getKey(); - RelationField relationField = entry.getValue(); + ModelRefField relationField = entry.getValue(); log.debug("Processing relation field: {} (alias: {})", relationField.getName(), relationFieldAlias); processRelationField(parentDataList, relationQueryFunction, model, query, @@ -460,7 +460,7 @@ private void processRelationField(List> parentDataList, Query query, AtomicInteger remainingDepth, String relationFieldAlias, - RelationField relationField) { + ModelRefField relationField) { // 收集所有外键值 Set foreignKeyValues = parentDataList.stream() .map(dataItem -> dataItem.get(relationField.getLocalField())) @@ -508,7 +508,7 @@ private void processRelationField(List> parentDataList, * @param relationModel 关联模型定义 */ private void fillRelationDataToParent(Map parentDataItem, - RelationField relationField, + ModelRefField relationField, String relationFieldAlias, Map>> relationDataGroup, BiFunction>> relationQueryFunction, @@ -590,7 +590,7 @@ private void processInputData(Map inputData, EntityDefinition en inputData.forEach((fieldName, fieldValue) -> { TypedField field = entity.getField(fieldName); - if (field != null && !(field instanceof RelationField)) { + if (field != null && !(field instanceof ModelRefField)) { Object convertedValue = convertParameter(field, fieldValue); processedData.put(field.getName(), convertedValue); log.debug("Converted field: {} = {} -> {}", fieldName, fieldValue, convertedValue); @@ -613,7 +613,7 @@ private void processDefaultAndGeneratedValues(List> entityField log.debug("Processing default and generated values for {} fields", entityFields.size()); for (TypedField field : entityFields) { - if (field instanceof RelationField) { + if (field instanceof ModelRefField) { continue; } @@ -726,7 +726,7 @@ protected void insertRelatedRecords(String modelName, Map relati try { EntityDefinition entity = (EntityDefinition) sessionContext.getModelDefinition(modelName); relationObject.forEach((fieldName, fieldValue) -> { - if (fieldValue != null && entity.getField(fieldName) instanceof RelationField relationField) { + if (fieldValue != null && entity.getField(fieldName) instanceof ModelRefField relationField) { processRelationFieldInsertion(entity, fieldName, fieldValue, relationObject.get(relationField.getLocalField())); } }); @@ -748,7 +748,7 @@ protected void insertRelatedRecords(String modelName, Map relati */ @SuppressWarnings({"rawtypes", "unchecked"}) private void processRelationFieldInsertion(EntityDefinition entity, String fieldName, Object fieldValue, Object parentId) { - if (!(entity.getField(fieldName) instanceof RelationField relationField)) { + if (!(entity.getField(fieldName) instanceof ModelRefField relationField)) { return; } log.debug("Processing relation field insertion: field={}, relationField={}, parentId={}", fieldName, relationField.getName(), parentId); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlDataService.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlDataService.java index 57a2726..7b9d550 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlDataService.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlDataService.java @@ -6,7 +6,7 @@ import dev.flexmodel.model.ModelDefinition; import dev.flexmodel.model.NativeQueryDefinition; import dev.flexmodel.model.field.Field; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.query.Query; import dev.flexmodel.service.BaseService; @@ -298,7 +298,7 @@ public Optional> findById(String modelName, Object id, List< EntityDefinition entity = (EntityDefinition) sessionContext.getModelDefinition(modelName); TypedField idField = entity.findIdField().orElseThrow(); String columnsString = entity.getFields().stream() - .filter(f -> !(f instanceof RelationField)) + .filter(f -> !(f instanceof ModelRefField)) .map(field -> sqlDialect.quoteIdentifier(field.getName())) .collect(Collectors.joining(", ")); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlSchemaService.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlSchemaService.java index be04fa7..8be778c 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlSchemaService.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlSchemaService.java @@ -6,8 +6,6 @@ import org.slf4j.LoggerFactory; import dev.flexmodel.JsonUtils; import dev.flexmodel.ModelRegistry; -import dev.flexmodel.model.*; -import dev.flexmodel.model.field.*; import dev.flexmodel.service.BaseService; import dev.flexmodel.service.SchemaService; @@ -120,7 +118,7 @@ private void dropTable(SqlTable sqlTable) { entity.addField(field); modelRegistry.register(sessionContext.getSchemaName(), entity); } - if (!(field instanceof RelationField)) { + if (!(field instanceof ModelRefField)) { createColumn(toSqlColumn(field)); } return field; @@ -136,7 +134,7 @@ private void dropTable(SqlTable sqlTable) { modelRegistry.register(sessionContext.getSchemaName(), entity); } try { - if (!(field instanceof RelationField)) { + if (!(field instanceof ModelRefField)) { modifyColumn(toSqlColumn(field)); } } catch (Exception e) { @@ -310,7 +308,7 @@ private SqlTable toSqlTable(EntityDefinition entity) { SqlPrimaryKey primaryKey = new SqlPrimaryKey(sqlTable); for (TypedField field : entity.getFields()) { field.setModelName(entity.getName()); - if (field instanceof RelationField) { + if (field instanceof ModelRefField) { continue; } if (sqlTable.getColumn(field.getName()) != null) { @@ -333,7 +331,7 @@ private SqlTable toSqlTable(EntityDefinition entity) { } private SqlColumn toSqlColumn(TypedField field) { - if (field instanceof RelationField relationField) { + if (field instanceof ModelRefField relationField) { SqlColumn associationColumn = new SqlColumn(); associationColumn.setName(relationField.getForeignField()); associationColumn.setTableName( diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlStatementBuilder.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlStatementBuilder.java index 975a11f..7e1629c 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlStatementBuilder.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlStatementBuilder.java @@ -3,7 +3,7 @@ import dev.flexmodel.ExpressionCalculatorException; import dev.flexmodel.model.EntityDefinition; import dev.flexmodel.model.ModelDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.ScalarType; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.query.Query; @@ -123,7 +123,7 @@ private void appendJoins(String modelName, Query query, ModelDefinition model, S } String localField = joiner.getLocalField(); String foreignField = joiner.getForeignField(); - RelationField relationField; + ModelRefField relationField; if (model instanceof EntityDefinition entity && (relationField = entity.findRelationByModelName(joiner.getFrom()).orElse(null)) != null) { foreignField = relationField.getForeignField(); joinCause.append(joinTableName).append(" \n on \n").append(toFullColumnQuoteString(modelName, localField)).append("=").append(toFullColumnQuoteString(joiner.getAs(), foreignField)); @@ -157,7 +157,7 @@ private void appendFromClause(String modelName, StringBuilder sqlBuilder) { private void appendProjection(String modelName, Query query, ModelDefinition model, Map projectionMap, StringBuilder sqlBuilder) { SqlDialect sqlDialect = sqlContext.getSqlDialect(); Query.Projection projection = query.getProjection(); - Map relationFields = findRelationFields(model, query); + Map relationFields = findRelationFields(model, query); StringJoiner columns = new StringJoiner(", "); if (projection != null && !projection.getFields().isEmpty()) { projection.getFields().forEach((key, value) -> { diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/FlexmodelCoreModule.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/FlexmodelCoreModule.java index 10e9a56..107bb08 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/FlexmodelCoreModule.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/FlexmodelCoreModule.java @@ -6,8 +6,6 @@ import com.fasterxml.jackson.databind.module.SimpleModule; import dev.flexmodel.model.*; import dev.flexmodel.model.field.*; -import dev.flexmodel.model.*; -import dev.flexmodel.model.field.*; import java.io.IOException; import java.text.SimpleDateFormat; @@ -36,7 +34,7 @@ public FlexmodelCoreModule() { setMixInAnnotation(DateField.class, TypedFieldMixIn.class); setMixInAnnotation(TimeField.class, TypedFieldMixIn.class); setMixInAnnotation(JSONField.class, TypedFieldMixIn.class); - setMixInAnnotation(RelationField.class, TypedFieldMixIn.class); + setMixInAnnotation(ModelRefField.class, TypedFieldMixIn.class); setMixInAnnotation(EnumRefField.class, TypedFieldMixIn.class); // Index setMixInAnnotation(IndexDefinition.class, IndexMixIn.class); diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/LazyObjectSerializer.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/LazyObjectSerializer.java index 8013788..5d352d2 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/LazyObjectSerializer.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/LazyObjectSerializer.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.reflect.ProxyInterface; import dev.flexmodel.reflect.ReflectionUtils; @@ -39,7 +39,7 @@ private Map invokeGetter(ProxyInterface value) { Field[] declaredFields = aClass.getDeclaredFields(); Map data = new HashMap<>(); for (Field field : declaredFields) { - if (entity.getField(field.getName()) instanceof RelationField) { + if (entity.getField(field.getName()) instanceof ModelRefField) { continue; } try { diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/TypedFieldMixIn.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/TypedFieldMixIn.java index 753dd57..1e91eaa 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/TypedFieldMixIn.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/TypedFieldMixIn.java @@ -5,7 +5,6 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import dev.flexmodel.model.field.*; -import dev.flexmodel.model.field.*; /** * @author cjbi @@ -21,8 +20,8 @@ @JsonSubTypes.Type(value = TimeField.class, name = ScalarType.TIME_TYPE), @JsonSubTypes.Type(value = BooleanField.class, name = ScalarType.BOOLEAN_TYPE), @JsonSubTypes.Type(value = JSONField.class, name = ScalarType.JSON_TYPE), - @JsonSubTypes.Type(value = RelationField.class, name = ScalarType.RELATION_TYPE), - @JsonSubTypes.Type(value = EnumRefField.class, name = ScalarType.ENUM_TYPE), + @JsonSubTypes.Type(value = ModelRefField.class, name = ScalarType.MODEL_REF_TYPE), + @JsonSubTypes.Type(value = EnumRefField.class, name = ScalarType.ENUM_REF_TYPE), }) public abstract class TypedFieldMixIn { diff --git a/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json b/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json index d1f2232..092c5a1 100644 --- a/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json +++ b/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json @@ -1,7 +1,7 @@ [ { "name": "fs_datasource", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -66,7 +66,7 @@ }, { "name": "fs_api_definition", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -171,7 +171,7 @@ }, { "name": "fs_api_log", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -237,7 +237,7 @@ }, { "name": "fs_identity_provider", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -282,7 +282,7 @@ { "name": "fs_config", "comment": "配置", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -350,7 +350,7 @@ ] }, { - "type": "entity", + "type": "Entity", "name": "Teacher", "fields": [ { @@ -381,7 +381,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "Student", "fields": [ { @@ -433,7 +433,7 @@ "nullable": true }, { - "type": "Relation", + "type": "ModelRef", "name": "studentClass", "comment": "班级", "modelName": "Student", @@ -445,7 +445,7 @@ }, { "name": "studentDetail", - "type": "Relation", + "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, @@ -482,7 +482,7 @@ ] }, { - "type": "entity", + "type": "Entity", "name": "StudentDetail", "fields": [ { @@ -505,7 +505,7 @@ "nullable": true }, { - "type": "Relation", + "type": "ModelRef", "name": "student", "comment": "学生", "modelName": "StudentDetail", @@ -527,7 +527,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "Classes", "fields": [ { @@ -555,7 +555,7 @@ "length": 255 }, { - "type": "Relation", + "type": "ModelRef", "name": "students", "modelName": "Classes", "unique": false, @@ -569,7 +569,7 @@ ] }, { - "type": "entity", + "type": "Entity", "name": "Course", "fields": [ { @@ -605,7 +605,7 @@ }, { "name": "ApiType", - "type": "enum", + "type": "Enum", "elements": [ "FOLDER", "API" @@ -614,7 +614,7 @@ }, { "name": "DatasourceType", - "type": "enum", + "type": "Enum", "elements": [ "SYSTEM", "USER" @@ -623,7 +623,7 @@ }, { "name": "UserGender", - "type": "enum", + "type": "Enum", "elements": [ "UNKNOWN", "MALE", @@ -633,7 +633,7 @@ }, { "name": "user_interest", - "type": "enum", + "type": "Enum", "elements": [ "chang", "tiao", @@ -644,7 +644,7 @@ }, { "name": "LogLevel", - "type": "enum", + "type": "Enum", "elements": [ "DEBUG", "INFO", @@ -658,4 +658,4 @@ "statement": "select count(*) as total from fs_api_log", "type": "native_query" } -] +] \ No newline at end of file diff --git a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelAbstractDataFetcher.java b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelAbstractDataFetcher.java index fae1eeb..2e745fd 100644 --- a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelAbstractDataFetcher.java +++ b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelAbstractDataFetcher.java @@ -7,7 +7,7 @@ import graphql.schema.SelectedField; import dev.flexmodel.JsonUtils; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.query.Direction; import dev.flexmodel.query.Query; @@ -51,12 +51,12 @@ public FlexmodelAbstractDataFetcher(String schemaName, String modelName, Session this.sessionFactory = sessionFactory; } - protected List> findRelationDataList(Session session, DataFetchingEnvironment env, String path, String modelName, RelationField relationField, Object id) { + protected List> findRelationDataList(Session session, DataFetchingEnvironment env, String path, String modelName, ModelRefField relationField, Object id) { EntityDefinition entity = (EntityDefinition) session.schema().getModel(relationField.getModelName()); EntityDefinition targetEntity = (EntityDefinition) session.schema().getModel(relationField.getFrom()); path = path == null ? relationField.getName() : path + "/" + relationField.getName(); List selectedFields = env.getSelectionSet().getFields(path + "/*"); - List relationFields = new ArrayList<>(); + List relationFields = new ArrayList<>(); List> list = session.dsl() .select(selector -> { @@ -67,7 +67,7 @@ protected List> findRelationDataList(Session session, DataFe if (flexModelField == null) { continue; } - if (flexModelField instanceof RelationField secondaryRelationField) { + if (flexModelField instanceof ModelRefField secondaryRelationField) { relationFields.add(secondaryRelationField); continue; } @@ -84,7 +84,7 @@ protected List> findRelationDataList(Session session, DataFe for (Map map : list) { Map resultData = new HashMap<>(map); result.add(resultData); - for (RelationField sencondaryRelationField : relationFields) { + for (ModelRefField sencondaryRelationField : relationFields) { Object secondaryId = map.get(entity.findIdField().map(TypedField::getName).orElseThrow()); List> associationDataList = findRelationDataList(session, env, path, sencondaryRelationField.getFrom(), sencondaryRelationField, secondaryId); resultData.put(sencondaryRelationField.getName(), sencondaryRelationField.isMultiple() ? diff --git a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelByIdDataFetcher.java b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelByIdDataFetcher.java index 40b83aa..2f23a6c 100644 --- a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelByIdDataFetcher.java +++ b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelByIdDataFetcher.java @@ -3,7 +3,7 @@ import graphql.schema.DataFetchingEnvironment; import graphql.schema.SelectedField; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.session.Session; import dev.flexmodel.session.SessionFactory; @@ -13,8 +13,6 @@ import java.util.List; import java.util.Map; -import static dev.flexmodel.query.Expressions.field; - import dev.flexmodel.query.Expressions; import dev.flexmodel.query.Query; @@ -35,7 +33,7 @@ public Map get(DataFetchingEnvironment env) { EntityDefinition entity = (EntityDefinition) session.schema().getModel(modelName); TypedField idField = entity.findIdField().orElseThrow(); - List relationFields = new ArrayList<>(); + List relationFields = new ArrayList<>(); List> list = session.dsl() .select(projection -> { @@ -45,7 +43,7 @@ public Map get(DataFetchingEnvironment env) { if (flexModelField == null) { continue; } - if (flexModelField instanceof RelationField secondaryRelationField) { + if (flexModelField instanceof ModelRefField secondaryRelationField) { relationFields.add(secondaryRelationField); continue; } @@ -62,7 +60,7 @@ public Map get(DataFetchingEnvironment env) { return null; } Map resultData = new HashMap<>(list.stream().findFirst().orElseThrow()); - for (RelationField secondaryRelationField : relationFields) { + for (ModelRefField secondaryRelationField : relationFields) { Object secondaryId = resultData.get(idField.getName()); List> relationDataList = findRelationDataList(session, env, null, secondaryRelationField.getFrom(), secondaryRelationField, secondaryId); resultData.put(secondaryRelationField.getName(), secondaryRelationField.isMultiple() ? relationDataList : relationDataList.stream().findFirst().orElse(null)); diff --git a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelListDataFetcher.java b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelListDataFetcher.java index d464188..8f836c8 100644 --- a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelListDataFetcher.java +++ b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/FlexmodelListDataFetcher.java @@ -4,7 +4,7 @@ import graphql.schema.SelectedField; import dev.flexmodel.JsonUtils; import dev.flexmodel.model.EntityDefinition; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.TypedField; import dev.flexmodel.query.Direction; import dev.flexmodel.query.Query; @@ -41,7 +41,7 @@ public List> findRootData(DataFetchingEnvironment env) { List selectedFields = env.getSelectionSet().getImmediateFields(); try (Session session = sessionFactory.createSession(schemaName)) { EntityDefinition entity = (EntityDefinition) session.schema().getModel(modelName); - List relationFields = new ArrayList<>(); + List relationFields = new ArrayList<>(); String whereString = null; if (where != null) { @@ -70,7 +70,7 @@ public List> findRootData(DataFetchingEnvironment env) { if (flexModelField == null) { continue; } - if (flexModelField instanceof RelationField secondaryRelationField) { + if (flexModelField instanceof ModelRefField secondaryRelationField) { relationFields.add(secondaryRelationField); continue; } @@ -88,7 +88,7 @@ public List> findRootData(DataFetchingEnvironment env) { for (Map map : list) { Map resultData = new HashMap<>(map); result.add(resultData); - for (RelationField sencondaryRelationField : relationFields) { + for (ModelRefField sencondaryRelationField : relationFields) { Object secondaryId = map.get(entity.findIdField().map(TypedField::getName).orElseThrow()); List> relationDataList = findRelationDataList(session, env, null, sencondaryRelationField.getFrom(), sencondaryRelationField, secondaryId); resultData.put(sencondaryRelationField.getName(), diff --git a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/GraphQLSchemaGenerator.java b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/GraphQLSchemaGenerator.java index 300b634..99a0b9a 100644 --- a/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/GraphQLSchemaGenerator.java +++ b/flexmodel-engine/flexmodel-graphql/src/main/java/dev/flexmodel/graphql/GraphQLSchemaGenerator.java @@ -2,11 +2,10 @@ import dev.flexmodel.codegen.AbstractGenerator; import dev.flexmodel.codegen.GenerationContext; -import dev.flexmodel.codegen.ModelClass; import dev.flexmodel.codegen.ModelField; import dev.flexmodel.codegen.StringUtils; import dev.flexmodel.model.field.EnumRefField; -import dev.flexmodel.model.field.RelationField; +import dev.flexmodel.model.field.ModelRefField; import dev.flexmodel.model.field.ScalarType; import dev.flexmodel.model.field.TypedField; @@ -47,8 +46,8 @@ public class GraphQLSchemaGenerator extends AbstractGenerator { private final I18nUtil i18n = new I18nUtil(); private String toGraphQLType(ModelField itt, GenerationContext context) { - if (itt.isRelationField()) { - RelationField rf = (RelationField) itt.getOriginal(); + if (itt.isModelRefField()) { + ModelRefField rf = (ModelRefField) itt.getOriginal(); String typeName = StringUtils.capitalize(StringUtils.snakeToCamel(rf.getFrom())); if (rf.isMultiple()) { return "[" + typeName + "]"; @@ -203,7 +202,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println(); out.println("type " + key + "AvgFields {"); for (var f : it.getAllFields()) { - if (!f.isRelationField()) { + if (!f.isModelRefField()) { out.println(" " + f.getName() + ": Float"); } } @@ -220,7 +219,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println(" and: [" + key + "BoolExp!]"); out.println(" or: [" + key + "BoolExp!]"); for (var f : it.getAllFields()) { - if (!f.isRelationField() && !f.isEnumField()) { + if (!f.isModelRefField() && !f.isEnumField()) { TypedField tf = (TypedField) f.getOriginal(); out.println(" " + f.getName() + ": " + comparisonMapping.getOrDefault(tf.getType(), "StringComparisonExp")); } else if (f.isEnumField() && context.containsEnumClass(((EnumRefField) f.getOriginal()).getFrom())) { @@ -235,7 +234,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println("\"" + i18n.getString("gql.order_by.comment", key) + "\""); out.println("input " + key + "OrderBy {"); for (var f : it.getAllFields()) { - if (!f.isRelationField()) { + if (!f.isModelRefField()) { out.println(" " + f.getName() + ": OrderBy"); } } @@ -243,7 +242,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println(); out.println("input " + key + "InsertInput {"); for (var f : it.getAllFields()) { - if (!f.isRelationField()) { + if (!f.isModelRefField()) { out.println(" " + f.getName() + ": " + toGraphQLType(f, context)); } } @@ -251,7 +250,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println(); out.println("input " + key + "SetInput {"); for (var f : it.getAllFields()) { - if (!f.isRelationField()) { + if (!f.isModelRefField()) { out.println(" " + f.getName() + ": " + toGraphQLType(f, context)); } } @@ -264,7 +263,7 @@ public void write(PrintWriter out, GenerationContext context) { out.println(); out.println("enum " + key + "SelectField {"); for (var f : it.getAllFields()) { - if (!f.isRelationField()) { + if (!f.isModelRefField()) { out.println(" " + f.getName()); } } diff --git a/flexmodel-engine/flexmodel-graphql/src/test/java/dev/flexmodel/graphql/Models.java b/flexmodel-engine/flexmodel-graphql/src/test/java/dev/flexmodel/graphql/Models.java index 5567d2b..29c3fbf 100644 --- a/flexmodel-engine/flexmodel-graphql/src/test/java/dev/flexmodel/graphql/Models.java +++ b/flexmodel-engine/flexmodel-graphql/src/test/java/dev/flexmodel/graphql/Models.java @@ -74,7 +74,7 @@ public static EntityDefinition createTeacherEntity(Session session, String entit public static void createAssociations(Session session, String classRoomEntityName, String studentEntityName, String studentDetailEntityName, String courseEntityName, String teacherEntityName) { // 班级:学生 - session.schema().createField(new RelationField("students") + session.schema().createField(new ModelRefField("students") .setModelName(classRoomEntityName) .setFrom(studentEntityName) .setForeignField("classId") @@ -82,7 +82,7 @@ public static void createAssociations(Session session, String classRoomEntityNam .setCascadeDelete(true) ); // 学生:学生明细 -> 1:1 - session.schema().createField(new RelationField("studentDetail") + session.schema().createField(new ModelRefField("studentDetail") .setModelName(studentEntityName) .setFrom(studentDetailEntityName) .setForeignField("studentId") diff --git a/flexmodel-engine/flexmodel-graphql/src/test/resources/import.json b/flexmodel-engine/flexmodel-graphql/src/test/resources/import.json index 850f0bf..a08f290 100644 --- a/flexmodel-engine/flexmodel-graphql/src/test/resources/import.json +++ b/flexmodel-engine/flexmodel-graphql/src/test/resources/import.json @@ -2,7 +2,7 @@ "objects": [ { "name": "Datasource", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -59,7 +59,7 @@ { "name": "ApiInfo", "comment": "接口信息", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -144,7 +144,7 @@ }, { "name": "ApiLog", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -204,7 +204,7 @@ }, { "name": "IdentityProvider", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -241,7 +241,7 @@ { "name": "Config", "comment": "配置", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -302,7 +302,7 @@ ] }, { - "type": "entity", + "type": "Entity", "name": "Teacher", "fields": [ { @@ -337,7 +337,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "Student", "fields": [ { @@ -394,7 +394,7 @@ }, { "name": "studentDetail", - "type": "Relation", + "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, @@ -407,7 +407,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "StudentDetail", "fields": [ { @@ -440,7 +440,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "Classes", "fields": [ { @@ -468,7 +468,7 @@ "length": 255 }, { - "type": "Relation", + "type": "ModelRef", "name": "students", "modelName": "Classes", "unique": false, @@ -482,7 +482,7 @@ "indexes": [] }, { - "type": "entity", + "type": "Entity", "name": "Course", "fields": [ { @@ -502,7 +502,7 @@ }, { "name": "students", - "type": "Relation", + "type": "ModelRef", "modelName": "Course", "unique": false, "nullable": true, @@ -528,7 +528,7 @@ }, { "name": "UserGender", - "type": "enum", + "type": "Enum", "elements": [ "UNKNOWN", "MALE", @@ -538,7 +538,7 @@ }, { "name": "User_interest", - "type": "enum", + "type": "Enum", "elements": [ "Chang", "Tiao", @@ -788,4 +788,4 @@ ] } ] -} +} \ No newline at end of file diff --git a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/AbstractSessionTests.java b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/AbstractSessionTests.java index 8751e0c..637a792 100644 --- a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/AbstractSessionTests.java +++ b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/AbstractSessionTests.java @@ -203,7 +203,7 @@ void createAssociations(String classRoomEntityName, String studentEntityName, String studentDetailEntityName, String courseEntityName, String teacherEntityName) { // 班级:学生 session.schema().createField( - new RelationField("students") + new ModelRefField("students") .setModelName(classRoomEntityName) .setFrom(studentEntityName) .setLocalField("id") @@ -213,7 +213,7 @@ void createAssociations(String classRoomEntityName, String studentEntityName, ); // 学生:学生明细 -> 1:1 session.schema().createField( - new RelationField("studentDetail") + new ModelRefField("studentDetail") .setModelName(studentEntityName) .setFrom(studentDetailEntityName) .setLocalField("id") @@ -222,7 +222,7 @@ void createAssociations(String classRoomEntityName, String studentEntityName, ); // 明细:学生 -> 1:1 session.schema().createField( - new RelationField("student") + new ModelRefField("student") .setModelName(studentDetailEntityName) .setFrom(studentEntityName) .setLocalField("studentId") @@ -626,7 +626,7 @@ void createTeacherCourseEntity(String teacherEntityName, String teacherCourseEnt .setComment("教师成绩表") ); session.schema().createField( - new RelationField("courses") + new ModelRefField("courses") .setModelName(teacherEntityName) .setMultiple(true) .setCascadeDelete(true) diff --git a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Classes.java b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Classes.java index 89fd101..a5693e0 100644 --- a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Classes.java +++ b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Classes.java @@ -2,7 +2,7 @@ import dev.flexmodel.annotation.ModelClass; import dev.flexmodel.annotation.ModelField; -import dev.flexmodel.annotation.ModelRelation; +import dev.flexmodel.annotation.ModelRef; import java.util.List; @@ -12,7 +12,7 @@ @ModelClass("Classes") public class Classes { - @ModelRelation + @ModelRef @ModelField("students") private List students; diff --git a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Student.java b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Student.java index 79e0f31..0db226a 100644 --- a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Student.java +++ b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/java/dev/flexmodel/entity/Student.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonRootName; -import dev.flexmodel.annotation.ModelRelation; +import dev.flexmodel.annotation.ModelRef; import dev.flexmodel.enumeration.UserGender; import dev.flexmodel.enumeration.UserInterest; @@ -14,7 +14,7 @@ @JsonRootName("Student") public class Student { - @ModelRelation + @ModelRef @JsonProperty("studentDetail") private StudentDetail studentDetail; diff --git a/flexmodel-sdks b/flexmodel-sdks index cd01e13..cb79787 160000 --- a/flexmodel-sdks +++ b/flexmodel-sdks @@ -1 +1 @@ -Subproject commit cd01e135a16de50c0926d2f1d1685b874b9297c4 +Subproject commit cb79787bd5b8a861bb18e8f3ed78e65d976e102e diff --git a/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java b/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java index 4a17b4c..623c370 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java @@ -71,13 +71,13 @@ private void requirePermission(String permission) { @ExampleObject( name = "实体", value = """ - [{ "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] }] + [{ "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] }] """ ), @ExampleObject( name = "枚举", value = """ - [{ "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" }] + [{ "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" }] """ ), @ExampleObject( @@ -114,13 +114,13 @@ public List findModels(@PathParam("projectId") String projectId) { @ExampleObject( name = "实体", value = """ - { "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } + { "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } """ ), @ExampleObject( name = "枚举", value = """ - { "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } + { "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } """ ), @ExampleObject( @@ -154,13 +154,13 @@ public SchemaObject findModel(@PathParam("projectId") String projectId, @PathPar @ExampleObject( name = "实体", value = """ - { "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } + { "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } """ ), @ExampleObject( name = "枚举", value = """ - { "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } + { "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } """ ), @ExampleObject( @@ -190,13 +190,13 @@ public SchemaObject findModel(@PathParam("projectId") String projectId, @PathPar @ExampleObject( name = "实体", value = """ - { "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } + { "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } """ ), @ExampleObject( name = "枚举", value = """ - { "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } + { "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } """ ), @ExampleObject( @@ -241,13 +241,13 @@ public Boolean executeFml(@PathParam("projectId") String projectId, FmlRequest r @ExampleObject( name = "实体", value = """ - { "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } + { "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } """ ), @ExampleObject( name = "枚举", value = """ - { "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } + { "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } """ ), @ExampleObject( @@ -277,13 +277,13 @@ public Boolean executeFml(@PathParam("projectId") String projectId, FmlRequest r @ExampleObject( name = "实体", value = """ - { "type": "entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "Relation", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } + { "type": "Entity", "name": "Student", "fields": [ { "name": "id", "type": "Long", "identity": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentName", "type": "String", "modelName": "Student", "unique": false, "nullable": true, "length": 255 }, { "name": "gender", "type": "EnumRef", "from": "UserGender", "multiple": false, "modelName": "Student", "unique": false, "nullable": true }, { "name": "interest", "type": "EnumRef", "from": "user_interest", "multiple": true, "modelName": "Student", "unique": false, "nullable": true }, { "name": "age", "type": "Int", "modelName": "Student", "unique": false, "nullable": true }, { "name": "classId", "type": "Long", "modelName": "Student", "unique": false, "nullable": true }, { "name": "studentDetail", "type": "ModelRef", "modelName": "Student", "unique": false, "nullable": true, "multiple": false, "from": "StudentDetail", "localField": "id", "foreignField": "studentId", "cascadeDelete": true } ], "indexes": [ { "modelName": "Student", "name": "IDX_studentName", "fields": [ { "fieldName": "studentName", "direction": "ASC" } ], "unique": false } ] } """ ), @ExampleObject( name = "枚举", value = """ - { "name": "UserGender", "type": "enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } + { "name": "UserGender", "type": "Enum", "elements": [ "UNKNOWN", "MALE", "FEMALE" ], "comment": "性别" } """ ), @ExampleObject( @@ -526,7 +526,7 @@ public EnumSchema(String name) { description = "本地查询", properties = { @SchemaProperty(name = "name", description = "名称"), - @SchemaProperty(name = "type", description = "类型, entity: 实体;native_query: 本地查询;enum: 枚举"), + @SchemaProperty(name = "type", description = "类型, Entity: 实体;native_query: 本地查询;Enum: 枚举"), @SchemaProperty(name = "statement", description = "语句"), @SchemaProperty(name = "comment", description = "注释"), @SchemaProperty(name = "additionalProperties", description = "用户自定义扩展属性"), @@ -543,7 +543,7 @@ public NativeQuerySchema(String name) { description = "实体", properties = { @SchemaProperty(name = "name", description = "名称"), - @SchemaProperty(name = "type", description = "类型, entity: 实体;native_query: 本地查询;enum: 枚举"), + @SchemaProperty(name = "type", description = "类型, Entity: 实体;native_query: 本地查询;Enum: 枚举"), @SchemaProperty(name = "fields", description = "字段列表"), @SchemaProperty(name = "indexes", description = "索引列表"), @SchemaProperty(name = "comment", description = "注释"), diff --git a/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/reachability-metadata.json b/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/reachability-metadata.json index 33d9ef6..04a05b1 100644 --- a/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/reachability-metadata.json +++ b/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/reachability-metadata.json @@ -5366,7 +5366,7 @@ ] }, { - "type": "dev.flexmodel.model.field.RelationField", + "type": "dev.flexmodel.model.field.ModelRefField", "serializable": true, "methods": [ { diff --git a/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/serialization-config.json b/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/serialization-config.json index 53f48df..6a66695 100644 --- a/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/serialization-config.json +++ b/flexmodel-server/src/main/resources/META-INF/native-image/dev.flexmodel/flexmodel-server/serialization-config.json @@ -45,7 +45,7 @@ "name": "dev.flexmodel.model.field.EnumRefField" }, { - "name": "dev.flexmodel.model.field.RelationField" + "name": "dev.flexmodel.model.field.ModelRefField" }, { "name": "dev.flexmodel.model.field.TypedField" diff --git a/flexmodel-ui b/flexmodel-ui index 8d0b601..2ba929c 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit 8d0b6013dd2b421e2ab6eb4de7ab9a2e024afc0e +Subproject commit 2ba929c609381a95bb0d1b593ddb9807d29d46f9 diff --git a/flexmodel-website b/flexmodel-website index 501c05e..8b96b55 160000 --- a/flexmodel-website +++ b/flexmodel-website @@ -1 +1 @@ -Subproject commit 501c05ec3151cc36ddd9bdb657c52be0d549bd13 +Subproject commit 8b96b55fbb173516b49c49d60f25cdfd676daa8f From d8bb3cb9dd2abf9f7497c9df68230c21b63dedd6 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Thu, 13 Aug 2026 20:50:05 +0800 Subject: [PATCH 02/12] =?UTF-8?q?fix(core):=20=E4=BF=AE=E6=AD=A3=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E5=BC=95=E7=94=A8=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 EnumRefField 构造函数中的 ScalarType.ENUM 替换为 ScalarType.ENUM_REF - 修正 EnumDefinition 中 getType 方法返回值为 "Enum" - 移除 MongoContext 中重复的类型导入 - 更新 MongoContext 中类型处理器映射使用 ENUM_REF 类型 - 移除 SqlContext 中重复的类型导入 - 更新 SqlContext 中类型处理器映射使用 ENUM_REF 类型 - 修正 ModelMixIn 中 JSON 子类型注解的名称大小写 - 更新测试资源文件中实体类型的命名约定 - 修正 ModelingTools 中文档描述的类型名称大小写 - 更新 ModelResourceTest 中测试数据的类型名称大小写 --- .../java/dev/flexmodel/model/EnumDefinition.java | 2 +- .../dev/flexmodel/model/field/EnumRefField.java | 2 +- .../java/dev/flexmodel/mongodb/MongoContext.java | 3 +-- .../main/java/dev/flexmodel/sql/SqlContext.java | 3 +-- .../flexmodel/supports/jackson/ModelMixIn.java | 4 ++-- .../src/main/resources/import.json | 8 ++++---- .../java/dev/flexmodel/mcp/ModelingTools.java | 12 ++++++------ .../dev/flexmodel/rest/ModelResourceTest.java | 16 ++++++++-------- 8 files changed, 24 insertions(+), 26 deletions(-) diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EnumDefinition.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EnumDefinition.java index 5c7ded4..3410764 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EnumDefinition.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/EnumDefinition.java @@ -31,7 +31,7 @@ public String getName() { @Override public String getType() { - return "enum"; + return "Enum"; } public EnumDefinition setElements(List elements) { diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/EnumRefField.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/EnumRefField.java index 05af3c1..7730d2f 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/EnumRefField.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/field/EnumRefField.java @@ -18,7 +18,7 @@ public class EnumRefField extends TypedField { private String from; public EnumRefField(String name) { - super(name, ScalarType.ENUM.getType()); + super(name, ScalarType.ENUM_REF.getType()); } public boolean isMultiple() { diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoContext.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoContext.java index a86abf0..28df1df 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoContext.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/mongodb/MongoContext.java @@ -7,7 +7,6 @@ import dev.flexmodel.session.AbstractSessionContext; import dev.flexmodel.session.SessionFactory; import dev.flexmodel.type.*; -import dev.flexmodel.type.*; import java.util.HashMap; import java.util.Map; @@ -35,7 +34,7 @@ public MongoContext(String schemaName, MongoDatabase mongoDatabase, ModelRegistr this.typeHandlerMap.put(ScalarType.DATE.getType(), new DateTypeHandler()); this.typeHandlerMap.put(ScalarType.TIME.getType(), new TimeTypeHandler()); this.typeHandlerMap.put(ScalarType.JSON.getType(), new JsonTypeHandler()); - this.typeHandlerMap.put(ScalarType.ENUM.getType(), new EnumTypeHandler()); + this.typeHandlerMap.put(ScalarType.ENUM_REF.getType(), new EnumTypeHandler()); } public MongoDatabase getMongoDatabase() { diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlContext.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlContext.java index eb2a796..65c7931 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlContext.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/sql/SqlContext.java @@ -6,7 +6,6 @@ import dev.flexmodel.session.SessionFactory; import dev.flexmodel.sql.dialect.SqlDialect; import dev.flexmodel.sql.type.*; -import dev.flexmodel.sql.type.*; import java.sql.Connection; import java.sql.DatabaseMetaData; @@ -60,7 +59,7 @@ public SqlContext(String schemaName, this.typeHandlerMap.put(ScalarType.TIME.getType(), new LegacyTimeSqlTypeHandler()); } this.typeHandlerMap.put(ScalarType.JSON.getType(), new JsonSqlTypeHandler()); - this.typeHandlerMap.put(ScalarType.ENUM.getType(), new EnumSqlTypeHandler()); + this.typeHandlerMap.put(ScalarType.ENUM_REF.getType(), new EnumSqlTypeHandler()); } @Override diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java index 93e586b..1a253ca 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java @@ -13,9 +13,9 @@ */ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ - @JsonSubTypes.Type(value = EntityDefinition.class, name = "entity"), + @JsonSubTypes.Type(value = EntityDefinition.class, name = "Entity"), @JsonSubTypes.Type(value = NativeQueryDefinition.class, name = "native_query"), - @JsonSubTypes.Type(value = EnumDefinition.class, name = "enum"), + @JsonSubTypes.Type(value = EnumDefinition.class, name = "Enum"), }) public class ModelMixIn { diff --git a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/resources/import.json b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/resources/import.json index b13fa87..77e7ab6 100644 --- a/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/resources/import.json +++ b/flexmodel-engine/integration-tests/flexmodel-common-it/src/main/resources/import.json @@ -2,7 +2,7 @@ "objects": [ { "name": "Datasource", - "type": "entity", + "type": "Entity", "fields": [ { "name": "name", @@ -46,7 +46,7 @@ }, { "name": "ApiInfo", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -142,7 +142,7 @@ }, { "name": "ApiLog", - "type": "entity", + "type": "Entity", "fields": [ { "name": "id", @@ -214,7 +214,7 @@ }, { "name": "IdentityProvider", - "type": "entity", + "type": "Entity", "fields": [ { "name": "createdAt", diff --git a/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java b/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java index c524c94..23f94f2 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java @@ -61,14 +61,14 @@ public String get_model( @Tool(description = """ Create a new entity model (maps to a database table) in a project. \ - The entityJson must be a JSON object with type='entity', name, and fields array. \ + The entityJson must be a JSON object with type='Entity', name, and fields array. \ Supported field types: String (with length, default 255), Int, Long, Float (with precision/scale), \ Boolean, DateTime, Date, Time, JSON, Enum (EnumRef, with 'from' pointing to an enum name, 'multiple' for array), \ Relation (with 'from', 'localField', 'foreignField', 'cascadeDelete'). \ Common field properties: name, type, modelName (must match entity name), nullable (default true), \ unique (default false), identity (for primary key), comment, defaultValue. \ Optional indexes array at entity level. \ - Example: {"type":"entity","name":"Student","fields":[\ + Example: {"type":"Entity","name":"Student","fields":[\ {"name":"id","type":"Long","identity":true,"modelName":"Student"},\ {"name":"studentName","type":"String","modelName":"Student","length":255},\ {"name":"age","type":"Int","modelName":"Student"},\ @@ -80,7 +80,7 @@ Boolean, DateTime, Date, Time, JSON, Enum (EnumRef, with 'from' pointing to an e public String create_entity_model( @ToolArg(description = "The project ID, e.g. 'dev_test', 'default'") String projectId, @ToolArg(description = """ - Entity definition as JSON string: must contain type='entity', name, and fields array. \ + Entity definition as JSON string: must contain type='Entity', name, and fields array. \ Each field must have name, type, and modelName. See tool description for supported types and properties.\ """) String entityJson ) { @@ -98,14 +98,14 @@ public String create_entity_model( @Tool(description = """ Create a new enum definition in a project. Enums define a fixed set of string values \ that can be referenced by entity fields via the EnumRef field type (using 'from' property). \ - The enumJson must be a JSON object with name, type='enum', and elements (string array). \ + The enumJson must be a JSON object with name, type='Enum', and elements (string array). \ Elements should be uppercase or UPPER_SNAKE_CASE by convention. \ Optional: comment for description, additionalProperties for i18n or extensions. \ - Example: {"name":"UserGender","type":"enum","elements":["UNKNOWN","MALE","FEMALE"],"comment":"User gender options"}\ + Example: {"name":"UserGender","type":"Enum","elements":["UNKNOWN","MALE","FEMALE"],"comment":"User gender options"}\ """) public String create_enum_model( @ToolArg(description = "The project ID, e.g. 'dev_test', 'default'") String projectId, - @ToolArg(description = "Enum definition as JSON string: must contain name, type='enum', and elements (string array)") String enumJson + @ToolArg(description = "Enum definition as JSON string: must contain name, type='Enum', and elements (string array)") String enumJson ) { log.info("create_enum_model called, projectId={}, enumJson={}", projectId, enumJson); try { diff --git a/flexmodel-server/src/test/java/dev/flexmodel/rest/ModelResourceTest.java b/flexmodel-server/src/test/java/dev/flexmodel/rest/ModelResourceTest.java index eadcf0e..6abe09f 100644 --- a/flexmodel-server/src/test/java/dev/flexmodel/rest/ModelResourceTest.java +++ b/flexmodel-server/src/test/java/dev/flexmodel/rest/ModelResourceTest.java @@ -60,7 +60,7 @@ void testCreateModel() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testCreateModelStudent", "fields": [ { @@ -112,7 +112,7 @@ void testDropModel() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testDropModelStudent", "fields": [ { @@ -181,7 +181,7 @@ void testCreateField() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testCreateFieldStudent", "fields": [ { @@ -260,7 +260,7 @@ void testModifyField() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testModifyFieldStudent", "fields": [ { @@ -340,7 +340,7 @@ void testDropField() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testDropFieldStudent", "fields": [ { @@ -411,7 +411,7 @@ void testCreateIndex() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testCreateIndexStudent", "fields": [ { @@ -494,7 +494,7 @@ void testModifyIndex() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testModifyIndexStudent", "fields": [ { @@ -589,7 +589,7 @@ void testDropIndex() { .contentType(ContentType.JSON) .body(""" { - "type": "entity", + "type": "Entity", "name": "testDropIndexStudent", "fields": [ { From a33fb44410884b9e54f00a692dfbd6eb4e6787d6 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Sat, 15 Aug 2026 04:11:50 +0800 Subject: [PATCH 03/12] =?UTF-8?q?docs(api):=20=E6=9B=B4=E6=96=B0=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=BC=95=E7=94=A8=E5=AD=97=E6=AE=B5=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E4=BB=A5=E5=8C=B9=E9=85=8DAPI=E5=8F=98=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将关系字段章节标题改为模型引用字段 - 将RelationField示例重写为ModelRefField新API - 删除多对多关系示例因新API不再支持 - 更新flexmodel-core.md中的字段创建代码 - 修改codegen文档中的isRelationField调用为isModelRefField --- flexmodel-engine/docs/API.md | 37 ++++++++-------------- flexmodel-engine/docs/flexmodel-codegen.md | 2 +- flexmodel-engine/docs/flexmodel-core.md | 4 ++- progress.md | 21 +++++++++++- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/flexmodel-engine/docs/API.md b/flexmodel-engine/docs/API.md index 4cbe056..5d56bc8 100644 --- a/flexmodel-engine/docs/API.md +++ b/flexmodel-engine/docs/API.md @@ -339,31 +339,22 @@ EnumField statusField = new EnumField("status") .setDefaultValue("PENDING"); ``` -#### 关系字段 +#### 模型引用字段 ```java -// 一对一关系 -RelationField profileField = new RelationField("profile") - .setType(RelationField.Type.ONE_TO_ONE) - .setFrom("User") - .setTo("UserProfile") - .setForeignField("user_id"); - -// 一对多关系 -RelationField ordersField = new RelationField("orders") - .setType(RelationField.Type.ONE_TO_MANY) - .setFrom("User") - .setTo("Order") - .setForeignField("user_id"); - -// 多对多关系 -RelationField rolesField = new RelationField("roles") - .setType(RelationField.Type.MANY_TO_MANY) - .setFrom("User") - .setTo("Role") - .setJoinTable("user_roles") - .setJoinColumn("user_id") - .setInverseJoinColumn("role_id"); +// 单选引用(一对一) +ModelRefField profileField = new ModelRefField("profile") + .setFrom("UserProfile") + .setLocalField("profileId") + .setForeignField("id"); + +// 多选引用(一对多) +ModelRefField ordersField = new ModelRefField("orders") + .setMultiple(true) + .setFrom("Order") + .setLocalField("userId") + .setForeignField("id"); + ``` ### 异常处理 diff --git a/flexmodel-engine/docs/flexmodel-codegen.md b/flexmodel-engine/docs/flexmodel-codegen.md index 710596b..31bf099 100644 --- a/flexmodel-engine/docs/flexmodel-codegen.md +++ b/flexmodel-engine/docs/flexmodel-codegen.md @@ -27,7 +27,7 @@ class ListApiDefinitionGenerator extends ApiDefinitionGenerator { out.println "query MyListQuery( \$where: ${modelName}BoolExp) {" out.println " ${modelName}(where: \$where) {" context.getModelClass().getAllFields().each { - if (!it.isRelationField()) { + if (!it.isModelRefField()) { out.println " ${it.fieldName}" } } diff --git a/flexmodel-engine/docs/flexmodel-core.md b/flexmodel-engine/docs/flexmodel-core.md index 226a940..0d8c8b1 100644 --- a/flexmodel-engine/docs/flexmodel-core.md +++ b/flexmodel-engine/docs/flexmodel-core.md @@ -175,7 +175,9 @@ session.schema().createEntity("Student", entity -> entity .addField(new IntField("age")) .addField(new FloatField("score").setPrecision(5).setScale(2)) .addField(new EnumRefField("gender").setFrom("UserGender")) - .addField(new RelationField("studentClass") + . + +addField(new ModelRefField("studentClass") .setFrom("Classes") .setLocalField("classId") .setForeignField("id")) diff --git a/progress.md b/progress.md index 3049593..6cd2030 100644 --- a/progress.md +++ b/progress.md @@ -1,4 +1,23 @@ -# Session Progress Log +# Session Progress Log + +## Doc Fix: 补全模型引用字段重命名的文档更新(2026-08-15) + +**背景:** `feature/model-ref` 分支此前将 `RelationField` 重命名为 `ModelRefField`、`ScalarType.RELATION` → `MODEL_REF`、 +`ScalarType.ENUM` → `ENUM_REF`(commit d3be8f0、d8bb3cb)。源码与测试资源已全部更新且编译通过,但 `flexmodel-engine/docs/` 下 +3 个文档仍残留旧 API 名称。 + +**修复:** + +- `flexmodel-engine/docs/API.md`:将「关系字段」章节标题改为「模型引用字段」;将 `RelationField` 示例重写为 `ModelRefField` 新 + API(`setFrom`/`setLocalField`/`setForeignField`/`setMultiple`);删除新 API 已不支持的多对多示例(`setJoinTable` 等方法已移除)。 +- `flexmodel-engine/docs/flexmodel-core.md`:`new RelationField("studentClass")` → `new ModelRefField("studentClass")`。 +- `flexmodel-engine/docs/flexmodel-codegen.md`:`it.isRelationField()` → `it.isModelRefField()`。 + +**验证:** + +- `mvn test -pl flexmodel-engine/flexmodel-core -o` → BUILD SUCCESS,Tests run: 49, Failures: 0, Errors: 0(含 + `JsonSerializeTest`)。 +- 全仓搜索 `RelationField` / `isRelationField`(docs 目录)→ 0 残留。 ## Bug Fix: Storage 复制访问链接不能访问(2026-08-06) From 37024720650beee9b439023cf7f20704946c2964 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Sat, 15 Aug 2026 04:23:11 +0800 Subject: [PATCH 04/12] =?UTF-8?q?fix(core):=20=E7=BB=9F=E4=B8=80NativeQuer?= =?UTF-8?q?y=E7=B1=BB=E5=9E=8B=E6=A0=87=E8=AF=86=E7=AC=A6=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将NativeQueryDefinition.getType()返回值从"native_query"改为"NativeQuery" - 更新ModelMixIn中NativeQueryDefinition的类型名称映射 - 修改sample_input.json测试文件中的类型值 - 更新ModelingTools工具描述中的类型说明 - 修正ModelingResource中所有示例对象的类型值 - 更新ModelingResource中API文档的类型枚举说明 - 修改UI组件ProvidersTab中的类型过滤条件 - 更新ModelExplorer中模型图标获取和分组逻辑的类型判断 - 修正ModelForm中表单提交和标签页切换的类型匹配 - 更新NativeQueryForm中类型赋值和确认逻辑 - 修改DataModeling页面中模型视图渲染的类型判断 - 更新data-modeling.d.ts中TypeWrapper --- .../flexmodel/model/NativeQueryDefinition.java | 2 +- .../flexmodel/supports/jackson/ModelMixIn.java | 2 +- .../src/test/resources/sample_input.json | 4 ++-- .../java/dev/flexmodel/mcp/ModelingTools.java | 2 +- .../dev/flexmodel/modeling/ModelingResource.java | 16 ++++++++-------- flexmodel-ui | 2 +- flexmodel-website | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/NativeQueryDefinition.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/NativeQueryDefinition.java index d534be9..6fb0b40 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/NativeQueryDefinition.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/model/NativeQueryDefinition.java @@ -32,7 +32,7 @@ public NativeQueryDefinition setStatement(String statement) { @Override public String getType() { - return "native_query"; + return "NativeQuery"; } /** diff --git a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java index 1a253ca..dabe3d0 100644 --- a/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java +++ b/flexmodel-engine/flexmodel-core/src/main/java/dev/flexmodel/supports/jackson/ModelMixIn.java @@ -14,7 +14,7 @@ @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") @JsonSubTypes({ @JsonSubTypes.Type(value = EntityDefinition.class, name = "Entity"), - @JsonSubTypes.Type(value = NativeQueryDefinition.class, name = "native_query"), + @JsonSubTypes.Type(value = NativeQueryDefinition.class, name = "NativeQuery"), @JsonSubTypes.Type(value = EnumDefinition.class, name = "Enum"), }) public class ModelMixIn { diff --git a/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json b/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json index 092c5a1..b6905e8 100644 --- a/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json +++ b/flexmodel-engine/flexmodel-core/src/test/resources/sample_input.json @@ -656,6 +656,6 @@ { "name": "select_log_count", "statement": "select count(*) as total from fs_api_log", - "type": "native_query" + "type": "NativeQuery" } -] \ No newline at end of file +] diff --git a/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java b/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java index 23f94f2..50d63ba 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/mcp/ModelingTools.java @@ -23,7 +23,7 @@ public class ModelingTools { @Tool(description = """ List all models (entities, enums, native queries) in a project. \ - Returns a JSON array of model definitions. Each model has: type (entity/enum/native_query), name, \ + Returns a JSON array of model definitions. Each model has: type (entity/enum/NativeQuery), name, \ and type-specific fields. Entities include fields array and indexes array. \ Enums include elements array. Native queries include statement string.\ """) diff --git a/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java b/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java index 623c370..2fce04f 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/modeling/ModelingResource.java @@ -83,7 +83,7 @@ private void requirePermission(String permission) { @ExampleObject( name = "本地查询", value = """ - [{ "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" }] + [{ "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" }] """ ), } @@ -126,7 +126,7 @@ public List findModels(@PathParam("projectId") String projectId) { @ExampleObject( name = "本地查询", value = """ - { "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } + { "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } """ ), } @@ -166,7 +166,7 @@ public SchemaObject findModel(@PathParam("projectId") String projectId, @PathPar @ExampleObject( name = "本地查询", value = """ - { "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } + { "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } """ ), } @@ -202,7 +202,7 @@ public SchemaObject findModel(@PathParam("projectId") String projectId, @PathPar @ExampleObject( name = "本地查询", value = """ - { "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } + { "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } """ ), } @@ -253,7 +253,7 @@ public Boolean executeFml(@PathParam("projectId") String projectId, FmlRequest r @ExampleObject( name = "本地查询", value = """ - { "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } + { "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } """ ), } @@ -289,7 +289,7 @@ public Boolean executeFml(@PathParam("projectId") String projectId, FmlRequest r @ExampleObject( name = "本地查询", value = """ - { "name": "分组查询", "type": "native_query", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } + { "name": "分组查询", "type": "NativeQuery", "statement": "select count(id) as total, gender, max(age) as ageSum from Student group by gender" } """ ), } @@ -526,7 +526,7 @@ public EnumSchema(String name) { description = "本地查询", properties = { @SchemaProperty(name = "name", description = "名称"), - @SchemaProperty(name = "type", description = "类型, Entity: 实体;native_query: 本地查询;Enum: 枚举"), + @SchemaProperty(name = "type", description = "类型, Entity: 实体;NativeQuery: 本地查询;Enum: 枚举"), @SchemaProperty(name = "statement", description = "语句"), @SchemaProperty(name = "comment", description = "注释"), @SchemaProperty(name = "additionalProperties", description = "用户自定义扩展属性"), @@ -543,7 +543,7 @@ public NativeQuerySchema(String name) { description = "实体", properties = { @SchemaProperty(name = "name", description = "名称"), - @SchemaProperty(name = "type", description = "类型, Entity: 实体;native_query: 本地查询;Enum: 枚举"), + @SchemaProperty(name = "type", description = "类型, Entity: 实体;NativeQuery: 本地查询;Enum: 枚举"), @SchemaProperty(name = "fields", description = "字段列表"), @SchemaProperty(name = "indexes", description = "索引列表"), @SchemaProperty(name = "comment", description = "注释"), diff --git a/flexmodel-ui b/flexmodel-ui index 2ba929c..c7da28f 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit 2ba929c609381a95bb0d1b593ddb9807d29d46f9 +Subproject commit c7da28fdf4d1e6ba4a4d8fe2edf8c152c1bddf59 diff --git a/flexmodel-website b/flexmodel-website index 8b96b55..c6a5fad 160000 --- a/flexmodel-website +++ b/flexmodel-website @@ -1 +1 @@ -Subproject commit 8b96b55fbb173516b49c49d60f25cdfd676daa8f +Subproject commit c6a5fadbf9be52ea2a5cc32f4aff6f00470a8fba From 4b98c052e841639132b6256fa13746fb48b2f6cf Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Sat, 15 Aug 2026 04:37:59 +0800 Subject: [PATCH 05/12] =?UTF-8?q?refactor(datamodeling):=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E6=95=B0=E6=8D=AE=E6=A8=A1=E5=9E=8B=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E8=A7=84=E8=8C=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将所有 'enum' 类型统一更改为 'Enum' - 将所有 'entity' 类型统一更改为 'Entity' - 更新 ModelForm 中的标签页键值为大写开头 - 修正 ERDiagramView 中实体过滤条件的一致性 - 确保所有组件中的类型判断逻辑保持统一 --- flexmodel-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flexmodel-ui b/flexmodel-ui index c7da28f..59e1260 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit c7da28fdf4d1e6ba4a4d8fe2edf8c152c1bddf59 +Subproject commit 59e1260a43804f79221000f95649780773002081 From 570a1082e3c7e50832df4f155c7d60a749380553 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Sat, 15 Aug 2026 16:44:31 +0800 Subject: [PATCH 06/12] =?UTF-8?q?fix(datamodeling):=20=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E5=AE=9E=E4=BD=93=E5=85=B3=E7=B3=BB=E5=9B=BE=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E7=B1=BB=E5=9E=8B=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将字段类型判断从 'Relation' 修改为 'ModelRef' - 确保只有 ModelRef 类型的字段才会被处理为关联关系 - 修复因类型判断错误导致的关系映射问题 --- flexmodel-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flexmodel-ui b/flexmodel-ui index 59e1260..644e6df 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit 59e1260a43804f79221000f95649780773002081 +Subproject commit 644e6dfd7d91908551c9dc2da02b08c1c1c0096a From a72c6121353a5ec8cbe59035fd52ea1c7a3a5bbf Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 13:01:57 +0800 Subject: [PATCH 07/12] =?UTF-8?q?chore(ci):=20=E6=9B=B4=E6=96=B0=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E4=BB=A5=E6=94=AF=E6=8C=81=E5=A4=9A=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E9=95=9C=E5=83=8F=E6=9E=84=E5=BB=BA=E5=92=8C=E9=83=A8?= =?UTF-8?q?=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加版本环境变量设置(BUILD_VERSION、SHORT_SHA、FULL_VERSION) - 修改服务器镜像构建配置以支持多标签推送 - 修改原生服务器镜像构建配置以支持多标签推送 - 更新函数运行时镜像的标签策略 - 启用生产部署步骤并配置相关环境变量 - 修改部署脚本以使用动态镜像标签 --- .github/workflows/ci.yml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9390189..3e7ad44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,10 +115,15 @@ jobs: cp .github/settings.xml ~/.m2/settings.xml - name: Build and push server image run: | + echo "BUILD_VERSION=${{ github.run_number }}" >> $GITHUB_ENV + echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "FULL_VERSION=${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV mvn -B -Dmaven.test.skip=true clean package -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ - -Dquarkus.container-image.image=cjbi/flexmodel-server:latest \ + -Dquarkus.container-image.image=cjbi/flexmodel-server \ + -Dquarkus.container-image.tags=latest \ + -Dquarkus.container-image.additional-tags=${{ env.FULL_VERSION }},${{ env.BUILD_VERSION }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -140,10 +145,15 @@ jobs: cache-dependency-path: '**/pom.xml' - name: Build and push server native image run: | + echo "BUILD_VERSION=${{ github.run_number }}" >> $GITHUB_ENV + echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "FULL_VERSION=${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV mvn -B -Dmaven.test.skip=true clean package -Pnative -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ - -Dquarkus.container-image.image=cjbi/flexmodel-server-native:latest \ + -Dquarkus.container-image.image=cjbi/flexmodel-server-native \ + -Dquarkus.container-image.tags=latest \ + -Dquarkus.container-image.additional-tags=${{ env.FULL_VERSION }},${{ env.BUILD_VERSION }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -165,23 +175,35 @@ jobs: with: context: flexmodel-functions-runtime push: true - tags: cjbi/flexmodel-functions-runtime:latest + tags: | + cjbi/flexmodel-functions-runtime:latest + cjbi/flexmodel-functions-runtime:${{ github.run_number }} + cjbi/flexmodel-functions-runtime:${{ github.run_number }}-${{ github.sha }} + cjbi/flexmodel-functions-runtime:sha-${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max # deploy: +# name: Deploy to production # runs-on: ubuntu-latest -# needs: [ push-server-image, push-ui-image, push-functions-runtime-image ] +# needs: [ push-server-image, push-functions-runtime-image ] # steps: # - name: Deploy Docker Image # uses: appleboy/ssh-action@master +# env: +# IMAGE_TAG: ${{ github.run_number }} # with: # host: ${{ secrets.HOST }} # username: ${{ secrets.SSH_USER }} # port: ${{ secrets.SSH_PORT }} # key: ${{ secrets.SSH_KEY }} +# envs: IMAGE_TAG # command_timeout: 10m # script: | # cd /opt/flexmodel-quickstarts/docker-compose -# docker-compose pull flexmodel-server flexmodel-ui flexmodel-functions-runtime +# docker pull cjbi/flexmodel-server:${IMAGE_TAG} +# docker pull cjbi/flexmodel-functions-runtime:${IMAGE_TAG} +# docker tag cjbi/flexmodel-server:${IMAGE_TAG} cjbi/flexmodel-server:latest +# docker tag cjbi/flexmodel-functions-runtime:${IMAGE_TAG} cjbi/flexmodel-functions-runtime:latest # docker-compose up -d +# echo "Deployed version ${IMAGE_TAG}" From b0962a2486c6dede45db9e745162fb3e11b27f7b Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 14:43:00 +0800 Subject: [PATCH 08/12] =?UTF-8?q?feat(ci):=20=E6=9B=B4=E6=96=B0CI=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E4=BB=A5=E9=9B=86=E6=88=90UI=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E5=B9=B6=E6=94=B9=E8=BF=9B=E7=89=88=E6=9C=AC=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在主CI流程中添加flexmodel-ui镜像构建和推送任务 - 实现从VERSION文件读取基础版本号并与GitHub运行编号组合 - 更新服务器和函数运行时镜像标签策略为版本号加运行编号格式 - 重构部署任务以包含UI镜像的拉取和标记操作 - 添加对UI组件的手动工作流调度支持 - 升级Docker相关Action到最新版本并优化缓存配置 - 添加VERSION文件用于版本控制 --- .github/workflows/ci.yml | 108 ++++++++++++++++++++++++++++----------- VERSION | 1 + flexmodel-ui | 2 +- 3 files changed, 80 insertions(+), 31 deletions(-) create mode 100644 VERSION diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e7ad44..f9bdffa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -115,9 +115,10 @@ jobs: cp .github/settings.xml ~/.m2/settings.xml - name: Build and push server image run: | - echo "BUILD_VERSION=${{ github.run_number }}" >> $GITHUB_ENV + VERSION=$(cat VERSION | tr -d '[:space:]') + echo "BUILD_VERSION=${VERSION}.${{ github.run_number }}" >> $GITHUB_ENV echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "FULL_VERSION=${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "FULL_VERSION=${VERSION}.${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV mvn -B -Dmaven.test.skip=true clean package -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ @@ -145,9 +146,10 @@ jobs: cache-dependency-path: '**/pom.xml' - name: Build and push server native image run: | - echo "BUILD_VERSION=${{ github.run_number }}" >> $GITHUB_ENV + VERSION=$(cat VERSION | tr -d '[:space:]') + echo "BUILD_VERSION=${VERSION}.${{ github.run_number }}" >> $GITHUB_ENV echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "FULL_VERSION=${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + echo "FULL_VERSION=${VERSION}.${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV mvn -B -Dmaven.test.skip=true clean package -Pnative -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ @@ -163,6 +165,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 + - name: Read version + id: version + run: | + VERSION=$(cat VERSION | tr -d '[:space:]') + echo "tag=${VERSION}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "full=${VERSION}.${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Log in to Docker Hub @@ -177,33 +185,73 @@ jobs: push: true tags: | cjbi/flexmodel-functions-runtime:latest - cjbi/flexmodel-functions-runtime:${{ github.run_number }} - cjbi/flexmodel-functions-runtime:${{ github.run_number }}-${{ github.sha }} + cjbi/flexmodel-functions-runtime:${{ steps.version.outputs.tag }} + cjbi/flexmodel-functions-runtime:${{ steps.version.outputs.full }} cjbi/flexmodel-functions-runtime:sha-${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max -# deploy: -# name: Deploy to production -# runs-on: ubuntu-latest -# needs: [ push-server-image, push-functions-runtime-image ] -# steps: -# - name: Deploy Docker Image -# uses: appleboy/ssh-action@master -# env: -# IMAGE_TAG: ${{ github.run_number }} -# with: -# host: ${{ secrets.HOST }} -# username: ${{ secrets.SSH_USER }} -# port: ${{ secrets.SSH_PORT }} -# key: ${{ secrets.SSH_KEY }} -# envs: IMAGE_TAG -# command_timeout: 10m -# script: | -# cd /opt/flexmodel-quickstarts/docker-compose -# docker pull cjbi/flexmodel-server:${IMAGE_TAG} -# docker pull cjbi/flexmodel-functions-runtime:${IMAGE_TAG} -# docker tag cjbi/flexmodel-server:${IMAGE_TAG} cjbi/flexmodel-server:latest -# docker tag cjbi/flexmodel-functions-runtime:${IMAGE_TAG} cjbi/flexmodel-functions-runtime:latest -# docker-compose up -d -# echo "Deployed version ${IMAGE_TAG}" + push-ui-image: + name: Push UI docker image + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + submodules: 'recursive' + token: ${{ secrets.GITHUB_TOKEN }} + - name: Read version + id: version + run: | + VERSION=$(cat VERSION | tr -d '[:space:]') + echo "tag=${VERSION}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "full=${VERSION}.${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + - name: Log in to Docker Hub + uses: docker/login-action@v4 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Build and push UI image + uses: docker/build-push-action@v7 + with: + context: flexmodel-ui + push: true + tags: | + cjbi/flexmodel-ui:latest + cjbi/flexmodel-ui:${{ steps.version.outputs.tag }} + cjbi/flexmodel-ui:${{ steps.version.outputs.full }} + cjbi/flexmodel-ui:sha-${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + deploy: + name: Deploy to production + runs-on: ubuntu-latest + needs: [ push-server-image, push-functions-runtime-image, push-ui-image ] + steps: + - uses: actions/checkout@v5 + - name: Read version + id: version + run: echo "tag=$(cat VERSION | tr -d '[:space:]').${{ github.run_number }}" >> $GITHUB_OUTPUT + - name: Deploy Docker Image + uses: appleboy/ssh-action@master + env: + IMAGE_TAG: ${{ steps.version.outputs.tag }} + with: + host: ${{ secrets.HOST }} + username: ${{ secrets.SSH_USER }} + port: ${{ secrets.SSH_PORT }} + key: ${{ secrets.SSH_KEY }} + envs: IMAGE_TAG + command_timeout: 10m + script: | + cd /opt/flexmodel-quickstarts/docker-compose + docker pull cjbi/flexmodel-server:${IMAGE_TAG} + docker pull cjbi/flexmodel-functions-runtime:${IMAGE_TAG} + docker pull cjbi/flexmodel-ui:${IMAGE_TAG} + docker tag cjbi/flexmodel-server:${IMAGE_TAG} cjbi/flexmodel-server:latest + docker tag cjbi/flexmodel-functions-runtime:${IMAGE_TAG} cjbi/flexmodel-functions-runtime:latest + docker tag cjbi/flexmodel-ui:${IMAGE_TAG} cjbi/flexmodel-ui:latest + docker-compose up -d + echo "Deployed version ${IMAGE_TAG}" diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..8acdd82 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.0.1 diff --git a/flexmodel-ui b/flexmodel-ui index 644e6df..9898148 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit 644e6dfd7d91908551c9dc2da02b08c1c1c0096a +Subproject commit 98981485eff2ea00b2a9b5284dbb2f03fd549d63 From 6047a48fc8c138bed66da7ff9b413b51b559e91c Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 15:20:59 +0800 Subject: [PATCH 09/12] =?UTF-8?q?refactor(ci):=20=E4=BC=98=E5=8C=96GitHub?= =?UTF-8?q?=20Actions=E5=B7=A5=E4=BD=9C=E6=B5=81=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化构建版本变量设置,移除环境变量定义 - 更新容器镜像标签策略,将版本号直接附加到镜像名 - 添加基于完整提交哈希的镜像标签支持 - 注释掉生产环境部署步骤以进行重构 --- .github/workflows/ci.yml | 80 +++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 42 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9bdffa..143c0f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,15 +116,13 @@ jobs: - name: Build and push server image run: | VERSION=$(cat VERSION | tr -d '[:space:]') - echo "BUILD_VERSION=${VERSION}.${{ github.run_number }}" >> $GITHUB_ENV - echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "FULL_VERSION=${VERSION}.${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + BUILD_VERSION="${VERSION}.${{ github.run_number }}" + FULL_VERSION="${BUILD_VERSION}-$(git rev-parse --short HEAD)" mvn -B -Dmaven.test.skip=true clean package -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ - -Dquarkus.container-image.image=cjbi/flexmodel-server \ - -Dquarkus.container-image.tags=latest \ - -Dquarkus.container-image.additional-tags=${{ env.FULL_VERSION }},${{ env.BUILD_VERSION }} \ + -Dquarkus.container-image.image=cjbi/flexmodel-server:${BUILD_VERSION} \ + -Dquarkus.container-image.additional-tags=latest,${FULL_VERSION},sha-${{ github.sha }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -147,15 +145,13 @@ jobs: - name: Build and push server native image run: | VERSION=$(cat VERSION | tr -d '[:space:]') - echo "BUILD_VERSION=${VERSION}.${{ github.run_number }}" >> $GITHUB_ENV - echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - echo "FULL_VERSION=${VERSION}.${{ github.run_number }}-$(git rev-parse --short HEAD)" >> $GITHUB_ENV + BUILD_VERSION="${VERSION}.${{ github.run_number }}" + FULL_VERSION="${BUILD_VERSION}-$(git rev-parse --short HEAD)" mvn -B -Dmaven.test.skip=true clean package -Pnative -pl flexmodel-server -am \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ - -Dquarkus.container-image.image=cjbi/flexmodel-server-native \ - -Dquarkus.container-image.tags=latest \ - -Dquarkus.container-image.additional-tags=${{ env.FULL_VERSION }},${{ env.BUILD_VERSION }} \ + -Dquarkus.container-image.image=cjbi/flexmodel-server-native:${BUILD_VERSION} \ + -Dquarkus.container-image.additional-tags=latest,${FULL_VERSION},sha-${{ github.sha }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -225,33 +221,33 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - deploy: - name: Deploy to production - runs-on: ubuntu-latest - needs: [ push-server-image, push-functions-runtime-image, push-ui-image ] - steps: - - uses: actions/checkout@v5 - - name: Read version - id: version - run: echo "tag=$(cat VERSION | tr -d '[:space:]').${{ github.run_number }}" >> $GITHUB_OUTPUT - - name: Deploy Docker Image - uses: appleboy/ssh-action@master - env: - IMAGE_TAG: ${{ steps.version.outputs.tag }} - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.SSH_USER }} - port: ${{ secrets.SSH_PORT }} - key: ${{ secrets.SSH_KEY }} - envs: IMAGE_TAG - command_timeout: 10m - script: | - cd /opt/flexmodel-quickstarts/docker-compose - docker pull cjbi/flexmodel-server:${IMAGE_TAG} - docker pull cjbi/flexmodel-functions-runtime:${IMAGE_TAG} - docker pull cjbi/flexmodel-ui:${IMAGE_TAG} - docker tag cjbi/flexmodel-server:${IMAGE_TAG} cjbi/flexmodel-server:latest - docker tag cjbi/flexmodel-functions-runtime:${IMAGE_TAG} cjbi/flexmodel-functions-runtime:latest - docker tag cjbi/flexmodel-ui:${IMAGE_TAG} cjbi/flexmodel-ui:latest - docker-compose up -d - echo "Deployed version ${IMAGE_TAG}" +# deploy: +# name: Deploy to production +# runs-on: ubuntu-latest +# needs: [ push-server-image, push-functions-runtime-image, push-ui-image ] +# steps: +# - uses: actions/checkout@v5 +# - name: Read version +# id: version +# run: echo "tag=$(cat VERSION | tr -d '[:space:]').${{ github.run_number }}" >> $GITHUB_OUTPUT +# - name: Deploy Docker Image +# uses: appleboy/ssh-action@master +# env: +# IMAGE_TAG: ${{ steps.version.outputs.tag }} +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.SSH_USER }} +# port: ${{ secrets.SSH_PORT }} +# key: ${{ secrets.SSH_KEY }} +# envs: IMAGE_TAG +# command_timeout: 10m +# script: | +# cd /opt/flexmodel-quickstarts/docker-compose +# docker pull cjbi/flexmodel-server:${IMAGE_TAG} +# docker pull cjbi/flexmodel-functions-runtime:${IMAGE_TAG} +# docker pull cjbi/flexmodel-ui:${IMAGE_TAG} +# docker tag cjbi/flexmodel-server:${IMAGE_TAG} cjbi/flexmodel-server:latest +# docker tag cjbi/flexmodel-functions-runtime:${IMAGE_TAG} cjbi/flexmodel-functions-runtime:latest +# docker tag cjbi/flexmodel-ui:${IMAGE_TAG} cjbi/flexmodel-ui:latest +# docker-compose up -d +# echo "Deployed version ${IMAGE_TAG}" From 9cee463e855c4430469b4721371e307853e36987 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 15:27:09 +0800 Subject: [PATCH 10/12] =?UTF-8?q?fix(test):=20=E4=BF=AE=E6=AD=A3=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E4=B8=AD=E7=9A=84=E5=AE=9E=E4=BD=93=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E5=86=99=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将请求体中的"type"值从"entity"更改为"Entity" - 确保测试数据与实际API期望的格式一致 --- .../src/test/java/dev/flexmodel/rest/PermissionFilterTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flexmodel-server/src/test/java/dev/flexmodel/rest/PermissionFilterTest.java b/flexmodel-server/src/test/java/dev/flexmodel/rest/PermissionFilterTest.java index 3d6faa3..b910f0c 100644 --- a/flexmodel-server/src/test/java/dev/flexmodel/rest/PermissionFilterTest.java +++ b/flexmodel-server/src/test/java/dev/flexmodel/rest/PermissionFilterTest.java @@ -205,7 +205,7 @@ void viewOnlyDenyWrite() { .header("Authorization", testTokenHelper.getAuthorizationHeader()) .header("X-Test-Permissions", "modeling:Student:view") .contentType(ContentType.JSON) - .body("{\"type\":\"entity\",\"name\":\"Student\"}") + .body("{\"type\":\"Entity\",\"name\":\"Student\"}") .when() .put(Resources.ROOT_PATH + "/projects/dev_test/models/Student") .then() From 26569163a4cc95afc63e03495732e583a77c3c57 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 16:03:12 +0800 Subject: [PATCH 11/12] =?UTF-8?q?feat(build):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E6=98=BE=E7=A4=BA=E5=92=8C=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 CI 工作流中添加版本号变量输出和镜像标签 - 为 flexmodel-server 添加版本号配置属性和资源过滤 - 在全局资源配置中添加版本号字段 - 在 UI 侧边栏和关于页面中显示版本号信息 - 更新应用状态管理中的系统配置类型定义 --- .github/workflows/ci.yml | 10 ++++++++-- flexmodel-server/pom.xml | 15 +++++++++++++++ .../dev/flexmodel/common/FlexmodelConfig.java | 8 ++++++++ .../dev/flexmodel/settings/GlobalResource.java | 4 +++- .../src/main/resources/application.properties | 1 + .../dev/flexmodel/pages/PageAliasManagerTest.java | 5 +++++ .../dev/flexmodel/pages/PageDeployerTest.java | 5 +++++ flexmodel-ui | 2 +- 8 files changed, 46 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 143c0f4..02db804 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,10 +119,11 @@ jobs: BUILD_VERSION="${VERSION}.${{ github.run_number }}" FULL_VERSION="${BUILD_VERSION}-$(git rev-parse --short HEAD)" mvn -B -Dmaven.test.skip=true clean package -pl flexmodel-server -am \ + -Dflexmodel.version=${BUILD_VERSION} \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ -Dquarkus.container-image.image=cjbi/flexmodel-server:${BUILD_VERSION} \ - -Dquarkus.container-image.additional-tags=latest,${FULL_VERSION},sha-${{ github.sha }} \ + -Dquarkus.container-image.additional-tags=latest,${VERSION},${FULL_VERSION},sha-${{ github.sha }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -148,10 +149,11 @@ jobs: BUILD_VERSION="${VERSION}.${{ github.run_number }}" FULL_VERSION="${BUILD_VERSION}-$(git rev-parse --short HEAD)" mvn -B -Dmaven.test.skip=true clean package -Pnative -pl flexmodel-server -am \ + -Dflexmodel.version=${BUILD_VERSION} \ -Dquarkus.container-image.build=true \ -Dquarkus.container-image.push=true \ -Dquarkus.container-image.image=cjbi/flexmodel-server-native:${BUILD_VERSION} \ - -Dquarkus.container-image.additional-tags=latest,${FULL_VERSION},sha-${{ github.sha }} \ + -Dquarkus.container-image.additional-tags=latest,${VERSION},${FULL_VERSION},sha-${{ github.sha }} \ -Dquarkus.container-image.username=${{ secrets.DOCKER_USERNAME }} \ -Dquarkus.container-image.password=${{ secrets.DOCKER_PASSWORD }} @@ -166,6 +168,7 @@ jobs: run: | VERSION=$(cat VERSION | tr -d '[:space:]') echo "tag=${VERSION}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "ver=${VERSION}" >> $GITHUB_OUTPUT echo "full=${VERSION}.${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -181,6 +184,7 @@ jobs: push: true tags: | cjbi/flexmodel-functions-runtime:latest + cjbi/flexmodel-functions-runtime:${{ steps.version.outputs.ver }} cjbi/flexmodel-functions-runtime:${{ steps.version.outputs.tag }} cjbi/flexmodel-functions-runtime:${{ steps.version.outputs.full }} cjbi/flexmodel-functions-runtime:sha-${{ github.sha }} @@ -200,6 +204,7 @@ jobs: run: | VERSION=$(cat VERSION | tr -d '[:space:]') echo "tag=${VERSION}.${{ github.run_number }}" >> $GITHUB_OUTPUT + echo "ver=${VERSION}" >> $GITHUB_OUTPUT echo "full=${VERSION}.${{ github.run_number }}-${{ github.sha }}" >> $GITHUB_OUTPUT - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 @@ -215,6 +220,7 @@ jobs: push: true tags: | cjbi/flexmodel-ui:latest + cjbi/flexmodel-ui:${{ steps.version.outputs.ver }} cjbi/flexmodel-ui:${{ steps.version.outputs.tag }} cjbi/flexmodel-ui:${{ steps.version.outputs.full }} cjbi/flexmodel-ui:sha-${{ github.sha }} diff --git a/flexmodel-server/pom.xml b/flexmodel-server/pom.xml index d406ed6..e872c06 100644 --- a/flexmodel-server/pom.xml +++ b/flexmodel-server/pom.xml @@ -11,6 +11,7 @@ flexmodel-server true + dev @@ -137,6 +138,20 @@ + + maven-resources-plugin + + + @ + + + + src/main/resources + true + + + + dev.flexmodel flexmodel-maven-plugin diff --git a/flexmodel-server/src/main/java/dev/flexmodel/common/FlexmodelConfig.java b/flexmodel-server/src/main/java/dev/flexmodel/common/FlexmodelConfig.java index 99b0c83..e8e19d1 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/common/FlexmodelConfig.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/common/FlexmodelConfig.java @@ -71,6 +71,14 @@ default String pagesUrlTemplate() { @WithDefault("${quarkus.http.root-path}") String apiRootPath(); + /** + * 构建版本号,由 CI 在构建时通过 Maven 资源过滤注入(-Dflexmodel.version=...)。 + * 本地开发未指定时为 "dev"。 + */ + @WithName("version") + @WithDefault("dev") + String version(); + @WithName("jwt") JwtConfig jwt(); diff --git a/flexmodel-server/src/main/java/dev/flexmodel/settings/GlobalResource.java b/flexmodel-server/src/main/java/dev/flexmodel/settings/GlobalResource.java index 0e7c2ce..904f832 100644 --- a/flexmodel-server/src/main/java/dev/flexmodel/settings/GlobalResource.java +++ b/flexmodel-server/src/main/java/dev/flexmodel/settings/GlobalResource.java @@ -53,6 +53,7 @@ public class GlobalResource { @SchemaProperty(name = "routingMode", description = "路由模式:path 为路径模式,subdomain 为子域名模式"), @SchemaProperty(name = "edgeUrlTemplate", description = "边缘函数调用 URL,由 routingMode + projectBaseDomain 自动推导"), @SchemaProperty(name = "pagesUrlTemplate", description = "Pages 站点 URL,由 routingMode + projectBaseDomain 自动推导"), + @SchemaProperty(name = "version", description = "构建版本号"), } ) ) @@ -69,7 +70,8 @@ public Map getProfile() { "projectBaseDomain", config.projectBaseDomain().orElse(""), "routingMode", config.isSubdomainRouting() ? "subdomain" : "path", "edgeUrlTemplate", config.edgeUrlTemplate(), - "pagesUrlTemplate", config.pagesUrlTemplate() + "pagesUrlTemplate", config.pagesUrlTemplate(), + "version", config.version() ); } diff --git a/flexmodel-server/src/main/resources/application.properties b/flexmodel-server/src/main/resources/application.properties index 1aa85dd..3624944 100644 --- a/flexmodel-server/src/main/resources/application.properties +++ b/flexmodel-server/src/main/resources/application.properties @@ -3,6 +3,7 @@ quarkus.virtual-threads.enabled=true quarkus.swagger-ui.always-include=true quarkus.http.root-path=/api quarkus.http.limits.max-body-size=100M +flexmodel.version=@flexmodel.version@ quarkus.log.category."dev.flexmodel".level=INFO # File logging — daily rotation, retain 7 days quarkus.log.file.enable=true diff --git a/flexmodel-server/src/test/java/dev/flexmodel/pages/PageAliasManagerTest.java b/flexmodel-server/src/test/java/dev/flexmodel/pages/PageAliasManagerTest.java index da5dc0b..41283e5 100644 --- a/flexmodel-server/src/test/java/dev/flexmodel/pages/PageAliasManagerTest.java +++ b/flexmodel-server/src/test/java/dev/flexmodel/pages/PageAliasManagerTest.java @@ -220,6 +220,11 @@ public java.util.Optional projectBaseDomain() { @Override public String apiRootPath() { return "/api"; } + @Override + public String version() { + return "dev"; + } + @Override public JwtConfig jwt() { return null; } } diff --git a/flexmodel-server/src/test/java/dev/flexmodel/pages/PageDeployerTest.java b/flexmodel-server/src/test/java/dev/flexmodel/pages/PageDeployerTest.java index 3a57622..3bb52c4 100644 --- a/flexmodel-server/src/test/java/dev/flexmodel/pages/PageDeployerTest.java +++ b/flexmodel-server/src/test/java/dev/flexmodel/pages/PageDeployerTest.java @@ -249,6 +249,11 @@ public java.util.Optional projectBaseDomain() { @Override public String apiRootPath() { return "/api"; } + @Override + public String version() { + return "dev"; + } + @Override public JwtConfig jwt() { return null; } } diff --git a/flexmodel-ui b/flexmodel-ui index 9898148..85a36d3 160000 --- a/flexmodel-ui +++ b/flexmodel-ui @@ -1 +1 @@ -Subproject commit 98981485eff2ea00b2a9b5284dbb2f03fd549d63 +Subproject commit 85a36d39d82ac58ddd2b156cb4a3f2ab4aa9f389 From 486c56a7144ad0e251f973df95bc7460d14f14a3 Mon Sep 17 00:00:00 2001 From: Cheng Jinbao Date: Mon, 17 Aug 2026 17:04:56 +0800 Subject: [PATCH 12/12] =?UTF-8?q?chore(version):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将版本号从 0.0.1 更改为 v0.0.1 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 8acdd82..45c7a58 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1 +v0.0.1