前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于springboot+vue前后端分离的图书管理系统【2023】

基于springboot+vue前后端分离的图书管理系统【2023】

作者头像
MIKE笔记
发布2023-10-16 20:30:16
1.5K0
发布2023-10-16 20:30:16
举报
文章被收录于专栏:MIKE笔记 技术教程

前言

【课程设计】基于springboot+vue前后端分离的图书管理系统【2023】

🥇个人主页@MIKE笔记 🥈文章专栏毕业设计源码合集联系博主: wx:mikenote


一、毕设目录

🔰导航目录:http://t.csdn.cn/Nfd2q

项目名

地址

1、【毕业设计】基于springboot的大学生综合素质测评管理系统

http://t.csdn.cn/smVjL

2、【毕业设计】基于springboot + vue微信小程序文创平台商城

http://t.csdn.cn/rUQDg

二、系统介绍

图书管理系统是一个基于Web的应用程序,使用SpringBoot和Vue前后端分离的技术实现。该系统允许用户管理图书目录,并进行借阅和归还等操作。以下是该系统的详细介绍:

  1. 后端部分

后端部分使用SpringBoot框架进行开发。SpringBoot是一个流行的Java框架,可用于快速开发基于Spring的Web应用程序。

后端部分主要负责处理业务逻辑和数据持久化。它包括以下几个主要模块:

(1)用户模块:该模块负责处理用户注册、登录和注销等操作。它还包括一个身份验证服务,用于验证用户的身份信息。

(2)图书模块:该模块负责处理图书的增删改查等操作。它还包括一个搜索服务,用于根据关键字搜索图书。

(3)借阅模块:该模块负责处理借阅和归还等操作。它还包括一个借阅历史记录服务,用于记录用户的借阅历史。

  1. 前端部分

前端部分使用Vue框架进行开发。Vue是一个流行的JavaScript框架,可用于快速开发基于Web的SPA(Single Page Application)。

前端部分主要负责与用户进行交互,并提供友好的用户界面。它包括以下几个主要组件:

(1)首页组件:该组件展示图书馆的简介和最新的图书信息。

(2)图书列表组件:该组件展示图书馆的所有图书信息,并允许用户根据关键字搜索图书。

(3)图书详情组件:该组件展示所选图书的详细信息,并允许用户进行借阅和归还等操作。

(4)借阅历史组件:该组件展示用户的借阅历史记录,并允许用户查看和管理自己的借阅情况。

  1. 前后端通信

前后端通信使用基于RESTful API的HTTP协议进行通信。后端提供RESTful API,前端通过HTTP请求调用这些API来与后端进行通信。通信过程中使用JSON格式的数据进行传输。

  1. 数据持久化

后端使用MySQL数据库进行数据持久化。它包括以下几个主要表:

(1)用户表:用于存储用户信息。

(2)图书表:用于存储图书信息。

(3)借阅表:用于存储借阅历史记录。

  1. 安全性和认证

系统采用JWT(JSON Web Token)认证方案进行身份验证。后端提供身份验证服务,用于验证用户的身份信息,并生成JWT令牌。前端在每次请求时携带该令牌,后端验证令牌的有效性,确保只有合法的用户才能访问系统的敏感资源。

创建vue工程

npm config set registry https://registry.npm.taobao.org

安装 vue/cli:https://cli.vuejs.org/zh/guide/installation.html

@vue/cli@5.0.8

使用elementUI

官网:https://element.eleme.cn/

安装 ElementUI

代码语言:javascript
复制
npm i element-ui -S
代码语言:javascript
复制
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';


Vue.use(ElementUI);

完成主页布局

头部

图标网站:https://www.iconfont.cn/

代码语言:javascript
复制
<!-- 头部区域 -->
<div style="height: 60px; line-height: 60px; background-color: white; margin-bottom: 2px">
  <img src="@/assets/logo.png" alt="" style="width: 40px; position: relative; top: 10px; left: 20px">
  <span style="margin-left: 25px; font-size: 24px">图书管理系统</span>
</div>
左侧菜单
代码语言:javascript
复制
<!-- 侧边栏导航 -->
<div style="width: 200px; min-height: calc(100vh - 62px); overflow: hidden; margin-right: 2px; background-color: white">
  <el-menu :default-active="$route.path" :default-openeds="['/']" router class="el-menu-demo">
    <el-menu-item index="/">
      <i class="el-icon-eleme"></i>
      <span>首页</span>
    </el-menu-item>
    <el-submenu index="/">
      <template slot="title">
        <i class="el-icon-question"></i>
        <span>关于页面</span>
      </template>
      <el-menu-item index="about">关于详情</el-menu-item>
    </el-submenu>
  </el-menu>
</div>
右侧主体
代码语言:javascript
复制
  <!-- 主体数据 -->
<div style="flex: 1; background-color: white; padding: 10px">
  <router-view/>
</div>
写个表格试试
代码语言:javascript
复制
<!--    搜索表单-->
<div style="margin-bottom: 20px">
  <el-input style="width: 240px" placeholder="请输入名称"></el-input>
  <el-input style="width: 240px; margin-left: 5px" placeholder="请输入联系方式"></el-input>
  <el-button style="margin-left: 5px" type="primary"><i class="el-icon-search"></i> 搜索</el-button>
</div>

<el-table :data="tableData" stripe>
  <el-table-column prop="name" label="名称"></el-table-column>
  <el-table-column prop="age" label="年龄"></el-table-column>
  <el-table-column prop="address" label="地址"></el-table-column>
  <el-table-column prop="phone" label="联系方式"></el-table-column>
  <el-table-column prop="sex" label="性别"></el-table-column>
</el-table>

<!--    分页-->
<div style="margin-top: 20px">
  <el-pagination
      background
      :page-size="5"
      layout="prev, pager, next"
      :total="100">
  </el-pagination>
</div>



tableData: [
  { name: '王二', age: 20, address: '北京市', phone: '13899008899', sex: '男' },
  { name: '王二', age: 20, address: '北京市', phone: '13899008899', sex: '男' },
  { name: '王二', age: 20, address: '北京市', phone: '13899008899', sex: '女' },
]

搭建后台服务

跨域错误

Access to fetch at ‘http://localhost:9090/user/list’ from origin ‘http://localhost:8080’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

如何解决? @CrossOrigin

百度:SpringBoot如何解决跨域问题 / Vue如何解决跨域问题

Mybatis官网示例

https://mybatis.net.cn/getting-started.html

代码语言:javascript
复制
<?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="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

安装MybatisX插件

错误:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.example.springboot.mapper.UserMapper.listUsers

如何解决?配置 mapper.xml

后台增删改查

pageHelper

代码语言:javascript
复制
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.4.5</version>
</dependency>
axios安装和使用

npm i axios -S

axios封装request.js

代码语言:javascript
复制
import axios from 'axios'

const request = axios.create({
	baseURL: '/api',  // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
    timeout: 5000
})

// request 拦截器
// 可以自请求发送前对请求做一些处理
// 比如统一加token,对请求参数统一加密
request.interceptors.request.use(config => {
    config.headers['Content-Type'] = 'application/json;charset=utf-8';
  
 // config.headers['token'] = user.token;  // 设置请求头
    return config
}, error => {
    return Promise.reject(error)
});

// response 拦截器
// 可以在接口响应后统一处理结果
request.interceptors.response.use(
    response => {
        let res = response.data;
        // 兼容服务端返回的字符串数据
        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

删除sql报错:

java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘where id = 12’ at line

如何解决?检查sql语法

常见的错误:

java.lang.IllegalArgumentException: Source must not be null

为什么会出现这个错误? 因为写代码的时候未考虑异常情况,新手常犯错误!

全局异常处理
代码语言:javascript
复制
import com.example.springboot.common.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@Slf4j
@RestControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler(value = ServiceException.class)
    public Result serviceExceptionError(ServiceException e) {
        log.error("业务异常", e);
        return Result.error(e.getMessage());
    }

    @ExceptionHandler(value = Exception.class)
    public Result exceptionError(Exception e) {
        log.error("系统错误", e);
        return Result.error("系统错误");
    }

}
代码语言:javascript
复制
public class ServiceException extends RuntimeException{

    public ServiceException(String message) {
        super(message);
    }

}

登录和数据安全

js-cookie的使用

代码语言:javascript
复制
npm i js-cookie -S

// 导入使用

import Cookies from 'js-cookie'

Cookies.set('user', obj)  // 默认失效时间为该网站关闭时
Cookies.set('user', obj, { expires: 1 })  // 1天过期

Cookies.get('user')  // 获取cookie数据

Cookies.remove('user')  // 删除cookie数据
代码语言:javascript
复制
-- 清空表数据
TRUNCATE table admin;

Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Data too long for column ‘password’ at row 1 数据字段设置的长度不够

路由守卫

代码语言:javascript
复制
// 404路由:
 {
    path: '*',
        component: () => import('@/views/404.vue'),
}

router.beforeEach((to, from, next) => {
    if (to.path === '/login') next()
    const admin = Cookies.get("admin")
    if (!admin && to.path !== '/login') return next("/login")
    next()
})

错误:Uncaught (in promise) Error: Redirected when going from “/login” to “/home” via a navigation guard. 原因:cookie数据没存,就发生了跳转,我们应该先存数据,再跳转 if (res.data !== null) { Cookies.set(‘admin’, JSON.stringify(res.data)) } this.$router.push(‘/’)

代码语言:javascript
复制
//  设置自定义头配置

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 {


    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
        corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
        corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
        source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
        return new CorsFilter(source);
    }
}

滑块验证

开源插件地址:https://gitee.com/monoplasty/vue-monoplasty-slide-verify

代码语言:javascript
复制
npm i vue-monoplasty-slide-verify -S

import SlideVerify from 'vue-monoplasty-slide-verify';
Vue.use(SlideVerify);
代码语言:javascript
复制
<el-card class="cover" v-if="loginAdmin.id">
      <slide-verify :l="42"
                    :r="10"
                    :w="310"
                    :h="155"
                    slider-text="向右滑动"
                    @success="onSuccess"
                    @fail="onFail"
                    @refresh="onRefresh"
      ></slide-verify>
    </el-card>
    
    
函数:
  onSuccess() {
      Cookies.set('admin', JSON.stringify(this.loginAdmin))
      this.$router.push('/')
      this.$notify.success("登录成功")
    },
    onFail() {
      
    },
    onRefresh() {
      console.log('refresh')
    }
    
.cover {
  width: fit-content;
  background-color: white;
  position: absolute;
  top:50%;
  left:50%;
  transform: translate(-50%, -50%);
  z-index: 1000;
}

三、系统架构

  1. 后端: springbooot
  2. 前端:vue
  3. 数据库:Mysql

四、系统环境

环境

版本 / 下载

系统

win 10 /win 11

JDK

1.8.0_144

Maven

3.6.3

JDK

1.8.0_144

IDEA

2023

Node

14.16.0 +

npm

6.14.11 +

MySQL

5.6.42 / 5.7.x

备注:以上版本为博主电脑配置,可点击进入官网下载

五、数据库表设计

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

六、系统页面展示

1、登陆-注册页面

学生和教师可以通过注册功能创建账户,然后通过登录功能访问系统。登录信息将存储在数据库中,并且登录过程将进行身份验证,以确保只有授权用户才能访问系统。
![在这里插入图片描述](https://img-blog.csdnimg.cn/507624ea13f9417c89fa7d20f0d85c49.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/91b08d8799e14bb5be11411141259793.png)
学生和教师可以通过注册功能创建账户,然后通过登录功能访问系统。登录信息将存储在数据库中,并且登录过程将进行身份验证,以确保只有授权用户才能访问系统。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/507624ea13f9417c89fa7d20f0d85c49.png) ![在这里插入图片描述](https://img-blog.csdnimg.cn/91b08d8799e14bb5be11411141259793.png)
在这里插入图片描述
在这里插入图片描述

2、系统界面

管理员界面

(1)主页

在这里插入图片描述
在这里插入图片描述

(2)会员管理

在这里插入图片描述
在这里插入图片描述

(3)会员列表

在这里插入图片描述
在这里插入图片描述

(4)管理员管理

在这里插入图片描述
在这里插入图片描述

(5)图书管理

在这里插入图片描述
在这里插入图片描述
教师界面
在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、毕设目录
  • 二、系统介绍
    • 创建vue工程
      • 使用elementUI
        • 完成主页布局
          • 头部
          • 左侧菜单
          • 右侧主体
          • 写个表格试试
        • 搭建后台服务
          • 跨域错误
          • Mybatis官网示例
        • 后台增删改查
          • axios安装和使用
          • 全局异常处理
        • 登录和数据安全
          • 路由守卫
            • 滑块验证
            • 三、系统架构
            • 四、系统环境
            • 五、数据库表设计
            • 六、系统页面展示
              • 1、登陆-注册页面
                • 2、系统界面
                  • 管理员界面
                  • 教师界面
              相关产品与服务
              云数据库 MySQL
              腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档