# 前言
在此次教程中,我会教大家如何写一套前后端分离图书管理系统:
前端技术栈:
HTML5+CSS3+JavaScript
后端技术栈:
Java+SpringBoot+MySQL
适合人群:未来做前端或后端或全栈有兴趣的技术人员
系统环境:
操作系统:Windows 10
前端工具:Visual Studio Code
后端工具:IDEA
数据库:MySQL 5.7.26
环境搭建:PHPStudy
本项目采用 MVC 模式书写
注意!!!本章节含有大量 CV 代码,慎重!!!只是简单的一些对数据库的处理操作,看看就行
# 已知 BUG
1. 使用 MySQL 8 + 此项目在此项目有bug | |
BUG 产生原因 | |
因为在 MySQL 8 中, 已将 groups 添加为关键字,所以导致查询,插入,修改图书表字段 groups 时会发生报错 | |
修改 BUG 方式 | |
将图书表的 groups 字段修改为 bookgroups 字段 | |
前端图书管理页面,把 input 输入框为 groups 的输入框改为 bookgroups | |
后端 Book 实体类 groups 改为 bookgroups |
# 什么是 MVC 模式?

引用 runoob 对 MVC 的介绍 源地址
# 零、项目图片
# 登录页面

# 图书管理页面

# 借阅图书页面

# 归还图书页面

# 超时查询页面

# 用户管理页面

# 一、项目结构



# 二、从 0 到 1 (0 -> 1)
# 首先是
选择一个合适的硬盘创建自己的项目文件夹,在项目文件夹里创建 HTML5 和 SpringBoot 文件夹

HTML5 文件夹用于存放前端显示页面
SpringBoot 文件夹用于存放后端服务器代码
以上两个文件夹也可以按照自己喜欢的名字来进行创建,本篇教程之后会以这两个文件夹创建文件,请注意自己的文件存放位置
# 数据库设置
首先创建 library 数据库
create database library default character set utf8 collate utf8_general_ci; |
然后进入 library 数据库里
use library; |
创建图书表
CREATE TABLE `books` ( | |
`Id` int(11) NOT NULL AUTO_INCREMENT, | |
`groups` varchar(255) NOT NULL DEFAULT '', | |
`name` varchar(255) NOT NULL DEFAULT '', | |
`author` varchar(255) NOT NULL DEFAULT '', | |
`press` varchar(255) NOT NULL DEFAULT '', | |
`price` double(10,2) NOT NULL DEFAULT '0.00', | |
`quantity` int(5) NOT NULL DEFAULT '0', | |
`ISBN` varchar(13) NOT NULL DEFAULT '', | |
PRIMARY KEY (`Id`) | |
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8; |
在图书表里添加书本
INSERT INTO `books` VALUES (1,'地理','房龙地理','房龙','文汇出版社',29.01,10,'9780000000001'),(2,'地理','地理学与生活','[美] 阿瑟·格蒂斯 ','世界图书出版公司',49.00,10,'9780000000002'),(3,'地理','古老阳光的末日','Thom Hartmann','上海远东出版社',20.00,10,'9780000000003'),(4,'法律','洞穴奇案','[美] 萨伯','生活.读书.新知三联书店',18.00,10,'9780000000004'),(5,'法律','西窗法雨','刘星','法律出版社',24.00,10,'9780000000005'),(6,'法律','审判为什么不公正','[英] 卡德里','新星出版社',49.50,10,'9780000000006'),(7,'军事','亮剑(舒适阅读版)','都梁','北京联合出版公司',45.00,10,'9780000000007'),(8,'军事','二战记忆 安妮日记','[德] 安妮·弗兰克','人民文学出版社',23.00,10,'9780000000008'),(9,'军事','亮剑','都梁','解放军文艺出版社',25.00,10,'9780000000009'),(10,'历史','历史是什么?','爱德华·霍列特·卡尔','商务印书馆',19.00,10,'9780000000010'),(11,'历史','中国史学史','金毓黻','商务印书馆',19.00,10,'9780000000011'),(12,'历史','史记选','[清] 储欣','商务印书馆',48.00,10,'9780000000012'),(13,'计算机','Java从入门到精通 ','明日科技','清华大学出版社',69.00,10,'9780000000013'),(14,'计算机','C++从入门到精通','李伟明','清华大学出版社',49.00,10,'9780000000014'),(15,'计算机','PHP从入门到精通','千锋教育高教产品研发部','清华大学出版社',59.00,10,'9780000000015'); |
创建用户表
CREATE TABLE `users` ( | |
`Id` int(11) NOT NULL AUTO_INCREMENT, | |
`groups` varchar(255) NOT NULL DEFAULT 'user', | |
`username` varchar(255) NOT NULL DEFAULT '', | |
`password` varchar(255) NOT NULL DEFAULT '', | |
`gender` varchar(255) NOT NULL DEFAULT '', | |
`id_card` int(8) NOT NULL DEFAULT '0', | |
`phone` varchar(11) NOT NULL DEFAULT '0', | |
`identity` varchar(255) NOT NULL DEFAULT '学生', | |
PRIMARY KEY (`Id`) | |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
插入一条管理员用户数据
INSERT INTO `users` VALUES (1,'admin','Admin','123456','男',0,0,'管理员'); |
Admin 是用户名
123456 是密码
可以自行修改用户名或密码,之后执行登录操作时需要用到
创建借书表
CREATE TABLE `borrow` ( | |
`Id` int(11) NOT NULL AUTO_INCREMENT, | |
`name` varchar(255) NOT NULL DEFAULT '', | |
`ISBN` varchar(13) NOT NULL DEFAULT '', | |
`username` varchar(255) NOT NULL DEFAULT '', | |
`id_card` varchar(8) NOT NULL DEFAULT '', | |
`phone` varchar(11) NOT NULL DEFAULT '', | |
`time` date NOT NULL DEFAULT '1970-01-01', | |
`r_time` date NOT NULL DEFAULT '1970-01-01', | |
PRIMARY KEY (`Id`) | |
) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
存放借阅的图书信息
or
你可以选择下载此文件来自动导入到数据库中
网盘链接
提取码: 6666
# 创建 SpringBoot 项目
新建一个项目

选择 Spring Initializr 项目

设置以下信息

Group:组名
一般格式为 com. 公司名。项目名。模块名 没有公司名就用自己的名字
Artifact:工程名
Type:项目类型
Language:使用语言
Packaging:包装类型
Java Version:JDK 版本
Version:项目版本
Name:项目名
Description:项目描述
Package:包
选择 Spring 要添加的组件
Lombok

Spring Web

Spring Data JPA 和 MySQL Driver

选择刚才创建的 SpringBoot 文件夹

在 pom.xml 文件下添加 JSONObject 依赖
<!-- JSONObject--> | |
<dependency> | |
<groupId>com.alibaba</groupId> | |
<artifactId>fastjson</artifactId> | |
<version>1.2.28</version> | |
</dependency> | |
<!-- JSONObject 依赖 --> | |
<dependency> | |
<groupId>commons-beanutils</groupId> | |
<artifactId>commons-beanutils</artifactId> | |
<version>1.9.3</version> | |
</dependency> |

构建过程中最好使用代理构建项目
如果您的项目构建失败,您可以通过下面的链接下载我已经构建好的项目来开发
项目链接
提取码: 77tr
# 配置数据库连接文件
先删除 src 下的 application.properties 文件

在这里我用 yml 格式连接数据库
在 resources 文件夹新建一个 application.yml 文件
在文件里写入以下代码
spring: | |
datasource: | |
url: jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai | |
username: root #用户名 | |
password: 123456 #密码 | |
driver-class-name: com.mysql.cj.jdbc.Driver | |
jpa: | |
show-sql: true | |
properties: | |
hibernate: | |
format_sql: true | |
server: | |
port: 8181 #服务器端口 |
以上就创建完了 SpringBoot 项目
# 三、登录页面
# 前端
创建完成后,就可以开始写第一个页面
在 HTML5 文件夹创建 index.html 文件
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
</head> | |
<body> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
</html> |
分别在 css 文件夹和 js 文件夹创建 index.css 和 index.js
然后在 index.html 文件里引用这两个文件
<link rel="stylesheet" href="library/css/index.css"> | |
<script src="library/js/index.js"> |
接下来创建一个登录面板
<div class="login-pane"> | |
<form method="post" class="login-form"> | |
<h3>图书管理系统</h3> | |
<input type="text" name="username" id="username" class="username-text" placeholder="用户名"> | |
<input type="password" name="password" id="password" class="password-text" placeholder="密码"> | |
<input type="submit" value="登录" class="login-button btn btn-primary" id="login-button"> | |
</form> | |
</div> |
在 index.css 写样式代码 美化登录面板
*{ | |
margin:0; | |
padding: 0; | |
outline: none; | |
} | |
html,body{ | |
width: 100%; | |
height: 100%; | |
} | |
body{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
background-color: rgb(249,249,249); | |
} | |
.login-pane{ | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
width: 375px; | |
height: 500px; | |
background-color: #fff; | |
border-radius: 4px; | |
box-shadow: 1px 1px 10px #b8b8b8; | |
} | |
.login-pane .login-form h3{ | |
text-align: center; | |
margin-bottom: 50px; | |
} | |
.login-pane .login-form input{ | |
display: block; | |
text-align: center; | |
width: 250px; | |
padding-top: 4px; | |
padding-bottom: 4px; | |
margin-bottom: 16px; | |
border: 1px solid gainsboro; | |
border-radius: 4px; | |
} | |
.login-pane .login-form .login-button{ | |
padding-top: 4px; | |
padding-bottom: 4px; | |
width: 250px; | |
} |
给登录面板绑定事件
在 index.js 写入
$(function(){ | |
// 判断用户是否登录过 | |
var is_login = $.cookie("username"); | |
if(is_login != null && is_login != "" && is_login != ''){ | |
window.location.replace("/library/library.html"); | |
} | |
// 获取表单组件 | |
var username = $('.username-text'); | |
var password = $('.password-text'); | |
var login_button = $('.login-button'); | |
// 登录按钮点击事件 | |
login_button.click(function (e) { | |
e.preventDefault(); | |
// 判断输入框 | |
if(username.val() == ""){ | |
alert("请输入用户名"); | |
} | |
else if(password.val() == ""){ | |
alert("请输入密码"); | |
} | |
else{ | |
// 事件执行 | |
$.ajax({ | |
type: "post", | |
url: "http://这里填你电脑的本地IP:这里填你SpringBoot服务端的端口/nav/login", | |
data: {"username":username.val(),"password":password.val()}, | |
dataType: "json", | |
success:function(data){ | |
// 如果后端返回的 code 值为 1 则登录成功 | |
if(data.code == "1"){ | |
alert("登录成功"); | |
$.cookie("username",data.username); | |
window.location.replace("/library/library.html"); | |
} | |
// 如果后端返回的 code 值为 0 则登录失败 | |
if(data.code == "0"){ | |
alert("账号或密码错误"); | |
} | |
}, | |
error:function(data){ | |
// 如果前端与后端交互出问题则报错 | |
alert("系统错误"); | |
} | |
}); | |
} | |
}); | |
}); |
# 后端
现在,登录页面就已经制作完成,现在开始制作后端登录模型
在 SpringBoot 项目中创建以下包与文件

包:
config ------------ 配置类
controller --------- 控制类
entity -------------- 实体类
repository -------- 储存类
类:
CrosConfig ------------ 解决跨域问题
UsersHandler ---------- 用户操作
Users --------------------- 用户实体
UsersRepository ------- 用户存储库
注意!这里的 Users 最好是对应上数据库的 users 表名,不然对数据库的操作会报错
在 CrosConfig 下写入
package com.ksamar.library.config; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.web.servlet.config.annotation.CorsRegistry; | |
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |
@Configuration | |
public class CrosConfig implements WebMvcConfigurer { | |
@Override | |
public void addCorsMappings(CorsRegistry registry) { | |
registry.addMapping("/**") // 映射 | |
.allowedOriginPatterns("*") // 允许的模式 | |
.allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS") // 允许的请求 | |
.allowCredentials(true) // 允许凭据 | |
.maxAge(3600) // 最大请求 | |
.allowedHeaders("*"); // 允许的标头 | |
} | |
} |
在 UsersHandler 写入
package com.ksamar.library.controller; | |
import com.alibaba.fastjson.JSONObject; | |
import com.ksamar.library.entity.Users; | |
import com.ksamar.library.repository.UsersRepository; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.data.domain.Example; | |
import org.springframework.web.bind.annotation.*; | |
import java.util.Optional; | |
@RestController | |
@RequestMapping("/nav") // 这里是请求地址如 果要用这个类的方法就需要使用 http://ip/nav 请求地址 | |
public class UsersHandler { | |
@Autowired | |
private UsersRepository usersRepository; // 用户存储库 用来装用户的数据 | |
// 用户登录 | |
@PostMapping("/login") // 这里是登录的请求地址和上面一样在 /nav 后面加上 /login 就能请求了 | |
public Object findOne(Users users){ | |
Example<Users> userExample = Example.of(users) ; // 封装表单传过来的数据 | |
Optional<Users> userOptional = usersRepository.findOne(userExample); // 与数据库交互 去寻找表单所提交的用户存不存在 | |
JSONObject jsonObject = new JSONObject(); // 创建一个空 JSONObject 对象 | |
//0 代表登录失败 1 代表登录成功 | |
// 判断这个用户是否存在 | |
if (userOptional.isPresent()){ | |
Users userTemp = userOptional.get(); // 获取用户数据 | |
// 判断这个用户是不是管理组的 | |
if(userTemp.getGroups().equals("admin")){ | |
// 判断用户提交的用户名和数据库的是否一致 | |
if(users.getUsername().equals(userTemp.getUsername())){ | |
// 判断用户提交的密码和数据库的是否一致 | |
if(users.getPassword().equals(userTemp.getPassword())){ | |
jsonObject.put("code","1"); | |
jsonObject.put("username",userTemp.getUsername()); | |
} | |
else{ | |
jsonObject.put("code","0"); | |
} | |
} | |
else{ | |
jsonObject.put("code","0"); | |
} | |
} | |
else{ | |
jsonObject.put("code","0"); | |
} | |
} | |
else{ | |
jsonObject.put("code","0"); | |
} | |
return jsonObject; | |
} | |
} |
在 Users 里写入
package com.ksamar.library.entity; | |
import lombok.Data; | |
import javax.persistence.Entity; | |
import javax.persistence.GeneratedValue; | |
import javax.persistence.GenerationType; | |
import javax.persistence.Id; | |
@Entity | |
@Data | |
public class Users { | |
@Id | |
@GeneratedValue(strategy = GenerationType.AUTO) // 设置 Id 自增 | |
// 这里就是与数据库对应字段就可以了 Integer 代表 int String 代表 varchar | |
private Integer id; | |
private String groups; | |
private String username; | |
private String password; | |
private String gender; | |
private String id_card; | |
private String phone; | |
private String identity; | |
} |
在 UsersRepository 里写入
package com.ksamar.library.repository; | |
import com.ksamar.library.entity.Users; | |
import org.springframework.data.jpa.repository.JpaRepository; | |
// 这里实现用户存储的接口 | |
public interface UsersRepository extends JpaRepository<Users,Integer> { | |
} |

运行一下 SpringBoot 然后打开之前写的登录页面就能食用了
最后,在 library 文件夹下新建一个 library.html 登录页面就制作完成了
是不是很简单呢?
当然,使用Cookie的方式存储用户登录是不安全的行为
# 登录是如何实现的?
首先是从 View 视图页面获取用户输入的表单信息,点击表单按钮后,表单信息利用 Controller 把信息传送 到后端的 Model 里,然后这些信息在 Model 里进行数据处理,数据处理完之后,再从后端的 Model 里面,返回一个 json 文件给 Controller,然后 Controller 接收到 Model 的 json 返回文件,就去处理 json 文件里的信息,然后用 View 展示处理后的界面。

# 四、图书管理页面
弄好了登录页面后,登录成功将会切到图书管理页面
要做的工作:
#. 判断用户登录状态
1. 图书管理页面
2. 借阅图书页面
3. 归还图书页面
4. 超时查询页面
5. 用户管理页面
# 判断用户登录状态
Web 进行登录操作时,登录成功后,用户的 cookie 信息会存留在浏览器里,用来判断用户登录,用户操作等等
在 JS 文件夹下创建 library.js 文件
在下面写入判断用户 cookie 登录信息
$(function(){ | |
// 获取 cookie 判断用户登录状态 | |
var is_login = $.cookie("username"); | |
if(is_login == null || is_login == "" || is_login == ''){ | |
alert("请登录!"); | |
window.location.replace("/index.html"); | |
} | |
}); |
这样就可以简易的实现判断用户是否处于登录状态
如果登录了,就可以访问当前页面,如果没有登录,则跳回登录页面让用户进行登录操作
# 前端
# 显示图书数据
这个是普遍后台的 UI 界面 (至少是我认为的

在 library.html 里写入
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="/library/css/library.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="manage-nav bg-primary"> | |
<nav class="navbar bg-primary navbar-dark"> | |
<ul class="navbar-nav"> | |
<li class="nav-item active"> | |
<a class="nav-link" href="/library/library.html">图书管理</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#">借阅图书</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#">归还图书</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#">超时查询</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#">用户管理</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="#">退出系统</a> | |
</li> | |
</ul> | |
</nav> | |
</div> | |
<div class="main-pane"> | |
<div class="user-nav"> | |
<p class="username">Admin</p> | |
</div> | |
<div class="info-pane"> | |
<div class="search-pane"> | |
<button class="btn btn-success add-button">添加书籍</button> | |
<input type="text" name="search" id="search" placeholder="请输入搜索的内容"> | |
<button class="btn btn-primary search-button">搜索</button> | |
</div> | |
<table class="table table-hover"> | |
<thead> | |
<tr> | |
<th>Id</th> | |
<th>组名</th> | |
<th>书名</th> | |
<th>作者</th> | |
<th>出版社</th> | |
<th>价格(人民币)</th> | |
<th>数量(本)</th> | |
<th>ISBN号码</th> | |
<th>操作</th> | |
</tr> | |
</thead> | |
<tbody> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
<script src="/library/js/library.js"></script> | |
</html> |
在 css 文件夹创建 library.css 文件 写入
*{ | |
margin:0; | |
padding: 0; | |
outline: none; | |
} | |
html,body,.main{ | |
width: 100%; | |
height: 100%; | |
} | |
/* 主页面样式 */ | |
.main{ | |
display: flex; | |
} | |
/* 侧边导航栏样式 */ | |
.manage-nav{ | |
display: flex; | |
justify-content: center; | |
position: fixed; | |
min-width: 256px; | |
max-width: 256px; | |
height: 100%; | |
text-align: center; | |
} | |
/* 面板样式 */ | |
.main-pane{ | |
margin-left: 256px; | |
width: 100%; | |
height: 100%; | |
} | |
/* 用户导航栏样式 */ | |
.user-nav{ | |
display: flex; | |
align-items: center; | |
justify-content: flex-end; | |
position: fixed; | |
min-width: calc(100% - 256px); | |
height: 64px; | |
background-color: rgb(248, 248, 248); | |
} | |
.user-nav .username{ | |
padding: 0; | |
margin: 0; | |
margin-right: 64px; | |
} | |
/* 信息面板样式 */ | |
.info-pane{ | |
margin-top: 64px; | |
min-width: calc(100% - 256px); | |
min-height: calc(100% - 64px); | |
height: calc(100% - 64px); | |
background-color: white; | |
} | |
.info-pane .search-pane{ | |
display: flex; | |
justify-content: center; | |
width: 100%; | |
height: 32px; | |
margin-bottom: 16px; | |
} | |
.info-pane .search-pane button{ | |
margin-right: 32px; | |
padding: 0; | |
padding-left: 16px; | |
padding-right: 16px; | |
} | |
.info-pane .search-pane #search{ | |
width: 400px; | |
padding-left: 12px; | |
border: 1px solid #aaa; | |
border-radius: 4px; | |
} |
在 js 文件夹创建 library.js 文件 写入
$(function(){ | |
// 获取 cookie 判断用户登录状态 | |
var is_login = $.cookie("username"); | |
if(is_login == null || is_login == "" || is_login == ''){ | |
alert("请登录!"); | |
window.location.replace("/index.html"); | |
} | |
// 添加假数据 | |
for(var i = 1; i < 51; i++){ | |
var text = "<tr id='" + i + "'>" + | |
"<td>" + i + "</td>" + | |
"<td>基础书籍</td>" + | |
"<td>语文书</td>" + | |
"<td>张三</td>" + | |
"<td>无</td>" + | |
"<td>6.66</td>" + | |
"<td>6</td>" + | |
"<td>978000000006</td>" + | |
"<td><button class='btn btn-success btn-sm edit' name='" + i + "'>编辑</button><button class='btn btn-danger btn-sm delete' name='" + i + "'>删除</button></td>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
}); |
至此,我们就创建好了前端的图书管理页面

现在这个图书页面也只是一个静态页面,那怎么让他动起来呢?
首先我们要知道,后台页面有些内容是不会经常进行变动,比如侧边的导航栏,顶部的用户栏,经常改变的内容是信息面板这一块,为了减少代码沉余,在后台页面我将添加一个 iframe 框架动态刷新信息内容,静态更改 url 就能访问其他页面,导航栏和用户栏相对也不会进行变化。
现在把导航栏需要的页面都给创建出来
在 library 文件夹创建下面的文件
后台 -> library.html
图书管理 -> books.html
借阅图书 -> borrow.html
归还图书 -> return.html
超时查询 -> overtime.html
用户管理 -> users.html

然后再给每一个 html 文件创建一个对应名字的 css 文件,js 文件即可
创建文件完毕后,在 library.html 文件夹添加一个 iframe 框架
替换 <div class="info-pane"> 下的代码,只用添加一个 iframe 写上 src 页面路径
<div class="info-pane"> | |
<iframe src="/library/books.html" frameborder="0" name="info-iframe"></iframe> | |
</div> |
给 ** library.css** 样式表添加 iframe 的样式
.info-pane iframe{ | |
width: 100%; | |
height: 100%; | |
} |
现在可以把原来写在 <div class="info-pane"> 下的代码搬到 books.html 文件里
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="/library/css/books.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="search-pane"> | |
<button class="btn btn-success add-button">添加书籍</button> | |
<input type="text" name="search" id="search" placeholder="请输入搜索的内容"> | |
<button class="btn btn-primary search-button">搜索</button> | |
</div> | |
<table class="table table-hover"> | |
<thead> | |
<tr> | |
<th>Id</th> | |
<th>组名</th> | |
<th>书名</th> | |
<th>作者</th> | |
<th>出版社</th> | |
<th>价格(人民币)</th> | |
<th>数量(本)</th> | |
<th>ISBN号码</th> | |
<th>操作</th> | |
</tr> | |
</thead> | |
<tbody> | |
</tbody> | |
</table> | |
</div> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
<script src="/library/js/books.js"></script> | |
</html> |
然后把 search-pane 的样式搬到 books.css 文件里
*{ | |
margin:0; | |
padding: 0; | |
outline: none; | |
} | |
html,body,.main{ | |
width: 100%; | |
height: 100%; | |
} | |
/* 主页面样式 */ | |
.main{ | |
display: flex; | |
flex-direction: column; | |
padding: 32px; | |
} | |
.search-pane{ | |
display: flex; | |
justify-content: center; | |
width: 100%; | |
height: 32px; | |
margin-bottom: 16px; | |
} | |
.search-pane button{ | |
margin-right: 32px; | |
padding: 0; | |
padding-left: 16px; | |
padding-right: 16px; | |
} | |
.search-pane #search{ | |
width: 400px; | |
padding-left: 12px; | |
border: 1px solid #aaa; | |
border-radius: 4px; | |
} |
把之前写的假数据代码搬到 books.js
$(function(){ | |
// 添加假数据 | |
for(var i = 1; i < 51; i++){ | |
var text = "<tr id='" + i + "'>" + | |
"<td>" + i + "</td>" + | |
"<td>基础书籍</td>" + | |
"<td>语文书</td>" + | |
"<td>张三</td>" + | |
"<td>无</td>" + | |
"<td>6.66</td>" + | |
"<td>6</td>" + | |
"<td>978000000006</td>" + | |
"<td><button class='btn btn-success btn-sm edit' name='" + i + "'>编辑</button><button class='btn btn-danger btn-sm delete' name='" + i + "'>删除</button></td>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
}); |
现在把侧边导航栏的地址一一对应到每一个文件
<nav class="navbar bg-primary navbar-dark"> | |
<ul class="navbar-nav"> | |
<li class="nav-item active"> | |
<a class="nav-link" href="/library/books.html" target="info-iframe">图书管理</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="/library/borrow.html" target="info-iframe">借阅图书</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="/library/return.html" target="info-iframe">归还图书</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="/library/overtime.html" target="info-iframe">超时查询</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link" href="/library/users.html" target="info-iframe">用户管理</a> | |
</li> | |
<li class="nav-item"> | |
<a class="nav-link exit" href="#">退出系统</a> | |
</li> | |
</ul> | |
</nav> |
给侧边导航栏添加动态激活样式,在 library.js 写入
// 侧边栏激活状态 | |
$("ul>li").click(function (e) { | |
$("li").removeClass("active"); | |
$(this).addClass("active"); | |
}); |
退出系统的操作
// 退出系统 | |
$(".exit").click(function (e) { | |
var exit = $.removeCookie('username', { path: '/' }); | |
if(exit){ | |
window.location.replace("/index.html"); | |
alert("您已退出系统"); | |
} | |
else{ | |
alert("系统错误"); | |
} | |
}); |
在图书管理页面显示真数据,将原先的假数据代码替换成如下代码
$(function(){ | |
$.ajax({ | |
type: "get", // 请求方式 | |
url: "http://192.168.1.3:8181/nav/books", // 请求地址 | |
dataType: "json", // 返回文件格式 | |
success:function(data){ | |
// 添加数据 | |
for(var i = 0; i < data.length; i++){ | |
var text = "<tr id='" + data[i].id + "'>" + | |
"<td>" + data[i].id + "</td>" + | |
"<td>" + data[i].groups + "</td>" + | |
"<td>" + data[i].name + "</td>" + | |
"<td>" + data[i].author + "</td>" + | |
"<td>" + data[i].press + "</td>" + | |
"<td>" + data[i].price + "</td>" + | |
"<td>" + data[i].quantity + "</td>" + | |
"<td>" + data[i].isbn + "</td>" + | |
"<td><button class='btn btn-success btn-sm edit' name='" + data[i].id + "'>编辑</button><button class='btn btn-danger btn-sm delete' name='" + data[i].id + "'>删除</button></td>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
}, | |
error: function(data){ | |
alert("系统错误"); | |
} | |
}); | |
}); |
# 搜索图书
添加一个新的请求,接收返回的数据,处理一下即可,更改 library.js 的代码为
$(function(){ | |
// 获取图书数据 | |
$.ajax({ | |
type: "get", // 请求方式 | |
url: "http://localhost:8181/nav/books", // 请求地址 | |
dataType: "json", // 返回文件格式 | |
success:function(data){ | |
// 添加数据 | |
searchBook(data); | |
}, | |
error: function(data){ | |
alert("系统错误"); | |
} | |
}); | |
// 搜索图书 | |
var search_button = $('.search-button'); | |
var input_text = $('#search'); | |
$(search_button).click(function (e) { | |
e.preventDefault(); | |
$.ajax({ | |
type: "get", | |
url: "http://localhost:8181/nav/books/find", | |
data: {book:input_text.val()}, | |
dataType: "json", | |
success:function(data){ | |
$(".book").remove(); // 删除原来的书 | |
searchBook(data); // 搜索图书 | |
}, | |
error:function(data){ | |
alert("系统错误"); | |
} | |
}); | |
}); | |
}); | |
// 显示图书信息函数 | |
function searchBook(data){ | |
for(var i = 0; i < data.length; i++){ | |
var text = "<tr id='" + data[i].id + "' class='book'>" + | |
"<td name='id'>" + data[i].id + "</td>" + | |
"<td name='groups'>" + data[i].groups + "</td>" + | |
"<td name='name'>" + data[i].name + "</td>" + | |
"<td name='author'>" + data[i].author + "</td>" + | |
"<td name='press'>" + data[i].press + "</td>" + | |
"<td name='price'>" + data[i].price + "</td>" + | |
"<td name='quantity'>" + data[i].quantity + "</td>" + | |
"<td name='isbn'>" + data[i].isbn + "</td>" + | |
"<td><button class='btn btn-success btn-sm edit' name='" + data[i].id + "' data-toggle='modal' data-target='#book-modal'>编辑</button><button class='btn btn-danger btn-sm delete' name='" + data[i].id + "' data-toggle='modal' data-target='#delete-modal'>删除</button></td>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
} |
# 添加图书
在 books.html 添加一个模态框,输入图书的信息
<!-- 给添加按钮写入打开模态框参数 --> | |
<button class="btn btn-success add-button" data-toggle="modal" data-target="#book-modal">添加书籍</button> | |
<!-- 模态框 --> | |
<div class="modal fade" id="book-modal"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<h4 class="modal-title"></h4> | |
<button type="button" class="close" data-dismiss="modal">×</button> | |
</div> | |
<div class="modal-body"> | |
<form id="book-form" name="book-form" class="book-form"> | |
<div class="form-group"> | |
<label for="groups">图书组名</label> | |
<input type="text" class="form-control" placeholder="请输入图书组名" id="groups" name="groups"> | |
</div> | |
<div class="form-group"> | |
<label for="name">图书名称</label> | |
<input type="text" class="form-control" placeholder="请输入图书名称" id="name" name="name"> | |
</div> | |
<div class="form-group"> | |
<label for="author">作者名称:</label> | |
<input type="text" class="form-control" placeholder="请输入作者名称" id="author" name="author"> | |
</div> | |
<div class="form-group"> | |
<label for="press">出版社名称:</label> | |
<input type="text" class="form-control" placeholder="请输入出版社名称" id="press" name="press"> | |
</div> | |
<div class="form-group"> | |
<label for="price">价格(人民币):</label> | |
<input type="text" class="form-control" placeholder="请输入价格" id="price" name="price" maxlength="10"> | |
</div> | |
<div class="form-group"> | |
<label for="quantity">数量(本):</label> | |
<input type="text" class="form-control" placeholder="请输入数量" id="quantity" name="quantity" maxlength="4"> | |
</div> | |
<div class="form-group"> | |
<label for="isbn">ISBN号码:</label> | |
<input type="text" class="form-control" placeholder="请输入ISBN号码" id="isbn" name="isbn" maxlength="13"> | |
</div> | |
</form> | |
</div> | |
<div class="modal-footer"> | |
<button type="submit" class="btn btn-success operate-button"></button> | |
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> | |
</div> | |
</div> | |
</div> | |
</div> |
在 library.js 添加
// 表单组件 | |
var book_title = $('#book-modal .modal-title'); // 标题栏 | |
var book_form = $('.book-form'); // 表单 | |
var operate_button= $('.operate-button'); // 添加图书按钮 | |
// 添加图书 | |
var add_button = $('.add-button'); // 添加按钮 | |
$(add_button).click(function (e) { | |
e.preventDefault(); | |
book_title.text("添加图书"); // 设置标题栏 | |
book_form[0].reset(); // 重置表单 | |
operate_button.text("添加"); // 设置按钮文本 | |
}); | |
// 图书操作 | |
$(operate_button).click(function (e) { | |
e.preventDefault(); | |
if(book_title.text() == "添加图书"){ | |
addBook(book_form); | |
} | |
}); | |
// 检查表单函数 | |
function checkForm(){ | |
var group = $('#groups'); | |
var name = $('#name'); | |
var author = $('#author'); | |
var press = $('#press'); | |
var price = $('#price'); | |
var quantity = $('#quantity'); | |
var isbn = $('#isbn'); | |
if(group.val() == '' || group.val() == "" || group.val() == null){ | |
alert("请输入图书组名"); | |
} | |
else if(name.val() == '' || name.val() == "" || name.val() == null){ | |
alert("请输入图书名称"); | |
} | |
else if(author.val() == '' || author.val() == "" || author.val() == null){ | |
alert("请输入作者名称"); | |
} | |
else if(press.val() == '' || press.val() == "" || press.val() == null){ | |
alert("请输入出版社名称"); | |
} | |
else if(price.val() == '' || price.val() == "" || price.val() == null){ | |
alert("请输入价格(人民币)"); | |
} | |
else if(quantity.val() == '' || quantity.val() == "" || quantity.val() == null){ | |
alert("请输入数量(本)"); | |
} | |
else if(isbn.val() == '' || isbn.val() == "" || isbn.val() == null){ | |
alert("请输入ISBN号码"); | |
} | |
else if(isbn.val().length != 13){ | |
alert("请输入正确的ISBN号码"); | |
} | |
else{ | |
return true; | |
} | |
return false; | |
} | |
// 添加图书函数 | |
function addBook(book_form){ | |
// 判断表单,返回 false 不能添加,返回 true 能添加 | |
if(checkForm() != false){ | |
$.ajax({ | |
type: "post", | |
url: "http://localhost:8181/nav/books/save", | |
data: book_form.serialize(), | |
dataType: "json", | |
success:function(data){ | |
if(data.resultCode == '-1'){ | |
alert("添加失败,服务器错误"); | |
} | |
if(data.resultCode == '0'){ | |
alert("添加失败,此书已存在"); | |
} | |
if(data.resultCode == '1'){ | |
alert("添加成功"); | |
window.location.reload(); | |
} | |
}, | |
error:function(data){ | |
alert("错误"); | |
} | |
}); | |
} | |
} |
# 编辑图书
在 books.js 添加
// 编辑图书 | |
$(document).on('click', '.edit', function (e) { | |
e.preventDefault(); | |
book_title.text("编辑图书"); // 设置标题 | |
book_form[0].reset(); // 重置表单 | |
operate_button.text("编辑"); // 设置按钮文本 | |
operate_button.attr("name",$(this).attr("name")); // 设置 id | |
getBook($(this).attr("name")); // 获取图书信息 | |
}); | |
// 图书操作 | |
$(operate_button).click(function (e) { | |
e.preventDefault(); | |
if(book_title.text() == "添加图书"){ | |
addBook(book_form); | |
} | |
if(book_title.text() == "编辑图书"){ | |
editBook($(this).attr("name"), book_form); | |
} | |
}); | |
// 获取图书信息 | |
function getBook(id){ | |
$.ajax({ | |
type: "get", | |
url: "http://localhost:8181/nav/books/find/" + id, | |
dataType: "json", | |
success: function (data) { | |
$('#groups').val(data.groups); | |
$('#name').val(data.name); | |
$('#author').val(data.author); | |
$('#press').val(data.press); | |
$('#price').val(data.price); | |
$('#quantity').val(data.quantity); | |
$('#isbn').val(data.isbn); | |
}, | |
error: function (data){ | |
alert("错误"); | |
} | |
}); | |
} | |
// 编辑图书信息 | |
function editBook(id, book_form){ | |
if(checkForm() == true){ | |
$.ajax({ | |
type: "put", | |
url: "http://localhost:8181/nav/books/update/" + id, | |
data: book_form.serialize(), | |
dataType: "json", | |
success: function (data) { | |
if(data.resultCode == "-1"){ | |
alert("修改失败,服务器错误"); | |
} | |
if(data.resultCode == "0"){ | |
alert("修改失败,要修改的ISBN号码已存在"); | |
} | |
if(data.resultCode == "1"){ | |
alert("修改成功"); | |
window.location.reload(); | |
} | |
}, | |
error: function (data) { | |
alert("错误") | |
} | |
}); | |
} | |
} |
# 删除图书
在 books.html 添加一个模态框
<div class="modal fade" id="delete-modal"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<h4 class="modal-title">删除图书</h4> | |
<button type="button" class="close" data-dismiss="modal">×</button> | |
</div> | |
<div class="modal-body"> | |
<p class="tip"></p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-danger delete-button">删除</button> | |
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> | |
</div> | |
</div> | |
</div> | |
</div> |
在 books.js 写入
// 删除图书 | |
$(document).on('click', '.delete', function (e) { | |
e.preventDefault(); | |
$('.delete-button').attr("name",$(this).attr("name")); // 设置 id | |
$('.tip').text("确定删除" + $('#' + $(this).attr("name") + '>td[name="name"]').text() + "?"); | |
}); | |
$('.delete-button').click(function (e){ | |
e.preventDefault(); | |
deleteBook($(this).attr("name")); | |
}); | |
// 删除书本函数 | |
function deleteBook(id){ | |
$.ajax({ | |
type: "delete", | |
url: "http://localhost:8181/nav/books/delete/" + id, | |
dataType: "json", | |
success: function (data) { | |
if(data.resultCode == "-1"){ | |
alert("服务器错误"); | |
} | |
if(data.resultCode == "1"){ | |
alert("删除成功"); | |
window.location.reload(); | |
} | |
}, | |
error: function (data){ | |
alert("错误"); | |
} | |
}); | |
} |
# 后端
# 获取图书
在 SpringBoot 项目创建

类:
BooksHandler -------- 图书操作
Books ------------------- 图书实体
BooksRepository ----- 图书存储库
在 BooksHandler 写入
package com.ksamar.library.controller; | |
import com.ksamar.library.entity.Books; | |
import com.ksamar.library.repository.BooksRepository; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.data.domain.Example; | |
import org.springframework.web.bind.annotation.*; | |
import java.util.List; | |
import java.util.Optional; | |
@RestController | |
@RequestMapping("/nav") // 请求地址 | |
public class BooksHandler { | |
@Autowired | |
private BooksRepository booksRepository; | |
// 搜索全部 | |
@GetMapping("/books") // 请求地址 | |
public List<Books> findAll() { | |
return booksRepository.findAll(); | |
} | |
} |
在 Books 写入
package com.ksamar.library.entity; | |
import lombok.Data; | |
import javax.persistence.Entity; | |
import javax.persistence.GeneratedValue; | |
import javax.persistence.GenerationType; | |
import javax.persistence.Id; | |
@Entity | |
@Data | |
public class Books { | |
@Id | |
@GeneratedValue(strategy = GenerationType.IDENTITY) | |
private Integer Id; | |
private String groups; | |
private String name; | |
private String author; | |
private String press; | |
private Double price; | |
private Integer quantity; | |
private String isbn; | |
} |
在 BooksRepository 写入
package com.ksamar.library.repository; | |
import com.ksamar.library.entity.Books; | |
import org.springframework.data.jpa.repository.JpaRepository; | |
public interface BooksRepository extends JpaRepository<Books,Integer> { | |
} |
# 搜索图书
在 BooksHandler 里添加
// 搜索单本图书 | |
@GetMapping("/books/find") | |
public List<Books> findByNameLike(String book){ | |
return booksRepository.findByNameLike("%" + book + "%"); | |
} |
在 BooksRepository 里添加
List<Books> findByNameLike(String book); |
# 添加图书
在 BooksHandler 添加
/** | |
* -1:错误,添加失败 | |
* 0:存在,添加失败 | |
* 1:添加成功 | |
*/ | |
@PostMapping("/books/save") | |
public Object save(Books books){ | |
List<Books> book1 = booksRepository.findByIsbn(books.getIsbn()); // 搜索书籍是否存在 | |
JSONObject jsonObject = new JSONObject(); // 创建一个空 JSONObject 对象 | |
if(book1.size() == 0){ | |
Books result = booksRepository.save(books); // 保存书籍 | |
if(result != null){ | |
jsonObject.put("resultCode","1"); | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
return jsonObject; | |
} |
在 BooksReposiitory 添加
List<Books> findByIsbn(String Isbn); |
# 编辑图书
在 BooksHandler 添加
/** | |
* 修改图书 | |
* -1:错误,修改失败 | |
* 0:修改后的 isbn 存在,修改失败 | |
* 1:修改成功 | |
*/ | |
@PutMapping("/books/update/{id}") | |
public Object update(Books books){ | |
JSONObject jsonObject = new JSONObject(); | |
List<Books> booksList = booksRepository.findByIsbn(books.getIsbn()); // 搜索 isbn 是否存在 | |
// 存在 | |
if(booksList.size() == 1){ | |
int oldId = books.getId(); // 获取旧 id | |
int newId = booksList.get(0).getId(); // 获取新 id | |
// 判断要修改的书的 id 是否和原来的书 id 一致 | |
if(oldId == newId){ | |
Books save = booksRepository.save(books); | |
if(save != null){ | |
jsonObject.put("resultCode","1"); | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
} | |
// 不存在 | |
else if(booksList.size() == 0){ | |
booksRepository.save(books); | |
jsonObject.put("resultCode","1"); | |
} | |
// 其他情况 | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
return jsonObject; | |
} |
# 删除图书
在 Bookshandler 写入
/** | |
* 删除图书 | |
* -1:删除失败 | |
* 1:删除成功 | |
*/ | |
@DeleteMapping("/books/delete/{id}") | |
public Object deleteById(@PathVariable("id") Integer Id){ | |
JSONObject jsonObject = new JSONObject(); | |
if(booksRepository.existsById(Id)){ | |
booksRepository.deleteById(Id); | |
jsonObject.put("resultCode","1"); | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
return jsonObject; | |
} |
# 页面是如何与数据库交互的?

# 获取图书数据
前端通过调用 Ajax 发送一个 get 请求到服务端,然后服务端返回一组 json 数据给 Web 前端,用 JavaScript 对 json 数据进行处理,然后将处理好的数据展示到 Web 前端
# 搜托图书
与上面方法类似,多添加了一个 book 的参数,作为查询的书名,后端接收到请求去查询数据库有没有该本书,有则返回书本信息,没有则返回空
# 添加图书
前端发送一个带表单信息 post 请求到服务端,然后由服务器检测这本书是否存在,如果存在则返回添加失败的 Code,如果不存在则发返回添加成功的 Code,如果服务器添加书本不成功则返回异常的 Code
# 编辑图书
前端先发送一个请求获取该本书的信息 ,然后修改数据后再向服务器发送修改请求,服务器检测 id 和 isbn 号码,如果 isbn 没有变动可以直接修改,如果修改的 isbn 在数据库里没有则可以直接修改,如果修改新的 isbn 在数据库中存在,则判断原来的 id 与数据库搜索出来的 isbn 图书 id 是否一致,不一致则修改失败
# 删除图书
前端发送一个带 id 的删除请求,服务器接受删除请求,判断 id 是否在数据库中,如果存在就删除,不存在就不删除
# 五、借阅图书页面
# 前端
在 borrow.html 里写入
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="/library/css/borrow.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<h2>借阅图书</h2> | |
<div class="search-pane"> | |
<input type="text" name="search-input" id="search-input" class="search-input" maxlength="13" placeholder="请搜索要借阅的图书ISBN号码"> | |
<input type="submit" value="搜索" name="search-button" id="search-button" class="search-button"> | |
</div> | |
<div class="info-pane"> | |
<div class="book"> | |
<h3>图书信息</h3> | |
<p>图书名称:<span class="book-name"></span></p> | |
<p>作者名称: <span class="book-author"></span></p> | |
<p>出版社名称:<span class="book-press"></span></p> | |
<p>ISBN号码: <span class="book-isbn"></span></p> | |
<p>库存(本): <span class="book-quantity"></span></p> | |
</div> | |
<div class="user"> | |
<h3>用户信息</h3> | |
<input type="text" name="username" id="username" class="username" placeholder="借阅人名字"> | |
<input type="text" name="id-card" id="id-card" class="id-card" placeholder="借阅人卡号"> | |
<input type="text" name="phone" id="phone" class="phone" placeholder="借阅人手机号"> | |
<input type="button" name="borrow-button" id="borrow-button" class="btn btn-primary borrow-button" value="借阅图书"></button> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
<script src="/library/js/config.js"></script> | |
<script src="/library/js/borrow.js"></script> | |
</html> |
在 borrow.css 写入
* { | |
margin: 0; | |
padding: 0; | |
outline: none; | |
} | |
html, | |
body, | |
.main { | |
width: 100%; | |
height: 100%; | |
} | |
/* 主页面样式 */ | |
.main { | |
display: flex; | |
flex-direction: column; | |
padding: 32px; | |
justify-content: center; | |
align-items: center; | |
} | |
/* 搜索栏样式 */ | |
.search-pane{ | |
display: flex; | |
margin-bottom: 32px; | |
} | |
.search-pane .search-input{ | |
width: 480px; | |
height: 38px; | |
border-radius: 8px 0px 0px 8px; | |
border: 2px solid #007BFF; | |
padding-left: 12px; | |
} | |
.search-pane .search-button{ | |
width: 70px; | |
border: transparent; | |
border-radius: 0px 8px 8px 0px; | |
background-color: #007BFF; | |
color: white; | |
} | |
/* 信息栏样式 */ | |
.info-pane{ | |
display: flex; | |
width: 550px; | |
} | |
.info-pane div{ | |
display: flex; | |
width: 50%; | |
flex-direction: column; | |
} | |
.info-pane .user input{ | |
margin-top: 12px; | |
padding: 4px; | |
border-radius: 4px; | |
} | |
.info-pane .user input[type=text]{ | |
border: 1px solid rgb(77, 77, 77); | |
} |
在 borrow.js 写入
$(function(){ | |
// 搜索图书 | |
var search_button = $(".search-button"); | |
$(search_button).click(function (e) { | |
e.preventDefault(); | |
var isbn = $(".search-input").val(); | |
if(isbn != '' && isbn != "" && isbn != null){ | |
if(isbn.length == 13){ | |
$.ajax({ | |
type: "get", | |
url: ip + "/nav/books/find/isbn/" + isbn, | |
dataType: "json", | |
success:function(data){ | |
if(!jQuery.isEmptyObject(data)){ | |
$('.book-name').text(data[0].name); | |
$('.book-author').text(data[0].author); | |
$('.book-press').text(data[0].press); | |
$('.book-isbn').text(data[0].isbn); | |
$('.book-quantity').text(data[0].quantity); | |
} | |
else{ | |
alert("查无此书"); | |
} | |
}, | |
error:function(data){ | |
alert("系统错误"); | |
} | |
}); | |
} | |
else{ | |
alert("请输入正确的ISBN号码"); | |
} | |
} | |
else{ | |
alert("请输入ISBN号码"); | |
} | |
}); | |
// 借阅图书 | |
var borrow_button = $('.borrow-button'); | |
$(borrow_button).click(function (e) { | |
e.preventDefault(); | |
var isbn = $('.book-isbn').text(); | |
var username = $('.username').val(); | |
var id_card = $('.id-card').val(); | |
var phone = $('.phone').val(); | |
if(isbn != '' && isbn != "" && isbn != null){ | |
if(username != '' && username != "" && username != null){ | |
if(id_card != '' && id_card != "" && id_card != null){ | |
if(phone != '' && phone != "" && phone != null){ | |
$.ajax({ | |
type: "post", | |
url: ip + "/nav/books/borrow", | |
data: {isbn:isbn,username:username,id_card:id_card,phone:phone}, | |
dataType: "json", | |
success: function (data) { | |
console.log(data); | |
if(data.resultCode == "-1"){ | |
alert("借阅失败,系统错误"); | |
} | |
if(data.resultCode == "0"){ | |
alert("借阅失败,库存不足"); | |
} | |
if(data.resultCode == "1"){ | |
alert("借阅成功"); | |
window.location.reload(); | |
} | |
}, | |
error: function (data){ | |
alert("系统错误"); | |
} | |
}); | |
} | |
else{ | |
alert("请输入借阅人手机"); | |
} | |
} | |
else{ | |
alert("请输入借阅人卡号"); | |
} | |
} | |
else{ | |
alert("请输入借阅人名字"); | |
} | |
} | |
else{ | |
alert("请先选择书籍!"); | |
} | |
}); | |
}); |
# 后端
在 BookHandler 里写入
// 搜索单本图书 ISBN | |
@GetMapping("/books/find/isbn/{isbn}") | |
public List<Books> findByIsbn(@PathVariable("isbn") String isbn) { | |
return booksRepository.findByIsbn(isbn); | |
} |
新建 Borrow 类,BorrowRepository 接口,BorrowHandler 类,分别写入
Borrow
package com.ksamar.library.entity; | |
import lombok.Data; | |
import javax.persistence.Entity; | |
import javax.persistence.GeneratedValue; | |
import javax.persistence.GenerationType; | |
import javax.persistence.Id; | |
import java.sql.Date; | |
@Entity | |
@Data | |
public class Borrow { | |
@Id | |
@GeneratedValue(strategy = GenerationType.IDENTITY) | |
private Integer Id; | |
private String name; | |
private String isbn; | |
private String username; | |
private String id_card; | |
private String phone; | |
private Date time; | |
private Date r_time; | |
} |
BorrowRepository
package com.ksamar.library.repository; | |
import com.ksamar.library.entity.Borrow; | |
import org.springframework.data.jpa.repository.JpaRepository; | |
public interface BorrowRepository extends JpaRepository<Borrow,Integer> { | |
} |
BorrowHandler
package com.ksamar.library.controller; | |
import com.alibaba.fastjson.JSONObject; | |
import com.ksamar.library.entity.Books; | |
import com.ksamar.library.entity.Borrow; | |
import com.ksamar.library.entity.Users; | |
import com.ksamar.library.repository.BooksRepository; | |
import com.ksamar.library.repository.BorrowRepository; | |
import com.ksamar.library.repository.UsersRepository; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.web.bind.annotation.PostMapping; | |
import org.springframework.web.bind.annotation.RequestMapping; | |
import org.springframework.web.bind.annotation.RestController; | |
import java.util.Calendar; | |
import java.util.List; | |
@RestController | |
@RequestMapping("/nav") // 请求地址 | |
public class BorrowHandler { | |
@Autowired | |
private BooksRepository booksRepository; | |
@Autowired | |
private BorrowRepository borrowRepository; | |
@Autowired | |
private UsersRepository usersRepository; | |
/** | |
* 借阅图书 | |
* -1: 系统错误 | |
* 0: 库存不足 | |
* 1: 借阅成功 | |
*/ | |
@PostMapping("/books/borrow") | |
public Object bookBorrow(String isbn, String username, String id_card, String phone){ | |
JSONObject jsonObject = new JSONObject(); | |
if(!isbn.equals("") && !username.equals("") && !id_card.equals("") && !phone.equals("")){ | |
List<Books> booksList = booksRepository.findByIsbn(isbn); // 搜索图书 | |
// 判断有没有书 | |
if(booksList.size() != 0){ | |
Books books = booksList.get(0); | |
if(books.getQuantity() - 1 >= 0){ | |
books.setQuantity(books.getQuantity() - 1); | |
Users users = usersRepository.findByPhone(phone); // 搜索用户 | |
// 判断有没有用户 用户信息是否正确 | |
if(users != null && users.getUsername().equals(username) && users.getId_card().equals(id_card) && users.getPhone().equals(phone)){ | |
TimeZone.setDefault(TimeZone.getTimeZone("GMT")); // 设置时区 | |
Calendar calendar = Calendar.getInstance(); // 获取时间 | |
Date nowDate; // 借阅时间 | |
Date returnDate; // 归还时间 | |
nowDate = calendar.getTime(); // 借阅时间 | |
calendar.add(Calendar.DATE, 7); // 添加时间 | |
returnDate = calendar.getTime(); // 归还时间 | |
Borrow borrow = new Borrow(); | |
borrow.setName(books.getName()); // 图书名称 | |
borrow.setIsbn(books.getIsbn()); //ISBN 号码 | |
borrow.setUsername(users.getUsername()); // 借阅人名字 | |
borrow.setId_card(users.getId_card()); // 借阅人 ID | |
borrow.setPhone(users.getPhone()); // 借阅人手机号 | |
borrow.setTime(nowDate); // 设置借阅图书时间 | |
borrow.setR_time(returnDate); // 添加归还书本时间 | |
Borrow save = borrowRepository.save(borrow); // 保存数据 | |
if(save != null){ | |
jsonObject.put("resultCode","1"); | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
return jsonObject; | |
} |
# 借阅图书是如何实现的?
前端先发送一个搜索图书的请求,查询这本书是否存在,然后显示图书的信息,然后再填写好借阅人的信息,后端判断借阅人信息是否存在,若都存在,借阅图书成功
# 六、归还图书页面
# 前端
在 return.html 里写入
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="/library/css/return.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="search-pane"> | |
<input type="text" name="search" id="search" placeholder="请输入搜索的内容"> | |
<button class="btn btn-primary search-button">搜索</button> | |
</div> | |
<table class="table table-hover"> | |
<thead> | |
<tr> | |
<th>Id</th> | |
<th>书名</th> | |
<th>ISBN号码</th> | |
<th>借阅人名字</th> | |
<th>借阅人卡号</th> | |
<th>借阅人手机号</th> | |
<th>借阅时间</th> | |
<th>归还时间</th> | |
<th>操作</th> | |
</tr> | |
</thead> | |
<tbody> | |
</tbody> | |
</table> | |
</div> | |
<!-- 模态框 --> | |
<div class="modal fade" id="return-modal"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<h4 class="modal-title">归还图书</h4> | |
<button type="button" class="close" data-dismiss="modal">×</button> | |
</div> | |
<div class="modal-body"> | |
<p class="tip"></p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-danger return-button">归还</button> | |
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
<script src="/library//js/config.js"></script> | |
<script src="/library/js/return.js"></script> | |
</html> |
在 return.css 里写入
* { | |
margin: 0; | |
padding: 0; | |
outline: none; | |
} | |
html, | |
body, | |
.main { | |
width: 100%; | |
height: 100%; | |
} | |
/* 主页面样式 */ | |
.main { | |
display: flex; | |
flex-direction: column; | |
padding: 32px; | |
} | |
.search-pane { | |
display: flex; | |
justify-content: center; | |
width: 100%; | |
height: 32px; | |
margin-bottom: 16px; | |
} | |
.search-pane button { | |
margin-right: 32px; | |
padding: 0; | |
padding-left: 16px; | |
padding-right: 16px; | |
} | |
.search-pane #search { | |
width: 400px; | |
padding-left: 12px; | |
border: 1px solid #aaa; | |
border-radius: 4px; | |
} |
在 return.js 里写入
$(function(){ | |
// 获取图书数据 | |
$.ajax({ | |
type: "get", // 请求方式 | |
url: ip + "/nav/books/borrow/find", // 请求地址 | |
dataType: "json", // 返回文件格式 | |
success:function(data){ | |
// 添加数据 | |
searchBook(data); | |
}, | |
error: function(data){ | |
alert("系统错误"); | |
} | |
}); | |
// 搜索图书 | |
var search_button = $('.search-button'); | |
var isbn = $('#search'); | |
$(search_button).click(function (e) { | |
e.preventDefault(); | |
$.ajax({ | |
type: "get", | |
url: ip + "/nav/books/borrow/find/" + isbn.val(), | |
dataType: "json", | |
success:function(data){ | |
$(".book").remove(); // 删除原来的书 | |
searchBook(data); // 搜索图书 | |
}, | |
error:function(data){ | |
alert("系统错误"); | |
} | |
}); | |
}); | |
// 归还图书 | |
$(document).on('click', '.return', function (e) { | |
e.preventDefault(); | |
$('.return-button').attr("name",$(this).attr("name")); // 设置 id | |
$('.tip').text("确定归还 " + $('#' + $(this).attr("name") + '>td[name="username"]').text() + " 的 " + $('#' + $(this).attr("name") + '>td[name="name"]').text() + " 书吗?"); | |
}); | |
$('.return-button').click(function (e){ | |
e.preventDefault(); | |
returnBook($(this).attr("name")); | |
}); | |
}); | |
// 显示图书信息函数 | |
function searchBook(data){ | |
for(var i = 0; i < data.length; i++){ | |
var text = "<tr id='" + data[i].id + "' class='book'>" + | |
"<td name='id'>" + data[i].id + "</td>" + | |
"<td name='name'>" + data[i].name + "</td>" + | |
"<td name='isbn'>" + data[i].isbn + "</td>" + | |
"<td name='username'>" + data[i].username + "</td>" + | |
"<td name='id_card'>" + data[i].id_card + "</td>" + | |
"<td name='phone'>" + data[i].phone + "</td>" + | |
"<td name='time'>" + data[i].time.substr(0,10) + "</td>" + | |
"<td name='r_time'>" + data[i].r_time.substr(0,10) + "</td>" + | |
"<td><button class='btn btn-warning btn-sm return' name='" + data[i].id + "' data-toggle='modal' data-target='#return-modal'>归还</button>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
} | |
// 归还书本函数 | |
function returnBook(id){ | |
$.ajax({ | |
type: "delete", | |
url: ip + "/nav/books/borrow/return/" + id, | |
dataType: "json", | |
success: function (data) { | |
if(data.resultCode == "-1"){ | |
alert("服务器错误"); | |
} | |
if(data.resultCode == "0"){ | |
alert("归还失败"); | |
} | |
if(data.resultCode == "1"){ | |
alert("归还成功"); | |
window.location.reload(); | |
} | |
}, | |
error: function (data){ | |
alert("错误"); | |
} | |
}); | |
} |
# 后端
在 BorrowHandler 里写入
// 搜索图书信息 | |
@GetMapping("/books/borrow/find") | |
public List<Borrow> findAll() { | |
return borrowRepository.findAll(); | |
} | |
// 搜索图书信息 ISBN | |
@GetMapping("/books/borrow/find/{isbn}") | |
public List<Borrow> findByIsbn(@PathVariable("isbn") String isbn){ | |
return borrowRepository.findByIsbn(isbn); | |
} | |
/** | |
* 归还图书 | |
* -1: 系统错误 | |
* 0: 归还失败 | |
* 1: 归还成功 | |
*/ | |
@DeleteMapping("/books/borrow/return/{id}") | |
public Object bookReturn(@PathVariable("id") int Id){ | |
JSONObject jsonObject = new JSONObject();; | |
Borrow borrow = borrowRepository.getById(Id); // 获取借阅信息 | |
List<Books> booksList = booksRepository.findByIsbn(borrow.getIsbn()); // 获取图书 | |
if(booksList.size() != 0){ | |
// 删除信息 | |
if(borrowRepository.existsById(Id)){ | |
borrowRepository.deleteById(Id); | |
Books books = booksList.get(0); // 获取图书信息 | |
books.setQuantity(books.getQuantity() + 1); // 图书数量加一 | |
booksRepository.save(books); | |
jsonObject.put("resultCode","1"); | |
} | |
else{ | |
jsonObject.put("resultCode","0"); | |
} | |
} | |
else{ | |
jsonObject.put("resultCode","-1"); | |
} | |
return jsonObject; | |
} |
# 归还图书是如何实现的?
获取借阅图书表的信息,点击按钮发送归还请求,后端搜索数据 ID,再用搜索出的 ISBN 号码再搜索图书表的书,归还成功后该书本数量加一
# 七、超时查询页面
# 前端
在 overtime.html 写入
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>图书管理系统</title> | |
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="/library/css/overtime.css"> | |
</head> | |
<body> | |
<div class="main"> | |
<div class="search-pane"> | |
<input type="text" name="search" id="search" placeholder="请输入搜索的内容"> | |
<button class="btn btn-primary search-button">搜索</button> | |
</div> | |
<table class="table table-hover"> | |
<thead> | |
<tr> | |
<th>Id</th> | |
<th>书名</th> | |
<th>ISBN号码</th> | |
<th>借阅人名字</th> | |
<th>借阅人卡号</th> | |
<th>借阅人手机号</th> | |
<th>借阅时间</th> | |
<th>归还时间</th> | |
<th>操作</th> | |
</tr> | |
</thead> | |
<tbody> | |
</tbody> | |
</table> | |
</div> | |
<!-- 模态框 --> | |
<div class="modal fade" id="return-modal"> | |
<div class="modal-dialog"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<h4 class="modal-title">归还图书</h4> | |
<button type="button" class="close" data-dismiss="modal">×</button> | |
</div> | |
<div class="modal-body"> | |
<p class="tip"></p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-danger return-button">归还</button> | |
<button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</body> | |
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script> | |
<script src="https://cdn.staticfile.org/popper.js/1.15.0/umd/popper.min.js"></script> | |
<script src="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script> | |
<script src="https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js"></script> | |
<script src="/library//js/config.js"></script> | |
<script src="/library/js/overtime.js"></script> | |
</html> |
在 overtime.css 写入
* { | |
margin: 0; | |
padding: 0; | |
outline: none; | |
} | |
html, | |
body, | |
.main { | |
width: 100%; | |
height: 100%; | |
} | |
/* 主页面样式 */ | |
.main { | |
display: flex; | |
flex-direction: column; | |
padding: 32px; | |
} | |
.search-pane { | |
display: flex; | |
justify-content: center; | |
width: 100%; | |
height: 32px; | |
margin-bottom: 16px; | |
} | |
.search-pane button { | |
margin-right: 32px; | |
padding: 0; | |
padding-left: 16px; | |
padding-right: 16px; | |
} | |
.search-pane #search { | |
width: 400px; | |
padding-left: 12px; | |
border: 1px solid #aaa; | |
border-radius: 4px; | |
} |
在 overtime.js 写入
$(function(){ | |
// 获取图书数据 | |
$.ajax({ | |
type: "get", // 请求方式 | |
url: ip + "/nav/books/overtime/find/0", // 请求地址 | |
dataType: "json", // 返回文件格式 | |
success:function(data){ | |
// 添加数据 | |
searchBook(data); | |
}, | |
error: function(data){ | |
alert("系统错误"); | |
} | |
}); | |
// 搜索图书 | |
var search_button = $('.search-button'); | |
var isbn = $('#search'); | |
$(search_button).click(function (e) { | |
e.preventDefault(); | |
$.ajax({ | |
type: "get", | |
url: ip + "/nav/books/overtime/find/" + isbn.val(), | |
dataType: "json", | |
success:function(data){ | |
$(".book").remove(); // 删除原来的书 | |
searchBook(data); // 搜索图书 | |
}, | |
error:function(data){ | |
alert("系统错误"); | |
} | |
}); | |
}); | |
// 归还图书 | |
$(document).on('click', '.return', function (e) { | |
e.preventDefault(); | |
$('.return-button').attr("name",$(this).attr("name")); // 设置 id | |
$('.tip').text("确定归还 " + $('#' + $(this).attr("name") + '>td[name="username"]').text() + " 的 " + $('#' + $(this).attr("name") + '>td[name="name"]').text() + " 书吗?"); | |
}); | |
$('.return-button').click(function (e){ | |
e.preventDefault(); | |
returnBook($(this).attr("name")); | |
}); | |
}); | |
// 显示图书信息函数 | |
function searchBook(data){ | |
for(var i = 0; i < data.length; i++){ | |
var text = "<tr id='" + data[i].id + "' class='book'>" + | |
"<td name='id'>" + data[i].id + "</td>" + | |
"<td name='name'>" + data[i].name + "</td>" + | |
"<td name='isbn'>" + data[i].isbn + "</td>" + | |
"<td name='username'>" + data[i].username + "</td>" + | |
"<td name='id_card'>" + data[i].id_card + "</td>" + | |
"<td name='phone'>" + data[i].phone + "</td>" + | |
"<td name='time'>" + data[i].time.substr(0,10) + "</td>" + | |
"<td name='r_time'>" + data[i].r_time.substr(0,10) + "</td>" + | |
"<td><button class='btn btn-warning btn-sm return' name='" + data[i].id + "' data-toggle='modal' data-target='#return-modal'>归还</button>" + | |
"</tr>"; | |
$("tbody").append(text); | |
} | |
} | |
// 归还书本函数 | |
function returnBook(id){ | |
$.ajax({ | |
type: "delete", | |
url: ip + "/nav/books/borrow/return/" + id, | |
dataType: "json", | |
success: function (data) { | |
if(data.resultCode == "-1"){ | |
alert("服务器错误"); | |
} | |
if(data.resultCode == "0"){ | |
alert("归还失败"); | |
} | |
if(data.resultCode == "1"){ | |
alert("归还成功"); | |
window.location.reload(); | |
} | |
}, | |
error: function (data){ | |
alert("错误"); | |
} | |
}); | |
} |
# 后端
在 BorrowHandler 写入
// 搜索超时信息 | |
@GetMapping("/books/overtime/find/{isbn}") | |
public List<Borrow> findOverTime(@PathVariable("isbn") String isbn) { | |
List<Borrow> oldBorrowList; | |
List<Borrow> borrowList = new ArrayList<>(); | |
TimeZone.setDefault(TimeZone.getTimeZone("GMT")); // 设置时区 | |
if(isbn.equals("0")){ | |
oldBorrowList = borrowRepository.findAll(); // 获取数据 | |
} | |
else{ | |
oldBorrowList = borrowRepository.findByIsbn(isbn); | |
} | |
// 判断表里有没有数据 | |
if(oldBorrowList.size() != 0){ | |
// 循环读取数据 | |
for (Borrow borrow : oldBorrowList) { | |
Calendar calendar = Calendar.getInstance(); | |
if(calendar.getTime().after(borrow.getR_time())){ | |
borrowList.add(borrow); // 添加超时归还的数据 | |
} | |
} | |
} | |
return borrowList; | |
} |
# 超时查询是如何实现的?
前端发送搜索请求,后端把表里的数据处理,超过归还时间的书就放到一个列表里然后返回,前端处理数据显示即可
# 八、用户管理页面
与图书管理页面是一模一样的,这里就不放出来了,在源码里有,想自己写的也可以试试
# 九、退出登录
# 前端
在 library.js 写入
// 退出系统 | |
$(".exit").click(function (e) { | |
var exit = $.removeCookie('username', { path: '/' }); | |
if(exit){ | |
window.location.replace("/index.html"); | |
alert("您已退出系统"); | |
} | |
else{ | |
alert("系统错误"); | |
} | |
}); |
# 用户的退出是如何实现的?
前端把 Cookie 删掉就退出了
# 总结与项目源码地址
源码下载地址
GitHub: Github
Gitee: Gitee
# Tooltip 小贴士
1.SpringBoot 热更新
Spring Boot 热更新 / 热部署
2.CSS3 display: flex 使用指南
CSS3 display: felx 使用指南
