diff --git a/src/main/java/cc/ryanc/halo/service/PostTagService.java b/src/main/java/cc/ryanc/halo/service/PostTagService.java index d47a72cfd..1b4b74138 100644 --- a/src/main/java/cc/ryanc/halo/service/PostTagService.java +++ b/src/main/java/cc/ryanc/halo/service/PostTagService.java @@ -5,6 +5,8 @@ import cc.ryanc.halo.model.entity.Post; import cc.ryanc.halo.model.entity.PostTag; import cc.ryanc.halo.model.entity.Tag; import cc.ryanc.halo.service.base.CrudService; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; @@ -58,6 +60,15 @@ public interface PostTagService extends CrudService { @NonNull List listPostsBy(@NonNull Integer tagId); + /** + * Pages posts by tag id. + * + * @param tagId must not be null + * @param pageable must not be null + * @return a page of post + */ + Page pagePostsBy(@NonNull Integer tagId, Pageable pageable); + /** * Merges or creates post tags by post id and tag id set if absent. * diff --git a/src/main/java/cc/ryanc/halo/service/TagService.java b/src/main/java/cc/ryanc/halo/service/TagService.java index 392fd9ba1..9fa6d89ef 100644 --- a/src/main/java/cc/ryanc/halo/service/TagService.java +++ b/src/main/java/cc/ryanc/halo/service/TagService.java @@ -21,7 +21,8 @@ public interface TagService extends CrudService { * @param slugName slug name * @return Tag */ - Tag getBySlugName(@NonNull String slugName); + @NonNull + Tag getBySlugNameOfNonNull(@NonNull String slugName); /** * Converts to tag output dtos. diff --git a/src/main/java/cc/ryanc/halo/service/impl/PostTagServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/PostTagServiceImpl.java index 00c3abbe9..15763683c 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/PostTagServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/PostTagServiceImpl.java @@ -11,6 +11,8 @@ import cc.ryanc.halo.repository.TagRepository; import cc.ryanc.halo.service.PostTagService; import cc.ryanc.halo.service.base.AbstractCrudService; import cc.ryanc.halo.utils.ServiceUtils; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.util.Assert; @@ -111,6 +113,17 @@ public class PostTagServiceImpl extends AbstractCrudService im return postRepository.findAllById(postIds); } + @Override + public Page pagePostsBy(Integer tagId, Pageable pageable) { + Assert.notNull(tagId, "Tag id must not be null"); + Assert.notNull(pageable, "Page info must not be null"); + + // Find all post ids + Set postIds = postTagRepository.findAllPostIdsByTagId(tagId); + + return postRepository.findAllByIdIn(postIds, pageable); + } + @Override public List mergeOrCreateByIfAbsent(Integer postId, Set tagIds) { Assert.notNull(postId, "Post id must not be null"); diff --git a/src/main/java/cc/ryanc/halo/service/impl/TagServiceImpl.java b/src/main/java/cc/ryanc/halo/service/impl/TagServiceImpl.java index dd84a6dc7..0bc794233 100644 --- a/src/main/java/cc/ryanc/halo/service/impl/TagServiceImpl.java +++ b/src/main/java/cc/ryanc/halo/service/impl/TagServiceImpl.java @@ -55,7 +55,7 @@ public class TagServiceImpl extends AbstractCrudService implements * @return Tag */ @Override - public Tag getBySlugName(String slugName) { + public Tag getBySlugNameOfNonNull(String slugName) { return tagRepository.getBySlugName(slugName).orElseThrow(() -> new NotFoundException("The tag does not exist").setErrorData(slugName)); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/content/ContentTagController.java b/src/main/java/cc/ryanc/halo/web/controller/content/ContentTagController.java index 720c0426b..bf10608cb 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/content/ContentTagController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/content/ContentTagController.java @@ -79,7 +79,7 @@ public class ContentTagController extends BaseContentController { @PathVariable("slugName") String slugName, @PathVariable("page") Integer page, @SortDefault(sort = "postDate", direction = DESC) Sort sort) { - final Tag tag = tagService.getBySlugName(slugName); + final Tag tag = tagService.getBySlugNameOfNonNull(slugName); if (null == tag) { return this.renderNotFound(); } diff --git a/src/main/java/cc/ryanc/halo/web/controller/portal/api/TagController.java b/src/main/java/cc/ryanc/halo/web/controller/portal/api/TagController.java index 71a6ee991..ee6d15fcb 100644 --- a/src/main/java/cc/ryanc/halo/web/controller/portal/api/TagController.java +++ b/src/main/java/cc/ryanc/halo/web/controller/portal/api/TagController.java @@ -1,18 +1,22 @@ package cc.ryanc.halo.web.controller.portal.api; import cc.ryanc.halo.model.dto.TagOutputDTO; +import cc.ryanc.halo.model.dto.post.PostSimpleOutputDTO; +import cc.ryanc.halo.model.entity.Tag; import cc.ryanc.halo.service.PostTagService; import cc.ryanc.halo.service.TagService; import io.swagger.annotations.ApiOperation; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; import org.springframework.data.web.SortDefault; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; +import static org.springframework.data.domain.Sort.Direction.DESC; + /** * Portal tag controller. * @@ -34,7 +38,7 @@ public class TagController { @GetMapping @ApiOperation("Lists tags") - public List listTags(@SortDefault(sort = "updateTime", direction = Sort.Direction.DESC) Sort sort, + public List listTags(@SortDefault(sort = "updateTime", direction = DESC) Sort sort, @RequestParam(name = "more", required = false, defaultValue = "false") Boolean more) { if (more) { return postTagService.listTagWithCountDtos(sort); @@ -42,4 +46,14 @@ public class TagController { return tagService.convertTo(tagService.listAll(sort)); } + @GetMapping("{slugName}/posts") + @ApiOperation("Lists posts by tag slug name") + public Page listPostsBy(@PathVariable("slugName") String slugName, + @PageableDefault(sort = "updateTime", direction = DESC) Pageable pageable) { + // Get tag by slug name + Tag tag = tagService.getBySlugNameOfNonNull(slugName); + + // Get posts, convert and return + return postTagService.pagePostsBy(tag.getId(), pageable).map(post -> new PostSimpleOutputDTO().convertFrom(post)); + } }