基于移动端的校园班车预约系统的设计与实现(高质量、Java、源码、毕业设计、15000字、小程序)
摘 要
随着高校校园规模的不断扩大和师生出行需求的持续增长,传统校园班车人工调度、线下登记的管理模式在效率和服务体验方面逐渐显现出局限性。为解决班车信息查询不及时、预约流程繁琐、班次调度不灵活等现实问题,本研究设计并实现了一套基于移动端的校园班车预约系统。该系统采用前后端分离架构,后端基于SpringBoot框架构建,前端采用适配移动端的Vue.js技术栈实现,数据库选用MySQL,并整合了MyBatis-Plus数据持久层框架和Shiro权限认证框架,保障系统的安全性与数据交互效率。
在功能设计上,系统采用角色权限控制机制,将用户划分为管理员和普通师生两类。管理员可以进行校园信息管理、车站信息管理、班次信息管理、订单管理、用户信息管理等后台运维操作;普通师生用户可以完成账号注册与个人信息维护、班车车票查询与购买、预约订单管理、优惠券查询与使用等核心操作,实现班车预约全流程的线上化办理。
经系统测试验证,校园班车预约系统运行性能稳定,移动端界面交互友好,操作流程简洁直观,能够有效满足高校师生日常班车出行的预约需求,显著提升班车运营调度的效率与服务透明度,为校园交通数字化管理提供了可靠的技术解决方案。而系统模块化的设计具备良好的扩展性,也便于后续对系统的功能进行迭代与维护,适配更多校园出行场景。
关键词:校园班车预约;移动端;SpringBoot框架;订单管理
Abstract: With the continuous expansion of university campuses and the growing travel demands of faculty and students, the traditional manual scheduling and offline registration management model for campus shuttles has increasingly revealed limitations in efficiency and user experience. To address practical issues such as delayed shuttle information queries, cumbersome booking procedures, and inflexible schedule flexibility, this study designs and implements a mobile-based campus shuttle reservation system. The system employs a front-end-back-end separation architecture, with the backend built using the Spring Boot framework and the frontend implemented with the mobile-friendly Vue.js technology stack. It utilizes MySQL as the database and integrates the MyBatis-Plus data persistence layer framework and Shiro authentication mechanism to ensure system security and efficient data interaction.
In terms of functional design, the system employs a role-based permission control mechanism, categorizing users into administrators and regular faculty/students. Administrators can perform backend operations such as campus information management, station information management, schedule management, order management, and user profile management; regular users can carry out core tasks including account registration and personal information maintenance, bus ticket inquiry and purchase, appointment order management, and coupon search and usage, enabling fully digital processing of the entire bus reservation workflow.
System testing has confirmed that the campus shuttle reservation system operates with stable performance, features a user-friendly mobile interface, and straightforward operational workflows. It effectively meets the daily shuttle travel booking needs of university faculty and students, significantly enhancing operational efficiency and service transparency while providing a reliable technical solution for digital campus transportation management. The system's modular design ensures excellent scalability, facilitating future functional upgrades and maintenance to accommodate diverse campus mobility scenarios.
Key words: Campus shuttle booking; Mobile device; Spring Boot framework; Order management
目 录
摘 要.................................................................. I
Abstract............................................................... II
第1章 序言....................................................... 1
1.1 研究背景...................................................... 1
1.2 开发意义...................................................... 1
1.3 国内外研究现状.......................................... 2
1.4 设计说明书结构.......................................... 2
第2章 相关技术介绍....................................... 3
2.1 Spring Boot框架........................................... 3
2.2 MyBatis-Plus框架........................................ 3
2.3 Vue移动端技术栈........................................ 4
2.4 Sa-Token框架............................................... 4
第3章 系统分析............................................... 5
3.1 系统可行性分析.......................................... 5
3.1.1 技术可行性分析....................................... 5
3.1.2 经济可行性分析....................................... 5
3.1.3 操作可行性分析....................................... 5
3.2 系统功能分析.............................................. 6
3.2.1管理员模块................................................ 6
3.2.2社团成员模块............................................ 6
3.2.3 系统用例图............................................... 7
3.2.4 系统角色分析........................................... 8
3.3 功能流程分析.............................................. 8
3.3.1 班次信息发布流程................................... 9
3.3.2 车票预约购买流程................................. 10
3.3.4 订单取消与修改流程............................. 11
3.3.4 优惠券使用流程..................................... 11
第4章 系统设计............................................. 13
4.1 系统概述.................................................... 13
4.2 系统结构设计............................................ 13
4.3 数据库设计................................................ 14
4.3.1 数据库概念结构设计............................. 14
4.3.2 数据库逻辑结构设计............................. 15
4.3.3 数据库物理结构设计............................. 16
第5章 系统功能实现..................................... 24
5.1 管理员功能模块........................................ 24
5.1.1 校园信息管理......................................... 24
5.1.2 车站信息管理......................................... 25
5.1.3 班次信息管理......................................... 27
5.1.4 订单信息管理......................................... 30
5.1.5 用户信息管理......................................... 32
5.2 用户功能模块............................................ 33
5.2.1 登录注册页面......................................... 33
5.2.2 车票预约购买......................................... 35
5.2.3 订单管理................................................. 38
5.2.4 优惠券管理............................................. 41
第6章 系统测试............................................. 43
6.1 软件测试方法............................................ 43
6.2 测试用例.................................................... 43
6.2.1 班次信息发布功能测试......................... 43
6.2.2 车票预约购买功能测试......................... 44
6.2.3 订单取消功能测试................................. 45
6.2.4 优惠券使用功能测试............................. 46
6.2.5 管理员订单管理功能测试..................... 46
6.2.6 用户信息管理功能测试......................... 47
6.3 软件测试结果分析.................................... 48
第7章 总结与展望......................................... 49
参考文献........................................................... 50
致 谢............................................................... 52
3.2.3 系统用例图
管理员有车票管理、班次管理、订单管理、用户管理、校园管理、优惠卷管理等功能。其中校园管理主要是去查询校园的相关信息,可以对校园进行新增、修改、查询、删除的操作。车站管理主要是去查询每个校园相对应的车站,可以对车站进行新增、修改、查询、删除的操作。班次管理主要是对每个校园相对应的车站之间形成的班次进行相对应的管理。订单管理主要是去查询已经生成的订单,查询订单可以查询用户所有的订单的状态及交易时间等。同时用户生成的订单如果有误也需要用户进行人工的变动。查询异常订单等。用户管理是为了管理员能够更加直观的管理用户,方便对用户信息进行修改删除新增等的操作等。用例图如图3-1所示。
图3-1 管理员用例图
用户是系统中重要的组成部分,用户使用本系统主要的功能由订单管理、班次查询、生成订单等功能。其中车票查询就是按起始校园查询可以订票的所有班次,用户查询车票之后可以在班次上进行下单操作。下完订单的班次可以在用户的订单中查询到。订单管理就是管理所有的生成的订单,查询自己即将出行的订单等。如图3-2所示
图3-2 用户用例图
3.3 功能流程分析
功能流程分析部分主要通过流程图对校园班车预约系统的核心业务流程进行结构化分析,重点展示系统各功能模块之间的逻辑顺序。分析了班次信息发布流程、车票预约购买流程、订单取消与修改流程以及优惠券使用流程等关键业务场景,确保流程描述的规范性和可读性。流程设计遵循“用户友好、效率优先”原则,在满足业务规则的前提下尽可能优化操作步骤,减少冗余环节。
3.3.1 班次信息发布流程
管理员登录系统后台后,在班次管理模块中可以进行新增班次的操作,新增班次需填写班次的基本信息,包括所属校园、发车时间、停靠站点、核载人数、车票价格等。填写完毕后,管理员提交班次信息,系统会首先校验班次信息的合法性,比如发车时间是否合理、停靠站点是否已录入等。校验通过后,系统将保存该班次信息,移动端首页的班次列表则会同步更新新增的班次信息,供师生浏览预约。若班次信息存在不合规或填写错误的内容,管理员可以直接在后台对班次信息进行修改或删除操作。班次信息发布流程如图3-3所示。
图3-3 班次信息发布流程图
3.3.2 车票预约购买流程
师生用户登录移动端系统后,在首页浏览全部可预约的班车班次信息,选择符合出行需求的班次进入班次详情页面,点击“立即预约”按钮,系统会弹出预约确认的对话框,展示班次的发车时间、站点、票价等信息供用户核对。用户确认无误后,点击确认提交预约申请。平台系统首先会验证该班次是否还有剩余座位,如果座位已满,则会弹出提示“当前班次座位已售罄,请选择其他班次”的弹窗。如果仍有剩余座位,系统则会进入支付环节,用户完成支付后成功保存预约订单,并同步添加至管理员后台订单管理的订单记录中,同时对应班次的剩余座位数自动减1。整个流程如图3-4所示。
图3-4 车票预约购买流程图
3.3.4 订单取消与修改流程
师生用户进入个人中心的订单管理页面,浏览自己的所有预约订单,选择需要操作的未出行订单,可进行取消或修改操作。若选择取消订单,系统会弹出取消确认的对话框,用户确认后,系统将更新订单状态为“已取消”,同时同步恢复对应班次的剩余座位数,并按规则完成退款操作。若选择修改订单,用户可调整乘车人信息等可修改内容,提交修改后系统会校验修改内容的合法性,校验通过则更新订单信息,并同步至管理员后台的订单管理模块。若订单已过发车时间,系统则会提示“已发车订单无法进行取消或修改操作”。订单取消与修改流程如图3-5所示。
图3-5 订单取消与修改流程图
3.3.4 优惠券使用流程
师生用户在完成车票预约、进入支付环节时,可选择使用账户内的优惠券。系统会自动筛选出符合当前订单使用规则的可用优惠券,用户选择想要使用的优惠券后,系统会自动计算抵扣后的实付金额。用户确认支付金额无误后,完成支付操作,系统会同步更新优惠券状态为“已使用”,并保存订单与优惠券的关联信息。若用户选择不使用优惠券,系统则按原价完成支付,优惠券状态保持不变。支付完成后,用户可在个人中心的优惠券管理页面,查看所有优惠券的状态、有效期与使用记录。优惠券使用流程如图3-6所示。

图3-6 优惠券使用流程图
第4章 系统设计
4.1 系统概述
校园班车预约系统采用前后端分离的混合架构设计,整体由移动端表现层、业务服务层和数据持久层组成。在表现层,用户通过移动端浏览器或小程序访问适配移动端的前端界面,前端基于Vue.js+Vant组件库构建,完成班次查询、车票预约、订单管理等操作;后端由SpringBoot的Controller层处理RESTfulAPI请求,接收并响应前端的交互数据。业务层通过SpringBoot的Service层实现,负责核心业务逻辑处理和事务管理,包含权限校验、座位库存计算、订单状态流转等核心逻辑。数据持久层通过Mapper操作MySQL数据库,完成用户信息、班次信息、订单数据等内容的持久化存储和管理。
校园班车预约系统使用前后端分离的开发模式,通过标准化RESTfulAPI进行数据交互,确保系统的可扩展性和维护性,能够高效支持班次信息管理、车票预约购买、订单全生命周期管理等核心功能,满足校园班车预约系统的各项运营与使用需求[12]。校园班车预约系统三层架构如图4-1所示。

图4-1 校园班车预约系统三层架构图
4.2 系统结构设计
4.3.2 数据库逻辑结构设计
在逻辑设计的关系模式转换中,根据概念设计的实体关系模型进行映射,其中主键用“ ”表示,外键用“ ”表示。
(1)微信小程序用户表(id、user_id、文件、创建时间、更新时间、版本号)
(2)班次信息表(id、start_station_id、arrival_station_id、售价、余票总数、发车时间、备注、创建时间、更新时间、版本号)
(3)校园信息表(id、名称、创建时间、更新时间、版本号、拼音前缀)
(4)优惠券信息表(id、user_id、订单号、优惠券名称、优惠券金额、优惠券状态、创建时间、更新时间、版本号)
(5)订单表(id、订单号、user_id、car_shift_id、订单金额、支付金额、coupon_id、优惠券名称、优惠券金额、订单状态、支付时间、创建时间、更新时间、版本号)
(6)支付记录表(id、订单号、user_id、支付金额、支付时间、创建时间、更新时间、版本号)
(7)乘车人表(id、user_id、乘车人名称、身份证号码、手机号码、角色、创建时间、更新时间、版本号)
(8)车站信息表(id、车站名称、city_id、创建时间、更新时间、版本号)
(9)车票表(id、订单号、user_id、rider_id、乘车人名称、car_shift_id、发车车站、发车车站名称、到达车站、到达车站名称、售价、发车时间、车票状态、创建时间、更新时间、版本号)
(10)用户表(id、用户名称、密码、手机号码、角色、创建时间、更新时间、版本号)
4.3.3 数据库物理结构设计
数据库物理结构的设计应基于业务需求和技术规范,在存储空间和查询性能之间寻求最优方案,确保数据的一致性和完整性。设计时需规范字段类型和长度,合理设置索引,优化表连接方式,并考虑分区、分表等策略,以提升数据存取效率[13]。同时,要兼顾系统的可扩展性和维护性,在满足当前业务需求的同时,为未来可能的扩展预留灵活性,从而在长期运行中保持数据库的高效和稳定[14]。
(1)微信小程序用户表(tp_avatar),用于存储和管理校园班车预约系统中微信小程序端用户的头像与关联信息。包括6个字段,分别为id(主键)、user_id(用户id)、file(头像文件)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-1所示。
表4-1微信小程序用户表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
user_id |
bigint |
20 |
用户id |
外键 |
-- |
|
file |
blob |
-- |
头像文件 |
-- |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(2)班次信息表(tp_car_shift),用于存储和管理校园班车预约系统中所有班车班次的基础信息,是用户预约车票的核心数据来源。包括10个字段,分别为id(主键)、start_station_id(发车车站id)、arrival_station_id(到达车站id)、sale_price(售价)、ticket_count(余票总数)、start_time(发车时间)、Remark(备注)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-2所示。
表4-2班次信息表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
start_station_id |
bigint |
20 |
发车车站id |
外键 |
-- |
|
arrival_station_id |
bigint |
20 |
到达车站id |
外键 |
-- |
|
sale_price |
int |
11 |
售价 |
-- |
-- |
|
ticket_count |
int |
11 |
余票总数 |
-- |
-- |
|
start_time |
datetime |
-- |
发车时间 |
-- |
-- |
|
Remark |
varchar |
255 |
备注 |
-- |
NULL |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(3)校园信息表(tp_city),用于存储和管理校园班车预约系统中所有校区的基础信息,为车站与班次的校区归属提供数据支撑。包括5个字段,分别为id(主键)、city_name(校园名称)、create_time(创建时间)、update_time(更新时间)、version(版本号)、pinyin_prefix(拼音前缀)。表结构设计如表4-3所示。
表4-3校园信息表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
city_name |
varchar |
50 |
校园名称 |
-- |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
|
pinyin_prefix |
varchar |
10 |
拼音前缀 |
-- |
NULL |
(4)优惠券信息表(tp_coupon),用于存储和管理校园班车预约系统中用户持有的优惠券信息,为订单支付的优惠抵扣提供数据支撑。包括9个字段,分别为id(主键)、user_id(用户id)、coupon_number(优惠券编号)、coupon_name(优惠券名称)、coupon_price(优惠券金额)、coupon_status(优惠券状态)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-4所示。
表4-4优惠券信息表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
user_id |
bigint |
20 |
用户id |
外键 |
-- |
|
coupon_number |
varchar |
255 |
优惠券编号 |
-- |
-- |
|
coupon_name |
varchar |
50 |
优惠券名称 |
-- |
-- |
|
coupon_price |
int |
11 |
优惠券金额 |
-- |
-- |
|
coupon_status |
int |
11 |
优惠券状态 |
-- |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(5)订单表(tp_order),是系统的核心数据表之一,用于存储和管理校园班车预约系统中所有用户的预约订单信息,记录订单的全生命周期状态。包括15个字段,分别为id(主键)、order_number(订单号)、user_id(用户id)、car_shift_id(班次id)、order_price(订单金额)、pay_price(支付金额)、coupon_id(优惠券id)、coupon_name(优惠券名称)、coupon_price(优惠券金额)、order_status(订单状态)、pay_time(支付时间)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-5所示。
表4-5订单表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
order_number |
varchar |
255 |
订单号 |
-- |
-- |
|
user_id |
bigint |
20 |
用户id |
外键 |
-- |
|
car_shift_id |
bigint |
20 |
班次id |
外键 |
-- |
|
order_price |
int |
11 |
订单金额 |
-- |
-- |
|
pay_price |
int |
11 |
支付金额 |
-- |
-- |
|
coupon_id |
bigint |
20 |
优惠券id |
外键 |
NULL |
|
coupon_name |
varchar |
50 |
优惠券名称 |
-- |
NULL |
|
coupon_price |
int |
11 |
优惠券金额 |
-- |
NULL |
|
order_status |
int |
11 |
订单状态 |
-- |
-- |
|
pay_time |
datetime |
-- |
支付时间 |
-- |
NULL |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(6)支付记录表(tp_pay_log),用于存储和管理校园班车预约系统中所有订单的支付记录信息,为订单对账与支付追溯提供数据支撑。包括7个字段,分别为id(主键)、order_number(订单号)、user_id(用户id)、pay_price(支付金额)、pay_time(支付时间)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-6所示。
表4-6支付记录表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
varchar |
20 |
主键id |
主键 |
-- |
|
order_number |
varchar |
255 |
订单号 |
-- |
-- |
|
user_id |
varchar |
20 |
用户id |
外键 |
-- |
|
pay_price |
varchar |
11 |
支付金额 |
-- |
-- |
|
pay_time |
varchar |
-- |
支付时间 |
-- |
NULL |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(7)乘车人表(tp_rider),用于存储和管理校园班车预约系统中用户添加的乘车人信息,为车票开具与乘车核验提供数据支撑。包括8个字段,分别为id(主键)、user_id(用户id)、rider_name(乘车人名称)、id_number(身份证号码)、phone(手机号码)、rider_type(角色)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-7所示。
表4-7乘车人表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
user_id |
bigint |
20 |
用户id |
外键 |
-- |
|
rider_name |
varchar |
50 |
乘车人名称 |
-- |
-- |
|
id_number |
varchar |
50 |
身份证号码 |
-- |
-- |
|
phone |
varchar |
50 |
手机号码 |
-- |
-- |
|
rider_type |
int |
11 |
角色 |
-- |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(8)车站信息表(tp_station),用于存储和管理校园班车预约系统中所有班车停靠车站的基础信息,为班次规划与站点查询提供数据支撑。包括5个字段,分别为id(主键)、station_name(车站名称)、city_id(所属校园id)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-8所示。
表4-8车站信息表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
station_name |
varchar |
50 |
车站名称 |
-- |
-- |
|
city_id |
bigint |
20 |
所属校园id |
外键 |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(9)车票表(tp_ticket),用于存储和管理校园班车预约系统中所有已生成的车票信息,是用户乘车核验的核心凭证数据。包括16个字段,分别为id(主键)、order_number(订单号)、user_id(用户id)、rider_id(乘车人id)、rider_name(乘车人名称)、car_shift_id(班次id)、start_station_id(发车车站id)、start_station_name(发车车站名称)、arrival_station_id(到达车站id)、arrival_station_name(到达车站名称)、sale_price(售价)、start_time(发车时间)、ticket_status(车票状态)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-9所示。
表4-9车票表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
order_number |
varchar |
255 |
订单号 |
-- |
-- |
|
user_id |
bigint |
20 |
用户id |
外键 |
-- |
|
rider_id |
bigint |
20 |
乘车人id |
外键 |
-- |
|
rider_name |
varchar |
50 |
乘车人名称 |
-- |
-- |
|
car_shift_id |
bigint |
20 |
班次id |
外键 |
-- |
|
start_station_id |
bigint |
20 |
发车车站id |
-- |
-- |
|
start_station_name |
varchar |
50 |
发车车站名称 |
-- |
-- |
|
arrival_station_id |
bigint |
20 |
到达车站id |
-- |
-- |
|
arrival_station_name |
varchar |
50 |
到达车站名称 |
-- |
-- |
|
sale_price |
int |
11 |
售价 |
-- |
-- |
|
start_time |
datetime |
-- |
发车时间 |
-- |
-- |
|
ticket_status |
int |
11 |
车票状态 |
-- |
-- |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
(10)用户表(tp_user),是系统的核心基础数据表,用于存储和管理校园班车预约系统中所有用户的账号与基础信息。包括8个字段,分别为id(主键)、user_name(用户名称)、password(密码)、phone(手机号码)、user_type(角色)、create_time(创建时间)、update_time(更新时间)、version(版本号)。表结构设计如表4-10所示。
表4-10用户表
|
字段名称 |
类型 |
长度 |
字段说明 |
主键 |
默认值 |
|
id |
bigint |
20 |
主键id |
主键 |
-- |
|
user_name |
varchar |
50 |
用户名称 |
-- |
NULL |
|
password |
varchar |
255 |
密码 |
-- |
NULL |
|
phone |
varchar |
50 |
手机号码 |
-- |
NULL |
|
user_type |
int |
11 |
角色 |
-- |
NULL |
|
create_time |
datetime |
-- |
创建时间 |
-- |
NULL |
|
update_time |
datetime |
-- |
更新时间 |
-- |
NULL |
|
version |
int |
11 |
版本号 |
-- |
NULL |
第5章 系统功能实现
5.1 管理员功能模块
5.1.1 校园信息管理
校园信息管理的后端处理逻辑集中在CampusController控制器中。addOrUpdate方法接收Campus对象作为参数,首先通过campusService.lambdaQuery()检查校园名称是否重复,避免出现同名校区的信息冲突,验证通过后调用campusService.saveOrUpdate方法保存或更新校园信息。remove方法接收校园ID数组参数,直接调用campusService.removeBatchByIds方法批量删除校园记录。在校园列表查询的list方法中,管理员可以查看所有校园信息,支持按校园名称模糊查询,查询结果会自动关联对应校区下的车站数量,最终返回给前端完整的表格数据。校园信息管理界面如图5-1所示。


图5-1 校园信息管理界面图
核心代码:
@GetMapping("/list")
public TableDataInfo list(Campus campus) {
startPage();
LambdaQueryWrapper<Campus> wrapper = Wrappers.lambdaQuery(Campus.class)
.like(StringUtils.isNotEmpty(campus.getCityName()), Campus::getCityName, campus.getCityName())
.orderByDesc(Campus::getCreateTime);
List<Campus> campusList = campusService.list(wrapper);
return getDataTable(campusList);
}
@PostMapping("/addOrUpdate")
public AjaxResult addOrUpdate(@RequestBody Campus campus) {
long count = campusService.count(Wrappers.lambdaQuery(Campus.class)
.eq(Campus::getCityName, campus.getCityName())
.ne(campus.getId() != null, Campus::getId, campus.getId()));
if (count > 0) {
return AjaxResult.error("该校园名称已存在");
}
campusService.saveOrUpdate(campus);
return AjaxResult.success();
}
5.1.2 车站信息管理
车站信息管理的后端处理逻辑集中在StationController控制器中。addOrUpdate方法接收Station对象作为参数,首先校验所属校园是否存在,同时检查同一校园下车站名称是否重复,验证通过后调用stationService.saveOrUpdate方法保存或更新车站信息。remove方法接收车站ID数组参数,调用stationService.removeBatchByIds方法批量删除车站记录,同时会同步校验该车站是否关联了未发车的班次,若存在关联则禁止删除并提示错误。在车站列表查询的list方法中,支持按车站名称模糊查询、按所属校园精准筛选,查询结果会关联展示所属校园名称,最终返回给前端完整的表格数据。车站信息管理界面如图5-2所示。


图5-2 车站信息管理界面图
核心代码:
@GetMapping("/list")
public TableDataInfo list(Station station) {
startPage();
LambdaQueryWrapper<Station> wrapper = Wrappers.lambdaQuery(Station.class)
.like(StringUtils.isNotEmpty(station.getStationName()), Station::getStationName, station.getStationName())
.eq(station.getCityId() != null, Station::getCityId, station.getCityId())
.orderByDesc(Station::getCreateTime);
List<Station> stationList = stationService.list(wrapper);
stationList.forEach(item -> item.setCityName(campusService.getById(item.getCityId()).getCityName()));
return getDataTable(stationList);
}
@PostMapping("/remove")
public AjaxResult remove(@RequestBody Long[] ids) {
for (Long id : ids) {
long shiftCount = shiftService.count(Wrappers.lambdaQuery(CarShift.class)
.eq(CarShift::getStartStationId, id)
.or()
.eq(CarShift::getArrivalStationId, id));
if (shiftCount > 0) {
return AjaxResult.error("存在关联班次的车站,无法删除");
}
}
stationService.removeBatchByIds(Arrays.asList(ids));
return AjaxResult.success();
}
5.1.3 班次信息管理
班次信息管理的后端处理逻辑集中在CarShiftController控制器中。addOrUpdate方法接收CarShift对象作为参数,首先校验发车车站与到达车站不能为同一站点,同时校验发车时间不能早于当前时间,验证通过后调用carShiftService.saveOrUpdate方法保存或更新班次信息。remove方法接收班次ID数组参数,校验班次是否存在已支付的未出行订单,若存在则禁止删除,验证通过后批量删除班次记录。在班次列表查询的list方法中,支持按发车时间范围、发车车站、到达车站进行筛选,查询结果会关联展示发车车站、到达车站名称,同时实时计算剩余票数,最终返回给前端完整的表格数据。班次信息管理界面如图5-3所示。


图5-3 班次信息管理界面图
核心代码:
@GetMapping("/list")
public TableDataInfo list(CarShift carShift, String startTimeStart, String startTimeEnd) {
startPage();
LambdaQueryWrapper<CarShift> wrapper = Wrappers.lambdaQuery(CarShift.class)
.eq(carShift.getStartStationId() != null, CarShift::getStartStationId, carShift.getStartStationId())
.eq(carShift.getArrivalStationId() != null, CarShift::getArrivalStationId, carShift.getArrivalStationId())
.ge(StringUtils.isNotEmpty(startTimeStart), CarShift::getStartTime, startTimeStart)
.le(StringUtils.isNotEmpty(startTimeEnd), CarShift::getStartTime, startTimeEnd)
.orderByDesc(CarShift::getStartTime);
List<CarShift> shiftList = carShiftService.list(wrapper);
shiftList.forEach(item -> {
item.setStartStationName(stationService.getById(item.getStartStationId()).getStationName());
item.setArrivalStationName(stationService.getById(item.getArrivalStationId()).getStationName());
});
return getDataTable(shiftList);
}
@PostMapping("/addOrUpdate")
public AjaxResult addOrUpdate(@RequestBody CarShift carShift) {
if (carShift.getStartStationId().equals(carShift.getArrivalStationId())) {
return AjaxResult.error("发车车站与到达车站不能相同");
}
if (carShift.getStartTime().before(new Date())) {
return AjaxResult.error("发车时间不能早于当前时间");
}
carShiftService.saveOrUpdate(carShift);
return AjaxResult.success();
}
5.1.4 订单信息管理
订单信息管理的后端处理逻辑集中在OrderController控制器中。list方法支持按订单号、用户ID、订单状态、下单时间范围进行筛选,查询结果会关联展示用户名称、班次信息、优惠券使用情况,管理员可查看所有订单的完整信息。updateStatus方法用于管理员修改订单状态,支持取消未出行订单、标记订单为已完成等操作,修改订单状态时会同步更新对应班次的剩余票数,同时同步关联的车票状态。订单信息管理界面如图5-4所示。


图5-4 订单信息管理界面图
核心代码:
@GetMapping("/list")
public TableDataInfo list(Order order, String createTimeStart, String createTimeEnd) {
startPage();
LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(Order.class)
.like(StringUtils.isNotEmpty(order.getOrderNumber()), Order::getOrderNumber, order.getOrderNumber())
.eq(order.getUserId() != null, Order::getUserId, order.getUserId())
.eq(order.getOrderStatus() != null, Order::getOrderStatus, order.getOrderStatus())
.ge(StringUtils.isNotEmpty(createTimeStart), Order::getCreateTime, createTimeStart)
.le(StringUtils.isNotEmpty(createTimeEnd), Order::getCreateTime, createTimeEnd)
.orderByDesc(Order::getCreateTime);
List<Order> orderList = orderService.list(wrapper);
return getDataTable(orderList);
}
@PostMapping("/updateStatus")
public AjaxResult updateStatus(@RequestBody Order order) {
Order oldOrder = orderService.getById(order.getId());
// 取消订单时恢复班次余票
if (order.getOrderStatus() == 3 && oldOrder.getOrderStatus() == 1) {
CarShift shift = carShiftService.getById(oldOrder.getCarShiftId());
shift.setTicketCount(shift.getTicketCount() + 1);
carShiftService.updateById(shift);
}
orderService.updateById(order);
// 同步更新关联车票状态
ticketService.update(Wrappers.lambdaUpdate(Ticket.class)
.eq(Ticket::getOrderNumber, oldOrder.getOrderNumber())
.set(Ticket::getTicketStatus, order.getOrderStatus()));
return AjaxResult.success();
}
5.1.5 用户信息管理
用户信息管理的后端处理逻辑集中在UserController控制器中。addOrUpdate方法接收User对象作为参数,校验用户名和手机号是否重复,验证通过后对密码进行加密存储,完成用户信息的新增或修改。remove方法接收用户ID数组参数,校验用户是否存在未完成的订单,若存在则禁止删除,验证通过后批量删除用户账号。list方法支持按用户名、手机号、用户角色进行筛选,管理员可重置用户密码、修改用户角色权限。用户信息管理界面如图5-5所示。


图5-5 用户信息管理界面图
核心代码:
@GetMapping("/list")
public TableDataInfo list(User user) {
startPage();
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(User.class)
.like(StringUtils.isNotEmpty(user.getUserName()), User::getUserName, user.getUserName())
.like(StringUtils.isNotEmpty(user.getPhone()), User::getPhone, user.getPhone())
.eq(user.getUserType() != null, User::getUserType, user.getUserType())
.orderByDesc(User::getCreateTime);
List<User> userList = userService.list(wrapper);
return getDataTable(userList);
}
@PostMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody User user) {
User updateUser = new User();
updateUser.setId(user.getId());
updateUser.setPassword(SecureUtil.md5(user.getPassword()));
userService.updateById(updateUser);
return AjaxResult.success();
}
5.2 用户功能模块
5.2.1 登录注册页面
基于微信小程序的校园班车预定系统的小程序端运行打开首先是用户的登录/注册页面,在登录界面,用户提供输入手机号码,密码可以通过后端对账号密码进行验证实现登录操作,注册界面,用户通过输入手机号码、昵称和密码,可以对用户进行注册。界面如图5-6所示。


图5-6 登录/注册页面
核心代码:
@GetMapping("/getUserInfo")
public AjaxResult getUserInfo() {
Long userId = StpUtil.getLoginIdAsLong();
User user = userService.getById(userId);
user.setPassword(null);
return AjaxResult.success(user);
}
@PostMapping("/updateUserInfo")
public AjaxResult updateUserInfo(@RequestBody User user) {
user.setId(StpUtil.getLoginIdAsLong());
long count = userService.count(Wrappers.lambdaQuery(User.class)
.eq(User::getPhone, user.getPhone())
.ne(User::getId, user.getId()));
if (count > 0) {
return AjaxResult.error("该手机号已被使用");
}
userService.updateById(user);
return AjaxResult.success();
}
5.2.2 车票预约购买
车票预约购买的后端处理逻辑集中在TicketController控制器中。listShift方法为移动端提供可预约班次列表,支持按发车日期、发车车站、到达车站筛选,仅展示发车时间在当前时间之后、余票大于0的班次。createOrder方法处理用户的预约下单请求,首先校验班次余票是否充足,然后生成唯一订单号,计算订单金额,若用户选择使用优惠券则自动抵扣对应金额,完成支付后扣减班次余票、生成对应车票、更新优惠券状态。车票预约界面如图5-7所示。




图5-7 车票预约购买界面图
核心代码:
@GetMapping("/shiftList")
public AjaxResult shiftList(String date, Long startStationId, Long arrivalStationId) {
LambdaQueryWrapper<CarShift> wrapper = Wrappers.lambdaQuery(CarShift.class)
.eq(startStationId != null, CarShift::getStartStationId, startStationId)
.eq(arrivalStationId != null, CarShift::getArrivalStationId, arrivalStationId)
.apply("DATE(start_time) = {0}", date)
.gt(CarShift::getStartTime, new Date())
.gt(CarShift::getTicketCount, 0)
.orderByAsc(CarShift::getStartTime);
List<CarShift> shiftList = carShiftService.list(wrapper);
return AjaxResult.success(shiftList);
}
@PostMapping("/createOrder")
@Transactional(rollbackFor = Exception.class)
public AjaxResult createOrder(@RequestBody Order order) {
Long userId = StpUtil.getLoginIdAsLong();
CarShift shift = carShiftService.getById(order.getCarShiftId());
if (shift.getTicketCount() <= 0) {
return AjaxResult.error("当前班次余票不足");
}
// 生成订单号
order.setOrderNumber("ORD" + System.currentTimeMillis());
order.setUserId(userId);
order.setOrderStatus(1);
order.setOrderPrice(shift.getSalePrice());
// 处理优惠券抵扣
if (order.getCouponId() != null) {
Coupon coupon = couponService.getById(order.getCouponId());
order.setPayPrice(shift.getSalePrice() - coupon.getCouponPrice());
order.setCouponName(coupon.getCouponName());
order.setCouponPrice(coupon.getCouponPrice());
// 更新优惠券状态
coupon.setCouponStatus(1);
couponService.updateById(coupon);
} else {
order.setPayPrice(shift.getSalePrice());
}
orderService.save(order);
// 扣减余票
shift.setTicketCount(shift.getTicketCount() - 1);
carShiftService.updateById(shift);
// 生成车票
Ticket ticket = new Ticket();
ticket.setOrderNumber(order.getOrderNumber());
ticket.setUserId(userId);
ticket.setCarShiftId(shift.getId());
ticket.setStartStationId(shift.getStartStationId());
ticket.setArrivalStationId(shift.getArrivalStationId());
ticket.setSalePrice(shift.getSalePrice());
ticket.setStartTime(shift.getStartTime());
ticket.setTicketStatus(1);
ticketService.save(ticket);
return AjaxResult.success(order);
}
5.2.3 订单管理
订单管理的后端处理逻辑集中在OrderController的userOrder相关方法中。userOrderList方法仅返回当前登录用户的所有订单,支持按订单状态筛选,查询结果会关联展示班次信息与车票详情。cancelOrder方法处理用户的取消订单请求,校验订单是否为未出行状态,验证通过后更新订单状态为已取消,恢复对应班次的余票,同时将优惠券退回至用户账户。用户还可在订单详情中查看电子车票信息,作为乘车核验凭证。订单管理界面如图5-8所示。










图5-8 订单管理界面图
核心代码:
@GetMapping("/userOrderList")
public TableDataInfo userOrderList(Integer orderStatus) {
Long userId = StpUtil.getLoginIdAsLong();
startPage();
LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(Order.class)
.eq(Order::getUserId, userId)
.eq(orderStatus != null, Order::getOrderStatus, orderStatus)
.orderByDesc(Order::getCreateTime);
List<Order> orderList = orderService.list(wrapper);
return getDataTable(orderList);
}
@PostMapping("/cancelOrder")
@Transactional(rollbackFor = Exception.class)
public AjaxResult cancelOrder(Long orderId) {
Long userId = StpUtil.getLoginIdAsLong();
Order order = orderService.getById(orderId);
if (!order.getUserId().equals(userId)) {
return AjaxResult.error("无权操作他人订单");
}
if (order.getOrderStatus() != 1) {
return AjaxResult.error("仅可取消未出行的订单");
}
// 更新订单状态
order.setOrderStatus(3);
orderService.updateById(order);
// 恢复班次余票
CarShift shift = carShiftService.getById(order.getCarShiftId());
shift.setTicketCount(shift.getTicketCount() + 1);
carShiftService.updateById(shift);
// 退回优惠券
if (order.getCouponId() != null) {
Coupon coupon = couponService.getById(order.getCouponId());
coupon.setCouponStatus(0);
couponService.updateById(coupon);
}
// 更新车票状态
ticketService.update(Wrappers.lambdaUpdate(Ticket.class)
.eq(Ticket::getOrderNumber, order.getOrderNumber())
.set(Ticket::getTicketStatus, 3));
return AjaxResult.success();
}
5.2.4 优惠券管理
优惠券管理的后端处理逻辑集中在CouponController控制器中。userCouponList方法返回当前登录用户的所有优惠券,支持按未使用、已使用、已过期状态筛选,展示优惠券的金额、有效期与使用规则。用户在预约下单时,系统会自动筛选出符合当前订单使用条件的未过期、未使用优惠券,供用户选择抵扣。优惠券管理界面如图5-9所示。


图5-9 优惠券管理界面图
核心代码:
@GetMapping("/userCouponList")
public TableDataInfo userCouponList(Integer couponStatus) {
Long userId = StpUtil.getLoginIdAsLong();
startPage();
LambdaQueryWrapper<Coupon> wrapper = Wrappers.lambdaQuery(Coupon.class)
.eq(Coupon::getUserId, userId)
.eq(couponStatus != null, Coupon::getCouponStatus, couponStatus)
.orderByDesc(Coupon::getCreateTime);
List<Coupon> couponList = couponService.list(wrapper);
return getDataTable(couponList);
}
@GetMapping("/availableCoupon")
public AjaxResult availableCoupon(Integer orderAmount) {
Long userId = StpUtil.getLoginIdAsLong();
LambdaQueryWrapper<Coupon> wrapper = Wrappers.lambdaQuery(Coupon.class)
.eq(Coupon::getUserId, userId)
.eq(Coupon::getCouponStatus, 0)
.gt(Coupon::getExpireTime, new Date());
List<Coupon> couponList = couponService.list(wrapper);
// 筛选满减条件符合的优惠券
couponList = couponList.stream()
.filter(item -> orderAmount >= item.getFullAmount())
.collect(Collectors.toList());
return AjaxResult.success(couponList);
}
更多推荐



所有评论(0)