# library-system **Repository Path**: wu-yani/library-system ## Basic Information - **Project Name**: library-system - **Description**: 图书借阅系统(前)与图书管理系统(后) - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2021-08-23 - **Last Updated**: 2021-08-23 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 图书管理系统 ## 数据库设计 ### 用户表(user) ``` id 用户id,主键 username 用户名 非空 password 用户密码 默认123456 status 用户状态,1表示正常,0表示停用,默认1 sex 用户性别 citizenid 身份证号码 studentname 学生姓名 非空 ``` ### 图书表(book) ``` id 图书id bookname 图书名称 非空 stock 库存 默认1 writer 作者 默认未知 category 图书类目 organ 出版社 price 价格 ``` ### 图书流通表(reg_book) 归还后将是否归还设为1。 ``` id 主键id time 发生时间 status 1表示已归还,0表示未归还,默认未归还 endtime 归还时间 userid 用户id bookid 图书id ``` ### 管理员表(admin) ``` id 管理员id name 账号 password 密码 level 级别,级别1为超级管理员,可操作管理员。级别2为普通管理员,不可操作管理员 ``` ### 菜单表(menu) ``` id 主键id menuid 所属菜单,1代表book,2代表user,3代表图书流向表 name 表头,显示在表格头部 menuname 对应的表头,用于查询 ``` ### 用户订单表(form) ``` id 主键id bookid 图书ID userid 用户ID buyTime 订单时间 status 订单是否完成 ``` ## 后端技术 | 技术 | 描述 | | ---------------- | ------------ | | spring-framework | IOC容器 | | SpringMVC | MVC框架 | | MyBatis | ORM框架 | | Druid | 数据库连接池 | | MyBatisGenerator | 持久层代码 | ## 前端技术 | 技术 | 描述 | | --------- | -------------------------------------- | | Bootstrap | 响应式前端框架,可在多端部署。模态窗口 | | JQuery | 操作DOM | | Echarts | 图表框架,数据可视化 | | AJAX | 发起请求 | ## 开发环境 | 工具 | 版本号 | | ------ | ------ | | JDK | 11 | | MySQL | 8.0.19 | | tomcat | 8.x | ## 开发工具 | 工具 | 描述 | | ------------- | -------------- | | IntelliJ IDEA | IDE开发工具 | | workbench | 数据库连接工具 | ## 门户网站功能 ### 登录功能 1、跳转注册页面 当用户访问默认地址时,自动将请求转发到`door` ```java @GetMapping("") public String index() { return "door"; } ``` `door`请求内容: 参数为:`HttpSession`,session作用域,用于验证用户登录的状态。 `Model`,视图中的数据,当响应视图时,该视图包含的数据内容。 `User user = (User) session.getAttribute("user");` 获取session作用域中的`user`,判断该内容是否为空,如果为空则说明用户并未登录,如果不为空,说明用户已经登录。 如果不为空,才会去请求数据库,并会返回书籍数据和导航条数据给视图。 ```java @GetMapping("door") public String door(HttpSession session, Model model) { User user = (User) session.getAttribute("user"); if (user == null || "".equals(user.getUsername())) { return "doorLogin.jsp"; } List books = bookService.getIndexBooks(); model.addAttribute("books", books); model.addAttribute("nav", 1); return "door.jsp"; } ``` 2、判断用户名和密码是否正确 ```java /** * 当用户发起的请求是 door ,并且请求方式是post时,进入该方法体 * * @param user 用户填写的账户名和密码,该参数是一个自动包装的实体类 * @param model 响应视图的数据 * @param session session作用域 * @return */ @PostMapping("door") public String door(User user, Model model, HttpSession session) { /** * 通过登录的用户名查找数据库,返回查找结果,再从查找结果中判断是否有密码为用户输入的密码 * 如果有 * 则返回首页视图,并返回导航栏视图数据和图书视图数据 * 并且将该用户放到session作用域中,表示该用户已经登录,无需再跳转登录界面了 * 如果没有 * 则返回登录视图,并返回错误码203,表示虽然响应成功但是用户名或则密码有错误 */ // 通过登录的用户名查找数据库,返回查找结果 List users = userService.findUserByName(user.getUsername()); // 再从查找结果中判断是否有密码为用户输入的密码 for (User u : users) { // 如果有 if (u.getPassword().equals(user.getPassword())) { model.addAttribute("nav", 1); List books = bookService.getIndexBooks(); model.addAttribute("books", books); session.setAttribute("user", u); return "door.jsp"; } } // 登录失败 则返回登录视图,并返回错误码203,表示虽然响应成功但是用户名或则密码有错误 model.addAttribute("error", "203"); return "doorLogin.jsp"; } ``` ### 注册功能 1、跳转注册页面 ```java @GetMapping("doorReg") public String doorReg() { return "doorReg.jsp"; } ``` 2、表单验证输入是否合法(输入的是不是邮箱) 用户在注册界面点击注册按钮后,会检测用户输入是否合法,比如:注册的邮箱是否是真实合法的邮箱,如果不合法则无法提交表单数据到后台。 通过标签属性`type="email"`进行验证。通过标签属性`required`来验证用户是否提交了空值。 3、验证当前邮箱是否被注册 此时就来到了后端。 通过用户提交的邮箱查询该邮箱是否已经注册过了: ```java List userByName = userService.findUserByName(user.getUsername()); if (userByName.size() != 0) { model.addAttribute("error", 202); return "doorReg.jsp"; } ``` 4、注册成功自动跳转至登录页面,注册失败不会跳转 如果该邮箱没有注册过,则完成注册,将用户填写的内容插入到数据库中: ```mysql INSERT INTO user(username,password,sex,citizenid,studentname) VALUES(#{username},#{password},#{sex},#{citizenid},#{studentname}); ``` ### 搜索功能 用户在搜索框输入图书的名称、作者、类别,后台在接收到该关键词后,去数据库模糊查询该关键词,并返回符合条件的内容。 sql语句: ```sql SELECT * FROM book WHERE bookname LIKE '%${val}%' OR writer LIKE '%${val}%' OR category LIKE '%${val}%'; ``` 将结果封装为数据,返回给前台页面: ```java List list = bookService.findBookByVal(val); model.addAttribute("list", list); return "/index.jsp"; ``` ### 统计功能 该统计功能记录的数据是书籍类别中被借阅的次数。所以需要通过书籍分类,计算各分类被借阅的数量,然后将结果数据返回给前台。 该返回的数据以json格式返回,让echarts解析该数据从而展现动态的借阅统计数据。 ```java @GetMapping("getCount") @ResponseBody // 该注解表示返回的是数据而非视图 public Map getCount(){ // 访问业务层调用数据库获取数据信息 List count = regBookService.getCount(); // 通过JDK11新特性,生成一个Map返回 return Map.of("count",count); } ``` 所调用的sql语句: ```sql SELECT b.category category,count(*) count FROM reg_book a,book b WHERE a.bookid=b.id GROUP BY b.category; ``` 使用echarts通过如下代码解析数据: ```js var myChart = echarts.init(document.getElementById('myECharts')); var option = { title: { text: '信息统计' }, tooltip: {}, legend: { data:['书籍类型'] }, xAxis: { data: xTitle }, yAxis: {}, series: [{ name: '人数', type: 'bar', data: yTitle }] }; myChart.setOption(option); ``` ### 借阅功能 在客户端中,点击图书的借阅按钮后,通过当前登录的用户完成该用户的借阅。 具体如下 点击借阅按钮后: 通过post的方式向后端发送异步请求,参数为所借阅图书的id,如果完成借阅则返回状态码`1`,否则为借阅失败。 ```js $.ajax({ url:'/book/bookMake', type:'post', data:{ bookid:index }, success(ret){ if(ret.status==1){ alert("借阅成功"); }else if (ret.status == 2) { alert("用户ID不存在,无法借阅"); }else { alert("系统繁忙!"); } } }) ``` 后端接收借阅请求: 通过当前用户id和图书id,建立一条借阅记录,当然这需要调用数据库来执行。 ```java int i = regBookService.create(bookid, userid); if(i==1){ return Map.of("status", 1); } ``` sql语句: ```sql INSERT INTO reg_book(time,status, endtime, userid, bookid) VALUES (#{time},0,#{endtime},#{userid},#{bookid}); ``` ### 归还功能 在客户端中,如果当前用户所借阅的图书并没有归还,则在操作栏中显示归还按钮,否则为删除按钮。 两个按钮不会同时出现,因为系统不允许删除未归还的借阅记录。 **当点击归还按钮:** 通过get的方式向后端发起一个异步请求,参数为用户要归还的借阅记录ID。 ```js $.ajax({ url:'/returnBook', type:'get', data:{ id:regId }, success(ret) { window.location.reload(); } }); ``` **后端接收请求** 获取当前时间,作为用户归还图书的时间记录。 ```java SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String format = df.format(new Date()); ``` **归还图书的sql语句** 修改该借阅记录的状态和归还时间。 ```sql UPDATE reg_book SET time=#{time},status=#{status},endtime=#{endtime},userid=#{userid},bookid=#{bookid} WHERE id=#{id} ``` ### 库存加减: 当用户点击借阅按钮,系统去数据库中查找当前书籍的库存,判断该书籍库存是否为0,如果为0,则说明库存不足。不能被借阅。 如果库存大于0,则借阅成功,同时该书籍的库存-1. 归还时,将该书籍库存+1。这样就可以保证每本书籍的总数量不变。 ### 客户端借阅管理 客户端借阅管理通过当前登录用户去数据库中查找当前用户借阅的书籍记录,包括未归还和已归还。如果当前用户借阅的书籍已超过七天未归还,则标注为已逾期。 ### 管理端借阅管理 管理端借阅管理查询数据库中全表,并陈列。 通过搜索用户的用户名,来查询该用户的所有借阅信息。 ### 借阅数量限制 每位用户最多限制只能借阅三本书籍,当已经借阅三本书籍之后,则无法完成借阅操作。并弹出提醒,告知用户该用户已经到达最多限制数量无法借阅。 想要再次借阅只能将为归还的书籍归还,才能完成借阅。 当前用户未归还书籍最多为3本。