目录
一、评论发布与删除
1.前端评论发布与删除
2.后端评论发布与删除
二、评论回复、点赞与举报
1.前端评论回复、点赞与举报
2.后端评论回复、点赞与举报
三、评论分页加载与排序
1.前端评论分页加载与排序
2.后端评论分页加载与排序
四、用户评论时的身份验证
五、评论管理后台
1.前端评论管理后台
1.后端评论管理后台
六、文章收藏功能
1.前端文章收藏功能
2.后端文章收藏功能
七、关注作者功能
2.前端关注作者功能
2.后端关注作者功能
在文章详情组件中添加评论列表、发布评论表单以及删除评论按钮。
在CommentController
中添加创建评论和删除评论的接口。
@PostMapping("/articles/{articleId}/comments")
public ResponseEntity createComment(@PathVariable Long articleId, @RequestBody Comment comment) {
Optional 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 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 {
List findByArticleId(Long articleId);
}
在评论列表中添加回复评论表单、点赞按钮和举报按钮。
-
{{ comment.content }}
在CommentController
中添加回复评论、点赞评论和举报评论的接口。
@PostMapping("/{commentId}/replies")
public ResponseEntity replyComment(@PathVariable Long commentId, @RequestBody Comment reply) {
Optional 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 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.");
}
通过上述代码,我们实现了评论回复、点赞与举报功能。在前端,我们为每个评论添加了回复表单、点赞按钮和举报按钮。在后端,我们创建了回复评论、点赞评论和举报评论的接口。
在这一部分,我们将继续实现文章详情页面中的评论功能。我们将实现评论的分页加载、评论排序以及用户评论时的身份验证。
首先,在评论列表的底部添加一个“加载更多”按钮。
然后,在 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;
},
},
};
在 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 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 {
// ...
}
为了方便管理员对评论进行管理,我们将实现一个评论管理后台。
在前端项目中,创建一个评论管理组件。该组件应包含一个评论列表,以便管理员查看、编辑和删除评论。
Comment Management
ID
Content
Actions
{{ comment.id }}
{{ comment.content }}
在后端项目中,创建一个新的 AdminCommentController
,提供获取所有评论、编辑评论和删除评论的接口。
@RestController
@RequestMapping("/api/admin/comments")
public class AdminCommentController {
@Autowired
private CommentRepository commentRepository;
@GetMapping
public ResponseEntity getAllComments() {
List comments = commentRepository.findAll();
return ResponseEntity.ok(comments);
}
@PutMapping("/{commentId}")
public ResponseEntity updateComment(@PathVariable Long commentId, @RequestBody Comment updatedComment) {
Optional 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 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.");
}
}
}
通过上述代码,我们实现了一个简单的评论管理后台。管理员可以查看、编辑和删除评论。你可以根据实际需求进一步完善这个后台,例如添加分页、筛选和排序功能。
至此,我们已经完成了博客平台的评论功能。我们实现了评论的发布与删除、回复、点赞与举报、分页加载与排序、身份验证以及评论管理后台。你可以参考这些实现来完成其他功能模块,例如文章收藏、关注作者等。
在文章详情页面添加一个收藏按钮,用户可以点击该按钮收藏或取消收藏文章。
在后端项目中,创建一个新的 Favorite
实体类,表示用户收藏的文章。
@Entity
public class Favorite {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private User user;
@ManyToOne
private Article article;
// ... getter 和 setter ...
}
然后,创建一个 FavoriteRepository
,用于操作 Favorite
实体。
public interface FavoriteRepository extends JpaRepository {
Optional findByUserIdAndArticleId(Long userId, Long articleId);
List findByUserId(Long userId);
void deleteByUserIdAndArticleId(Long userId, Long articleId);
}
接下来,在 FavoriteController
中添加收藏文章和取消收藏文章的接口。
@RestController
@RequestMapping("/api/favorites")
public class FavoriteController {
@Autowired
private 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.");
}
}
在作者详情页面添加一个关注按钮,用户可以点击该按钮关注或取消关注作者。
在后端项目中,创建一个新的 Follow
实体类,表示用户关注的作者。
@Entity
public class Follow {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private User follower;
@ManyToOne
private User following;
// ... getter 和 setter ...
}
然后,创建一个 FollowRepository
,用于操作 Follow
实体。
public interface FollowRepository extends JpaRepository {
Optional findByFollowerIdAndFollowingId(Long followerId, Long followingId);
List findByFollowerId(Long followerId);
void deleteByFollowerIdAndFollowingId(Long followerId, Long followingId);
}
接下来,在 FollowController
中添加关注作者和取消关注作者的接口。
@RestController
@RequestMapping("/api/follows")
public class FollowController {
@Autowired
private 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.");
}
}
至此,我们已经实现了文章收藏和关注作者功能。用户可以在文章详情页面收藏或取消收藏文章,在作者详情页面关注或取消关注作者。你可以继续扩展这个博客平台,实现更多功能,如用户动态、通知等。
Comments