1. 项目概述
这个基于SpringBoot+Vue的剧本杀预约管理系统,是我去年为本地一家实景推理馆设计的运营管理平台。当时店主找到我,说他们还在用Excel表格登记预约,经常出现时间冲突、玩家信息混乱的问题。经过三个月的开发迭代,这套系统成功帮助他们实现了线上预约、场次管理、剧本库存等核心功能的数字化升级。
系统采用前后端分离架构,后端基于SpringBoot框架提供RESTful API接口,前端使用Vue.js构建响应式管理界面。数据库选用MySQL 8.0存储业务数据,通过JWT实现安全的用户认证。特别针对剧本杀行业特性,设计了多维度场次排期、剧本库存预警、玩家偏好分析等特色功能。
2. 核心需求解析
2.1 行业背景与痛点
剧本杀作为新兴的社交娱乐方式,其运营管理面临几个典型问题:
- 场次安排复杂:不同剧本需要不同时长(3-6小时不等),房间和DM(主持人)资源需要精确匹配
- 库存管理困难:实体剧本、服装道具等需要跟踪使用状态
- 玩家体验优化:需要记录玩家历史游玩记录以推荐合适剧本
2.2 功能矩阵设计
基于上述痛点,系统主要包含以下功能模块:
code复制1. 预约管理
- 场次创建与排期
- 玩家预约登记
- 预约冲突检测
2. 剧本管理
- 剧本信息维护
- 库存状态跟踪
- 损坏报修流程
3. 用户中心
- 玩家档案管理
- 游玩历史记录
- 偏好标签系统
4. 数据统计
- 场次上座率分析
- 剧本热度排行
- 营收报表生成
3. 技术架构设计
3.1 后端技术栈
采用SpringBoot 2.7作为基础框架,主要依赖包括:
xml复制<dependencies>
<!-- Web支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 数据库访问 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<!-- 安全认证 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
3.2 前端技术选型
Vue 3组合式API开发,主要技术点:
- 使用Vue Router实现前端路由
- Pinia进行状态管理
- Element Plus组件库构建UI
- Axios处理HTTP请求
3.3 数据库设计
核心表结构设计:
sql复制CREATE TABLE `game_session` (
`id` bigint NOT NULL AUTO_INCREMENT,
`script_id` bigint NOT NULL COMMENT '剧本ID',
`room_id` bigint NOT NULL COMMENT '房间ID',
`dm_id` bigint NOT NULL COMMENT '主持人ID',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime NOT NULL COMMENT '结束时间',
`max_players` int DEFAULT '6' COMMENT '最大玩家数',
`current_players` int DEFAULT '0' COMMENT '当前报名数',
`status` tinyint DEFAULT '0' COMMENT '0-待开始 1-进行中 2-已结束',
PRIMARY KEY (`id`),
KEY `idx_time` (`start_time`,`end_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4. 关键实现细节
4.1 场次冲突检测算法
核心难点在于如何高效检测时间、房间、DM的三重冲突。实现方案:
java复制public boolean checkSessionConflict(GameSession newSession) {
return sessionRepository.exists(
(root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
// 同一房间
predicates.add(cb.equal(root.get("roomId"), newSession.getRoomId()));
// 时间重叠检测
predicates.add(cb.lessThan(root.get("startTime"), newSession.getEndTime()));
predicates.add(cb.greaterThan(root.get("endTime"), newSession.getStartTime()));
// 状态过滤
predicates.add(cb.notEqual(root.get("status"), 2)); // 排除已结束场次
return cb.and(predicates.toArray(new Predicate[0]));
}
);
}
4.2 预约流程的并发控制
为防止超卖问题,采用乐观锁实现:
java复制@Transactional
public ReservationResult makeReservation(Long sessionId, Long userId) {
GameSession session = sessionRepository.findById(sessionId)
.orElseThrow(() -> new BusinessException("场次不存在"));
// 检查当前人数
if (session.getCurrentPlayers() >= session.getMaxPlayers()) {
return ReservationResult.fail("该场次已满员");
}
// 乐观锁更新
int updated = sessionRepository.incrementPlayerCount(
sessionId,
session.getVersion()
);
if (updated == 0) {
throw new ConcurrentModificationException("预约冲突,请重试");
}
// 创建预约记录
Reservation reservation = new Reservation();
reservation.setSessionId(sessionId);
reservation.setUserId(userId);
reservationRepository.save(reservation);
return ReservationResult.success();
}
5. 系统部署方案
5.1 后端部署要点
采用Docker容器化部署,关键配置:
dockerfile复制FROM openjdk:11-jre
COPY target/script-booking-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
启动参数建议:
bash复制java -jar -Xms512m -Xmx1024m \
-Dspring.profiles.active=prod \
-Dspring.datasource.url=jdbc:mysql://mysql-host:3306/script_booking \
-Dspring.datasource.username=booking_user \
-Dspring.datasource.password=Booking@1234 \
app.jar
5.2 前端部署优化
使用Nginx作为静态资源服务器,配置示例:
nginx复制server {
listen 80;
server_name booking.example.com;
location / {
root /var/www/booking-frontend;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
}
}
6. 踩坑经验分享
6.1 时间处理时区问题
初期遇到场次时间显示错误的问题,解决方案:
- 数据库统一使用UTC时间存储
- 前端展示时根据用户时区转换
- 后端接口文档明确标注所有时间字段的时区要求
6.2 微信支付集成注意事项
对接微信支付时特别注意:
- 证书文件需要放在classpath下的特定目录
- 回调地址必须支持HTTPS
- 订单号生成规则要符合微信规范(32字符内)
6.3 性能优化实践
针对预约高峰期的优化措施:
- 热门场次数据加入Redis缓存
- 预约接口添加限流(Guava RateLimiter)
- 数据库连接池配置优化(HikariCP)
7. 扩展功能建议
根据实际运营反馈,后续可以考虑:
- 玩家社交系统:组队功能、评价体系
- 智能推荐引擎:基于玩家历史行为的剧本推荐
- 连锁店支持:多门店管理、资源调度
- 微信小程序端:轻量级预约入口
这套系统上线后,商家的预约效率提升了80%,人力成本降低了40%。最让我有成就感的是看到店员从繁琐的表格中解放出来,能更专注于提升玩家体验。
