feat: 提供更多配置项,减轻负担
This commit is contained in:
parent
da892f6bda
commit
2722a86949
@ -13,14 +13,9 @@ import java.lang.annotation.*;
|
||||
public @interface Properties {
|
||||
|
||||
/**
|
||||
* 需要映射的key
|
||||
* @return 键们
|
||||
* 属性们
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String[] keys();
|
||||
|
||||
/**
|
||||
* 需要映射的标题
|
||||
* @return 标题们
|
||||
*/
|
||||
String[] titles();
|
||||
Property[] value();
|
||||
}
|
||||
|
@ -9,13 +9,22 @@ import java.lang.annotation.*;
|
||||
*
|
||||
* @author wangyu
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Repeatable(Properties.class)
|
||||
public @interface Property {
|
||||
|
||||
/**
|
||||
* 手动指定key,用于覆盖模式
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String key() default "";
|
||||
|
||||
/**
|
||||
* 显示标题
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
@AliasFor("title")
|
||||
@ -23,6 +32,7 @@ public @interface Property {
|
||||
|
||||
/**
|
||||
* 显示标题(别名)
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
@AliasFor("value")
|
||||
@ -30,19 +40,36 @@ public @interface Property {
|
||||
|
||||
/**
|
||||
* 描述
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String description() default "";
|
||||
|
||||
/**
|
||||
* 被继承的,用于父类,自动拼接名称
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
boolean inherited() default false;
|
||||
|
||||
/**
|
||||
* 是否只读
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
boolean readonly() default false;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
int order() default 0;
|
||||
|
||||
/**
|
||||
* 分组
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String group() default "";
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.flyfish.framework.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Repeatable(PropertyGroups.class)
|
||||
public @interface PropertyGroup {
|
||||
|
||||
/**
|
||||
* 分组名称
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 分组编码
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String code();
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.flyfish.framework.annotations;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 属性组定义
|
||||
* @author wangyu
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface PropertyGroups {
|
||||
|
||||
PropertyGroup[] value();
|
||||
}
|
@ -60,7 +60,10 @@ public final class DataUtils {
|
||||
return IntStream.range(0, Math.min(keys.length, names.length))
|
||||
.boxed()
|
||||
.reduce(new ArrayList<>(), (result, index) -> {
|
||||
result.add(mapper.apply(keys[index], names[index]));
|
||||
R mapped = mapper.apply(keys[index], names[index]);
|
||||
if (null != mapped) {
|
||||
result.add(mapped);
|
||||
}
|
||||
return result;
|
||||
}, (a, b) -> a);
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.flyfish.framework.beans.meta;
|
||||
|
||||
import com.flyfish.framework.annotations.PropertyGroups;
|
||||
import com.flyfish.framework.bean.Result;
|
||||
import com.flyfish.framework.beans.resolver.DynamicRestBeanResolver;
|
||||
import com.flyfish.framework.domain.base.Vo;
|
||||
import com.flyfish.framework.utils.StringFormats;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.ClassUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
@ -13,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -76,9 +79,22 @@ public class BeanController {
|
||||
if (!Vo.class.equals(annotation.listViewClass())) {
|
||||
info.setColumns(BeanProperty.from(annotation.listViewClass()));
|
||||
}
|
||||
if (ArrayUtils.isNotEmpty(annotation.meta())) {
|
||||
Arrays.stream(annotation.meta()).forEach(meta -> {
|
||||
String[] kv = meta.split("=");
|
||||
if (kv.length == 2) {
|
||||
info.set(kv[0], kv[1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
info.setCode(StringFormats.camel2Line(ClassUtils.getShortClassName(clazz)));
|
||||
}
|
||||
if (clazz.isAnnotationPresent(PropertyGroups.class)) {
|
||||
PropertyGroups groups = clazz.getAnnotation(PropertyGroups.class);
|
||||
info.setGroups(Arrays.stream(groups.value()).map(group -> new BeanPropertyGroup(group.name(), group.code()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
info.setProperties(BeanProperty.from(clazz));
|
||||
return info;
|
||||
}
|
||||
|
@ -1,11 +1,14 @@
|
||||
package com.flyfish.framework.beans.meta;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* bean的属性们
|
||||
*
|
||||
* @author wangyu
|
||||
*/
|
||||
@Data
|
||||
@ -17,6 +20,12 @@ public class BeanInfo {
|
||||
// bean的显示名
|
||||
private String name;
|
||||
|
||||
// bean的类型
|
||||
private String type;
|
||||
|
||||
// 分组们
|
||||
private List<BeanPropertyGroup> groups;
|
||||
|
||||
// bean的属性们
|
||||
private List<BeanProperty> properties;
|
||||
|
||||
@ -25,4 +34,19 @@ public class BeanInfo {
|
||||
|
||||
// 表格查询属性
|
||||
private List<BeanProperty> search;
|
||||
|
||||
/**
|
||||
* 自由设置值
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void set(String key, Object value) {
|
||||
try {
|
||||
Objects.requireNonNull(BeanUtils.getPropertyDescriptor(this.getClass(), key))
|
||||
.getWriteMethod().invoke(this, value);
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import com.flyfish.framework.annotations.Properties;
|
||||
import com.flyfish.framework.annotations.*;
|
||||
import com.flyfish.framework.domain.base.Qo;
|
||||
import com.flyfish.framework.domain.base.Vo;
|
||||
import com.flyfish.framework.utils.DataUtils;
|
||||
import com.flyfish.framework.utils.ReflectionUtils;
|
||||
import com.flyfish.framework.utils.StringFormats;
|
||||
import lombok.Data;
|
||||
@ -57,6 +56,12 @@ public class BeanProperty {
|
||||
// 类型为object时,拥有子表单
|
||||
private List<BeanProperty> children;
|
||||
|
||||
// 排序变量,用于排序
|
||||
private transient int order;
|
||||
|
||||
// 所属分组,该分组必须在元数据中定义
|
||||
private String group;
|
||||
|
||||
/**
|
||||
* 来自属性解释器构造
|
||||
* 支持对象嵌套
|
||||
@ -85,6 +90,7 @@ public class BeanProperty {
|
||||
property.setTitle(props.inherited() ? parentName + props.title() : props.title());
|
||||
property.setDescription(props.description());
|
||||
property.setReadonly(props.readonly());
|
||||
property.setOrder(props.order());
|
||||
} else if (strict) {
|
||||
property.setReadonly(true);
|
||||
return property;
|
||||
@ -132,8 +138,9 @@ public class BeanProperty {
|
||||
parseSubClass(field).ifPresent(subClazz -> property.setChildren(from(subClazz)));
|
||||
} else if (field.isAnnotationPresent(DateRange.class)) {
|
||||
property.setType(BeanPropertyType.DATE);
|
||||
property.prop("type", "range");
|
||||
property.prop("placeholder", Arrays.asList("开始时间", "结束时间"));
|
||||
property
|
||||
.prop("type", "range")
|
||||
.prop("placeholder", Arrays.asList("开始时间", "结束时间"));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -194,7 +201,9 @@ public class BeanProperty {
|
||||
.map(descriptor -> BeanProperty.form(descriptor, clazz))
|
||||
.filter(property -> !property.isReadonly())
|
||||
.collect(Collectors.toList());
|
||||
return ListUtils.union(parseExtras(clazz), properties);
|
||||
List<BeanProperty> result = ListUtils.union(parseExtras(clazz, properties), properties);
|
||||
result.sort(Comparator.comparingInt(a -> a.order));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,21 +219,37 @@ public class BeanProperty {
|
||||
|
||||
/**
|
||||
* 解析额外的注解
|
||||
* 以该注解的优先级更高
|
||||
*
|
||||
* @param clazz 类
|
||||
* @param clazz 类
|
||||
* @param origin 原本的元数据
|
||||
* @return 结果
|
||||
*/
|
||||
private static List<BeanProperty> parseExtras(Class<?> clazz) {
|
||||
private static List<BeanProperty> parseExtras(Class<?> clazz, List<BeanProperty> origin) {
|
||||
// 包含properties
|
||||
if (clazz.isAnnotationPresent(Properties.class)) {
|
||||
List<BeanProperty> result = new ArrayList<>();
|
||||
Properties properties = clazz.getAnnotation(Properties.class);
|
||||
return DataUtils.zip(properties.keys(), properties.titles(), (key, name) -> {
|
||||
BeanProperty property = new BeanProperty();
|
||||
property.setType(BeanPropertyType.STRING);
|
||||
property.setName(key);
|
||||
property.setTitle(name);
|
||||
return property;
|
||||
});
|
||||
for (Property prop : properties.value()) {
|
||||
String key = prop.key();
|
||||
// 如果基础元数据已经包含了这部分,相当于重载属性,此时不会调整其他属性,而是替换名称(将来可能扩展更多)
|
||||
Optional<BeanProperty> found = origin.stream().filter(property -> property.name.equals(key))
|
||||
.findFirst();
|
||||
if (found.isPresent()) {
|
||||
BeanProperty property = found.get();
|
||||
property.title = prop.title();
|
||||
if (prop.order() != 0) {
|
||||
property.order = prop.order();
|
||||
}
|
||||
} else {
|
||||
BeanProperty property = new BeanProperty();
|
||||
property.setType(BeanPropertyType.STRING);
|
||||
property.setName(key);
|
||||
property.setTitle(prop.title());
|
||||
result.add(property);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.flyfish.framework.beans.meta;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 对象属性分组
|
||||
*
|
||||
* @author wangyu
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class BeanPropertyGroup {
|
||||
|
||||
private String name;
|
||||
|
||||
private String code;
|
||||
}
|
@ -41,10 +41,18 @@ public @interface RestBean {
|
||||
|
||||
/**
|
||||
* 排除的属性
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String[] exclude() default {};
|
||||
|
||||
/**
|
||||
* 元数据,可以自由地指定一些值
|
||||
*
|
||||
* @return 结果
|
||||
*/
|
||||
String[] meta() default {};
|
||||
|
||||
/**
|
||||
* 必须指定qo
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user