基于Spring Boot的借阅、续借、归还、审核流程完整功能实现

拿大学图书管理系统当例

实体类 需要有记录用户(包含管理员)操作的变量

package com.example.entity;

import java.io.Serializable;

/**
 * 借阅管理表
*/
public class Borrow implements Serializable {
    private static final long serialVersionUID = 1L;

    /** 记录ID */
    private Integer id;
    /** 学生ID */
    private Integer studentId;
    /** 书籍ID */
    private Integer booksId;
    /** 借阅日期 */
    private String borrowDate;
    /** 归还日期 */
    private String returnDate;
    /** 借阅状态 */
    private String status;
    /** 审核状态 */
    private String reviewStatus;
    /** 审核理由 */
    private String reason;
    
    /** 学生姓名 */
    private String studentName;        //关联查询用
    /** 书籍名 */
    private String bookName;          //关联查询用
    /** 学生的操作类型 */
    private String operation;         //需要有记录用户(包含管理员)操作的变量
    /** 书籍封面 */
    private String booksCover;          //关联查询用
}

在Service层的新增里实现借阅功能,写一个辅助新增查看该学生是否已经借阅的方法。 (代码量多,归还在下面)

public void add(Borrow borrow) {
Account currentUser = TokenUtils.getCurrentUser();
// 查看该学生是否已经借阅
List<Borrow> existingBorrowList = this.selectByBorrowIdAndStudentId(borrow.getBooksId(), currentUser.getId(),
                                                                    borrow.getStatus());

if (existingBorrowList != null && !existingBorrowList.isEmpty()) {
    // 找到最新的借阅记录
    Borrow latestBorrow = existingBorrowList.stream()
    .max(Comparator.comparing(Borrow::getBorrowDate)) // 假设Borrow对象有getBorrowDate方法
    .orElse(null);

    if (latestBorrow != null) {
        if (latestBorrow.getStatus().equals(Constants.RETURNED)
            || latestBorrow.getStatus().equals(Constants.BORROWING_FAILED)) {
            processBorrowRequest(borrow, currentUser);
        } else {
            throw new CustomException(ResultCodeEnum.BOOKS_BORROW_ERROR);
        }
    }
} else {
    processBorrowRequest(borrow, currentUser);
}
}

/**
     * 辅助新增查看该学生是否已经借阅
     */
    public List<Borrow> selectByBorrowIdAndStudentId(Integer booksId, Integer studentId, String status) {
        return borrowMapper.selectByBorrowIdAndStudentId(booksId, studentId, status);
    }

/**
     * 封装借阅功能,降低代码重复率
     */
    private void processBorrowRequest(Borrow borrow, Account currentUser) {
        // 更新书籍的可借副本数量
        if (booksMapper.decrementCopies(borrow.getBooksId()) > 0) {
            borrow.setStudentId(currentUser.getId());
            borrow.setBorrowDate(DateUtil.now());
            // 根据借阅日期计算归还日期并设置
            DateTime returnDateTime = DateUtil.offsetDay(DateUtil.parse(borrow.getBorrowDate()), 30);
            borrow.setReturnDate(DateUtil.formatDateTime(returnDateTime));

            if (borrow.getOperation().equals(Constants.BORROWED)) {
                borrow.setStatus(Constants.BORROWING_REVIEW_IN_PROGRESS);
                borrow.setReviewStatus(Constants.PENDING_REVIEW);
            }
            borrowMapper.insert(borrow);
        } else {
            throw new CustomException(ResultCodeEnum.BOOKS_COPIES_ERROR);
        }
    }

单独写辅助新增查看该学生是否已经借阅的方法的Mapper层里的SQL代码,就有这一个单独写的方法,其他CRUD忽略没写

@Select("select * from borrow where books_id = #{booksId} and student_id = #{studentId} and status <> '已归还'")
List<Borrow> selectByBorrowIdAndStudentId(Integer booksId, Integer studentId, String status);

在Service层的修改里实现续借、归还、审核功能。 因为逻辑有点复杂,使用if-else的话(如果喜欢用if-else的话,代码我放在下面,就是有点丑),不容易维护,可读性差,所以我用了switch case 方法

public void updateById(Borrow borrow) {
switch (borrow.getOperation()) {
    case Constants.ADOPT:
        handleAdoptOperation(borrow);
        break;
    case Constants.REFUSE:
        handleRefuseOperation(borrow);
        break;
    case Constants.CONTINUE_BORROWING:
        handleContinueBorrowingOperation(borrow);
        break;
    case Constants.RETURN:
        handleReturnOperation(borrow);
        break;
}
borrowMapper.updateById(borrow);
}

private void handleAdoptOperation(Borrow borrow) {
    switch (borrow.getStatus()) {
        case Constants.BORROWING_REVIEW_IN_PROGRESS:
            borrow.setStatus(Constants.BORROWING);
            borrow.setReviewStatus(Constants.ADOPT);
            break;
        case Constants.RENEWAL_REVIEW_IN_PROGRESS:
            borrow.setStatus(Constants.RENEWAL);
            borrow.setReviewStatus(Constants.ADOPT);
            setRenewalReturnDate(borrow);
            break;
        case Constants.RETURNED_REVIEW_IN_PROGRESS:
            borrow.setStatus(Constants.RETURNED);
            borrow.setReviewStatus(Constants.ADOPT);
            borrow.setReturnDate(DateUtil.now());
            booksMapper.incrementCopies(borrow.getBooksId());
            break;
    }
}

private void handleRefuseOperation(Borrow borrow) {
switch (borrow.getStatus()) {
    case Constants.RETURNED_REVIEW_IN_PROGRESS:
        borrow.setStatus(Constants.RESTITUTION_FAILED);
        borrow.setReviewStatus(Constants.REFUSE);
        break;
    case Constants.RENEWAL_REVIEW_IN_PROGRESS:
        borrow.setStatus(Constants.RENEWAL_FAILED);
        borrow.setReviewStatus(Constants.REFUSE);
        break;
    default:
        borrow.setStatus(Constants.BORROWING_FAILED);
        borrow.setReviewStatus(Constants.REFUSE);
        booksMapper.incrementCopies(borrow.getBooksId());
        break;
}
}

private void handleContinueBorrowingOperation(Borrow borrow) {
    borrow.setStatus(Constants.RENEWAL_REVIEW_IN_PROGRESS);
    borrow.setReviewStatus(Constants.PENDING_REVIEW);
}

private void handleReturnOperation(Borrow borrow) {
borrow.setStatus(Constants.RETURNED_REVIEW_IN_PROGRESS);
borrow.setReviewStatus(Constants.PENDING_REVIEW);
}

private void setRenewalReturnDate(Borrow borrow) {
    DateTime returnDateTime = DateUtil.offsetDay(DateUtil.parse(borrow.getReturnDate()), 15);
    borrow.setReturnDate(DateUtil.formatDateTime(returnDateTime));
}

在Service层的修改里使用if-else实现续借、归还、审核功能。

public void updateById(Borrow borrow) {
        if (borrow.getOperation().equals(Constants.ADOPT)) {
            if (borrow.getStatus().equals(Constants.BORROWING_REVIEW_IN_PROGRESS)) {
                borrow.setStatus(Constants.BORROWING);
                borrow.setReviewStatus(Constants.ADOPT);
            } else if (borrow.getStatus().equals(Constants.RENEWAL_REVIEW_IN_PROGRESS)) {
                borrow.setStatus(Constants.RENEWAL);
                borrow.setReviewStatus(Constants.ADOPT);
                // 根据借阅后的归还日期计算续借后的归还日期并设置
                DateTime returnDateTime = DateUtil.offsetDay(DateUtil.parse(borrow.getReturnDate()), 15);
                borrow.setReturnDate(DateUtil.formatDateTime(returnDateTime));
            } else if (borrow.getStatus().equals(Constants.RETURNED_REVIEW_IN_PROGRESS)) {
                borrow.setStatus(Constants.RETURNED);
                borrow.setReviewStatus(Constants.ADOPT);
                borrow.setReturnDate(DateUtil.now());
                booksMapper.incrementCopies(borrow.getBooksId());
            }
        } else if (borrow.getOperation().equals(Constants.REFUSE)) {
            if (borrow.getStatus().equals(Constants.RETURNED_REVIEW_IN_PROGRESS)) {
                borrow.setStatus(Constants.RESTITUTION_FAILED);
                borrow.setReviewStatus(Constants.REFUSE);
            } else if (borrow.getStatus().equals(Constants.RENEWAL_REVIEW_IN_PROGRESS)) {
                borrow.setStatus(Constants.RENEWAL_FAILED);
                borrow.setReviewStatus(Constants.REFUSE);
            } else {
                borrow.setStatus(Constants.BORROWING_FAILED);
                borrow.setReviewStatus(Constants.REFUSE);
                booksMapper.incrementCopies(borrow.getBooksId());
            }
        } else if (borrow.getOperation().equals(Constants.CONTINUE_BORROWING)) {
            borrow.setStatus(Constants.RENEWAL_REVIEW_IN_PROGRESS);
            borrow.setReviewStatus(Constants.PENDING_REVIEW);
        } else if (borrow.getOperation().equals(Constants.RETURN)) {
            borrow.setStatus(Constants.RETURNED_REVIEW_IN_PROGRESS);
            borrow.setReviewStatus(Constants.PENDING_REVIEW);
        }
        borrowMapper.updateById(borrow);
    }

这是用数据库操作的方式实现借阅时书籍可借副本数量+1和归还时书籍可借副本数量-1,在books类的Mapper层里实现。这两在上面的修改里被调用(注意被调用时的方法名)

/**
 * 数据库借阅书籍操作
 */
@Update("UPDATE books SET copies = copies - 1 WHERE id = #{bookId} AND copies > 0")
int decrementCopies(@Param("bookId") int bookId);

/**
 * 数据库归还书籍操作
 */
@Update("UPDATE books SET copies = copies + 1 WHERE id = #{bookId}")
int incrementCopies(@Param("bookId") int bookId);

在新增和修改里用到的常量

package com.example.common;

public interface Constants {

    String TOKEN = "xxxxx";

    String STUDENT_DEFAULT_PASSWORD = "xxxxxx";

    String BORROWING_REVIEW_IN_PROGRESS = "借阅审核中";
    String BORROWING = "借阅中";
    String BORROWING_FAILED = "借阅失败";
    String RENEWAL_REVIEW_IN_PROGRESS = "续借审核中";
    String RENEWAL_FAILED = "续借失败";
    String RENEWAL = "续借中";
    String RETURNED_REVIEW_IN_PROGRESS = "归还审核中";
    String RESTITUTION_FAILED = "归还失败";
    String RETURNED = "已归还";
    String PENDING_REVIEW = "待审核";
    String ADOPT = "通过";
    String REFUSE = "拒绝";
    String BORROWED = "借阅";
    String CONTINUE_BORROWING = "续借";
    String RETURN = "归还";
}

最后用普通人看得懂的话来讲一下,这一整套操作的逻辑和流程哈。

review_status 审核状态 , status 借阅状态

学生在自己的页面里点击借阅时review_status值为“待审核”,status值为“借阅审核中”。管理员在status值为“借阅审核中”时给用户审核通过后review_status值为“通过”,status值为“借阅中”,从可借副本数量-1。如果给用户审核“拒绝”review_status值为“拒绝”,status值为“借阅失败”,给可借副本数量+1。

用户点击续借时review_status值为“待审核”,status值为“续借审核中”。管理员在status值为“续借审核中”时给用户审核“通过”后review_status值为“通过”,status值为“续借中”。如果给用户审核“拒绝”review_status值为“拒绝”,status值为“续借失败”。

用户点击归还时review_status值为“待审核”,status值为“归还审核中”。管理员在status值为“归还审核中”时给用户审核“通过”就review_status值为“通过”,status值为“已归还”,给可借副本数量+1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值