SpringBoot新闻管理系统——评论+分类+标签

1 评论

1.1 编写实体类

一条评论的基本要素,包括了评论本身的id、用户的昵称、email、内容、头像等要显示的信息,还有创建时间、在哪一条新闻下评论的。比较重要的是1.父评论(一个)2.子评论(一个列表)

@Entity
@Table(name = "t_comment")
public class Comment {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String nickname;
    private String email;
    private  String content;
    private String avatar;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    @ManyToOne
    private News news;

    @OneToMany(mappedBy = "parentComment")
    private List<Comment> replyComments=new ArrayList<>();

    @ManyToOne
    private Comment parentComment;

    private boolean adminComment;

1.2 编写dao接口

我们要做的就是评论的增加和显示。增加评论比较简单,就是增加一条记录,显示评论则有些技巧,需要将评论的层级关系显示出来。在数据库层面考虑的话,取同一级的所有评论需要的就是评论的文章和父评论。

public interface CommentRepository extends JpaRepository<Comment,Long> {
    List<Comment> findByNewsIdAndParentCommentNull(Long newId, Sort sort);
}

1.3 编写Service

根据上述两个需求,写出service接口:

public interface CommentService {
    List<Comment> listCommentByNewId(Long newId);
    Comment saveComment(Comment comment);
}

实现保存新评论:
比较简单,也就是获取评论,根据评论的父评论id设定它的父评论对象,接着设置创建时间,然后存放到数据库中。

@Override
    public Comment saveComment(Comment comment) {
        Long parentCommentId=comment.getParentComment().getId();
        if(parentCommentId!=-1){
            comment.setParentComment(commentRepository.findById(parentCommentId).orElse(null));
        }else{
            comment.setParentComment(null);
        }
        comment.setCreateTime(new Date());
        return commentRepository.save(comment);

    }

实现列举评论
主要是要获取评论的所有子评论,由于评论又有自己的子评论,所以有一个递归调用的过程。

  @Override
    public List<Comment> listCommentByNewId(Long newId) {
        Sort sort=Sort.by("createTime");
        List<Comment> comments=commentRepository.findByNewsIdAndParentCommentNull(newId,sort);
        return eachComment(comments);
    }

    private List<Comment> eachComment(List<Comment> comments){
        List<Comment> commentView=new ArrayList<>();
        for(Comment comment:comments){
            Comment c=new Comment();
            BeanUtils.copyProperties(comment,c);
            commentView.add(c);
        }
        //合并评论的各层子代到第一级子代集合
        combineChildren(commentView);
        return commentView;
    }

    private void combineChildren(List<Comment> comments){
        for(Comment comment:comments){
            List<Comment> replys1=comment.getReplyComments();
            for(Comment reply1:replys1){
                //循环迭代,找出子代,存放在tempReplys里
                recursively(reply1);
            }
            comment.setReplyComments(tempReplys);
            //清除temp
            tempReplys=new ArrayList<>();
        }
    }

    private List<Comment> tempReplys=new ArrayList<>();
    private void recursively(Comment comment){
        tempReplys.add(comment);//顶节点
        if(comment.getReplyComments().size()>0){
            List<Comment> replys =comment.getReplyComments();
            for(Comment reply:replys){
                tempReplys.add(reply);
                if(reply.getReplyComments().size()>0){
                    recursively(reply);
                }
            }
        }
    }

1.4 编写Controller

Get请求用于获取所有评论列表。Post请求将新添加的评论根据当前的用户信息添加到数据库中。

@Controller
public class CommentController {

    @Autowired
    private CommentService commentService;

    @Autowired
    private NewService newService;

    private String avatar="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1596010448468&di=907ebbe0a67751f8c93d79da1c9a2c6a&imgtype=0&src=http%3A%2F%2Fattachments.gfan.com%2Fforum%2F201608%2F04%2F2339412b3z30zbd2j6k652.jpg";

    @GetMapping("/comments/{newId}")
    private String comments(@PathVariable Long newId, Model model){
        model.addAttribute("comments",commentService.listCommentByNewId(newId));
        return "new::commentList";
    }
    @PostMapping("/comments")
    private String post(Comment comment, HttpSession session){
        Long newId=comment.getNews().getId();
        comment.setNews(newService.getNew(newId));
        User user=(User) session.getAttribute("user");
        if(user!=null){//是管理员,因为只有管理员能登录
            comment.setAdminComment(true);
            comment.setAvatar(avatar);
        }else{
            comment.setAvatar(avatar);
        }
        commentService.saveComment(comment);
        //System.out.println(commentService.saveComment(comment));
        return "redirect:/comments/"+newId;
    }
}

2 分类和标签显示

主要是显示当前所有的标签和分类,并且点击不同的标签和分类可以分别显示属于它们的新闻。
由于Service基本已经有显示标签和种类的方法了,接下来主要是写两个Controller方法来回应前端的请求。
Tag回应前端的get请求。构造pageable,返回所有的标签的列表和分页显示的新闻,以及当前查看的tag。

@Controller
public class TagShowController {

    @Autowired
    private NewService newService;

    @Autowired
    private TagService tagService;

    @GetMapping("/tags/{id}")
    public String tags(@PageableDefault(size=8,sort = {"updateTime"},direction = Sort.Direction.DESC) Pageable pageable,
                        @PathVariable Long id, Model model){
        List<Tag> tags=tagService.listTagTop(20);
        if(id==-1){
            id=tags.get(0).getId();
        }
        NewQuery newQuery=new NewQuery();
        newQuery.setTypeId(id);
        model.addAttribute("tags",tags);
        model.addAttribute("page",newService.listNew(id,pageable));
        model.addAttribute("activeTagId",id);
        return "tags";
    }
}

同理可以写出Type的Controller:

@Controller
public class TypeShowController {
    @Autowired
    private TypeService typeService;

    @Autowired
    private NewService newService;


    @GetMapping("/types/{id}")
    public String types(@PageableDefault(size=8,sort = {"updateTime"},direction = Sort.Direction.DESC)Pageable pageable,
                        @PathVariable Long id, Model model){
        List<Type> types=typeService.listTypeTop(20);
        if(id==-1){
            id=types.get(0).getId();
        }
        NewQuery newQuery=new NewQuery();
        newQuery.setTypeId(id);
        model.addAttribute("types",types);
        model.addAttribute("page",newService.listNew(pageable,newQuery));
        model.addAttribute("activeTypeId",id);
        return "types";
    }
}

3 测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_42189888/article/details/107746200