From 453cbd7bc97c1267bd994504944fee3431435a1d Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Fri, 23 Jan 2026 16:37:34 +0700 Subject: [PATCH 1/9] update feature --- personal/personal-admin-plugin/pom.xml | 17 ++++ .../test/PersonalAdminPluginStartupTest.java | 3 +- .../PostTitleAndFeaturedImageResult.java | 20 ++++ personal/personal-theme/pom.xml | 17 ++++ .../view/WebPersonalBlogController.java | 10 ++ .../resources/static/css/blog-details.css | 30 ++++++ .../resources/templates/blog/details.html | 94 +++++++++++++------ .../web/test/PersonalThemeStartupTest.java | 3 +- personal/personal-web-plugin/pom.xml | 17 ++++ .../WebPersonalBlogTopViewRepository.java | 35 +++++++ .../web/response/TopBlogResponse.java | 28 ++++++ .../WebPersonalBlogTopViewService.java | 89 ++++++++++++++++++ .../WebPersonalBlogDetailsViewDecorator.java | 30 ++++++ .../view/WebPersonalBlogsViewDecorator.java | 1 + .../test/PersonalWebPluginStartupTest.java | 3 +- personal/pom.xml | 9 +- 16 files changed, 370 insertions(+), 36 deletions(-) create mode 100644 personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java create mode 100644 personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java create mode 100644 personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/response/TopBlogResponse.java create mode 100644 personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java create mode 100644 personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java diff --git a/personal/personal-admin-plugin/pom.xml b/personal/personal-admin-plugin/pom.xml index 2fc38e1..d003aa1 100644 --- a/personal/personal-admin-plugin/pom.xml +++ b/personal/personal-admin-plugin/pom.xml @@ -115,6 +115,20 @@ system ${ezyplatform.home}/admin/plugins/ezycrm/lib/ezycrm-admin-plugin-${ezycrm.version}.jar + + org.youngmonkeys + ezyrating-sdk + ${ezyrating.version} + system + ${ezyplatform.home}/admin/plugins/ezyrating/lib/ezyrating-sdk-${ezyrating.version}.jar + + + org.youngmonkeys + ezyrating-admin-plugin + ${ezyrating.version} + system + ${ezyplatform.home}/admin/plugins/ezyrating/lib/ezyrating-admin-plugin-${ezyrating.version}.jar + @@ -151,6 +165,9 @@ ${ezyplatform.home}/admin/plugins/ecommerce/resources + + ${ezyplatform.home}/admin\plugins/ezyrating/resources + diff --git a/personal/personal-admin-plugin/src/test/java/org/youngmonkeys/personal/admin/test/PersonalAdminPluginStartupTest.java b/personal/personal-admin-plugin/src/test/java/org/youngmonkeys/personal/admin/test/PersonalAdminPluginStartupTest.java index 59491c3..3831065 100644 --- a/personal/personal-admin-plugin/src/test/java/org/youngmonkeys/personal/admin/test/PersonalAdminPluginStartupTest.java +++ b/personal/personal-admin-plugin/src/test/java/org/youngmonkeys/personal/admin/test/PersonalAdminPluginStartupTest.java @@ -15,7 +15,8 @@ "org.youngmonkeys.ezysupport", "org.youngmonkeys.ezymail", "org.youngmonkeys.ezycrm", - "org.youngmonkeys.ecommerce" + "org.youngmonkeys.ecommerce", + "org.youngmonkeys.ezyrating" }) public class PersonalAdminPluginStartupTest { diff --git a/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java b/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java new file mode 100644 index 0000000..15ea1d5 --- /dev/null +++ b/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java @@ -0,0 +1,20 @@ +package org.youngmonkeys.personal.result; + +import com.tvd12.ezyfox.database.annotation.EzyQueryResult; +import lombok.Generated; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; + +@Getter +@Setter +@EzyQueryResult +public class PostTitleAndFeaturedImageResult { + private long id; + private String title; + private String slug; + private long featuredImageId; + private long views; + private LocalDateTime publishedAt; +} diff --git a/personal/personal-theme/pom.xml b/personal/personal-theme/pom.xml index 6fcc1dc..3679ec3 100644 --- a/personal/personal-theme/pom.xml +++ b/personal/personal-theme/pom.xml @@ -125,6 +125,20 @@ system ${ezyplatform.home}/web/plugins/ezycrm/lib/ezycrm-web-plugin-${ezycrm.version}.jar + + org.youngmonkeys + ezyrating-sdk + ${ezyrating.version} + system + ${ezyplatform.home}/web/plugins/ezyrating/lib/ezyrating-sdk-${ezyrating.version}.jar + + + org.youngmonkeys + ezyrating-web-plugin + ${ezyrating.version} + system + ${ezyplatform.home}/web/plugins/ezyrating/lib/ezyrating-web-plugin-${ezyrating.version}.jar + @@ -161,6 +175,9 @@ ${ezyplatform.home}/web/plugins/ecommerce/resources + + ${ezyplatform.home}/web\plugins/ezyrating/resources + diff --git a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java index 3656d9f..c675a52 100644 --- a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java +++ b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java @@ -20,6 +20,7 @@ import com.tvd12.ezyhttp.server.core.view.View; import lombok.AllArgsConstructor; import org.youngmonkeys.ezyarticle.web.controller.view.BlogController; +import org.youngmonkeys.personal.web.view.WebPersonalBlogDetailsViewDecorator; import org.youngmonkeys.personal.web.view.WebPersonalBlogsViewDecorator; import javax.servlet.http.HttpServletRequest; @@ -29,6 +30,7 @@ public class WebPersonalBlogController extends BlogController { private final WebPersonalBlogsViewDecorator blogsViewDecorator; + private final WebPersonalBlogDetailsViewDecorator blogDetailsViewDecorator; @Override protected void decorateBlogView( @@ -37,4 +39,12 @@ protected void decorateBlogView( ) { blogsViewDecorator.decorateBlogView(view); } + + @Override + protected void decorateBlogDetailsView( + HttpServletRequest request, + View view + ) { + blogDetailsViewDecorator.decorateBlogDetailsView(view); + } } diff --git a/personal/personal-theme/src/main/resources/static/css/blog-details.css b/personal/personal-theme/src/main/resources/static/css/blog-details.css index efa8ba9..0933dd5 100644 --- a/personal/personal-theme/src/main/resources/static/css/blog-details.css +++ b/personal/personal-theme/src/main/resources/static/css/blog-details.css @@ -15,3 +15,33 @@ align-items: center; gap: 10px; } + +.blog-top-view-outside { +} + +.top-view-item { + margin-bottom: 14px; +} + +.top-view-link { + display: flex; + gap: 10px; + text-decoration: none; + color: inherit; +} + +.top-view-thumb img { + width: 64px; + height: 64px; + object-fit: cover; + border-radius: 4px; +} + +.top-view-title { + font-weight: 700; +} + +.top-view-meta { + font-size: 11px; + color: #888; +} diff --git a/personal/personal-theme/src/main/resources/templates/blog/details.html b/personal/personal-theme/src/main/resources/templates/blog/details.html index 68b4acb..1c8aab4 100644 --- a/personal/personal-theme/src/main/resources/templates/blog/details.html +++ b/personal/personal-theme/src/main/resources/templates/blog/details.html @@ -2,40 +2,76 @@
-
- -
-
-
- [[#{posted_by}]]: [[${blog.author.name}]] - - [[${#strings.toLowerCase(#messages.msg('at'))}]]: [[${blog.publishedAt}]] - -
-
-
- [[#{in}]]: -
- - [[${term.name}]] - +
+
+ +
+
+
+
+
+
+
+
+
+ [[#{posted_by}]]: [[${blog.author.name}]] + + [[${#strings.toLowerCase(#messages.msg('at'))}]]: [[${blog.publishedAt}]] + +
+
+
+ [[#{in}]]: + +
+
+
+
+
+
+
+ +
+
+
+
+
-
-
-
-
-
+
+
+
+ -
- - + + +
diff --git a/personal/personal-theme/src/test/java/org/youngmonkeys/personal/web/test/PersonalThemeStartupTest.java b/personal/personal-theme/src/test/java/org/youngmonkeys/personal/web/test/PersonalThemeStartupTest.java index 30b49ac..c5661ec 100644 --- a/personal/personal-theme/src/test/java/org/youngmonkeys/personal/web/test/PersonalThemeStartupTest.java +++ b/personal/personal-theme/src/test/java/org/youngmonkeys/personal/web/test/PersonalThemeStartupTest.java @@ -15,7 +15,8 @@ "org.youngmonkeys.ezysupport", "org.youngmonkeys.ezymail", "org.youngmonkeys.ezycrm", - "org.youngmonkeys.ecommerce" + "org.youngmonkeys.ecommerce", + "org.youngmonkeys.ezyrating" }) public class PersonalThemeStartupTest { diff --git a/personal/personal-web-plugin/pom.xml b/personal/personal-web-plugin/pom.xml index 9d81e9b..cdfba2a 100644 --- a/personal/personal-web-plugin/pom.xml +++ b/personal/personal-web-plugin/pom.xml @@ -117,6 +117,20 @@ system ${ezyplatform.home}/web/plugins/ezycrm/lib/ezycrm-web-plugin-${ezycrm.version}.jar + + org.youngmonkeys + ezyrating-sdk + ${ezyrating.version} + system + ${ezyplatform.home}/web/plugins/ezyrating/lib/ezyrating-sdk-${ezyrating.version}.jar + + + org.youngmonkeys + ezyrating-web-plugin + ${ezyrating.version} + system + ${ezyplatform.home}/web/plugins/ezyrating/lib/ezyrating-web-plugin-${ezyrating.version}.jar + @@ -153,6 +167,9 @@ ${ezyplatform.home}/web/plugins/ecommerce/resources + + ${ezyplatform.home}/web\plugins/ezyrating/resources + diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java new file mode 100644 index 0000000..f8c0ffe --- /dev/null +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java @@ -0,0 +1,35 @@ +package org.youngmonkeys.personal.web.repo; + +import com.tvd12.ezydata.database.EzyDatabaseRepository; +import com.tvd12.ezyfox.database.annotation.EzyQuery; +import com.tvd12.ezyfox.database.annotation.EzyRepository; +import com.tvd12.ezyfox.util.Next; +import org.youngmonkeys.ezyarticle.sdk.entity.PostMeta; +import org.youngmonkeys.personal.result.PostTitleAndFeaturedImageResult; + +import java.util.List; + +@EzyRepository +public interface WebPersonalBlogTopViewRepository extends EzyDatabaseRepository { + + @EzyQuery( + "SELECT " + + "p.id, p.title, p.slug, p.featuredImageId, " + + "pm.metaNumberValue AS views, " + + "p.publishedAt " + + "FROM Post p " + + "JOIN PostMeta pm ON p.id = pm.postId " + + "WHERE p.postType = ?1 " + + "AND p.status = ?2 " + + "AND pm.metaKey = ?0 " + + "ORDER BY pm.metaNumberValue DESC" + ) + List findTopPublicBlogOrderByViews(String metaKey, String postType, String status, Next next); + + @EzyQuery( + "SELECT e.postId FROM PostMeta e " + + "WHERE e.metaKey = ?0 " + + "ORDER BY e.metaNumberValue DESC" + ) + List findTopPostIdsByMetaKey(String metaKey, Next next); +} diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/response/TopBlogResponse.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/response/TopBlogResponse.java new file mode 100644 index 0000000..0bd1d5e --- /dev/null +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/response/TopBlogResponse.java @@ -0,0 +1,28 @@ +package org.youngmonkeys.personal.web.response; + +import java.time.LocalDateTime; + +public class TopBlogResponse { + private long id; + private String title; + private String slug; + private String featuredImageUrl; + private long views; + private LocalDateTime publishedAt; + + public TopBlogResponse(long id, String title, String slug, String featuredImageUrl, long views, LocalDateTime publishedAt) { + this.id = id; + this.title = title; + this.slug = slug; + this.featuredImageUrl = featuredImageUrl; + this.views = views; + this.publishedAt = publishedAt; + } + + public long getId() { return id; } + public String getTitle() { return title; } + public String getSlug() { return slug; } + public String getFeaturedImageUrl() { return featuredImageUrl; } + public long getViews() { return views; } + public LocalDateTime getPublishedAt() { return publishedAt; } +} diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java new file mode 100644 index 0000000..123edab --- /dev/null +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java @@ -0,0 +1,89 @@ +package org.youngmonkeys.personal.web.service; + +import com.tvd12.ezyfox.util.Next; +import com.tvd12.ezyhttp.server.core.annotation.Service; +import org.youngmonkeys.ezyarticle.sdk.entity.PostStatus; +import org.youngmonkeys.ezyarticle.sdk.entity.PostType; +import org.youngmonkeys.ezyarticle.sdk.model.PostModel; +import org.youngmonkeys.ezyarticle.sdk.repo.PostRepository; +import org.youngmonkeys.ezyarticle.sdk.result.PostIdAndTitleResult; +import org.youngmonkeys.ezyarticle.web.response.WebPostContentResponse; +import org.youngmonkeys.ezyplatform.model.MediaNameModel; +import org.youngmonkeys.ezyplatform.model.PaginationModel; +import org.youngmonkeys.ezyplatform.web.service.WebMediaService; +import org.youngmonkeys.personal.result.PostTitleAndFeaturedImageResult; +import org.youngmonkeys.personal.web.repo.WebPersonalBlogTopViewRepository; +import org.youngmonkeys.personal.web.response.TopBlogResponse; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@Service +public class WebPersonalBlogTopViewService { + private final WebPersonalBlogTopViewRepository blogTopViewRepository; + private final PostRepository postRepository; + private final WebMediaService mediaService; + + public WebPersonalBlogTopViewService( + WebPersonalBlogTopViewRepository blogTopViewRepository, + PostRepository postRepository, + WebMediaService mediaService) { + this.blogTopViewRepository = blogTopViewRepository; + this.postRepository = postRepository; + this.mediaService = mediaService; + } + + public List getTopViewedBlogs(int limit) { + List posts = blogTopViewRepository.findTopPublicBlogOrderByViews( + "víews", + PostType.BLOG.toString(), + PostStatus.PUBLISHED.toString(), + Next.limit(6) + ); + + if (posts.isEmpty()) { + return Collections.emptyList(); + } + + Set imageIds = posts.stream() + .map(PostTitleAndFeaturedImageResult::getFeaturedImageId) + .filter(id -> id > 0) + .collect(Collectors.toSet()); + + Map mediaMap = imageIds.isEmpty() + ? Collections.emptyMap() + : mediaService.getMediaNameMapByIds(imageIds); + + return posts.stream().map(post -> { + MediaNameModel media = mediaMap.get(post.getFeaturedImageId()); + String imageUrl = media != null + ? media.getUrlOrDefault(null) + : ""; + return new TopBlogResponse( + post.getId(), + post.getTitle(), + post.getSlug(), + imageUrl, + post.getViews(), + post.getPublishedAt() + ); + }).collect(Collectors.toList()); + } + + public List getTopViewedPostIds(int limit) { + List postIds = + blogTopViewRepository.findTopPostIdsByMetaKey( + "views", + Next.limit(limit) + ); + + if (postIds.isEmpty()) { + return Collections.emptyList(); + } + + return postRepository.findPostIdAndTitlesByIdIn(postIds); + } +} diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java new file mode 100644 index 0000000..7fefead --- /dev/null +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java @@ -0,0 +1,30 @@ +package org.youngmonkeys.personal.web.view; + +import com.tvd12.ezyfox.bean.annotation.EzySingleton; +import com.tvd12.ezyhttp.server.core.view.View; +import lombok.AllArgsConstructor; +import org.youngmonkeys.ezyarticle.sdk.result.PostIdAndTitleResult; +import org.youngmonkeys.personal.web.response.TopBlogResponse; +import org.youngmonkeys.personal.web.service.WebPersonalBlogTopViewService; + +import java.util.List; + +@EzySingleton +@AllArgsConstructor +public class WebPersonalBlogDetailsViewDecorator { + + private final WebPersonalBlogTopViewService blogService; + + public void decorateBlogDetailsView( + View view + ) { +// List topViewedBlogs = +// blogService.getTopViewedPostIds(6); + List topViewedBlogs = blogService.getTopViewedBlogs(6); + + view.setVariable( + "topViewedBlogs", + topViewedBlogs + ); + } +} diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java index 189d54b..f78075c 100644 --- a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java @@ -3,6 +3,7 @@ import com.tvd12.ezyfox.bean.annotation.EzySingleton; import com.tvd12.ezyhttp.server.core.view.View; import lombok.AllArgsConstructor; +import org.youngmonkeys.ezyarticle.sdk.entity.Post; import org.youngmonkeys.ezyarticle.web.response.WebPostContentResponse; import org.youngmonkeys.ezyplatform.model.PaginationModel; import org.youngmonkeys.ezyplatform.model.UuidNameModel; diff --git a/personal/personal-web-plugin/src/test/java/org/youngmonkeys/personal/web/test/PersonalWebPluginStartupTest.java b/personal/personal-web-plugin/src/test/java/org/youngmonkeys/personal/web/test/PersonalWebPluginStartupTest.java index 28c8fb3..bdae38e 100644 --- a/personal/personal-web-plugin/src/test/java/org/youngmonkeys/personal/web/test/PersonalWebPluginStartupTest.java +++ b/personal/personal-web-plugin/src/test/java/org/youngmonkeys/personal/web/test/PersonalWebPluginStartupTest.java @@ -15,7 +15,8 @@ "org.youngmonkeys.ezysupport", "org.youngmonkeys.ezymail", "org.youngmonkeys.ezycrm", - "org.youngmonkeys.ecommerce" + "org.youngmonkeys.ecommerce", + "org.youngmonkeys.ezyrating" }) public class PersonalWebPluginStartupTest { diff --git a/personal/pom.xml b/personal/pom.xml index 48067d6..5ea8d5a 100644 --- a/personal/pom.xml +++ b/personal/pom.xml @@ -18,13 +18,14 @@ ${env.EZYPLATFORM_HOME} 1.18.3 - 0.8.8 + 0.9.0 0.1.4 1.6.2 - 0.2.9 - 1.0.7 + 0.3.0 + 1.0.9 3.5.3 - 0.3.7 + 0.3.8 + 0.1.7 From e7be0c7b2bf9a454bd93df62106024ceeee9cb2b Mon Sep 17 00:00:00 2001 From: Nguyen Ba Hieu Date: Fri, 23 Jan 2026 22:37:40 +0700 Subject: [PATCH 2/9] update blog top view --- .../result/PostIdAndNumberViewsResult.java | 13 +++ .../PostTitleAndFeaturedImageResult.java | 20 ----- .../view/WebPersonalBlogController.java | 6 +- .../resources/templates/blog/details.html | 10 +-- .../web/decorator/WebTopBlogDecorator.java | 85 +++++++++++++++++++ .../WebPersonalBlogTopViewRepository.java | 16 +--- .../WebPersonalBlogTopViewService.java | 76 ++++++----------- .../WebPersonalBlogDetailsViewDecorator.java | 8 +- .../view/WebPersonalBlogsViewDecorator.java | 1 - 9 files changed, 139 insertions(+), 96 deletions(-) create mode 100644 personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostIdAndNumberViewsResult.java delete mode 100644 personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java create mode 100644 personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/decorator/WebTopBlogDecorator.java diff --git a/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostIdAndNumberViewsResult.java b/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostIdAndNumberViewsResult.java new file mode 100644 index 0000000..f7bb795 --- /dev/null +++ b/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostIdAndNumberViewsResult.java @@ -0,0 +1,13 @@ +package org.youngmonkeys.personal.result; + +import com.tvd12.ezyfox.database.annotation.EzyQueryResult; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@EzyQueryResult +public class PostIdAndNumberViewsResult { + private long id; + private long views; +} diff --git a/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java b/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java deleted file mode 100644 index 15ea1d5..0000000 --- a/personal/personal-sdk/src/main/java/org/youngmonkeys/personal/result/PostTitleAndFeaturedImageResult.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.youngmonkeys.personal.result; - -import com.tvd12.ezyfox.database.annotation.EzyQueryResult; -import lombok.Generated; -import lombok.Getter; -import lombok.Setter; - -import java.time.LocalDateTime; - -@Getter -@Setter -@EzyQueryResult -public class PostTitleAndFeaturedImageResult { - private long id; - private String title; - private String slug; - private long featuredImageId; - private long views; - private LocalDateTime publishedAt; -} diff --git a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java index c675a52..92a271f 100644 --- a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java +++ b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java @@ -20,6 +20,7 @@ import com.tvd12.ezyhttp.server.core.view.View; import lombok.AllArgsConstructor; import org.youngmonkeys.ezyarticle.web.controller.view.BlogController; +import org.youngmonkeys.ezyplatform.web.controller.service.WebLanguageControllerService; import org.youngmonkeys.personal.web.view.WebPersonalBlogDetailsViewDecorator; import org.youngmonkeys.personal.web.view.WebPersonalBlogsViewDecorator; @@ -31,6 +32,7 @@ public class WebPersonalBlogController extends BlogController { private final WebPersonalBlogsViewDecorator blogsViewDecorator; private final WebPersonalBlogDetailsViewDecorator blogDetailsViewDecorator; + private WebLanguageControllerService languageControllerService; @Override protected void decorateBlogView( @@ -45,6 +47,8 @@ protected void decorateBlogDetailsView( HttpServletRequest request, View view ) { - blogDetailsViewDecorator.decorateBlogDetailsView(view); + String languageCode = + languageControllerService.getLanguageCodeOrDefault(request); + blogDetailsViewDecorator.decorateBlogDetailsView(view, languageCode); } } diff --git a/personal/personal-theme/src/main/resources/templates/blog/details.html b/personal/personal-theme/src/main/resources/templates/blog/details.html index 1c8aab4..c3dc393 100644 --- a/personal/personal-theme/src/main/resources/templates/blog/details.html +++ b/personal/personal-theme/src/main/resources/templates/blog/details.html @@ -54,17 +54,17 @@
- + th:if="${post.featuredImageUrl != null}"> +
[[${post.title}]]
- - 18h30 - + + [[${post.publishedAt}]] +
diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/decorator/WebTopBlogDecorator.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/decorator/WebTopBlogDecorator.java new file mode 100644 index 0000000..61d50d5 --- /dev/null +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/decorator/WebTopBlogDecorator.java @@ -0,0 +1,85 @@ +package org.youngmonkeys.personal.web.decorator; + +import com.tvd12.ezyfox.bean.annotation.EzySingleton; +import org.youngmonkeys.ezyarticle.sdk.model.PostI18nModel; +import org.youngmonkeys.ezyarticle.sdk.model.PostModel; +import org.youngmonkeys.ezyarticle.web.service.WebPostI18nService; +import org.youngmonkeys.ezyarticle.web.service.WebPostSlugService; +import org.youngmonkeys.ezyplatform.model.MediaNameModel; +import org.youngmonkeys.ezyplatform.web.service.WebMediaService; +import org.youngmonkeys.personal.web.response.TopBlogResponse; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +@EzySingleton +public class WebTopBlogDecorator { + private final WebMediaService mediaService; + private final WebPostSlugService postSlugService; + private final WebPostI18nService postI18nService; + + public WebTopBlogDecorator( + WebMediaService mediaService, + WebPostSlugService postSlugService, + WebPostI18nService postI18nService + ) { + this.mediaService = mediaService; + this.postSlugService = postSlugService; + this.postI18nService = postI18nService; + } + + public List decorate( + List posts, + Map viewsMap, + String language + ) { + if (posts.isEmpty()) { + return Collections.emptyList(); + } + + List postIds = posts.stream() + .map(PostModel::getId) + .collect(Collectors.toList()); + + Set mediaIds = posts.stream() + .map(PostModel::getFeaturedImageId) + .filter(id -> id > 0) + .collect(Collectors.toSet()); + + Map i18nMap = + postI18nService.getShortedPostI18nMapByPostIdsAndLanguage( + postIds, language + ); + + Map slugMap = + postSlugService.getLatestSlugMapByPostIds(postIds); + + Map mediaMap = + mediaService.getMediaNameMapByIds(mediaIds); + + return posts.stream() + .map(post -> { + PostI18nModel i18n = i18nMap.get(post.getId()); + MediaNameModel media = mediaMap.get(post.getFeaturedImageId()); + + String title = + i18n != null ? i18n.getTitle() : post.getTitle(); + + String imageUrl = + MediaNameModel.getMediaUrlOrNull(media); + + return new TopBlogResponse( + post.getId(), + title, + slugMap.get(post.getId()), + imageUrl, + viewsMap.get(post.getId()), + post.getPublishedAtDateTime() + ); + }) + .collect(Collectors.toList()); + } +} diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java index f8c0ffe..665a542 100644 --- a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/repo/WebPersonalBlogTopViewRepository.java @@ -5,7 +5,7 @@ import com.tvd12.ezyfox.database.annotation.EzyRepository; import com.tvd12.ezyfox.util.Next; import org.youngmonkeys.ezyarticle.sdk.entity.PostMeta; -import org.youngmonkeys.personal.result.PostTitleAndFeaturedImageResult; +import org.youngmonkeys.personal.result.PostIdAndNumberViewsResult; import java.util.List; @@ -13,10 +13,7 @@ public interface WebPersonalBlogTopViewRepository extends EzyDatabaseRepository { @EzyQuery( - "SELECT " + - "p.id, p.title, p.slug, p.featuredImageId, " + - "pm.metaNumberValue AS views, " + - "p.publishedAt " + + "SELECT p.id, pm.metaNumberValue AS views " + "FROM Post p " + "JOIN PostMeta pm ON p.id = pm.postId " + "WHERE p.postType = ?1 " + @@ -24,12 +21,5 @@ public interface WebPersonalBlogTopViewRepository extends EzyDatabaseRepository< "AND pm.metaKey = ?0 " + "ORDER BY pm.metaNumberValue DESC" ) - List findTopPublicBlogOrderByViews(String metaKey, String postType, String status, Next next); - - @EzyQuery( - "SELECT e.postId FROM PostMeta e " + - "WHERE e.metaKey = ?0 " + - "ORDER BY e.metaNumberValue DESC" - ) - List findTopPostIdsByMetaKey(String metaKey, Next next); + List findTopPostByMetaKeyAndTypeAndStatusOrderByViews(String metaKey, String postType, String status, Next next); } diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java index 123edab..c569fe2 100644 --- a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/WebPersonalBlogTopViewService.java @@ -5,85 +5,59 @@ import org.youngmonkeys.ezyarticle.sdk.entity.PostStatus; import org.youngmonkeys.ezyarticle.sdk.entity.PostType; import org.youngmonkeys.ezyarticle.sdk.model.PostModel; -import org.youngmonkeys.ezyarticle.sdk.repo.PostRepository; -import org.youngmonkeys.ezyarticle.sdk.result.PostIdAndTitleResult; -import org.youngmonkeys.ezyarticle.web.response.WebPostContentResponse; -import org.youngmonkeys.ezyplatform.model.MediaNameModel; -import org.youngmonkeys.ezyplatform.model.PaginationModel; -import org.youngmonkeys.ezyplatform.web.service.WebMediaService; -import org.youngmonkeys.personal.result.PostTitleAndFeaturedImageResult; +import org.youngmonkeys.ezyarticle.sdk.service.PostService; +import org.youngmonkeys.personal.result.PostIdAndNumberViewsResult; +import org.youngmonkeys.personal.web.decorator.WebTopBlogDecorator; import org.youngmonkeys.personal.web.repo.WebPersonalBlogTopViewRepository; import org.youngmonkeys.personal.web.response.TopBlogResponse; import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; @Service public class WebPersonalBlogTopViewService { private final WebPersonalBlogTopViewRepository blogTopViewRepository; - private final PostRepository postRepository; - private final WebMediaService mediaService; + private final PostService postService; + private final WebTopBlogDecorator blogDecorator; public WebPersonalBlogTopViewService( WebPersonalBlogTopViewRepository blogTopViewRepository, - PostRepository postRepository, - WebMediaService mediaService) { + PostService postService, + WebTopBlogDecorator blogDecorator + ) { this.blogTopViewRepository = blogTopViewRepository; - this.postRepository = postRepository; - this.mediaService = mediaService; + this.postService = postService; + this.blogDecorator = blogDecorator; } - public List getTopViewedBlogs(int limit) { - List posts = blogTopViewRepository.findTopPublicBlogOrderByViews( + public List getTopViewedBlogs(int limit, String language) { + List rows = blogTopViewRepository.findTopPostByMetaKeyAndTypeAndStatusOrderByViews( "víews", PostType.BLOG.toString(), PostStatus.PUBLISHED.toString(), Next.limit(6) ); - if (posts.isEmpty()) { + if (rows.isEmpty()) { return Collections.emptyList(); } - Set imageIds = posts.stream() - .map(PostTitleAndFeaturedImageResult::getFeaturedImageId) - .filter(id -> id > 0) - .collect(Collectors.toSet()); + List postIds = rows.stream() + .map(PostIdAndNumberViewsResult::getId) + .collect(Collectors.toList()); - Map mediaMap = imageIds.isEmpty() - ? Collections.emptyMap() - : mediaService.getMediaNameMapByIds(imageIds); + List posts = + postService.getShortedPostsByIds(postIds); - return posts.stream().map(post -> { - MediaNameModel media = mediaMap.get(post.getFeaturedImageId()); - String imageUrl = media != null - ? media.getUrlOrDefault(null) - : ""; - return new TopBlogResponse( - post.getId(), - post.getTitle(), - post.getSlug(), - imageUrl, - post.getViews(), - post.getPublishedAt() - ); - }).collect(Collectors.toList()); - } - - public List getTopViewedPostIds(int limit) { - List postIds = - blogTopViewRepository.findTopPostIdsByMetaKey( - "views", - Next.limit(limit) - ); - - if (postIds.isEmpty()) { - return Collections.emptyList(); - } + Map viewsMap = rows.stream() + .collect(Collectors.toMap( + PostIdAndNumberViewsResult::getId, + PostIdAndNumberViewsResult::getViews + )); - return postRepository.findPostIdAndTitlesByIdIn(postIds); + return blogDecorator + .decorate(posts, viewsMap, language); } } diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java index 7fefead..1d247cf 100644 --- a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogDetailsViewDecorator.java @@ -3,7 +3,6 @@ import com.tvd12.ezyfox.bean.annotation.EzySingleton; import com.tvd12.ezyhttp.server.core.view.View; import lombok.AllArgsConstructor; -import org.youngmonkeys.ezyarticle.sdk.result.PostIdAndTitleResult; import org.youngmonkeys.personal.web.response.TopBlogResponse; import org.youngmonkeys.personal.web.service.WebPersonalBlogTopViewService; @@ -16,11 +15,10 @@ public class WebPersonalBlogDetailsViewDecorator { private final WebPersonalBlogTopViewService blogService; public void decorateBlogDetailsView( - View view + View view, + String languageCode ) { -// List topViewedBlogs = -// blogService.getTopViewedPostIds(6); - List topViewedBlogs = blogService.getTopViewedBlogs(6); + List topViewedBlogs = blogService.getTopViewedBlogs(6, languageCode); view.setVariable( "topViewedBlogs", diff --git a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java index f78075c..189d54b 100644 --- a/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java +++ b/personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/view/WebPersonalBlogsViewDecorator.java @@ -3,7 +3,6 @@ import com.tvd12.ezyfox.bean.annotation.EzySingleton; import com.tvd12.ezyhttp.server.core.view.View; import lombok.AllArgsConstructor; -import org.youngmonkeys.ezyarticle.sdk.entity.Post; import org.youngmonkeys.ezyarticle.web.response.WebPostContentResponse; import org.youngmonkeys.ezyplatform.model.PaginationModel; import org.youngmonkeys.ezyplatform.model.UuidNameModel; From fd1aee2a43358a2a9e9abd64540a1fba6d5d3b04 Mon Sep 17 00:00:00 2001 From: Hieu Nguyen Date: Mon, 26 Jan 2026 14:22:54 +0700 Subject: [PATCH 3/9] fix --- .../view/WebPersonalBlogController.java | 2 +- .../resources/messages/messages_vi.properties | 1 + .../resources/static/css/blog-details.css | 3 -- .../resources/templates/blog/details.html | 2 +- .../WebPersonalBlogTopViewRepository.java | 3 +- .../web/response/TopBlogResponse.java | 39 +++++++++++++++---- ...PersonalBlogTopViewControllerService.java} | 7 ++-- .../WebPersonalBlogDetailsViewDecorator.java | 4 +- personal/pom.xml | 8 ++-- 9 files changed, 47 insertions(+), 22 deletions(-) rename personal/personal-web-plugin/src/main/java/org/youngmonkeys/personal/web/service/{WebPersonalBlogTopViewService.java => WebPersonalBlogTopViewControllerService.java} (92%) diff --git a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java index 92a271f..88236b3 100644 --- a/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java +++ b/personal/personal-theme/src/main/java/org/youngmonkeys/personal/web/controller/view/WebPersonalBlogController.java @@ -32,7 +32,7 @@ public class WebPersonalBlogController extends BlogController { private final WebPersonalBlogsViewDecorator blogsViewDecorator; private final WebPersonalBlogDetailsViewDecorator blogDetailsViewDecorator; - private WebLanguageControllerService languageControllerService; + private final WebLanguageControllerService languageControllerService; @Override protected void decorateBlogView( diff --git a/personal/personal-theme/src/main/resources/messages/messages_vi.properties b/personal/personal-theme/src/main/resources/messages/messages_vi.properties index be49405..98325f2 100644 --- a/personal/personal-theme/src/main/resources/messages/messages_vi.properties +++ b/personal/personal-theme/src/main/resources/messages/messages_vi.properties @@ -32,4 +32,5 @@ subscribe_successfully=\u0110\u0103ng k\u00FD th\u00E0nh c\u00F4ng tags=Th\u1EBB terms_of_use=Ch\u00EDnh s\u00E1ch s\u1EED d\u1EE5ng topics=C\u00E1c ch\u1EE7 \u0111\u1EC1 +top_view =Xem nhi\u1EC1u nh\u1EA5t unknown_author=Kh\u00F4ng r\u00F5 t\u00E1c gi\u1EA3 diff --git a/personal/personal-theme/src/main/resources/static/css/blog-details.css b/personal/personal-theme/src/main/resources/static/css/blog-details.css index 0933dd5..573677a 100644 --- a/personal/personal-theme/src/main/resources/static/css/blog-details.css +++ b/personal/personal-theme/src/main/resources/static/css/blog-details.css @@ -16,9 +16,6 @@ gap: 10px; } -.blog-top-view-outside { -} - .top-view-item { margin-bottom: 14px; } diff --git a/personal/personal-theme/src/main/resources/templates/blog/details.html b/personal/personal-theme/src/main/resources/templates/blog/details.html index c3dc393..eb8a33c 100644 --- a/personal/personal-theme/src/main/resources/templates/blog/details.html +++ b/personal/personal-theme/src/main/resources/templates/blog/details.html @@ -49,7 +49,7 @@