温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片!
1. 项目背景与意义
随着互联网和移动支付的普及,线上购票已成为电影消费的主流方式。传统线下排队购票效率低、体验差,影院需要一套高效、稳定的在线购票系统来提升运营效率和用户满意度。本项目基于 Spring Boot 和 Vue3 构建一套电影购票管理系统,覆盖影片展示、选座购票、订单管理和后台运营等核心业务场景。
系统采用前后端分离架构,后端基于 Spring Boot 提供 RESTful API,前端基于 Vue3 和 Element Plus 构建交互界面,具备良好的扩展性、可维护性和用户体验。
2. 技术选型
本系统采用主流前后端分离技术栈,具体选型如下:
| 层次 | 技术 | 说明 |
|---|---|---|
| 后端框架 | Spring Boot 2.7 | 快速构建 RESTful 服务 |
| 持久层 | MyBatis-Plus | 简化数据库操作 |
| 数据库 | MySQL 8.0 | 存储用户、影片、订单等数据 |
| 前端框架 | Vue3 + Vite | 组合式 API 开发 |
| UI 组件库 | Element Plus | 后台管理界面组件 |
| 状态管理 | Pinia | 前端全局状态管理 |
| 路由 | Vue Router 4 | 前端页面路由 |
| 认证 | JWT + Spring Security | 用户登录鉴权 |
3. 系统功能模块
系统分为用户端和管理端两大模块,核心功能如下:
3.1 用户端功能
- 用户注册登录:支持手机号注册、密码登录和 JWT 鉴权。
- 影片浏览:按热映、即将上映、评分等维度展示影片列表和详情。
- 选座购票:选择场次、座位并生成订单,支持在线支付。
- 订单管理:查看历史订单、订单状态和退票操作。
- 个人中心:维护个人信息、修改密码。
3.2 管理端功能
- 影片管理:新增、编辑、上下架影片信息。
- 场次管理:为影片配置放映厅、时间和票价。
- 订单管理:查询、统计和处理用户订单。
- 用户管理:查看和管理注册用户。
- 数据统计:按影片、日期维度统计票房和上座率。
4. 数据库设计
系统核心数据表包括用户表、影片表、放映厅表、场次表、座位表和订单表。各表关系如下:
-- 用户表 CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) NOT NULL, password VARCHAR(100) NOT NULL, phone VARCHAR(20), role VARCHAR(20) DEFAULT 'USER', create_time DATETIME ); -- 影片表 CREATE TABLE movie ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100) NOT NULL, director VARCHAR(50), actors VARCHAR(200), duration INT, release_date DATE, poster_url VARCHAR(255), status TINYINT DEFAULT 1 ); -- 场次表 CREATE TABLE session ( id BIGINT PRIMARY KEY AUTO_INCREMENT, movie_id BIGINT NOT NULL, hall_id BIGINT NOT NULL, start_time DATETIME NOT NULL, price DECIMAL(10,2) NOT NULL ); -- 订单表 CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT NOT NULL, session_id BIGINT NOT NULL, seat_ids VARCHAR(100), total_price DECIMAL(10,2), status TINYINT DEFAULT 0, create_time DATETIME );5. 后端核心实现
后端采用分层架构,Controller 层负责接口暴露,Service 层处理业务逻辑,Mapper 层通过 MyBatis-Plus 操作数据库。
5.1 用户登录接口
@RestController @RequestMapping("/api/auth") public class AuthController { @Autowired private UserService userService; @PostMapping("/login") public Result login(@RequestBody LoginDTO dto) { String token = userService.login(dto.getUsername(), dto.getPassword()); return Result.success(token); } @PostMapping("/register") public Result register(@RequestBody User user) { userService.register(user); return Result.success("注册成功"); } }5.2 选座购票核心逻辑
@Service public class OrderServiceImpl implements OrderService { @Override @Transactional public Order createOrder(OrderDTO dto) { // 校验座位是否已被占用 List<String> occupied = orderMapper.findOccupiedSeats(dto.getSessionId()); for (String seat : dto.getSeatIds()) { if (occupied.contains(seat)) { throw new BusinessException("座位 " + seat + " 已被购买"); } } // 计算总价 Session session = sessionMapper.selectById(dto.getSessionId()); BigDecimal total = session.getPrice().multiply( new BigDecimal(dto.getSeatIds().size())); // 创建订单 Order order = new Order(); order.setUserId(dto.getUserId()); order.setSessionId(dto.getSessionId()); order.setSeatIds(String.join(",", dto.getSeatIds())); order.setTotalPrice(total); order.setStatus(0); orderMapper.insert(order); return order; } }6. 前端核心实现
前端基于 Vue3 组合式 API 开发,使用 Pinia 管理用户状态,Axios 封装请求。
6.1 影片列表页面
<script setup> import { ref, onMounted } from 'vue' import { getMovieList } from '@/api/movie' import { useRouter } from 'vue-router' const movies = ref([]) const router = useRouter() onMounted(async () => { const res = await getMovieList() movies.value = res.data }) function goDetail(id) { router.push(/movie/${id}) } </script> <template> <div class="movie-grid"> <div v-for="movie in movies" :key="movie.id" class="movie-card" @click="goDetail(movie.id)"> <img :src="movie.posterUrl" :alt="movie.title" /> <h3>{{ movie.title }}</h3> <p>评分:{{ movie.rating }}</p> </div> </div> </template>6.2 选座组件
<script setup> import { ref } from 'vue' const selectedSeats = ref([]) const hall = ref([ ['A1', 'A2', 'A3', 'A4'], ['B1', 'B2', 'B3', 'B4'], ['C1', 'C2', 'C3', 'C4'] ]) function toggleSeat(seat) { const index = selectedSeats.value.indexOf(seat) if (index > -1) { selectedSeats.value.splice(index, 1) } else { selectedSeats.value.push(seat) } } </script> <template> <div class="seat-map"> <div v-for="row in hall" :key="row" class="seat-row"> <span v-for="seat in row" :key="seat" :class="{ active: selectedSeats.includes(seat) }" @click="toggleSeat(seat)"> {{ seat }} </span> </div> </div> </template>7. 系统部署与运行
项目采用前后端分离部署方式,后端打包为 Jar 包运行,前端构建为静态资源部署到 Nginx。
# 后端打包 mvn clean package -DskipTests java -jar target/movie-system.jar 前端构建 npm install npm run build 将 dist 目录部署到 Nginx8. 总结
本文设计并实现了一套基于 Spring Boot 和 Vue3 的电影购票管理系统,覆盖影片展示、选座购票、订单管理和后台运营等核心功能。系统采用前后端分离架构,后端提供稳定高效的 RESTful 接口,前端提供流畅友好的交互体验。未来可进一步扩展会员积分、优惠券、影评互动等功能,提升系统的商业价值和用户粘性。