豆宝社区项目实战教程简介
本项目实战教程配有免费视频教程,配套代码完全开源。手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目。本项目难度适中,为便于大家学习,每一集视频教程对应在Github上的每一次提交。
项目首页截图
代码开源地址
视频教程地址
前端技术栈
Vue
Vuex
Vue Router
Axios
Bulma
Buefy
Element
Vditor
DarkReader
后端技术栈
Spring Boot
Mysql
Mybatis
MyBatis-Plus
Spring Security
JWT
Lombok
后端实现公告
1.实体类
package com.notepad.blog.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; // @Builder 支持链式操作 @Accessors 支持链式操作 @Data @Builder @Accessors(chain = true) @TableName("bms_billboard") public class BmsBillboard implements Serializable { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(type = IdType.AUTO) private Integer id; /** * 公告牌 */ @TableField("content") private String content; /** * 公告时间 */ @TableField(value = "create_time", fill = FieldFill.INSERT) private Date createTime; /** * 1:展示中,0:过期 */ @Builder.Default @TableField("`show`") private boolean show = false; }
2.mapper层接口搭建
//@Repository 在启动类 @MapperScan("com.notepad.blog.mapper") public interface BmsBillboardMapper extends BaseMapper<BmsBillboard> { }
3.service层搭建
@Service public class BmsBillboardService extends ServiceImpl<BmsBillboardMapper,BmsBillboard> { }
4.controller
@RestController @RequestMapping("/billboard") public class BmsBillboardController { @Autowired private BmsBillboardService bmsBillboardService; @GetMapping("/show") public ApiResult getNotices() { BmsBillboard billboard = bmsBillboardService.getNotices(); return ApiResult.success(billboard); } }
5.service
@Service public class BmsBillboardService extends ServiceImpl<BmsBillboardMapper, BmsBillboard> { @Autowired private BmsBillboardMapper billboardMapper; public BmsBillboard getNotices() { return billboardMapper.getNotices(); } }
6.mapper接口
//@Repository 在启动类 @MapperScan("com.notepad.blog.mapper") public interface BmsBillboardMapper extends BaseMapper<BmsBillboard> { BmsBillboard getNotices(); }
7.在mapper/创建BmsBillboardMapper.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.BmsBillboardMapper"> <select id="getNotices" resultType="com.notepad.blog.domain.BmsBillboard"> SELECT bb.id, bb.content, bb.create_time, bb.SHOW FROM bms_billboard bb WHERE bb.SHOW = 1 ORDER BY rand() LIMIT 1 </select> </mapper>
访问地址测试 :http://localhost:8081/billboard/show
前端实现公告
1.在src下创建/utils/request.js
将下面内容复制即可,简单看看注释
import axios from 'axios' import { Message, MessageBox } from 'element-ui' // 1.创建axios实例 const service = axios.create({ // 公共接口--这里注意后面会讲,url = base url + request url baseURL: process.env.VUE_APP_SERVER_URL, // baseURL: 'https://api.example.com', // 超时时间 单位是ms,这里设置了5s的超时时间 timeout: 5 * 1000 }) // 设置cross跨域 并设置访问权限 允许跨域携带cookie信息,使用JWT可关闭 service.defaults.withCredentials = false service.interceptors.response.use( // 接收到响应数据并成功后的一些共有的处理,关闭loading等 response => { const res = response.data // 如果自定义代码不是200,则将其判断为错误。 if (res.code !== 200) { // 50008: 非法Token; 50012: 异地登录; 50014: Token失效; if (res.code === 401 || res.code === 50012 || res.code === 50014) { // 重新登录 MessageBox.confirm('会话失效,您可以留在当前页面,或重新登录', '权限不足', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', center: true }).then(() => { window.location.href = '#/login' }) } else { // 其他异常直接提示 Message({ showClose: true, message: '⚠' + res.message || 'Error', type: 'error', duration: 3 * 1000 }) } return Promise.reject(new Error(res.message || 'Error')) } else { return res } }, error => { /** *** 接收到异常响应的处理开始 *****/ // console.log('err' + error) // for debug Message({ showClose: true, message: error.message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) export default service
2.在根目录下创建 .env
这里请求的是后端地址,注意是建在根目录下,不是src目录里
VUE_APP_SERVER_URL = 'http://localhost:8081'
3.在src下创建/api/billboard.js
请求地址
import request from '@/utils/request' export function getBillboard() { return request({ url: '/billboard/show', method: 'get' }) }
4.修改src/home.vue
<template> <div> <div class="box"> 🔔 {{ billboard.content }} </div> </div> </template> <script> import { getBillboard } from "@/api/billboard"; export default { name: 'Home', data() { return { billboard: { content: "", }, }; }, created() { this.fetchBillboard(); }, methods: { async fetchBillboard() { getBillboard().then((value) => { const { data } = value; this.billboard = data; }); }, }, }; </script>
5.启动项目
yarn serve
image-20210211185749335
后端跨域
方式一(不推荐):
// controller 上添加 @CrossOrigin
方式二(推荐):
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class GlobalWebMvcConfigurer implements WebMvcConfigurer { /** * 跨域 */ @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); //允许所有域名进行跨域调用 config.addAllowedOrigin("*"); //允许跨越发送cookie config.setAllowCredentials(true); //放行全部原始头信息 config.addAllowedHeader("*"); //允许所有请求方法跨域调用 config.addAllowedMethod("*"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); } }