一、项目背景与需求分析
在互联网购票场景中,用户需要完成车次查询、座位选择、订单生成、支付等核心功能。本系统采用分层架构设计,包含以下核心模块:
- 用户管理模块:支持注册/登录/信息修改
- 车次管理模块:实现车次信息的增删改查
- 订单管理模块:处理订单生成、支付、退改签
- 通知服务模块:集成短信/邮件通知功能
技术选型方面,采用Spring Boot 2.7快速开发框架,结合MyBatis-Plus实现ORM映射,使用MySQL 8.0作为主数据库,Redis缓存高频访问数据。前端采用Thymeleaf模板引擎实现基础页面,预留RESTful API接口供后续扩展。
二、数据库设计详解
- 核心表结构设计
``sqltrain_schedule
CREATE TABLE(idbigint NOT NULL AUTO_INCREMENT,train_novarchar(20) NOT NULL COMMENT '车次编号',start_stationvarchar(50) NOT NULL COMMENT '始发站',end_stationvarchar(50) NOT NULL COMMENT '终点站',depart_timedatetime NOT NULL COMMENT '发车时间',arrive_timedatetime NOT NULL COMMENT '到达时间',id
PRIMARY KEY (),idx_train_no
UNIQUE KEY(train_no`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE seat_inventory (
id bigint NOT NULL AUTO_INCREMENT,
schedule_id bigint NOT NULL COMMENT ‘关联车次ID’,
seat_type enum(‘FIRST_CLASS’,’SECOND_CLASS’,’HARD_SEAT’) NOT NULL COMMENT ‘座位类型’,
total_seats int NOT NULL COMMENT ‘总座位数’,
available_seats int NOT NULL COMMENT ‘可用座位数’,
PRIMARY KEY (id),
KEY idx_schedule (schedule_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 索引优化策略- 在车次表的train_no字段建立唯一索引- 座位库存表按schedule_id建立普通索引- 订单表按user_id和create_time建立复合索引三、核心模块实现1. 分布式锁实现余票控制```java@Servicepublic class SeatServiceImpl implements SeatService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Overridepublic boolean lockSeat(Long scheduleId, String seatType) {String lockKey = "seat:lock:" + scheduleId + ":" + seatType;try {return redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);} catch (Exception e) {log.error("获取座位锁失败", e);return false;}}@Overridepublic void releaseSeat(Long scheduleId, String seatType) {String lockKey = "seat:lock:" + scheduleId + ":" + seatType;redisTemplate.delete(lockKey);}}
-
订单状态机设计
采用枚举类定义订单状态流转:public enum OrderStatus {UNPAID(0, "待支付"),PAID(1, "已支付"),REFUNDED(2, "已退款"),CANCELLED(3, "已取消");private final int code;private final String desc;// 状态流转规则public static boolean canTransition(OrderStatus from, OrderStatus to) {switch (from) {case UNPAID:return to == PAID || to == CANCELLED;case PAID:return to == REFUNDED;default:return false;}}}
-
查询优化实现
-
使用MyBatis-Plus的Wrapper条件构造器
public Page<TrainSchedule> querySchedules(String startStation, String endStation,LocalDate departDate, Pageable pageable) {LambdaQueryWrapper<TrainSchedule> wrapper = new LambdaQueryWrapper<>();wrapper.eq(TrainSchedule::getStartStation, startStation).eq(TrainSchedule::getEndStation, endStation).ge(TrainSchedule::getDepartTime, departDate.atStartOfDay()).lt(TrainSchedule::getDepartTime, departDate.plusDays(1).atStartOfDay());return trainScheduleMapper.selectPage(new Page<>(pageable.getPageNumber(), pageable.getPageSize()),wrapper);}
四、系统部署方案
- 开发环境配置
- JDK 11+
- Maven 3.8+
- MySQL 8.0
- Redis 6.0+
- 生产环境建议
- 采用Nginx负载均衡
- 数据库主从复制架构
- 引入消息队列处理异步通知
- 使用对象存储保存票据文件
- 性能优化措施
- 热点数据缓存:车次信息缓存10分钟
- 数据库连接池配置:HikariCP默认配置优化
- 异步处理:订单支付结果通知采用消息队列
五、完整源码获取方式
项目采用MIT开源协议,完整源码包含:
- 前端页面(Thymeleaf模板)
- 后端服务(Spring Boot项目)
- 数据库脚本(DDL+初始化数据)
- 接口文档(Swagger UI)
- 部署指南(Docker Compose配置)
获取方式:关注开发者社区,回复”train-ticket”获取托管仓库地址。源码包含详细注释和开发文档,适合不同层次的开发者学习参考。
六、扩展功能建议
- 支付系统集成:对接主流支付渠道
- 用户等级体系:根据购票次数划分等级
- 智能推荐:基于历史数据推荐车次
- 数据分析模块:统计客流高峰时段
- 移动端适配:开发微信小程序版本
本系统设计充分考虑了高并发场景下的数据一致性要求,通过分布式锁、乐观锁等机制保证余票计算的准确性。实际开发中可根据具体需求调整技术选型,例如将MySQL替换为其他关系型数据库,或引入分布式事务框架处理复杂业务场景。