基于SpringBoot+小程序的实验室预约管理系统的设计与实现
1. 项目背景与意义随着高校及科研机构实验室规模的扩大和信息化建设的深入传统的人工预约、电话预约或纸质登记管理模式已难以满足高效、透明、便捷的管理需求。实验室预约管理系统应运而生旨在通过数字化手段解决以下痛点管理效率低下人工处理预约申请、审核、排期耗时耗力易出错。信息不透明学生无法实时查看实验室设备状态、空闲时段导致资源闲置与冲突并存。流程不规范审批流程依赖人工传递缺乏标准化、可追溯的记录。移动化需求迫切师生更倾向于使用手机等移动终端随时随地进行预约操作。本系统采用“SpringBoot后端 微信小程序前端”的技术架构实现了实验室资源的在线可视化预约、智能审核、数据统计与分析对于提升实验室管理现代化水平、优化资源配置、服务教学科研具有重要的实践意义。2. 技术栈选型2.1 后端技术栈 (SpringBoot)核心框架Spring Boot 2.7提供快速启动和自动配置。Web框架Spring MVC处理RESTful API请求。数据持久层MyBatis-Plus简化CRUD操作内置分页、代码生成器。数据库MySQL 8.0关系型数据库存储用户、实验室、预约、设备等核心数据。缓存Redis用于存储会话信息、验证码、热点数据如实验室状态提升系统响应速度。安全与权限Spring Security JWT (JSON Web Token)实现用户认证与接口权限控制。API文档Knife4j (Swagger增强)自动生成并美化后端API接口文档。其他工具Lombok简化代码、Hutool工具集、Quartz定时任务如自动释放超时未确认预约。2.2 前端技术栈 (微信小程序)开发框架微信小程序原生框架使用WXML、WXSS、JavaScript。UI组件库Vant Weapp 或 ColorUI提供丰富的预制组件加速开发。网络请求wx.request 封装配合Promise或async/await处理异步API调用。状态管理小程序全局变量或简易的观察者模式管理用户登录状态、实验室列表等共享数据。地图与日历集成微信小程序内置地图组件展示实验室位置、自定义日历组件可视化选择预约日期。2.3 开发与部署项目管理Maven / Gradle。版本控制Git。部署后端可打包为JAR部署至Linux服务器如使用Nginx反向代理小程序前端提交至微信公众平台审核发布。3. 系统核心功能模块设计3.1 用户端小程序功能用户注册/登录学工号绑定微信一键登录。实验室浏览与搜索按名称、类型、楼宇筛选查看实验室详情图片、设备、容量、规则。预约功能选择实验室、日期、时段提交预约申请。我的预约查看预约记录待审核、已通过、已拒绝、已完成支持取消预约。消息通知接收审核结果、预约提醒等微信模板消息。3.2 管理端Web后台功能实验室管理CRUD操作设置开放时间、预约规则、关联设备。预约审核审批或拒绝用户提交的预约申请填写审批意见。用户管理管理学生、教师、管理员账号与角色权限。数据统计可视化仪表盘展示实验室使用率、热门时段、用户预约频次等。系统设置公告发布、预约规则配置如最长预约时长、提前预约天数。4. 数据库核心表设计-- 用户表 CREATE TABLE sys_user ( id bigint PRIMARY KEY AUTO_INCREMENT, username varchar(50) NOT NULL COMMENT 学工号, password varchar(255) NOT NULL COMMENT 密码加密, real_name varchar(20) COMMENT 真实姓名, role varchar(20) DEFAULT STUDENT COMMENT 角色STUDENT, TEACHER, ADMIN, openid varchar(100) COMMENT 微信OpenID用于小程序登录, create_time datetime DEFAULT CURRENT_TIMESTAMP ); -- 实验室表 CREATE TABLE lab ( id bigint PRIMARY KEY AUTO_INCREMENT, name varchar(100) NOT NULL COMMENT 实验室名称, location varchar(200) COMMENT 位置, capacity int COMMENT 最大容纳人数, description text COMMENT 描述, status tinyint DEFAULT 1 COMMENT 状态0-关闭1-开放, rules text COMMENT 预约规则JSON格式 ); -- 预约记录表核心业务表 CREATE TABLE reservation ( id bigint PRIMARY KEY AUTO_INCREMENT, user_id bigint NOT NULL COMMENT 预约用户ID, lab_id bigint NOT NULL COMMENT 实验室ID, date date NOT NULL COMMENT 预约日期, start_time time NOT NULL COMMENT 开始时间, end_time time NOT NULL COMMENT 结束时间, purpose varchar(500) COMMENT 使用目的, status varchar(20) DEFAULT PENDING COMMENT 状态PENDING, APPROVED, REJECTED, CANCELLED, COMPLETED, audit_comment varchar(500) COMMENT 审核意见, auditor_id bigint COMMENT 审核人ID, audit_time datetime COMMENT 审核时间, create_time datetime DEFAULT CURRENT_TIMESTAMP ); -- 设备表与实验室关联 CREATE TABLE equipment ( id bigint PRIMARY KEY AUTO_INCREMENT, lab_id bigint NOT NULL, name varchar(100) NOT NULL, model varchar(100), status varchar(20) DEFAULT AVAILABLE COMMENT 状态 );5. 核心代码示例 (SpringBoot MyBatis-Plus)5.1 实体类 (Reservation.java)import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import java.time.LocalDate; import java.time.LocalTime; import java.time.LocalDateTime; Data TableName(reservation) public class Reservation { TableId(type IdType.AUTO) private Long id; private Long userId; private Long labId; private LocalDate date; private LocalTime startTime; private LocalTime endTime; private String purpose; private String status; // PENDING, APPROVED... private String auditComment; private Long auditorId; private LocalDateTime auditTime; TableField(fill FieldFill.INSERT) private LocalDateTime createTime; }5.2 Mapper 接口 (ReservationMapper.java)import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import java.time.LocalDate; import java.util.List; Mapper public interface ReservationMapper extends BaseMapperReservation { // 自定义查询检查某个实验室在某个时间段是否已被预约 Select(SELECT COUNT(*) FROM reservation WHERE lab_id #{labId} AND date #{date} AND status IN (APPROVED, PENDING) AND ((start_time #{endTime} AND end_time #{startTime}))) int checkTimeConflict(Param(labId) Long labId, Param(date) LocalDate date, Param(startTime) String startTime, Param(endTime) String endTime); // 查询用户预约历史联表查询实验室名称 ListReservationVO selectUserReservations(Param(userId) Long userId); }5.3 Service 层核心逻辑 (ReservationService.java)import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; Service public class ReservationService extends ServiceImplReservationMapper, Reservation { Autowired private ReservationMapper reservationMapper; Transactional public ApiResult createReservation(ReservationDTO dto) { // 1. 参数校验 if (dto.getStartTime().isAfter(dto.getEndTime())) { return ApiResult.error(开始时间不能晚于结束时间); } // 2. 检查时间冲突 int conflictCount reservationMapper.checkTimeConflict( dto.getLabId(), dto.getDate(), dto.getStartTime().toString(), dto.getEndTime().toString() ); if (conflictCount 0) { return ApiResult.error(该时段已被预约请选择其他时间); } // 3. 构建实体并保存 Reservation reservation new Reservation(); BeanUtils.copyProperties(dto, reservation); reservation.setStatus(PENDING); boolean saved save(reservation); if (saved) { // 4. 可在此处触发微信模板消息通知管理员审核 return ApiResult.success(预约申请提交成功等待审核, reservation.getId()); } else { return ApiResult.error(预约提交失败); } } Transactional public ApiResult auditReservation(Long reservationId, String status, String comment, Long auditorId) { Reservation reservation getById(reservationId); if (reservation null) { return ApiResult.error(预约记录不存在); } if (!PENDING.equals(reservation.getStatus())) { return ApiResult.error(当前状态不可审核); } reservation.setStatus(status); reservation.setAuditComment(comment); reservation.setAuditorId(auditorId); reservation.setAuditTime(LocalDateTime.now()); boolean updated updateById(reservation); if (updated) { // 审核后通知用户 notifyUser(reservation.getUserId(), status, comment); return ApiResult.success(审核操作成功); } return ApiResult.error(审核操作失败); } }5.4 Controller 层接口 (ReservationController.java)import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; RestController RequestMapping(/api/reservation) public class ReservationController { Autowired private ReservationService reservationService; PostMapping(/create) public ApiResult create(RequestBody Valid ReservationDTO dto) { return reservationService.createReservation(dto); } GetMapping(/my) public ApiResultListReservationVO getMyReservations(RequestHeader(Authorization) String token) { Long userId JwtUtil.getUserIdFromToken(token); ListReservationVO list reservationService.getUserReservations(userId); return ApiResult.success(list); } PostMapping(/audit) PreAuthorize(hasRole(ADMIN)) // 权限控制仅管理员可访问 public ApiResult audit(RequestBody AuditDTO auditDTO) { Long auditorId JwtUtil.getUserIdFromToken(SecurityUtils.getCurrentUserToken()); return reservationService.auditReservation( auditDTO.getReservationId(), auditDTO.getStatus(), auditDTO.getComment(), auditorId ); } }6. 小程序端核心页面示例 (WXML JS)6.1 实验室列表页 (pages/lab/list/index.wxml)!-- 实验室列表页 WXML 片段 -- view classpage view classsearch-bar input placeholder搜索实验室名称 bindinputonSearchInput / /view view wx:for{{labList}} wx:keyid classlab-card bindtapgoToDetail>// 预约提交 JS 逻辑 Page({ data: { labId: , date: , startTime: 09:00, endTime: 11:00, purpose: }, // 提交预约申请 submitReservation() { const that this; const { labId, date, startTime, endTime, purpose } this.data; if (!labId || !date || !purpose) { wx.showToast({ title: 请填写完整信息, icon: none }); return; } wx.showLoading({ title: 提交中... }); wx.request({ url: https://your-domain.com/api/reservation/create, method: POST, header: { Authorization: wx.getStorageSync(token), Content-Type: application/json }, data: { labId, date, startTime, endTime, purpose }, success(res) { wx.hideLoading(); if (res.data.code 200) { wx.showToast({ title: 预约提交成功 }); setTimeout(() { wx.navigateBack(); }, 1500); } else { wx.showToast({ title: res.data.msg || 提交失败, icon: none }); } }, fail() { wx.hideLoading(); wx.showToast({ title: 网络错误, icon: none }); } }); } })7. 总结与展望本文详细阐述了基于 SpringBoot 后端与微信小程序前端构建实验室预约管理系统的整体方案。系统通过清晰的分层架构、合理的技术选型与数据库设计实现了实验室预约的核心业务流程。核心代码示例涵盖了后端从实体、Mapper、Service到Controller的关键实现以及小程序前端页面与交互逻辑。未来可扩展方向包括智能排期引入算法根据历史数据自动推荐最优预约时段。物联网集成对接门禁、电源控制器实现预约成功后自动开门通电。数据深度分析利用大数据技术分析实验室使用模式为资源采购与管理决策提供支持。多端适配开发Web管理端、APP端满足不同角色用户的使用习惯。该系统具有良好的可扩展性和实用性可作为高校及企业实验室信息化建设的参考实现。