1. 项目概述
作为一名有着10年Java全栈开发经验的工程师,我最近完成了一个基于Spring Boot的台球厅管理系统。这个项目从需求分析到最终上线历时3个月,采用了当前主流的技术栈,包括Spring Boot 2.7、Vue 3、MyBatis Plus和MySQL 8.0。系统实现了台球厅日常运营的全流程管理,包括会员管理、场地预约、消费结算、库存管理等核心功能。
在实际开发过程中,我发现很多台球厅还在使用传统的手工记账方式,效率低下且容易出错。这个系统正是为了解决这些痛点而设计的,它能够帮助台球厅实现数字化管理,提升运营效率。系统采用前后端分离架构,后端使用Spring Boot提供RESTful API,前端使用Vue构建响应式界面,数据库选用MySQL保证数据安全性和可靠性。
2. 系统架构设计
2.1 MVC架构实现
系统采用经典的MVC(Model-View-Controller)设计模式,将业务逻辑、数据展示和用户交互分离,提高了代码的可维护性和可扩展性。
模型层(Model):使用MyBatis Plus作为ORM框架,通过实体类映射数据库表结构。我特别设计了以下核心实体:
- User(用户信息)
- BilliardTable(台球桌信息)
- Reservation(预约记录)
- Consumption(消费记录)
- Inventory(库存物品)
视图层(View):前端使用Vue 3 + Element Plus构建,采用组件化开发方式。每个功能模块对应一个或多个Vue组件,通过axios与后端API交互。
控制层(Controller):Spring Boot的@RestController注解处理HTTP请求,调用Service层完成业务逻辑。例如:
java复制@RestController
@RequestMapping("/api/reservation")
public class ReservationController {
@Autowired
private ReservationService reservationService;
@PostMapping
public Result addReservation(@RequestBody ReservationDTO dto) {
return reservationService.addReservation(dto);
}
@GetMapping("/{date}")
public Result getReservationsByDate(@PathVariable String date) {
return reservationService.getReservationsByDate(date);
}
}
2.2 技术栈选型
后端技术栈:
- Spring Boot 2.7:简化配置,快速开发
- Spring Security:认证和授权
- MyBatis Plus:增强的ORM框架
- Redis:缓存高频访问数据
- Lombok:简化POJO编写
- Swagger:API文档生成
前端技术栈:
- Vue 3:响应式前端框架
- Element Plus:UI组件库
- Axios:HTTP客户端
- Vue Router:路由管理
- Pinia:状态管理
数据库:
- MySQL 8.0:关系型数据库
- 数据库连接池:HikariCP
选择这些技术的主要考虑是:
- Spring Boot的自动配置和起步依赖大大减少了样板代码
- Vue 3的Composition API使代码组织更灵活
- MyBatis Plus提供了强大的CRUD操作和条件构造器
- MySQL作为成熟的关系数据库,社区支持完善
3. 核心功能模块实现
3.1 会员管理系统
会员管理是台球厅运营的核心,系统实现了完整的会员生命周期管理:
会员注册流程:
- 前端收集用户基本信息(姓名、手机号、密码等)
- 后端验证数据合法性
- 密码使用BCrypt加密存储
- 生成会员卡号并初始化账户信息
java复制@Service
public class MemberServiceImpl implements MemberService {
@Override
public Result register(MemberRegisterDTO dto) {
// 验证手机号是否已注册
if (memberMapper.existsByPhone(dto.getPhone())) {
return Result.error("该手机号已注册");
}
// 密码加密
String encodedPwd = passwordEncoder.encode(dto.getPassword());
// 构建会员实体
Member member = new Member();
member.setPhone(dto.getPhone());
member.setPassword(encodedPwd);
member.setName(dto.getName());
member.setCardNumber(generateCardNumber());
member.setBalance(BigDecimal.ZERO);
member.setStatus(1);
// 保存到数据库
memberMapper.insert(member);
return Result.success("注册成功");
}
}
会员管理功能:
- 会员信息维护(基本信息、消费记录、余额)
- 会员卡充值
- 会员等级管理
- 消费积分累计
3.2 台球桌预约系统
预约系统实现了台球桌的在线预约和管理,主要功能包括:
预约流程设计:
- 会员登录系统
- 选择日期和时间段
- 查看可选台球桌
- 提交预约申请
- 系统生成预约记录
java复制@Service
public class ReservationServiceImpl implements ReservationService {
@Override
public Result addReservation(ReservationDTO dto) {
// 检查时间段是否可用
if (reservationMapper.existsConflict(
dto.getTableId(),
dto.getStartTime(),
dto.getEndTime())) {
return Result.error("该时间段已被预约");
}
// 构建预约记录
Reservation reservation = new Reservation();
reservation.setMemberId(dto.getMemberId());
reservation.setTableId(dto.getTableId());
reservation.setStartTime(dto.getStartTime());
reservation.setEndTime(dto.getEndTime());
reservation.setStatus(0); // 待确认
// 保存预约
reservationMapper.insert(reservation);
return Result.success("预约成功");
}
}
预约管理功能:
- 实时查看台球桌状态
- 预约确认/取消
- 预约历史查询
- 超时自动取消
3.3 消费结算系统
消费结算系统处理会员在台球厅的各种消费行为:
结算流程:
- 会员选择消费项目(台球、饮料等)
- 系统计算总金额
- 会员选择支付方式(余额/现金/微信/支付宝)
- 完成支付并生成消费记录
java复制@Service
public class ConsumptionServiceImpl implements ConsumptionService {
@Override
@Transactional
public Result settle(ConsumptionDTO dto) {
// 验证会员信息
Member member = memberMapper.selectById(dto.getMemberId());
if (member == null) {
return Result.error("会员不存在");
}
// 计算总金额
BigDecimal total = calculateTotal(dto.getItems());
// 余额支付处理
if (dto.getPaymentMethod() == 1) { // 余额支付
if (member.getBalance().compareTo(total) < 0) {
return Result.error("余额不足");
}
// 扣减余额
member.setBalance(member.getBalance().subtract(total));
memberMapper.updateById(member);
}
// 生成消费记录
Consumption consumption = new Consumption();
consumption.setMemberId(dto.getMemberId());
consumption.setAmount(total);
consumption.setPaymentMethod(dto.getPaymentMethod());
consumption.setCreateTime(LocalDateTime.now());
consumptionMapper.insert(consumption);
// 更新库存
updateInventory(dto.getItems());
return Result.success("结算成功");
}
}
4. 数据库设计与优化
4.1 数据库表结构
系统数据库包含以下主要表:
会员表(member):
sql复制CREATE TABLE `member` (
`id` bigint NOT NULL AUTO_INCREMENT,
`card_number` varchar(20) NOT NULL COMMENT '会员卡号',
`name` varchar(50) NOT NULL COMMENT '姓名',
`phone` varchar(20) NOT NULL COMMENT '手机号',
`password` varchar(100) NOT NULL COMMENT '密码',
`balance` decimal(10,2) DEFAULT '0.00' COMMENT '余额',
`points` int DEFAULT '0' COMMENT '积分',
`level` int DEFAULT '1' COMMENT '会员等级',
`status` tinyint DEFAULT '1' COMMENT '状态(0-禁用,1-正常)',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_phone` (`phone`),
UNIQUE KEY `idx_card_number` (`card_number`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
台球桌表(billiard_table):
sql复制CREATE TABLE `billiard_table` (
`id` bigint NOT NULL AUTO_INCREMENT,
`code` varchar(20) NOT NULL COMMENT '编号',
`type` tinyint NOT NULL COMMENT '类型(1-斯诺克,2-美式)',
`price_per_hour` decimal(10,2) NOT NULL COMMENT '每小时价格',
`status` tinyint DEFAULT '1' COMMENT '状态(0-维护中,1-可用)',
`description` varchar(200) DEFAULT NULL COMMENT '描述',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_code` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
4.2 数据库优化措施
在实际开发中,我采取了以下优化措施提升数据库性能:
-
索引优化:
- 为常用查询字段添加索引
- 使用复合索引减少回表操作
- 定期分析慢查询日志优化SQL
-
查询优化:
- 使用MyBatis Plus的QueryWrapper构建高效查询
- 避免SELECT *,只查询必要字段
- 大数据量查询使用分页
-
缓存策略:
- 使用Redis缓存热点数据(如台球桌状态)
- 实现二级缓存减少数据库访问
- 合理设置缓存过期时间
5. 系统安全设计
5.1 认证与授权
系统采用Spring Security实现安全的认证和授权机制:
认证流程:
- 用户提交用户名和密码
- 过滤器验证凭证
- 生成JWT令牌返回客户端
- 后续请求携带令牌进行认证
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
权限控制:
- 基于角色的访问控制(RBAC)
- 细粒度的权限注解(@PreAuthorize)
- 接口级别的权限校验
5.2 数据安全
为确保数据安全,系统实现了以下措施:
-
敏感数据加密:
- 密码使用BCrypt加密存储
- 敏感信息如手机号在数据库加密存储
- 传输数据使用HTTPS加密
-
防SQL注入:
- 使用预编译语句
- MyBatis使用#{}防止注入
- 输入参数严格校验
-
日志审计:
- 记录关键操作日志
- 异常操作告警
- 定期审计日志
6. 系统测试与部署
6.1 测试策略
系统采用分层测试策略确保质量:
单元测试:
- 使用JUnit + Mockito测试Service层
- 覆盖率目标:核心业务逻辑80%+
集成测试:
- 测试API接口
- 使用TestRestTemplate模拟HTTP请求
- 验证数据一致性
系统测试:
- 端到端测试完整业务流程
- 性能测试(JMeter)
- 安全测试(OWASP ZAP)
6.2 部署方案
系统采用Docker容器化部署,提高可移植性和扩展性:
后端服务部署:
dockerfile复制FROM openjdk:11-jre
COPY target/billiard-system.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
前端部署:
dockerfile复制FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
数据库部署:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: billiard
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
volumes:
mysql_data:
7. 开发经验与心得
在开发这个系统的过程中,我积累了一些宝贵的经验:
-
需求分析要彻底:前期与台球厅经营者深入沟通,了解真实业务流程,避免后期频繁修改。
-
技术选型要务实:不盲目追求新技术,选择成熟稳定、团队熟悉的技术栈。
-
代码规范很重要:统一代码风格,使用Checkstyle、PMD等工具保证代码质量。
-
测试要尽早进行:TDD(测试驱动开发)可以显著减少bug数量。
-
文档要同步更新:代码变更时及时更新文档,避免文档与实现不一致。
-
性能要考虑周全:从设计阶段就考虑性能问题,比后期优化更有效。
这个项目让我深刻体会到,一个好的管理系统不仅要功能完善,更要考虑用户体验和实际业务需求。在后续的版本中,我计划加入更多智能化功能,如:
- 基于历史数据的智能排班
- 会员消费行为分析
- 移动端小程序支持
通过这个项目,我不仅提升了自己的技术能力,也更加理解了如何将技术真正应用到实际业务场景中,解决实际问题。