springboot+vue制作后台管理系统项目

网友投稿 295 2022-12-17

springboot+vue制作后台管理系统项目

目录一、所使用的环境配置:二、项目简介三、知识点总结(代码和配置)SpringBoot:1.Mybatis-Plus配置文件,实现分页查询:MybatisPlusConfig2.跨域配置文件:CorsConfig3.请求返回类!:Result4.pom.xml配置文件vue:其余知识点总结:总结:

学习笔记

学习资源来自于B站UP,up他讲的非常详细,对于熟悉两大框架很有用。

我的作业源代码在文章末尾,欢迎有需要的同学,学习参考使用,内置SQL文件,导入后,开启springboot和vue服务即可使用,注意更改自己的数据库信息配置,一起学习,一起进步哦!!

一、所使用的环境配置:

编译器:IDEA

后台框架:SpringBoot

Mybatis-Plus

数据库:mysql8.0

数据库工具:Navicat premium

前端框架:Vue

Element UI

引用的富文本编辑器:wangEditor

二、项目简介

这是一个基于SpringBoot和Vue的后台管理系统。

主要功能:

1.实现用户信息的CRUD,以及页面的显示。

2.用户权限的分配,不同权限的用户锁能看到的的界面信息和能进行的操作是不同的。

3.实现图片,文件的上传和下载。

4.实现页面富文本编译器的使用与信息的CRUD。

5.跨域配置,MybatisPlus配置。

6.用户的登录注册,拦截器。

7.查询功能。

。。。。

项目展示:(图片)

1.登录界面

2.注册页面这两个页面可以自由切换

3.root登录后的默认页面以及高亮显示

4.几个页面的展示

5.root账户所能进行的CRUD操作和能查看的用户信息页面

修改

6.个人信息修改,以及退出

7.普通用户登录

这里只做了图书页面的权限限制和用户信息的限制

三、知识点总结(代码和配置)

配置文件:

SpringBoot:

1.Mybatis-Plus配置文件,实现分页查询:MybatisPlusConfig

参考官网:MybatisPlus

package com.wen.common;

import com.baomidou.mybatisplus.annotation.DbType;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;

import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

//Spring boot方式

@Configuration

@MapperScan("com.wen.mapper")//这里所扫描的是项目中mapper文件的位置!

public class MybatisPlusConfig {

// 旧版,官网的旧版视乎无法使用

// 最新版

@Bean

public MybatisPlusInterceptor mybatisPlusInterceptor() {

MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

return interceptor;

}

}

2.跨域配置文件:CorsConfig

package com.wen.common;

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;

@Configuration

public class CorsConfig {

private static final long Max_AGE = 24*60*60;//连接时间

private CorsConfiguration buildConfig(){

CorsConfiguration corsConfiguration = new CorsConfiguration();

//定义所允许的请求头,方法等。*代表所有

corsConfiguration.addAllowedOrigin("*");

corsConfiguration.addAllowedHeader("*");

corsConfiguration.addAllowedMethod("*");

corsConfiguration.setMaxAge(Max_AGE);

return corsConfiguration;

}

@Bean

public CorsFilter corsFilter(){

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("/**",buildConfig());;//允许访问后台的所有接口

return new CorsFilter(source);

}

}

3.请求返回类!:Result

这里算是一个重点,解放了我平时后端coding的思维,非常感谢,没有想到get,set这么方便。

将所有的请求放回统一定义,根据项目所规定的code进行再定义与返回,达到项目通用的效果,非常实用!

package com.wen.common;

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;

@Configuration

public class CorsConfig {

private static final long Max_AGE = 24*60*60;//连接时间

private CorsConfiguration buildConfig(){

CorsConfiguration corsConfiguration = new CorsConfiguration();

//定义所允许的请求头,方法等。*代表所有

corsConfiguration.addAllowedOrigin("*");

corsConfiguration.addAllowedHeader("*");

corsConfiguration.addAllowedMethod("*");

corsConfiguration.setMaxAge(Max_AGE);

return corsConfiguration;

}

@Bean

public CorsFilter corsFilter(){

UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("/**",buildConfig());;//允许访问后台的所有接口

return new CorsFilter(source);

}

}

4.pom.xml配置文件

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.3

com.wen

demo

0.0.1-SNAPSHOT

demo

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-web

mysql

mysql-connector-java

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.2.0

com.baomidou

mybatis-plus-boot-starter

3.4.3.1

cn.hutool

hutool-all

5.7.7

org.springframework.boot

spring-boot-maven-plugin

org.projectlombok

lombok

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.5.3

com.wen

demo

0.0.1-SNAPSHOT

demo

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-web

mysql

mysql-connector-java

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-test

test

org.mybatis.spring.boot

mybatis-spring-boot-starter

2.2.0

com.baomidou

mybatis-plus-boot-starter

3.4.3.1

cn.hutool

hutool-all

5.7.7

org.springframework.boot

spring-boot-maven-plugin

org.projectlombok

lombok

Vue:

1.这里为解决未登录用户页面拦截的问题,在Vue中创建了一工具类/utils/:request.js

import axios from 'axios'

import router from "@/router";

const request = axios.create({

//baseUrl:'/api'

timeout: 5000

})

// request 拦截器

// 可以自请求发送前对请求做一些处理

// 比如统一加token,对请求参数统一加密

request.interceptors.request.use(config => {

config.headers['Content-Type'] = 'application/json;charset=utf-8';

// config.headers['token'] = user.token; // 设置请求头

//取出sessionStorage里面的用户信息

let userJson = sessionStorage.getItem("user");

if (!userJson){

router.push("/login");

}

return config

}, error => {

return Promise.reject(error)

});

// response 拦截器

// 可以在接口响应后统一处理结果

request.interceptors.response.use(

response => {

let res = response.data;

// 如果是返回的文件

if (response.config.responseType === 'blob') {

return res

}

// 兼容服务端返回的字符串数据

if (typeof res === 'string') {

res = res ? JSON.parse(res) : res

}

return res;

},

error => {

console.log('err' + error) // for debug

return Promise.reject(error)

}

)

export default request

2.为解决跨域问题:在vue文件下新建vue.config.js文件

// 跨域配置

module.exports = {

devServer: { //记住,别写错了devServer//设置本地默认端口 选填

port: 9876,//设置的本项目端口

proxy: { //设置代理,必须填

'/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定

target: 'http://localhost:9090/', //代理的目标地址

changeOrigin: true, //是否设置同源,输入是的

pathRewrite: { //路径重写

'/api': '' //选择忽略拦截器里面的单词

}

}

}

}

}

其余知识点总结:

SpringBoot后端文件上传和下载的Controller:FileController

package com.wen.controller;

import cn.hutool.core.io.FileUtil;

import cn.hutool.core.util.IdUtil;

import cn.hutool.core.util.StrUtil;

import cn.hutool.json.JSON;

import cn.hutool.json.JSONArray;

import cn.hutool.json.JSONObject;

import com.wen.common.Result;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.OutputStream;

import java.net.URLEncoder;

import java.util.List;

@RestController

@RequestMapping("/files")

public class FileController {

@Value("${server.port}")

private String port;

private static final String ip = "http://localhost";

/**

* 上传接口

* @param file

* @return

*/

@PostMapping("/upload")

public Result> upload(MultipartFile file){

String originalFilename = file.getOriginalFilename();//获取源文件的名称

// 定义文件的唯一标识(前缀)

String flag = IdUtil.fastSimpleUUID();

String rootFilePath = System.getProperty("user.dir")+"/springboot/src/main/resources/files/"+flag+"_"+originalFilename;//获取文件上传的路径

try {

FileUtil.writeBytes(file.getBytes(),rootFilePath);//把文件写入该路径

} catch (IOException e) {

e.printStackTrace();

}

String url = ip+":"+port+"/files/"+flag;

return Result.success(url);//返回结果url

}

/**

* 下载接口

* @param flag

* @param response

*/

@GetMapping("/{flag}")

public void getFiles(@PathVariable String flag, HttpServletResponse response){

OutputStream os;//新建一个输出对象

String basePath = System.getProperty("user.dir")+"/springboot/src/main/resources/files/";//文件路径

List fileNames = FileUtil.listFileNames((basePath));//获取所有的文件名称

String fileName = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");//找到根参数一致的文件

try {

if (StrUtil.isNotEmpty(fileName)){

response.addHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));

response.setContentType("application/octet-stream");

byte[] bytes = FileUtil.readBytes(basePath + fileName);//通过文件路径读取文字节流

os = response.getOutputStream();//通过输出流返回文件

os.write(bytes);

os.flush();

os.close();

}

}catch (Exception e){

System.out.println("文件下载失败");

}

}

/**

* 富文本上传接口

* @param file

* @return

*/

@PostMapping("editor/upload")

public JSON editorUpload(MultipartFile file){

String originalFilename = file.getOriginalFilename();//获取源文件的名称

// 定义文件的唯一标识(前缀)

String flag = IdUtil.fastSimpleUUID();

String rootFilePath = System.getProperty("user.dir")+"/springboot/src/main/resources/files/"+flag+"_"+originalFilename;//获取文件上传的路径

try {

FileUtil.writeBytes(file.getBytes(),rootFilePath);//把文件写入该路径

} catch (IOException e) {

e.printStackTrace();

}

String url = ip+":"+port+"/files/"+flag;

JSONObject jsonObject = new JSONObject();

jsonObject.set("errno",0);

JSONArray arr = new JSONArray();

JSONObject data = new JSONObject();

arr.add(data);

data.set("url",url);

jsonObject.set("data",arr);

return jsonObject;//返回结果url

}

}

总结:

@Value:获取配置文件中指定的数据(这里的server.port存在于项目文件中application.yaml文件中),存入下方定义的变量中。

MultipartFile:用于接收上传文件的类,推荐文章,其中包含了该类的许多用法,很详细。

IdUtil.fastSimpleUUID():使用的是hutool中的方法,用于生成唯一标识的UUID,加在上传图片的前面,用于唯一区别,避免了相同文件名上传后覆盖的问题。

System.getProperty(“user.dir”):获取当前项目的根目录,在本项目中也就是springboot-vue-demo目录了。

HttpServletResponse:http请求的响应。(学习重点,自己也不是很熟啦,加强学习!)

response.addHeader(“Content-Disposition”,“attachment;filename=”+ URLEncoder.encode(fileName,“UTF-8”));:添加相应头,定义文件下载后的名字。

response.setContentType(“application/octet-stream”);:定义文件下载的格式,二进制流。

关于Mybatis-Plus: 总之就是非常方便,结合lombok进行开发极大的简化了后端的实体定义和数据库相关的操作问题。

SpringBoot中:

SpringBoot通过maven引入MybatisPlus

com.baomidou

mybatis-plus-boot-starter

mybatis-plus-latest-version//这里记得更改成版本号,这样是无法导入的!

配置只需要通过@MapperScan注解即可使用

@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")//这里是项目中mapper存放的文件路径。

需要使用的注解:官网

例如:在实体上使用@TableName(“user”),即是将实体与数据库中相应的表格相对应,@TableId,即是数据库中的主键。

定义接口,即是mapper层或者service层:继承BaseMapper<相应的实体名>即可使用BaseMapper中的方法,包括各种CRUD操作,如果有定义自身的XXmapper.xml文件的话,就会使用xml文件中相应的CRUD方法。官方中的所有接口

public interface BookMapper extends BaseMapper {

}

关于wangEditor:

哈哈哈,解决了重复创建编辑器的问题!

学习时错误如下:

问题描述:由于编辑器的节点只有在弹窗创建之后才能生成,也就是才能获取,在项目中,原本的代码会导致新增和修改弹窗重复创建编辑器。

解决办法:

let editor;

method:{

creatDom(){

editor = new E('#div1');//富文本编辑器创建,获取节点

// 配置 server 接口地址

editor.config.uploadImgServer = 'http://localhost:9090/files/editor/upload';

editor.config.uploadFileName = 'file';//设置文件上传的名字

editor.create();//创建。

},

//这里是新增弹窗

add(){

this.dialogVisible = true;

this.form = {};

//由于只有在弹窗启动之后,div节点才会被创建,那么创建富文本编辑器也只能在其之后。

this.$nextTick(()=>{

if (editor==null){

this.creatDom();

}else {

editor.destroy();//这里做了一次判断,判断编辑器是否被创建,如果创建了就先销毁。

this.creatDom();

}

});

},

//这里是修改弹窗

handleEdit(row){

this.form = JSON.parse((JSON.stringify(row)));

this.dialogVisible = true;

this.$nextTick(()=>{

if (editor==null){

this.creatDom();

editor.txt.html(row.content);

}else {

editor.destroy();//这里做了一次判断,判断编辑器是否被创建,如果创建了就先销毁。

this.creatDom();

editor.txt.html(row.content);

}

});

},

}

后续更新。。。。。。

项目源代码:github仓库

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:手把手教你JAVA进制之间的转换
下一篇:SpringBoot中@Transiactional注解没有效果的解决
相关文章

 发表评论

暂时没有评论,来抢沙发吧~