diff --git a/src/main/java/run/halo/app/core/extension/Category.java b/src/main/java/run/halo/app/core/extension/Category.java index bec7b4583..ea865844d 100644 --- a/src/main/java/run/halo/app/core/extension/Category.java +++ b/src/main/java/run/halo/app/core/extension/Category.java @@ -67,8 +67,13 @@ public class Category extends AbstractExtension { private String permalink; /** - * 包括当前和其下所有层级的文章 name (depth=max). + * 包括当前和其下所有层级的文章数量 (depth=max). */ - private List posts; + public Integer postCount; + + /** + * 包括当前和其下所有层级的已发布且公开的文章数量 (depth=max). + */ + public Integer visiblePostCount; } } diff --git a/src/main/java/run/halo/app/core/extension/Tag.java b/src/main/java/run/halo/app/core/extension/Tag.java index bafc14f65..4397a6345 100644 --- a/src/main/java/run/halo/app/core/extension/Tag.java +++ b/src/main/java/run/halo/app/core/extension/Tag.java @@ -2,7 +2,6 @@ package run.halo.app.core.extension; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; @@ -69,6 +68,8 @@ public class Tag extends AbstractExtension { private String permalink; - private List posts; + public Integer visiblePostCount; + + public Integer postCount; } } diff --git a/src/main/java/run/halo/app/core/extension/reconciler/CategoryReconciler.java b/src/main/java/run/halo/app/core/extension/reconciler/CategoryReconciler.java index 4d5bc5966..ee71ae9cb 100644 --- a/src/main/java/run/halo/app/core/extension/reconciler/CategoryReconciler.java +++ b/src/main/java/run/halo/app/core/extension/reconciler/CategoryReconciler.java @@ -7,6 +7,7 @@ import java.util.Deque; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; @@ -131,7 +132,13 @@ public class CategoryReconciler implements Reconciler { .published(post.isPublished()) .build()) .toList(); - category.getStatusOrDefault().setPosts(compactPosts); + category.getStatusOrDefault().setPostCount(compactPosts.size()); + + long visiblePostCount = compactPosts.stream() + .filter(post -> Objects.equals(true, post.getPublished()) + && Post.VisibleEnum.PUBLIC.equals(post.getVisible())) + .count(); + category.getStatusOrDefault().setVisiblePostCount((int) visiblePostCount); } /** diff --git a/src/main/java/run/halo/app/core/extension/reconciler/TagReconciler.java b/src/main/java/run/halo/app/core/extension/reconciler/TagReconciler.java index c4ccbc932..74316cdd6 100644 --- a/src/main/java/run/halo/app/core/extension/reconciler/TagReconciler.java +++ b/src/main/java/run/halo/app/core/extension/reconciler/TagReconciler.java @@ -3,6 +3,7 @@ package run.halo.app.core.extension.reconciler; import java.time.Duration; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import run.halo.app.content.permalinks.TagPermalinkPolicy; import run.halo.app.core.extension.Post; @@ -115,7 +116,13 @@ public class TagReconciler implements Reconciler { .visible(post.getSpec().getVisible()) .build()) .toList(); - tag.getStatusOrDefault().setPosts(compactPosts); + tag.getStatusOrDefault().setPostCount(compactPosts.size()); + + long visiblePostCount = compactPosts.stream() + .filter(post -> Objects.equals(true, post.getPublished()) + && Post.VisibleEnum.PUBLIC.equals(post.getVisible())) + .count(); + tag.getStatusOrDefault().setVisiblePostCount((int) visiblePostCount); } private boolean includes(List tags, String tagName) { diff --git a/src/main/java/run/halo/app/theme/finders/vo/CategoryTreeVo.java b/src/main/java/run/halo/app/theme/finders/vo/CategoryTreeVo.java index 4276992ec..ffc8296df 100644 --- a/src/main/java/run/halo/app/theme/finders/vo/CategoryTreeVo.java +++ b/src/main/java/run/halo/app/theme/finders/vo/CategoryTreeVo.java @@ -1,14 +1,12 @@ package run.halo.app.theme.finders.vo; import java.util.List; -import java.util.Objects; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.util.Assert; import run.halo.app.core.extension.Category; -import run.halo.app.core.extension.Post; import run.halo.app.extension.MetadataOperator; /** @@ -33,6 +31,8 @@ public class CategoryTreeVo { private String parentName; + private Integer postCount; + /** * Convert {@link CategoryVo} to {@link CategoryTreeVo}. * @@ -46,21 +46,7 @@ public class CategoryTreeVo { .spec(category.getSpec()) .status(category.getStatus()) .children(List.of()) + .postCount(category.getPostCount()) .build(); } - - /** - * Gets the number of posts under the current category and its sub categories. - * - * @return the number of posts - */ - public long postCount() { - if (this.status == null || this.status.getPosts() == null) { - return 0; - } - return this.status.getPosts().stream() - .filter(post -> Objects.equals(true, post.getPublished()) - && Post.VisibleEnum.PUBLIC.equals(post.getVisible())) - .count(); - } } diff --git a/src/main/java/run/halo/app/theme/finders/vo/CategoryVo.java b/src/main/java/run/halo/app/theme/finders/vo/CategoryVo.java index 0aa77d572..8222be38b 100644 --- a/src/main/java/run/halo/app/theme/finders/vo/CategoryVo.java +++ b/src/main/java/run/halo/app/theme/finders/vo/CategoryVo.java @@ -1,11 +1,9 @@ package run.halo.app.theme.finders.vo; -import java.util.Objects; import lombok.Builder; import lombok.EqualsAndHashCode; import lombok.Value; import run.halo.app.core.extension.Category; -import run.halo.app.core.extension.Post; import run.halo.app.extension.MetadataOperator; /** @@ -25,6 +23,8 @@ public class CategoryVo { Category.CategoryStatus status; + Integer postCount; + /** * Convert {@link Category} to {@link CategoryVo}. * @@ -36,21 +36,7 @@ public class CategoryVo { .metadata(category.getMetadata()) .spec(category.getSpec()) .status(category.getStatus()) + .postCount(category.getStatusOrDefault().visiblePostCount) .build(); } - - /** - * Gets the number of posts under the current category and its sub categories. - * - * @return the number of posts - */ - public long postCount() { - if (this.status == null || this.status.getPosts() == null) { - return 0; - } - return this.status.getPosts().stream() - .filter(post -> Objects.equals(true, post.getPublished()) - && Post.VisibleEnum.PUBLIC.equals(post.getVisible())) - .count(); - } } diff --git a/src/main/java/run/halo/app/theme/finders/vo/TagVo.java b/src/main/java/run/halo/app/theme/finders/vo/TagVo.java index ce1835680..5d6625a26 100644 --- a/src/main/java/run/halo/app/theme/finders/vo/TagVo.java +++ b/src/main/java/run/halo/app/theme/finders/vo/TagVo.java @@ -1,9 +1,7 @@ package run.halo.app.theme.finders.vo; -import java.util.Objects; import lombok.Builder; import lombok.Value; -import run.halo.app.core.extension.Post; import run.halo.app.core.extension.Tag; import run.halo.app.extension.MetadataOperator; @@ -20,6 +18,8 @@ public class TagVo { Tag.TagStatus status; + Integer postCount; + /** * Convert {@link Tag} to {@link TagVo}. * @@ -33,22 +33,7 @@ public class TagVo { .metadata(tag.getMetadata()) .spec(spec) .status(status) + .postCount(tag.getStatusOrDefault().getVisiblePostCount()) .build(); } - - /** - * Gets the number of posts under the current tag. - * - * @return the number of posts - */ - public long postCount() { - if (this.status == null || this.status.getPosts() == null) { - return 0; - } - return this.status.getPosts() - .stream() - .filter(post -> Objects.equals(true, post.getPublished()) - && Post.VisibleEnum.PUBLIC.equals(post.getVisible())) - .count(); - } } diff --git a/src/test/java/run/halo/app/core/extension/reconciler/CategoryReconcilerTest.java b/src/test/java/run/halo/app/core/extension/reconciler/CategoryReconcilerTest.java index f562e465d..52d243bf0 100644 --- a/src/test/java/run/halo/app/core/extension/reconciler/CategoryReconcilerTest.java +++ b/src/test/java/run/halo/app/core/extension/reconciler/CategoryReconcilerTest.java @@ -17,7 +17,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.skyscreamer.jsonassert.JSONAssert; import run.halo.app.content.TestPost; import run.halo.app.content.permalinks.CategoryPermalinkPolicy; import run.halo.app.core.extension.Category; @@ -25,7 +24,6 @@ import run.halo.app.core.extension.Post; import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.Metadata; import run.halo.app.extension.controller.Reconciler; -import run.halo.app.infra.utils.JsonUtils; /** * Tests for {@link CategoryReconciler}. @@ -50,32 +48,9 @@ class CategoryReconcilerTest { ArgumentCaptor captor = ArgumentCaptor.forClass(Category.class); verify(client, times(2)).update(captor.capture()); - JSONAssert.assertEquals(""" - [ - { - "name": "post-1", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-2", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-3", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-4", - "visible": "PUBLIC", - "published": false - } - ] - """, - JsonUtils.objectToJson(captor.getAllValues().get(1).getStatusOrDefault().getPosts()), - true); + assertThat(captor.getAllValues().get(1).getStatusOrDefault().getPostCount()).isEqualTo(4); + assertThat( + captor.getAllValues().get(1).getStatusOrDefault().getVisiblePostCount()).isEqualTo(0); } @Test @@ -83,27 +58,9 @@ class CategoryReconcilerTest { reconcileStatusPostPilling("category-B"); ArgumentCaptor captor = ArgumentCaptor.forClass(Category.class); verify(client, times(2)).update(captor.capture()); - JSONAssert.assertEquals(""" - [ - { - "name": "post-1", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-2", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-3", - "visible": "PUBLIC", - "published": false - } - ] - """, - JsonUtils.objectToJson(captor.getAllValues().get(1).getStatusOrDefault().getPosts()), - true); + Category category = captor.getAllValues().get(1); + assertThat(category.getStatusOrDefault().getPostCount()).isEqualTo(3); + assertThat(category.getStatusOrDefault().getVisiblePostCount()).isEqualTo(0); } @Test @@ -111,22 +68,9 @@ class CategoryReconcilerTest { reconcileStatusPostPilling("category-C"); ArgumentCaptor captor = ArgumentCaptor.forClass(Category.class); verify(client, times(2)).update(captor.capture()); - JSONAssert.assertEquals(""" - [ - { - "name": "post-1", - "visible": "PUBLIC", - "published": false - }, - { - "name": "post-2", - "visible": "PUBLIC", - "published": false - } - ] - """, - JsonUtils.objectToJson(captor.getAllValues().get(1).getStatusOrDefault().getPosts()), - true); + assertThat(captor.getAllValues().get(1).getStatusOrDefault().getPostCount()).isEqualTo(2); + assertThat( + captor.getAllValues().get(1).getStatusOrDefault().getVisiblePostCount()).isEqualTo(0); } @Test @@ -134,17 +78,8 @@ class CategoryReconcilerTest { reconcileStatusPostPilling("category-D"); ArgumentCaptor captor = ArgumentCaptor.forClass(Category.class); verify(client, times(2)).update(captor.capture()); - JSONAssert.assertEquals(""" - [ - { - "name": "post-1", - "visible": "PUBLIC", - "published": false - } - ] - """, - JsonUtils.objectToJson(captor.getAllValues().get(1).getStatusOrDefault().getPosts()), - true); + assertThat(captor.getAllValues().get(1).getStatusOrDefault().postCount).isEqualTo(1); + assertThat(captor.getAllValues().get(1).getStatusOrDefault().visiblePostCount).isEqualTo(0); } diff --git a/src/test/java/run/halo/app/core/extension/reconciler/TagReconcilerTest.java b/src/test/java/run/halo/app/core/extension/reconciler/TagReconcilerTest.java index 018d7ccb6..db12b7f40 100644 --- a/src/test/java/run/halo/app/core/extension/reconciler/TagReconcilerTest.java +++ b/src/test/java/run/halo/app/core/extension/reconciler/TagReconcilerTest.java @@ -10,21 +10,18 @@ import static org.mockito.Mockito.when; import java.time.Instant; import java.util.List; import java.util.Optional; -import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.skyscreamer.jsonassert.JSONAssert; import run.halo.app.content.TestPost; import run.halo.app.content.permalinks.TagPermalinkPolicy; import run.halo.app.core.extension.Post; import run.halo.app.core.extension.Tag; import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.Metadata; -import run.halo.app.infra.utils.JsonUtils; /** * Tests for {@link TagReconciler}. @@ -85,7 +82,7 @@ class TagReconcilerTest { } @Test - void reconcileStatusPosts() throws JSONException { + void reconcileStatusPosts() { Tag tag = tag(); when(client.fetch(eq(Tag.class), eq("fake-tag"))) .thenReturn(Optional.of(tag)); @@ -95,20 +92,8 @@ class TagReconcilerTest { tagReconciler.reconcile(new TagReconciler.Request("fake-tag")); verify(client, times(2)).update(captor.capture()); List allValues = captor.getAllValues(); - List posts = allValues.get(1).getStatusOrDefault().getPosts(); - JSONAssert.assertEquals(""" - [{ - "name": "fake-post-1", - "published": false, - "visible": "PUBLIC" - }, - { - "name": "fake-post-3", - "published": false, - "visible": "PRIVATE" - }] - """, - JsonUtils.objectToJson(posts), true); + assertThat(allValues.get(1).getStatusOrDefault().getPostCount()).isEqualTo(2); + assertThat(allValues.get(1).getStatusOrDefault().getVisiblePostCount()).isEqualTo(0); } Tag tag() { diff --git a/src/test/java/run/halo/app/theme/finders/impl/TagFinderImplTest.java b/src/test/java/run/halo/app/theme/finders/impl/TagFinderImplTest.java index 00cb49857..66b503b16 100644 --- a/src/test/java/run/halo/app/theme/finders/impl/TagFinderImplTest.java +++ b/src/test/java/run/halo/app/theme/finders/impl/TagFinderImplTest.java @@ -65,8 +65,10 @@ class TagFinderImplTest { }, "status": { "permalink": "permalink-1", - "posts": [] - } + "postCount": 2, + "visiblePostCount": 1 + }, + "postCount": 1 } """, JsonUtils.objectToJson(tagVo), @@ -117,7 +119,8 @@ class TagFinderImplTest { Tag.TagStatus tagStatus = new Tag.TagStatus(); tagStatus.setPermalink("permalink-" + i); - tagStatus.setPosts(List.of()); + tagStatus.setPostCount(2); + tagStatus.setVisiblePostCount(1); tag.setStatus(tagStatus); return tag; }