6.3 KiB
6.3 KiB
任务名称: 点赞和收藏动态
目标:
- 巩固练习: 熟练掌握基于spring boot开发的基本步骤
- 掌握单元测试
预备知识:
操作步骤:
1. API文档
2. 数据模型设计和实现
2.1 实体类
PostStar
@Entity
public class PostStar extends BaseAuditingEntity{
@Comment("POST ID")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;
@Comment("用户ID")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
}
PostCollection
@Entity
public class PostCollection extends BaseAuditingEntity{
@Comment("POST ID")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;
@Comment("用户ID")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
}
2.2 DTO
PostStarDTO
@Value
public class PostStarDto {
Long id;
PostDto post;
UserDto user;
@JsonSerialize(using = MillisecondToSecondSerializer.class)
Long createdOn;
@JsonSerialize(using = MillisecondToSecondSerializer.class)
Long modifiedOn;
}
PostCollectionDTO
@Value
public class PostCollectionDto {
Long id;
PostDto post;
UserDto user;
@JsonSerialize(using = MillisecondToSecondSerializer.class)
Long createdOn;
@JsonSerialize(using = MillisecondToSecondSerializer.class)
Long modifiedOn;
}
2.3 Mapper
PostStarMapper
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
public interface PostStarMapper {
PostStar toEntity(PostStarDto postStarDto);
PostStarDto toDto(PostStar postStar);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
PostStar partialUpdate(PostStarDto postStarDto, @MappingTarget PostStar postStar);
}
PostCollectionMapper
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = MappingConstants.ComponentModel.SPRING)
public interface PostCollectionMapper {
PostCollection toEntity(PostCollectionDto postCollectionDto);
PostCollectionDto toDto(PostCollection postCollection);
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
PostCollection partialUpdate(PostCollectionDto postCollectionDto, @MappingTarget PostCollection postCollection);
}
3. JPA接口
PostStarRepository
public interface PostStarRepository extends JpaRepository<PostStar, Long> {
Optional<PostStar> findByUserIdAndPostId(Long postId, Long userId);
}
PostCollectionRepository
public interface PostCollectionRepository extends JpaRepository<PostCollection, Long> {
Optional<PostCollection> findByUserIdAndPostId(Long userId, Long postId);
}
4. 业务逻辑
在PostService中添加处理点赞的方法:
/**
* 判断当前用户是对指定文章否已点赞
* @param postId
* @return
*/
public boolean currentUserHasStarred(Long postId){
User user = authService.getCurrentUser();
return postStarRepository.findByUserIdAndPostId(user.getId(), postId).isPresent();
}
/**
* 点赞文章
* @param postId 文章ID
* @return 如果点赞成功返回true,如果已点过赞则返回false
*/
public boolean toggleStar(long postId){
// 获取当前用户
User user = authService.getCurrentUser();
// 确认文章存在
Post post = postRepository.findById(postId).orElseThrow(()->new ResourceNotFoundException("Post","id="+postId));
// 确认用户是否已点赞
PostStar postStar = postStarRepository.findByUserIdAndPostId(user.getId(),postId).orElse(null);
if(postStar==null){
// 如果未点赞,则创建点赞记录并更新文章点赞数
postStar = new PostStar();
postStar.setPost(post);
postStar.setUser(user);
postStarRepository.save(postStar);
post.setUpvoteCount(post.getUpvoteCount()+1);
postRepository.save(post);
return true;
}
// 如果已点赞,则删除点赞记录并更新文章点赞数
postStarRepository.delete(postStar);
post.setUpvoteCount(post.getUpvoteCount()-1);
postRepository.save(post);
return false;
}
对于收藏的处理与点赞类似,不再赘述。
5. RestController
在PostController中添加点赞相关的接口:
@GetMapping("/post/star")
public DataResult<Map<String, Boolean>> currentHasStarred(@PathParam("id") Long postId) {
Map<String, Boolean> result = new HashMap<>();
result.put("status", postService.currentUserHasStarred(postId));
return ResultUtil.ok(result);
}
@PostMapping("/post/star")
public DataResult<Map<String, Boolean>> toggleStar(@RequestBody Map<String, Long> payload) {
boolean stared = postService.toggleStar(payload.get("id"));
Map<String, Boolean> result = new HashMap<>();
result.put("status", stared);
return ResultUtil.ok(result);
}
收藏的接口与点赞类似,不再赘述。
6. 测试
技术/工具需求:
- [列出完成任务所需的技术栈、工具、软件版本等。]
成功标准:
- [明确完成任务的评判标准,如代码功能实现、性能指标、测试通过条件等。]
扩展学习(可选):
- [提供一些额外学习资源或挑战性任务,鼓励学有余力的学生进一步探索。]
评估与反馈:
- [说明如何提交作业、代码审查的标准、或任何反馈收集机制。]
时间估算:
- [给出预计完成该任务所需的时间,帮助学生合理安排学习计划。]