Bean Treasure community project actual combat tutorial introduction

This project is equipped with a free video tutorial, the supporting code is completely open source. Build from scratch the most widely used Springboot+Vue front-end and back-end separation multi-user community project. This project is of moderate difficulty. For your convenience, each video tutorial will correspond to each submission on Github.

Screenshot of project Home Page

Open source code address

The front end

Video Tutorial Address

Video tutorial

Front-end technology stack

Vue Vuex Vue Router Axios Bulma Buefy Element Vditor DarkReader

Back-end technology stack

Spring Boot Mysql Mybatis MyBatis-Plus Spring Security JWT Lombok

Post list backend implementation

Entity class

BmsPost

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_post")
@AllArgsConstructor
@NoArgsConstructor
public class BmsPost implements Serializable {

    private static final long serialVersionUID = 1L;

    /** * primary key */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;
    /** ** title */
    @notblank (message = "header must not be empty ")
    @TableField(value = "title")
    private String title;
    /** * markdown */
    @notblank (message = "The content must not be empty ")
    @TableField("`content`")
    private String content;

    /** * author ID */
    @TableField("user_id")
    private String userId;

    /** * number of comments */
    @TableField("comments")
    @Builder.Default
    private Integer comments = 0;

    /** * select */
    @TableField("collects")
    @Builder.Default
    private Integer collects = 0;

    /** * Number of views */
    @TableField("view")
    @Builder.Default
    private Integer view = 0;

    /** * column ID, default is no column */
    @TableField("section_id")
    @Builder.Default
    private Integer sectionId = 0;

    /** ** top */
    @TableField("top")
    @Builder.Default
    private Boolean top = false;

    /** ** */
    @TableField("essence")
    @Builder.Default
    private Boolean essence = false;

    /** * create time */
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private Date createTime;

    /** * Change the time */
    @TableField(value = "modify_time", fill = FieldFill.UPDATE)
    private Date modifyTime;

    /** * description */
    @TableField("summary")
    private String summary;
}
Copy the code

BmsPostTag

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;


@Data
@TableName("bms_post_tag")
@Accessors(chain = true)
public class BmsPostTag implements Serializable {
    private static final long serialVersionUID = -5028599844989220715L;

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

    @TableField("tag_id")
    private String tagId;

    @TableField("post_id")
    private String postId;
}
Copy the code

BmsTag

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;


@Data
@Builder
@TableName("bms_tag")
@Accessors(chain = true)
public class BmsTag implements Serializable {
    private static final long serialVersionUID = 3257790983905872243L;

    @TableId(type = IdType.ASSIGN_ID)
    private String id;

    @TableField("name")
    private String name;
    /** * Number of topics under the current tag */
    @TableField("post_count")
    @Builder.Default
    private Integer postCount = 1;
}
Copy the code

Vo

package com.notepad.blog.domain.vo;

import com.notepad.blog.domain.BmsTag;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.Date;
import java.util.List;


@Data
@NoArgsConstructor
@AllArgsConstructor
public class PostVO implements Serializable {

    private static final long serialVersionUID = -261082150965211545L;

    /** * article ID */
    private String id;
    /** * user ID */
    private String userId;
    /** ** avatar */
    private String avatar;
    /** * User name */
    private String alias;
    /** * account */
    private String username;
    /** ** title */
    private String title;
    /** * comment statistics */
    private Integer comments;
    /** ** top */
    private Boolean top;
    /** ** */
    private Boolean essence;
    /** * select */
    private Integer collects;
    /** * topic tag */
    private List<BmsTag> tags;
    /** * views */
    private Integer view;
    /** * create time */
    private Date createTime;
    /** * Change the time */
    private Date modifyTime;

    /** ** **
    private String summary;
}
Copy the code

mapper.xml


      
<! DOCTYPEmapper PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.notepad.blog.mapper.BmsPostMapper">
    <resultMap id="postVo" type="com.notepad.blog.domain.vo.PostVO">
        <id column="id" property="id"/>
        <result column="title" property="title"/>
        <result column="user_id" property="userId"/>
        <result column="comments" property="comments"/>
        <result column="view" property="view"/>
        <result column="collects" property="collects"/>
        <result column="top" property="top"/>
        <result column="essence" property="essence"/>
        <result column="create_time" property="createTime"/>
        <result column="modify_time" property="modifyTime"/>
        <result column="username" property="username"/>
        <result column="alias" property="alias"/>
        <result column="avatar" property="avatar"/>
        <result column="summary" property="summary"/>
        <collection property="tags" ofType="com.notepad.blog.domain.BmsTag">
            <result column="tag_id" property="id"/>
            <result column="name" property="name"/>
            <result column="post_count" property="postCount"/>
        </collection>
    </resultMap>

    <select id="selectListAndPage" resultMap="postVo">
        SELECT
        p.id,
        p.title,
        <! -- p.user_id, -->
        p.comments,
        p.VIEW,
        p.collects,
        p.top,
        p.essence,
        p.create_time,
        p.modify_time,
        u.username,
        u.alias,
        u.avatar,
        pt.tag_id,
        t.`name`,
        t.post_count
        FROM
        bms_post p
        LEFT JOIN ums_user u ON p.user_id = u.id
        LEFT JOIN bms_post_tag pt ON p.id = pt.post_id
        LEFT JOIN bms_tag t ON t.id = pt.tag_id
        
        <if test="tab == 'hot'">
            <where>
                date(p.create_time) &lt;= date_add(curdate(), interval 1 day)
                and date(p.create_time) &gt;= date_sub(curdate(), interval 7 day)
            </where>
            order by p.view desc, p.create_time desc
        </if>
        
        <if test="tab == 'atest'">
            order by p.create_time desc
        </if>
        
        <if test="tab == 'update'">
            <where>
                p.modify_time is NOT null
            </where>
            order by p.modify_time desc
        </if>
    </select>

</mapper>
Copy the code

The mapper layer

public interface BmsPostMapper extends BaseMapper<BmsPost> {

    Page<PostVO> selectListAndPage(@Param("page") Page<PostVO> page, @Param("tab") String tab);
}java
Copy the code

controller

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.notepad.blog.common.api.ApiResult;
import com.notepad.blog.domain.vo.PostVO;
import com.notepad.blog.service.BmsPostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/post")
public class BmsPostController {

    @Autowired
    private BmsPostService postService;

    @GetMapping("/list")
    public ApiResult<Page<PostVO>> list(@RequestParam(value = "tab", defaultValue = "latest") String tab,
                                        @RequestParam(value = "pageNo", defaultValue = "1")  Integer pageNo,
                                        @RequestParam(value = "size", defaultValue = "10") Integer pageSize) {
        Page<PostVO> list = postService.getList(pageNo,pageSize, tab);
        returnApiResult.success(list); }}Copy the code

service

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.notepad.blog.domain.BmsPost;
import com.notepad.blog.domain.BmsPostTag;
import com.notepad.blog.domain.BmsTag;
import com.notepad.blog.domain.vo.PostVO;
import com.notepad.blog.mapper.BmsPostMapper;
import com.notepad.blog.mapper.BmsPostTagMapper;
import com.notepad.blog.mapper.BmsTagMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class BmsPostService extends ServiceImpl<BmsPostMapper.BmsPost> {

    @Autowired
    private BmsPostMapper postMapper;

    public Page<PostVO> getList(Integer pageNo, Integer pageSize, String tab) {
        Page<PostVO> page = new Page(pageNo, pageSize);
        // query the article
        Page<PostVO> iPage = postMapper.selectListAndPage(page, tab);
        returniPage; }}Copy the code