SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能

新建数据库表SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第1张图片

Article

@Data
@TableName("sys_article")
public class Article implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 标题
     */
    private String name;

    /**
     * 内容
     */
    private String content;

    /**
     * 发布人
     */
    private String user;

    /**
     * 时间
     */
    private String time;


}

 ArticleController

@RestController
@RequestMapping("/article")
public class ArticleController {

    @Resource
    private ArticleService articleService;

    //修改或增加
    @PostMapping("/saveArticle")
    public Result saveArticle(@RequestBody Article article) {
        //新增或修改
        return Result.success(articleService.saveOrUpdate(article));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(articleService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(articleService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List ids) {
        return Result.success(articleService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage
page = new Page<>(pageNum, pageSize); QueryWrapper
queryWrapper = new QueryWrapper<>(); if (StrUtil.isNotBlank(name)) { queryWrapper.like("name", name); } return Result.success(articleService.page(page, queryWrapper)); } }

Article.vue





一、集成markdown

1.下载

npm install [email protected] -S

2.全局注册

main.js

import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'

Vue.use(mavonEditor)

二、文章上传功能实现

Article.vue

//绑定事件

            
          


//导入包

import axios from "axios";


//方法

//绑定@imgAdd event
    imgAdd(pos,$file){
      let $vm =this.$refs.md
      //第一步,将图片上传到服务器
      const formData = new FormData();
      formData.append('file',$file);
      axios({
        url:'http://localhost:9090/file/upload',
        method:'post',
        data:formData,
        heards:{'Content-Type':'multipart/form-data'},
      }).then((res) =>{
        //第二步,将要返回的url替换到原本位置![...](./0) -> ![...](url)
        $vm.$img2Url(pos,res.data)
      })
    },

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第2张图片

 ArticleController

 //修改或增加
    @PostMapping("/saveArticle")
    public Result saveArticle(@RequestBody Article article) {
        if (article.getId() == null){//新增
            article.setTime(DateUtil.now());
            article.setUser(TokenUtils.getCurrentUser().getNickname());
        }
        //新增或修改
        return Result.success(articleService.saveOrUpdate(article));
    }

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第3张图片

 内容预览实现

//绑定事件

          
        


//显示文章内容

        
          
//定义变量 content: '', viewDialogVis: false //编写方法 view(content) { this.content = content this.viewDialogVis = true },

前台显示:

router/index.js

{
                path: 'article',
                name: 'FrontArticle',
                component: () => import('../views/front/Article.vue')
            },

front/Article.vue





渲染列表:





SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第4张图片

三、前台文章详情显示

ArticelController

@Resource
    private ArticleMapper articleMapper;



    @GetMapping("/detail/{id}")
    public Result getById(@PathVariable("id") Integer id){
        return Result.success(articleMapper.selectById(id));
    }

 ArticleDetail





四、评论功能

新建数据库表:

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第5张图片

 Comment

@Data
@TableName("t_comment")
public class Comment implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 评论内容
     */
    private String content;

    /**
     * 用户id,用于关联用户头像
     */
    private Integer userId;

    /**
     * 时间
     */
    private String time;

    /**
     * 父id
     */
    private Integer pid;

    /**
     * 最上级评论id
     */
    private Integer originId;

    /**
     * 关联文章的article
     */
    private Integer articleId;


    @TableField(exist = false)
    private String nickname;

    @TableField(exist = false)
    private String avatarUrl;

}

CommentController

@RestController
@RequestMapping("/comment")
public class CommentController {

    @Resource
    private CommentService commentService;

    @Resource
    private CommentMapper commentMapper;

    @GetMapping("/detail/{id}")
    public Result getById(@PathVariable("id") Integer id){
        return Result.success(commentMapper.selectById(id));
    }

    //修改或增加
    @PostMapping("/saveComment")
    public Result saveComment(@RequestBody Comment comment) {
        //新增或修改
        return Result.success(commentService.saveOrUpdate(comment));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(commentService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(commentService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List ids) {
        return Result.success(commentService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage page = new Page<>(pageNum, pageSize);
        QueryWrapper queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(commentService.page(page, queryWrapper));
    }

}

实现

①查询评论实现

Comment

 @TableField(exist = false)
    private String nickname;

    @TableField(exist = false)
    private String avatarUrl;

CommentController

 @GetMapping("/findCommentDetail/{articleId}")
    public Result findCommentDetail(@PathVariable("articleId") Integer articleId) {
        List articleComments = commentService.findCommentDetail(articleId);
        return Result.success(articleComments);
    }

CommentService

List findCommentDetail(Integer articleId);

CommentServiceImpl

@Resource
    private CommentMapper commentMapper;

    @Override
    public List findCommentDetail(Integer articleId) {
        return commentMapper.findCommentDetail(articleId);
    }

CommentMapper

@Select("select c.*,u.nickname,u.avatar_url from t_comment c left join sys_user u on c.user_id = u.id where  c.article_id = #{articleId}")
    List findCommentDetail(@Param("articleId") Integer articleId);

 ArticleDetail.vue

评论
评论
{{ item.nickname }}: {{ item.content }}
{{ item.time }}
回复 删除
content: '', comments: [] created() { this.load() this.loadComment() }, methods: { load() { const id = this.$route.query.id this.request.get("/article/detail/" + id).then(res => { //注意data this.article = res.data }) }, loadComment(){ const id = this.$route.query.id this.request.get("/comment/findCommentDetail/" + id).then(res => { //注意data this.comments = res.data }) } }

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第6张图片 

 ②评论功能实现

 CommentController

//修改或增加
    @PostMapping("/saveComment")
    public Result saveComment(@RequestBody Comment comment) {
        //新增评论
        if(comment.getId() == null){
            comment.setUserId(TokenUtils.getCurrentUser().getId());
            comment.setTime(DateUtil.now());
        }
        //新增或修改
        return Result.success(commentService.saveOrUpdate(comment));
    }

ArticleDetail

评论
commentForm: {}, //将id设为全局变量 id: this.$route.query.id save() { if (!this.user.id){ this.$message.warning("请登录之后操作") return } this.commentForm.articleId = this.id this.request.post("/comment/saveComment", this.commentForm).then(res => { if (res.code === '200') { this.$message.success("评论成功") this.loadComment() //初始化评论对象内容 this.commentForm = {} } else { this.$message.error(res.msg) } }) },

 ③删除评论功能实现

 ArticleDetail.vue

            删除



del(id) {
      this.request.delete("/comment/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.loadComment()
        } else {
          this.$message.error("删除失败")
        }
      })
    },

④多级评论功能实现

回复对话框

ArticleDetail

 回复




      
        
          
        
      
      
    



dialogFormVisible: false



save() {
      if (!this.user.id) {
        this.$message.warning("请登录之后操作")
        return
      }
      this.commentForm.articleId = this.id
      if (this.commentForm.contentReply) {
        this.commentForm.content = this.commentForm.contentReply
      }
      this.request.post("/comment/saveComment", this.commentForm).then(res => {
        if (res.code === '200') {
          this.$message.success("评论成功")
          //初始化评论对象内容
          this.commentForm = {}
          this.loadComment()
          this.dialogFormVisible = false
        } else {
          this.$message.error(res.msg)
        }
      })
    },



handleReply(pid) {
      this.commentForm = {pid: pid, originId: pid}
      this.dialogFormVisible = true
    }

 评论显示:

{{ subItem.nickname }}: {{ subItem.content }}
{{ subItem.time }}
回复 删除
handleReply(pid) { this.commentForm = {pid: pid} this.dialogFormVisible = true }

Comment

@TableField(exist = false)
    private List children;

    @TableField(exist = false)
    //父节点的用户昵称
    private String pNickname;

    @TableField(exist = false)
    //父节点的用户id
    private Integer pUserId;

CommentController

//修改或增加
    @PostMapping("/saveComment")
    public Result saveComment(@RequestBody Comment comment) {
        //新增评论
        if (comment.getId() == null) {
            comment.setUserId(TokenUtils.getCurrentUser().getId());
            comment.setTime(DateUtil.now());

            //判断如果是回复,进行处理
            if (comment.getPid() != null) {
                Integer pid = comment.getPid();
                Comment pComment = commentService.getById(pid);
                //如果当前回复的父级有祖宗,那么设置相同的祖宗
                if (pComment.getOriginId() != null) {
                    comment.setOriginId(pComment.getOriginId());
                    //否则设置为当前回复的祖宗
                } else {
                    comment.setOriginId(comment.getPid());
                }
            }
        }
        //新增或修改
        commentService.saveOrUpdate(comment);
        return Result.success();
    }


@GetMapping("/findCommentDetail/{articleId}")
    public Result findCommentDetail(@PathVariable("articleId") Integer articleId) {
        //查询所有的评论数据
        List articleComments = commentService.findCommentDetail(articleId);
        //查询评论数据,不包括回复
        List originList = articleComments.stream().filter(comment -> comment.getOriginId() == null).collect(Collectors.toList());

        //设置评论数据的子节点,也就是回复内容
        for (Comment origin : originList) {
            //表示回复对象集合
            List comments = articleComments.stream().filter(comment -> origin.getId().equals(comment.getOriginId())).collect(Collectors.toList());
            comments.forEach(comment -> {
                //找到父级评论的用户id和用户昵称,并设置给当前的回复对象
                articleComments.stream().filter(c1 -> c1.getId().equals(comment.getPid())).findFirst().ifPresent(v -> {
                    comment.setPUserId(v.getUserId());
                    comment.setPNickname(v.getNickname());
                });
            });
            origin.setChildren(comments);
        }
        return Result.success(originList);
    }

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第7张图片

 回复人显示

ArticleDetail.vue

@{{subItem.pnickname}}:

SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能_第8张图片

 

你可能感兴趣的:(windows)