1. 项目背景与核心需求
校园台球厅作为高校常见的休闲娱乐场所,其日常运营涉及复杂的设备维护和人员管理需求。传统的手工登记方式存在效率低下、数据易丢失、统计困难等问题。这个毕业设计项目正是为了解决这些痛点而生。
我选择SpringBoot作为技术栈的核心,主要基于以下几个考量:
- 快速开发特性:SpringBoot的自动配置和起步依赖能大幅减少基础代码量
- 微服务友好:便于后续扩展为多场馆管理系统
- 成熟生态:与MyBatis、Thymeleaf等常用框架无缝集成
- 内嵌Tomcat:简化部署流程,特别适合校园环境的技术支持水平
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术选型与版本控制
后端技术栈:
- SpringBoot 2.7.18(LTS版本)
- MyBatis-Plus 3.5.3(增强CRUD操作)
- Spring Security(权限控制)
- Redis 6.2(缓存和会话管理)
前端技术栈:
- Thymeleaf 3.1(服务端模板引擎)
- Bootstrap 5.2(响应式布局)
- ECharts 5.4(数据可视化)
数据库:
- MySQL 8.0(主数据库)
- Redis(辅助缓存)
版本控制:
- Git + GitHub(代码托管)
- 采用Git Flow工作流管理开发周期
2.2 数据库设计关键表结构
- 用户表(user):
sql复制CREATE TABLE `user` (
`id` bigint NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '学号/工号',
`password` varchar(100) NOT NULL,
`real_name` varchar(20) DEFAULT NULL,
`phone` varchar(20) DEFAULT NULL,
`role` enum('admin','staff','student') NOT NULL,
`status` tinyint(1) DEFAULT '1' COMMENT '1-正常 0-禁用',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 台球桌设备表(pool_table):
sql复制CREATE TABLE `pool_table` (
`id` bigint NOT NULL AUTO_INCREMENT,
`table_no` varchar(10) NOT NULL COMMENT '台球桌编号',
`type` varchar(20) DEFAULT 'standard' COMMENT '球桌类型',
`status` enum('available','in_use','maintenance') NOT NULL DEFAULT 'available',
`hourly_rate` decimal(10,2) NOT NULL COMMENT '每小时费用',
`last_maintenance` date DEFAULT NULL,
`next_maintenance` date DEFAULT NULL,
`purchase_date` date DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_table_no` (`table_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
- 预约记录表(reservation):
sql复制CREATE TABLE `reservation` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` bigint NOT NULL,
`table_id` bigint NOT NULL,
`start_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
`actual_end_time` datetime DEFAULT NULL,
`status` enum('pending','confirmed','completed','cancelled') NOT NULL DEFAULT 'pending',
`payment_amount` decimal(10,2) DEFAULT NULL,
`payment_status` tinyint(1) DEFAULT '0' COMMENT '0-未支付 1-已支付',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_user` (`user_id`),
KEY `idx_table_time` (`table_id`,`start_time`,`end_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. 核心功能实现
3.1 多角色权限控制
系统采用RBAC模型设计三种角色:
- 管理员:系统配置、用户管理、设备管理
- 工作人员:日常预约处理、设备状态维护
- 学生用户:自助预约、个人记录查询
权限控制实现要点:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/staff/**").hasAnyRole("STAFF", "ADMIN")
.antMatchers("/user/**").authenticated()
.anyRequest().permitAll()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.and()
.logout()
.logoutSuccessUrl("/login?logout");
}
// 密码加密配置
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
3.2 台球桌状态实时更新
采用WebSocket实现设备状态实时推送:
java复制@Controller
@ServerEndpoint("/websocket/tableStatus")
public class TableStatusWebSocket {
private static final Map<Long, Session> sessions = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("tableId") Long tableId) {
sessions.put(tableId, session);
}
@OnClose
public void onClose(@PathParam("tableId") Long tableId) {
sessions.remove(tableId);
}
public static void sendStatusUpdate(Long tableId, String status) {
Session session = sessions.get(tableId);
if (session != null && session.isOpen()) {
try {
session.getBasicRemote().sendText(status);
} catch (IOException e) {
log.error("WebSocket发送失败", e);
}
}
}
}
前端订阅代码:
javascript复制function connectTableStatusSocket(tableId) {
const socket = new WebSocket(`ws://${location.host}/websocket/tableStatus/${tableId}`);
socket.onmessage = function(event) {
const status = event.data;
updateTableUI(status); // 更新前端界面显示
};
socket.onclose = function() {
setTimeout(() => connectTableStatusSocket(tableId), 5000);
};
}
4. 系统特色功能
4.1 智能预约冲突检测
实现预约时间冲突检测算法:
java复制public boolean checkReservationConflict(Long tableId, LocalDateTime start, LocalDateTime end) {
return reservationMapper.exists(
new QueryWrapper<Reservation>()
.eq("table_id", tableId)
.ne("status", "cancelled")
.and(wrapper -> wrapper
.between("start_time", start, end)
.or()
.between("end_time", start, end)
.or()
.le("start_time", start)
.ge("end_time", end)
)
);
}
4.2 设备维护预警系统
基于使用频率自动计算维护周期:
java复制@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void checkMaintenance() {
List<PoolTable> tables = tableMapper.selectList(null);
LocalDate today = LocalDate.now();
for (PoolTable table : tables) {
long usageHours = reservationMapper.sumUsageHours(table.getId(),
today.minusMonths(1), today);
if (usageHours > 100 && table.getNextMaintenance() == null) {
table.setNextMaintenance(today.plusWeeks(2));
tableMapper.updateById(table);
sendMaintenanceAlert(table);
}
}
}
5. 系统部署方案
5.1 本地开发环境配置
- 安装JDK 17+和Maven 3.8+
- 克隆项目仓库:
bash复制git clone https://github.com/yourname/campus-pool-hall.git
cd campus-pool-hall
- 导入IDE(推荐IntelliJ IDEA)
- 创建本地数据库:
bash复制mysql -u root -p
> CREATE DATABASE pool_hall DEFAULT CHARSET utf8mb4;
> exit
- 修改application-dev.yml配置数据库连接
- 启动应用:
bash复制mvn spring-boot:run
5.2 生产环境Docker部署
Docker-compose配置示例:
yaml复制version: '3.8'
services:
app:
image: openjdk:17-jdk
container_name: pool-hall
ports:
- "8080:8080"
volumes:
- ./target/campus-pool-hall.jar:/app.jar
environment:
- SPRING_PROFILES_ACTIVE=prod
command: java -jar /app.jar
depends_on:
- mysql
- redis
mysql:
image: mysql:8.0
container_name: pool-hall-mysql
environment:
MYSQL_ROOT_PASSWORD: yourpassword
MYSQL_DATABASE: pool_hall
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
redis:
image: redis:6.2
container_name: pool-hall-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
volumes:
mysql-data:
redis-data:
6. 毕业论文撰写要点
6.1 论文结构建议
-
绪论
- 研究背景与意义
- 国内外研究现状
- 本文主要工作
-
系统需求分析
- 功能性需求(用例图)
- 非功能性需求
- 业务流程分析
-
系统设计
- 架构设计(分层架构图)
- 数据库设计(ER图)
- 接口设计
-
系统实现
- 核心功能实现
- 关键技术难点解决
-
系统测试
- 测试方案
- 测试用例与结果
- 性能测试
-
总结与展望
6.2 技术亮点阐述建议
- SpringBoot自动配置原理的应用
- MyBatis-Plus动态SQL的实践
- WebSocket实时通信的实现
- 基于RBAC的权限控制方案
- 定时任务与批处理设计
7. 答辩PPT制作技巧
7.1 内容结构设计
- 封面页(题目、姓名、导师)
- 研究背景(1-2页)
- 系统架构(技术架构图)
- 功能演示(截图+说明)
- 创新点总结
- 成果展示(系统截图)
- 致谢
7.2 设计注意事项
- 使用学校官方模板(如有)
- 每页不超过6行文字
- 多用图表代替文字描述
- 关键代码只展示核心片段
- 保持动画效果简洁
- 准备备注稿应对提问
提示:演示视频应包含系统主要功能操作流程,时长控制在5-8分钟,建议采用画中画形式同时展示操作者和屏幕内容。
8. 常见问题解决方案
8.1 跨时段预约处理
处理跨天预约的业务逻辑:
java复制public List<TimeSlot> getAvailableSlots(Long tableId, LocalDate date) {
List<Reservation> reservations = reservationMapper.selectList(
new QueryWrapper<Reservation>()
.eq("table_id", tableId)
.ge("end_time", date.atStartOfDay())
.le("start_time", date.plusDays(1).atStartOfDay())
.ne("status", "cancelled")
);
// 生成可预约时间段
List<TimeSlot> allSlots = generateTimeSlots(date);
return filterAvailableSlots(allSlots, reservations);
}
8.2 并发预约控制
使用数据库乐观锁防止超订:
java复制@Transactional
public boolean makeReservation(ReservationDTO dto) {
// 检查台球桌版本号
PoolTable table = tableMapper.selectByIdForUpdate(dto.getTableId());
if (table.getVersion() != dto.getTableVersion()) {
throw new OptimisticLockException("台球桌状态已变更");
}
// 创建预约记录
Reservation reservation = convertToEntity(dto);
return reservationMapper.insert(reservation) > 0;
}
9. 项目扩展方向
- 移动端适配:开发微信小程序或APP版本
- 支付集成:对接校园一卡通或支付宝支付
- 数据分析:台球厅运营数据可视化
- 智能排班:工作人员自动排班系统
- 设备物联网:台球桌传感器数据采集
10. 开发经验分享
在开发过程中有几个特别值得注意的技术点:
-
时间处理:整个系统涉及大量时间计算,建议统一使用Java 8的LocalDateTime,避免时区问题。我们在处理跨天预约时,最初使用Date类型遇到了不少边界条件问题。
-
事务管理:对于预约-支付这类需要事务保证的操作,要特别注意事务传播行为的设置。我们遇到过因为不当的事务隔离级别导致的数据不一致问题。
-
缓存策略:台球桌状态这类高频访问但更新不频繁的数据,适合用Redis缓存。但要注意缓存一致性问题,我们采用了"先更新数据库再删除缓存"的策略。
-
前端性能:设备状态实时更新如果处理不当会导致频繁的DOM操作,最终我们使用虚拟DOM diff算法优化了性能,使即使同时监控20张台球桌也不会卡顿。
