mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-23 14:40:49 +08:00
Add ranking endpoint and UI
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
</div>
|
||||
|
||||
<div class="article-container">
|
||||
<template v-if="selectedTopic === '最新'">
|
||||
<template v-if="selectedTopic === '最新' || selectedTopic === '排行榜'">
|
||||
<div class="header-container">
|
||||
<div class="header-item main-item">
|
||||
<div class="header-item-text">话题</div>
|
||||
@@ -81,9 +81,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else-if="selectedTopic === '排行榜'" class="placeholder-container">
|
||||
排行榜功能开发中,敬请期待。
|
||||
</div>
|
||||
<div v-else-if="selectedTopic === '热门'" class="placeholder-container">
|
||||
热门帖子功能开发中,敬请期待。
|
||||
</div>
|
||||
@@ -144,6 +141,10 @@ export default {
|
||||
return url
|
||||
}
|
||||
|
||||
const buildRankUrl = () => {
|
||||
return `${API_BASE_URL}/api/posts/ranking?page=${page.value}&pageSize=${pageSize}`
|
||||
}
|
||||
|
||||
const fetchPosts = async (reset = false) => {
|
||||
if (reset) {
|
||||
page.value = 0
|
||||
@@ -180,17 +181,73 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
const handleScroll = (e) => {
|
||||
const el = e.target
|
||||
if (el.scrollHeight - el.scrollTop <= el.clientHeight + 50) {
|
||||
fetchPosts()
|
||||
const fetchRanking = async (reset = false) => {
|
||||
if (reset) {
|
||||
page.value = 0
|
||||
allLoaded.value = false
|
||||
articles.value = []
|
||||
}
|
||||
if (isLoadingPosts.value || allLoaded.value) return
|
||||
try {
|
||||
isLoadingPosts.value = true
|
||||
const res = await fetch(buildRankUrl())
|
||||
isLoadingPosts.value = false
|
||||
if (!res.ok) return
|
||||
const data = await res.json()
|
||||
articles.value.push(
|
||||
...data.map(p => ({
|
||||
id: p.id,
|
||||
title: p.title,
|
||||
description: p.content,
|
||||
category: p.category,
|
||||
tags: p.tags || [],
|
||||
members: [],
|
||||
comments: (p.comments || []).length,
|
||||
views: p.views,
|
||||
time: TimeManager.format(p.createdAt)
|
||||
}))
|
||||
)
|
||||
if (data.length < pageSize) {
|
||||
allLoaded.value = true
|
||||
} else {
|
||||
page.value += 1
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(fetchPosts)
|
||||
const handleScroll = (e) => {
|
||||
const el = e.target
|
||||
if (el.scrollHeight - el.scrollTop <= el.clientHeight + 50) {
|
||||
if (selectedTopic.value === '排行榜') {
|
||||
fetchRanking()
|
||||
} else {
|
||||
fetchPosts()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (selectedTopic.value === '排行榜') {
|
||||
fetchRanking()
|
||||
} else {
|
||||
fetchPosts()
|
||||
}
|
||||
})
|
||||
|
||||
watch([selectedCategory, selectedTags], () => {
|
||||
fetchPosts(true)
|
||||
if (selectedTopic.value === '最新') {
|
||||
fetchPosts(true)
|
||||
}
|
||||
})
|
||||
|
||||
watch(selectedTopic, () => {
|
||||
if (selectedTopic.value === '排行榜') {
|
||||
fetchRanking(true)
|
||||
} else {
|
||||
fetchPosts(true)
|
||||
}
|
||||
})
|
||||
|
||||
const sanitizeDescription = (text) => stripMarkdown(text)
|
||||
|
||||
@@ -78,13 +78,20 @@ public class PostController {
|
||||
}
|
||||
if (hasTags) {
|
||||
return postService.listPostsByTags(tids, page, pageSize)
|
||||
.stream().map(this::toDto).collect(Collectors.toList());
|
||||
.stream().map(this::toDto).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return postService.listPostsByCategories(ids, page, pageSize)
|
||||
.stream().map(this::toDto).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@GetMapping("/ranking")
|
||||
public List<PostDto> rankingPosts(@RequestParam(value = "page", required = false) Integer page,
|
||||
@RequestParam(value = "pageSize", required = false) Integer pageSize) {
|
||||
return postService.listPostsByViews(page, pageSize)
|
||||
.stream().map(this::toDto).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private PostDto toDto(Post post) {
|
||||
PostDto dto = new PostDto();
|
||||
dto.setId(post.getId());
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.data.repository.query.Param;
|
||||
public interface PostRepository extends JpaRepository<Post, Long> {
|
||||
List<Post> findByStatus(PostStatus status);
|
||||
List<Post> findByStatus(PostStatus status, Pageable pageable);
|
||||
List<Post> findByStatusOrderByViewsDesc(PostStatus status);
|
||||
List<Post> findByStatusOrderByViewsDesc(PostStatus status, Pageable pageable);
|
||||
List<Post> findByAuthorAndStatusOrderByCreatedAtDesc(User author, PostStatus status, Pageable pageable);
|
||||
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status);
|
||||
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status, Pageable pageable);
|
||||
|
||||
@@ -107,6 +107,17 @@ public class PostService {
|
||||
return listPostsByCategories(null, null, null);
|
||||
}
|
||||
|
||||
public List<Post> listPostsByViews(Integer page, Integer pageSize) {
|
||||
Pageable pageable = null;
|
||||
if (page != null && pageSize != null) {
|
||||
pageable = PageRequest.of(page, pageSize);
|
||||
}
|
||||
if (pageable != null) {
|
||||
return postRepository.findByStatusOrderByViewsDesc(PostStatus.PUBLISHED, pageable);
|
||||
}
|
||||
return postRepository.findByStatusOrderByViewsDesc(PostStatus.PUBLISHED);
|
||||
}
|
||||
|
||||
public List<Post> listPostsByCategories(java.util.List<Long> categoryIds,
|
||||
Integer page,
|
||||
Integer pageSize) {
|
||||
|
||||
Reference in New Issue
Block a user