大家好,我是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