feat:提出公共审查
This commit is contained in:
parent
a68ac80b4d
commit
9ebfb2cb49
@ -0,0 +1,9 @@
|
|||||||
|
package com.flyfish.framework.validation.groups;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共校验,可被策略忽略
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
public interface CodeValid {
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.flyfish.framework.validation.groups;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共校验,可被策略忽略
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
public interface NameValid {
|
||||||
|
}
|
@ -9,6 +9,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 指定动态分组
|
* 指定动态分组
|
||||||
|
*
|
||||||
* @author wangyu
|
* @author wangyu
|
||||||
*/
|
*/
|
||||||
@Target({TYPE})
|
@Target({TYPE})
|
||||||
@ -16,5 +17,24 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
|||||||
@Documented
|
@Documented
|
||||||
public @interface ConditionalGroup {
|
public @interface ConditionalGroup {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义验证分组提供者
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
Class<? extends ConditionalValidGroupProvider<?>>[] value() default {};
|
Class<? extends ConditionalValidGroupProvider<?>>[] value() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否不验证编码
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
boolean codeless() default false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否不验证名称
|
||||||
|
*
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
boolean nameless() default false;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.flyfish.framework.auditor;
|
||||||
|
|
||||||
|
import com.flyfish.framework.domain.base.Domain;
|
||||||
|
import com.flyfish.framework.generation.CodeRules;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CommonBeanAuditor implements BeanAuditor<Domain> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对实体进行审查,并补全相关字段
|
||||||
|
*
|
||||||
|
* @param data 原数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void audit(Domain data) {
|
||||||
|
// 编码审查,自动生成
|
||||||
|
if (StringUtils.isBlank(data.getId()) && StringUtils.isBlank(data.getCode())) {
|
||||||
|
String ruledCode = CodeRules.get(data);
|
||||||
|
if (null != ruledCode) {
|
||||||
|
data.setCode(ruledCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.flyfish.framework.auditor;
|
||||||
|
|
||||||
|
import com.flyfish.framework.domain.base.Domain;
|
||||||
|
import com.flyfish.framework.generation.CodeRules;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步公共审查
|
||||||
|
*
|
||||||
|
* @author wangyu
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class ReactiveCommonBeanAuditor implements ReactiveBeanAuditor<Domain> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对实体进行审查,并补全相关字段
|
||||||
|
*
|
||||||
|
* @param data 原数据
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Mono<Domain> audit(Domain data) {
|
||||||
|
// 编码审查,自动生成
|
||||||
|
if (StringUtils.isBlank(data.getId()) && StringUtils.isBlank(data.getCode())) {
|
||||||
|
return CodeRules.retrieve(data)
|
||||||
|
.map(code -> {
|
||||||
|
data.setCode(code);
|
||||||
|
return data;
|
||||||
|
})
|
||||||
|
.thenReturn(data);
|
||||||
|
}
|
||||||
|
return Mono.just(data);
|
||||||
|
}
|
||||||
|
}
|
@ -3,11 +3,10 @@ package com.flyfish.framework.domain.base;
|
|||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import com.flyfish.framework.annotations.Generation;
|
import com.flyfish.framework.annotations.Generation;
|
||||||
import com.flyfish.framework.annotations.Property;
|
import com.flyfish.framework.annotations.Property;
|
||||||
import com.flyfish.framework.generation.CodeRules;
|
import com.flyfish.framework.validation.groups.CodeValid;
|
||||||
import lombok.AccessLevel;
|
import com.flyfish.framework.validation.groups.NameValid;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.springframework.data.annotation.Id;
|
import org.springframework.data.annotation.Id;
|
||||||
import org.springframework.data.annotation.Transient;
|
import org.springframework.data.annotation.Transient;
|
||||||
import org.springframework.data.mongodb.core.index.Indexed;
|
import org.springframework.data.mongodb.core.index.Indexed;
|
||||||
@ -34,9 +33,8 @@ public abstract class Domain implements Po, Named, Serializable {
|
|||||||
* 编号
|
* 编号
|
||||||
*/
|
*/
|
||||||
@Property(title = "编码", inherited = true)
|
@Property(title = "编码", inherited = true)
|
||||||
@NotBlank(message = "编码不可为空")
|
@NotBlank(message = "编码不可为空", groups = CodeValid.class)
|
||||||
@Generation(Generation.Strategy.CODE)
|
@Generation(Generation.Strategy.CODE)
|
||||||
@Getter(AccessLevel.NONE)
|
|
||||||
protected String code;
|
protected String code;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +42,7 @@ public abstract class Domain implements Po, Named, Serializable {
|
|||||||
*/
|
*/
|
||||||
@Indexed
|
@Indexed
|
||||||
@Property(title = "名称", inherited = true)
|
@Property(title = "名称", inherited = true)
|
||||||
@NotBlank(message = "名称不可为空")
|
@NotBlank(message = "名称不可为空", groups = NameValid.class)
|
||||||
@Generation(Generation.Strategy.NAME)
|
@Generation(Generation.Strategy.NAME)
|
||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
@ -56,18 +54,6 @@ public abstract class Domain implements Po, Named, Serializable {
|
|||||||
@Property(readonly = true)
|
@Property(readonly = true)
|
||||||
private IUser currentUser;
|
private IUser currentUser;
|
||||||
|
|
||||||
/**
|
|
||||||
* 自动生成code环节
|
|
||||||
*
|
|
||||||
* @return 结果
|
|
||||||
*/
|
|
||||||
public String getCode() {
|
|
||||||
if (StringUtils.isBlank(id) && StringUtils.isBlank(code)) {
|
|
||||||
code = CodeRules.getCode(this);
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.flyfish.framework.generation;
|
package com.flyfish.framework.generation;
|
||||||
|
|
||||||
import com.flyfish.framework.domain.base.Domain;
|
import com.flyfish.framework.domain.base.Domain;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代码规则策略
|
* 代码规则策略
|
||||||
@ -16,4 +17,14 @@ public interface CodeRuleStrategy {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
String generate(Domain domain);
|
String generate(Domain domain);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步方式,支持异步请求
|
||||||
|
*
|
||||||
|
* @param domain 实体
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
default Mono<String> retrieve(Domain domain) {
|
||||||
|
return Mono.just(generate(domain));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import com.flyfish.framework.domain.base.Domain;
|
|||||||
import com.flyfish.framework.generation.strategy.TransactionCodeRuleStrategy;
|
import com.flyfish.framework.generation.strategy.TransactionCodeRuleStrategy;
|
||||||
import com.flyfish.framework.generation.strategy.UUIDCodeRuleStrategy;
|
import com.flyfish.framework.generation.strategy.UUIDCodeRuleStrategy;
|
||||||
import com.flyfish.framework.utils.ReflectionUtils;
|
import com.flyfish.framework.utils.ReflectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@ -32,12 +32,27 @@ public interface CodeRules {
|
|||||||
* @param instance 实体
|
* @param instance 实体
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
static String getCode(Domain instance) {
|
static String get(Domain instance) {
|
||||||
CodeRule rule = instance.getClass().getAnnotation(CodeRule.class);
|
CodeRule rule = instance.getClass().getAnnotation(CodeRule.class);
|
||||||
if (null != rule && StringUtils.isBlank(instance.getId())) {
|
if (null != rule) {
|
||||||
CodeRuleStrategy strategy = strategies.computeIfAbsent(rule.value(), ReflectionUtils::instantiate);
|
CodeRuleStrategy strategy = strategies.computeIfAbsent(rule.value(), ReflectionUtils::instantiate);
|
||||||
return strategy.generate(instance);
|
return strategy.generate(instance);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步获取code
|
||||||
|
*
|
||||||
|
* @param instance 实体
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
static Mono<String> retrieve(Domain instance) {
|
||||||
|
CodeRule rule = instance.getClass().getAnnotation(CodeRule.class);
|
||||||
|
if (null != rule) {
|
||||||
|
CodeRuleStrategy strategy = strategies.computeIfAbsent(rule.value(), ReflectionUtils::instantiate);
|
||||||
|
return strategy.retrieve(instance);
|
||||||
|
}
|
||||||
|
return Mono.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.flyfish.framework.configuration.resolver;
|
package com.flyfish.framework.configuration.resolver;
|
||||||
|
|
||||||
import com.flyfish.framework.configuration.annotations.ValidRequestBody;
|
import com.flyfish.framework.configuration.annotations.ValidRequestBody;
|
||||||
|
import com.flyfish.framework.validation.groups.CodeValid;
|
||||||
|
import com.flyfish.framework.validation.groups.NameValid;
|
||||||
import com.flyfish.framework.validation.spi.ConditionalGroup;
|
import com.flyfish.framework.validation.spi.ConditionalGroup;
|
||||||
import com.flyfish.framework.validation.spi.ConditionalValidGroupProvider;
|
import com.flyfish.framework.validation.spi.ConditionalValidGroupProvider;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
@ -30,7 +32,6 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException;
|
|||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import javax.validation.groups.Default;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -153,17 +154,27 @@ public class ValidRequestBodyMethodArgumentResolver extends AbstractMessageReade
|
|||||||
@NonNull
|
@NonNull
|
||||||
private Object[] extractValidationHints(Object target) {
|
private Object[] extractValidationHints(Object target) {
|
||||||
ConditionalGroup group = AnnotationUtils.findAnnotation(target.getClass(), ConditionalGroup.class);
|
ConditionalGroup group = AnnotationUtils.findAnnotation(target.getClass(), ConditionalGroup.class);
|
||||||
if (null != group && ArrayUtils.isNotEmpty(group.value())) {
|
List<Class<?>> groups = new ArrayList<>();
|
||||||
List<Class<?>> groups = new ArrayList<>();
|
if (null != group) {
|
||||||
for (Class<? extends ConditionalValidGroupProvider<?>> clazz : group.value()) {
|
if (!group.codeless()) {
|
||||||
try {
|
groups.add(CodeValid.class);
|
||||||
groups.addAll(Arrays.asList(clazz.newInstance().provide(CastUtils.cast(target))));
|
}
|
||||||
} catch (InstantiationException | IllegalAccessException ignored) {
|
if (!group.nameless()) {
|
||||||
|
groups.add(NameValid.class);
|
||||||
|
}
|
||||||
|
if (ArrayUtils.isNotEmpty(group.value())) {
|
||||||
|
for (Class<? extends ConditionalValidGroupProvider<?>> clazz : group.value()) {
|
||||||
|
try {
|
||||||
|
groups.addAll(Arrays.asList(clazz.newInstance().provide(CastUtils.cast(target))));
|
||||||
|
} catch (InstantiationException | IllegalAccessException ignored) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (CollectionUtils.isNotEmpty(groups)) {
|
} else {
|
||||||
return groups.toArray();
|
groups = Arrays.asList(CodeValid.class, NameValid.class);
|
||||||
}
|
}
|
||||||
|
if (CollectionUtils.isNotEmpty(groups)) {
|
||||||
|
return groups.toArray();
|
||||||
}
|
}
|
||||||
return new Object[]{};
|
return new Object[]{};
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
protected ReactiveBeanPoster<T> poster;
|
protected ReactiveBeanPoster<T> poster;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private ReactiveBeanAuditor<Domain> commonAuditor;
|
||||||
|
@Autowired
|
||||||
private ReactiveBeanAuditor<AuditDomain> operationAuditor;
|
private ReactiveBeanAuditor<AuditDomain> operationAuditor;
|
||||||
@Autowired
|
@Autowired
|
||||||
private ReactiveBeanAuditor<AuthorizedDomain> authorizeAuditor;
|
private ReactiveBeanAuditor<AuthorizedDomain> authorizeAuditor;
|
||||||
@ -373,19 +375,22 @@ public class BaseReactiveServiceImpl<T extends Domain> implements BaseReactiveSe
|
|||||||
*
|
*
|
||||||
* @param entity 实体
|
* @param entity 实体
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
protected Mono<T> audit(T entity) {
|
protected Mono<T> audit(T entity) {
|
||||||
Mono<T> mono = Mono.just(entity);
|
Mono<T> mono = Mono.just(entity);
|
||||||
// 首先自定义审查,可能返回自定义对象
|
// 首先自定义审查,可能返回自定义对象
|
||||||
if (auditor != null) {
|
if (auditor != null) {
|
||||||
mono = mono.flatMap(auditor::audit);
|
mono = mono.flatMap(auditor::audit);
|
||||||
}
|
}
|
||||||
// 操作信息审查
|
// 然后公共审查
|
||||||
|
mono = (Mono<T>) mono.flatMap(commonAuditor::audit);
|
||||||
|
// 接着操作信息审查
|
||||||
if (entity instanceof AuditDomain) {
|
if (entity instanceof AuditDomain) {
|
||||||
mono = CastUtils.cast(mono.cast(AuditDomain.class).flatMap(operationAuditor::audit));
|
mono = (Mono<T>) mono.cast(AuditDomain.class).flatMap(operationAuditor::audit);
|
||||||
}
|
}
|
||||||
// 权限审查
|
// 最后权限审查
|
||||||
if (entity instanceof AuthorizedDomain) {
|
if (entity instanceof AuthorizedDomain) {
|
||||||
mono = CastUtils.cast(mono.cast(AuthorizedDomain.class).flatMap(authorizeAuditor::audit));
|
mono = (Mono<T>) mono.cast(AuthorizedDomain.class).flatMap(authorizeAuditor::audit);
|
||||||
}
|
}
|
||||||
return mono;
|
return mono;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,8 @@ public class BaseServiceImpl<T extends Domain> implements BaseService<T> {
|
|||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
protected BeanPoster<T> poster;
|
protected BeanPoster<T> poster;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private BeanAuditor<Domain> commonAuditor;
|
||||||
|
@Autowired
|
||||||
private BeanAuditor<AuditDomain> operationAuditor;
|
private BeanAuditor<AuditDomain> operationAuditor;
|
||||||
@Autowired
|
@Autowired
|
||||||
private BeanAuditor<AuthorizedDomain> authorizeAuditor;
|
private BeanAuditor<AuthorizedDomain> authorizeAuditor;
|
||||||
@ -348,6 +350,8 @@ public class BaseServiceImpl<T extends Domain> implements BaseService<T> {
|
|||||||
if (auditor != null) {
|
if (auditor != null) {
|
||||||
auditor.audit(entity);
|
auditor.audit(entity);
|
||||||
}
|
}
|
||||||
|
// 公共审查
|
||||||
|
commonAuditor.audit(entity);
|
||||||
// 用户审查
|
// 用户审查
|
||||||
if (entity instanceof AuditDomain) {
|
if (entity instanceof AuditDomain) {
|
||||||
operationAuditor.audit((AuditDomain) entity);
|
operationAuditor.audit((AuditDomain) entity);
|
||||||
|
Loading…
Reference in New Issue
Block a user