feat:实现动态响应处理
This commit is contained in:
parent
273484b62e
commit
691d3ce121
@ -0,0 +1,53 @@
|
||||
package com.flyfish.framework.context;
|
||||
|
||||
import com.flyfish.framework.context.interceptor.ViewModelInterceptor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 全局上下文
|
||||
*
|
||||
* @author wangyu
|
||||
* 支持插件式增加处理器
|
||||
*/
|
||||
@Component
|
||||
public class ViewModelContext {
|
||||
|
||||
// 唯一实例
|
||||
private static ViewModelContext INSTANCE;
|
||||
|
||||
// 拦截器们
|
||||
private final List<ViewModelInterceptor> interceptors;
|
||||
|
||||
/**
|
||||
* 通过构造器注入
|
||||
*/
|
||||
public ViewModelContext(List<ViewModelInterceptor> interceptors) {
|
||||
this.interceptors = interceptors;
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局对象拦截器
|
||||
*
|
||||
* @param value 对象值
|
||||
* @param <T> 泛型
|
||||
* @return 结果
|
||||
*/
|
||||
public static <T> Mono<T> intercept(T value) {
|
||||
if (null != INSTANCE) {
|
||||
List<ViewModelInterceptor> interceptors = INSTANCE.interceptors;
|
||||
if (CollectionUtils.isNotEmpty(interceptors)) {
|
||||
for (ViewModelInterceptor interceptor : interceptors) {
|
||||
if (interceptor.supports(value)) {
|
||||
return interceptor.intercept(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Mono.just(value);
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.flyfish.framework.context.interceptor;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* 视图模型拦截器
|
||||
*
|
||||
* @author wangyu
|
||||
*/
|
||||
public interface ViewModelInterceptor {
|
||||
|
||||
/**
|
||||
* 是否支持
|
||||
*
|
||||
* @param data 数据
|
||||
* @return 结果
|
||||
*/
|
||||
boolean supports(Object data);
|
||||
|
||||
/**
|
||||
* 拦截并返回
|
||||
*
|
||||
* @param data 数据
|
||||
* @param <T> 泛型
|
||||
* @return 结果
|
||||
*/
|
||||
<T> Mono<T> intercept(T data);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.flyfish.framework.domain.base;
|
||||
|
||||
import com.flyfish.framework.context.ViewModelContext;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
@ -32,4 +33,14 @@ public interface Vo<T> {
|
||||
default Mono<Vo<T>> retrieve(T po) {
|
||||
return Mono.just(from(po));
|
||||
}
|
||||
|
||||
/**
|
||||
* 最终的wrap方法,用于全局拦截
|
||||
*
|
||||
* @param po 数据库实体
|
||||
* @return 结果
|
||||
*/
|
||||
default Mono<Vo<T>> wrap(T po) {
|
||||
return retrieve(po).flatMap(ViewModelContext::intercept);
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +40,5 @@ public class DictionaryConfig implements ImportBeanDefinitionRegistrar {
|
||||
Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableDictProcess.class.getCanonicalName(), true);
|
||||
this.basePackages = (String[]) MapUtils.getObject(attrs, "basePackages");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,76 @@
|
||||
package com.flyfish.framework.dict.handler;
|
||||
|
||||
import com.flyfish.framework.annotations.DictValue;
|
||||
import com.flyfish.framework.context.interceptor.ViewModelInterceptor;
|
||||
import com.flyfish.framework.dict.domain.DictionaryValue;
|
||||
import com.flyfish.framework.dict.service.DictionaryService;
|
||||
import com.flyfish.framework.utils.ReflectionUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
|
||||
|
||||
/**
|
||||
* 保证首当其冲被检测到,设置order 0
|
||||
* 用于处理字典值,无侵入注入
|
||||
*
|
||||
* @author wangyu
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DictAnnotationInterceptor implements ViewModelInterceptor {
|
||||
|
||||
// 字典服务
|
||||
private final DictionaryService dictionaryService;
|
||||
|
||||
/**
|
||||
* 当前对象包含@DictValue的属性时支持
|
||||
*
|
||||
* @param data 返回值
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public boolean supports(Object data) {
|
||||
List<Field> fields = FieldUtils.getFieldsListWithAnnotation(data.getClass(), DictValue.class);
|
||||
return CollectionUtils.isNotEmpty(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理对象中的字典注解
|
||||
*
|
||||
* @param data 数据
|
||||
* @return 处理后结果
|
||||
*/
|
||||
@Override
|
||||
public <T> Mono<T> intercept(T data) {
|
||||
List<Field> fields = FieldUtils.getFieldsListWithAnnotation(data.getClass(), DictValue.class);
|
||||
return Flux.fromIterable(fields)
|
||||
.flatMap(field -> {
|
||||
DictValue dictValue = field.getAnnotation(DictValue.class);
|
||||
String code = dictValue.value();
|
||||
String fieldName = field.getName();
|
||||
Object value = ReflectionUtils.getFieldValue(data, fieldName);
|
||||
return dictionaryService.getByCode(code).map(dict -> dict.getValues()
|
||||
.stream()
|
||||
.filter(item -> item.getValue().equals(value))
|
||||
.findFirst()
|
||||
.map(DictionaryValue::getText)
|
||||
.orElse(defaultIfNull((String) value, ""))
|
||||
).map(mapped -> Tuples.of(fieldName, mapped));
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.reduce(data, (result, tuple) -> {
|
||||
ReflectionUtils.setFieldValue(result, tuple.getT1(), tuple.getT2());
|
||||
return result;
|
||||
});
|
||||
}
|
||||
}
|
@ -28,10 +28,10 @@ public class #{className} {
|
||||
return service.getPageList(qo)
|
||||
.map(Result::accept)
|
||||
.flatMap(result -> result.flatMap(list -> Flux.fromIterable(list)
|
||||
.flatMap(item -> new #{listViewClassName}().retrieve(item))
|
||||
.flatMap(item -> new #{listViewClassName}().wrap(item))
|
||||
.collectList()));
|
||||
}
|
||||
return service.getList(qo).flatMap(item -> new #{listViewClassName}().retrieve(item))
|
||||
return service.getList(qo).flatMap(item -> new #{listViewClassName}().wrap(item))
|
||||
.collectList()
|
||||
.map(Result::accept);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user