paopao/docs/tasks/任务11-Sprint-2-点赞和收藏动态.md
2024-06-30 19:33:33 +08:00

6.3 KiB
Raw Blame History

任务名称: 点赞和收藏动态

目标:

  • 巩固练习: 熟练掌握基于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. 测试

技术/工具需求:

  • [列出完成任务所需的技术栈、工具、软件版本等。]

成功标准:

  • [明确完成任务的评判标准,如代码功能实现、性能指标、测试通过条件等。]

扩展学习(可选):

  • [提供一些额外学习资源或挑战性任务,鼓励学有余力的学生进一步探索。]

评估与反馈:

  • [说明如何提交作业、代码审查的标准、或任何反馈收集机制。]

时间估算:

  • [给出预计完成该任务所需的时间,帮助学生合理安排学习计划。]