mirror of https://github.com/halo-dev/halo
feat: add site stats finder for theme-side (#2604)
#### What type of PR is this? /kind feature /area core /milestone 2.0 #### What this PR does / why we need it: 提供主题端站点统计信息查询器 #### Which issue(s) this PR fixes: Fixes # #### Special notes for your reviewer: how to test it? 在任意主题页面使用如下语法 ``` <p th:text="${siteStatsFinder.getStats()}"></p> ``` /cc @halo-dev/sig-halo #### Does this PR introduce a user-facing change? ```release-note 提供主题端站点统计信息查询器 ```pull/2613/head^2
parent
6b2aea9301
commit
969c0d56f6
|
@ -0,0 +1,14 @@
|
||||||
|
package run.halo.app.theme.finders;
|
||||||
|
|
||||||
|
import run.halo.app.theme.finders.vo.SiteStatsVo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Site statistics finder.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
public interface SiteStatsFinder {
|
||||||
|
|
||||||
|
SiteStatsVo getStats();
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package run.halo.app.theme.finders.impl;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import run.halo.app.core.extension.Category;
|
||||||
|
import run.halo.app.core.extension.Counter;
|
||||||
|
import run.halo.app.core.extension.Post;
|
||||||
|
import run.halo.app.extension.ReactiveExtensionClient;
|
||||||
|
import run.halo.app.theme.finders.Finder;
|
||||||
|
import run.halo.app.theme.finders.SiteStatsFinder;
|
||||||
|
import run.halo.app.theme.finders.vo.SiteStatsVo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A default implementation of {@link SiteStatsFinder}.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Finder("siteStatsFinder")
|
||||||
|
public class SiteStatsFinderImpl implements SiteStatsFinder {
|
||||||
|
private final ReactiveExtensionClient client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SiteStatsVo getStats() {
|
||||||
|
return client.list(Counter.class, null, null)
|
||||||
|
.reduce(SiteStatsVo.empty(), (stats, counter) -> {
|
||||||
|
stats.setVisit(stats.getVisit() + counter.getVisit());
|
||||||
|
stats.setComment(stats.getComment() + counter.getApprovedComment());
|
||||||
|
stats.setUpvote(stats.getUpvote() + counter.getUpvote());
|
||||||
|
return stats;
|
||||||
|
})
|
||||||
|
.flatMap(siteStatsVo -> postCount()
|
||||||
|
.doOnNext(siteStatsVo::setPost)
|
||||||
|
.thenReturn(siteStatsVo)
|
||||||
|
)
|
||||||
|
.flatMap(siteStatsVo -> categoryCount()
|
||||||
|
.doOnNext(siteStatsVo::setCategory)
|
||||||
|
.thenReturn(siteStatsVo))
|
||||||
|
.block();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mono<Integer> postCount() {
|
||||||
|
return client.list(Post.class, post -> !post.isDeleted() && post.isPublished(), null)
|
||||||
|
.count()
|
||||||
|
.map(Long::intValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mono<Integer> categoryCount() {
|
||||||
|
return client.list(Category.class, null, null)
|
||||||
|
.count()
|
||||||
|
.map(Long::intValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package run.halo.app.theme.finders.vo;
|
||||||
|
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A value object for site stats.
|
||||||
|
*
|
||||||
|
* @author guqing
|
||||||
|
* @since 2.0.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public class SiteStatsVo {
|
||||||
|
|
||||||
|
private Integer visit;
|
||||||
|
|
||||||
|
private Integer upvote;
|
||||||
|
|
||||||
|
private Integer comment;
|
||||||
|
|
||||||
|
private Integer post;
|
||||||
|
|
||||||
|
private Integer category;
|
||||||
|
|
||||||
|
public static SiteStatsVo empty() {
|
||||||
|
return SiteStatsVo.builder()
|
||||||
|
.visit(0)
|
||||||
|
.upvote(0)
|
||||||
|
.comment(0)
|
||||||
|
.post(0)
|
||||||
|
.category(0)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue