From a6c128da648be5ca25fa2f7d96f5d9f47baba309 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Tue, 3 Dec 2024 13:00:16 +0800 Subject: [PATCH] =?UTF-8?q?feat(web):=20=E5=A2=9E=E5=8A=A0REST=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E6=9F=A5=E8=AF=A2=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AuthenticationController.java | 2 +- .../base/controller/DetailController.java | 2 + .../base/controller/ListController.java | 2 + .../controller/SimpleControllerSupport.java | 21 ++- .../base/controller/query/DetailQuery.java | 52 ++++++ .../base/controller/query/ListQuery.java | 53 +++++++ .../base/service/LogicDeleteService.java | 7 +- .../domain/base/service/SimpleService.java | 12 ++ .../base/service/SimpleServiceSupport.java | 150 +++++++++++++----- .../controller/CheckOrderController.java | 6 + .../controller/ConfirmationController.java | 2 +- .../eshore/gringotts/web/TestQueryParse.java | 69 ++++++++ 12 files changed, 331 insertions(+), 47 deletions(-) create mode 100644 gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/DetailQuery.java create mode 100644 gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/ListQuery.java create mode 100644 gringotts-web/src/test/java/com/eshore/gringotts/web/TestQueryParse.java diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java index 4dec07c..f0d55bc 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/authentication/controller/AuthenticationController.java @@ -36,7 +36,7 @@ public class AuthenticationController extends SimpleControllerSupport { AmisResponse detail(Long id) throws Exception; + AmisResponse detail(DetailQuery query) throws Exception; } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/ListController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/ListController.java index 2334b4a..7ff1779 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/ListController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/ListController.java @@ -1,6 +1,7 @@ package com.eshore.gringotts.web.domain.base.controller; import com.eshore.gringotts.web.configuration.amis.AmisResponse; +import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import org.eclipse.collections.api.list.ImmutableList; /** @@ -9,4 +10,5 @@ import org.eclipse.collections.api.list.ImmutableList; */ public interface ListController { AmisResponse> list() throws Exception; + AmisResponse> list(ListQuery query) throws Exception; } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/SimpleControllerSupport.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/SimpleControllerSupport.java index a3b3ad4..d24d58e 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/SimpleControllerSupport.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/SimpleControllerSupport.java @@ -1,6 +1,8 @@ package com.eshore.gringotts.web.domain.base.controller; import com.eshore.gringotts.web.configuration.amis.AmisResponse; +import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; +import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.service.SimpleServiceSupport; import org.eclipse.collections.api.list.ImmutableList; @@ -16,7 +18,8 @@ import org.springframework.web.bind.annotation.RequestBody; public abstract class SimpleControllerSupport implements SimpleController { protected static final String SAVE = "/save"; protected static final String LIST = "/list"; - protected static final String DETAIL = "/detail/{id}"; + protected static final String DETAIL_ID = "/detail/{id}"; + protected static final String DETAIL = "/detail"; protected static final String REMOVE = "/remove/{id}"; private final SimpleServiceSupport service; @@ -33,7 +36,7 @@ public abstract class SimpleControllerSupport> list() { + public AmisResponse> list() throws Exception { return AmisResponse.responseSuccess(service.list().collect(entity -> { try { return toListItem(entity); @@ -43,12 +46,24 @@ public abstract class SimpleControllerSupport> list(@RequestBody ListQuery query) throws Exception { + return null; + } + + @GetMapping(DETAIL_ID) @Override public AmisResponse detail(@PathVariable Long id) throws Exception { return AmisResponse.responseSuccess(toDetailItem(service.detail(id))); } + @PostMapping(DETAIL) + @Override + public AmisResponse detail(@RequestBody DetailQuery query) throws Exception { + return null; + } + @GetMapping(REMOVE) @Override public AmisResponse remove(@PathVariable Long id) { diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/DetailQuery.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/DetailQuery.java new file mode 100644 index 0000000..ce40e26 --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/DetailQuery.java @@ -0,0 +1,52 @@ +package com.eshore.gringotts.web.domain.base.controller.query; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.eclipse.collections.api.list.ImmutableList; +import org.eclipse.collections.api.map.ImmutableMap; + +/** + * 统一查询 + * + * @author lanyuanxiaoyao + * @date 2024-12-03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class DetailQuery { + private Queryable query; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class Queryable { + private ImmutableList nullEqual; + private ImmutableList notNullEqual; + private ImmutableList empty; + private ImmutableList notEmpty; + private ImmutableMap equal; + private ImmutableMap notEqual; + private ImmutableMap like; + private ImmutableMap notLike; + private ImmutableMap great; + private ImmutableMap less; + private ImmutableMap greatEqual; + private ImmutableMap lessEqual; + private ImmutableMap> in; + private ImmutableMap> notIn; + private ImmutableMap between; + private ImmutableMap notBetween; + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Between { + private String start; + private String end; + } + } +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/ListQuery.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/ListQuery.java new file mode 100644 index 0000000..dd23f15 --- /dev/null +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/controller/query/ListQuery.java @@ -0,0 +1,53 @@ +package com.eshore.gringotts.web.domain.base.controller.query; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.eclipse.collections.api.list.ImmutableList; + +/** + * @author lanyuanxiaoyao + * @date 2024-12-03 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +@ToString(callSuper = true) +@EqualsAndHashCode(callSuper = true) +public class ListQuery extends DetailQuery { + private ImmutableList sort; + private Pageable page; + + public ListQuery(Queryable query) { + super(query); + } + + public ListQuery(Queryable query, ImmutableList sort, Pageable page) { + super(query); + this.sort = sort; + this.page = page; + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Sortable { + private String column; + private Direction direction; + + public enum Direction { + ASC, + DESC, + } + } + + @Data + @NoArgsConstructor + @AllArgsConstructor + public static class Pageable { + private Integer page = 1; + private Integer size = 10; + } +} diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/LogicDeleteService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/LogicDeleteService.java index d862d5e..0c635a0 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/LogicDeleteService.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/LogicDeleteService.java @@ -30,12 +30,7 @@ public abstract class LogicDeleteService exten } @Override - protected ImmutableList extraListPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return Lists.immutable.of(builder.equal(root.get("deleted"), false)); - } - - @Override - protected ImmutableList extraDetailPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { + protected ImmutableList listPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { return Lists.immutable.of(builder.equal(root.get("deleted"), false)); } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java index cd5505d..a502019 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleService.java @@ -1,5 +1,7 @@ package com.eshore.gringotts.web.domain.base.service; +import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; +import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import java.util.Optional; import org.eclipse.collections.api.list.ImmutableList; @@ -16,13 +18,23 @@ public interface SimpleService { ImmutableList list(ImmutableSet ids) throws Exception; + ImmutableList list(ListQuery query) throws Exception; + Optional detailOptional(Long id) throws Exception; + Optional detailOptional(DetailQuery query) throws Exception; + ENTITY detail(Long id) throws Exception; + ENTITY detail(DetailQuery query) throws Exception; + ENTITY detailOrThrow(Long id) throws Exception; + ENTITY detailOrThrow(DetailQuery query) throws Exception; + ENTITY detailOrNull(Long id) throws Exception; + ENTITY detailOrNull(DetailQuery query) throws Exception; + void remove(Long id) throws Exception; } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleServiceSupport.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleServiceSupport.java index 8900c3a..b1b00ce 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleServiceSupport.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/base/service/SimpleServiceSupport.java @@ -4,6 +4,8 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import com.eshore.gringotts.web.domain.base.controller.query.DetailQuery; +import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.base.entity.SimpleEntity; import com.eshore.gringotts.web.domain.base.repository.SimpleRepository; import com.eshore.gringotts.web.domain.user.entity.User; @@ -59,43 +61,99 @@ public abstract class SimpleServiceSupport implemen } @Override - public ImmutableList list() { - return Lists.immutable.ofAll(repository.findAll( - (root, query, builder) -> { - MutableList predicates = Lists.mutable.empty(); - User user = userService.currentLoginUser(); - if (User.isNotAdministrator(user)) { - predicates.add(builder.equal(root.get("createdUser"), user)); - } - predicates.addAllIterable(extraListPredicates(root, query, builder)); - return builder.and(predicates.toArray(new Predicate[predicates.size()])); - }, - Sort.by("createdTime").descending() - )); + public ImmutableList list() throws Exception { + return Lists.immutable.ofAll(repository.findAll((root, query, builder) -> builder.and(listPredicates(root, query, builder).toArray(new Predicate[]{})))); } @Override - public ImmutableList list(ImmutableSet ids) { + public ImmutableList list(ImmutableSet ids) throws Exception { return Lists.immutable.ofAll(repository.findAll( (root, query, builder) -> { - MutableList predicates = Lists.mutable.of( - builder.in(root.get("id")).value(ids.select(ObjectUtil::isNotNull)) - ); - User user = userService.currentLoginUser(); - if (User.isNotAdministrator(user)) { - predicates.add(builder.equal(root.get("createdUser"), user)); - } - predicates.addAllIterable(extraListPredicates(root, query, builder)); + MutableList predicates = Lists.mutable.ofAll(listPredicates(root, query, builder)); + predicates.add(builder.in(root.get("id")).value(ids)); + return builder.and(predicates.toArray(new Predicate[predicates.size()])); + } + )); + } + + @SuppressWarnings("unchecked") + private ImmutableList queryPredicates(DetailQuery.Queryable queryable, Root root, CriteriaQuery query, CriteriaBuilder builder) { + MutableList predicates = Lists.mutable.empty(); + if (ObjectUtil.isEmpty(queryable)) { + return predicates.toImmutable(); + } + if (ObjectUtil.isNotEmpty(queryable.getNullEqual())) { + queryable.getNullEqual().forEach(column -> predicates.add(builder.isNull(root.get(column)))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotNullEqual())) { + queryable.getNotNullEqual().forEach(column -> predicates.add(builder.isNull(root.get(column)))); + } + if (ObjectUtil.isNotEmpty(queryable.getEmpty())) { + queryable.getEmpty().forEach(column -> predicates.add(builder.isEmpty(root.get(column)))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotEmpty())) { + queryable.getNotEmpty().forEach(column -> predicates.add(builder.isNotEmpty(root.get(column)))); + } + if (ObjectUtil.isNotEmpty(queryable.getEqual())) { + queryable.getEqual().forEachKeyValue((column, value) -> predicates.add(builder.equal(root.get(column), value))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotEqual())) { + queryable.getEqual().forEachKeyValue((column, value) -> predicates.add(builder.notEqual(root.get(column), value))); + } + if (ObjectUtil.isNotEmpty(queryable.getLike())) { + queryable.getLike().forEachKeyValue((column, value) -> predicates.add(builder.like(root.get(column), value))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotLike())) { + queryable.getNotLike().forEachKeyValue((column, value) -> predicates.add(builder.notLike(root.get(column), value))); + } + if (ObjectUtil.isNotEmpty(queryable.getGreat())) { + queryable.getGreat().forEachKeyValue((column, value) -> predicates.add(builder.greaterThan(root.get(column), (Comparable) value))); + } + if (ObjectUtil.isNotEmpty(queryable.getLess())) { + queryable.getLess().forEachKeyValue((column, value) -> predicates.add(builder.lessThan(root.get(column), (Comparable) value))); + } + if (ObjectUtil.isNotEmpty(queryable.getGreatEqual())) { + queryable.getGreatEqual().forEachKeyValue((column, value) -> predicates.add(builder.greaterThanOrEqualTo(root.get(column), (Comparable) value))); + } + if (ObjectUtil.isNotEmpty(queryable.getLessEqual())) { + queryable.getLessEqual().forEachKeyValue((column, value) -> predicates.add(builder.lessThanOrEqualTo(root.get(column), (Comparable) value))); + } + if (ObjectUtil.isNotEmpty(queryable.getIn())) { + queryable.getIn().forEachKeyValue((column, value) -> predicates.add(builder.in(root.get(column)).value(value))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotIn())) { + queryable.getNotIn().forEachKeyValue((column, value) -> predicates.add(builder.in(root.get(column)).value(value).not())); + } + if (ObjectUtil.isNotEmpty(queryable.getBetween())) { + queryable.getBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(root.get(column), value.getStart(), value.getEnd()))); + } + if (ObjectUtil.isNotEmpty(queryable.getNotBetween())) { + queryable.getNotBetween().forEachKeyValue((column, value) -> predicates.add(builder.between(root.get(column), value.getStart(), value.getEnd()))); + } + return predicates.toImmutable(); + } + + protected ImmutableList listPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { + MutableList predicates = Lists.mutable.empty(); + User user = userService.currentLoginUser(); + if (User.isNotAdministrator(user)) { + predicates.add(builder.equal(root.get("createdUser"), user)); + } + return predicates.toImmutable(); + } + + @Override + public ImmutableList list(ListQuery listQuery) throws Exception { + return Lists.immutable.ofAll(repository.findAll( + (root, query, builder) -> { + MutableList predicates = Lists.mutable.ofAll(listPredicates(root, query, builder)); + predicates.addAllIterable(queryPredicates(listQuery.getQuery(), root, query, builder)); return builder.and(predicates.toArray(new Predicate[predicates.size()])); }, Sort.by("createdTime").descending() )); } - protected ImmutableList extraListPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return Lists.immutable.empty(); - } - @Override public Optional detailOptional(Long id) { if (ObjectUtil.isNull(id)) { @@ -103,21 +161,22 @@ public abstract class SimpleServiceSupport implemen } return repository.findOne( (root, query, builder) -> { - MutableList predicates = Lists.mutable.of( - builder.equal(root.get("id"), id) - ); - User user = userService.currentLoginUser(); - if (User.isNotAdministrator(user)) { - predicates.add(builder.equal(root.get("createdUser"), user)); - } - predicates.addAllIterable(extraDetailPredicates(root, query, builder)); + MutableList predicates = Lists.mutable.ofAll(listPredicates(root, query, builder)); + predicates.add(builder.equal(root.get("id"), id)); return builder.and(predicates.toArray(new Predicate[predicates.size()])); } ); } - protected ImmutableList extraDetailPredicates(Root root, CriteriaQuery query, CriteriaBuilder builder) { - return Lists.immutable.empty(); + @Override + public Optional detailOptional(DetailQuery detailQuery) throws Exception { + return repository.findOne( + (root, query, builder) -> { + MutableList predicates = Lists.mutable.ofAll(listPredicates(root, query, builder)); + predicates.addAllIterable(queryPredicates(detailQuery.getQuery(), root, query, builder)); + return builder.and(predicates.toArray(new Predicate[predicates.size()])); + } + ); } @Override @@ -125,16 +184,31 @@ public abstract class SimpleServiceSupport implemen return detailOrNull(id); } + @Override + public ENTITY detail(DetailQuery query) throws Exception { + return detailOrNull(query); + } + @Override public ENTITY detailOrThrow(Long id) { return detailOptional(id).orElseThrow(() -> new IdNotFoundException(id)); } + @Override + public ENTITY detailOrThrow(DetailQuery query) throws Exception { + return detailOptional(query).orElseThrow(IdNotFoundException::new); + } + @Override public ENTITY detailOrNull(Long id) { return detailOptional(id).orElse(null); } + @Override + public ENTITY detailOrNull(DetailQuery query) throws Exception { + return detailOptional(query).orElse(null); + } + @Transactional(rollbackOn = Throwable.class) @Override public void remove(Long id) { @@ -144,6 +218,10 @@ public abstract class SimpleServiceSupport implemen } public static final class IdNotFoundException extends RuntimeException { + public IdNotFoundException() { + super("资源不存在"); + } + public IdNotFoundException(Long id) { super(StrUtil.format("ID为{}的资源不存在", id)); } diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/check/controller/CheckOrderController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/check/controller/CheckOrderController.java index d7887be..b59ae66 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/check/controller/CheckOrderController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/check/controller/CheckOrderController.java @@ -2,6 +2,7 @@ package com.eshore.gringotts.web.domain.check.controller; import com.eshore.gringotts.web.configuration.amis.AmisResponse; import com.eshore.gringotts.web.domain.base.controller.ListController; +import com.eshore.gringotts.web.domain.base.controller.query.ListQuery; import com.eshore.gringotts.web.domain.check.entity.CheckOrder; import com.eshore.gringotts.web.domain.check.service.CheckOrderService; import com.fasterxml.jackson.core.JsonProcessingException; @@ -43,6 +44,11 @@ public class CheckOrderController implements ListController> list(ListQuery query) throws Exception { + return AmisResponse.responseSuccess(checkOrderService.list().collect(this::toListItem)); + } + @SneakyThrows private ListItem toListItem(CheckOrder order) { ListItem item = new ListItem(); diff --git a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/confirmation/controller/ConfirmationController.java b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/confirmation/controller/ConfirmationController.java index 828c5d5..46804d7 100644 --- a/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/confirmation/controller/ConfirmationController.java +++ b/gringotts-web/src/main/java/com/eshore/gringotts/web/domain/confirmation/controller/ConfirmationController.java @@ -53,7 +53,7 @@ public class ConfirmationController extends SimpleControllerSupport