跳到正文
Joeplover
后端开发·2025-12-03·约 3 分钟阅读

Joejoe_Hotel:Spring Boot + MyBatis-Plus 酒店管理系统

完整的酒店后台管理系统,集成 MyBatis-Plus、Spring Security、JWT、Druid、Swagger 等技术栈。

酒店管理系统

Joejoe_Hotel:Spring Boot + MyBatis-Plus 酒店管理系统

系统功能

包含酒店管理的基本模块:房间管理、预订管理、入住登记、订单结算。虽然功能看起来常规,但酒店业务有几个很有意思的技术难点。

核心难点:时间冲突检测

酒店预订系统最核心的算法是检测两个预订时间段是否重叠:

public boolean hasConflict(Long roomId, Date newStart, Date newEnd) {
    // 冲突条件:新预订开始 < 已有预订结束 AND 新预订结束 > 已有预订开始
    LambdaQueryWrapper<Booking> wrapper = Wrappers.<Booking>lambdaQuery()
        .eq(Booking::getRoomId, roomId)
        .in(Booking::getStatus, "confirmed", "checked_in")
        .lt(Booking::getCheckIn, newEnd)    // 已有开始 < 新结束
        .gt(Booking::getCheckOut, newStart); // 已有结束 > 新开始
    
    return bookingMapper.selectCount(wrapper) > 0;
}

这个冲突检测逻辑不局限于酒店——会议室预约、租车、机房机位、教室等所有需要"时间段独占"的场景都适用。

需要注意的边界情况:

  • 入住当天 14:00 到退房当天 12:00 算一天(时间精度问题)
  • 同一个房间的连续预订中间需要预留打扫时间(+2 小时)
  • 跨月、跨年的预订日期计算

房间状态流转

房间有 4 种状态,状态转换有严格限制:

空闲 ──预订──→ 已预订 ──入住──→ 入住中 ──退房──→ 空闲
  ↑                ↑                    ↓
  └──打扫完成──← 打扫中 ←───── 退房 ─────────┘

状态机实现:

public enum RoomStatus {
    AVAILABLE,      // 空闲
    RESERVED,      // 已预订(未入住)
    OCCUPIED,      // 入住中
    CLEANING;      // 打扫中
    
    public boolean canTransitionTo(RoomStatus target) {
        return switch (this) {
            case AVAILABLE -> target == RESERVED;
            case RESERVED -> target == OCCUPIED || target == AVAILABLE;
            case OCCUPIED -> target == CLEANING;
            case CLEANING -> target == AVAILABLE;
        };
    }
}

状态机可以防止非法操作:比如入住中的房间不能跳过打扫直接变为空闲。

价格体系

酒店价格根据不同日期变化:

  • 平日:标准价
  • 周末:标准价 × 1.2
  • 节假日:标准价 × 1.5-2.0(如春节、国庆)
  • 连住优惠:连住 3 天以上打 9 折
public BigDecimal calculatePrice(Room room, LocalDate start, LocalDate end) {
    BigDecimal total = BigDecimal.ZERO;
    LocalDate date = start;
    while (date.isBefore(end)) {
        BigDecimal price = isHoliday(date) ? room.getHolidayPrice()
                        : isWeekend(date) ? room.getWeekendPrice()
                        : room.getWeekdayPrice();
        total = total.add(price);
        date = date.plusDays(1);
    }
    // 连住优惠
    long nights = ChronoUnit.DAYS.between(start, end);
    if (nights >= 3) total = total.multiply(new BigDecimal("0.9"));
    return total;
}

总结

酒店管理系统的难点不在 CRUD,而在时间冲突检测、状态机管理、动态定价这三个业务逻辑。这些模式在会议室、机票、租车等预订类系统中都是通用的,理解了一个就等于理解了全部。