Spring Boot图书管理系统项目实战-7.借阅图书
导航:
pre: 6.图书管理
next:8.续借图书
只挑重点的讲,具体的请看项目源码。
1.项目源码
需要源码的朋友,请捐赠任意金额后留下邮箱发送:)
2.页面设计
2.1 bookBorrow.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>借阅图书</title>
<link rel="stylesheet" href="/static/layui/css/layui.css" th:href="@{/static/layui/css/layui.css}">
</head>
<body>
<!-- 内容主体区域 -->
<div>
<!--<div class="demoTable" style="padding: 15px">
搜索:
<div class="layui-inline">
<input class="layui-input" id="find" autocomplete="off">
</div>
<button class="layui-btn" data-type="reload" id="queryRole">搜索</button>
</div>-->
<div>
<div class="search-div">
<div class="">
<div class="layui-inline">
<label class="layui-form-label">读者编码:</label>
<div class="layui-input-inline">
<input class="layui-input" id="readerCode" name="readerCode" autocomplete="off">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">ISBN:</label>
<div class="layui-input-inline">
<input class="layui-input" id="isbn" name="isbn" autocomplete="off">
</div>
</div>
<button class="layui-btn" data-type="reload" id="search">搜索</button>
</div>
</div>
<table id="tb-book" lay-filter="tb-book"></table>
</div>
<table id="tb_bookBorrow" lay-filter="tb_bookBorrow"></table>
</div>
<!--编辑表单-->
<script type="text/html" id="book-toolbar">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon"></i>新增</button>
<button class="layui-btn layui-btn-sm layui-btn-danger" lay-event="remove"><i class="layui-icon"></i>删除
</button>
<button class="layui-btn layui-btn-sm" lay-event="refresh"><i class="layui-icon"></i>刷新
</button>
</div>
<!--<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="getCheckData">获取选中行数据</button>
<button class="layui-btn layui-btn-sm" lay-event="getCheckLength">获取选中数目</button>
<button class="layui-btn layui-btn-sm" lay-event="isAll">验证是否全选</button>
</div>-->
</script>
<script type="text/html" id="barOps">
<a class="layui-btn layui-btn-sm" lay-event="edit"><i class="layui-icon"></i> </a>
</script>
<script src="/static/js/jquery-1.11.3.min.js" th:src="@{/static/js/jquery-1.11.3.min.js}"></script>
<script src="/static/layui/layui.all.js" th:src="@{static/layui/layui.all.js}"></script>
<script src="/static/js/util.js" th:src="@{/static/js/util.js}"></script>
<!--ctx-->
<script th:replace="~{fragment::ctx}"/>
<script>
var element, layer, laydate, table, form,userTable;
function reload(){
userTable.reload();
}
$(function () {
// 使用模块
layui.use(['element', 'layer', 'laydate', 'table', 'form'], function () {
element = layui.element;
layer = layui.layer;
laydate = layui.laydate;
table = layui.table;
form = layui.form;
});
element.on('tab(demo)', function(data){
var src=$(".layui-tab-item.layui-show").find("iframe").attr("src");
$(".layui-tab-item.layui-show").find("iframe").attr("src",src);
});
//第一个实例
userTable = table.render({
elem: '#tb_bookBorrow'
, height: 515
, url: ctx+'api/bookBorrow/getPageResult' //数据接口
, page: true //开启分页
, toolbar: '#book-toolbar'
/*,request: {
pageName: 'pageNo' //页码的参数名称,默认:page
,limitName: 'pageSize' //每页数据量的参数名,默认:limit
}
, response: {
statusName: 'code', //规定返回的状态码字段为code
statusCode: 200 //规定成功的状态码为200,默认为0
}
, parseData: function (res) {
return {
"code": res.code, //解析接口状态
"msg": res.msg, //解析提示文本
"count": res.records, //解析数据长度
"data": res.rows //解析数据列表
}
}*/
, cols: [
[ //表头
{type: 'checkbox', fixed: 'left'}
, {field: 'id', title: 'ID', width: 80, sort: true, fixed: 'left',hide:true}
, {field: 'borrowStatus', title: '状态', width: 80,templet:showStatus}
, {field: 'readerCode', title: '读者编码', width: 160}
, {field: 'readerName', title: '读者姓名', width: 160}
, {field: 'readerSex', title: '读者性别', width: 120}
, {field: 'readerPhone', title: '读者电话', width: 160}
, {field: 'bookIsbn', title: '图书ISBN', width: 160}
, {field: 'bookName', title: '图书名称', width: 160}
, {field: 'bookAuthor', title: '图书作者', width: 120}
, {field: 'bookCategory', title: '图书分类', width: 120}
, {field: 'bookLocation', title: '图书位置', width: 180}
, {field: 'bookTotal', title: '图书数量', width: 120}
, {field: 'bookLeft', title: '图书剩余', width: 120}
, {field: 'borrowDate', title: '借阅日期', width: 120,templet:'<div>{{ layui.util.toDateString(d.borrowDate, "yyyy-MM-dd") }}</div>'}
, {field: 'returnDate', title: '应还日期', width: 120,templet:'<div>{{ layui.util.toDateString(d.returnDate, "yyyy-MM-dd") }}</div>'}
, {field: 'borrowDays', title: '借阅天数', width: 120}
, {field: 'remark', title: '备注', width: 180}
, {fixed: 'right', title: '操作', toolbar: '#barOps', width: 120}
]
]
});
//工具栏事件
table.on('toolbar(tb_bookBorrow)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id);
var checkData = checkStatus.data;
var ids = [];
switch (obj.event) {
// 新增
case 'add':
cleanForm("#saveBook");
top.layer.open({
type: 2,
offset: '10px',
title: "新增借阅",
area: ['800px', '680px'],
content: ['bookBorrowAdd']
});
break;
// 删除
case 'remove':
if (checkData.length == 0) {
layer.alert('请选择要操作的行');
} else {
layer.confirm('确定要删除吗?', function (index) {
for (var i = 0; i < checkData.length; i++) {
ids.push(checkData[i].id);
}
//layer.alert(JSON.stringify(ids));
$.ajax({
url: ctx+'api/bookBorrow/remove',
type: 'POST',
contentType: "application/json",
dataType: "json",
data: JSON.stringify(ids),
success: function (result) {
if (result.code == 200) {
setTimeout(function () {
layer.closeAll();//关闭所有的弹出层
userTable.reload();
}, 300);
}else {
layer.msg("操作失败!", {icon: 5});
}
}
});
});
}
break;
case 'refresh':
userTable.reload();
break;
case 'getCheckData':
layer.alert(JSON.stringify(data));
break;
case 'getCheckLength':
var data = checkStatus.data;
layer.msg('选中了:' + data.length + ' 个');
break;
case 'isAll':
layer.msg(checkStatus.isAll ? '全选' : '未全选')
break;
}
;
});
// 监听工具条
table.on('tool(tb_bookBorrow)', function (obj) {
var data = obj.data;
// 修改
if (obj.event === 'edit') {
top.layer.open({
type: 2,
offset: '10px',
title: "修改借阅",
area: ['800px', '680px'],
content: [ctx+'bookBorrowEdit/'+data.id]
});
}
});
// 搜索
$('#search').click(function () {
var readerCode = $('#readerCode').val();
var isbn = $('#isbn').val();
table.reload('tb_bookBorrow', {
url: ctx+'api/bookBorrow/getPageResult'
,where: {
readerCode:readerCode,isbn:isbn
}
,page: {
curr: 1
}
});
});
});
// 借阅状态
function showStatus(data) {
var status = data.borrowStatus;
var result;
if (status == 0) {
result = '<a class="" style="color:#FF5722">未还</a>';
}
if (status == 1) {
result = '<a class="" style="color:#009688">已还</a>';
}
if (status == 2) {
result = '<a class="" style="color:#FF5722">逾期</a>';
}
return result;
}
</script>
</body>
</html>
3.借阅管理service
/**
* @Description: 借阅图书服务
* @Author laoxu
* @Date 2020/1/12
**/
@Service
public class BookBorrowService extends AbstractService {
public void add(BookBorrowVO entity) {
//String username = SecurityUtil.getLoginUser();
insert("bookBorrowMapper.insert",entity);
}
public void modify(BookBorrowVO entity) {
update("bookBorrowMapper.update",entity);
}
public void remove(Long id) {
delete("bookBorrowMapper.delete",id);
}
public void removes(Long[] ids) {
delete("bookBorrowMapper.deletes",ids);
}
public void returnBook(Map<String, Object> param) {
delete("bookBorrowMapper.return",param);
}
public BookBorrowVO get(Long id) {
return selectOne("bookBorrowMapper.select",id);
}
public List<BookBorrow> getParentList(Long id) {
return selectList("bookBorrowMapper.selectParentList",id);
}
public int count(Map<String, Object> param) {
return selectOne("bookBorrowMapper.count",param);
}
public List<BookBorrow> getList(Map<String, Object> param) {
return selectList("bookBorrowMapper.selectList",param);
}
public List<BookBorrowVO> getPageResult(Map<String, Object> param) {
return selectList("bookBorrowMapper.selectPageResult",param);
}
public int checkBorrow(BookBorrowVO entity){
return selectOne("bookBorrowMapper.countBorrow",entity);
}
public int getBorrowCount(String date){
return selectOne("bookBorrowMapper.selectBorrowCount",date);
}
public int getReturnCount(String date){
return selectOne("bookBorrowMapper.selectReturnCount",date);
}
}
4.借阅管理controller
/**
* @Description: 借阅图书控制器
* @Author laoxu
* @Date 2020/1/12 23:24
**/
@RestController
@RequestMapping("/api/bookBorrow")
public class BookBorrowController {
@Autowired
BookBorrowService bookBorrowService;
@Autowired
BookReaderService bookReaderService;
@Autowired
BookService bookService;
/**
* 保存(新增/修改)
*
* @param entity
* @return
*/
@PostMapping("/save")
public Result<String> modify(@RequestBody BookBorrowVO entity) {
Long id = entity.getId();
if(id!=null){
bookBorrowService.modify(entity);
}else{
Map<String,Object> param = new HashMap<>();
param.put("isbn",entity.getBookIsbn());
param.put("code",entity.getReaderCode());
//1.检查读者编号是否存在
if(bookReaderService.count(param)==0){
return ResultUtil.fail("读者不存在!");
}
//2.检查图书编号是否存在
if(bookService.count(param)==0){
return ResultUtil.fail("图书不存在!");
}
//3.检查该读者是否已经借过此书
int count = bookBorrowService.checkBorrow(entity);
if(count>0){
return ResultUtil.fail("您已借过该图书!");
}
//4.检查图书剩余
Book book = bookService.getByIsbn(entity.getBookIsbn());
int leftNumber = book.getLeftNumber();
if(leftNumber<1){
return ResultUtil.fail("图书剩余数量为0!");
}
//5.扣减图书剩余
book.setLeftNumber(leftNumber-1);
bookService.modify(book);
//6.保存借阅记录
bookBorrowService.add(entity);
}
return ResultUtil.ok();
}
@PostMapping("/remove")
public Result<String> remove(@RequestBody Long[] ids) {
bookBorrowService.removes(ids);
return ResultUtil.ok();
}
/**
* 归还
* @param ids
* @return
*/
@PostMapping("/return")
@Transactional
public Result<String> returnBook(@RequestBody Long[] ids) {
// 1.增加图书库存
Book entity = null;
for (Long id: ids) {
entity = bookService.getByIsbn(bookBorrowService.get(id).getBookIsbn());
entity.setLeftNumber(entity.getLeftNumber()+1);
bookService.modify(entity);
}
// 2.更新借阅状态
Map<String,Object> param = new HashMap<>();
param.put("ids", ids);
param.put("borrowStatus",1);
bookBorrowService.returnBook(param);
return ResultUtil.ok();
}
@GetMapping("/get")
public Result<BookBorrowVO> get(@RequestParam("id") Long id) {
BookBorrowVO entity = bookBorrowService.get(id);
return ResultUtil.ok(entity);
}
@GetMapping("/getPageResult")
public ResultBean<List<BookBorrowVO>> getPageResult(
@RequestParam(required = false) Integer[] borrowStatus,
@RequestParam(required = false) String readerCode,
@RequestParam(required = false) String isbn,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer limit) {
Map<String, Object> param = new HashMap<>();
// 统计记录数
int totalRows = bookBorrowService.count(param);
// 计算起始行号
int offset = (page - 1) * limit;
int rows = limit;
param.put("offset", offset);
param.put("rows", rows);
param.put("borrowStatus",borrowStatus);
param.put("readerCode",readerCode);
param.put("isbn",isbn);
// 获取当前页结果集
List<BookBorrowVO> entities = bookBorrowService.getPageResult(param);
ResultBean result = new ResultBean(0, "查询成功", totalRows, entities);
return result;
}
@GetMapping("/getBorrowStat")
public Result<Map<String,Object>> getBorrowStat(){
Map<String,Object> map = new HashMap<>();
List<String> days = DateUtil.getDaysBetwwen(6);
map.put("columnName",days);
BorrowStatVO borrowVO = new BorrowStatVO();
BorrowStatVO returnVO = new BorrowStatVO();
borrowVO.setName("借");
returnVO.setName("还");
borrowVO.setType("bar");
returnVO.setType("bar");
List<Integer> borrowData = new ArrayList<>();
List<Integer> returnData = new ArrayList<>();
for (String day:days) {
borrowData.add(bookBorrowService.getBorrowCount(day));
returnData.add(bookBorrowService.getReturnCount(day));
}
borrowVO.setData(borrowData);
returnVO.setData(returnData);
List<BorrowStatVO> list = new ArrayList<>();
list.add(borrowVO);
list.add(returnVO);
map.put("columnValue",list);
return ResultUtil.ok(map);
}
}
Spring Boot图书管理系统项目实战-7.借阅图书的更多相关文章
- Spring Boot → 11:项目实战-账单管理系统完整版
Spring Boot → 11:项目实战-账单管理系统完整版
- Spring Boot → 06:项目实战-账单管理系统
Spring Boot → 06:项目实战-账单管理系统
- Java 架构师+高并发+性能优化+Spring boot大型分布式项目实战
视频课程内容包含: 高级 Java 架构师包含:Spring boot.Spring cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat.Spring.MongoDB.Zer ...
- 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚
新书上线 大家好,笔者的新书<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>已上线,此书内容充实.材质优良,乃家中必备垫桌脚 ...
- 图书-技术-SpringBoot:《Spring Boot 企业级应用开发实战》
ylbtech-图书-技术-SpringBoot:<Spring Boot 企业级应用开发实战> Spring Boot 企业级应用开发实战,全书围绕如何整合以 Spring Boot 为 ...
- 从零一起学Spring Boot之LayIM项目长成记(五)websocket
前言 距离上一篇已经比较久的时间了,项目也是开了个头.并且,由于网上的关于Spring Boot的websocket讲解也比较多.于是我采用了另外的一个通讯框架 t-io 来实现LayIM中的通讯功能 ...
- Spring Boot会员管理系统——处理文件上传
温馨提示 Spring Boot会员管理系统的中,需要涉及到Spring框架,SpringMVC框架,Hibernate框架,thymeleaf模板引擎.所以,可以学习下这些知识.当然,直接入门的话使 ...
- 使用Spring Boot开发Web项目(二)之添加HTTPS支持
上篇博客使用Spring Boot开发Web项目我们简单介绍了使用如何使用Spring Boot创建一个使用了Thymeleaf模板引擎的Web项目,当然这还远远不够.今天我们再来看看如何给我们的We ...
- 从零一起学Spring Boot之LayIM项目长成记(二) LayIM初体验
前言 接上篇,已经完成了一个SpringBoot项目的基本搭建.那么现在就要考虑要做什么,怎么做的问题.所以本篇内容不多,带大家一起来简单了解一下要做的东西,之前有很多人不知道从哪里下手,那么今天我带 ...
- Spring Boot 从入门到实战汇总
之前写过几篇spring boot入门到实战的博文,因为某些原因没能继续. 框架更新迭代很快,之前还是基于1.x,现在2.x都出来很久了.还是希望能从基于该框架项目开发的整体有一个比较系统的梳理,于是 ...
随机推荐
- [转帖]Oracle 19c 新特性|增加 VARCHAR2 数据类型的大小限制
JiekeXuAll China Database Union2022-10-13 795 经朋友介绍,我读完 Tim Hall 于 2022 年 9 月 27 日他的博客上发表的博文.10 月 11 ...
- [转帖]nginx配置默认首页(index.html index.htm)全流程(包含遇到问题的解决)
https://www.cnblogs.com/tujietg/p/10753041.html#:~:text=%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88%EF%BC%9 ...
- [转帖]五类IP的范围
五类IP的范围 IP地址分为A,B,C,D,E五类. 网络号:用于识别主机所在的网络: 主机号:用于识别该网络中的主机. 其中A类分配给政府机关使用,B类地址给大中型企业使用,C类地址给个人使用.这 ...
- [转帖]yum 下载全量依赖 rpm 包及离线安装(终极解决方案)
简介 通常生产环境由于安全原因都无法访问互联网.此时就需要进行离线安装,主要有两种方式:源码编译.rpm包安装.源码编译耗费时间长且缺乏编译环境,所以一般都选择使用离线 rpm 包安装. 验证环境 C ...
- [转帖]查看堆内对象的工具:jmap
文章目录 用途 命令格式 示例 一,no option 二,heap 三,histo[:live] 四,clstats 五,finalizerinfo 六,dump:<dump-options& ...
- Docker 23.0.0 简单学习与使用
前言 Docker 从2013年火起来到现在才第十个年头. 现在已经被Google的K8S打的没有任何还手之力. 随着K8S放弃支持docker,仅支持containerd的方式. 直接导致docke ...
- charles如何抓取https请求
我们都知道charles下载安装后只能抓取http请求,要想抓取https请求需要下载安装证书 下面介绍pc端和移动端的配置方法 一.pc端(win) 1.打开charles,点击help>SS ...
- 01显示转换隐私转换 有8个值转为false 显示转换Number的注意点
prompt()函数会弹出一个框,接受用户的输入.但是在实际的开发中.这样的操作是很少. 至少在我做开发的过程中没有使用过.我二没有看见人家在过开发的使用使用. console.log(Number( ...
- statsvn只支持到svn1.3
怎样找出svn修改次数最多的文件? 我想统计配置表中,那个配置文件修改次数最多,但经过实践发现statsvn只支持到1.3的版本. 通过svn的命令行接口,把提交记录保存到xml中,再通过自己写代码解 ...
- 强化学习基础篇[2]:SARSA、Q-learning算法简介、应用举例、优缺点分析
强化学习基础篇[2]:SARSA.Q-learning算法简介.应用举例.优缺点分析 1.SARSA SARSA(State-Action-Reward-State-Action)是一个学习马尔可夫决 ...