1. 项目概述与技术栈选型
这套影院购票系统采用前后端分离架构,后端基于SpringBoot2框架构建,前端使用Vue3实现,数据持久层采用MyBatis-Plus操作MySQL8.0数据库。系统完整实现了从影片管理、场次排期到在线选座购票的全流程业务功能。
技术栈组合的合理性体现在:
- SpringBoot2的自动配置特性大幅减少了XML配置,内嵌Tomcat简化部署
- Vue3的Composition API更适合复杂前端状态管理,与影院选座这类交互密集场景完美契合
- MyBatis-Plus的ActiveRecord模式让数据库操作更直观,其分页插件直接支持购票系统的分页查询需求
- MySQL8.0的窗口函数和CTE特性有利于实现票房统计等复杂报表
提示:实际开发中发现,MySQL8.0默认的身份验证插件caching_sha2_password可能导致旧版本JDBC驱动连接失败,建议在安装时选择"Legacy Authentication"或升级驱动
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心模块设计与实现
2.1 影院基础数据管理
采用RBAC模型实现多级权限控制:
java复制// 基于Spring Security的权限配置示例
@PreAuthorize("hasRole('CINEMA_ADMIN')")
@PostMapping("/movies")
public Result addMovie(@Valid @RequestBody MovieDTO dto) {
return movieService.saveMovie(dto);
}
影片信息表设计关键字段:
sql复制CREATE TABLE `movie` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`duration` int DEFAULT NULL COMMENT '分钟',
`poster_url` varchar(255) DEFAULT NULL,
`status` tinyint DEFAULT '0' COMMENT '0-待上映 1-上映中 2-已下架',
`price` decimal(10,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
2.2 场次排期与座位管理
场次排期需要考虑的业务约束:
- 影厅不可同时段重复使用
- 排期时间需在影片上映周期内
- 特殊场次(如午夜场)需额外审批
座位状态使用二维数组存储:
javascript复制// Vue3中的座位状态管理
const seats = ref([
[1,1,0,1], // 1-可选 0-已售 2-维修中
[1,1,1,1],
[2,1,1,1]
])
// 使用watchEffect实现选中座位高亮
watchEffect(() => {
selectedSeats.value.forEach(pos => {
seats.value[pos.row][pos.col] = 3 // 3-选中状态
})
})
2.3 购票订单流程
订单状态机设计:
code复制待支付 --超时--> 已取消
待支付 --支付成功--> 已完成
待支付 --退款申请--> 退款中
退款中 --审核通过--> 已退款
分布式事务处理方案:
java复制// 使用Seata实现AT模式
@GlobalTransactional
public Result createOrder(OrderDTO dto) {
// 1. 扣减库存
scheduleService.lockSeats(dto.getScheduleId(), dto.getSeats());
// 2. 创建订单
orderService.saveOrder(dto);
// 3. 调用支付
paymentService.createPayment(dto);
}
3. 关键技术难点解决方案
3.1 高并发座位锁定
采用Redis分布式锁+乐观锁双重保障:
java复制public boolean lockSeats(Long scheduleId, List<String> seatPositions) {
String lockKey = "lock:schedule:" + scheduleId;
// 获取分布式锁
RLock lock = redissonClient.getLock(lockKey);
try {
if (lock.tryLock(3, 10, TimeUnit.SECONDS)) {
// 乐观锁更新
int updateRows = seatMapper.updateSeatStatus(
scheduleId,
seatPositions,
SeatStatus.AVAILABLE,
SeatStatus.LOCKED);
return updateRows == seatPositions.size();
}
} finally {
lock.unlock();
}
return false;
}
3.2 Vue3与SpringBoot跨域问题
解决方案组合:
- 后端配置CORS
java复制@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.maxAge(3600);
}
}
- 前端开发环境代理配置(vite.config.js)
javascript复制server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
3.3 MyBatis-Plus高级应用
动态表名处理器实现分表查询:
java复制public class CinemaTableNameHandler implements TableNameHandler {
@Override
public String dynamicTableName(String sql, String tableName) {
CinemaContext context = CinemaContextHolder.get();
if (context != null && context.getCinemaId() != null) {
return tableName + "_" + context.getCinemaId() % 10;
}
return tableName;
}
}
字段加密处理:
java复制@TableField(typeHandler = AesEncryptHandler.class)
private String phoneNumber;
4. 系统部署与性能优化
4.1 生产环境部署方案
推荐使用Docker Compose编排:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
ports:
- "3306:3306"
redis:
image: redis:6
ports:
- "6379:6379"
backend:
build: ./cinema-backend
ports:
- "8080:8080"
depends_on:
- mysql
- redis
frontend:
build: ./cinema-frontend
ports:
- "3000:3000"
4.2 性能调优实践
JVM参数优化(针对8G内存服务器):
code复制-XX:MetaspaceSize=128m
-XX:MaxMetaspaceSize=256m
-Xms2048m
-Xmx2048m
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
MySQL8.0配置优化:
ini复制[mysqld]
innodb_buffer_pool_size = 2G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
sync_binlog = 1000
4.3 监控与日志方案
SpringBoot Actuator集成:
properties复制management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always
ELK日志收集架构:
- Filebeat采集日志
- Logstash过滤处理
- Elasticsearch存储
- Kibana可视化
5. 常见问题排查指南
5.1 Vue3组件渲染异常
典型症状:Edge浏览器中偶尔出现UI元素无法关闭
解决方案:
- 检查是否使用了不兼容的CSS属性
- 添加v-cloak指令防止闪现
css复制[v-cloak] {
display: none;
}
5.2 MyBatis-Plus分页失效
排查步骤:
- 确认已配置分页插件
java复制@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
- 检查Page参数是否正确传递
- 验证SQL是否包含ORDER BY语句
5.3 内存泄漏问题处理
OOM错误排查工具:
- jmap生成堆转储
bash复制jmap -dump:format=b,file=heap.hprof <pid>
- Eclipse MAT分析内存占用
- 常见泄漏点:
- 未关闭的Redis连接
- 静态集合持续增长
- 线程池未正确销毁
6. 项目扩展方向建议
6.1 营销功能增强
可扩展功能模块:
- 优惠券系统(满减、折扣、代金券)
- 会员积分体系
- 限时特惠活动
6.2 大数据分析应用
基于现有数据可构建:
- 用户画像分析
- 影片推荐算法
- 上座率预测模型
6.3 微服务化改造
拆分建议:
- 用户服务
- 影片服务
- 订单服务
- 支付服务
- 通知服务
服务通信方案:
- RESTful API
- Spring Cloud OpenFeign
- 事件驱动架构(Spring Cloud Stream)
