文章目录
- 前言
- 一、需求
- 二、定义接口 BookAdminController
- 三、核心实现 BookBorrowService
- 新建 BookBorrowService 接口定义如下:
- 新建 BookBorrowServiceImpl 类,核心实现逻辑:
- 新建 BookBorrowBO
- 四、图书借阅状态枚举 BookBorrowStatusEnum
- 五、Postman测试
- 最后
前言
本文主要实战 管理员借阅审核分页列表,更多的是复习之前讲过的技术点,像API接口的定义、分页pageHelper的使用、角色权限的校验
等等,另外针对【图书借阅审核状态】引入了枚举
的使用。
按照规划,本专栏剩余的文章还会有很多新技术点,当然像本文这样的复习也少不了,唯有不断复习、不断强化,这样你才能一回生二回熟,将前面所学技术不断的在不同的场景下活学活用,举一反三,触类旁通,最后才会越用越熟练,熟成生巧,当有新需求时,当然就能更快的找到更优的落地方案!
因为我们需要实现的API还有一大把,所以对于接下来的文章,我的计划是穿插着综合实战,新技术点讲解,好戏还在后头,加油!
一、需求
当学生发起【图书借阅】的申请后,在管理员端提供【借阅审核列表】给管理员查看:谁要借阅哪本书,哪些是待审核的,哪些是审核通过的,哪些是驳回的请求,分页展示。
提前说明:学生的图书借阅接口还没有开发,我们是先从管理员端入手!
二、定义接口 BookAdminController
对于借阅审核列表,支持
管理员角色校验@Role
、分页参数
、状态status的筛选
,另外我们新注入了BookBorrowService
,代码如下:
@Autowired
private BookBorrowService bookBorrowService;@Role
@GetMapping("/book/borrow/examine/list")
public TgResult<BookBorrowBO> getBookBorrowExamineList(@RequestParam("pageNum") Integer pageNum, @RequestParam("pageSize") Integer pageSize, @RequestParam("status") Integer status) {return TgResult.ok(bookBorrowService.getBookBorrowExamineList(pageNum, pageSize, status));
}
详细的角色权限校验@Role,请参考 7.5 拦截器实现 和 7.6 AOP实现
三、核心实现 BookBorrowService
新建 BookBorrowService 接口定义如下:
public interface BookBorrowService {Page<BookBorrowBO> getBookBorrowExamineList(int pageNum, int pageSize, Integer status);
}
新建 BookBorrowServiceImpl 类,核心实现逻辑:
- 分页查询借阅表book_borrowing,支持按status筛选
- 通过studentId 查询学生信息
- 通过bookId 查询书名
- 通过verifyUserId 查询审核人
- 通过status 查询状态描述
我在【7.4】说明过,这里再重复说明一下:这里分开查询,主要考虑的是 用户、图书、学生等信息不经常修改,二期可以使用
Redis缓存优化
,如果用Join查询,回头再优化的话,改动的就会更多!
@Service
public class BookBorrowServiceImpl implements BookBorrowService {@Autowiredprivate BookBorrowingMapper bookBorrowingMapper;@Autowiredprivate BookMapper bookMapper;@Autowiredprivate StudentMapper studentMapper;@Autowiredprivate UserMapper userMapper;@Overridepublic Page<BookBorrowBO> getBookBorrowExamineList(int pageNum, int pageSize, Integer status) {// 图书借阅审核列表BookBorrowingExample example = new BookBorrowingExample();if (status != null) {example.createCriteria().andStatusEqualTo(status);}// 查询并分页Page<BookBorrowing> page = PageHelper.startPage(pageNum, pageSize).doSelectPage(() -> bookBorrowingMapper.selectByExample(example));Page<BookBorrowBO> pageBO = new Page<>();BeanUtils.copyProperties(page, pageBO);for (BookBorrowing bookBorrowing : page.getResult()) {BookBorrowBO bookBorrowBO = new BookBorrowBO();BeanUtils.copyProperties(bookBorrowing, bookBorrowBO);Student student = studentMapper.selectByPrimaryKey(bookBorrowBO.getStudentId());// 借阅的学生StudentBO studentBO = new StudentBO();BeanUtils.copyProperties(student, studentBO);bookBorrowBO.setStudent(studentBO);// 书名Book book = bookMapper.selectByPrimaryKey(bookBorrowBO.getBookId());bookBorrowBO.setBookName(book.getBookName());// 审核人if (bookBorrowBO.getVerifyUserId() != null) {User verifyUser = userMapper.selectByPrimaryKey(bookBorrowBO.getVerifyUserId());bookBorrowBO.setVerifyUserName(verifyUser.getUserName());}// 状态描述bookBorrowBO.setStatusDesc(BookBorrowStatusEnum.getMsgByCode(bookBorrowBO.getStatus()));pageBO.add(bookBorrowBO);}return pageBO;}
}
- 对于 BookBorrowStatusEnum.getMsgByCode,我在文章下节有说明!
- 其它的Mybatis的根据Mapper查询,使用的都是MBG生成的selectByPrimaryKey,即根据主键查询一条记录。如果生疏了,详见 5.6 Mybatis代码生成器Mybatis Generator (MBG)实战详解
新建 BookBorrowBO
@Data
public class BookBorrowBO implements Serializable {private Integer id;private Integer studentId;private Integer bookId;private Date borrowTime;private Integer status;private String rejectReason;private Date verifyTime;private Integer verifyUserId;private Date returnTime;private Date gmtCreate;private Date gmtModified;// BookBorrowing以外的字段private StudentBO student;private String statusDesc;private String bookName;private String verifyUserName;
}
四、图书借阅状态枚举 BookBorrowStatusEnum
枚举定义在tg-book-common
的enums包中,如下图:
Java中定义枚举使用
enum
关键字,并且支持成员变量
、构造方法
等,适用于定义一些状态码和描述。
对于图书借阅状态,共分4种:
- 0-待审核
- 1-审核通过
- 2-驳回
- 3-已还
对于一码一描述,可以通过定义两个字段code 和 msg,使用构造方法传入,代码如下:
/*** 图书借阅状态枚举**/
public enum BookBorrowStatusEnum {Integer code;String msg;BookBorrowStatusEnum(Integer code, String msg) {this.code = code;this.msg = msg;}public Integer getCode() {return this.code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
然后,我们可以在BookBorrowStatusEnum的最上方,中添加定义的4种状态:
/*** 图书借阅状态枚举**/
public enum BookBorrowStatusEnum {TO_BE_EXAMINE(0, "待审核"),APPROVED(1, "审核通过"),REJECTED(2, "驳回"),RETURNED(3, "已还"),;Integer code;String msg;BookBorrowStatusEnum(Integer code, String msg) {this.code = code;this.msg = msg;}public Integer getCode() {return this.code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
并且,可以像类一样,定义静态方法,例如在BookBorrowStatusEnum定义静态方法:根据code获取msg
/*** 根据code获取msg**/
public static String getMsgByCode(Integer code) {for (BookBorrowStatusEnum e : BookBorrowStatusEnum.values()) {if (e.getCode().equals(code)) {return e.getMsg();}}return null;
}
同理,我们再定义一个下文使用的图书状态枚举
:
/*** 图书状态枚举**/
public enum BookStatusEnum {FREE(0, "空闲"),BORROWING(1, "借阅中"),;Integer code;String msg;BookStatusEnum(Integer code, String msg) {this.code = code;this.msg = msg;}public Integer getCode() {return this.code;}public void setCode(Integer code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}
}
五、Postman测试
先用SQL模拟一条学生借阅记录数据
INSERT INTO `db_book`.`book_borrowing`
(`student_id`, `book_id`, `borrow_time`, `status`, `reject_reason`
, `verify_time`, `verify_user_id`, `return_time`, `gmt_create`, `gmt_modified`)
VALUES (1, 2, '2023-04-08 03:10:00', 0, ''
, NULL, NULL, NULL, '2023-07-29 03:10:00', NULL);
再用Postman请求status=0的数据,结果如下:
最后
想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!
具体的优势、规划、技术选型都可以在《开篇》试读!
订阅专栏后可以添加我的微信,我会为每一位用户进行针对性指导!
另外,别忘了关注我:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008