> 文章列表 > 博客平台:评论发布与删除、评论回复、评论点赞、举报、关注、收藏模块

博客平台:评论发布与删除、评论回复、评论点赞、举报、关注、收藏模块

博客平台:评论发布与删除、评论回复、评论点赞、举报、关注、收藏模块

目录

一、评论发布与删除

1.前端评论发布与删除

2.后端评论发布与删除

二、评论回复、点赞与举报

1.前端评论回复、点赞与举报

2.后端评论回复、点赞与举报

三、评论分页加载与排序

1.前端评论分页加载与排序

2.后端评论分页加载与排序

四、用户评论时的身份验证

五、评论管理后台

1.前端评论管理后台

1.后端评论管理后台

六、文章收藏功能

1.前端文章收藏功能

2.后端文章收藏功能

七、关注作者功能

2.前端关注作者功能

2.后端关注作者功能


一、评论发布与删除

1.前端评论发布与删除

在文章详情组件中添加评论列表、发布评论表单以及删除评论按钮。

<template><div class="article-detail"><!-- ... --><div class="comments"><h3>Comments</h3><div class="comment-form"><textarea v-model="newComment" placeholder="Write your comment"></textarea><button @click="submitComment">Submit</button></div><ul><li v-for="comment in comments" :key="comment.id">{{ comment.content }}<button @click="deleteComment(comment.id)">Delete</button></li></ul></div></div>
</template><script>
export default {data() {return {// ...newComment: "",comments: [],};},async mounted() {await this.fetchArticle();await this.incrementArticleViews();await this.fetchRelatedArticles();await this.fetchComments();},methods: {// ...async fetchComments() {const response = await this.$http.get(`/api/articles/${this.articleId}/comments`);this.comments = response.data;},async submitComment() {const response = await this.$http.post(`/api/articles/${this.articleId}/comments`, {content: this.newComment,});this.comments.push(response.data);this.newComment = "";},async deleteComment(commentId) {await this.$http.delete(`/api/comments/${commentId}`);this.comments = this.comments.filter((comment) => comment.id !== commentId);},},
};
</script>

2.后端评论发布与删除

CommentController中添加创建评论和删除评论的接口。

@PostMapping("/articles/{articleId}/comments")
public ResponseEntity<?> createComment(@PathVariable Long articleId, @RequestBody Comment comment) {Optional<Article> optionalArticle = articleRepository.findById(articleId);if (optionalArticle.isPresent()) {Article article = optionalArticle.get();comment.setArticle(article);Comment savedComment = commentRepository.save(comment);return ResponseEntity.ok(savedComment);} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Article not found.");}
}@DeleteMapping("/{commentId}")
public ResponseEntity<?> deleteComment(@PathVariable Long commentId) {Optional<Comment> optionalComment = commentRepository.findById(commentId);if (optionalComment.isPresent()) {Comment comment = optionalComment.get();commentRepository.delete(comment);return ResponseEntity.ok("Comment deleted successfully.");} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Comment not found.");}
}

CommentRepository中添加根据文章 ID 获取评论的方法。

public interface CommentRepository extends JpaRepository<Comment, Long> {List<Comment> findByArticleId(Long articleId);
}

二、评论回复、点赞与举报

1.前端评论回复、点赞与举报

在评论列表中添加回复评论表单、点赞按钮和举报按钮。

<template><div class="article-detail"><!-- ... --><div class="comments"><!-- ... --><ul><li v-for="comment in comments" :key="comment.id">{{ comment.content }}<div class="comment-actions"><button @click="replyComment(comment.id)">Reply</button><button @click="likeComment(comment.id)">Like ({{ comment.likes }})</button><button @click="reportComment(comment.id)">Report</button></div><div class="reply-form" v-if="replyCommentId === comment.id"><textarea v-model="newReply" placeholder="Write your reply"></textarea><button @click="submitReply">Submit</button></div></li></ul></div></div>
</template><script>
export default {data() {return {// ...newReply: "",replyCommentId: null,};},methods: {// ...replyComment(commentId) {this.replyCommentId = commentId;},async submitReply() {// ... 提交回复的逻辑 ...this.newReply = "";this.replyCommentId = null;},async likeComment(commentId) {// ... 点赞评论的逻辑 ...},async reportComment(commentId) {// ... 举报评论的逻辑 ...},},
};
</script>

2.后端评论回复、点赞与举报

CommentController中添加回复评论、点赞评论和举报评论的接口。

@PostMapping("/{commentId}/replies")
public ResponseEntity<?> replyComment(@PathVariable Long commentId, @RequestBody Comment reply) {Optional<Comment> optionalComment = commentRepository.findById(commentId);if (optionalComment.isPresent()) {Comment parentComment = optionalComment.get();reply.setParentComment(parentComment);Comment savedReply = commentRepository.save(reply);return ResponseEntity.ok(savedReply);} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Comment not found.");}
}@PostMapping("/{commentId}/likes")
public ResponseEntity<?> likeComment(@PathVariable Long commentId) {Optional<Comment> optionalComment = commentRepository.findById(commentId);if (optionalComment.isPresent()) {Comment comment = optionalComment.get();comment.setLikes(comment.getLikes() + 1);commentRepository.save(comment);return ResponseEntity.ok("Comment liked successfully.");} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Comment not found.");}
}@PostMapping("/{commentId}/reports")
public ResponseEntity<?> reportComment(@PathVariable Long commentId) {// ... 举报评论的逻辑 ...return ResponseEntity.ok("Comment reported successfully.");
}

通过上述代码,我们实现了评论回复、点赞与举报功能。在前端,我们为每个评论添加了回复表单、点赞按钮和举报按钮。在后端,我们创建了回复评论、点赞评论和举报评论的接口。

在这一部分,我们将继续实现文章详情页面中的评论功能。我们将实现评论的分页加载、评论排序以及用户评论时的身份验证。

三、评论分页加载与排序

1.前端评论分页加载与排序

首先,在评论列表的底部添加一个“加载更多”按钮。

<template><div class="article-detail"><!-- ... --><div class="comments"><!-- ... --><ul><!-- ... --></ul><button @click="loadMoreComments" v-if="hasMoreComments">Load more</button></div></div>
</template>

然后,在 Vue 组件的 data 对象中添加分页相关的数据。

export default {data() {return {// ...commentsPage: 0,hasMoreComments: true,};},methods: {// ...async loadMoreComments() {this.commentsPage++;const response = await this.$http.get(`/api/articles/${this.articleId}/comments`, {params: {page: this.commentsPage,sort: "createdAt,desc",},});this.comments.push(...response.data.content);this.hasMoreComments = !response.data.last;},},
};

2.后端评论分页加载与排序

CommentController 中修改获取评论的接口,支持分页查询和排序。

@GetMapping("/articles/{articleId}/comments")
public ResponseEntity<?> getComments(@PathVariable Long articleId,@RequestParam(defaultValue = "0") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(defaultValue = "createdAt,desc") String[] sort) {Sort sorted = Sort.by(Arrays.stream(sort).map(s -> {if (s.startsWith("-")) {return Sort.Order.desc(s.substring(1));} else {return Sort.Order.asc(s);}}).collect(Collectors.toList()));Pageable pageable = PageRequest.of(page, size, sorted);Page<Comment> comments = commentRepository.findByArticleId(articleId, pageable);return ResponseEntity.ok(comments);
}

四、用户评论时的身份验证

为了让只有登录用户才能评论,我们需要在前端添加身份验证逻辑。

在 Vue 组件的 data 对象中添加一个 isAuthenticated 数据。

export default {data() {return {// ...isAuthenticated: false,};},async mounted() {// ...this.isAuthenticated = await this.checkAuthentication();},methods: {// ...async checkAuthentication() {// ... 检查用户是否已登录的逻辑 ...},async submitComment() {if (!this.isAuthenticated) {alert("Please log in to comment.");return;}// ... 提交评论的逻辑 ...},},
};

在后端,我们可以使用 Spring Security 来实现用户身份验证。首先,在 CommentController 类上添加 @PreAuthorize 注解,要求用户登录后才能访问创建评论和删除评论的接口。

@RestController
@RequestMapping("/api/comments")
@PreAuthorize("isAuthenticated()")
public class CommentController {// ...
}

五、评论管理后台

为了方便管理员对评论进行管理,我们将实现一个评论管理后台。

1.前端评论管理后台

在前端项目中,创建一个评论管理组件。该组件应包含一个评论列表,以便管理员查看、编辑和删除评论。

<template><div class="comment-management"><h2>Comment Management</h2><table><thead><tr><th>ID</th><th>Content</th><th>Actions</th></tr></thead><tbody><tr v-for="comment in comments" :key="comment.id"><td>{{ comment.id }}</td><td>{{ comment.content }}</td><td><button @click="editComment(comment)">Edit</button><button @click="deleteComment(comment.id)">Delete</button></td></tr></tbody></table></div>
</template><script>
export default {data() {return {comments: [],};},async mounted() {await this.fetchComments();},methods: {async fetchComments() {const response = await this.$http.get("/api/admin/comments");this.comments = response.data;},editComment(comment) {// ... 编辑评论的逻辑 ...},async deleteComment(commentId) {// ... 删除评论的逻辑 ...},},
};
</script>

1.后端评论管理后台

在后端项目中,创建一个新的 AdminCommentController,提供获取所有评论、编辑评论和删除评论的接口。

@RestController
@RequestMapping("/api/admin/comments")
public class AdminCommentController {@Autowiredprivate CommentRepository commentRepository;@GetMappingpublic ResponseEntity<?> getAllComments() {List<Comment> comments = commentRepository.findAll();return ResponseEntity.ok(comments);}@PutMapping("/{commentId}")public ResponseEntity<?> updateComment(@PathVariable Long commentId, @RequestBody Comment updatedComment) {Optional<Comment> optionalComment = commentRepository.findById(commentId);if (optionalComment.isPresent()) {Comment comment = optionalComment.get();comment.setContent(updatedComment.getContent());commentRepository.save(comment);return ResponseEntity.ok("Comment updated successfully.");} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Comment not found.");}}@DeleteMapping("/{commentId}")public ResponseEntity<?> deleteComment(@PathVariable Long commentId) {Optional<Comment> optionalComment = commentRepository.findById(commentId);if (optionalComment.isPresent()) {Comment comment = optionalComment.get();commentRepository.delete(comment);return ResponseEntity.ok("Comment deleted successfully.");} else {return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Comment not found.");}}
}

通过上述代码,我们实现了一个简单的评论管理后台。管理员可以查看、编辑和删除评论。你可以根据实际需求进一步完善这个后台,例如添加分页、筛选和排序功能。

至此,我们已经完成了博客平台的评论功能。我们实现了评论的发布与删除、回复、点赞与举报、分页加载与排序、身份验证以及评论管理后台。你可以参考这些实现来完成其他功能模块,例如文章收藏、关注作者等。

六、文章收藏功能

1.前端文章收藏功能

在文章详情页面添加一个收藏按钮,用户可以点击该按钮收藏或取消收藏文章。

<template><div class="article-detail"><!-- ... --><button @click="toggleFavorite">{{ isFavorite ? 'Unfavorite' : 'Favorite' }}</button><!-- ... --></div>
</template><script>
export default {data() {return {// ...isFavorite: false,};},methods: {// ...async toggleFavorite() {if (!this.isAuthenticated) {alert("Please log in to favorite the article.");return;}if (this.isFavorite) {// 取消收藏文章的逻辑 ...} else {// 收藏文章的逻辑 ...}this.isFavorite = !this.isFavorite;},},
};
</script>

2.后端文章收藏功能

在后端项目中,创建一个新的 Favorite 实体类,表示用户收藏的文章。

@Entity
public class Favorite {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@ManyToOneprivate User user;@ManyToOneprivate Article article;// ... getter 和 setter ...
}

然后,创建一个 FavoriteRepository,用于操作 Favorite 实体。

public interface FavoriteRepository extends JpaRepository<Favorite, Long> {Optional<Favorite> findByUserIdAndArticleId(Long userId, Long articleId);List<Favorite> findByUserId(Long userId);void deleteByUserIdAndArticleId(Long userId, Long articleId);
}

接下来,在 FavoriteController 中添加收藏文章和取消收藏文章的接口。


@RestController
@RequestMapping("/api/favorites")
public class FavoriteController {@Autowiredprivate FavoriteRepository favoriteRepository;@PostMapping("/{articleId}")public ResponseEntity<?> favoriteArticle(@PathVariable Long articleId, Principal principal) {// ... 收藏文章的逻辑 ...return ResponseEntity.ok("Article favorited successfully.");}@DeleteMapping("/{articleId}")public ResponseEntity<?> unfavoriteArticle(@PathVariable Long articleId, Principal principal) {// ... 取消收藏文章的逻辑 ...return ResponseEntity.ok("Article unfavorited successfully.");}
}

七、关注作者功能

2.前端关注作者功能

在作者详情页面添加一个关注按钮,用户可以点击该按钮关注或取消关注作者。

<template><div class="author-detail"><!-- ... --><button @click="toggleFollow">{{ isFollowing ? 'Unfollow' : 'Follow' }}</button><!-- ... --></div>
</template><script>
export default {data() {return {// ...isFollowing: false,};},methods: {// ...async toggleFollow() {if (!this.isAuthenticated) {alert("Please log in to follow the author.");return;}if (this.isFollowing) {// 取消关注作者的逻辑 ...} else {// 关注作者的逻辑 ...}this.isFollowing = !this.isFollowing;},},
};
</script>

2.后端关注作者功能

在后端项目中,创建一个新的 Follow 实体类,表示用户关注的作者。

@Entity
public class Follow {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@ManyToOneprivate User follower;@ManyToOneprivate User following;// ... getter 和 setter ...
}

然后,创建一个 FollowRepository,用于操作 Follow 实体。

public interface FollowRepository extends JpaRepository<Follow, Long> {Optional<Follow> findByFollowerIdAndFollowingId(Long followerId, Long followingId);List<Follow> findByFollowerId(Long followerId);void deleteByFollowerIdAndFollowingId(Long followerId, Long followingId);
}

接下来,在 FollowController 中添加关注作者和取消关注作者的接口。


@RestController
@RequestMapping("/api/follows")
public class FollowController {@Autowiredprivate FollowRepository followRepository;@PostMapping("/{authorId}")public ResponseEntity<?> followAuthor(@PathVariable Long authorId, Principal principal) {// ... 关注作者的逻辑 ...return ResponseEntity.ok("Author followed successfully.");}@DeleteMapping("/{authorId}")public ResponseEntity<?> unfollowAuthor(@PathVariable Long authorId, Principal principal) {// ... 取消关注作者的逻辑 ...return ResponseEntity.ok("Author unfollowed successfully.");}
}

至此,我们已经实现了文章收藏和关注作者功能。用户可以在文章详情页面收藏或取消收藏文章,在作者详情页面关注或取消关注作者。你可以继续扩展这个博客平台,实现更多功能,如用户动态、通知等。