章节目录

  • 前言
  • 已知BUG
  • 什么是MVC模式?
  • 零、项目图片
  • 登录页面
  • 图书管理页面
  • 借阅图书页面
  • 归还图书页面
  • 超时查询页面
  • 用户管理页面
  • 一、项目结构
  • 二、从0到1 (0 -> 1)
  • 1.首先是
  • 2.数据库设置
  • 3.创建SpringBoot项目
  • 4.配置数据库连接文件
  • 三、登录页面
  • 1.前端
  • 2.后端
  • 3.登录是如何实现的?
  • 四、图书管理页面
  • #.判断用户登录状态
  • 1.前端
  • 1.显示图书数据
  • 2.搜索图书
  • 3.添加图书
  • 4.编辑图书
  • 5.删除图书
  • 2.后端
  • 1.获取图书
  • 2.搜索图书
  • 3.添加图书
  • 4.编辑图书
  • 5.删除图书
  • 3.页面是如何与数据库交互的?
  • 1.获取图书数据
  • 2.搜托图书
  • 3.添加图书
  • 4.编辑图书
  • 5.删除图书
  • 五、借阅图书页面
  • 1.前端
  • 2.后端
  • 3.借阅图书是如何实现的?
  • 六、归还图书页面
  • 1.前端
  • 2.后端
  • 3.归还图书是如何实现的?
  • 七、超时查询页面
  • 1.前端
  • 2.后端
  • 3.超时查询是如何实现的?
  • 八、用户管理页面
  • 九、退出登录
  • 1.前端
  • 2.用户的退出是如何实现的?
  • 总结与项目源码地址
  • # Tooltip 小贴士



前言

在此次教程中,我会教大家如何写一套前后端分离图书管理系统:

前端技术栈:
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模式?

基于html5 基于html5的图书馆管理系统_html5

引用runoob对MVC的介绍 源地址


零、项目图片

登录页面

基于html5 基于html5的图书馆管理系统_html5_02

图书管理页面

基于html5 基于html5的图书馆管理系统_html5_03

借阅图书页面

基于html5 基于html5的图书馆管理系统_html5_04

归还图书页面

基于html5 基于html5的图书馆管理系统_intellij-idea_05

超时查询页面

基于html5 基于html5的图书馆管理系统_intellij-idea_06

用户管理页面

基于html5 基于html5的图书馆管理系统_java_07

一、项目结构

基于html5 基于html5的图书馆管理系统_intellij-idea_08

基于html5 基于html5的图书馆管理系统_spring boot_09

基于html5 基于html5的图书馆管理系统_基于html5_10

二、从0到1 (0 -> 1)

1.首先是

选择一个合适的硬盘创建自己的项目文件夹,在项目文件夹里创建HTML5和SpringBoot文件夹

基于html5 基于html5的图书馆管理系统_java_11


HTML5文件夹用于存放前端显示页面

SpringBoot文件夹用于存放后端服务器代码

以上两个文件夹也可以按照自己喜欢的名字来进行创建,本篇教程之后会以这两个文件夹创建文件,请注意自己的文件存放位置

2.数据库设置

首先创建 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

3.创建SpringBoot项目

新建一个项目

基于html5 基于html5的图书馆管理系统_java_12


选择Spring Initializr项目

基于html5 基于html5的图书馆管理系统_intellij-idea_13


设置以下信息

基于html5 基于html5的图书馆管理系统_intellij-idea_14


Group:组名

一般格式为 com.公司名.项目名.模块名 没有公司名就用自己的名字

Artifact:工程名

Type:项目类型

Language:使用语言

Packaging:包装类型

Java Version:JDK版本

Version:项目版本

Name:项目名

Description:项目描述

Package:包选择Spring要添加的组件

Lombok

基于html5 基于html5的图书馆管理系统_spring boot_15


Spring Web

基于html5 基于html5的图书馆管理系统_intellij-idea_16


Spring Data JPA 和 MySQL Driver

基于html5 基于html5的图书馆管理系统_java_17


选择刚才创建的SpringBoot文件夹

基于html5 基于html5的图书馆管理系统_基于html5_18


在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>

基于html5 基于html5的图书馆管理系统_html5_19

构建过程中最好使用代理构建项目

如果您的项目构建失败,您可以通过下面的链接下载我已经构建好的项目来开发

项目链接 提取码: 77tr

4.配置数据库连接文件

先删除src下的application.properties文件

基于html5 基于html5的图书馆管理系统_html5_20


在这里我用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项目

三、登录页面

1.前端

创建完成后,就可以开始写第一个页面
在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("系统错误");
                }
            });
        }
    });
});

2.后端

现在,登录页面就已经制作完成,现在开始制作后端登录模型

在SpringBoot项目中创建以下包与文件

基于html5 基于html5的图书馆管理系统_java_21


包:

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> {
}

基于html5 基于html5的图书馆管理系统_java_22


运行一下SpringBoot然后打开之前写的登录页面就能食用了

最后,在library文件夹下新建一个library.html登录页面就制作完成了

是不是很简单呢?

当然,使用Cookie的方式存储用户登录是不安全的行为

3.登录是如何实现的?

首先是从View视图页面获取用户输入的表单信息,点击表单按钮后,表单信息利用Controller把信息传送 到后端的Model里,然后这些信息在Model里进行数据处理,数据处理完之后,再从后端的Model里面,返回一个json文件给Controller,然后Controller接收到Model的json返回文件,就去处理json文件里的信息,然后用View展示处理后的界面。

基于html5 基于html5的图书馆管理系统_intellij-idea_23

四、图书管理页面

弄好了登录页面后,登录成功将会切到图书管理页面
要做的工作:
#.判断用户登录状态
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");
    }
});

这样就可以简易的实现判断用户是否处于登录状态
如果登录了,就可以访问当前页面,如果没有登录,则跳回登录页面让用户进行登录操作

1.前端

1.显示图书数据

这个是普遍后台的UI界面 (至少是我认为的

基于html5 基于html5的图书馆管理系统_java_24


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);
    }
});

至此,我们就创建好了前端的图书管理页面

基于html5 基于html5的图书馆管理系统_spring boot_25

现在这个图书页面也只是一个静态页面,那怎么让他动起来呢?
首先我们要知道,后台页面有些内容是不会经常进行变动,比如侧边的导航栏,顶部的用户栏,经常改变的内容是信息面板这一块,为了减少代码沉余,在后台页面我将添加一个iframe框架动态刷新信息内容,静态更改url就能访问其他页面,导航栏和用户栏相对也不会进行变化。

现在把导航栏需要的页面都给创建出来

library 文件夹创建下面的文件

后台 -> library.html

图书管理 -> books.html

借阅图书 -> borrow.html

归还图书 -> return.html

超时查询 -> overtime.html

用户管理 -> users.html

基于html5 基于html5的图书馆管理系统_java_26


然后再给每一个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("系统错误");
        }
    });
});

2.搜索图书

添加一个新的请求,接收返回的数据,处理一下即可,更改 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);
    }
}

3.添加图书

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("错误");
            }
        });
    }
}

4.编辑图书

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("错误")
            }
        });
    }
}

5.删除图书

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("错误");
        }
    });
}

2.后端

1.获取图书

在SpringBoot项目创建

基于html5 基于html5的图书馆管理系统_java_27

类:
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> {
}

2.搜索图书

BooksHandler 里添加

//搜索单本图书
@GetMapping("/books/find")
public List<Books> findByNameLike(String book){
    return booksRepository.findByNameLike("%" + book + "%");
}

BooksRepository 里添加

List<Books> findByNameLike(String book);

3.添加图书

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);

4.编辑图书

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;
}

5.删除图书

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;
}

3.页面是如何与数据库交互的?

基于html5 基于html5的图书馆管理系统_intellij-idea_28

1.获取图书数据

前端通过调用Ajax发送一个get请求到服务端,然后服务端返回一组json数据给Web前端,用JavaScript对json数据进行处理,然后将处理好的数据展示到Web前端

2.搜托图书

与上面方法类似,多添加了一个book的参数,作为查询的书名,后端接收到请求去查询数据库有没有该本书,有则返回书本信息,没有则返回空

3.添加图书

前端发送一个带表单信息post请求到服务端,然后由服务器检测这本书是否存在,如果存在则返回添加失败的Code,如果不存在则发返回添加成功的Code,如果服务器添加书本不成功则返回异常的Code

4.编辑图书

前端先发送一个请求获取该本书的信息 ,然后修改数据后再向服务器发送修改请求,服务器检测id和isbn号码,如果isbn没有变动可以直接修改,如果修改的isbn在数据库里没有则可以直接修改,如果修改新的isbn在数据库中存在,则判断原来的id与数据库搜索出来的isbn图书id是否一致,不一致则修改失败

5.删除图书

前端发送一个带id的删除请求,服务器接受删除请求,判断id是否在数据库中,如果存在就删除,不存在就不删除

五、借阅图书页面

1.前端

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("请先选择书籍!");
        }
    });
});

2.后端

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;
}

3.借阅图书是如何实现的?

前端先发送一个搜索图书的请求,查询这本书是否存在,然后显示图书的信息,然后再填写好借阅人的信息,后端判断借阅人信息是否存在,若都存在,借阅图书成功

六、归还图书页面

1.前端

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("错误");
        }
    });
}

2.后端

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;
}

3.归还图书是如何实现的?

获取借阅图书表的信息,点击按钮发送归还请求,后端搜索数据ID,再用搜索出的ISBN号码再搜索图书表的书,归还成功后该书本数量加一

七、超时查询页面

1.前端

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("错误");
        }
    });
}

2.后端

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;
}

3.超时查询是如何实现的?

前端发送搜索请求,后端把表里的数据处理,超过归还时间的书就放到一个列表里然后返回,前端处理数据显示即可

八、用户管理页面

与图书管理页面是一模一样的,这里就不放出来了,在源码里有,想自己写的也可以试试

九、退出登录

1.前端

library.js写入

//退出系统
$(".exit").click(function (e) { 
    var exit = $.removeCookie('username', { path: '/' });
    if(exit){
        window.location.replace("/index.html");
        alert("您已退出系统");
    }
    else{
        alert("系统错误");
    }
});

2.用户的退出是如何实现的?

前端把Cookie删掉就退出了