豆宝社区项目实战教程简介
本项目实战教程配有免费视频教程,配套代码完全开源。手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目。本项目难度适中,为便于大家学习,每一集视频教程对应在Github上的每一次提交。
项目首页截图
代码开源地址
视频教程地址
前端技术栈
Vue Vuex Vue Router Axios Bulma Buefy Element Vditor DarkReader
后端技术栈
Spring Boot Mysql Mybatis MyBatis-Plus Spring Security JWT Lombok
评论功能列表前端
日期格式化
yarn add date-fns
使用
API
src\api\创建comment.js
import request from '@/utils/request'
export function fetchCommentsByTopicId(topic_Id) {
return request({
url: '/comment/get_comments',
method: 'get',
params: {
topicid: topic_Id
}
})
}
export function pushComment(data) {
return request({
url: '/comment/add_comment',
method: 'post',
data: data
})
}
创建组件
1.src\components\创建Comment\Comments.vue
<template>
<section class="box comments">
<hr />
<h3 class="title is-5">Comments</h3>
<lv-comments-item
v-for="comment in comments"
:key="`comment-${comment.id}`"
:comment="comment"
/>
</section>
</template>
<script>
import { mapGetters } from 'vuex'
import { fetchCommentsByTopicId } from '@/api/comment'
import LvCommentsItem from './CommentsItem'
export default {
name: 'LvComments',
components: {
LvCommentsItem
},
data() {
return {
comments: []
}
},
props: {
slug: {
type: String,
default: null
}
},
computed: {
...mapGetters([
'token'
])
},
async mounted() {
await this.fetchComments(this.slug)
},
methods: {
// 初始化
async fetchComments(topic_id) {
console.log(topic_id)
fetchCommentsByTopicId(topic_id).then(response => {
const { data } = response
this.comments = data
})
}
}
}
</script>
2.src\components\Comment\创建CommentsItem.vue
<template>
<article class="media">
<figure class="media-left image is-48x48">
<img :src="`https://cn.gravatar.com/avatar/${comment.userId}?s=164&d=monsterid`">
</figure>
<div class="media-content">
<div class="content">
<p>
<strong>{{ comment.username }}</strong>
<small class="ml-2">{{ comment.createTime | date }}</small>
<br />
{{ comment.content }}
</p>
</div>
</div>
</article>
</template>
<script>
export default {
name: 'LvCommentsItem',
props: {
comment: {
type: Object,
required: true
}
}
}
</script>
修改Detail.vue
src\views\post\Detail.vue
评论功能列表后端
VO
@Data
public class CommentVO {
private String id;
private String content;
private String topicId;
private String userId;
private String username;
private Date createTime;
}
BmsComment
import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
import java.util.Date;
@Data
@Builder
@TableName("bms_comment")
@AllArgsConstructor
@NoArgsConstructor
public class BmsComment implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private String id;
/**
* 内容
*/
@NotBlank(message = "内容不可以为空")
@TableField(value = "content")
private String content;
/**
* 作者ID
*/
@TableField("user_id")
private String userId;
/**
* topicID
*/
@TableField("post_id")
private String postId;
/**
* 创建时间
*/
@TableField(value = "create_time", fill = FieldFill.INSERT)
private Date createTime;
/**
* 修改时间
*/
@TableField(value = "modify_time", fill = FieldFill.UPDATE)
private Date modifyTime;
}
BmsCommentMapper
public interface BmsCommentMapper extends BaseMapper<BmsComment> {
List<CommentVO> getCommentsByTopicID(String topicid);
}
BmsCommentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.notepad.blog.mapper.BmsCommentMapper">
<resultMap id="topicVO" type="com.notepad.blog.domain.vo.CommentVO">
<id column="id" property="id"/>
<result column="content" property="content"/>
<result column="user_id" property="userId"/>
<result column="topic_id" property="topicId"/>
<result column="username" property="username"/>
<result column="create_time" property="createTime"/>
</resultMap>
<select id="getCommentsByTopicID" resultMap="topicVO">
select bms_comment.*, ums_user.username
from bms_comment
join ums_user on ums_user.id = bms_comment.user_id
where post_id = #{postId}
order by create_time desc
</select>
</mapper>
BmsCommentController
package com.notepad.blog.controller;
import com.notepad.blog.common.api.ApiResult;
import com.notepad.blog.domain.BmsComment;
import com.notepad.blog.domain.UmsUser;
import com.notepad.blog.domain.vo.CommentVO;
import com.notepad.blog.service.BmsCommentService;
import com.notepad.blog.service.UmsUserService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/comment")
public class BmsCommentController {
@Resource
private BmsCommentService commentService;
@Resource
private UmsUserService userService;
/**
* 评论列表
*
* @param topicid
* @return
*/
@GetMapping("/get_comments")
public ApiResult<List<CommentVO>> getCommentsByTopicID(@RequestParam(value = "topicid", defaultValue = "1") String topicid) {
List<CommentVO> lstBmsComment = commentService.getCommentsByTopicID(topicid);
return ApiResult.success(lstBmsComment);
}
}
BmsCommentService
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.notepad.blog.domain.BmsComment;
import com.notepad.blog.domain.vo.CommentVO;
import com.notepad.blog.mapper.BmsCommentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @ClassName BmsCommentService
* @description:
* @author: 一粒麦子
* @Date 2021/2/13 21:26
**/
@Service
public class BmsCommentService extends ServiceImpl<BmsCommentMapper, BmsComment> {
@Autowired
private BmsCommentMapper commentMapper;
/**
* 评论列表
*
* @param topicid
* @return
*/
public List<CommentVO> getCommentsByTopicID(String topicid) {
List<CommentVO> commentVOList = commentMapper.getCommentsByTopicID(topicid);
return commentVOList;
}
}