论坛功能前后端集成

czq
2991692032 4 weeks ago
parent 23a0166c71
commit 4ab9a50eed

@ -50,4 +50,22 @@ export const uploadAvatar = (file: File) => {
// 更新邮箱
export const updateEmail = (email: string, code: string) => {
return api.put<ApiResponse>('/users/email', { email, code })
}
// 获取用户统计数据
export const getUserStats = () => {
return api.get<ApiResponse<{
postsCount: number
commentsCount: number
resourcesCount: number
likesReceived: number
coursesCount: number
schedulesCount: number
}>>('/users/stats')
}
// 获取用户最近帖子
export const getUserRecentPosts = (limit?: number) => {
const params = limit ? { limit } : {}
return api.get<ApiResponse<any[]>>('/users/recent-posts', { params })
}

@ -49,6 +49,67 @@ export const likePost = (id: number) => {
return api.post<ApiResponse<null>>(`/posts/${id}/like`)
}
// 获取用户的帖子列表
export const getUserPosts = (userId: number, params?: {
page?: number
size?: number
sort?: string
}) => {
return api.get<ApiResponse<{
total: number
list: Post[]
pages: number
}>>(`/posts/user/${userId}`, { params })
}
// ==================== 评论管理 ====================
// 获取评论列表
export const getComments = (postId: number) => {
return api.get<ApiResponse<{
total: number
list: Array<{
id: number
content: string
userId: number
nickname: string
avatar: string
likeCount: number
isLiked: boolean
createdAt: string
replies?: Array<{
id: number
content: string
userId: number
nickname: string
avatar: string
likeCount: number
isLiked: boolean
createdAt: string
}>
}>
}>>(`/comments/post/${postId}`)
}
// 发表评论
export const createComment = (data: {
postId: number
content: string
parentId?: number | null
}) => {
return api.post<ApiResponse<{ commentId: number }>>('/comments', data)
}
// 删除评论
export const deleteComment = (id: number) => {
return api.delete<ApiResponse<null>>(`/comments/${id}`)
}
// 点赞/取消点赞评论
export const likeComment = (id: number) => {
return api.post<ApiResponse<null>>(`/comments/${id}/like`)
}
// 获取分类列表
export const getCategories = (params?: { status?: number }) => {
return api.get<ApiResponse<{

@ -116,7 +116,7 @@
</div>
<div class="filter-options">
<el-select v-model="sortBy" placeholder="排序方式" size="default">
<el-select v-model="sortBy" placeholder="排序方式" size="default" @change="handleSortChange">
<el-option label="最新发布" value="latest" />
<el-option label="最多点赞" value="likes" />
<el-option label="最多回复" value="comments" />
@ -129,17 +129,17 @@
</div>
</div>
<!-- 示例帖子列表 -->
<div class="posts-list">
<!-- 帖子列表 -->
<div class="posts-list" v-loading="loading">
<div
v-for="post in mockPosts"
v-for="post in posts"
:key="post.id"
class="post-card card-light animate-fade-in-up"
@click="viewPost(post.id)"
>
<div class="post-header">
<div class="author-info">
<el-avatar :size="40">
<el-avatar :size="40" :src="post.avatar">
{{ post.nickname?.charAt(0) }}
</el-avatar>
<div class="author-details">
@ -177,22 +177,39 @@
</div>
<div class="post-actions">
<el-button text @click.stop="toggleLike(post)">
<el-button
text
:type="post.isLiked ? 'primary' : 'default'"
@click.stop="toggleLike(post)"
>
<el-icon><Star /></el-icon>
点赞
{{ post.isLiked ? '已点赞' : '点赞' }}
</el-button>
</div>
</div>
</div>
<!-- 空状态 -->
<div v-if="mockPosts.length === 0" class="empty-state">
<div v-if="posts.length === 0 && !loading" class="empty-state">
<el-empty description="暂无帖子">
<el-button type="primary" @click="showCreatePost = true">
发布第一个帖子
</el-button>
</el-empty>
</div>
<!-- 分页 -->
<div v-if="posts.length > 0" class="pagination-section">
<el-pagination
v-model:current-page="pagination.page"
v-model:page-size="pagination.size"
:page-sizes="[10, 20, 50, 100]"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</main>
</div>
@ -207,21 +224,41 @@
>
<el-form label-position="top">
<el-form-item label="帖子标题">
<el-input placeholder="请输入帖子标题" size="large" />
<el-input
v-model="postForm.title"
placeholder="请输入帖子标题"
size="large"
/>
</el-form-item>
<el-form-item label="分类">
<el-select placeholder="请选择分类" size="large" style="width: 100%">
<el-option label="学习交流" value="1" />
<el-option label="生活分享" value="2" />
<el-select
v-model="postForm.categoryId"
placeholder="请选择分类"
size="large"
style="width: 100%"
>
<el-option
v-for="category in categories"
:key="category.id"
:label="category.name"
:value="category.id"
/>
</el-select>
</el-form-item>
<el-form-item label="帖子内容">
<el-input type="textarea" :rows="6" placeholder="请输入帖子内容..." />
<el-input
v-model="postForm.content"
type="textarea"
:rows="6"
placeholder="请输入帖子内容..."
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="showCreatePost = false">取消</el-button>
<el-button type="primary" @click="handleCreatePost"></el-button>
<el-button @click="showCreatePost = false" :disabled="posting">取消</el-button>
<el-button type="primary" @click="handleCreatePost" :loading="posting">
{{ posting ? '发布中...' : '发布' }}
</el-button>
</template>
</el-dialog>
</div>
@ -230,7 +267,7 @@
<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
Edit,
Search,
@ -242,6 +279,8 @@ import {
School
} from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { getPosts, getCategories, createPost, likePost } from '@/api/forum'
import type { Post, Category, ApiResponse } from '@/types'
const router = useRouter()
const userStore = useUserStore()
@ -251,53 +290,25 @@ const showCreatePost = ref(false)
const searchKeyword = ref('')
const selectedCategory = ref<number | null>(null)
const sortBy = ref('latest')
const loading = ref(false)
const posting = ref(false)
//
const categories = ref<Category[]>([])
const posts = ref<Post[]>([])
const pagination = ref({
page: 1,
size: 10,
total: 0,
pages: 0
})
//
const categories = ref([
{ id: 1, name: '学习交流', description: '', icon: '', sort: 1, status: 1, createdAt: '', updatedAt: '' },
{ id: 2, name: '生活分享', description: '', icon: '', sort: 2, status: 1, createdAt: '', updatedAt: '' },
{ id: 3, name: '技术讨论', description: '', icon: '', sort: 3, status: 1, createdAt: '', updatedAt: '' },
{ id: 4, name: '校园活动', description: '', icon: '', sort: 4, status: 1, createdAt: '', updatedAt: '' }
])
const mockPosts = ref([
{
id: 1,
title: '大学生活如何更好地安排时间?',
summary: '作为一名大一新生,想请教一下学长学姐们关于时间管理的经验...',
nickname: '小明',
avatar: '',
categoryName: '学习交流',
viewCount: 156,
commentCount: 23,
likeCount: 45,
createdAt: '2024-01-15 10:30'
},
{
id: 2,
title: '分享一些高效学习方法',
summary: '经过一学期的摸索,总结了一些比较有效的学习方法,希望对大家有帮助...',
nickname: '学霸小王',
avatar: '',
categoryName: '学习交流',
viewCount: 234,
commentCount: 67,
likeCount: 89,
createdAt: '2024-01-14 16:20'
},
{
id: 3,
title: '校园里发现的好去处推荐',
summary: '今天发现了几个校园里很安静适合学习的地方,想和大家分享一下...',
nickname: '探索者',
avatar: '',
categoryName: '生活分享',
viewCount: 98,
commentCount: 12,
likeCount: 34,
createdAt: '2024-01-13 14:15'
}
])
//
const postForm = reactive({
title: '',
content: '',
categoryId: null as number | null
})
//
const hotTags = ref(['学习交流', '生活分享', '技术讨论', '考试', '实习', '社团活动'])
@ -305,30 +316,97 @@ const hotTags = ref(['学习交流', '生活分享', '技术讨论', '考试', '
//
const selectCategory = (categoryId: number | null) => {
selectedCategory.value = selectedCategory.value === categoryId ? null : categoryId
pagination.value.page = 1 //
loadPosts()
}
const searchPosts = (keyword?: string) => {
if (keyword) {
searchKeyword.value = keyword
}
ElMessage.info('搜索功能开发中...')
pagination.value.page = 1 //
loadPosts()
}
const refreshPosts = () => {
ElMessage.success('刷新成功')
pagination.value.page = 1
loadPosts()
}
const handleSizeChange = (size: number) => {
pagination.value.size = size
pagination.value.page = 1
loadPosts()
}
const handleCurrentChange = (page: number) => {
pagination.value.page = page
loadPosts()
}
const handleSortChange = () => {
pagination.value.page = 1
loadPosts()
}
const viewPost = (postId: number) => {
router.push(`/forum/post/${postId}`)
}
const toggleLike = (post: any) => {
ElMessage.success('点赞成功')
const toggleLike = async (post: Post) => {
try {
const response = await likePost(post.id) as any as ApiResponse<null>
if (response.code === 200) {
//
const wasLiked = post.isLiked
post.isLiked = !wasLiked
post.likeCount += post.isLiked ? 1 : -1
ElMessage.success(post.isLiked ? '点赞成功' : '取消点赞')
} else {
ElMessage.error(response.message || '操作失败')
}
} catch (error: any) {
ElMessage.error(error.response?.data?.message || '操作失败')
}
}
const handleCreatePost = () => {
showCreatePost.value = false
ElMessage.success('发布成功!')
const handleCreatePost = async () => {
if (!postForm.title.trim()) {
ElMessage.warning('请输入帖子标题')
return
}
if (!postForm.categoryId) {
ElMessage.warning('请选择分类')
return
}
if (!postForm.content.trim()) {
ElMessage.warning('请输入帖子内容')
return
}
try {
posting.value = true
const response = await createPost({
title: postForm.title,
content: postForm.content,
categoryId: postForm.categoryId
}) as any as ApiResponse<{ postId: number }>
if (response.code === 200) {
showCreatePost.value = false
ElMessage.success('发布成功!')
//
postForm.title = ''
postForm.content = ''
postForm.categoryId = null
//
loadPosts()
}
} catch (error: any) {
ElMessage.error(error.message || '发布失败')
} finally {
posting.value = false
}
}
const handleCommand = (command: string) => {
@ -340,8 +418,76 @@ const handleCommand = (command: string) => {
}
}
//
const loadPosts = async () => {
try {
loading.value = true
const params: any = {
page: pagination.value.page,
size: pagination.value.size,
sort: sortBy.value
}
if (selectedCategory.value) {
params.categoryId = selectedCategory.value
}
if (searchKeyword.value.trim()) {
params.keyword = searchKeyword.value.trim()
}
const response = await getPosts(params) as any as ApiResponse<{
total: number
list: Post[]
pages: number
}>
if (response.code === 200) {
posts.value = response.data.list || []
pagination.value.total = response.data.total || 0
pagination.value.pages = response.data.pages || 0
//
console.log('加载的帖子数据:', posts.value.map(p => ({
id: p.id,
title: p.title,
isLiked: p.isLiked,
likeCount: p.likeCount
})))
} else {
ElMessage.error(response.message || '加载帖子失败')
}
} catch (error: any) {
console.error('加载帖子失败:', error)
ElMessage.error(error.response?.data?.message || '加载帖子失败')
} finally {
loading.value = false
}
}
//
const loadCategories = async () => {
try {
const response = await getCategories({ status: 1 }) as any as ApiResponse<{
total: number
list: Category[]
}>
if (response.code === 200) {
categories.value = response.data.list || []
} else {
console.error('加载分类失败:', response.message)
}
} catch (error: any) {
console.error('加载分类失败:', error)
ElMessage.error('加载分类失败')
}
}
onMounted(() => {
console.log('论坛页面加载完成')
loadCategories()
loadPosts()
})
</script>
@ -635,6 +781,18 @@ onMounted(() => {
gap: 16px;
}
/* 分页样式 */
.pagination-section {
margin-top: 32px;
display: flex;
justify-content: center;
padding: 24px;
background: rgba(255, 255, 255, 0.8);
border-radius: 16px;
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.stat-item {
display: flex;
align-items: center;

@ -41,7 +41,7 @@
</div>
<!-- 帖子内容 -->
<div class="post-content-section card-light">
<div class="post-content-section card-light" v-loading="loading">
<div class="post-header">
<div class="post-meta">
<el-tag type="primary">{{ post.categoryName }}</el-tag>
@ -87,7 +87,9 @@
<el-button type="primary" plain size="small">关注</el-button>
</div>
<div class="post-content" v-html="post.content"></div>
<div class="post-content">
<pre class="post-text">{{ post.content }}</pre>
</div>
<div class="post-footer">
<div class="post-stats">
@ -110,7 +112,7 @@
<!-- 评论区域 -->
<div class="comments-section card-light">
<div class="comments-header">
<h3>评论 ({{ comments.length }})</h3>
<h3>评论 ({{ post.commentCount || 0 }})</h3>
<el-select v-model="commentSort" size="small" style="width: 120px">
<el-option label="最新" value="latest" />
<el-option label="最热" value="hot" />
@ -127,14 +129,23 @@
class="comment-input"
/>
<div class="comment-actions">
<el-button type="primary" @click="submitComment">
发表评论
<el-button type="primary" @click="submitComment" :loading="commenting">
{{ commenting ? '发表中...' : '发表评论' }}
</el-button>
</div>
</div>
<!-- 评论列表 -->
<div class="comments-list">
<!-- 空状态 -->
<div v-if="comments.length === 0" class="empty-comments">
<el-empty description="暂无评论" :image-size="80">
<template #description>
<p>暂无评论快来发表第一个评论吧</p>
</template>
</el-empty>
</div>
<div
v-for="comment in comments"
:key="comment.id"
@ -206,6 +217,8 @@ import {
ChatDotRound
} from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'
import { getPostDetail, likePost as likePostAPI, getComments, createComment as createCommentAPI, likeComment as likeCommentAPI } from '@/api/forum'
import type { Post, ApiResponse } from '@/types'
const router = useRouter()
const route = useRoute()
@ -214,35 +227,28 @@ const userStore = useUserStore()
//
const newComment = ref('')
const commentSort = ref('latest')
//
const post = ref({
id: 1,
title: '大学生活如何更好地安排时间?',
content: `
<p>作为一名大一新生刚刚进入大学生活发现与高中相比有很大的不同高中时间安排比较固定而大学有更多的自由时间但也更容易迷茫</p>
<p>想请教一下学长学姐们关于时间管理的经验比如</p>
<ul>
<li>如何平衡学习和社团活动</li>
<li>怎么制定合理的学习计划</li>
<li>如何避免拖延症</li>
<li>课余时间应该如何充实自己</li>
</ul>
<p>希望大家能分享一些实用的方法和经验谢谢</p>
`,
nickname: '小明',
const loading = ref(false)
const commenting = ref(false)
//
const post = ref<Post>({
id: 0,
title: '',
content: '',
summary: '',
userId: 0,
nickname: '',
avatar: '',
categoryName: '学习交流',
viewCount: 156,
commentCount: 23,
likeCount: 45,
categoryId: 0,
categoryName: '',
viewCount: 0,
likeCount: 0,
commentCount: 0,
isLiked: false,
createdAt: '2024-01-15 10:30',
userId: 1
createdAt: '',
updatedAt: ''
})
const comments = ref<any[]>([])
//
const authorStats = ref({
@ -250,38 +256,6 @@ const authorStats = ref({
likeCount: 234
})
//
const comments = ref([
{
id: 1,
content: '时间管理确实很重要我推荐使用番茄工作法25分钟专注学习5分钟休息效果很好',
nickname: '学霸小王',
avatar: '',
likeCount: 12,
isLiked: false,
createdAt: '2024-01-15 11:20',
replies: [
{
id: 2,
content: '番茄工作法我也在用,确实挺有效的!',
nickname: '努力的小李',
avatar: '',
createdAt: '2024-01-15 12:10'
}
]
},
{
id: 3,
content: '建议制定每日、每周和每月的目标,这样会更有方向感。另外要学会说不,不是所有活动都要参加。',
nickname: '经验分享者',
avatar: '',
likeCount: 8,
isLiked: false,
createdAt: '2024-01-15 13:45',
replies: []
}
])
//
const isAuthor = computed(() => {
return userStore.user?.id === post.value.userId
@ -292,47 +266,127 @@ const goBack = () => {
router.go(-1)
}
const toggleLike = () => {
post.value.isLiked = !post.value.isLiked
post.value.likeCount += post.value.isLiked ? 1 : -1
ElMessage.success(post.value.isLiked ? '点赞成功' : '取消点赞')
const toggleLike = async () => {
if (!post.value) return
try {
const response = await likePostAPI(post.value.id) as any as ApiResponse<null>
if (response.code === 200) {
post.value.isLiked = !post.value.isLiked
post.value.likeCount += post.value.isLiked ? 1 : -1
ElMessage.success(post.value.isLiked ? '点赞成功' : '取消点赞')
}
} catch (error: any) {
ElMessage.error(error.message || '操作失败')
}
}
const submitComment = () => {
const submitComment = async () => {
if (!newComment.value.trim()) {
ElMessage.warning('请输入评论内容')
return
}
const comment = {
id: Date.now(),
content: newComment.value,
nickname: userStore.user?.nickname || '匿名用户',
avatar: userStore.user?.avatar || '',
likeCount: 0,
isLiked: false,
createdAt: new Date().toLocaleString('zh-CN'),
replies: []
try {
commenting.value = true
const response = await createCommentAPI({
postId: post.value.id,
content: newComment.value,
parentId: null
}) as any as ApiResponse<{ commentId: number }>
if (response.code === 200) {
newComment.value = ''
ElMessage.success('评论发表成功')
//
loadComments()
}
} catch (error: any) {
ElMessage.error(error.message || '评论发表失败')
} finally {
commenting.value = false
}
comments.value.unshift(comment)
newComment.value = ''
post.value.commentCount++
ElMessage.success('评论发表成功')
}
const replyToComment = (comment: any) => {
ElMessage.info('回复功能开发中...')
}
const likeComment = (comment: any) => {
comment.isLiked = !comment.isLiked
comment.likeCount += comment.isLiked ? 1 : -1
ElMessage.success(comment.isLiked ? '点赞成功' : '取消点赞')
const likeComment = async (comment: any) => {
try {
const response = await likeCommentAPI(comment.id) as any as ApiResponse<null>
if (response.code === 200) {
comment.isLiked = !comment.isLiked
comment.likeCount += comment.isLiked ? 1 : -1
ElMessage.success(comment.isLiked ? '点赞成功' : '取消点赞')
}
} catch (error: any) {
ElMessage.error(error.message || '操作失败')
}
}
//
const loadPost = async () => {
const postId = Number(route.params.id)
if (!postId) {
ElMessage.error('帖子ID无效')
router.push('/forum')
return
}
try {
loading.value = true
const response = await getPostDetail(postId) as any as ApiResponse<Post>
if (response.code === 200) {
post.value = response.data
//
console.log('加载的帖子详情:', {
id: post.value.id,
title: post.value.title,
isLiked: post.value.isLiked,
likeCount: post.value.likeCount
})
} else {
ElMessage.error(response.message || '加载帖子失败')
router.push('/forum')
}
} catch (error: any) {
console.error('加载帖子失败:', error)
ElMessage.error(error.response?.data?.message || '加载帖子失败')
router.push('/forum')
} finally {
loading.value = false
}
}
//
const loadComments = async () => {
if (!post.value.id) return
try {
const response = await getComments(post.value.id) as any as ApiResponse<{
total: number
list: any[]
}>
if (response.code === 200) {
comments.value = response.data.list || []
} else {
console.error('加载评论失败:', response.message)
}
} catch (error: any) {
console.error('加载评论失败:', error)
ElMessage.error('加载评论失败')
}
}
onMounted(() => {
onMounted(async () => {
console.log('帖子详情页面加载完成', route.params.id)
await loadPost()
if (post.value.id) {
await loadComments()
}
})
</script>
@ -536,6 +590,18 @@ onMounted(() => {
margin-bottom: 8px;
}
.post-text {
white-space: pre-wrap;
word-wrap: break-word;
font-family: inherit;
margin: 0;
background: none;
border: none;
font-size: inherit;
color: inherit;
line-height: inherit;
}
.post-footer {
padding-top: 24px;
border-top: 1px solid var(--gray-200);
@ -591,6 +657,12 @@ onMounted(() => {
gap: 24px;
}
.empty-comments {
text-align: center;
padding: 48px 24px;
color: var(--gray-500);
}
.comment-item {
display: flex;
gap: 16px;

@ -25,11 +25,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
"/users/code",
"/users/login/code",
// 论坛相关 - 允许未登录用户访问帖子列表和帖子详情
"/posts", // 帖子列表
"/posts/*/", // 帖子详情
"/posts/{id}", // 帖子详情(另一种匹配方式)
"/categories", // 分类列表
// 静态资源访问
"/api/files/**",

@ -47,7 +47,9 @@ public class PostController {
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size,
@RequestParam(value = "sort", defaultValue = "latest") String sort) {
return postService.getPostList(categoryId, keyword, page, size, sort);
// 从当前上下文获取用户ID可能为null未登录用户
Long userId = BaseContext.getId();
return postService.getPostList(categoryId, keyword, page, size, sort, userId);
}
@Operation(summary = "更新帖子")

@ -70,6 +70,11 @@ public class PostListVO {
*/
private Integer commentCount;
/**
*
*/
private Boolean isLiked;
/**
*
*/

@ -31,9 +31,10 @@ public interface PostService {
* @param page
* @param size
* @param sort latest-hot-
* @param userId IDnull
* @return
*/
Result getPostList(Long categoryId, String keyword, Integer page, Integer size, String sort);
Result getPostList(Long categoryId, String keyword, Integer page, Integer size, String sort, Long userId);
/**
*

@ -123,12 +123,16 @@ public class PostServiceImpl implements PostService {
}
@Override
public Result getPostList(Long categoryId, String keyword, Integer page, Integer size, String sort) {
public Result getPostList(Long categoryId, String keyword, Integer page, Integer size, String sort, Long userId) {
// 参数校验
if (page == null || page < 1) page = 1;
if (size == null || size < 1 || size > 50) size = 10;
if (StrUtil.isBlank(sort)) sort = "latest";
// 添加调试日志
log.info("getPostList - 接收到的参数: categoryId={}, keyword={}, page={}, size={}, sort={}, userId={}",
categoryId, keyword, page, size, sort, userId);
// 只使用PageHelper进行分页不设置排序
PageHelper.startPage(page, size);
@ -144,13 +148,13 @@ public class PostServiceImpl implements PostService {
// 获取分页信息
PageInfo<Post> pageInfo = new PageInfo<>(posts);
// 收集所有帖子的分类 ID
List<Long> categoryIds = posts.stream()
.map(Post::getCategoryId)
.distinct()
.collect(Collectors.toList());
// 批量获取分类信息
Map<Long, String> categoryMap = new HashMap<>();
if (!categoryIds.isEmpty()) {
@ -163,6 +167,18 @@ public class PostServiceImpl implements PostService {
// 转换为VO
List<PostListVO> postListVOs = posts.stream().map(post -> {
User user = userMapper.getUserById(post.getUserId());
// 查询用户是否点赞过该帖子
boolean isLiked = false;
if (userId != null) {
log.info("查询帖子 {} 的点赞状态用户ID: {}", post.getId(), userId);
Boolean liked = postLikeMapper.isLiked(post.getId(), userId);
isLiked = liked != null && liked;
log.info("帖子 {} 的点赞状态查询结果: liked={}, isLiked={}", post.getId(), liked, isLiked);
} else {
log.info("用户ID为null跳过帖子 {} 的点赞状态查询", post.getId());
}
return PostListVO.builder()
.id(post.getId())
.title(post.getTitle())
@ -175,10 +191,14 @@ public class PostServiceImpl implements PostService {
.viewCount(post.getViewCount())
.likeCount(post.getLikeCount())
.commentCount(post.getCommentCount())
.isLiked(isLiked)
.createdAt(post.getCreatedAt())
.build();
}).collect(Collectors.toList());
log.info("返回的帖子列表中点赞状态: {}",
postListVOs.stream().map(p -> "帖子" + p.getId() + ":isLiked=" + p.getIsLiked()).collect(Collectors.toList()));
// 返回结果
Map<String, Object> data = new HashMap<>();
data.put("total", pageInfo.getTotal());

Loading…
Cancel
Save