diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/ValidateEventListener.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/ValidateEventListener.java index 4d52c1c14..25572f1f9 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/ValidateEventListener.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/events/ValidateEventListener.java @@ -34,13 +34,13 @@ public class ValidateEventListener implements EventListener, Ordered { if (resultHolder.isPresent()) { resultHolder - .ifPresent(holder -> holder - .invoke(LocaleUtils - .doInReactive(() -> { - tryValidate(type, context); - return null; - }) - )); + .ifPresent(holder -> holder + .invoke(LocaleUtils + .doInReactive(() -> { + tryValidate(type, context); + return null; + }) + )); } else { tryValidate(type, context); } @@ -48,7 +48,8 @@ public class ValidateEventListener implements EventListener, Ordered { @SuppressWarnings("all") public void tryValidate(EventType type, EventContext context) { - if (type == MappingEventTypes.insert_before || type == MappingEventTypes.save_before) { + if (type == MappingEventTypes.insert_before + || type == MappingEventTypes.save_before) { boolean single = context.get(MappingContextKeys.type).map("single"::equals).orElse(false); if (single) { @@ -60,10 +61,11 @@ public class ValidateEventListener implements EventListener, Ordered { context.get(MappingContextKeys.instance) .filter(List.class::isInstance) .map(List.class::cast) - .ifPresent(lst -> lst.stream() - .filter(Entity.class::isInstance) - .map(Entity.class::cast) - .forEach(e -> ((Entity) e).tryValidate(CreateGroup.class)) + .ifPresent(lst -> lst + .stream() + .filter(Entity.class::isInstance) + .map(Entity.class::cast) + .forEach(e -> ((Entity) e).tryValidate(CreateGroup.class)) ); } diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/CrudService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/CrudService.java index 97477f941..c3963b854 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/CrudService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/CrudService.java @@ -32,7 +32,7 @@ public interface CrudService { return getRepository().createDelete(); } - @Transactional(readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional( readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) default Optional findById(K id) { return getRepository() .findById(id); @@ -48,48 +48,48 @@ public interface CrudService { .findById(id); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default SaveResult save(Collection entityArr) { return getRepository() .save(entityArr); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default int insert(Collection entityArr) { return getRepository() .insertBatch(entityArr); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default void insert(E entityArr) { getRepository() .insert(entityArr); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default int updateById(K id, E entityArr) { return getRepository() .updateById(id, entityArr); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default SaveResult save(E entity) { return getRepository() .save(Collections.singletonList(entity)); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default SaveResult save(List entities) { return getRepository() .save(entities); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default int deleteById(Collection idArr) { return getRepository().deleteById(idArr); } - @Transactional(transactionManager = TransactionManagers.jdbcTransactionManager) + @Transactional(rollbackFor = Throwable.class,transactionManager = TransactionManagers.jdbcTransactionManager) default int deleteById(K idArr) { return deleteById(Collections.singletonList(idArr)); } diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java index c996595c5..6fc7206d1 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/EnableCacheReactiveCrudService.java @@ -34,48 +34,55 @@ public interface EnableCacheReactiveCrudService extends ReactiveCrudServic } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono updateById(K id, E data) { return updateById(id, Mono.just(data)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono updateById(K id, Mono entityPublisher) { return registerClearCache(Collections.singleton("id:" + id)) .then(ReactiveCrudService.super.updateById(id, entityPublisher)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(Collection collection) { return registerClearCache() .then(ReactiveCrudService.super.save(collection)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(E data) { return registerClearCache() .then(ReactiveCrudService.super.save(data)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(Publisher entityPublisher) { return registerClearCache() .then(ReactiveCrudService.super.save(entityPublisher)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insert(E data) { return registerClearCache() .then(ReactiveCrudService.super.insert(data)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insert(Publisher entityPublisher) { return registerClearCache() .then(ReactiveCrudService.super.insert(entityPublisher)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insertBatch(Publisher> entityPublisher) { return registerClearCache() .then(ReactiveCrudService.super.insertBatch(entityPublisher)); @@ -106,12 +113,13 @@ public interface EnableCacheReactiveCrudService extends ReactiveCrudServic @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono deleteById(K id) { return deleteById(Mono.just(id)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono deleteById(Publisher idPublisher) { Flux cache = Flux.from(idPublisher).cache(); return cache diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/GenericCrudService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/GenericCrudService.java index 5b519de3a..bea845d7c 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/GenericCrudService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/GenericCrudService.java @@ -1,7 +1,9 @@ package org.hswebframework.web.crud.service; import org.hswebframework.ezorm.rdb.mapping.SyncRepository; +import org.hswebframework.web.api.crud.entity.TransactionManagers; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; public abstract class GenericCrudService implements CrudService { diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveCrudService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveCrudService.java index cec6e0ce8..ce2efce8d 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveCrudService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveCrudService.java @@ -90,13 +90,13 @@ public interface ReactiveCrudService { } - @Transactional(readOnly = true, transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono findById(K id) { return getRepository() .findById(id); } - @Transactional(readOnly = true, transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Flux findById(Collection publisher) { return getRepository() .findById(publisher); @@ -114,61 +114,61 @@ public interface ReactiveCrudService { .findById(publisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(Publisher entityPublisher) { return getRepository() .save(entityPublisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(E data) { return getRepository() .save(data); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(Collection collection) { return getRepository() .save(collection); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono updateById(K id, Mono entityPublisher) { return getRepository() .updateById(id, entityPublisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono updateById(K id, E data) { return getRepository() .updateById(id, Mono.just(data)); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insertBatch(Publisher> entityPublisher) { return getRepository() .insertBatch(entityPublisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insert(Publisher entityPublisher) { return getRepository() .insert(entityPublisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insert(E data) { return getRepository() .insert(Mono.just(data)); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono deleteById(Publisher idPublisher) { return getRepository() .deleteById(idPublisher); } - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono deleteById(K id) { return getRepository() .deleteById(Mono.just(id)); diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortEntityService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortEntityService.java index 97bd0187a..ec9619f04 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortEntityService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortEntityService.java @@ -174,23 +174,23 @@ public interface ReactiveTreeSortEntityService insert(Publisher entityPublisher) { return insertBatch(Flux.from(entityPublisher).collectList()); } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insert(E data) { return this.insertBatch(Flux.just(Collections.singletonList(data))); } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono insertBatch(Publisher> entityPublisher) { return this .getRepository() - .insertBatch(new TreeSortServiceHelper<>(this) + .insertBatch(new ReactiveTreeSortServiceHelper<>(this) .prepare(Flux.from(entityPublisher) .flatMapIterable(Function.identity())) // .doOnNext(e -> e.tryValidate(CreateGroup.class)) @@ -201,105 +201,11 @@ public interface ReactiveTreeSortEntityService applyTreeProperty(E ele) { - if (StringUtils.hasText(ele.getPath()) || - ObjectUtils.isEmpty(ele.getParentId())) { - return Mono.just(ele); - } - - return this.checkCyclicDependency(ele.getId(), ele) - .then(this.findById(ele.getParentId()) - .doOnNext(parent -> ele.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4)))) - .thenReturn(ele); - } - - @Deprecated - //校验是否有循环依赖,修改父节点为自己的子节点? - default Mono checkCyclicDependency(K id, E ele) { - if (ObjectUtils.isEmpty(id)) { - return Mono.empty(); - } - return this - .queryIncludeChildren(Collections.singletonList(id)) - .doOnNext(e -> { - if (Objects.equals(ele.getParentId(), e.getId())) { - throw new ValidationException.NoStackTrace("parentId", "error.tree_entity_cyclic_dependency"); - } - }) - .then(Mono.just(ele)); - } - - @Deprecated - default Mono> checkParentId(Collection source) { - - Set idSet = source - .stream() - .map(TreeSupportEntity::getId) - .filter(e -> !ObjectUtils.isEmpty(e)) - .collect(Collectors.toSet()); - - if (idSet.isEmpty()) { - return Mono.just(source); - } - - Set readyToCheck = source - .stream() - .map(TreeSupportEntity::getParentId) - .filter(e -> !ObjectUtils.isEmpty(e) && !idSet.contains(e)) - .collect(Collectors.toSet()); - - if (readyToCheck.isEmpty()) { - return Mono.just(source); - } - - return this - .createQuery() - .select("id") - .in("id", readyToCheck) - .fetch() - .doOnNext(e -> readyToCheck.remove(e.getId())) - .then(Mono.fromSupplier(() -> { - if (!readyToCheck.isEmpty()) { - throw new ValidationException( - "error.tree_entity_parent_id_not_exist", - Collections.singletonList( - new ValidationException.Detail( - "parentId", - "error.tree_entity_parent_id_not_exist", - readyToCheck)) - ); - } - return source; - })); - - } - - @Deprecated - //重构子节点的path - default void refactorChildPath(K id, Function> childGetter, String path, Consumer pathAccepter) { - - Collection children = childGetter.apply(id); - if (CollectionUtils.isEmpty(children)) { - return; - } - for (E child : children) { - if (ObjectUtils.isEmpty(path)) { - child.setPath(RandomUtil.randomChar(4)); - } else { - child.setPath(path + "-" + RandomUtil.randomChar(4)); - } - pathAccepter.accept(child); - this.refactorChildPath(child.getId(), childGetter, child.getPath(), pathAccepter); - } - - } - @Override @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) default Mono save(Publisher entityPublisher) { - return new TreeSortServiceHelper<>(this) + return new ReactiveTreeSortServiceHelper<>(this) .prepare(Flux.from(entityPublisher)) // .doOnNext(e -> e.tryValidate(CreateGroup.class)) .buffer(getBufferSize()) @@ -310,7 +216,7 @@ public interface ReactiveTreeSortEntityService tryRefactorPath(Flux stream) { - return new TreeSortServiceHelper<>(this).prepare(stream); + return new ReactiveTreeSortServiceHelper<>(this).prepare(stream); } @Override diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortServiceHelper.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortServiceHelper.java new file mode 100644 index 000000000..02faae4aa --- /dev/null +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/ReactiveTreeSortServiceHelper.java @@ -0,0 +1,41 @@ +package org.hswebframework.web.crud.service; + +import org.hswebframework.web.api.crud.entity.TreeSortSupportEntity; +import org.hswebframework.web.id.IDGenerator; +import reactor.core.publisher.Flux; + +import java.util.*; + +public class ReactiveTreeSortServiceHelper, PK> extends TreeSortServiceHelper { + + private final ReactiveTreeSortEntityService service; + + public ReactiveTreeSortServiceHelper(ReactiveTreeSortEntityService service) { + this.service = service; + } + + @Override + protected IDGenerator getIdGenerator() { + return service.getIDGenerator(); + } + + @Override + protected void applyChildren(E parent, List children) { + service.setChildren(parent, children); + } + + @Override + protected boolean isRootNode(E node) { + return service.isRootNode(node); + } + + @Override + protected Flux queryIncludeChildren(Collection idList) { + return service.queryIncludeChildren(idList); + } + + @Override + protected Flux queryById(Collection idList) { + return service.findById(idList); + } +} diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/SyncTreeSortServiceHelper.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/SyncTreeSortServiceHelper.java new file mode 100644 index 000000000..57cba64fe --- /dev/null +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/SyncTreeSortServiceHelper.java @@ -0,0 +1,52 @@ +package org.hswebframework.web.crud.service; + +import org.hswebframework.web.api.crud.entity.TreeSortSupportEntity; +import org.hswebframework.web.id.IDGenerator; +import reactor.core.publisher.Flux; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +public class SyncTreeSortServiceHelper, PK> extends TreeSortServiceHelper { + + private final TreeSortEntityService service; + + public SyncTreeSortServiceHelper(TreeSortEntityService service) { + this.service = service; + } + + @Override + protected IDGenerator getIdGenerator() { + return service.getIDGenerator(); + } + + @Override + protected void applyChildren(E parent, List children) { + service.setChildren(parent, children); + } + + @Override + protected boolean isRootNode(E node) { + return service.isRootNode(node); + } + + public List prepare(Collection source) { + return super + .prepare(Flux.fromIterable(source)) + .toStream() + .collect(Collectors.toList()); + } + + @Override + @SuppressWarnings("all") + protected Flux queryIncludeChildren(Collection idList) { + return Flux.fromIterable(service.queryIncludeChildren(idList)); + } + + @Override + @SuppressWarnings("all") + protected Flux queryById(Collection idList) { + return Flux.fromIterable(service.findById(idList)); + } +} diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortEntityService.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortEntityService.java index c35ffdd5f..5c565c50a 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortEntityService.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortEntityService.java @@ -25,124 +25,98 @@ import java.util.stream.Stream; * @see GenericReactiveTreeSupportCrudService */ public interface TreeSortEntityService, K> - extends CrudService { + extends CrudService { @Transactional(readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) default List queryResultToTree(QueryParamEntity paramEntity) { return TreeSupportEntity - .list2tree(query(paramEntity), - this::setChildren, - this::createRootNodePredicate); + .list2tree(query(paramEntity), + this::setChildren, + this::createRootNodePredicate); } @Transactional(readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) default List queryIncludeChildrenTree(QueryParamEntity paramEntity) { return TreeSupportEntity - .list2tree(queryIncludeChildren(paramEntity), - this::setChildren, - this::createRootNodePredicate); + .list2tree(queryIncludeChildren(paramEntity), + this::setChildren, + this::createRootNodePredicate); } @Transactional(readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) default List queryIncludeChildren(Collection idList) { return findById(idList) - .stream() - .flatMap(e -> createQuery() - .where() - .like$("path", e.getPath()) - .fetch() - .stream()) - .collect(Collectors.toList()); + .stream() + .flatMap(e -> createQuery() + .where() + .like$("path", e.getPath()) + .fetch() + .stream()) + .collect(Collectors.toList()); } @Transactional(readOnly = true, transactionManager = TransactionManagers.jdbcTransactionManager) default List queryIncludeChildren(QueryParamEntity queryParam) { return query(queryParam) - .stream() - .flatMap(e -> createQuery() - .where() - .like$("path", e.getPath()) - .fetch() - .stream()) - .collect(Collectors.toList()); + .stream() + .flatMap(e -> createQuery() + .where() + .like$("path", e.getPath()) + .fetch() + .stream()) + .collect(Collectors.toList()); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default void insert(E entityPublisher) { insert(Collections.singletonList(entityPublisher)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default int insert(Collection entityPublisher) { - return this - .getRepository() - .insertBatch(entityPublisher - .stream() - .flatMap(this::applyTreeProperty) - .flatMap(e -> TreeSupportEntity - .expandTree2List(e, getIDGenerator()) - .stream()) - .collect(Collectors.toList()) - ); - } - - default Stream applyTreeProperty(E ele) { - if (StringUtils.hasText(ele.getPath()) || - ObjectUtils.isEmpty(ele.getParentId())) { - return Stream.of(ele); - } - - this.checkCyclicDependency(ele.getId(), ele); - this.findById(ele.getParentId()) - .ifPresent(parent -> ele.setPath(parent.getPath() + "-" + RandomUtil.randomChar(4))); - return Stream.of(ele); - } - - //校验是否有循环依赖,修改父节点为自己的子节点? - default void checkCyclicDependency(K id, E ele) { - if (ObjectUtils.isEmpty(id)) { - return; - } - for (E e : this.queryIncludeChildren(Collections.singletonList(id))) { - if (Objects.equals(ele.getParentId(), e.getId())) { - throw new IllegalArgumentException("不能修改父节点为自己或者自己的子节点"); - } - } - + return new SyncTreeSortServiceHelper<>(this) + .prepare(Flux.fromIterable(entityPublisher)) + .buffer(getBufferSize()) + .map(this.getRepository()::insertBatch) + .reduce(Math::addExact) + .blockOptional() + .orElse(0); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default SaveResult save(List entities) { - return this.getRepository() - .save(entities - .stream() - .flatMap(this::applyTreeProperty) - //把树结构平铺 - .flatMap(e -> TreeSupportEntity - .expandTree2List(e, getIDGenerator()) - .stream()) - .collect(Collectors.toList()) - ); + return new SyncTreeSortServiceHelper<>(this) + .prepare(Flux.fromIterable(entities)) + .buffer(getBufferSize()) + .map(this.getRepository()::save) + .reduce(SaveResult::merge) + .blockOptional() + .orElse(SaveResult.of(0,0)); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default int updateById(K id, E entity) { entity.setId(id); return this.save(entity).getTotal(); } @Override + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.jdbcTransactionManager) default int deleteById(Collection idPublisher) { List dataList = findById(idPublisher); return dataList - .stream() - .map(e -> createDelete() - .where() - .like$(e::getPath) - .execute()) - .mapToInt(Integer::intValue) - .sum(); + .stream() + .map(e -> createDelete() + .where() + .like$(e::getPath) + .execute()) + .mapToInt(Integer::intValue) + .sum(); } IDGenerator getIDGenerator(); @@ -153,6 +127,10 @@ public interface TreeSortEntityService, K> return entity.getChildren(); } + default int getBufferSize() { + return 200; + } + default Predicate createRootNodePredicate(TreeSupportEntity.TreeHelper helper) { return node -> { if (isRootNode(node)) { diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java index 0da90387b..4050cd442 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/service/TreeSortServiceHelper.java @@ -6,6 +6,7 @@ import org.hswebframework.utils.RandomUtil; import org.hswebframework.web.api.crud.entity.TreeSortSupportEntity; import org.hswebframework.web.api.crud.entity.TreeSupportEntity; import org.hswebframework.web.exception.ValidationException; +import org.hswebframework.web.id.IDGenerator; import org.springframework.util.ObjectUtils; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -16,54 +17,59 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -public class TreeSortServiceHelper, PK> { +public abstract class TreeSortServiceHelper, PK> { //包含子节点的数据 - private Map allData; + protected Map allData; - private Map oldData; + protected Map oldData; - private Map thisTime; + protected Map thisTime; - private Map readyToSave; + protected Map readyToSave; - private final Map> childrenMapping = new LinkedHashMap<>(); + protected final Map> childrenMapping = new LinkedHashMap<>(); - private final ReactiveTreeSortEntityService service; + protected abstract IDGenerator getIdGenerator(); - TreeSortServiceHelper(ReactiveTreeSortEntityService service) { - this.service = service; - } + protected abstract void applyChildren(E parent, List children); - Flux prepare(Flux source) { + protected abstract boolean isRootNode(E node); + + protected abstract Flux queryIncludeChildren(Collection idList); + + protected abstract Flux queryById(Collection idList); + + + public Flux prepare(Flux source) { Flux cache = source - .flatMapIterable(e -> TreeSupportEntity.expandTree2List(e, service.getIDGenerator())) - .collectList() - .flatMapIterable(list -> { + .flatMapIterable(e -> TreeSupportEntity.expandTree2List(e, getIdGenerator())) + .collectList() + .flatMapIterable(list -> { - Map map = list - .stream() - .filter(e -> e.getId() != null) - .collect(Collectors.toMap( - TreeSupportEntity::getId, - Function.identity(), - (a, b) -> a - )); - //重新组装树结构 - TreeSupportEntity.list2tree(list, - service::setChildren, - (Predicate) e -> service.isRootNode(e) || map.get(e.getParentId()) == null); + Map map = list + .stream() + .filter(e -> e.getId() != null) + .collect(Collectors.toMap( + TreeSupportEntity::getId, + Function.identity(), + (a, b) -> a + )); + //重新组装树结构 + TreeSupportEntity.list2tree(list, + this::applyChildren, + (Predicate) e -> isRootNode(e) || map.get(e.getParentId()) == null); - return list; - }) - .cache(); + return list; + }) + .cache(); return init(cache) - .then(Mono.defer(this::checkParentId)) - .then(Mono.fromRunnable(this::checkCyclicDependency)) - .then(Mono.fromRunnable(this::refactorPath)) - .thenMany(Flux.defer(() -> Flux.fromIterable(readyToSave.values()))) - .doOnNext(this::refactor); + .then(Mono.defer(this::checkParentId)) + .then(Mono.fromRunnable(this::checkCyclicDependency)) + .then(Mono.fromRunnable(this::refactorPath)) + .thenMany(Flux.defer(() -> Flux.fromIterable(readyToSave.values()))) + .doOnNext(this::refactor); } private Mono init(Flux source) { @@ -73,49 +79,49 @@ public class TreeSortServiceHelper, PK> { readyToSave = new LinkedHashMap<>(); Mono> allDataFetcher = - source - .mapNotNull(e -> { + source + .mapNotNull(e -> { - if (e.getId() != null) { - thisTime.put(e.getId(), e); - } - - return e.getId(); - }) - .collect(Collectors.toSet()) - .flatMap(list -> service - .queryIncludeChildren(list) - .collectMap(TreeSupportEntity::getId, Function.identity())); - return allDataFetcher - .doOnNext(includeChildren -> { - //旧的数据 - for (E value : thisTime.values()) { - E old = includeChildren.get(value.getId()); - if (null != old) { - this.oldData.put(value.getId(), old); - } + if (e.getId() != null) { + thisTime.put(e.getId(), e); } - readyToSave.putAll(thisTime); - - allData.putAll(includeChildren); - allData.putAll(this.thisTime); - initChildren(); - + return e.getId(); }) - .then(); + .collect(Collectors.toSet()) + .flatMap(list -> + queryIncludeChildren(list) + .collectMap(TreeSupportEntity::getId, Function.identity())); + return allDataFetcher + .doOnNext(includeChildren -> { + //旧的数据 + for (E value : thisTime.values()) { + E old = includeChildren.get(value.getId()); + if (null != old) { + this.oldData.put(value.getId(), old); + } + } + + readyToSave.putAll(thisTime); + + allData.putAll(includeChildren); + allData.putAll(this.thisTime); + initChildren(); + + }) + .then(); } private void initChildren() { childrenMapping.clear(); for (E value : allData.values()) { - if (service.isRootNode(value) || value.getId() == null) { + if (isRootNode(value) || value.getId() == null) { continue; } childrenMapping - .computeIfAbsent(value.getParentId(), ignore -> new LinkedHashMap<>()) - .put(value.getId(), value); + .computeIfAbsent(value.getParentId(), ignore -> new LinkedHashMap<>()) + .put(value.getId(), value); } } @@ -144,43 +150,40 @@ public class TreeSortServiceHelper, PK> { } Set readyToCheck = thisTime - .values() - .stream() - .map(TreeSupportEntity::getParentId) - .filter(e -> !ObjectUtils.isEmpty(e) && !allData.containsKey(e)) - .collect(Collectors.toSet()); + .values() + .stream() + .map(TreeSupportEntity::getParentId) + .filter(e -> !ObjectUtils.isEmpty(e) && !allData.containsKey(e)) + .collect(Collectors.toSet()); if (readyToCheck.isEmpty()) { return Mono.empty(); } - return service - .createQuery() - .in("id", readyToCheck) - .fetch() - .doOnNext(e -> { - allData.put(e.getId(), e); - readyToCheck.remove(e.getId()); - }) - .then(Mono.fromRunnable(() -> { - if (!readyToCheck.isEmpty()) { - throw new ValidationException( + return queryById(readyToCheck) + .doOnNext(e -> { + allData.put(e.getId(), e); + readyToCheck.remove(e.getId()); + }) + .then(Mono.fromRunnable(() -> { + if (!readyToCheck.isEmpty()) { + throw new ValidationException( + "error.tree_entity_parent_id_not_exist", + Collections.singletonList( + new ValidationException.Detail( + "parentId", "error.tree_entity_parent_id_not_exist", - Collections.singletonList( - new ValidationException.Detail( - "parentId", - "error.tree_entity_parent_id_not_exist", - readyToCheck)) - ); - } - initChildren(); - })); + readyToCheck)) + ); + } + initChildren(); + })); } private void refactorPath() { Function> childGetter - = id -> childrenMapping - .getOrDefault(id, Collections.emptyMap()) - .values(); + = id -> childrenMapping + .getOrDefault(id, Collections.emptyMap()) + .values(); for (E data : thisTime.values()) { E old = data.getId() == null ? null : oldData.get(data.getId()); @@ -200,7 +203,7 @@ public class TreeSortServiceHelper, PK> { }; //变更到了顶级节点 - if (service.isRootNode(data)) { + if (isRootNode(data)) { data.setPath(RandomUtil.randomChar(4)); this.refactorChildPath(old.getId(), data.getPath(), childConsumer); //重新保存所有子节点 @@ -240,11 +243,11 @@ public class TreeSortServiceHelper, PK> { private void putChildToReadyToSave(Function> childGetter, E data) { childGetter - .apply(data.getId()) - .forEach(e -> { - readyToSave.put(e.getId(), e); - putChildToReadyToSave(childGetter, e); - }); + .apply(data.getId()) + .forEach(e -> { + readyToSave.put(e.getId(), e); + putChildToReadyToSave(childGetter, e); + }); } private void refactor(E e) { diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/sql/DefaultR2dbcExecutor.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/sql/DefaultR2dbcExecutor.java index d7f7a1047..616b6f2e5 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/sql/DefaultR2dbcExecutor.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/sql/DefaultR2dbcExecutor.java @@ -146,31 +146,31 @@ public class DefaultR2dbcExecutor extends R2dbcReactiveSqlExecutor { } @Override - @Transactional(propagation = Propagation.REQUIRES_NEW, transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW, transactionManager = TransactionManagers.reactiveTransactionManager) public Mono execute(SqlRequest request) { return super.execute(request); } @Override - @Transactional(propagation = Propagation.REQUIRES_NEW, transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRES_NEW, transactionManager = TransactionManagers.reactiveTransactionManager) public Mono execute(Publisher request) { return super.execute(request); } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) public Mono update(Publisher request) { return super.update(request); } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) public Mono update(SqlRequest request) { return super.update(request); } @Override - @Transactional(transactionManager = TransactionManagers.reactiveTransactionManager) + @Transactional(rollbackFor = Throwable.class, transactionManager = TransactionManagers.reactiveTransactionManager) public Mono update(String sql, Object... args) { return super.update(sql, args); } diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java index 43052d28e..6c21880e8 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonErrorControllerAdvice.java @@ -176,7 +176,7 @@ public class CommonErrorControllerAdvice { @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public Mono> handleException(jakarta.validation.ValidationException e) { - return Mono.just(ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getMessage())); + return Mono.just(ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getLocalizedMessage())); } @ExceptionHandler @@ -196,7 +196,7 @@ public class CommonErrorControllerAdvice { log.warn(e.getLocalizedMessage(), e); return LocaleUtils .resolveMessageReactive("error.internal_server_error") - .map(msg -> ResponseMessage.error(500, "internal_server_error", msg)); + .map(msg -> ResponseMessage.error(500, CodeConstants.Error.internal_server_error, msg)); } @ExceptionHandler @@ -206,7 +206,7 @@ public class CommonErrorControllerAdvice { return LocaleUtils .resolveMessageReactive("error.internal_server_error") - .map(msg -> ResponseMessage.error(500, "internal_server_error", msg)); + .map(msg -> ResponseMessage.error(500, CodeConstants.Error.internal_server_error, msg)); } @ExceptionHandler diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonWebMvcErrorControllerAdvice.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonWebMvcErrorControllerAdvice.java index 3feb580ee..f5c2a6abe 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonWebMvcErrorControllerAdvice.java +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/CommonWebMvcErrorControllerAdvice.java @@ -14,6 +14,7 @@ import org.hswebframework.web.i18n.LocaleUtils; import org.hswebframework.web.logger.ReactiveLogger; import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; +import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.validation.BindException; import org.springframework.validation.FieldError; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -28,6 +29,7 @@ import org.springframework.web.server.UnsupportedMediaTypeStatusException; import reactor.core.publisher.Mono; import jakarta.validation.ConstraintViolationException; + import java.util.List; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; @@ -39,7 +41,7 @@ public class CommonWebMvcErrorControllerAdvice { private String resolveMessage(Throwable e) { if (e instanceof I18nSupportException) { - return LocaleUtils.resolveMessage(((I18nSupportException) e).getI18nCode()); + return LocaleUtils.resolveMessage(((I18nSupportException) e).getI18nCode(),((I18nSupportException) e).getArgs()); } return e.getMessage() == null ? null : LocaleUtils.resolveMessage(e.getMessage()); } @@ -63,8 +65,8 @@ public class CommonWebMvcErrorControllerAdvice { @ResponseStatus(HttpStatus.UNAUTHORIZED) public ResponseMessage handleException(UnAuthorizedException e) { return ResponseMessage - .error(401, CodeConstants.Error.unauthorized, resolveMessage(e)) - .result(e.getState()); + .error(401, CodeConstants.Error.unauthorized, resolveMessage(e)) + .result(e.getState()); } @@ -85,9 +87,8 @@ public class CommonWebMvcErrorControllerAdvice { public ResponseMessage> handleException(ValidationException e) { return ResponseMessage - .>error(400, CodeConstants.Error.illegal_argument, resolveMessage(e)) - .result(e.getDetails()) - ; + .>error(400, CodeConstants.Error.illegal_argument, resolveMessage(e)) + .result(e.getDetails()); } @ExceptionHandler @@ -100,24 +101,24 @@ public class CommonWebMvcErrorControllerAdvice { @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseMessage> handleException(BindException e) { return handleException(new ValidationException(e.getMessage(), e - .getBindingResult().getAllErrors() - .stream() - .filter(FieldError.class::isInstance) - .map(FieldError.class::cast) - .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) - .collect(Collectors.toList()))); + .getBindingResult().getAllErrors() + .stream() + .filter(FieldError.class::isInstance) + .map(FieldError.class::cast) + .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) + .collect(Collectors.toList()))); } @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseMessage> handleException(WebExchangeBindException e) { return handleException(new ValidationException(e.getMessage(), e - .getBindingResult().getAllErrors() - .stream() - .filter(FieldError.class::isInstance) - .map(FieldError.class::cast) - .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) - .collect(Collectors.toList()))); + .getBindingResult().getAllErrors() + .stream() + .filter(FieldError.class::isInstance) + .map(FieldError.class::cast) + .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) + .collect(Collectors.toList()))); } @@ -125,18 +126,18 @@ public class CommonWebMvcErrorControllerAdvice { @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseMessage> handleException(MethodArgumentNotValidException e) { return handleException(new ValidationException(e.getMessage(), e - .getBindingResult().getAllErrors() - .stream() - .filter(FieldError.class::isInstance) - .map(FieldError.class::cast) - .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) - .collect(Collectors.toList()))); + .getBindingResult().getAllErrors() + .stream() + .filter(FieldError.class::isInstance) + .map(FieldError.class::cast) + .map(err -> new ValidationException.Detail(err.getField(), err.getDefaultMessage(), null)) + .collect(Collectors.toList()))); } @ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) public ResponseMessage handleException(jakarta.validation.ValidationException e) { - return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getMessage()); + return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getLocalizedMessage()); } @ExceptionHandler @@ -150,7 +151,18 @@ public class CommonWebMvcErrorControllerAdvice { @Order public ResponseMessage handleException(RuntimeException e) { log.warn(e.getLocalizedMessage(), e); - return ResponseMessage.error(resolveMessage(e)); + return ResponseMessage.error(CodeConstants.Error.internal_server_error, + LocaleUtils.resolveMessage("error.internal_server_error")); + } + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + @Order + public ResponseMessage handleException(HttpMessageNotReadableException e) { + return ResponseMessage + .error(400, + "missing_request_body", + LocaleUtils.resolveMessage("error.missing_request_body")); } @ExceptionHandler @@ -182,8 +194,8 @@ public class CommonWebMvcErrorControllerAdvice { log.warn(e.getLocalizedMessage(), e); return ResponseMessage - .error(415, "unsupported_media_type", LocaleUtils.resolveMessage("error.unsupported_media_type")) - .result(e.getSupportedMediaTypes()); + .error(415, "unsupported_media_type", LocaleUtils.resolveMessage("error.unsupported_media_type")) + .result(e.getSupportedMediaTypes()); } @ExceptionHandler @@ -192,9 +204,9 @@ public class CommonWebMvcErrorControllerAdvice { log.warn(e.getLocalizedMessage(), e); return ResponseMessage - .error(406, "not_acceptable_media_type", LocaleUtils - .resolveMessage("error.not_acceptable_media_type")) - .result(e.getSupportedMediaTypes()); + .error(406, "not_acceptable_media_type", LocaleUtils + .resolveMessage("error.not_acceptable_media_type")) + .result(e.getSupportedMediaTypes()); } @ExceptionHandler @@ -203,8 +215,8 @@ public class CommonWebMvcErrorControllerAdvice { log.warn(e.getLocalizedMessage(), e); return ResponseMessage - .error(406, "method_not_allowed", LocaleUtils.resolveMessage("error.method_not_allowed")) - .result(e.getSupportedMethods()); + .error(406, "method_not_allowed", LocaleUtils.resolveMessage("error.method_not_allowed")) + .result(e.getSupportedMethods()); } @@ -220,7 +232,7 @@ public class CommonWebMvcErrorControllerAdvice { } while (exception != null && exception != e); if (exception == null) { - return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getMessage()); + return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, e.getMessage()); } return ResponseMessage.error(400, CodeConstants.Error.illegal_argument, resolveMessage(exception)); } diff --git a/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/TreeServiceQueryController.java b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/TreeServiceQueryController.java new file mode 100644 index 000000000..dfee37e92 --- /dev/null +++ b/hsweb-commons/hsweb-commons-crud/src/main/java/org/hswebframework/web/crud/web/TreeServiceQueryController.java @@ -0,0 +1,67 @@ +package org.hswebframework.web.crud.web; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import org.hswebframework.web.api.crud.entity.QueryOperation; +import org.hswebframework.web.api.crud.entity.QueryParamEntity; +import org.hswebframework.web.api.crud.entity.TreeSortSupportEntity; +import org.hswebframework.web.authorization.annotation.Authorize; +import org.hswebframework.web.authorization.annotation.QueryAction; +import org.hswebframework.web.crud.service.ReactiveTreeSortEntityService; +import org.hswebframework.web.crud.service.TreeSortEntityService; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; + +public interface TreeServiceQueryController, K> { + + @Authorize(ignore = true) + TreeSortEntityService getService(); + + @GetMapping("/_query/tree") + @QueryAction + @QueryOperation(summary = "使用GET动态查询并返回树形结构") + default List findAllTree(@Parameter(hidden = true) QueryParamEntity param) { + return getService().queryResultToTree(param); + } + + @GetMapping("/_query/_children") + @QueryAction + @QueryOperation(summary = "使用GET动态查询并返回子节点数据") + default List findAllChildren(@Parameter(hidden = true) QueryParamEntity param) { + return getService().queryIncludeChildren(param); + } + + @GetMapping("/_query/_children/tree") + @QueryAction + @QueryOperation(summary = "使用GET动态查询并返回子节点树形结构数据") + default List findAllChildrenTree(@Parameter(hidden = true) QueryParamEntity param) { + return getService().queryIncludeChildrenTree(param); + } + + @PostMapping("/_query/tree") + @QueryAction + @Operation(summary = "使用POST动态查询并返回树形结构") + default List findAllTreePost(@RequestBody QueryParamEntity param) { + return getService().queryResultToTree(param); + } + + @PostMapping("/_query/_children") + @QueryAction + @Operation(summary = "使用POST动态查询并返回子节点数据") + default List findAllChildrenPost(@RequestBody QueryParamEntity param) { + return getService().queryIncludeChildren(param); + } + + @PostMapping("/_query/_children/tree") + @QueryAction + @Operation(summary = "使用POST动态查询并返回子节点树形结构数据") + default List findAllChildrenTreePost(@RequestBody QueryParamEntity param) { + return getService().queryIncludeChildrenTree(param); + } + +} diff --git a/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_en.properties b/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_en.properties index ca9a3d786..47df2c6d2 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_en.properties +++ b/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_en.properties @@ -8,4 +8,5 @@ error.tree_entity_cyclic_dependency=Cannot modify parent node as oneself or one' error.tree_entity_parent_id_not_exist=Parent node does not exist or has been deleted error.resource_not_found=Resource not found error.data.find.not_found=Data not found -error.sql.prepare.failed.IndexOutOfBoundsException=Execute SQL failed, try check config: `easyorm.dialect`. \ No newline at end of file +error.sql.prepare.failed.IndexOutOfBoundsException=Execute SQL failed, try check config: `easyorm.dialect`. +error.missing_request_body=Required request body is missing \ No newline at end of file diff --git a/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_zh.properties b/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_zh.properties index 28b2e85ae..ae29dd68f 100644 --- a/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_zh.properties +++ b/hsweb-commons/hsweb-commons-crud/src/main/resources/i18n/commons/messages_zh.properties @@ -7,4 +7,5 @@ error.internal_server_error=\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF error.tree_entity_cyclic_dependency=\u4E0D\u80FD\u4FEE\u6539\u7236\u8282\u70B9\u4E3A\u81EA\u5DF1\u6216\u8005\u81EA\u5DF1\u7684\u5B50\u8282\u70B9 error.tree_entity_parent_id_not_exist=\u7236\u8282\u70B9\u4E0D\u5B58\u5728\u6216\u5DF2\u88AB\u5220\u9664 error.data.find.not_found=\u6570\u636E\u4E0D\u5B58\u5728 -error.sql.prepare.failed.IndexOutOfBoundsException=SQL\u6267\u884C\u5931\u8D25,\u8BF7\u5C1D\u8BD5\u68C0\u67E5`easyorm.dialect`\u914D\u7F6E. \ No newline at end of file +error.sql.prepare.failed.IndexOutOfBoundsException=SQL\u6267\u884C\u5931\u8D25,\u8BF7\u5C1D\u8BD5\u68C0\u67E5`easyorm.dialect`\u914D\u7F6E. +error.missing_request_body=\u8BF7\u6C42\u4F53\u7F3A\u5931 \ No newline at end of file diff --git a/hsweb-core/src/main/java/org/hswebframework/web/CodeConstants.java b/hsweb-core/src/main/java/org/hswebframework/web/CodeConstants.java index 388b5df05..310c32cd2 100644 --- a/hsweb-core/src/main/java/org/hswebframework/web/CodeConstants.java +++ b/hsweb-core/src/main/java/org/hswebframework/web/CodeConstants.java @@ -12,6 +12,8 @@ public interface CodeConstants { String unauthorized = "unauthorized"; String not_found="not_found"; + + String internal_server_error="internal_server_error"; } }