1. 项目概述与背景
去年帮学弟调试他的毕业设计时,发现市面上很多影院购票系统都存在界面卡顿、选座体验差的问题。这促使我重新思考如何用SpringBoot+Vue这套技术栈,打造一个真正好用的在线购票平台。经过三个月的迭代开发,最终完成的系统不仅支持常规的选座购票,还实现了基于用户行为的智能推荐。
这个系统最核心的价值在于:用技术手段还原线下影院的选座体验。当用户拖动屏幕选择座位时,系统会实时高亮相邻座位,并自动避开已被预订的位置。后台采用乐观锁机制处理并发选座冲突,实测在500并发请求下,座位冲突率低于0.3%。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构设计
2.1 为什么选择SpringBoot+Vue
2018年第一次用jQuery+JSP做购票系统时,前后端混杂的架构让修改一个按钮样式都需要重新部署整个应用。现在的方案中:
- 前端Vue 3.x + TypeScript + Pinia状态管理
- 后端SpringBoot 2.7 + MyBatis-Plus + Redis
- 数据库MySQL 8.0 + Redis缓存
实测数据显示,这种架构下:
- 首屏加载时间从原来的4.2s降至1.8s
- API响应时间中位数从320ms降到150ms
- 部署时前端静态资源与后端服务完全解耦
2.2 数据库设计的三个关键点
2.2.1 座位存储方案对比
最初采用字符串存储座位号(如"A1,A2"),但在统计上座率时需要复杂的字符串解析。最终方案是:
sql复制CREATE TABLE cinema_seat (
showtime_id BIGINT,
row_num CHAR(1), -- 排号A-Z
col_num INT, -- 列号1-20
status TINYINT, -- 0可用 1锁定 2已售
PRIMARY KEY (showtime_id, row_num, col_num)
) ENGINE=InnoDB;
这种设计使得查询某场次的剩余座位只需简单COUNT查询,性能提升40倍。
2.2.2 订单与支付状态分离
踩坑记录:曾将支付状态与订单状态合并,导致支付超时后状态回滚异常。优化后的状态机设计:
java复制// 订单状态
public enum OrderStatus {
PENDING, // 待支付
PAID, // 已支付
CANCELLED, // 已取消
COMPLETED // 已完成(观影后)
}
// 支付状态单独维护
public enum PaymentStatus {
INIT,
PROCESSING,
SUCCESS,
FAILED,
REFUNDED
}
2.2.3 影院排片的数据结构
场次安排是最复杂的业务逻辑,核心表结构:
sql复制CREATE TABLE schedule (
id BIGINT AUTO_INCREMENT,
movie_id BIGINT,
hall_id INT,
start_time DATETIME,
end_time DATETIME,
price DECIMAL(10,2),
version INT DEFAULT 0, -- 乐观锁版本
PRIMARY KEY (id),
FOREIGN KEY (movie_id) REFERENCES movie(id),
