Merge branch '4.0.x'

This commit is contained in:
zhou-hao
2021-04-01 09:13:20 +08:00
33 changed files with 170 additions and 94 deletions

View File

@@ -1,10 +1,11 @@
# hsweb4 基于spring-boot2,全响应式的后台管理框架
[![Codecov](https://codecov.io/gh/hs-web/hsweb-framework/branch/4.0.x/graph/badge.svg)](https://codecov.io/gh/hs-web/hsweb-framework/branch/master)
[![Build Status](https://travis-ci.org/hs-web/hsweb-framework.svg?branch=4.0.x)](https://travis-ci.org/hs-web/hsweb-framework)
[![Build Status](https://api.travis-ci.com/hs-web/hsweb-framework.svg?branch=4.0.x)](https://travis-ci.
com/hs-web/hsweb-framework)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square)](https://www.apache.org/licenses/LICENSE-2.0.html)
# 功能,特性
- [x] 基于[r2dbc](https://github.com/r2dbc) ,[easy-orm](https://github.com/hs-web/hsweb-easy-orm/tree/4.0.x)的通用响应式CRUD
- [x] 基于[r2dbc](https://github.com/r2dbc) ,[easy-orm](https://github.com/hs-web/hsweb-easy-orm/tree/4.0.x) 的通用响应式CRUD
- [x] H2,Mysql,SqlServer,PostgreSQL
- [x] 响应式r2dbc事务控制
- [x] 响应式权限控制,以及权限信息获取

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -20,6 +20,7 @@ package org.hswebframework.web.api.crud.entity;
import org.hswebframework.utils.RandomUtil;
import org.hswebframework.web.exception.ValidationException;
import org.hswebframework.web.id.IDGenerator;
import org.springframework.util.CollectionUtils;
@@ -49,6 +50,14 @@ public interface TreeSupportEntity<PK> extends Entity {
<T extends TreeSupportEntity<PK>> List<T> getChildren();
@Override
default void tryValidate(Class<?>... groups) {
Entity.super.tryValidate(groups);
if (getId() != null && Objects.equals(getId(), getParentId())) {
throw new ValidationException("parentId", "子节点ID不能与父节点ID相同");
}
}
/**
* 根据path获取父节点的path
*
@@ -180,7 +189,8 @@ public interface TreeSupportEntity<PK> extends Entity {
* @return 树形结构集合
*/
static <N extends TreeSupportEntity<PK>, PK> List<N> list2tree(Collection<N> dataList, BiConsumer<N, List<N>> childConsumer) {
return list2tree(dataList, childConsumer, (Function<TreeHelper<N, PK>, Predicate<N>>) predicate -> node -> node == null || predicate.getNode(node.getParentId()) == null);
return list2tree(dataList, childConsumer, (Function<TreeHelper<N, PK>, Predicate<N>>) predicate -> node -> node == null || predicate
.getNode(node.getParentId()) == null);
}
static <N extends TreeSupportEntity<PK>, PK> List<N> list2tree(Collection<N> dataList,
@@ -211,9 +221,9 @@ public interface TreeSupportEntity<PK> extends Entity {
Map<PK, N> cache = new HashMap<>();
// parentId,children
Map<PK, List<N>> treeCache = streamSupplier.get()
.peek(node -> cache.put(node.getId(), node))
.filter(e -> e.getParentId() != null)
.collect(Collectors.groupingBy(TreeSupportEntity::getParentId));
.peek(node -> cache.put(node.getId(), node))
.filter(e -> e.getParentId() != null)
.collect(Collectors.groupingBy(TreeSupportEntity::getParentId));
Predicate<N> rootNodePredicate = predicateFunction.apply(new TreeHelper<N, PK>() {
@Override
@@ -228,11 +238,11 @@ public interface TreeSupportEntity<PK> extends Entity {
});
return streamSupplier.get()
//设置每个节点的子节点
.peek(node -> childConsumer.accept(node, treeCache.get(node.getId())))
//获取根节点
.filter(rootNodePredicate)
.collect(Collectors.toList());
//设置每个节点的子节点
.peek(node -> childConsumer.accept(node, treeCache.get(node.getId())))
//获取根节点
.filter(rootNodePredicate)
.collect(Collectors.toList());
}
/**

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-commons</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -88,7 +88,6 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
<scope>test</scope>
</dependency>

View File

@@ -38,6 +38,14 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
private final MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory();
@SneakyThrows
private Stream<Resource> doGetResources(String packageStr) {
String path = ResourcePatternResolver
.CLASSPATH_ALL_URL_PREFIX
.concat(packageStr.replace(".", "/")).concat("/**/*.class");
return Arrays.stream(resourcePatternResolver.getResources(path));
}
@Override
@SneakyThrows
@SuppressWarnings("all")
@@ -47,33 +55,36 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
if (attr == null) {
return;
}
boolean reactivePrecent = org.springframework.util.ClassUtils.isPresent("io.r2dbc.spi.ConnectionFactory", this.getClass().getClassLoader());
boolean reactivePrecent = org.springframework.util.ClassUtils.isPresent("io.r2dbc.spi.ConnectionFactory", this
.getClass()
.getClassLoader());
String[] arr = (String[]) attr.get("value");
String path = Arrays.stream(arr)
.map(str -> ResourcePatternResolver
.CLASSPATH_ALL_URL_PREFIX
.concat(str.replace(".", "/")).concat("/**/*.class"))
.collect(Collectors.joining());
Set<Resource> resources = Arrays
.stream(arr)
.flatMap(this::doGetResources)
.collect(Collectors.toSet());
Class<Annotation>[] anno = (Class[]) attr.get("annotation");
Set<EntityInfo> entityInfos = new HashSet<>();
for (Resource resource : resourcePatternResolver.getResources(path)) {
for (Resource resource : resources) {
MetadataReader reader = metadataReaderFactory.getMetadataReader(resource);
String className = reader.getClassMetadata().getClassName();
Class<?> entityType = org.springframework.util.ClassUtils.forName(className,null);
Class<?> entityType = org.springframework.util.ClassUtils.forName(className, null);
if (Arrays.stream(anno)
.noneMatch(ann -> AnnotationUtils.findAnnotation(entityType, ann) != null)) {
.noneMatch(ann -> AnnotationUtils.findAnnotation(entityType, ann) != null)) {
continue;
}
ImplementFor implementFor = AnnotationUtils.findAnnotation(entityType, ImplementFor.class);
Reactive reactive = AnnotationUtils.findAnnotation(entityType, Reactive.class);
Class genericType = Optional.ofNullable(implementFor)
Class genericType = Optional
.ofNullable(implementFor)
.map(ImplementFor::value)
.orElseGet(() -> {
return Stream.of(entityType.getInterfaces())
return Stream
.of(entityType.getInterfaces())
.filter(e -> GenericEntity.class.isAssignableFrom(e))
.findFirst()
.orElse(entityType);
@@ -97,7 +108,8 @@ public class EasyormRepositoryRegistrar implements ImportBeanDefinitionRegistrar
idType = implementFor.idType();
}
EntityInfo entityInfo = new EntityInfo(genericType, entityType, idType, reactivePrecent && (reactive == null || reactive.enable()));
EntityInfo entityInfo = new EntityInfo(genericType, entityType, idType, reactivePrecent && (reactive == null || reactive
.enable()));
if (!entityInfos.contains(entityInfo) || implementFor != null) {
entityInfos.add(entityInfo);
}

View File

@@ -32,16 +32,16 @@ public interface ReactiveTreeSortEntityService<E extends TreeSortSupportEntity<K
return query(paramEntity)
.collectList()
.map(list -> TreeSupportEntity.list2tree(list,
this::setChildren,
this::createRootNodePredicate));
this::setChildren,
this::createRootNodePredicate));
}
default Mono<List<E>> queryIncludeChildrenTree(QueryParamEntity paramEntity) {
return queryIncludeChildren(paramEntity)
.collectList()
.map(list -> TreeSupportEntity.list2tree(list,
this::setChildren,
this::createRootNodePredicate));
this::setChildren,
this::createRootNodePredicate));
}
default Flux<E> queryIncludeChildren(Collection<K> idList) {
@@ -68,11 +68,11 @@ public interface ReactiveTreeSortEntityService<E extends TreeSortSupportEntity<K
@Override
default Mono<Integer> insertBatch(Publisher<? extends Collection<E>> entityPublisher) {
return this.getRepository()
.insertBatch(Flux.from(entityPublisher)
.flatMap(Flux::fromIterable)
.flatMap(this::applyTreeProperty)
.flatMap(e -> Flux.fromIterable(TreeSupportEntity.expandTree2List(e, getIDGenerator())))
.collectList());
.insertBatch(Flux.from(entityPublisher)
.flatMap(Flux::fromIterable)
.flatMap(this::applyTreeProperty)
.flatMap(e -> Flux.fromIterable(TreeSupportEntity.expandTree2List(e, getIDGenerator())))
.collectList());
}
default Mono<E> applyTreeProperty(E ele) {
@@ -80,25 +80,42 @@ public interface ReactiveTreeSortEntityService<E extends TreeSortSupportEntity<K
StringUtils.isEmpty(ele.getParentId())) {
return Mono.just(ele);
}
return findById(ele.getParentId())
.doOnNext(parent -> ele.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4)))
.thenReturn(ele);
return this.checkCyclicDependency(ele.getId(), ele)
.then(this.findById(ele.getParentId())
.doOnNext(parent -> ele.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4))))
.thenReturn(ele);
}
//校验是否有循环依赖,修改父节点为自己的子节点?
default Mono<E> checkCyclicDependency(K id, E ele) {
if (StringUtils.isEmpty(id)) {
return Mono.empty();
}
return this
.queryIncludeChildren(Collections.singletonList(id))
.doOnNext(e -> {
if (Objects.equals(ele.getParentId(), e.getId())) {
throw new IllegalArgumentException("不能修改父节点为自己或者自己的子节点");
}
})
.then(Mono.just(ele));
}
@Override
default Mono<SaveResult> save(Publisher<E> entityPublisher) {
return this.getRepository()
.save(Flux.from(entityPublisher)
.flatMap(this::applyTreeProperty)
//把树结构平铺
.flatMap(e -> Flux.fromIterable(TreeSupportEntity.expandTree2List(e, getIDGenerator())))
);
.save(Flux.from(entityPublisher)
.flatMap(this::applyTreeProperty)
//把树结构平铺
.flatMap(e -> Flux.fromIterable(TreeSupportEntity.expandTree2List(e, getIDGenerator())))
);
}
@Override
default Mono<Integer> updateById(K id, Mono<E> entityPublisher) {
return save(entityPublisher
.doOnNext(e -> e.setId(id)))
return this
.save(entityPublisher.doOnNext(e -> e.setId(id)))
.map(SaveResult::getTotal);
}

View File

@@ -1,5 +1,7 @@
package org.hswebframework.web.crud.web;
import io.r2dbc.spi.R2dbcDataIntegrityViolationException;
import io.r2dbc.spi.R2dbcNonTransientException;
import lombok.extern.slf4j.Slf4j;
import org.hswebframework.web.authorization.exception.AccessDenyException;
import org.hswebframework.web.authorization.exception.AuthenticationException;
@@ -42,7 +44,7 @@ public class CommonErrorControllerAdvice {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Mono<ResponseMessage<Object>> handleException(BusinessException e) {
return Mono.just(ResponseMessage.error(e.getCode(), e.getMessage()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@@ -72,7 +74,8 @@ public class CommonErrorControllerAdvice {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(ValidationException e) {
return Mono.just(ResponseMessage.<List<ValidationException.Detail>>error(400, "illegal_argument", e.getMessage()).result(e.getDetails()));
return Mono.just(ResponseMessage.<List<ValidationException.Detail>>error(400, "illegal_argument", e.getMessage())
.result(e.getDetails()));
}
@ExceptionHandler
@@ -84,7 +87,8 @@ public class CommonErrorControllerAdvice {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(BindException e) {
return handleException(new ValidationException(e.getMessage(), e.getBindingResult().getAllErrors()
return handleException(new ValidationException(e.getMessage(), e
.getBindingResult().getAllErrors()
.stream()
.filter(FieldError.class::isInstance)
.map(FieldError.class::cast)
@@ -95,7 +99,8 @@ public class CommonErrorControllerAdvice {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(WebExchangeBindException e) {
return handleException(new ValidationException(e.getMessage(), e.getBindingResult().getAllErrors()
return handleException(new ValidationException(e.getMessage(), e
.getBindingResult().getAllErrors()
.stream()
.filter(FieldError.class::isInstance)
.map(FieldError.class::cast)
@@ -107,7 +112,8 @@ public class CommonErrorControllerAdvice {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(MethodArgumentNotValidException e) {
return handleException(new ValidationException(e.getMessage(), e.getBindingResult().getAllErrors()
return handleException(new ValidationException(e.getMessage(), e
.getBindingResult().getAllErrors()
.stream()
.filter(FieldError.class::isInstance)
.map(FieldError.class::cast)
@@ -125,7 +131,7 @@ public class CommonErrorControllerAdvice {
@ResponseStatus(HttpStatus.GATEWAY_TIMEOUT)
public Mono<ResponseMessage<Object>> handleException(TimeoutException e) {
return Mono.just(ResponseMessage.error(504, "timeout", e.getMessage()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@@ -134,7 +140,7 @@ public class CommonErrorControllerAdvice {
@Order
public Mono<ResponseMessage<Object>> handleException(RuntimeException e) {
return Mono.just(ResponseMessage.error(e.getMessage()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@@ -143,14 +149,14 @@ public class CommonErrorControllerAdvice {
public Mono<ResponseMessage<Object>> handleException(NullPointerException e) {
return Mono.just(ResponseMessage.error(e.getMessage()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<Object>> handleException(IllegalArgumentException e) {
return Mono.just(ResponseMessage.error(400, "illegal_argument", e.getMessage()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@@ -163,29 +169,40 @@ public class CommonErrorControllerAdvice {
@ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
public Mono<ResponseMessage<Object>> handleException(MediaTypeNotSupportedStatusException e) {
return Mono.just(ResponseMessage
.error(415, "unsupported_media_type", "不支持的请求类型")
.result(e.getSupportedMediaTypes()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.error(415, "unsupported_media_type", "不支持的请求类型")
.result(e.getSupportedMediaTypes()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
public Mono<ResponseMessage<Object>> handleException(NotAcceptableStatusException e) {
return Mono.just(ResponseMessage
.error(406, "not_acceptable_media_type", "不支持的响应类型")
.result(e.getSupportedMediaTypes()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.error(406, "not_acceptable_media_type", "不支持的响应类型")
.result(e.getSupportedMediaTypes()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
public Mono<ResponseMessage<Object>> handleException(MethodNotAllowedException e) {
return Mono.just(ResponseMessage
.error(405, "method_not_allowed", "不支持的请求方法:" + e.getHttpMethod())
.result(e.getSupportedMethods()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
.error(405, "method_not_allowed", "不支持的请求方法:" + e.getHttpMethod())
.result(e.getSupportedMethods()))
.doOnEach(ReactiveLogger.onNext(r -> log.error(e.getMessage(), e)));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<Object>> handleException(R2dbcDataIntegrityViolationException exception) {
if (exception.getMessage().contains("Duplicate")) {
return Mono.just(ResponseMessage.error("存在重复的数据"));
}
log.warn(exception.getMessage(), exception);
return Mono.just(ResponseMessage.error("数据错误"));
}
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Mono<ResponseMessage<List<ValidationException.Detail>>> handleException(ServerWebInputException e) {

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-concurrent</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -40,7 +40,6 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
<optional>true</optional>
</dependency>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -17,6 +17,7 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@@ -29,7 +30,7 @@ import java.util.stream.Stream;
*/
@Slf4j
public final class FastBeanCopier {
private static final Map<CacheKey, Copier> CACHE = new HashMap<>();
private static final Map<CacheKey, Copier> CACHE = new ConcurrentHashMap<>();
private static final PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils();
@@ -96,7 +97,7 @@ public final class FastBeanCopier {
}
public static <T, S> T copy(S source, T target, Converter converter, String... ignore) {
return copy(source, target, converter, (ignore == null || ignore.length == 0) ? new java.util.HashSet<>() : new HashSet<>(Arrays.asList(ignore)));
return copy(source, target, converter, (ignore == null || ignore.length == 0) ? Collections.emptySet() : new HashSet<>(Arrays.asList(ignore)));
}
public static <T, S> T copy(S source, T target, Set<String> ignore) {

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-datasource</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-logging</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-logging</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -23,7 +23,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -7,29 +7,43 @@ import org.hswebframework.ezorm.rdb.mapping.annotation.ColumnType;
import org.hswebframework.ezorm.rdb.mapping.annotation.Comment;
import org.hswebframework.ezorm.rdb.mapping.annotation.JsonCodec;
import org.hswebframework.web.api.crud.entity.GenericTreeSortSupportEntity;
import org.hswebframework.web.validator.CreateGroup;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Index;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;
import java.sql.JDBCType;
import java.util.List;
import java.util.Map;
@Getter
@Setter
@Table(name = "s_dimension",indexes = {
@Index(name = "idx_dims_path",columnList = "path")
@Table(name = "s_dimension", indexes = {
@Index(name = "idx_dims_path", columnList = "path")
})
public class DimensionEntity extends GenericTreeSortSupportEntity<String> {
@Override
@Pattern(
regexp = "^[0-9a-zA-Z_\\-]+$",
message = "ID只能由数字,字母,下划线和中划线组成",
groups = CreateGroup.class)
public String getId() {
return super.getId();
}
@Comment("维度类型ID")
@Column(length = 32,name = "type_id")
@Column(length = 32, name = "type_id")
@Schema(description = "维度类型ID")
private String typeId;
@Comment("维度名称")
@Column(length = 32)
@Schema(description = "维度名称")
@NotBlank(message = "名称不能为空", groups = CreateGroup.class)
private String name;
@Comment("描述")
@@ -42,7 +56,7 @@ public class DimensionEntity extends GenericTreeSortSupportEntity<String> {
@Comment("其他配置")
@JsonCodec
@Schema(description = "其他配置")
private Map<String,Object> properties;
private Map<String, Object> properties;
@Schema(description = "子节点")
private List<DimensionEntity> children;

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system-authorization</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-system</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>hsweb-framework</artifactId>
<groupId>org.hswebframework.web</groupId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -24,7 +24,7 @@
<groupId>org.hswebframework.web</groupId>
<artifactId>hsweb-framework</artifactId>
<version>4.0.9</version>
<version>4.0.10-SNAPSHOT</version>
<modules>
<module>hsweb-starter</module>
<module>hsweb-core</module>
@@ -338,6 +338,12 @@
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>