1. 项目背景与核心需求
剧本杀作为近年来快速崛起的线下社交娱乐方式,其预约管理痛点日益凸显。传统电话/微信预约方式存在三大硬伤:预约信息易遗漏、场次状态不透明、数据统计全靠人工。我们团队为本地连锁剧本杀店设计的这套Web系统,用SpringBoot+Vue技术栈实现了三大核心功能:
- 玩家端:实时场次查询+在线选座
- 商家端:剧本库存管理+DM排班
- 数据看板:热本分析+客流预测
实测上线后,门店预约效率提升60%,错单率从15%降至3%以下。下面从技术实现角度拆解关键模块。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 前后端分离架构
采用经典的前后端分离模式:
- 前端:Vue3 + Element Plus
- 后端:SpringBoot 2.7 + MyBatis-Plus
- 通信:RESTful API + JWT鉴权
特别注意:剧本杀场景存在高并发预约需求(例如热门本首发日),我们在网关层做了限流配置,单个IP 10秒内不得超过5次请求。
2.2 数据库设计要点
核心表关系设计:
sql复制CREATE TABLE `game_session` (
`id` bigint NOT NULL COMMENT '场次ID',
`script_id` bigint NOT NULL COMMENT '剧本ID',
`start_time` datetime NOT NULL COMMENT '开始时间',
`dm_id` bigint NOT NULL COMMENT '主持人ID',
`room_id` int NOT NULL COMMENT '房间ID',
`max_players` int DEFAULT '6' COMMENT '最大玩家数',
`status` tinyint DEFAULT '0' COMMENT '0待开始 1已满员 2已结束'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
特殊字段处理:
- 剧本时长字段:使用分钟数存储,前端展示时转换"3h30m"格式
- 玩家偏好标签:采用JSON格式存储,便于推荐系统调用
3. 核心功能实现
3.1 实时座位状态管理
采用WebSocket+Redis实现座位状态同步:
- 玩家进入预约页时建立WS连接
- 后端维护Redis哈希存储场次座位状态
- 任何座位变更通过WS广播给所有在线用户
关键代码片段:
java复制@GetMapping("/seatStatus/{sessionId}")
public ResponseEntity<SeatStatus> getSeatStatus(
@PathVariable Long sessionId) {
String redisKey = "session:seats:" + sessionId;
Map<Object, Object> seatMap = redisTemplate.opsForHash().entries(redisKey);
return ResponseEntity.ok(new SeatStatus(seatMap));
}
3.2 预约冲突检测
处理并发预约的三种方案对比:
| 方案 | 实现方式 | 优缺点 |
|---|---|---|
| 数据库锁 | SELECT FOR UPDATE | 性能差,不推荐 |
| Redis原子操作 | INCR + EXPIRE | 中等并发适用 |
| 分布式锁 | Redisson Lock | 高并发首选 |
我们最终采用Redisson方案:
java复制RLock lock = redissonClient.getLock("lock:reserve:"+sessionId);
try {
if(lock.tryLock(3, 10, TimeUnit.SECONDS)) {
// 执行业务逻辑
}
} finally {
lock.unlock();
}
4. 特色功能开发
4.1 智能排班系统
根据DM能力标签自动推荐排班:
- 使用HanLP分词处理剧本标签
- 计算DM与剧本的标签匹配度
- 结合历史评分进行综合排序
算法核心:
python复制# 伪代码示例
def calculate_match_score(dm, script):
tag_similarity = cosine_similarity(dm.tags, script.tags)
experience_score = dm.level * 0.3
return tag_similarity * 0.7 + experience_score
4.2 动态定价模块
基于以下因素实时调整价格:
- 时间段(周末/工作日)
- 预约提前量(临开场降价)
- 剧本热度指数
- 当前上座率
实现策略模式:
java复制public interface PricingStrategy {
BigDecimal calculatePrice(SessionInfo session);
}
@Component
@Qualifier("weekendStrategy")
public class WeekendPricing implements PricingStrategy {
@Override
public BigDecimal calculatePrice(SessionInfo session) {
return basePrice.multiply(new BigDecimal("1.2"));
}
}
5. 性能优化实践
5.1 缓存策略设计
三级缓存体系:
- 本地缓存(Caffeine):存储静态数据如剧本基本信息
- Redis缓存:存储动态数据如场次状态
- 数据库:最终数据持久化
缓存更新策略对比表:
| 策略 | 触发条件 | 适用场景 |
|---|---|---|
| 定时刷新 | 固定时间间隔 | 变化不频繁的数据 |
| 主动失效 | 数据变更时 | 需要强一致性的数据 |
| 懒加载 | 查询时检查 | 读多写少的数据 |
5.2 数据库优化
针对剧本查询的索引优化:
sql复制ALTER TABLE `script_info`
ADD INDEX `idx_search` (`genre`, `difficulty`, `duration`) USING BTREE;
慢查询优化案例:
sql复制-- 优化前(执行时间1.8s)
EXPLAIN SELECT * FROM sessions
WHERE start_time > NOW()
ORDER BY create_time DESC;
-- 优化后(执行时间0.02s)
EXPLAIN SELECT * FROM sessions
WHERE start_time > NOW()
ORDER BY start_time ASC, create_time DESC;
6. 安全防护措施
6.1 防脚本刷单
实现验证码策略:
- 常规操作:图形验证码
- 高频操作:短信验证码
- 风险IP:人机验证
6.2 支付安全
采用支付宝SDK的异步通知机制,处理支付结果回调时注意:
- 验证签名
- 检查订单状态
- 处理幂等性
关键代码:
java复制public boolean verifyNotification(Map<String,String> params) {
String sign = params.get("sign");
String content = getSignContent(params);
return AlipaySignature.rsaCheck(
content, sign, alipayPublicKey, "UTF-8", "RSA2");
}
7. 部署实践
7.1 容器化部署
Docker Compose文件关键配置:
yaml复制services:
app:
image: openjdk:11-jre
environment:
- REDIS_HOST=redis
- MYSQL_HOST=mysql
depends_on:
- redis
- mysql
redis:
image: redis:6-alpine
ports:
- "6379:6379"
7.2 性能监控
Prometheus监控指标配置示例:
yaml复制- pattern: 'springboot.actuator.metrics.<name>'
name: 'script_metrics_$1'
labels:
module: 'reservation_system'
8. 踩坑实录
- 时区问题:初期发现预约时间显示错误,原因是Docker容器默认UTC时间,解决方案:
dockerfile复制ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
- 微信支付回调:遇到Nginx代理导致获取不到真实IP,需添加配置:
nginx复制location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
- Vue路由缓存:玩家返回预约页时表单数据丢失,解决方案:
javascript复制{
path: '/reserve',
component: () => import('@/views/Reserve.vue'),
meta: { keepAlive: true }
}
这套系统经过三个月的迭代开发,目前日均处理预约订单200+,峰值QPS达到150。最大的收获是深刻理解了娱乐行业IT系统的特殊需求——既要保证高并发下的稳定性,又要满足灵活的业务规则变化。后续计划加入AI推荐算法,进一步提升玩家匹配精准度。
