ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

SpringBoot高校浴室预约系统设计与实现:技术栈、背景意义与核心代码

2026/8/14 7:30:52 拓冰建站 浏览量
SpringBoot高校浴室预约系统设计与实现:技术栈、背景意义与核心代码

1. 项目背景与意义

在高校校园生活中,公共浴室是学生日常必需的基础设施。传统的“先到先得”排队模式在高峰时段(如下课后、晚间)常导致学生长时间排队等候,不仅浪费宝贵的学习和休息时间,也容易引发拥挤、插队等管理问题。同时,浴室管理者难以实时掌握各时段使用情况,无法进行有效的资源调配和能耗管理。

因此,开发一套基于SpringBoot的高校浴室预约系统具有重要的现实意义:

  • 提升学生体验:学生可提前规划洗浴时间,避免无效排队,实现错峰使用。
  • 优化资源配置:系统可统计各时段预约数据,为浴室开放时间、淋浴位数量调整提供数据支持。
  • 提高管理效率:实现预约、签到、结算全流程线上化,减少人工管理成本。
  • 节能环保:通过预约控制人流量,避免浴室空转,达到节水节电的目的。

2. 系统技术栈选型

本系统采用前后端分离的架构设计,后端基于SpringBoot快速构建,具体技术栈如下:

层次技术选型说明
后端框架Spring Boot 2.7.x快速构建、自动配置、内嵌Tomcat
安全框架Spring Security + JWT实现用户认证与授权,保障接口安全
数据持久层MyBatis-Plus简化CRUD操作,提供强大的条件构造器
数据库MySQL 8.0关系型数据库,存储用户、预约、浴室等核心数据
缓存Redis缓存热点数据(如浴室实时状态)、分布式锁防超卖
消息队列RabbitMQ异步处理预约超时未签到取消、消息通知等任务
API文档Knife4j + Swagger2生成在线API文档,便于前后端联调
前端框架Vue 3 + Element Plus构建用户友好的管理后台与学生端页面
部署与监控Docker, Prometheus, Grafana容器化部署,监控系统运行状态

3. 核心功能模块设计

系统主要分为学生端、管理后台和浴室终端三部分,核心功能模块如下:

  • 用户管理模块:学生注册/登录(支持学号绑定)、个人信息管理。
  • 浴室与淋浴位管理模块:管理员可增删改查浴室信息、淋浴位状态(空闲/占用/维修)。
  • 预约规则管理模块:设置可预约时段(如:每日8:00-22:00)、单次预约时长(如:30分钟)、取消规则等。
  • 预约核心模块:学生查看可预约时段、选择淋浴位、提交预约、支付(可选集成校园卡/微信支付)。
  • 签到与使用模块:学生通过扫码或输入验证码在浴室终端签到,开始使用并计时。
  • 订单与结算模块:记录预约订单、实际使用时长、费用结算(按时间计费或免费)。
  • 数据统计模块:为管理员提供预约热力图、使用率报表、收入统计等。

4. 核心代码实现

4.1 预约服务核心逻辑(防超卖)

预约是系统的核心并发场景,需防止同一时段同一淋浴位被重复预约。这里采用Redis分布式锁 + 数据库乐观锁确保一致性。

@Service @Slf4j public class ReservationServiceImpl implements ReservationService { @Autowired private RedisTemplate<String, String> redisTemplate; @Autowired private BathroomMapper bathroomMapper; @Autowired private ReservationMapper reservationMapper; @Autowired private RabbitTemplate rabbitTemplate; private static final String LOCK_KEY_PREFIX = "reservation:lock:"; @Override @Transactional(rollbackFor = Exception.class) public ApiResult createReservation(ReservationDTO dto) { Long showerId = dto.getShowerId(); LocalDateTime startTime = dto.getStartTime(); LocalDateTime endTime = dto.getEndTime(); // 1. 校验时段是否可预约(业务规则,略) // 2. 尝试获取分布式锁 String lockKey = LOCK_KEY_PREFIX + showerId + ":" + startTime; String lockValue = UUID.randomUUID().toString(); Boolean lockAcquired = redisTemplate.opsForValue() .setIfAbsent(lockKey, lockValue, 30, TimeUnit.SECONDS); if (Boolean.FALSE.equals(lockAcquired)) { return ApiResult.fail("当前淋浴位正在被预约,请稍后重试"); } try { // 3. 双重校验:查询数据库该时段是否已被占用 Integer count = reservationMapper.countByShowerAndTime(showerId, startTime, endTime); if (count > 0) { return ApiResult.fail("该时段已被预约"); } // 4. 扣减淋浴位库存(乐观锁) Bathroom bathroom = bathroomMapper.selectById(showerId); if (bathroom == null || !bathroom.getStatus().equals(ShowerStatus.AVAILABLE)) { return ApiResult.fail("淋浴位不可用"); } // 假设有一个字段表示当前时段是否被占用,这里用版本号控制 int updateRows = bathroomMapper.lockShower(showerId, bathroom.getVersion()); if (updateRows == 0) { return ApiResult.fail("库存更新失败,请重试"); } // 5. 创建预约记录 Reservation reservation = new Reservation(); BeanUtils.copyProperties(dto, reservation); reservation.setOrderNo(IdUtil.simpleUUID()); reservation.setStatus(ReservationStatus.BOOKED); reservationMapper.insert(reservation); // 6. 发送延迟消息,处理超时未签到自动取消 ReservationCancelMessage message = new ReservationCancelMessage(); message.setReservationId(reservation.getId()); rabbitTemplate.convertAndSend( "reservation.delay.exchange", "reservation.cancel", message, msg -> { // 设置15分钟后过期 msg.getMessageProperties().setDelay(15 * 60 * 1000); return msg; } ); return ApiResult.success("预约成功", reservation.getOrderNo()); } finally { // 释放锁(确保原子性,使用Lua脚本) String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Collections.singletonList(lockKey), lockValue); } } }

4.2 浴室终端签到服务

学生到达浴室后,通过终端(如平板)扫码或输入验证码签到,系统开始计时。

@RestController @RequestMapping("/terminal") public class TerminalController { @PostMapping("/checkin") public ApiResult checkIn(@RequestBody CheckInDTO dto) { // 1. 验证预约码或二维码 Reservation reservation = reservationService.getByCheckInCode(dto.getCode()); if (reservation == null) { return ApiResult.fail("预约码无效"); } if (!reservation.getStatus().equals(ReservationStatus.BOOKED)) { return ApiResult.fail("预约状态异常,无法签到"); } if (LocalDateTime.now().isAfter(reservation.getStartTime().plusMinutes(15))) { return ApiResult.fail("已过签到有效期,预约自动取消"); } // 2. 更新预约状态为“使用中”,记录开始时间 reservation.setStatus(ReservationStatus.IN_USE); reservation.setActualStartTime(LocalDateTime.now()); reservationMapper.updateById(reservation); // 3. 更新淋浴位实时状态为“占用”,并写入Redis缓存供前端实时展示 String key = "shower:status:" + reservation.getShowerId(); redisTemplate.opsForValue().set(key, "OCCUPIED", 2, TimeUnit.HOURS); // 4. 发送WebSocket消息,通知管理后台状态更新 webSocketService.sendShowerStatusUpdate(reservation.getShowerId(), "OCCUPIED"); return ApiResult.success("签到成功,请开始使用"); } @PostMapping("/checkout") public ApiResult checkOut(@RequestBody CheckOutDTO dto) { // 结算逻辑:根据实际使用时长计算费用,更新订单状态等 // ... } }

4.3 数据统计(使用热力图)

为管理员提供可视化数据,辅助决策。

@Service public class StatisticsServiceImpl implements StatisticsService { @Override public List<UsageHeatmapVO> getUsageHeatmap(LocalDate startDate, LocalDate endDate) { // 查询指定日期范围内,每小时的预约数量 List<Map<String, Object>> rawData = reservationMapper.selectHourlyCount(startDate, endDate); // 构建热力图数据:日期 -> 小时 -> 数量 Map<LocalDate, Map<Integer, Long>> heatmap = new LinkedHashMap<>(); for (Map<String, Object> row : rawData) { LocalDate date = ((java.sql.Date) row.get("date")).toLocalDate(); Integer hour = (Integer) row.get("hour"); Long count = (Long) row.get("count"); heatmap.computeIfAbsent(date, k -> new HashMap<>()).put(hour, count); } // 转换为前端需要的VO列表 List<UsageHeatmapVO> result = new ArrayList<>(); for (Map.Entry<LocalDate, Map<Integer, Long>> entry : heatmap.entrySet()) { UsageHeatmapVO vo = new UsageHeatmapVO(); vo.setDate(entry.getKey()); vo.setHourlyCounts(entry.getValue()); result.add(vo); } return result; } }

5. 总结与展望

本文介绍了基于SpringBoot的高校浴室预约系统的设计背景、技术栈选型、核心功能模块以及关键代码实现。该系统通过引入线上预约机制,能有效解决高校浴室排队难题,提升资源利用效率与管理水平。

未来可扩展方向

  • 智能推荐:基于历史数据,为学生推荐空闲时段。
  • 硬件集成:与智能水表、门锁联动,实现自动计费与开关控制。
  • 小程序/APP:开发移动端应用,提供更便捷的预约体验。
  • 大数据分析:深入分析使用模式,为校园基础设施建设提供决策支持。