# hotel-reservation-system **Repository Path**: mnbi/hotel-reservation-system ## Basic Information - **Project Name**: hotel-reservation-system - **Description**: 酒店预订系统 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 1 - **Created**: 2025-11-10 - **Last Updated**: 2025-12-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # hotel-reservation-system #### 项目介绍 酒店预订系统 本项目为一体化酒店预订管理系统,集酒店搜索、房型预订与在线支付于一体,支持用户注册登录、订单管理、评论互动及消息推送,覆盖完整入住流程。 #### 软件架构 该项目用到的框架是 Spring Boot 3.5.6 持久层由 Mybatis-plus 逆向工程生成 数据库使用的是 MySQL 8.0 #### 用到的技术 JDK17、MySQL (8.0)、Spring Boot (3.5.6)、MyBatis-Plus (3.5.5)、Redis (3.0.2)、RabbitMQ (3.0.2)、Canal (1.1.3)、JWT、XXL-Job (3.2.0)、Elasticsearch、MongoDB、MinIO、Vue 3、Element Plus、Axios、HTML、CSS、WebSocket 实时通信、支付宝沙箱支付环境 #### 思维导图 ![MindMap](images/MindMap.png) #### 项目收获 - **掌握了 Spring Boot 框架的整体开发流程** 熟悉了从项目初始化、配置管理到依赖整合的完整流程,能够基于 Spring Boot 快速搭建后端服务。 - **熟悉了 MyBatis Plus 的使用与代码生成** 学会使用 MyBatis Plus 实现 CRUD、分页查询、条件构造器等操作,并通过代码生成器快速构建实体、Mapper、Service 层结构。 - **掌握了 Redis 的缓存应用场景** 在项目中使用 Redis 实现了数据缓存、验证码存储、会话管理等功能,理解了缓存穿透、击穿、雪崩等问题及其解决方案。 - **实现了用户登录与 JWT 鉴权机制** 通过 JWT 技术实现前后端分离下的安全认证,掌握了 Token 的生成、校验与刷新流程。 - **熟悉了 RabbitMQ 消息队列的使用** 学会通过异步消息机制优化订单创建、通知、日志等模块,提高系统的解耦性与可靠性。 - **掌握了 MinIO 分布式文件存储的集成与应用** 使用 MinIO 管理用户头像、酒店图片等静态资源,学习了对象存储的上传、访问与安全控制。 - **理解了系统性能优化与数据一致性处理** 通过缓存与数据库的结合使用、异步任务分发、事务控制等方式提升了系统性能与稳定性。 - **增强了项目实战与团队协作能力** 在项目开发过程中学会了 Git 版本控制、代码规范化、模块化开发与多人协作流程,为实际企业开发打下基础。 #### 项目功能介绍 1. 登录注册 系统在用户登录时,会校验用户名和密码,验证通过后生成包含用户ID、用户名、头像等信息的JWT Token。该 Token 返回给前端并存入 localStorage,同时在后端保存到 Redis 中并设置30分钟有效期,实现登录状态自动过期与续签。系统通过登录拦截器对受限接口进行验证:若请求头中未携带或携带无效 Token,则返回未登录提示;验证通过则放行。每次用户请求都会携带 Token,拦截器验证有效后会自动刷新其在 Redis 中的过期时间,确保用户在持续操作中保持登录状态,而长时间未操作则自动失效登出。 ![login](images/login.png) 2. 首页 在首页模块中,系统使用 Redis 的 ZSet(有序集合) 存储和管理热门酒店信息。 ZSet 可以对酒店进行自动排序,使系统能够快速获取热门酒店列表。当用户访问首页时,系统会优先从 Redis 中读取热门酒店数据,若缓存中存在则直接返回,避免频繁访问数据库,从而显著降低数据库压力、提升响应速度和系统并发性能。 ![home](images/home.png) ![hothotel](images/hothotel.png) 3. 查询,es高亮显示 酒店搜索,采用 Elasticsearch 实现酒店信息的全文检索与高亮显示。数据同步方面,通过 Logstash 定时将 MySQL 中的酒店数据全量同步到 Elasticsearch 索引库,确保数据一致性,同时保留动态 SQL 查询作为备用方案,用于在必要时补充或覆盖搜索结果。搜索功能采用 match 与 multi_match 分词查询,支持按酒店名称、城市、标签等关键字进行模糊搜索,并结合 高亮查询(highlight) 实现搜索结果中的关键词高亮展示,有效提升了用户的搜索体验与系统的查询性能。 ![es](images/es.png) 4. 酒店详情页 房间库存 使用xxl-job实现了酒店库存自动生成的定时任务。这个任务的作用是保证系统中始终有未来90天的预定库存。第一次执行时,系统会自动为所有酒店房型生成未来90天的库存记录并写入数据库;从第二次开始,每天定时运行一次,只为新的一天自动补充库存数据。同时还做了定期清理三个月之前的库存数据,保留必要的历史记录便于统计和报表分析,避免了数据库冗余,又保证了库存数据的连续性和可追溯性。 ![hoteldetil_1](images/hoteldetil_1.png) 5. 预定下单 在用户选择好时间之后会从redis中查询该房型剩余的库存数,如果redis不存在就会去数据库中查找,并放到redis中,如果该房型的剩余库存不足或者该时间段库存不完整就会出现已售罄。 系统实现了基于 Redis 与 Lua 脚本 的库存扣减功能,用于应对多人同时预订同一房型时的高并发与超卖问题。 用户选择房型后,系统会将对应时间段的库存信息缓存至 Redis,实现高效读取与预扣。下单时通过 setnx 创建分布式锁(含唯一 UUID 值)并设置过期时间,防止死锁。加锁成功后执行 Lua 脚本原子性扣减库存:检查库存是否存在且充足后再扣减,避免并发超卖。扣减成功则同步更新数据库锁定库存字段,若失败则回滚 Redis 库存保持一致。无论成功与否,系统都会通过 Lua 脚本安全释放锁,确保不会误删他人锁。未支付订单超时后系统自动释放锁定库存,保证库存可再次被预订。 ![hoteldetail_2](images/hoteldetail_2.png) 6. 订单详情页面 系统通过 @ApiIdempotent 注解 + 拦截器 实现接口幂等性控制,用于防止用户重复提交请求。 在页面加载时,前端首先调用后端接口生成一个唯一的 Token,并分别将其存储在前端和 Redis 中。 当用户发起业务请求时,前端会在请求头中携带该 Token,后端拦截器在处理前先校验 Redis 中是否存在该 Token: - 若存在,说明是第一次请求,允许执行业务逻辑并立即删除 Redis 中的 Token; - 若不存在,则判定为重复请求,系统直接拒绝执行并返回“请勿重复提交”的提示。 这种机制简单高效,避免了重复下单、重复支付等问题,保证了接口操作的 幂等性与数据安全性。 ![orderdetail](images/orderdetail.png) 7. 实现支付功能 生成订单并请求支付宝支付接口;支付完成后,系统根据支付宝的 同步回调 显示支付成功界面,同时等待支付宝的 异步通知 来最终确认支付状态;异步通知到达后,系统会验证签名与幂等标识,只允许处理一次,然后将订单状态更新为「已支付」。 ![pay](images/pay.png) 8. 超时自动取消 将生成的订单信息发送给延迟交换机,RabbitMQ延迟交换机将订单信息发送给延迟队列,超时15分钟未支付消费者自动取消订单,消费者调用订单取消的方法,回滚库存,并修改订单状态 ![delaycancel](images/delaycancel.png) 9. 我的订单 ![myorder](images/myorder.png) 10. 提前取消 当用户发起已支付订单的取消请求时,后端首先校验订单状态是否可取消,并根据入住时间与当前时间的差值匹配取消规则,计算应退金额与违约金,生成取消说明。随后系统将计算结果封装成消息发送至 RabbitMQ 的订单取消交换机,实现异步处理。消费者接收到消息后会进行幂等性校验,防止重复处理,并调用支付宝接口完成退款及库存回滚。消息处理完成后发送 ACK 确认,确保不会重复消费;若退款异常,则通过 NACK 使消息重新入队或触发事务回滚,从而保障数据一致性与系统可靠性。 ![cancel](images/cancel.png) 11. 延迟退房 在延迟退房模块中,用户发起延迟退房请求后,系统会先查询所选酒店房型在当日是否仍有剩余库存。如果库存充足,系统允许用户最多延迟退房 5 小时;若库存不足,则仅支持延迟 2 小时。通过这种方式,系统在提升用户体验的同时,兼顾了酒店房间的周转效率与库存管理的合理性。 ![delay](images/delay.png) 12. 盖楼式评论 在评论模块中,我使用 MongoDB 实现了盖楼式评论功能,采用引用式存储维护评论之间的父子关系。每条评论都会记录其父评论 ID,顶级评论的 parentId 为空,子评论则在父评论的回复列表中引用其 ID。这样设计结构更清晰,既可以通过递归查询子评论,也可以使用 MongoDB 的 $lookup 聚合一次性查询整棵评论树。同时避免了嵌套式存储中因层级过深导致文档过大、查询性能下降的问题。最终实现的效果类似于论坛或酒店评价区的楼中楼评论,支持多层回复与分页加载,兼顾了可扩展性与性能。 ![mongodb](images/mongodb.png) 13. 我的评价 在“我的订单”中,用户可以对已完成的订单进行评价。 用户提交的文字评价存入数据库,上传的图片通过 MinIO 分布式对象存储保存,并在数据库中记录文件路径,支持多图片上传、文件高可用存储。 同时实现了评价的增删改查功能,用户可删除自己的评价,系统会同步删除对应的图片资源。 ![comment_1](images/comment_1.png) ![comment_2](images/comment_2.png) 14. 我的消息 系统在用户支付成功后,会生成包含用户ID、订单号和消息内容的通知消息,并存入数据库标记为“未推送”。支付模块作为生产者将消息发送至 RabbitMQ,开启消息与队列持久化及 confirm 确认机制,确保消息可靠送达;确认成功后更新数据库状态为“已推送”。消费者监听队列后通过 WebSocket 实时向用户推送消息,推送成功则更新状态为“未读”并向 RabbitMQ 发送 ack 确认,防止消息丢失。若用户离线,消息将暂存至 Redis 并设置 30 分钟过期,期间用户重新上线可立即接收;系统还通过定时任务定期重投“未推送”消息,确保消息在异常情况下也能可靠送达。 ![message](images/message.png)