mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-05-08 11:47:28 +08:00
Add ranking endpoint and UI
This commit is contained in:
@@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="article-container">
|
<div class="article-container">
|
||||||
<template v-if="selectedTopic === '最新'">
|
<template v-if="selectedTopic === '最新' || selectedTopic === '排行榜'">
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<div class="header-item main-item">
|
<div class="header-item main-item">
|
||||||
<div class="header-item-text">话题</div>
|
<div class="header-item-text">话题</div>
|
||||||
@@ -81,9 +81,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else-if="selectedTopic === '排行榜'" class="placeholder-container">
|
|
||||||
排行榜功能开发中,敬请期待。
|
|
||||||
</div>
|
|
||||||
<div v-else-if="selectedTopic === '热门'" class="placeholder-container">
|
<div v-else-if="selectedTopic === '热门'" class="placeholder-container">
|
||||||
热门帖子功能开发中,敬请期待。
|
热门帖子功能开发中,敬请期待。
|
||||||
</div>
|
</div>
|
||||||
@@ -144,6 +141,10 @@ export default {
|
|||||||
return url
|
return url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const buildRankUrl = () => {
|
||||||
|
return `${API_BASE_URL}/api/posts/ranking?page=${page.value}&pageSize=${pageSize}`
|
||||||
|
}
|
||||||
|
|
||||||
const fetchPosts = async (reset = false) => {
|
const fetchPosts = async (reset = false) => {
|
||||||
if (reset) {
|
if (reset) {
|
||||||
page.value = 0
|
page.value = 0
|
||||||
@@ -180,17 +181,73 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleScroll = (e) => {
|
const fetchRanking = async (reset = false) => {
|
||||||
const el = e.target
|
if (reset) {
|
||||||
if (el.scrollHeight - el.scrollTop <= el.clientHeight + 50) {
|
page.value = 0
|
||||||
fetchPosts()
|
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], () => {
|
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)
|
const sanitizeDescription = (text) => stripMarkdown(text)
|
||||||
|
|||||||
@@ -78,13 +78,20 @@ public class PostController {
|
|||||||
}
|
}
|
||||||
if (hasTags) {
|
if (hasTags) {
|
||||||
return postService.listPostsByTags(tids, page, pageSize)
|
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)
|
return postService.listPostsByCategories(ids, page, pageSize)
|
||||||
.stream().map(this::toDto).collect(Collectors.toList());
|
.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) {
|
private PostDto toDto(Post post) {
|
||||||
PostDto dto = new PostDto();
|
PostDto dto = new PostDto();
|
||||||
dto.setId(post.getId());
|
dto.setId(post.getId());
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import org.springframework.data.repository.query.Param;
|
|||||||
public interface PostRepository extends JpaRepository<Post, Long> {
|
public interface PostRepository extends JpaRepository<Post, Long> {
|
||||||
List<Post> findByStatus(PostStatus status);
|
List<Post> findByStatus(PostStatus status);
|
||||||
List<Post> findByStatus(PostStatus status, Pageable pageable);
|
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> findByAuthorAndStatusOrderByCreatedAtDesc(User author, PostStatus status, Pageable pageable);
|
||||||
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status);
|
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status);
|
||||||
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status, Pageable pageable);
|
List<Post> findByCategoryInAndStatus(List<Category> categories, PostStatus status, Pageable pageable);
|
||||||
|
|||||||
@@ -107,6 +107,17 @@ public class PostService {
|
|||||||
return listPostsByCategories(null, null, null);
|
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,
|
public List<Post> listPostsByCategories(java.util.List<Long> categoryIds,
|
||||||
Integer page,
|
Integer page,
|
||||||
Integer pageSize) {
|
Integer pageSize) {
|
||||||
|
|||||||
Reference in New Issue
Block a user