基于Node.js+Vue+MySQL实现的(Web)图书管理系统

1 需求分析

本图书管理系统主要实现对图书馆的管理:图书、读者、管理员、借阅。由此,结构可分为:图书管理、读者管理、管理员管理、借还管理、罚单管理、还书信息。

1.1 需求定义

1.1.1 图书管理

可对图书信息进行浏览、编辑(包括对图书的修改、入库、删除)

  1. 浏览图书信息
  2. 编辑图书信息:修改、入库、删除

1.1.2 读者管理

可对读者信息进行浏览、编辑(包括对读者的修改、入库、删除)

  1. 浏览读者信息
  2. 编辑读者信息:修改、添加、删除

1.1.3 管理员管理

可对管理员信息进行浏览、编辑(包括对管理员的修改、入库、删除)

  1. 浏览管理员信息
  2. 编辑管理员信息:修改、添加、删除

1.1.4 借还管理

可对借书信息进行浏览;进行借书操作,每次只能进行一次操作,也可对新增借书进行删除;进行还书操作,如逾期欠费有提示,需要进行缴费操作,才能还书

  1. 浏览图书借书信息
  2. 借书(每次只能操作一次)-> 可对新增借书的删除
  3. 还书(逾期欠费需缴费才能还书)

1.1.5 罚单管理

可对罚单信息进行浏览;进行缴费操作;对已缴费的记录进行清理删除

  1. 浏览罚单信息
  2. 缴费
  3. 删除已缴费的记录

1.1.6 还书信息

可浏览还书信息

1.2 功能需求

  1. 图书的查阅、修改、删除、图书入库:编号、书名、作者、出版社、在库数、类别
  2. 读者的查询、修改、删除、新增读者:借书证号、姓名、班级、院系
  3. 管理员的查询、修改、删除、新增管理员:编号、姓名、负责书库
  4. 借还信息的查询、还书(逾期欠费需缴费才能还书)、新增借书:借书证号、读者名、编号、书名、借书日期、预计归还日期,可删除新增记录
  5. 罚单的查阅、缴费、删除(已缴费)
  6. 还书信息的查阅

图 1 图书管理系统功能图

2 概念结构设计

根据需求分析我们规划出实体有:读者信息实体、管理员信息实体、图书信息实体。各个实体具体的描述 E-R 实体如下。

2.1 读者信息模块

读者属性包括:借书证号、姓名、班级、院系

2.2 图书信息模块

图书属性包括:编号、书名、作者、出版社、在库数、类别

2.3 管理员信息模块

管理员属性包括:编号、姓名、负责书库

2.4 完整的 E-R 图

实体间的联系:

  1. 读者借书:拥有借书证号、图书编号、借出日期、应归还日期 属性
  2. 读者还书:拥有借书证号、图书编号、借出日期、应归还日期、归还日期、推迟天数、罚款总额 属性

3 逻辑结构设计

3.1 数据库逻辑设计

由 E-R 模型得到关系模型:借阅关系模型

3.3.1 借阅关系

属性:借书证号、图书编号、借出日期、应归还日期、归还日期、推迟天数、罚款总额

主键:借书证号、图书编号

3.2 数据库逻辑结构

  1. 图书信息表(属性:id(INT(11))、name(VARCHAR(20))、author(VARCHAR(20))、publisher(VARCHAR(20))、num(INT(11))、sort(VARCHAR(20)))
  2. 读者信息表(属性:id(INT(11))、name(VARCHAR(20))、class(VARCHAR(20))、department(VARCHAR(20)))
  3. 管理员信息表(属性:id(INT(11))、name(VARCHAR(20))、stackroom(VARCHAR(10)))
  4. 借书信息表(属性:bookId(INT(11))、readerId(INT(11))、borrow_date(DATE)、expect_rerurn_date(DATE))
  5. 罚单信息表(属性:bookId(INT(11))、readerId(INT(11))、over_date(INT)、ticket_fee(FLOAT)、payoff(INT))
  6. 还书信息表(属性:bookId(INT(11))、readerId(INT(11))、borrow_date(DATE)、rerurn_date(DATE))

3.2.1 图书信息表

4 物理设计

由上述数据库逻辑结构转换为实际数据模型,本图书管理系统的各个表如下:

4.1 建立图书馆数据库(library)

CREATE DATABASE library;

4.2 建立图书表(book)

CREATE TABLE `book` (
    `id` INT(11) NOT NULL DEFAULT '0',
    `name` VARCHAR(20) NOT NULL,
    `author` VARCHAR(20) NOT NULL,
    `publisher` VARCHAR(20) NOT NULL,
    `num` INT(11) NOT NULL,
    `sort` VARCHAR(20) NOT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
        ENGINE=InnoDB
               ;
desc book;

4.3 建立读者表(reader)

CREATE TABLE `reader` (
    `id` INT(11) NOT NULL DEFAULT '0',
    `name` VARCHAR(20) NOT NULL,
    `class` VARCHAR(10) NOT NULL,
    `department` VARCHAR(10) NOT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
        ENGINE=InnoDB
               ;
desc reader;

4.4 建立借阅表(borrow)

CREATE TABLE `borrow` (
    `bookId` INT(11) NOT NULL COMMENT '学生编号',
    `readerId` INT(11) NOT NULL COMMENT '图书编号',
    `borrow_date` DATE NULL DEFAULT NULL COMMENT '借书时间',
    `expect_return_date` DATE NULL DEFAULT NULL COMMENT '预期归还时间',
    PRIMARY KEY (`bookId`, `readerId`),
    INDEX `READERID` (`readerId`, `bookId`),
    CONSTRAINT `BOOKID` FOREIGN KEY (`bookId`) REFERENCES `book` (`id`),
    CONSTRAINT `READERID` FOREIGN KEY (`readerId`) REFERENCES `reader` (`id`)
)
COMMENT='存储学生的借书信息'
        COLLATE='latin1_swedish_ci'
                ENGINE=InnoDB
                       ;
desc borrow;

4.5 建立管理员表(administartors)

CREATE TABLE `administrators` (
    `id` INT(11) NOT NULL DEFAULT '0',
    `name` VARCHAR(20) NOT NULL,
    `stackroom` VARCHAR(10) NOT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
        ENGINE=InnoDB
               ;
desc administrators;

4.6 建立还书信息表(return_table)

CREATE TABLE `return_table` (
    `bookId` INT(11) NOT NULL,
    `readerId` INT(11) NOT NULL,
    `borrow_date` DATE NULL DEFAULT NULL,
    `return_date` DATE NULL DEFAULT NULL COMMENT '实际还书情况',
    PRIMARY KEY (`bookId`, `readerId`),
    INDEX `readerId` (`readerId`, `bookId`),
    CONSTRAINT `BOOKID_R` FOREIGN KEY (`bookId`) REFERENCES `book` (`id`),
    CONSTRAINT `READERID_R` FOREIGN KEY (`readerId`) REFERENCES `reader` (`id`)
)
COMMENT='存储学生的归还信息'
        COLLATE='latin1_swedish_ci'
                ENGINE=InnoDB
                       ;
desc return_table;

4.7 建立罚单信息表(ticket)

CREATE TABLE `ticket` (
    `readerId` INT(11) NOT NULL COMMENT '学生编号',
    `bookId` INT(11) NOT NULL COMMENT '书籍编号',
    `over_date` INT(11) NULL DEFAULT NULL COMMENT '超期天数',
    `ticket_fee` FLOAT NULL DEFAULT NULL COMMENT '处罚金额',
    `payoff` INT(11) NULL DEFAULT NULL,
    PRIMARY KEY (`readerId`, `bookId`),
    INDEX `BOOKID_T` (`bookId`),
    CONSTRAINT `BOOKID_T` FOREIGN KEY (`bookId`) REFERENCES `book` (`id`),
    CONSTRAINT `READERID_T` FOREIGN KEY (`readerId`) REFERENCES `reader` (`id`)
)
COMMENT='存储学生的罚单信息'
        COLLATE='latin1_swedish_ci'
                ENGINE=InnoDB
                       ;
desc ticket;

5 实施过程

5.1 装载数据过程

5.1.1 用 DML 语句对 book 表加入数据

INSERT INTO `library`.`book` (`id`, `name`, `author`, `publisher`, `num`, `sort`) VALUES ('8', '时事报告', '张习文', '时事报告杂志社', '1', '政治');
INSERT INTO `library`.`book` (`id`, `name`, `author`, `publisher`, `num`, `sort`) VALUES ('9', '计算机网络安全', '马利', '清华大学出版社', '1', '计算机');
select * from book;

5.1.2 用 DML 语句对 reader 表加入数据

INSERT INTO `library`.`reader` (`id`, `name`, `class`, `department`) VALUES ('6', '张三', '1603', '机器人学院');
INSERT INTO `library`.`reader` (`id`, `name`, `class`, `department`) VALUES ('7', '李四', '1602', '金融学院');
select * from reader;

5.1.3 用 DML 语句对 administartors 表加入数据

INSERT INTO `library`.`administrators` (`id`, `name`, `stackroom`) VALUES ('4', '王五', '外国文学');
INSERT INTO `library`.`administrators` (`id`, `name`, `stackroom`) VALUES ('5', '江六', '中国文学');
select * from administrators;

5.2 设计视图

5.2.1 在 reader,borrow 和 book 上创建借书者的全面信息视图 reader_borrow

create view reader_borrow as
select reader.id AS reader_id,reader.name AS reader_name,book.id AS book_id,book.name AS book_name,borrow_date,addDate(borrow_date,30) expect_return_date
from reader,book,borrow
where reader.id = borrow.readerId and book.id = borrow.bookId;

5.2.3 创建个人所有借书归还记录视图 reader_borrow_return

create view reader_borrow_return as
select reader.id AS reader_id,reader.name AS reader_name,book.id AS book_id,book.name AS book_name,return_date
from reader,book,return_table
where reader.id = return_table.readerId and book.id = return_table.bookId;

5.3 存储过程设计

5.3.1 产生罚单 proc_gen_ticket

当日期超过预定归还日期,产生罚单,并将记录写入表 ticket 中,这个存储过程在定时器 eventJob 中调用

CREATE DEFINER=`root`@`%` PROCEDURE `proc_gen_ticket`(
                   IN `currentdate` date
               )
               BEGIN
               replace into ticket(readerId,bookId,over_date,ticket_fee,payoff)
               SELECT reader_id,book_id,dateDiff(currentdate,reader_borrow.expect_return_date),0.1*datediff(currentdate,reader_borrow.expect_return_date),1
               FROM reader_borrow
               WHERE currentdate>reader_borrow.expect_return_date;
END

5.3.2 借书过程实现

1)设计存储函数,func_get_booknum,返回书籍是否在架上

CREATE DEFINER=`root`@`%` FUNCTION `func_get_booknum`(
                   `book_id` INT
               )
               RETURNS int(11)
               BEGIN
               return(select num from book where book.id=book_id);
END

2)设计存储过程 proc_borrow,调用 func_get_booknum,判断书籍是否在架上,若为真,则借书成功,在 borrow 表中插入记录;否则提示失败

CREATE DEFINER=`root`@`%` PROCEDURE `proc_borrow`(
                   IN `reader_id` INT,
                   IN `book_id` INT,
                   IN `borrow_date` DATE,
                   IN `expect_return_date` DATE
               )
               BEGIN
               if func_get_booknum(book_id) > 0 then
                   insert into borrow(readerId,bookId,borrow_date,expect_return_date)
                   values(reader_id,book_id,borrow_date,expect_return_date);
else
    select -1 as msg;
end if;
END

目前 borrow 记录如下

执行函数,读者 0001 借图书 0002

call proc_borrow('0001','0002',CURDATE());

执行函数,读者 0002 借图书 0002

call proc_borrow('0002','0002',CURDATE());

5.3.3 还书存储过程 proc_return

还书时,查看是否超期,即查询 ticket 表项,当发现超期,提示交罚单后再还书;如未超期,则记录归还项目到 return_table 中,并且删除借书记录(以免还书后定时器仍然扫描这个记录)

CREATE DEFINER=`root`@`%` PROCEDURE `proc_return`(
                   IN `reader_id` INT(11),
                   IN `book_id` INT(11),
                   IN `return_date` DATE
               )
               BEGIN
               declare borrowdate date;
if(select payoff from ticket where ticket.readerId = reader_id and ticket.bookId = book_id) = 1 then
            select -1 as msg;
else if(select count(*) from return_table where return_table.readerId = reader_id and return_table.bookId = book_id ) > 0 then
    DELETE FROM return_table WHERE readerId = reader_id;
set borrowdate = (select borrow_date from borrow where borrow.readerId = reader_id and borrow.bookId = book_id);
insert into return_table(readerId,bookId,borrow_date,return_date)
values(reader_id,book_id,borrowdate,return_date);
delete from borrow
where borrow.readerId = reader_id and borrow.bookId = book_id;
else
    set borrowdate = (select borrow_date from borrow where borrow.readerId = reader_id and borrow.bookId = book_id);
insert into return_table(readerId,bookId,borrow_date,return_date)
values(reader_id,book_id,borrowdate,return_date);
delete from borrow
where borrow.readerId = reader_id and borrow.bookId = book_id;
end if;
end if;
END

读者 0001 借了 0001 图书,超期产生了罚单

call proc_return('0001','0001',CURDATE());

交罚单

call proc_payoff('0001','0001');

再次还书

5.3.4 交罚单存储过程 proc_payoff

修改罚单中 payoff 段为 0,表明罚单已交

CREATE DEFINER=`root`@`%` PROCEDURE `proc_payoff`(
                   IN `reader_id` INT,
                   IN `book_id` INT
               )
               BEGIN
               update ticket
               set ticket.payoff = 0
                                   where ticket.readerId = reader_id and ticket.bookId = book_id;
select 'succeed';
END

5.3.5 删除图书存储过程 proc_deleteBook

删除图书时,除了 book 表,还要把关联表 return_table 对应的书也删掉

CREATE DEFINER=`root`@`%` PROCEDURE `proc_deleteBook`(
                   IN `book_id` INT
               )
               BEGIN
               DELETE FROM return_table WHERE return_table.bookId = book_id;
DELETE FROM book WHERE book.id = book_id;
END

5.4 触发器设计

5.4.1 设计触发器 borrow_after_insert

当某学生借书成功后,图书表相应的图书不在架上,变为 0;

CREATE TRIGGER `borrow_after_insert` AFTER INSERT ON `borrow` FOR EACH ROW BEGIN
update book set num = num-1 where id = new.bookId;
END

在插入表 borrow 之前,id=0003 的图书还在架上,为 1

学生 0001 借了这本书后,在 boorow 中插入记录

在 borrow 中插入这条记录后,id=0003 的图书,不在架上,为 0

5.4.2 设计触发器 return_after_insert

还书成功后,对应的书籍 num 变为 1

CREATE TRIGGER `return_after_insert` AFTER INSERT ON `return` FOR EACH ROW BEGIN
        update book set num = num+1 where id = new.bookId;
END

还书时在 return_table 插入

此时图书归还架上

5.4.3 定义定时器(事件)eventJob

每天自动触发一次,扫描视图 reader_borrow,若发现当前有预期归还时间小于当前时间,则判断为超期,生成处罚记录,这个定时器将每天定时触发存储过程 proc_gen_ticket

CREATE EVENT `eventJob`
ON SCHEDULE
EVERY 1 DAY STARTS '2018-08-01 16:22:42'
ON COMPLETION PRESERVE
ENABLE
COMMENT ''
DO call proc_gen_ticket(CURDATE())

读者 0003 借了图书 0001,生成借书记录 reader_borrow 视图

当他在 1 月 9 日前还书,没有生成罚单

当他在 1 月 9 日后还书,生成罚单

6 系统实现

6.1 搭建前端框架

6.1.1 搭建 vue-cli 脚手架

本系统使用 VUE 编写,所以需要搭建脚手架,使系统达到:提高效率、组件化、模块化、数据双向绑定的优秀特性

// 在项目的根目录下
npm install vue-cli -g
vue init webpack web-lib
cd web-lib
npm install
npm run dev

6.1.2 引入 axious、element 库

因为有很多 http 请求,使用 axious 库,可以更方便的书写请求,并且易于管理;对于一个后台系统,其 ui 适合使用简洁的风格,element-ui 即可满足

// 引入 aixos
npm i aixos vue-axios -s

在入口文件 main.js 里面加入

import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios);
// 引入 elment-ui
npm i element-ui -S

在入口文件 main.js 里面加入

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

6.2 使用 NodeJs 建立本地服务器

使用 NodeJs 开发系统中间层接口,直接从 MySQL 获取数据并通过 express 制作数据获取接口

// 在项目的根目录中
"use strict";
/* 引入express框架 */
const express = require('express');
const app = express();
/* 引入cors */
const cors = require('cors');
app.use(cors());
/* 引入body-parser */
const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
/* 引入mysql */
const mysql = require('mysql');
const conn = mysql.createConnection({
host     : '47.101.130.10',
user     : 'root',
password : '1998WEI.',
database : 'library',
multipleStatements: true
})
conn.connect();
/* 监听端口 */
app.listen(4444, () => {
    console.log('——————————服务已启动——————————');
})
app.get('/', (req, res) => {
    res.send('<p style="color:red">服务已启动</p>');
})

6.3 图书管理-页面

6.3.1 功能介绍

1)导航:/book

2)显示功能:展示图书信息

3)编辑功能:进入图书编辑界面,可对图书进行修改、删除、入库,操作成功/失败会有相应提示。

注 1:修改、入库后需要点击完成,才能算操作完成

注 2:编辑在库数,已限制只能键入数字

注 3:记录均不可为空,完成提交时会检查,如为空,会提示,且无法提交

6.3.2 接口设计

// 书本列表
app.get('/api/getBooks', (req, res) => {
    const sqlStr = 'SELECT * FROM book'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 更新书本列表
app.post('/api/updateBook',(req,res) => {
    let str = ''
    for(var key in req.body) {
        str += key + ' = "' + req.body[key] + '",'
    }
    str = str.substr(0, str.length-1);
    const sqlStr = 'UPDATE book SET ' + str + ' WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 添加书本
app.post('/api/addBook',(req,res) => {
    let str1 = '', str2 = ''
    for(var key in req.body) {
        str1 += key + ','
                str2 += req.body[key] + ','
    }
    str1 = str1.substr(0, str1.length-1);
    str2 = '"' + str2.substr(0, str2.length-2);
    const sqlStr = 'INSERT INTO book (' + str1 + ')' + ' VALUES (' + str2 + ')'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 删除书本
app.post('/api/delectBook',(req,res) => {
    const sqlStr = 'DELETE FROM book WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})

6.4 读者管理-页面

6.4.1 功能介绍

1)导航:/user

2)显示功能:展示读者信息

3)编辑功能:进入读者编辑界面,可对读者进行修改、删除、新增,操作成功/失败会有相应提示。

注 1:修改、新增后需要点击完成,才能算操作完成

注 2:编辑班级,已限制只能键入数字

注 3:记录均不可为空,完成提交时会检查,如为空,会提示,且无法提交

6.4.2 接口设计

// 显示用户列表
app.get('/api/getUsers', (req, res) => {
    const sqlStr = 'SELECT * FROM reader'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 更新用户列表
app.post('/api/updateUser',(req,res) => {
    let str = ''
    for(var key in req.body) {
        str += key + ' = "' + req.body[key] + '",'
    }
    str = str.substr(0, str.length-1);
    const sqlStr = 'UPDATE reader SET ' + str + ' WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 添加用户
app.post('/api/addUser',(req,res) => {
    let str1 = '', str2 = ''
    for(var key in req.body) {
        str1 += key + ','
                str2 += req.body[key] + '","'
    }
    str1 = str1.substr(0, str1.length-1);
    str2 = '"' + str2.substr(0, str2.length-2);
    const sqlStr = 'INSERT INTO reader (' + str1 + ')' + ' VALUES (' + str2 + ')'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 删除用户
app.post('/api/delectUser',(req,res) => {
    const sqlStr = 'DELETE FROM reader WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})

6.5 管理员管理-页面

6.5.1 功能介绍

1)导航:/admin

2)显示功能:展示管理员信息

3)编辑功能:进入管理员编辑界面,可对管理员进行修改、删除、新增,操作成功/失败会有相应提示。

注 1:修改、新增后需要点击完成,才能算操作完成

注 2:记录均不可为空,完成提交时会检查,如为空,会提示,且无法提交

6.5.2 接口设计

// 显示管理员列表
app.get('/api/getAdmin', (req, res) => {
    const sqlStr = 'SELECT * FROM administrators'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 更新管理员列表
app.post('/api/updateAdmin',(req,res) => {
    let str = ''
    for(var key in req.body) {
        str += key + ' = "' + req.body[key] + '",'
    }
    str = str.substr(0, str.length-1);
    const sqlStr = 'UPDATE administrators SET ' + str + ' WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 添加管理员
app.post('/api/addAdmin',(req,res) => {
    let str1 = '', str2 = ''
    for(var key in req.body) {
        str1 += key + ','
                str2 += req.body[key] + '","'
    }
    str1 = str1.substr(0, str1.length-1);
    str2 = '"' + str2.substr(0, str2.length-2);
    const sqlStr = 'INSERT INTO administrators (' + str1 + ')' + ' VALUES (' + str2 + ')'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 删除管理员
app.post('/api/delectAdmin',(req,res) => {
    const sqlStr = 'DELETE FROM administrators WHERE id = ' + req.body.id
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})

6.6 借还管理-页面

6.6.1 功能介绍

1)导航:/borrow

2)显示功能:展示借还信息

3)借书功能:新增借书记录,点击确认即完成操作;可按删除,取消操作

注 1:记录均不可为空,完成提交时会检查,如为空,会提示,且无法提交

注 2:读者名,书名采取下拉框的形式,选择完毕,唯一标识符借书证号、编号会自动填上

注 3:每次只能进行一次借书操作,请完成新增操作再进行下面的操作

注 4:每次借书,图书中的在库数会减少,为 0 的,无法借阅

4)还书功能:进行还书;如超过预计归还日期,产生罚单,需要到 罚单管理 进行缴费,才能进行归还

注:还书后,相应图书的在库数会增加

6.6.2 接口设计

// 显示借书列表
app.get('/api/getBorrow', (req, res) => {
    const sqlStr = 'SELECT * FROM reader_borrow'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 获取 借书证号 列表
app.get('/api/getUserId', (req, res) => {
    const sqlStr = 'SELECT id,name FROM reader'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 获取 编号 列表
app.get('/api/getBookId', (req, res) => {
    const sqlStr = 'SELECT id,name FROM book'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 借书
app.post('/api/borrowBook',(req,res) => {
    const sqlStr = 'call proc_borrow("' + req.body.reader_id + '","' + req.body.book_id + '","' + req.body.borrow_date + '","' + req.body.expect_return_date + '")'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 还书
app.post('/api/returnBook',(req,res) => {
    const sqlStr = 'call proc_return("' + req.body.readerId + '","' + req.body.bookId + '","' + req.body.curDate + '")'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})

6.7 罚单管理-页面

6.7.1 功能介绍

1)导航:/ticket

2)显示功能:展示罚单信息,依据 是否欠费 进行排序,欠费记录为 1,已缴费记录为 0;可对已缴费的记录进行删除

注:系统每天会对借还列表进行查看,超过逾期,产生罚单

3)缴费功能:对欠费的记录进行缴费,之后可以归还书籍

6.7.2 接口设计

// 显示欠费列表
app.get('/api/getTicket', (req, res) => {
    const sqlStr = 'SELECT * FROM reader_ticket'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})
// 缴费
app.post('/api/payTicket',(req,res) => {
    const sqlStr = 'call proc_payoff("' + req.body.readerId + '","' + req.body.bookId + '")'
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})
// 删除已缴的欠费单
app.post('/api/delectTicket',(req,res) => {
    const sqlStr = 'DELETE FROM ticket WHERE readerId = ' + req.body.readerId + ' AND bookId = ' + req.body.bookId
    conn.query(sqlStr, (err,results) => {
        if(err) return res.json({ code: -1, message: err })
                           res.json({ code: 10000, data: results })
        })
})

6.8 还书信息-页面

6.8.1 功能介绍

1)导航:/return

2)显示功能:展示还书信息

6.8.2 接口设计

// 显示还书列表
app.get('/api/getReturn', (req, res) => {
    const sqlStr = 'SELECT * FROM reader_borrow_return'
    conn.query(sqlStr, (error, results) => {
        if (error) return res.json({ code: -1, message: error})
                              res.json({ code: 10000, data: results})
        })
})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络803-(5)运输层

目录 一.运输层的两个主要协议&#xff1a;TCP 与 UDP 1.TCP/IP 的运输层有两个不同的协议&#xff1a; 2.端口号(protocol port number) &#xff08;1&#xff09;软件端口与硬件端口 &#xff08;2&#xff09;TCP 的端口 &#xff08;3&#xff09;三类端口 二.用户…

机器学习之fetch_olivetti_faces人脸识别--基于Python实现

fetch_olivetti_faces 数据集下载 fetch_olivetti_faceshttps://github.com/jikechao/olivettifaces sklearn.datasets.fetch_olivetti_faces(*, data_homeNone, shuffleFalse, random_state0, download_if_missingTrue, return_X_yFalse, n_retries3, delay1.0)[source] L…

嵌入式硬件电子电路设计(三)电源电路之负电源

引言&#xff1a;在对信号线性度放大要求非常高的应用需要使用双电源运放&#xff0c;比如高精度测量仪器、仪表等;那么就需要给双电源运放提供正负电源。 目录 负电源电路原理 负电源的作用 如何产生负电源 负电源能作功吗&#xff1f; 地的理解 负电压产生电路 BUCK电…

【SpringMVC】传递json,获取url参数,上传文件

【传递json数据】 【json概念】 一种轻量级数据交互格式&#xff0c;有自己的格式和语法&#xff0c;使用文本表示一个对象或数组的信息&#xff0c;其本质上是字符串&#xff0c;负责在不同的语言中数据传递与交换 json数据以字符串的形式体现 【json字符串与Java对象互转…

web3.0 开发实践

优质博文&#xff1a;IT-BLOG-CN 一、简介 Web3.0也称为去中心化网络&#xff0c;是对互联网未来演进的一种概念性描述。它代表着对现有互联网的下一代版本的设想和期望。Web3.0的目标是通过整合区块链技术、分布式系统和加密技术等新兴技术&#xff0c;构建一个更加去中心化…

10.31.2024刷华为OD C题型

文章目录 HJ26HJ27语法知识记录 10.24.2024刷华为OD C题型&#xff08;四) - HJ26 HJ27 def get_dict(str1: str):dic_0 {}for ch in str1:if ch not in dic_0:dic_0[ch] 1else:dic_0[ch] 1return dic_0temp input().split() n int(temp[0]) list [] for i in range(n):l…

客户服务数据分析:洞察客户需求,优化服务策略

在数字经济时代&#xff0c;数据已成为企业决策的重要依据。特别是在客户服务领域&#xff0c;通过深度挖掘和分析客户服务数据&#xff0c;企业能够更精准地洞察客户需求&#xff0c;优化服务策略&#xff0c;从而提升客户满意度和忠诚度&#xff0c;增强市场竞争力。 一、客户…

【SQL】 Navicate 17 连接sql server

一直连接不上&#xff0c;找了好多博客&#xff0c;最后发现是端口号的字符串有问题 [08001] [Microsoft][ODBC Driver 17 for SQL Server]SQL Server Network Interfaces: Connection string is not valid [87]. (87) [HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Lo…

低至599元的N100办公神器,节能静音还双网口,區克MAX N迷你主机深度拆解与评测

低至599元的N100办公神器&#xff0c;节能静音还双网口&#xff0c;區克MAX N迷你主机深度拆解与评测 哈喽小伙伴们好&#xff0c;我是Stark-C~ 最近有小伙伴找到我想我咨询&#xff0c;想要一个日常使用&#xff0c;主打办公&#xff0c;闲暇之余刷刷视频看看剧的小主机&…

CSS--导航栏案例

利用CSS制作北大官网导航栏 详细代码如下&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>*{margin: 0;padding: 0;}#menu{background-color: darkred;width: 100%;height: 50px…

详细分析Pytorch中的transpose基本知识(附Demo)| 对比 permute

目录 前言1. 基本知识2. Demo 前言 原先的permute推荐阅读&#xff1a;详细分析Pytorch中的permute基本知识&#xff08;附Demo&#xff09; 1. 基本知识 transpose 是 PyTorch 中用于交换张量维度的函数&#xff0c;特别是用于二维张量&#xff08;矩阵&#xff09;的转置操…

2024年11月1日Day2第一部分(最详细简单有趣味的介绍2

1.CRC编解码练习 要计算CRC&#xff08;循环冗余校验&#xff09;码并验证及纠正接收到的数据&#xff0c;我们需要按照以下步骤进行&#xff1a; 步骤 1: 计算CRC校验码 信息字段代码: x1001生成多项式: G(x)x3x21&#xff0c;即 G(x)1101&#xff08;注意&#xff1a;这里…

【Kaggle | Pandas】练习5:数据类型和缺失值

文章目录 1. 获取列数据类型.dtype / .dypes2. 转换数据类型.astype()3. 获取数据为空的列 .isnull()4. 将缺少值替换并且排序.fillna()&#xff0c;.sort_values() 1. 获取列数据类型.dtype / .dypes 数据集中points列的数据类型是什么&#xff1f; # Your code here dtype …

使用Docker Swarm进行集群管理

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Docker Swarm进行集群管理 Docker Swarm简介 安装Docker 在Ubuntu上安装Docker 在CentOS上安装Docker 初始化Docker Swarm …

前端获取csv或者excel 静态数据并使用

这里我将空格全部替换成了 || 好让我变成数组&#xff0c;从而拿到每一条数据中的第一项&#xff0c;相当于excel或者csv文件的第一列的东西 axios.get("/csv/zhongxiang").then((res) > {let rows res.data.split("\n");for (let row of rows) {let c…

JavaWeb——Web入门(3/9)-HTTP协议:概述(概念、特点,HTTP协议定义,基于 TCP 协议,基于请求-响应模型)

目录 概念 特点 内容预告 概念 HTTP 协议定义&#xff1a;全称 Hyper Text Transfer Protocol&#xff0c;即超文本传输协议&#xff0c;规定了浏览器与服务器之间数据传输的规则&#xff0c;具体指客户端浏览器与服务器之间进行数据交互的数据格式。 在互联网的世界中&…

导致线上项目宕机的原因和排查手段

目录 导致线上项目宕机的原因cpu过载cpu过载怎么排查?内存溢出内存溢出怎么排查?磁盘空间不足磁盘空间不足怎么排查?网络问题网络问题怎么排查?垃圾回收(GC)问题垃圾回收(GC)问题怎么排查JVM参数配置不当JVM参数配置不当怎么排查?JVM内部错误JVM内部错误怎么排查?线程…

strace 调试追踪案例:对程序打开文件进行追踪

声明 本文版权属于笔者朋友 YangHui &#xff0c;所有资料内容均由 YangHui 提供&#xff0c;笔者只是一个转述者。 文章目录 声明1. 前言2. 问题的发生、跟踪、解决3. 小结 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#x…

(九)JavaWeb后端开发3——Servlet

目录 1.Servlet由来 2.Servlet快速入门 3.Servlet执行原理 4.Servlet生命周期 1.Servlet由来 在JaveEE API文档中对Servlet的描述是&#xff1a;可以运行在服务器端的微小程序&#xff0c;但是实际上&#xff0c;Servlet就是一个接口&#xff0c;定义了Java类被浏览器访问…

ZooKeeper 客户端API操作

文章目录 一、节点信息1、创建节点2、获取子节点并监听节点变化3、判断节点是否存在4、客户端向服务端写入数据写入请求直接发给 Leader 节点写入请求直接发给 follow 节点 二、服务器动态上下线监听1、监听过程2、代码 三、分布式锁1、什么是分布式锁?2、Curator 框架实现分布…