优化动态表单

This commit is contained in:
zhouhao
2018-07-02 18:05:07 +08:00
parent a0ef2f2e9b
commit 75c7af8b12
20 changed files with 477 additions and 63 deletions

View File

@@ -4,6 +4,8 @@ import org.hibernate.validator.constraints.NotBlank;
import org.hswebframework.web.commons.entity.GenericEntity;
import org.hswebframework.web.validator.group.CreateGroup;
import java.util.List;
/**
* 动态表单 实体
*
@@ -195,4 +197,9 @@ public interface DynamicFormColumnEntity extends GenericEntity<String> {
Long getSortIndex();
void setSortIndex(Long sortIndex);
List<String> getValidator();
void setValidator(List<String> validator);
}

View File

@@ -4,6 +4,8 @@ import lombok.Getter;
import lombok.Setter;
import org.hswebframework.web.commons.entity.SimpleGenericEntity;
import java.util.List;
/**
* 动态表单
*
@@ -13,29 +15,31 @@ import org.hswebframework.web.commons.entity.SimpleGenericEntity;
@Setter
public class SimpleDynamicFormColumnEntity extends SimpleGenericEntity<String> implements DynamicFormColumnEntity {
//表单ID
private String formId;
private String formId;
//字段名称
private String name;
private String name;
//数据库列
private String columnName;
private String columnName;
//备注
private String describe;
private String describe;
//别名
private String alias;
private String alias;
//java类型
private String javaType;
private String javaType;
//jdbc类型
private String jdbcType;
private String jdbcType;
//数据类型
private String dataType;
private String dataType;
//长度
private Integer length;
private Integer length;
//精度
private Integer precision;
private Integer precision;
//小数点位数
private Integer scale;
private Integer scale;
//数据字典配置
private String dictConfig;
private String dictConfig;
//序号
private Long sortIndex;
private Long sortIndex;
//验证器配置
private List<String> validator;
}

View File

@@ -1,6 +1,7 @@
package org.hswebframework.web.service.form;
import org.hswebframework.ezorm.core.OptionConverter;
import org.hswebframework.ezorm.core.ValueConverter;
import org.hswebframework.web.entity.form.DictConfig;
import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
@@ -10,4 +11,6 @@ import org.hswebframework.web.entity.form.DynamicFormColumnEntity;
*/
public interface OptionalConvertBuilder {
OptionConverter build(DictConfig dictConfig);
ValueConverter buildValueConverter(DictConfig dictConfig);
}

View File

@@ -4,7 +4,9 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.hswebframework.ezorm.core.ObjectWrapperFactory;
import org.hswebframework.ezorm.core.Trigger;
import org.hswebframework.ezorm.core.ValidatorFactory;
import org.hswebframework.ezorm.core.ValueConverter;
import org.hswebframework.ezorm.rdb.RDBDatabase;
import org.hswebframework.ezorm.rdb.meta.Correlation;
@@ -33,6 +35,7 @@ import org.hswebframework.web.service.form.OptionalConvertBuilder;
import org.hswebframework.web.service.form.initialize.ColumnInitializeContext;
import org.hswebframework.web.service.form.initialize.DynamicFormInitializeCustomer;
import org.hswebframework.web.service.form.initialize.TableInitializeContext;
import org.hswebframework.web.service.form.simple.dict.EnumDictValueConverter;
import org.hswebframework.web.validator.group.CreateGroup;
import org.hswebframework.web.validator.group.UpdateGroup;
import org.springframework.beans.factory.annotation.Autowired;
@@ -78,6 +81,12 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
@Autowired(required = false)
private List<DynamicFormInitializeCustomer> initializeCustomers;
@Autowired
private ValidatorFactory validatorFactory;
@Autowired(required = false)
private ObjectWrapperFactory objectWrapperFactory;
@Override
protected IDGenerator<String> getIDGenerator() {
return IDGenerator.MD5;
@@ -355,6 +364,8 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
? databaseRepository.getDefaultDatabase()
: databaseRepository.getDatabase(form.getDataSourceId());
RDBTableMetaData metaData = buildTable(database, form, columns);
metaData.setValidator(validatorFactory.createValidator(metaData));
try {
if (!database.getMeta().getParser().tableExists(metaData.getName())) {
database.createTable(metaData);
@@ -433,6 +444,7 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
metaData.setAlias(form.getAlias());
metaData.setCorrelations(buildCorrelations(form.getCorrelations()));
buildTrigger(form.getTriggers()).forEach(metaData::on);
columns.forEach(column -> {
RDBColumnMetaData columnMeta = new RDBColumnMetaData();
columnMeta.setName(column.getColumnName());
@@ -444,6 +456,9 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
columnMeta.setJdbcType(JDBCType.valueOf(column.getJdbcType()));
columnMeta.setJavaType(getJavaType(column.getJavaType()));
columnMeta.setProperties(column.getProperties() == null ? new HashMap<>() : column.getProperties());
if (!CollectionUtils.isEmpty(column.getValidator())) {
columnMeta.setValidator(new HashSet<>(column.getValidator()));
}
if (StringUtils.isEmpty(column.getDataType())) {
Dialect dialect = database.getMeta().getDialect();
columnMeta.setDataType(dialect.buildDataType(columnMeta));
@@ -462,6 +477,9 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
customColumnSetting(database, form, metaData, column, columnMeta);
metaData.addColumn(columnMeta);
});
if (objectWrapperFactory != null) {
metaData.setObjectWrapper(objectWrapperFactory.createObjectWrapper(metaData));
}
customTableSetting(database, form, metaData);
//没有主键并且没有id字段
if (metaData.getColumns().stream().noneMatch(RDBColumnMetaData::isPrimaryKey) && metaData.findColumn("id") == null) {
@@ -470,6 +488,7 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
primaryKey.setDataType(dialect.buildDataType(primaryKey));
metaData.addColumn(primaryKey);
}
return metaData;
}
@@ -551,9 +570,8 @@ public class SimpleDynamicFormService extends GenericEntityService<DynamicFormEn
.values()
.contains(javaType) || javaType != Map.class || javaType != List.class;
if (EnumDict.class.isAssignableFrom(javaType)) {
// TODO: 18-4-25
if (javaType.isEnum() && EnumDict.class.isAssignableFrom(javaType)) {
return new EnumDictValueConverter<EnumDict>(() -> (List) Arrays.asList(javaType.getEnumConstants()));
}
switch (jdbcType) {
case BLOB:

View File

@@ -1,6 +1,7 @@
package org.hswebframework.web.service.form.simple.dict;
import org.hswebframework.ezorm.core.OptionConverter;
import org.hswebframework.ezorm.core.ValueConverter;
import org.hswebframework.web.entity.form.DictConfig;
import org.hswebframework.web.service.form.OptionalConvertBuilder;
import org.springframework.beans.factory.annotation.Autowired;
@@ -31,4 +32,16 @@ public class DefaultOptionalConvertBuilder implements OptionalConvertBuilder {
.map(strategy -> strategy.build(dictConfig))
.orElse(null);
}
@Override
public ValueConverter buildValueConverter(DictConfig dictConfig) {
if(CollectionUtils.isEmpty(strategies)){
return null;
}
return strategies.stream()
.filter(strategy -> strategy.support(dictConfig.getType()))
.findFirst()
.map(strategy -> strategy.buildValueConverter(dictConfig))
.orElse(null);
}
}

View File

@@ -3,6 +3,7 @@ package org.hswebframework.web.service.form.simple.dict;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.hswebframework.ezorm.core.OptionConverter;
import org.hswebframework.ezorm.core.ValueConverter;
import org.hswebframework.web.dict.DictDefineRepository;
import org.hswebframework.web.dict.EnumDict;
import org.hswebframework.web.entity.form.DictConfig;
@@ -35,9 +36,7 @@ public class DictionaryOptionalConvertBuilderStrategy implements OptionalConvert
String dictId = conf.getString("dictId");
String fieldName = conf.getString("fieldName");
String sppliter = conf.getString("sppliter");
String writeObject = conf.getString("writeObject");
EnumDictOptionConverter<EnumDict<Object>> converter = new EnumDictOptionConverter<>(() -> dictDefineRepository.getDefine(dictId).getItems(), fieldName);
converter.setWriteObject(!"false".equalsIgnoreCase(writeObject));
@@ -48,4 +47,15 @@ public class DictionaryOptionalConvertBuilderStrategy implements OptionalConvert
return converter;
}
@Override
public ValueConverter buildValueConverter(DictConfig dictConfig) {
JSONObject conf = JSON.parseObject(dictConfig.getConfig());
String dictId = conf.getString("dictId");
EnumDictValueConverter<EnumDict<Object>> converter =
new EnumDictValueConverter<>(() -> dictDefineRepository.getDefine(dictId).getItems());
return converter;
}
}

View File

@@ -1,6 +1,7 @@
package org.hswebframework.web.service.form.simple.dict;
import org.hswebframework.ezorm.core.OptionConverter;
import org.hswebframework.ezorm.core.ValueConverter;
import org.hswebframework.web.entity.form.DictConfig;
/**
@@ -15,10 +16,12 @@ public interface OptionalConvertBuilderStrategy {
boolean support(String type);
/**
* 根据配置创建转换器
* 根据配置创建选项转换器
*
* @param dictConfig 配置内容
* @return 转换器对象
*/
OptionConverter build(DictConfig dictConfig);
ValueConverter buildValueConverter(DictConfig dictConfig);
}

View File

@@ -1,47 +1,25 @@
package org.hswebframework.web.service.form.simple.validator;
import org.hibernate.validator.constraints.NotBlank;
import org.hswebframework.ezorm.core.Validator;
import org.hswebframework.web.Maps;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.commons.bean.ValidateBean;
import org.hswebframework.web.proxy.Proxy;
import org.hswebframework.web.validator.group.CreateGroup;
import org.hswebframework.web.validator.group.UpdateGroup;
import javax.validation.GroupSequence;
import java.util.Arrays;
import java.util.HashMap;
import java.util.function.Supplier;
public class DynamicBeanValidator implements Validator {
protected Supplier<ValidateBean> beanSupplier;
public static void main(String[] args) {
MapBean bean = Proxy.create(MapBean.class)
.addField("private String name;", NotBlank.class, Maps.<String, Object>buildMap()
.put("message", "测试")
.put("groups", new Class[]{CreateGroup.class})
.get())
.addMethod("public String getName(){return this.name;}")
.addMethod("public java.util.Set keySet(){return new java.util.HashSet(java.util.Arrays.asList(new String[]{\"name\"}));}")
.addMethod("public void setName(String name){ this.name=name;}")
.addMethod("public void setProperty(String name,Object value){ this.name=(String)value;}")
.addMethod("public Object getProperty(String name){ return this.name;}")
.newInstance();
bean.setProperty("name", "test");
System.out.println((MapBean) bean.tryValidate(CreateGroup.class));
public DynamicBeanValidator(Supplier<ValidateBean> beanSupplier) {
this.beanSupplier = beanSupplier;
}
@Override
public boolean validate(Object o, Operation operation) {
public boolean validate(Object source, Operation operation) {
ValidateBean validateBean = beanSupplier.get();
FastBeanCopier.copy(o, validateBean);
FastBeanCopier.copy(source, validateBean);
if (operation == Operation.INSERT) {
validateBean.tryValidate(CreateGroup.class);
} else {

View File

@@ -1,25 +1,52 @@
package org.hswebframework.web.service.form.simple.validator;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import javassist.CtField;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.MemberValue;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.ezorm.core.Validator;
import org.hswebframework.ezorm.core.ValidatorFactory;
import org.hswebframework.ezorm.core.meta.ColumnMetaData;
import org.hswebframework.ezorm.core.meta.TableMetaData;
import org.hswebframework.utils.StringUtils;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.proxy.Proxy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
import static org.hswebframework.web.proxy.Proxy.createMemberValue;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class DynamicBeanValidatorFactory implements ValidatorFactory {
@Autowired
private List<JSR303AnnotationParserStrategy> strategies;
private String createSetPropertyCode(TableMetaData tableMetaData) {
StringBuilder builder = new StringBuilder();
builder.append("public void setProperty(String property,Object value){");
builder.append("public void setProperty(String property,Object value){\n");
int index = 0;
for (ColumnMetaData column : tableMetaData.getColumns()) {
String propertyName = column.getAlias();
Class type = column.getJavaType();
if (index++ > 0) {
builder.append("\nelse ");
}
builder.append("if(property.intern()==\"")
.append(propertyName)
.append("\"||property.intern()==\"")
@@ -29,38 +56,128 @@ public class DynamicBeanValidatorFactory implements ValidatorFactory {
.append("((").append(type.getName()).append(")")
.append("org.hswebframework.web.bean.FastBeanCopier.DEFAULT_CONVERT.convert(value,")
.append(type.getName())
.append(",null))")
.append(".class,null));")
.append("\n}");
}
builder.append("}");
return builder.toString();
}
private String createGetPropertyCode(TableMetaData tableMetaData) {
StringBuilder builder = new StringBuilder();
int index = 0;
builder.append("public Object getProperty(String property){\n");
for (ColumnMetaData column : tableMetaData.getColumns()) {
String propertyName = column.getAlias();
if (index++ > 0) {
builder.append("\nelse ");
}
builder.append("if(property.intern()==\"")
.append(propertyName)
.append("\"||property.intern()==\"")
.append(column.getName())
.append("\"){\n")
.append("return this.get")
.append(StringUtils.toUpperCaseFirstOne(propertyName))
.append("();")
.append("\n}");
}
builder.append("\nreturn null;\n}");
return builder.toString();
}
protected List<JSR303AnnotationInfo> createValidatorAnnotation(Set<String> config) {
if (CollectionUtils.isEmpty(config)) {
return Collections.emptyList();
}
return config.stream()
.map(this::createValidatorAnnotation)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
protected JSR303AnnotationInfo createValidatorAnnotation(String config) {
//JSON
if (config.startsWith("{")) {
JSONObject jsonConfig = JSON.parseObject(config);
String type = jsonConfig.getString("type");
return strategies.stream().filter(strategy -> strategy.support(type))
.findFirst()
.map(strategy -> strategy.parse(jsonConfig))
.orElse(null);
}
return null;
}
@Override
public Validator createValidator(TableMetaData tableMetaData) {
StringBuilder builder = new StringBuilder();
Proxy<MapBean> proxy = Proxy.create(MapBean.class);
proxy.addField("private java.util.Map proxy;")
.addMethod("public java.util.Map getProxy(){return this.proxy;};")
.addMethod("public org.hswebframework.web.service.form.simple.validator.MapBean setProxy(java.util.Map proxy){ this.proxy=proxy; return this;};");
StringBuilder keySet = new StringBuilder("public java.util.Set keySet(){\n return new java.util.HashSet(java.util.Arrays.asList(new String[]{");
int index = 0;
for (ColumnMetaData column : tableMetaData.getColumns()) {
String propertyName = column.getAlias();
Class type = column.getJavaType();
String typeName = type.getName();
proxy.addField("private " + type.getName() + " " + propertyName + ";");
proxy.addField("public void set " + StringUtils.toUpperCaseFirstOne(propertyName) + "(" + typeName + " " + propertyName + "){\n" +
if (index++ > 0) {
keySet.append(",");
}
keySet.append("\"")
.append(propertyName)
.append("\"");
proxy.custom(ctClass -> {
try {
CtField ctField = CtField.make("private " + type.getName() + " " + propertyName + ";", ctClass);
List<JSR303AnnotationInfo> jsr303 = createValidatorAnnotation(column.getValidator());
//添加注解
if (!CollectionUtils.isEmpty(jsr303)) {
ConstPool constPool = ctClass.getClassFile().getConstPool();
AnnotationsAttribute attributeInfo = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
for (JSR303AnnotationInfo jsr303AnnotationInfo : jsr303) {
Class<? extends java.lang.annotation.Annotation> jsr303Ann = jsr303AnnotationInfo.getAnnotation();
Annotation ann = new javassist.bytecode.annotation.Annotation(jsr303Ann.getName(), constPool);
if (!CollectionUtils.isEmpty(jsr303AnnotationInfo.getProperties())) {
jsr303AnnotationInfo.getProperties().forEach((key, value) -> {
MemberValue memberValue = createMemberValue(value, constPool);
if (memberValue != null) {
ann.addMemberValue(key, memberValue);
}
});
}
attributeInfo.addAnnotation(ann);
}
ctField.getFieldInfo().addAttribute(attributeInfo);
}
ctClass.addField(ctField);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
proxy.addMethod("public void set" + StringUtils.toUpperCaseFirstOne(propertyName) + "(" + typeName + " " + propertyName + "){\n" +
"this." + propertyName + "=" + propertyName + ";\n" +
"\n};");
proxy.addField("public " + typeName + " get " + StringUtils.toUpperCaseFirstOne(propertyName) + "(){\n" +
proxy.addMethod("public " + typeName + " get" + StringUtils.toUpperCaseFirstOne(propertyName) + "(){\n" +
"return this." + propertyName + ";\n" +
"\n};");
}
proxy.addMethod(createSetPropertyCode(tableMetaData));
return null;
keySet.append("}));\n}");
proxy.addMethod(keySet.toString());
proxy.addMethod(createSetPropertyCode(tableMetaData));
proxy.addMethod(createGetPropertyCode(tableMetaData));
//尝试一下能否创建实例
MapBean mapBean = proxy.newInstance();
Assert.notNull(mapBean, "创建验证器失败!");
return new DynamicBeanValidator(proxy::newInstance);
}
}

View File

@@ -0,0 +1,14 @@
package org.hswebframework.web.service.form.simple.validator;
import lombok.Getter;
import lombok.Setter;
import java.util.Map;
@Setter
@Getter
public class JSR303AnnotationInfo {
private Class<? extends java.lang.annotation.Annotation> annotation;
private Map<String, Object> properties;
}

View File

@@ -0,0 +1,14 @@
package org.hswebframework.web.service.form.simple.validator;
import java.util.Map;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
public interface JSR303AnnotationParserStrategy {
boolean support(String type);
JSR303AnnotationInfo parse(Map<String, Object> configMap);
}

View File

@@ -0,0 +1,109 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.bean.FastBeanCopier;
import org.hswebframework.web.service.form.simple.validator.JSR303AnnotationInfo;
import org.hswebframework.web.service.form.simple.validator.JSR303AnnotationParserStrategy;
import org.hswebframework.web.validator.group.CreateGroup;
import org.hswebframework.web.validator.group.UpdateGroup;
import org.springframework.util.CollectionUtils;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Slf4j
public abstract class AbstractStrategy implements JSR303AnnotationParserStrategy {
private List<PropertyMapping> propertyMappings = new ArrayList<>();
public AbstractStrategy() {
propertyMappings.add(PropertyMapping.of("message", String.class));
}
public void addPropertyMapping(PropertyMapping mapping) {
propertyMappings.add(mapping);
}
protected String getTypeString() {
return getAnnotationType().getSimpleName();
}
protected abstract Class<? extends Annotation> getAnnotationType();
@Getter
@Setter
public static class PropertyMapping<T> {
private String name;
private Class<T> type;
public static <T> PropertyMapping<T> of(String name, Class<T> type) {
PropertyMapping mapping = new PropertyMapping<>();
mapping.name = name;
mapping.type = type;
return mapping;
}
public static <T> PropertyMapping<T> of(String name, Class<T> type, Function<Object, T> converter) {
PropertyMapping mapping = new PropertyMapping<>();
mapping.name = name;
mapping.type = type;
mapping.converter = converter;
return mapping;
}
private Function<Object, T> converter = source -> FastBeanCopier.DEFAULT_CONVERT.convert(source, type, null);
}
@Override
public boolean support(String type) {
return type != null && (getTypeString().equalsIgnoreCase(type));
}
@Override
public JSR303AnnotationInfo parse(Map<String, Object> configMap) {
JSR303AnnotationInfo info = new JSR303AnnotationInfo();
info.setAnnotation(getAnnotationType());
Map<String, Object> properties = new HashMap<>();
propertyMappings.forEach(mapping -> {
Object value = mapping.getConverter().apply(configMap.get(mapping.getName()));
if (null != value) {
properties.put(mapping.getName(), value);
}
});
List<Object> groups = new JSONObject(configMap).getJSONArray("groups");
if (!CollectionUtils.isEmpty(groups)) {
properties.put("groups", groups.stream().map(obj -> {
if ("create".equals(obj)) {
return CreateGroup.class;
} else if ("update".equals(obj)) {
return UpdateGroup.class;
} else {
try {
return Class.forName(String.valueOf(obj));
} catch (ClassNotFoundException e) {
return CreateGroup.class;
}
}
}).toArray());
}
info.setProperties(properties);
return info;
}
}

View File

@@ -0,0 +1,28 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.springframework.stereotype.Component;
import javax.validation.constraints.Pattern;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class EmailStrategy extends AbstractStrategy {
public EmailStrategy() {
addPropertyMapping(PropertyMapping.of("regexp", String.class));
}
@Override
protected Class<Email> getAnnotationType() {
return Email.class;
}
}

View File

@@ -0,0 +1,27 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Length;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class LengthStrategy extends AbstractStrategy {
public LengthStrategy() {
addPropertyMapping(PropertyMapping.of("min", int.class));
addPropertyMapping(PropertyMapping.of("max", int.class));
}
@Override
protected Class<Length> getAnnotationType() {
return Length.class;
}
}

View File

@@ -0,0 +1,21 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class NotBlankStrategy extends AbstractStrategy {
@Override
protected Class<NotBlank> getAnnotationType() {
return NotBlank.class;
}
}

View File

@@ -0,0 +1,20 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.validation.constraints.NotNull;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class NotNullStrategy extends AbstractStrategy {
@Override
protected Class<NotNull> getAnnotationType() {
return NotNull.class;
}
}

View File

@@ -0,0 +1,26 @@
package org.hswebframework.web.service.form.simple.validator.jsr303;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import org.springframework.stereotype.Component;
/**
* @author zhouhao
* @since 3.0.0-RC
*/
@Component
@Slf4j
public class RangeStrategy extends AbstractStrategy {
public RangeStrategy() {
addPropertyMapping(PropertyMapping.of("min", int.class));
addPropertyMapping(PropertyMapping.of("max", int.class));
}
@Override
protected Class<Range> getAnnotationType() {
return Range.class;
}
}

View File

@@ -19,6 +19,7 @@
<result property="dictConfig" column="dict_config" javaType="String" jdbcType="CLOB"/>
<result property="sortIndex" column="sort_index" javaType="Long" jdbcType="DECIMAL"/>
<result property="properties" column="properties" javaType="java.util.Map" jdbcType="CLOB"/>
<result property="validator" column="validator" javaType="java.util.List" jdbcType="CLOB"/>
</resultMap>
<!--用于动态生成sql所需的配置-->

View File

@@ -54,7 +54,7 @@ function install(context) {
.addColumn().name("properties").alias("properties").comment("其他配置").jdbcType(java.sql.JDBCType.CLOB).commit()
.addColumn().name("dict_config").alias("dictConfig").comment("字典配置").jdbcType(java.sql.JDBCType.CLOB).commit()
.addColumn().name("sort_index").alias("sortIndex").comment("排序序号").jdbcType(java.sql.JDBCType.DECIMAL).length(32, 0).commit()
.addColumn().name("validator").alias("validator").comment("验证器配置").jdbcType(java.sql.JDBCType.CLOB).commit()
.comment("动态表单列").commit();
database.createOrAlter("s_dyn_form_log")

View File

@@ -15,6 +15,7 @@ import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Array;
import java.sql.JDBCType;
import java.sql.SQLException;
import java.util.Arrays;
@@ -65,7 +66,7 @@ public class SimpleDynamicFormServiceTest extends SimpleWebApplicationTests {
column_name.setJavaType("string");
column_name.setJdbcType(JDBCType.VARCHAR.getName());
column_name.setLength(32);
column_name.setValidator(Arrays.asList("{\"type\":\"NotBlank\",\"groups\":[\"create\"],\"message\":\"姓名不能为空\"}"));
DynamicFormColumnEntity column_age = entityFactory.newInstance(DynamicFormColumnEntity.class);
column_age.setName("年龄");
column_age.setColumnName("age");
@@ -87,7 +88,7 @@ public class SimpleDynamicFormServiceTest extends SimpleWebApplicationTests {
dynamicFormOperationService.insert(form.getId(), new HashMap<String, Object>() {
{
put("name", "张三");
// put("name", "张三");
put("age", 10);
}
});