一、项目背景:疫情下图书馆管理数字化的迫切需求
在疫情防控常态化背景下,传统图书馆管理模式面临人流管控难、借阅流程繁琐、纸质化办公效率低三大核心痛点。据图书馆行业报告显示,2022年超60%的图书馆仍依赖人工登记借阅、纸质表格统计进馆人员,导致疫情期间人流聚集风险高、借阅数据追溯难,同时用户因无法提前预约进馆和借阅图书,满意度大幅下降。
为破解这一困境,基于Spring Boot的疫情下图书馆管理系统应运而生。系统以“人流可控化、借阅线上化、管理数字化”为核心目标,采用B/S架构构建一体化图书馆管理平台,整合用户预约进馆、图书预约借阅/归还、健康打卡、员工审核、管理员统筹等核心功能,建立“管理员统筹-员工执行-用户操作”的三层应用模式,推动图书馆管理从“线下人工化”向“线上系统化、流程规范化、防控精准化”转型。
二、技术架构:图书馆管理系统的全栈技术选型
项目围绕“稳定性优先、易操作、高适配”三大原则,选用成熟且贴合疫情下图书馆管理需求的技术栈,确保系统在多角色并发操作、大量图书数据存储与疫情防控数据统计时的可靠性:
| 技术模块 | 具体工具/技术 | 核心作用 |
|---|---|---|
| 后端框架 | Spring Boot 2.x | 快速构建高效API接口,处理图书借阅、进馆预约、健康打卡等核心业务逻辑 |
| 前端技术 | JSP + Layui | 构建简洁直观的管理类界面,适配管理员、员工、用户三类角色操作场景 |
| 数据库 | MySQL 8.0 | 安全存储用户信息、图书数据、预约记录、健康打卡数据等核心信息 |
| 架构模式 | B/S(浏览器/服务器) | 无需客户端安装,支持管理员、员工在馆内办公设备,用户在家用设备随时访问 |
| 文件存储 | 本地文件系统 | 存储图书封面图片、用户头像、员工照片等静态资源 |
| 开发工具 | Eclipse + Navicat | 高效完成代码开发与数据库可视化管理,便捷维护图书、用户等数据 |
三、项目全流程:6步完成疫情下图书馆管理系统开发
3.1 第一步:需求分析——明确系统核心价值
针对传统图书馆管理的“防控难、效率低”痛点,系统聚焦“疫情防控精准化、借阅流程线上化、管理数据可视化”,明确三角色的核心需求:
3.1.1 功能性需求
-
三角色权限体系
- 管理员:个人中心(密码修改、信息维护)、用户管理(新增/编辑/删除用户)、员工管理(新增/编辑/审核员工)、图书分类管理(配置图书类别)、图书信息管理(上架/编辑/下架图书)、健康打卡管理(查看用户健康数据)、系统管理(发布温馨提示、配置系统参数);
- 员工:个人中心(密码修改)、预约借阅管理(审核用户借阅申请)、预约归还管理(审核用户归还申请)、查看图书与用户基础信息;
- 普通用户:个人中心(资料维护、密码修改)、图书信息查询(按分类/名称筛选)、进馆预约(选择日期与人数)、预约借阅/归还(提交图书借阅/归还申请)、健康打卡(每日上报体温与健康状况)、收藏管理(收藏心仪图书)。
-
核心业务功能
- 图书全生命周期管理:从图书信息录入、分类配置到用户查询、借阅/归还的完整流程;
- 疫情防控闭环:用户健康打卡→进馆预约→员工审核→用户到馆的全流程管控,避免人流聚集;
- 多维度查询:支持用户按图书分类、名称筛选图书,管理员/员工按条件查询用户、预约记录;
- 互动与提示:管理员发布温馨提示(如开馆时间调整、疫情防控要求),用户接收审核结果反馈;
- 数据记录:自动存储用户借阅/归还时间、健康打卡数据,便于后续追溯与统计。
3.1.2 非功能性需求
- 系统性能:支持30+并发用户操作(如同时提交进馆预约),图书查询响应时间<2秒,数据加载流畅;
- 数据安全:用户密码加密存储(MD5),健康打卡等敏感数据仅管理员可见,防止信息泄露;
- 用户体验:界面符合管理类系统操作习惯,核心功能(如预约借阅)操作步骤≤3步;
- 兼容性:支持Chrome、Edge、Firefox等主流浏览器,适配图书馆办公电脑与用户家用设备分辨率。
3.2 第二步:系统设计——构建整体架构
系统采用分层设计思想,确保各模块职责清晰、可维护性强,同时满足疫情下图书馆“防控优先、管理高效”的要求:
3.2.1 系统总体架构
-
前端架构
- 基于JSP实现页面动态渲染,结合Layui提供的表单、表格、弹窗等组件,快速搭建管理类界面;
- 采用Ajax实现异步数据交互(如用户提交借阅申请、员工审核反馈),避免页面刷新,提升操作效率;
- 按角色划分权限视图:管理员登录后展示完整管理菜单,员工仅显示“预约审核”相关功能,用户仅可见“图书查询、预约”等功能模块。
-
后端架构
- 基于Spring Boot实现分层架构:Controller(接口层,处理HTTP请求)、Service(业务逻辑层,实现借阅审核、健康打卡等核心功能)、Mapper(数据访问层,操作数据库);
- 统一异常处理机制:捕获业务异常(如“图书已被借阅”“用户未打卡无法预约”)并返回友好提示;
- 权限拦截器:验证用户登录状态与角色权限,防止用户越权访问(如普通用户无法进入员工审核页面)。
-
数据持久层
- 采用MyBatis实现数据库操作,通过XML配置SQL语句,降低代码耦合度;
- 配置HikariCP数据库连接池,优化数据库访问性能,确保多用户同时操作时的稳定性。
3.2.2 核心数据库设计
系统设计16张核心数据表,覆盖用户、图书、预约、健康打卡等全业务场景,关键表结构如下:
| 表名 | 核心字段 | 作用 |
|---|---|---|
| 用户表(user) | id、账号、密码(加密)、姓名、性别、手机、生日、住址、照片、创建时间 | 存储用户基本信息,控制登录与操作权限 |
| 员工表(yuangong) | id、员工账号、密码(加密)、员工姓名、性别、手机、生日、住址、照片、创建时间 | 存储员工信息,支持员工登录与审核操作 |
| 图书信息表(tushuxinxi) | id、图书编号、图书名称、图书分类、图片、作者、出版社、详情、点击次数、创建时间 | 存储图书核心信息,供用户查询与借阅 |
| 预约借阅表(yuyuejieyue) | id、借阅编号、图书编号、图书名称、账号、姓名、手机、借阅时间、是否审核、审核回复、创建时间 | 记录用户借阅申请与审核结果 |
| 预约归还表(yuyueguihuan) | id、归还编号、图书编号、图书名称、账号、姓名、手机、归还时间、是否审核、审核回复、创建时间 | 记录用户归还申请与审核结果 |
| 进馆预约表(jingguanyuyue) | id、图书馆名称、进馆日期、人数、备注、图片、创建时间 | 记录用户进馆预约信息,支持疫情人流管控 |
| 健康打卡表(jiankangdaka) | id、账号、姓名、手机、健康情况、接触史、今日体温、佩戴口罩、打卡日期、创建时间 | 存储用户健康数据,落实疫情防控要求 |
| 温馨提示表(wenxintishi) | id、标题、内容、时间、封面、创建时间 | 存储管理员发布的通知,如防控要求、开馆调整 |
3.3 第三步:后端核心功能实现——Spring Boot架构
基于Spring Boot框架实现系统核心业务逻辑,重点突破“图书借阅/归还审核”“进馆预约管理”“健康打卡”三大核心场景,确保功能符合疫情下图书馆管理实际需求:
3.3.1 预约借阅管理功能实现(员工核心操作)
@RestController
@RequestMapping("/api/borrow")
public class BorrowController {
@Autowired
private BorrowService borrowService;
/**
* 用户提交图书预约借阅申请
*/
@PostMapping("/apply")
public ResponseEntity<?> applyBorrow(@RequestBody BorrowDTO borrowDTO,
@RequestHeader("userId") Long userId) {
try {
// 参数校验:图书编号、借阅时间为必填项
if (StringUtils.isEmpty(borrowDTO.getTushubianhao()) ||
borrowDTO.getJieyueshijian() == null) {
return ResponseEntity.badRequest().body("图书编号、借阅时间不能为空");
}
// 校验用户是否已完成当日健康打卡(疫情防控要求)
boolean hasCheckedIn = borrowService.checkHealthCheckIn(userId);
if (!hasCheckedIn) {
return ResponseEntity.badRequest().body("未完成当日健康打卡,无法提交借阅申请");
}
// 提交借阅申请
Yuyuejieyue borrowRecord = borrowService.applyBorrow(borrowDTO, userId);
return ResponseEntity.ok("借阅申请提交成功,申请编号:" + borrowRecord.getJieyuebianhao());
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("借阅申请提交失败:" + e.getMessage());
}
}
/**
* 员工审核借阅申请
*/
@PostMapping("/audit")
public ResponseEntity<?> auditBorrow(@RequestBody BorrowAuditDTO auditDTO,
@RequestHeader("employeeId") Long employeeId) {
try {
// 参数校验:申请ID、审核结果、审核回复为必填项
if (auditDTO.getId() == null || auditDTO.getSfsh() == null ||
StringUtils.isEmpty(auditDTO.getShhf())) {
return ResponseEntity.badRequest().body("申请ID、审核结果、审核回复不能为空");
}
// 审核借阅申请
Yuyuejieyue borrowRecord = borrowService.auditBorrow(auditDTO);
return ResponseEntity.ok("借阅申请审核完成,审核结果:" + auditDTO.getSfsh() + ",回复:" + borrowRecord.getShhf());
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("借阅申请审核失败:" + e.getMessage());
}
}
}
@Service
@Transactional
public class BorrowServiceImpl implements BorrowService {
@Autowired
private YuyuejieyueMapper borrowMapper;
@Autowired
private JiankangdakaMapper healthCheckInMapper;
@Autowired
private TushuxinxiMapper bookMapper;
@Override
public boolean checkHealthCheckIn(Long userId) {
// 查询用户当日健康打卡记录
JiankangdakaExample example = new JiankangdakaExample();
example.createCriteria()
.andUseridEqualTo(userId)
.andDakariqiEqualTo(new Date()); // 简化处理,实际需按日期范围匹配
return healthCheckInMapper.countByExample(example) > 0;
}
@Override
public Yuyuejieyue applyBorrow(BorrowDTO dto, Long userId) {
// 1. 校验图书是否存在且可借阅
Tushuxinxi book = bookMapper.selectByPrimaryKey(dto.getTushubianhao());
if (book == null) {
throw new RuntimeException("该图书不存在");
}
// 2. 生成唯一借阅编号(如:BORROW_20240520_001)
String borrowNo = "BORROW_" + new SimpleDateFormat("yyyyMMdd").format(new Date()) +
"_" + String.format("%03d", borrowMapper.countByExample(new YuyuejieyueExample()) + 1);
// 3. 构建借阅记录实体
Yuyuejieyue borrowRecord = new Yuyuejieyue();
borrowRecord.setJieyuebianhao(borrowNo);
borrowRecord.setTushubianhao(dto.getTushubianhao());
borrowRecord.setTushumingcheng(book.getTushumingcheng());
borrowRecord.setTushufenlei(book.getTushufenlei());
borrowRecord.setZuozhe(book.getZuozhe());
borrowRecord.setTupian(book.getTupian());
borrowRecord.setZhanghao(dto.getZhanghao());
borrowRecord.setXingming(dto.getXingming());
borrowRecord.setShouji(dto.getShouji());
borrowRecord.setJieyueshijian(dto.getJieyueshijian());
borrowRecord.setSfsh("待审核"); // 初始状态为待审核
borrowRecord.setShhf("");
borrowRecord.setAddtime(new Date());
// 4. 保存借阅记录
borrowMapper.insert(borrowRecord);
return borrowRecord;
}
@Override
public Yuyuejieyue auditBorrow(BorrowAuditDTO dto) {
// 1. 查询借阅记录
Yuyuejieyue borrowRecord = borrowMapper.selectByPrimaryKey(dto.getId());
if (borrowRecord == null) {
throw new RuntimeException("该借阅申请不存在");
}
// 2. 更新审核状态与回复
borrowRecord.setSfsh(dto.getSfsh());
borrowRecord.setShhf(dto.getShhf());
borrowMapper.updateByPrimaryKeySelective(borrowRecord);
return borrowRecord;
}
}
3.3.2 进馆预约与健康打卡功能实现(疫情防控核心)
@RestController
@RequestMapping("/api/reserve")
public class ReserveController {
@Autowired
private ReserveService reserveService;
/**
* 用户提交进馆预约
*/
@PostMapping("/apply")
public ResponseEntity<?> applyReserve(@RequestBody ReserveDTO reserveDTO,
@RequestHeader("userId") Long userId) {
try {
// 参数校验:图书馆名称、进馆日期、人数为必填项
if (StringUtils.isEmpty(reserveDTO.getTushuguanmingcheng()) ||
reserveDTO.getJinguanriqi() == null || reserveDTO.getRenshu() == null) {
return ResponseEntity.badRequest().body("图书馆名称、进馆日期、人数不能为空");
}
// 提交进馆预约
Jingguanyuyue reserveRecord = reserveService.applyReserve(reserveDTO, userId);
return ResponseEntity.ok("进馆预约提交成功,预约编号:" + reserveRecord.getId());
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("进馆预约提交失败:" + e.getMessage());
}
}
}
@RestController
@RequestMapping("/api/health")
public class HealthCheckInController {
@Autowired
private HealthCheckInService healthCheckInService;
/**
* 用户提交健康打卡
*/
@PostMapping("/checkIn")
public ResponseEntity<?> healthCheckIn(@RequestBody HealthCheckInDTO checkInDTO,
@RequestHeader("userId") Long userId) {
try {
// 参数校验:健康情况、今日体温、佩戴口罩状态为必填项
if (StringUtils.isEmpty(checkInDTO.getJiankangqingkuang()) ||
StringUtils.isEmpty(checkInDTO.getJinritiwen()) ||
StringUtils.isEmpty(checkInDTO.getPeidaikouzhao())) {
return ResponseEntity.badRequest().body("健康情况、今日体温、佩戴口罩状态不能为空");
}
// 提交健康打卡
Jiankangdaka checkInRecord = healthCheckInService.healthCheckIn(checkInDTO, userId);
return ResponseEntity.ok("健康打卡成功,打卡日期:" + new SimpleDateFormat("yyyy-MM-dd").format(checkInRecord.getDakariqi()));
} catch (Exception e) {
return ResponseEntity.internalServerError()
.body("健康打卡失败:" + e.getMessage());
}
}
}
3.4 第四步:前端界面实现——管理类系统操作平台
基于JSP + Layui构建前端界面,贴合疫情下图书馆“防控优先、操作简洁”需求,按角色划分核心界面:
3.4.1 核心界面设计
- 登录界面:支持管理员/员工/用户三角色登录,输入账号密码后验证权限并跳转至对应首页,含“忘记密码”功能(用户/员工可重置,管理员需联系超级管理员);
- 管理员后台:
- 首页:展示系统核心数据(图书总数、用户总数、员工总数、待审核借阅/归还申请数);
- 用户管理:表格展示用户列表,支持新增(填写姓名、手机等信息)、编辑、删除;
- 员工管理:表格展示员工信息,支持新增(上传员工照片、配置联系方式)、编辑、删除;
- 图书信息管理:表格展示图书列表,支持按分类筛选,点击“编辑”修改图书作者、出版社等信息;
- 健康打卡管理:表格展示用户打卡数据,支持按日期、账号筛选,查看用户健康状况;
- 温馨提示管理:表单式编辑温馨提示,支持上传封面图片、填写防控通知内容;
- 员工后台:
- 首页:展示待审核借阅/归还申请数;
- 预约借阅管理:表格展示借阅申请,支持查看详情、审核(通过/拒绝并填写回复);
- 预约归还管理:表格展示归还申请,支持查看详情、审核;
- 用户前台:
- 首页:顶部导航(首页、图书信息、进馆预约、健康打卡、留言反馈),中部展示温馨提示与热门图书;
- 图书信息页:左侧筛选栏(按图书分类),右侧展示图书卡片(含封面、名称、作者),点击卡片查看详情并提交借阅申请;
- 进馆预约页:选择图书馆名称、进馆日期、人数,填写备注后提交预约;
- 健康打卡页:下拉选择健康情况、输入体温、选择是否佩戴口罩,提交打卡;
- 个人中心:维护个人信息、修改密码、查看借阅/归还记录与预约状态。
3.4.2 设计亮点
- 防控优先设计:用户进入前台首页时,优先提示“未打卡无法预约”,强制落实疫情防控要求;
- 操作简洁性:员工审核借阅/归还申请时,采用弹窗式快速审核,无需跳转页面,提升效率;
- 信息可视化:管理员首页用数字卡片展示核心数据,直观掌握系统运行状态;
- 权限清晰:不同角色界面菜单严格区分,避免功能混淆(如用户看不到“员工管理”菜单)。
3.5 第五步:系统测试——确保图书馆管理系统稳定性
通过多维度测试验证系统功能完整性、性能稳定性和安全性,符合疫情下图书馆“防控严格、管理高效”的要求:
3.5.1 功能测试
| 测试场景 | 测试用例 | 预期结果 | 实际结果 |
|---|---|---|---|
| 用户提交健康打卡 | 选择“健康”、输入“36.5℃”、选择“是”(佩戴口罩),提交 | 打卡成功,管理员后台可查 | 打卡成功,数据同步正常 |
| 员工审核借阅申请 | 选择“待审核”借阅申请,点击“通过”并填写“可到馆领取”,提交 | 审核状态更新为“已通过”,用户可查回复 | 审核成功,状态与回复同步 |
| 用户提交进馆预约 | 选择图书馆名称、进馆日期(次日)、人数(1人),提交 | 预约成功,记录存入数据库 | 预约成功,数据存储正常 |
| 管理员新增图书 | 填写图书名称、作者、上传封面,选择分类,提交 | 图书新增成功,用户前台可见 | 新增成功,展示正常 |
3.5.2 性能测试
- 并发测试:模拟20名用户同时提交健康打卡、10名员工同时审核借阅申请,系统响应时间<2秒,无数据丢失;
- 数据加载测试:加载100条图书信息、50条用户健康打卡数据,表格分页流畅,筛选响应时间<1秒;
- 稳定性测试:连续72小时运行系统,模拟管理员日常操作(新增用户、编辑图书),无崩溃或数据异常。
3.5.3 安全性测试
| 测试项 | 测试方法 | 预期结果 | 实际结果 |
|---|---|---|---|
| 密码加密 | 查看数据库user表mima字段 | 密码以加密形式存储(如MD5) | 符合预期,加密存储 |
| 越权访问 | 用户角色直接访问管理员“员工管理”接口 | 跳转至登录页,提示“无权限” | 符合预期,拦截成功 |
| 敏感数据保护 | 普通用户查看其他用户健康打卡数据 | 提示“无权限查看” | 符合预期,数据保护正常 |
| 数据校验 | 提交健康打卡时输入“40℃”(异常体温) | 提示“体温异常,请确认后提交” | 符合预期,校验成功 |
3.6 第六步:问题排查与优化——提升图书馆管理体验
开发过程中遇到的核心问题及解决方案,确保系统符合疫情下图书馆管理的实际需求:
- 问题:用户提交进馆预约时,未限制同一用户单日多次预约,导致人流统计混乱
解决方案:优化预约逻辑,新增“同一用户单日仅可提交1次进馆预约”校验,重复提交时提示“今日已预约,不可重复申请”; - 问题:图书借阅申请审核后,用户未及时收到反馈,导致到馆领取延迟
解决方案:在审核完成后增加“系统通知”功能,通过页面弹窗提示用户审核结果,同时记录通知时间; - 问题:管理员查询用户健康打卡数据时,大量数据加载缓慢
解决方案:对健康打卡表的“dakariqi”(打卡日期)、“zhanghao”(账号)字段建立索引,优化SQL查询语句,加载时间从5秒缩短至1秒内; - 问题:用户忘记健康打卡,无法提交借阅申请,无引导提示
解决方案:在用户提交借阅申请时,若未打卡则弹窗提示“请先完成今日健康打卡”,并提供“前往打卡”跳转按钮,简化操作流程。
四、毕业设计复盘:图书馆管理系统开发实践总结
4.1 开发过程中的技术挑战
- 多角色权限控制:管理员、员工、用户三类角色的功能边界划分,需确保员工无法修改用户健康数据、用户无法查看其他用户预约记录;
- 疫情防控逻辑整合:健康打卡与进馆预约、借阅申请的关联校验(如未打卡不可预约),需避免逻辑漏洞导致防控失效;
- 数据关联设计:图书信息、借阅记录、用户信息的多表关联查询(如按用户查询借阅历史),需确保数据一致性与查询效率;
- 用户体验平衡:疫情防控要求的“多步骤校验”与用户“便捷操作”的平衡,避免流程繁琐导致用户放弃使用。
4.2 给后续开发者的建议
- 技术选型:优先选择成熟稳定的技术栈(如Spring Boot + MySQL),管理类系统对稳定性的要求高于新技术尝鲜;
- 数据库设计:提前梳理业务数据关系(如用户-借阅记录-图书的关联),设计合理的表结构与索引,避免后期重构;
- 功能迭代:采用“核心功能优先”策略,先实现健康打卡、借阅审核等疫情防控核心功能,再迭代收藏、留言等附加功能;
- 用户视角优化:从图书馆用户(如学生、读者)视角出发,简化操作流程(如首页增加“快速预约”入口),降低使用门槛;
- 文档完善:编写详细的接口文档与操作手册,方便图书馆工作人员后期维护(如新增图书的操作步骤)。
五、项目资源与发展展望
5.1 项目核心资源
本项目提供完整的开发与部署资料,方便后续学习和二次开发,满足毕业设计与疫情下图书馆管理实际应用需求:
- 后端源码:完整的Spring Boot项目,包含所有业务逻辑代码(Controller、Service、Mapper),注释详细;
- 前端源码:JSP页面文件、Layui配置文件、JS脚本,可直接运行;
- 数据库脚本:MySQL建表语句和示例数据(含测试管理员账号、员工账号、用户账号);
- 部署指南:详细的环境配置(JDK 1.8、Tomcat 8.5、MySQL 8.0)和项目部署步骤;
- 使用手册:管理员、员工、用户的操作指南,含界面截图和步骤描述,适配图书馆工作人员培训需求。
5.2 系统扩展方向
- 智能化升级:集成AI图书推荐功能,根据用户借阅历史推荐相似图书(如用户借阅“计算机编程”类图书,推荐同分类新书);
- 移动端适配:开发微信小程序,支持用户在手机上完成健康打卡、进馆预约、借阅申请,提升便捷性;
- 图书到期提醒:新增“短信/微信提醒”功能,在图书借阅到期前3天通知用户,降低逾期率;
- 数据统计分析:增加可视化报表(如热门图书借阅量、用户打卡率、进馆人数趋势),为图书馆管理决策提供数据支持;
- 线上阅读模块:整合电子图书资源,支持用户在线阅读部分图书章节,拓展服务形式。
如果本文对您的Spring Boot学习、疫情下图书馆管理类毕业设计有帮助,欢迎点赞 + 收藏 + 关注,后续会分享更多企业级管理类项目实战案例!