feat:实现动态响应处理

This commit is contained in:
wangyu 2022-01-15 22:01:05 +08:00
parent 273484b62e
commit 691d3ce121
6 changed files with 171 additions and 2 deletions

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
package com.flyfish.framework.domain.base; package com.flyfish.framework.domain.base;
import com.flyfish.framework.context.ViewModelContext;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
/** /**
@ -32,4 +33,14 @@ public interface Vo<T> {
default Mono<Vo<T>> retrieve(T po) { default Mono<Vo<T>> retrieve(T po) {
return Mono.just(from(po)); return Mono.just(from(po));
} }
/**
* 最终的wrap方法用于全局拦截
*
* @param po 数据库实体
* @return 结果
*/
default Mono<Vo<T>> wrap(T po) {
return retrieve(po).flatMap(ViewModelContext::intercept);
}
} }

View File

@ -40,4 +40,5 @@ public class DictionaryConfig implements ImportBeanDefinitionRegistrar {
Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableDictProcess.class.getCanonicalName(), true); Map<String, Object> attrs = metadata.getAnnotationAttributes(EnableDictProcess.class.getCanonicalName(), true);
this.basePackages = (String[]) MapUtils.getObject(attrs, "basePackages"); this.basePackages = (String[]) MapUtils.getObject(attrs, "basePackages");
} }
} }

View File

@ -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;
});
}
}

View File

@ -28,10 +28,10 @@ public class #{className} {
return service.getPageList(qo) return service.getPageList(qo)
.map(Result::accept) .map(Result::accept)
.flatMap(result -> result.flatMap(list -> Flux.fromIterable(list) .flatMap(result -> result.flatMap(list -> Flux.fromIterable(list)
.flatMap(item -> new #{listViewClassName}().retrieve(item)) .flatMap(item -> new #{listViewClassName}().wrap(item))
.collectList())); .collectList()));
} }
return service.getList(qo).flatMap(item -> new #{listViewClassName}().retrieve(item)) return service.getList(qo).flatMap(item -> new #{listViewClassName}().wrap(item))
.collectList() .collectList()
.map(Result::accept); .map(Result::accept);
} }