7.7 SpringBoot实战 管理员借阅审核列表 --分页和枚举的使用

news2025/1/21 2:59:02

CSDN成就一亿技术人

文章目录

  • 前言
  • 一、需求
  • 二、定义接口 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 {

    @Autowired
    private BookBorrowingMapper bookBorrowingMapper;
    @Autowired
    private BookMapper bookMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public 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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

orm(连接MySQL,增删改,创建表,样例)

1.启动数据库 mysql -u root -p password:(输入密码)2.创建数据库 create database stu DEFAULT CHARSET utf8 COLLATE utf8_general_ci;3.更改Django中settings.py文件配置 Django连接数据库&#xff1a; DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: st…

NICE-SLAM代码复现和解析(解决使用yaml文件配置conda环境时下载慢的问题)

代码运行 代码地址&#xff1a;https://github.com/cvg/nice-slam/tree/master 环境配置 下载压缩包&#xff0c;打开environment.yaml文件 向yaml文件中添加如下代码 - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ - https://mirrors.ustc.edu.cn/anacon…

docker中涉及的挂载点总结

文章目录 1.场景描述2. 容器信息在主机上位置3. 通过docker run 命令4、通过Dockerfile创建挂载点5、容器共享卷&#xff08;挂载点&#xff09;6、最佳实践&#xff1a;数据容器 1.场景描述 在介绍VOLUME指令之前&#xff0c;我们来看下如下场景需求&#xff1a; 1&#xff…

关于OAuth2.0的一些基本知识

本文记录下关于OAuth2.0的一些基本知识 文章目录 什么是 OAuth2.0OAuth2.0 架构术语介绍Web 服务器用户代理本机应用程序本文小结 什么是 OAuth2.0 OAuth 是一种开放的授权协议&#xff0c;它是目前最流行的授权机制。它允许将存储在一个站点上的资源共享到另一个站点&#xff…

享元模式——实现对象的复用

1、简介 1.1、概述 当一个软件系统在运行时产生的对象数量太多&#xff0c;将导致运行代价过高&#xff0c;带来系统性能下降等问题。例如&#xff0c;在一个文本字符串中存在很多重复的字符&#xff0c;如果每个字符都用一个单独的对象来表示&#xff0c;将会占用较多的内存…

打印Winform控件实现简陋版的分页打印(C#)

本文的代码可以从这里获取&#xff1a;winformDemo.rar 张祥裕/分享的资源名称 - Gitee.com 作者的水平有限&#xff0c;如有错误&#xff0c;望指正。 为了简单起见&#xff0c;纸张大小&#xff0c;打印机等信息按照默认的来&#xff0c;本文的实现方案是&#xff1a;打印Pa…

超全整理,Jmeter性能测试-常用Jmeter第三方插件详解(超细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 Jmeter作为一个开…

【回眸】备考PMP考点汇总 三(距离考试还有20天)

目录 前言 【回眸】备考PMP考点汇总 三&#xff08;距离考试还有20天&#xff09; 29、管理质量 30、获取资源 31、建设团队 32、管理团队 33、管理沟通 34、实施风险应对 35、实施采购 36、管理相关方参与 37、监控项目工作&#xff08;10%&#xff09; 38、实施整…

php://filter绕过死亡exit

文章目录 php://filter绕过死亡exit前言[EIS 2019]EzPOP绕过exit 参考 php://filter绕过死亡exit 前言 最近写了一道反序列化的题&#xff0c;其中有一个需要通过php://filter去绕过死亡exit()的小trick&#xff0c;这里通过一道题目来讲解 [EIS 2019]EzPOP 题目源码&#…

*CTF 2023 web jwt2struts 题解wp

jwt2struts 根据题目名字猜测&#xff0c;这题考察jwt和Struts2 包里面果然有一个cookie 验证了&#xff0c;是jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiZXhwIjoyMDA2MjI1MjgxfQ.F7vOtdqg48M1DYK4tVZywTipIYDqKfsBSju7ekLSecU 我们的目标应该是把user改…

深蓝学院C++基础与深度解析笔记 第13章 模板

1. 函数模板 ● 使用 template 关键字引入模板&#xff1a; template<typename T> //声明&#xff1a;T模板形参void fun(T); // T 函数形参template<typename T> //定义void fun(T) {...}– 函数模板不是函数 –…

安全学习DAY12_信息打点-Web应用信息搜集

信息打点-Web应用 文章目录 信息打点-Web应用业务资产企业查信息的目的 Web应用信息搜集Web网站域名搜集WEB单域名WEB子域名OneForAll&#xff08;子域名收集工具&#xff09; WEB网站架构资产WEB指纹识别资产 常用查询平台汇总查企业信息查备案信息查公众号信息域名注册查询IP…

【Linux】进程篇Ⅱ:进程开始、进程终止、进程等待、程序替换

文章目录 五、fork 函数&#xff0c;创建进程写时拷贝 六、进程终止1. 退出码2. 如何终止程序 七、进程等待1. 概念2. wait 函数waitpid 函数 &#x1f53a; 3. 阻塞等待 八、程序替换1. execl2. execv3. execlp4. execvp5. execle &#x1f53a;6. execvpe 、execve 一个简易的…

vmware的window中安装GNS3

1.向vmware中的windows虚拟机传送文件 点击虚拟机-安装VMwaretools 安装在虚拟机上面 此图标代表已经成功&#xff0c;将文件复制到虚拟机上里面 2.安装 安装gns3&#xff0c;需要先安装winpcap&#xff08;检查网卡&#xff09;和wireshark&#xff08;对winpcap上数据进行抓…

16- C++多态-4 (C++)

第五章 多态 5.1 多态的引入 思考&#xff1a;在之前实现的英雄模型中&#xff0c;假如实现某个接口可以传入一个英雄&#xff0c;在该接口中可以对英雄的力量、敏捷和智力进行加强&#xff0c;请问该接口的参数该如何设计&#xff1f; 以上解决办法利用了C中的多态&#xf…

51单片机定时器/计数器

目录 1、定时器/计数器0/1介绍 1.1 定时器介绍 1.2 单片机定时/计数器原理 2、定时器/计数器0和1的相关寄存器 2.1 定时器/计数器控制寄存器TCON 2.2 定时器/计数器工作模式寄存器TMOD 2.3 定时器/计数器工作模式 2.3.1 模式0(13位定时器/计数器) 2.3.2 模式1(16位定…

CSDN如何输入公式

方法分三步&#xff1a; 1&#xff09;预先设置MathType的复制剪切选项 2&#xff09;将MathType已经编写好的公式复制到CSDN 3&#xff09;把复制的公式文本&#xff0c;首尾的“\[”和“\]”符号替换成“$$”和“$$” 1&#xff09;预先设置MathType的复制剪切选项 2&#x…

海量数据存储组件Hbase

hdfs hbase NoSQL数据库 支持海量数据的增删改查 基于Rowkey查询效率特别高 kudu 介于hdfs和hbase之间 hbase依赖hadoopzookeeper&#xff0c;同时整合框架phoenix(擅长读写),hive&#xff08;分析数据&#xff09; k&#xff0c;v 储存结构 稀疏的&#xff08;为空的不存…

Qt实现思维导图锦集

序号简述文章导航1思维导图树形结构、不重叠且均匀分布、支持折叠和展开核心树2菜单按钮风格、菜单提示风格、侧滑菜单、侧滑功能窗口UI设计3支持JPEG、PNG、XML、JSON、PDF、SVG格式文件数据导入导出4支持撤销回撤功能、显示节点操作流程、点击可跳转历史撤销回撤5思维导图横向…

哈工大计算机网络课程网络安全基本原理详解之:消息完整性与数字签名

哈工大计算机网络课程网络安全基本原理详解之&#xff1a;消息完整性与数字签名 这一小节&#xff0c;我们继续介绍网络完全中的另一个重要内容&#xff0c;就是消息完整性&#xff0c;也为后面的数字签名打下基础。 报文完整性 首先来看一下什么是报文完整性。 报文完整性…