免费分享一套SpringBoot+Vue图书(图书借阅)管理系统【论文+源码+SQL脚本】,帅呆了~~

news2024/9/27 17:27:30

大家好,我是java1234_小锋老师,看到一个不错的SpringBoot+Vue图书(图书借阅)管理系统,分享下哈。

项目视频演示

【免费】SpringBoot+Vue图书(图书借阅)管理系统 Java毕业设计_哔哩哔哩_bilibili

项目介绍

本论文阐述了一套先进的图书管理系统的设计与实现,该系统采用Java语言,结合现代Web开发框架和技术,旨在为图书馆提供高效、灵活且用户友好的资源管理解决方案。系统利用Spring Boot框架为核心,整合MyBatis ORM工具,以及MySQL数据库,构建了一个高性能、可扩展的后端服务。前端界面则采用了Vue.js框架,以提供流畅的用户交互体验。

论文首先进行了详尽的需求分析,确定了系统的核心功能,包括图书的添加、编辑、删除、查询,读者的注册、登录、个人信息管理,以及图书的借阅、归还、续借流程。为了确保数据安全与隐私保护,系统引入了JWT(JSON Web Tokens)身份验证方案。

系统设计遵循MVC(Model-View-Controller)架构原则,保证了代码的清晰与可维护性。同时,采用了RESTful API设计风格,支持跨平台访问,使系统能够适应不同类型的客户端设备。为了优化用户体验,系统还集成了全文搜索功能,允许用户通过关键词快速定位所需图书。

通过一系列的测试与评估,包括压力测试、功能测试和用户满意度调查,系统表现出了卓越的稳定性和响应速度。实验结果证明,新系统极大地提升了图书馆工作人员的工作效率,同时也显著增强了读者的满意度和图书馆资源的利用率。

未来工作将着眼于系统功能的持续扩展,例如电子图书集成、多语言支持、以及与社交媒体平台的互动,以进一步提升图书馆服务的现代化水平。

系统展示

部分代码

package com.rabbiter.bms.web;

import com.rabbiter.bms.model.User;
import com.rabbiter.bms.service.UserService;
import com.rabbiter.bms.utils.MyResult;
import com.rabbiter.bms.utils.MyUtils;
import com.rabbiter.bms.utils.TokenProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    UserService userService;

    // 登录
    @RequestMapping(value = "/login")
    public Map<String, Object> login(@RequestBody User user) {
        // 登录
        User userObj = userService.login(user);
        if(userObj == null) {   // 账号或密码错误
            // 返回结果对象
            return MyResult.getResultMap(420, "账号或密码错误");
        } else {    // 账号密码正确
            // 创建token
            String token = TokenProcessor.getInstance().makeToken();
            // 保存到Redis
            userService.saveUser(token, userObj);
            // 返回结果对象
            return MyResult.getResultMap(200, "登录成功",
                    new HashMap<String, String>(){{ put("token", token); }});
        }
    }

    // 查看用户信息
    @RequestMapping(value = "/info")
    public Map<String, Object> info(String token) {
        // 从redis中取用户
        User user = userService.getUser(token);
        if(user == null) {  // 获取失败
            return MyResult.getResultMap(420, "获取用户信息失败");
        } else {    // 获取成功
            return MyResult.getResultMap(200, "获取用户信息成功", user);
        }
    }

    // 退出登录
    @RequestMapping(value = "/logout")
    public Map<String, Object> logout(String token) {
        // 从redis中移除用户
        userService.removeUser(token);
        return MyResult.getResultMap(200, "退出登录成功" );
    }

    // 注册
    @RequestMapping(value = "/register")
    public Integer register(String username, String password){
        return userService.register(username, password);
    }

    // 修改密码
    @RequestMapping(value = {"/alterPassword", "reader/alterPassword"})
    public Integer alterPassword(Integer userid, String username, Byte isadmin, String oldPassword, String newPassword){
        //检查旧密码是否正确
        User userObj = new User();
        userObj.setUserid(userid);
        userObj.setUsername(username);
        userObj.setUserpassword(oldPassword);
        userObj.setIsadmin(isadmin);

        User user = userService.login(userObj);
        if(user == null) {  //旧密码不正确
            return 0;
        } else {    //旧密码正确,设置新密码
            userService.setPassword(userObj.getUserid(), newPassword);
            return 1;
        }
    }

    // 获得数量
    @GetMapping(value = "/getCount")
    public Integer getCount(){
        return userService.getCount();
    }

    // 查询所有用户
    @GetMapping(value = "/queryUsers")
    public List<User> queryUsers(){
        return userService.queryUsers();
    }

    // 分页查询用户 params: {page, limit, username}
    @GetMapping(value = "/queryUsersByPage")
    public Map<String, Object> queryUsersByPage(@RequestParam Map<String, Object> params){
        MyUtils.parsePageParams(params);
        int count = userService.getSearchCount(params);
        List<User> users = userService.searchUsersByPage(params);
        return MyResult.getListResultMap(0, "success", count, users);
    }

    // 添加用户
    @PostMapping(value = "/addUser")
    public Integer addUser(@RequestBody User user){
        return userService.addUser(user);
    }

    // 删除用户
    @DeleteMapping(value = "/deleteUser")
    public Integer deleteUser(@RequestBody User user){
        return userService.deleteUser(user);
    }

    // 删除一些用户
    @DeleteMapping(value = "/deleteUsers")
    public Integer deleteUsers(@RequestBody List<User> users){
        return userService.deleteUsers(users);
    }

    // 更新用户
    @RequestMapping(value = "/updateUser")
    public Integer updateUser(@RequestBody User user){
        return userService.updateUser(user);
    }
}
<template>
  <div class="login-container">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
      <!-- 标题 -->
      <div class="title-container">
        <h3 class="title">登录图书管理系统</h3>
      </div>
      <!-- 用户名 -->
      <el-form-item prop="username">
        <span class="svg-container">
          <i class="el-icon-a-052"></i>
        </span>
        <el-input
          class="yuan"
          ref="username"
          v-model="loginForm.username"
          placeholder="请输入用户名"
          name="username"
          type="text"
          tabindex="1"
          auto-complete="on"
        />
      </el-form-item>
      <!-- 密码 -->
      <el-form-item prop="password">
        <span class="svg-container">
          <i class="el-icon-a-051"></i>
        </span>
        <el-input
          class="yuan"
          :key="passwordType"
          ref="password"
          v-model="loginForm.password"
          :type="passwordType"
          placeholder="请输入密码"
          name="password"
          tabindex="2"
          auto-complete="on"
          @keyup.enter.native="handleLogin"
        />
        <span class="show-pwd" @click="showPwd">
          <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
        </span>
      </el-form-item>
      <!-- 权限 -->
      <el-form-item prop="authority">
        <span class="svg-container">
          <i class="el-icon-a-062"></i>
        </span>
        <el-select v-model="loginForm.isadmin" placeholder="请选择" style="width: 418px">
          <el-option :key="0" label="读者" :value="0"></el-option>
          <el-option :key="1" label="管理员" :value="1"></el-option>
        </el-select>
      </el-form-item>

      <!-- 登录按钮 -->
      <div style="height: 40px; margin-bottom: 30px;">
        <el-button :loading="loading" type="primary" style="width: 48%; float: left;" @click.native.prevent="handleLogin">登录</el-button>
        <el-button :loading="loading" type="success" style="width: 48%; float: right;" @click.native.prevent="handleRegister">注册</el-button>
      </div>
      <div style="text-align: center">

      </div>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'Login',
  data() {
    const validateUsername = (rule, value, callback) => {
      callback()
    }
    const validatePassword = (rule, value, callback) => {
      callback()
    }
    return {
      loginForm: {
        username: '',
        password: '',
        isadmin: 0
      },
      loginRules: {
        username: [{ required: true, trigger: 'blur', validator: validateUsername }],
        password: [{ required: true, trigger: 'blur', validator: validatePassword }]
      },
      loading: false,
      passwordType: 'password',
      redirect: undefined
    }
  },
  methods: {
    showPwd() {
      if (this.passwordType === 'password') {
        this.passwordType = ''
      } else {
        this.passwordType = 'password'
      }
      this.$nextTick(() => {
        this.$refs.password.focus()
      })
    },
    handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          this.$store.dispatch('user/login', this.loginForm).then(() => {
            this.$router.push({ path: '/' })  // 无脑进首页
            this.loading = false
          }).catch((message) => {
            this.$message.error(message)
            this.loading = false
          })
        } else {
          console.log('不允许提交!')
          return false
        }
      })
    },
    handleRegister() {
      console.log("注册按钮")
      this.$router.push({ path: '/register' })  // 进注册页面
    }
  }
}
</script>

<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */

$bg:#283443;
$light_gray:#fff;
$cursor: #fff;

@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
  .login-container .el-input input {
    color: $cursor;
  }
}

/* reset element-ui css */
.login-container {
  .el-input.yuan {
    display: inline-block;
    height: 47px;
    width: 85%;

    input {
      background: transparent;
      border: 0px;
      -webkit-appearance: none;
      border-radius: 0px;
      padding: 12px 5px 12px 15px;
      color: $light_gray;
      height: 47px;
      caret-color: $cursor;

      &:-webkit-autofill {
        box-shadow: 0 0 0px 1000px $bg inset !important;
        -webkit-text-fill-color: $cursor !important;
      }
    }
  }

  .el-input {
    display: inline-block;
    height: 47px;
    width: 100%;

    input {
      background: transparent;
      border: 0px;
      -webkit-appearance: none;
      border-radius: 0px;
      padding: 12px 5px 12px 15px;
      color: $light_gray;
      height: 47px;
      caret-color: $cursor;

      &:-webkit-autofill {
        box-shadow: 0 0 0px 1000px $bg inset !important;
        -webkit-text-fill-color: $cursor !important;
      }
    }
  }

  .el-form-item {
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(0, 0, 0, 0.1);
    border-radius: 5px;
    color: #454545;
  }
}
</style>

<style lang="scss" scoped>
$bg:#2d3a4b;
$dark_gray:#889aa4;
$light_gray:#eee;

.login-container {
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;

  .login-form {
    position: relative;
    width: 520px;
    max-width: 100%;
    padding: 160px 35px 0;
    margin: 0 auto;
    overflow: hidden;
  }

  .tips {
    font-size: 14px;
    color: #fff;
    margin-bottom: 10px;

    span {
      &:first-of-type {
        margin-right: 16px;
      }
    }
  }

  .svg-container {
    padding: 6px 5px 6px 15px;
    color: $dark_gray;
    vertical-align: middle;
    width: 30px;
    display: inline-block;

    font-size: 20px;
  }

  .title-container {
    position: relative;

    .title {
      font-size: 26px;
      color: $light_gray;
      margin: 0px auto 40px auto;
      text-align: center;
      font-weight: bold;
    }
  }

  .show-pwd {
    position: absolute;
    right: 10px;
    top: 7px;
    font-size: 16px;
    color: $dark_gray;
    cursor: pointer;
    user-select: none;
  }

}
</style>

源码下载

下载地址:
链接:https://pan.baidu.com/s/1FsxNxrVAn-TDQB3Jaf96Aw 
提取码:1234

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1981031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享一个基于Node.js和Vue的游戏点单陪玩系统(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

MQ面试篇

目录 传送门前言一、MQ优缺点二、MQ消息重复问题处理&#xff08;精品&#xff09;三、保证MQ消息不丢失四 、MQ百万消息持续积压问题五、如果保证MQ的高可用 传送门 SpringMVC的源码解析&#xff08;精品&#xff09; Spring6的源码解析&#xff08;精品&#xff09; SpringB…

山东青岛高校大学智能制造实验室数字孪生可视化系统平台建设项目验收

青岛高校大学智能制造实验室作为高校科研和人才培养的重要基地&#xff0c;一直致力于推动智能制造技术的研发和应用。为了提升实验室在智能制造领域的教学、科研和产业合作能力&#xff0c;实验室决定建设数字孪生可视化系统平台。 智能制造数字孪生项目旨在通过搭建一个全面…

C语言实现希尔排序和堆排序

目录 1.希尔排序 1.1基本思想 1.2希尔排序的特性总结 1.3希尔排序算法的实现 2.堆排序 2.1基本思想 2.2堆排序的特性总结 2.3堆排序算法的实现 1.希尔排序 1.1基本思想 希尔排序法的基本思想是&#xff1a;先选定一个整数(gap)&#xff0c;把待排序文件中所有记录分成…

自定义微信小程序源码系统 带网站的源代码包以及搭建部署教程

系统概述 自定义微信小程序源码系统是一套完整的解决方案&#xff0c;包含了微信小程序的源代码以及配套的网站源代码包。它为开发者提供了一个可定制、可扩展的开发平台&#xff0c;让开发者能够根据自己的需求和创意&#xff0c;快速构建出具有独特风格和功能的微信小程序。…

微力同步如何安装使用并使用内网穿透配置公网地址远程访问

文章目录 1.前言2. 微力同步网站搭建2.1 微力同步下载和安装2.2 微力同步网页测试2.3 内网穿透工具安装 3.本地网页发布3.1 Cpolar云端设置3.2 Cpolar本地设置 4. 公网访问测试5. 结语 1.前言 私有云盘作为云存储概念的延伸&#xff0c;虽然谈不上多么新颖&#xff0c;但是其广…

CodeWave简介

CodeWave是网易自主研发的领先低代码平台&#xff0c;可快速搭建公司官网、项目管理、OA等各种企业信息化系统&#xff0c;助力企业数字化提质增效。产品特点&#xff1a;低门槛&#xff08;降低软件开发门槛&#xff0c;赋能非专业技术人员专职从事软件开发工作&#xff09;、…

要想赚钱,AI模型该大该小?贾扬清:论AI模型经济学的技巧

卖模型就像感恩节卖火鸡&#xff0c;快才能赚钱。 最近的AI社区&#xff0c;关于模型规模的讨论有些活跃。 一方面&#xff0c;此前在大模型开发奉为“圣经”的Scaling Law&#xff0c;似乎正在褪去光环。去年大家还在猜测GPT-5的规模“可能会大到想不到”&#xff0c;现在这…

2024华数杯C题解题思路及详细建模步骤分享+双语言代码

2024“华数杯”数模竞赛已经开赛啦&#xff0c;这次给大家带来的是今年华数杯C题解题思路&#xff0c;内容由我们团队的众多国奖学长学姐给大家出具高质量的解题思路&#xff0c;参考代码等&#xff0c;希望能助大家一臂之力。 问题1: 请问352 个城市中所有35200 个景点评分的最…

【Nuxt】约定式路由和 NuxtLink

约定式路由 手动创建&#xff1a; 或者还可以使用终端创建页面&#xff1a;nuxi-add-page npx nuxi add page about — about.vue npx nuxi add page about/index — about/index.vue <NuxtLink to"/"><button>Home</button></NuxtLink><…

25集 ESP32 C3 AI chat聊天工程代码流程-《MCU嵌入式AI开发笔记》

25集 ESP32 C3 AI chat聊天工程代码流程-《MCU嵌入式AI开发笔记》 我们打开Ai chat工程&#xff0c;用vscode。 main.c里面&#xff0c;重点看一下app_main函数。 Created with Raphal 2.3.0 开始 nvs_flash_init audio_hal_ctrl_codec audio init display init &#xff08…

AUTOSAR之AUTOSAR OS(下)

前言&#xff1a;在上篇中&#xff0c;我们主要描述了OSEK OS的相关内容以及AUTOSAR OS的OS Application对象的一些内容&#xff0c;包括Counter&#xff0c;Alarm&#xff0c;Enent&#xff0c;ISR&#xff0c;Task&#xff0c;Schudule Table等&#xff0c;本篇文章中&#x…

element-plus 菜单组件 index属性如何正确赋值?

element-plus 菜单组件 index属性如果直接填写字符串&#xff0c;就会报如下的错误 正确写法与错误写法 报错解释&#xff1a;Error parsing JavaScript expression: Unterminated regular expression. (1:2) 这个错误表明你在解析一个JavaScript表达式时遇到了一个未正确结束…

【人工智能专栏】 PCA Decomposition

PCA Decomposition 算法 去除平均值 。计算协方差矩阵 。计算协方差矩阵的特征值和特征向量 。将特征值排序 保留前N个最大的特征值对应的特征向量 。将原始特征转换到上面得到的N个特征向量构建的新空间中(最后两步,实现了特征压缩)。解释 为什么样本在“协方差矩阵C的最大…

元太电磁膜SUDE-10S19MI-01X驱动适配

屏规格书&#xff1a; dts配置&#xff1a; 首先要确保CONFIG_I2C_HID宏打开&#xff0c;i2c-hid-core.c 文件才能编译进去代码。规格书vendor product 分别为0x2d1f 和0x0165 来区别&#xff0c;不至于影响到整体的hid其他设备。 i2c-hid-dev10 { compatible "hid-…

WordPress主题 CeoMax-Pro_v7.6总裁主题资源下载类主题

CeoNova-Pro 主题是一款轻量级、且简洁大气、产品官网类主题&#xff0c;定位于高端产品官网、同时包含了知识付费、定制服务、问答社区、论坛交流、网址导航、以及付费产品购买下载等全方位覆盖。

数据库扩展新篇章:主流分库分表中间件全解析

摘要&#xff1a; 随着企业数据量的激增&#xff0c;传统的单体数据库架构已经无法满足日益增长的性能需求和数据管理复杂性。分库分表技术作为解决这一问题的有效手段&#xff0c;通过将数据水平或垂直地分散到多个数据库中&#xff0c;提高了系统的扩展性和处理能力。本文将详…

JAVA答题系统练习模拟考试平台支持H 5小程序APP公众号源码

&#x1f4dd;“答题系统练习模拟考试平台”——你的备考神器来啦&#xff01;&#x1f393; &#x1f4da;【精准题库&#xff0c;覆盖全面知识点】 备考路上&#xff0c;最怕的就是题目不够全、不够新&#xff01;“答题系统练习模拟考试平台”汇聚了海量精编题库&#xff…

【枚举】:复合态的处理( Flag = Flag1 | Flag2 )

一、引言 枚举 enum是我们用的比较多的类型&#xff0c;而枚举通常适用的场景&#xff0c;也是为了我们在业务逻辑处理时&#xff0c;作为不同的逻辑分支的判断条件&#xff1b;比起直接定义1~N这样魔幻到让人一头雾水的分支 Flag , 定义完美的枚举类型可以见名知意&#xff0…

六西格玛培训应该采用什么方式?

六西格玛&#xff0c;作为一套被全球顶尖企业广泛采用的管理哲学和方法论&#xff0c;无疑是帮助企业实现这一目标的强有力工具。那么&#xff0c;如何有效开展六西格玛培训&#xff0c;让这一理念深入人心&#xff0c;成为每位员工日常工作中的自觉行动呢&#xff1f;深圳天行…