- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离手把手项目实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
- SpringBoot+Vue豆宝社区前后端分离项目手把手实战系列
豆宝社区项目实战教程简介
本项目实战教程配有免费视频教程,配套代码完全开源。手把手从零开始搭建一个目前应用最广泛的Springboot+Vue前后端分离多用户社区项目。本项目难度适中,为便于大家学习,每一集视频教程对应在Github上的每一次提交。
项目首页截图
image代码开源地址
视频教程地址
前端技术栈
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);
}
}
网友评论