diff --git a/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java b/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java index 37f9fd3d8..70214dc4c 100644 --- a/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java +++ b/application/src/main/java/run/halo/app/theme/endpoint/CommentFinderEndpoint.java @@ -20,7 +20,6 @@ import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springdoc.core.fn.builders.schema.Builder; import org.springdoc.webflux.core.fn.SpringdocRouteBuilder; -import org.springframework.context.MessageSource; import org.springframework.data.domain.Sort; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -55,6 +54,7 @@ import run.halo.app.infra.utils.IpAddressUtils; import run.halo.app.theme.finders.CommentFinder; import run.halo.app.theme.finders.CommentPublicQueryService; import run.halo.app.theme.finders.vo.CommentVo; +import run.halo.app.theme.finders.vo.CommentWithReplyVo; import run.halo.app.theme.finders.vo.ReplyVo; /** @@ -69,7 +69,6 @@ public class CommentFinderEndpoint implements CustomEndpoint { private final ReplyService replyService; private final SystemConfigurableEnvironmentFetcher environmentFetcher; private final RateLimiterRegistry rateLimiterRegistry; - private final MessageSource messageSource; @Override public RouterFunction endpoint() { @@ -112,7 +111,7 @@ public class CommentFinderEndpoint implements CustomEndpoint { .description("List comments.") .tag(tag) .response(responseBuilder() - .implementation(ListResult.generateGenericClass(CommentVo.class)) + .implementation(ListResult.generateGenericClass(CommentWithReplyVo.class)) ); QueryParamBuildUtil.buildParametersFromType(builder, CommentQuery.class); }) @@ -212,6 +211,13 @@ public class CommentFinderEndpoint implements CustomEndpoint { Mono listComments(ServerRequest request) { CommentQuery commentQuery = new CommentQuery(request); return commentPublicQueryService.list(commentQuery.toRef(), commentQuery.toPageRequest()) + .flatMap(result -> { + if (commentQuery.getWithReplies()) { + return commentPublicQueryService.convertToWithReplyVo(result, + commentQuery.getReplySize()); + } + return Mono.just(result); + }) .flatMap(list -> ServerResponse.ok().bodyValue(list)); } @@ -278,6 +284,20 @@ public class CommentFinderEndpoint implements CustomEndpoint { return name; } + @Schema(description = "Whether to include replies. Default is false.", + defaultValue = "false") + public Boolean getWithReplies() { + var withReplies = queryParams.getFirst("withReplies"); + return StringUtils.isNotBlank(withReplies) && Boolean.parseBoolean(withReplies); + } + + @Schema(description = "Reply size of the comment, default is 10, only works when " + + "withReplies is true.", defaultValue = "10") + public int getReplySize() { + var replySize = queryParams.getFirst("replySize"); + return StringUtils.isNotBlank(replySize) ? Integer.parseInt(replySize) : 10; + } + @ArraySchema(uniqueItems = true, arraySchema = @Schema(name = "sort", description = "Sort property and direction of the list result. Supported fields: " diff --git a/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java b/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java index db0123ee5..b11d92f5a 100644 --- a/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java +++ b/application/src/main/java/run/halo/app/theme/finders/CommentPublicQueryService.java @@ -6,6 +6,7 @@ import run.halo.app.extension.ListResult; import run.halo.app.extension.PageRequest; import run.halo.app.extension.Ref; import run.halo.app.theme.finders.vo.CommentVo; +import run.halo.app.theme.finders.vo.CommentWithReplyVo; import run.halo.app.theme.finders.vo.ReplyVo; /** @@ -21,6 +22,9 @@ public interface CommentPublicQueryService { Mono> list(Ref ref, @Nullable PageRequest pageRequest); + Mono> convertToWithReplyVo(ListResult comments, + int replySize); + Mono> listReply(String commentName, @Nullable Integer page, @Nullable Integer size); diff --git a/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java b/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java index bf3bc0393..426b11077 100644 --- a/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java +++ b/application/src/main/java/run/halo/app/theme/finders/impl/CommentPublicQueryServiceImpl.java @@ -40,6 +40,7 @@ import run.halo.app.metrics.MeterUtils; import run.halo.app.theme.finders.CommentPublicQueryService; import run.halo.app.theme.finders.vo.CommentStatsVo; import run.halo.app.theme.finders.vo.CommentVo; +import run.halo.app.theme.finders.vo.CommentWithReplyVo; import run.halo.app.theme.finders.vo.ExtensionVoOperator; import run.halo.app.theme.finders.vo.ReplyVo; @@ -94,6 +95,26 @@ public class CommentPublicQueryServiceImpl implements CommentPublicQueryService .defaultIfEmpty(ListResult.emptyResult()); } + @Override + public Mono> convertToWithReplyVo(ListResult comments, + int replySize) { + return Flux.fromIterable(comments.getItems()) + .flatMap(commentVo -> { + var commentName = commentVo.getMetadata().getName(); + return listReply(commentName, 1, replySize) + .map(replyList -> CommentWithReplyVo.from(commentVo) + .setReplies(replyList) + ); + }) + .collectList() + .map(result -> new ListResult<>( + comments.getPage(), + comments.getSize(), + comments.getTotal(), + result) + ); + } + @Override public Mono> listReply(String commentName, Integer page, Integer size) { return listReply(commentName, PageRequestImpl.of(pageNullSafe(page), sizeNullSafe(size), diff --git a/application/src/main/java/run/halo/app/theme/finders/vo/CommentVo.java b/application/src/main/java/run/halo/app/theme/finders/vo/CommentVo.java index a6725b3c0..42b233794 100644 --- a/application/src/main/java/run/halo/app/theme/finders/vo/CommentVo.java +++ b/application/src/main/java/run/halo/app/theme/finders/vo/CommentVo.java @@ -3,9 +3,9 @@ package run.halo.app.theme.finders.vo; import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; import run.halo.app.content.comment.OwnerInfo; import run.halo.app.core.extension.content.Comment; import run.halo.app.extension.MetadataOperator; @@ -17,7 +17,7 @@ import run.halo.app.extension.MetadataOperator; * @since 2.0.0 */ @Data -@Builder +@Accessors(chain = true) @EqualsAndHashCode public class CommentVo implements ExtensionVoOperator { @@ -42,10 +42,9 @@ public class CommentVo implements ExtensionVoOperator { * @return a value object for {@link Comment} */ public static CommentVo from(Comment comment) { - return CommentVo.builder() - .metadata(comment.getMetadata()) - .spec(comment.getSpec()) - .status(comment.getStatus()) - .build(); + return new CommentVo() + .setMetadata(comment.getMetadata()) + .setSpec(comment.getSpec()) + .setStatus(comment.getStatus()); } } diff --git a/application/src/main/java/run/halo/app/theme/finders/vo/CommentWithReplyVo.java b/application/src/main/java/run/halo/app/theme/finders/vo/CommentWithReplyVo.java new file mode 100644 index 000000000..2e9019aed --- /dev/null +++ b/application/src/main/java/run/halo/app/theme/finders/vo/CommentWithReplyVo.java @@ -0,0 +1,31 @@ +package run.halo.app.theme.finders.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.beans.BeanUtils; +import run.halo.app.extension.ListResult; + +/** + *

A value object for comment with reply.

+ * + * @author guqing + * @since 2.14.0 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class CommentWithReplyVo extends CommentVo { + + private ListResult replies; + + /** + * Convert {@link CommentVo} to {@link CommentWithReplyVo}. + */ + public static CommentWithReplyVo from(CommentVo commentVo) { + var commentWithReply = new CommentWithReplyVo(); + BeanUtils.copyProperties(commentVo, commentWithReply); + commentWithReply.setReplies(ListResult.emptyResult()); + return commentWithReply; + } +}