如果你今年的课题选了“基于 Spring Boot 的城市地铁综合服务管理系统”或者“城市轨道交通安全管理系统”,先给你一个基本判断:这个题目在课设/毕设里属于性价比很高的那一类。地铁场景的功能足够丰富,可以做乘客端、运营端、安全端三类角色的业务闭环;技术上也刚好覆盖了 Web 开发最常用的那一套东西——Spring Boot、MySQL、MyBatis、JWT 登录、数据可视化、Excel 导入导出。更重要的是,它好讲清楚。答辩的时候你不用扯复杂算法,只要把“线路换乘怎么查的”“客流数据怎么统计的”“安全事件怎么闭环处理的”这三件事说明白,评委基本就能认可工作量。
我接下来按我自己做完这个项目并拿去评审的完整流程,把从选题分析到数据库设计、从后端模块到安全管理、从部署打包到写文档答辩的全过程拆开来讲。内容不会只给结论,每一步都会解释为什么这么做,以及哪些地方最容易翻车。
1. 课设/毕设做地铁管理系统,先想清楚要交什么
1.1 一个“综合服务”系统到底该有哪些功能
很多同学拿到这个题目之后,第一反应是把功能表列得特别长,今天加一个“会员积分”,明天加一个“周边商城”,后天又想加“在线购票”。我在帮别人评审项目时最怕的就是这种功能堆砌——因为功能一旦超过你的掌控范围,后期每一个模块都在消耗你的时间,最后交出来的东西到处是半成品。
我第一次接手这个题目的时候,先把自己放在“真实地铁运营场景”里问了一遍:一个地铁综合服务管理系统,最核心的角色有谁?答案是三类:坐地铁的乘客、运营线路的管理员、负责轨道交通安全工作的人员。乘客想查线路、查站点、看实时客流;管理员要维护线路和列车的基础数据、查看运营统计;安全人员要上报隐患、处置突发事件、启动应急预案。把这三类角色能用的核心功能拉出来,系统的主干就是:
- 乘客端:注册登录、线路查询、站点查询、换乘方案推荐、实时客流查看、失物招领、意见反馈。
- 运营端:线路管理、站点管理、列车管理、运行时刻管理、客流数据统计、公告发布、用户管理。
- 安全端:安全隐患上报、隐患审核处理、突发事件登记、应急预案管理、事件处置记录、安全数据统计。
这个清单看起来有十几项,但剥开来看,底层就是“基础信息的增删改查 + 三张业务表的流程处理 + 统计图表”。哪怕你只有三周的时间,按这个范围做也完全来得及。比这更多的功能,比如对接第三方地图、模拟支付、GPS 定位,基本都属于锦上添花,不建议在课设阶段碰,工作量不可控,答辩也容易卡壳。
1.2 角色权限决定后端怎么写
确定了功能范围之后,紧接着就要定权限模型。这个题目里有明确的角色区分,所以后端不能只有一个简单的登录,必须让不同身份的人登录之后看到不同的菜单、执行不同的操作。我的做法是不引入特别重量级的权限框架,用最轻量的方式实现:
- 数据库里设计一张
role表,用户表通过role_id区分角色; - 登录成功后返回用户信息和角色标识,前端根据角色渲染菜单;
- 后端在需要管控的接口上加一个基于注解的角色校验,比如只有
ADMIN能调用的删除接口,在拦截器里判断用户身份,不匹配直接返回 403。
这里为什么不推荐上 Spring Security 的完整 RBAC 模型?因为课设论文答辩时,你很难把“动态权限配置、角色继承、细粒度按钮权限”这些概念讲得比评委更深刻。反而用“登录用户带上角色,后端接口校验角色”这种一眼能看懂的模型,所有代码都是自己写的,每一步都能解释,这本身就是一个很扎实的亮点。
1.3 项目的可展示性决定了你的分数上限
课设和毕设的评审,本质上是一个“可视化验收”过程。代码写得再好,评委看不到;但一个像样的管理后台界面、一个能联动图表的数据大屏、一个能导出的 Excel 报表,评委一眼就能感受到工作量。所以在设计系统的时候,我建议把“可展示性”作为功能裁剪的一个重要标准。
选这个题目有一个天然优势:地铁系统自带“站间连接图”和“客流热力”这种非常适合图表化的数据。客流统计数据可以用折线图展示分时客流趋势、柱状图展示站点客流排行,甚至可以做一个简单的大屏页,把今日客流、突发事件数、待处理隐患数统统摆上去。这些内容不仅能填充页面,还能在论文里作为“系统可视化设计”的截图素材,一举两得。
2. 技术栈定版:Spring Boot + MyBatis-Plus + MySQL 的搭配逻辑
2.1 为什么这门课设适合用 Spring Boot
技术选型这个问题,我见过太多同学纠结:用原生的 Servlet/JSP?用 SSM?还是直接上 Spring Boot?结论非常明确,选 Spring Boot。原因不是因为它比 SSM 更“高级”,而是它把 Spring、Spring MVC、配置管理这些事情都集成好了,让你把精力花在业务代码上,而不是花在写一堆 XML 配置文件上。对于一个还要写论文、做测试、准备答辩的课设项目来说,省下来的时间都是真实收益。
具体版本,我建议用 Spring Boot 2.7.x + Java 8。这个组合的生态最成熟,网上遇到任何问题都能搜到答案,数据库连接、文件上传、拦截器配置这些常见问题的解决方案极其丰富。如果你非要用 Spring Boot 3,也不是不行,但 Java 版本要到 17,有些老版本的 MyBatis-Plus 和生成工具可能不兼容,没必要给答辩前的自己添堵。
ORM 层我用的是 MyBatis-Plus。原因有两个:单表 CRUD 可以直接继承BaseMapper拿到一堆现成方法,写代码速度飞快;同时它保留 MyBatis 的能力,复杂统计查询我们可以在 XML 或者@Select注解手写 SQL,完全可控。有些同学喜欢用 JPA,但 JPA 的实体关系映射在“线路-站点多对多”这种场景下,自动生成的 SQL 一旦和你预期不符,排查起来相当难受。
2.2 前端方案取舍:服务端渲染还是前后端分离
前端怎么做,是另一个容易犹豫的点。我通常会给两条路线:
- 路线一:Thymeleaf 模板 + Bootstrap + jQuery + ECharts。服务端渲染,整个项目打成一个大 jar 包,部署最简单。开发时不需要额外启动一个前端服务,也不会遇到跨域问题。
- 路线二:Vue 3 + Element Plus + ECharts,通过 Axios 调用后端 REST 接口。页面效果更强,交互更现代,但开发时要开两个端口,联调时还要处理 CORS。
如果你用来做课程设计,时间紧、想求稳,我强烈建议走 Thymeleaf 的服务端渲染路线。阅卷和答辩时没人会因为你没用前后端分离而扣分,反而整套系统一个包就能跑起来,演示环境几乎不会出意外。如果你是想把这个项目当毕设并且学有余力,Vue 方案的可视化效果确实更好,面试时聊前端框架也有素材。我这里后面的代码讲解会同时照顾两条路线的核心逻辑,但代码样例默认偏服务端渲染,因为这套东西最容易完整复现。
2.3 项目目录结构与初始化清单
不管选哪条前端路线,后端代码的目录结构我建议统一拆成下面这样,把“按层分包”做清楚,后期写论文画架构图也方便:
com.example.metro ├── config/ // 配置类:拦截器、跨域、文件上传映射 ├── controller/ // 接口层,只做参数接收和结果封装 ├── service/ │ └── impl/ // 业务层,核心逻辑都放这里 ├── mapper/ // 数据访问层,MyBatis-Plus Mapper ├── entity/ // 实体类 ├── dto/ // 请求/响应的数据传输对象 ├── vo/ // 视图对象,比如图表统计结果 ├── utils/ // JWT工具、日期工具、Excel工具 └── interceptor/ // 登录拦截器、角色校验拦截器依赖清单里最核心的几项:spring-boot-starter-web、mybatis-plus-boot-starter、mysql-connector-j、jjwt或java-jwt、poi或easyexcel、lombok。Lombok 强烈建议用,能少写一半的 getter/setter;如果怕答辩被问“这是什么”,就说是编译期注解处理工具,减少样板代码。
配置文件application.yml关键要设置好数据库连接、MyBatis-Plus 的日志输出、文件上传大小限制,以及服务端口。端口选 8080 就好,不要用 8080 冲突的乱改端口;文件上传大小我通常设成 50MB,课设阶段上传图片文件用它足够。
3. 数据库建模:地铁业务的数据关系难点
3.1 核心表清单与设计意图
数据库设计这个环节,我建议一开始就严格按“业务模块”来拆表,千万别想到什么加什么。我最终沉淀下来的表大概有 12 张,分成四组:
| 分组 | 表名 | 说明 |
|---|---|---|
| 用户权限 | sys_user | 用户主表,含用户名、密码、手机号、角色ID、状态 |
| 用户权限 | sys_role | 角色表,ADMIN/OPERATOR/SAFETY/USER |
| 基础运营 | metro_line | 地铁线路表,含线路名称、编号、首末班时间、颜色标识 |
| 基础运营 | metro_station | 站点主表,含站点名称、经纬度、所属区域 |
| 基础运营 | line_station | 线路站点关联表,记录站点在线路上的顺序和换乘信息 |
| 基础运营 | metro_train | 列车表,含列车编号、所属线路、载客量、状态 |
| 基础运营 | train_schedule | 运行时刻表,记录列车在每个站点的到站时刻 |
| 运营数据 | passenger_flow | 客流表,记录站点分时段进站/出站人数 |
| 运营数据 | lost_found | 失物招领表 |
| 运营数据 | feedback | 意见反馈表 |
| 安全管理 | hidden_danger | 安全隐患表,含等级、位置、描述、图片、状态 |
| 安全管理 | safety_event | 突发事件表,含类型、级别、影响范围、处置状态 |
| 安全管理 | emergency_plan | 应急预案表,关联事件类型和处置步骤 |
这张表的背后是一个很朴素的原则:能表达“业务对象+业务状态”就行。比如安全隐患表必须有status字段,否则你根本没法做“待处理/处理中/已闭环”的流转管理。没有状态字段的流程表,写代码的时候百分之百会回头补字段。
3.2 站点与线路的多对多关系:这是全库设计的核心
地铁业务里最经典的数据建模问题,就是站点和线路的多对多关系:一条线路上有多个站点,一个站点可能同时被多条线路经过(换乘站)。如果不加关联表,直接把站点表的line_id字段挂在站点上,那换乘站只能靠复制一行记录来解决,后续查询会乱成一团。
我设计line_station关联表的时候,除了两个外键字段,还加了两个非常关键的字段:
station_order:站点在线路上的顺序编号。没有它,你没法绘制“线路走向”图,也没法判断相邻站点,前端的线网图直接画不出来。is_transfer:是否换乘站,用于换乘查询时判断是否需要提醒用户换线。
举个例子,查询某条线路所有站点并按顺序返回的 SQL 就是:
SELECT s.station_name, ls.station_order FROM line_station ls LEFT JOIN metro_station s ON ls.station_id = s.id WHERE ls.line_id = #{lineId} ORDER BY ls.station_order ASC;这个 SQL 在答辩里是很好的一个点,因为它说明你真的理解了“关联表 + 排序字段”在复杂业务里的作用。
3.3 客流量表与安全事件表的设计细节
passenger_flow客流表是给图表提供素材的。我建议字段设计为:station_id、line_id、stat_date统计日期、time_slot时段(比如 07:00-09:00)、in_count进站人数、out_count出站人数。统计某个站点一天的分时客流,只需要按时间字段分组聚合;统计全网的日客流,只需要按stat_date分组求和。这种设计把“明细数据”和“汇总展示”分开了,查询性能也好。
安全事件表的设计要特别关注状态流转。一张safety_event表里,我用event_type(设备故障、人员入侵、火灾隐患、自然灾害)、event_level(一般/较大/重大)、status(待受理/处置中/已完成)以及handle_time、handle_result这几个字段来支撑整套流程。需要特别注意的是“处置中”不能只是一个 String 写死,需要有一张关联的处置记录表或至少一个字段存处置说明,这样论文里的“事件闭环管理”才有数据支撑,画表格时也有内容可写。
4. 后端核心模块的实现与代码拆解
4.1 JWT 登录认证与拦截器的标准写法
登录认证这个模块,看起来简单,但很多项目在答辩时被问倒的一个重灾区就是“你凭什么知道当前登录的人是谁”。我当时的做法是 JWT + 拦截器:
用户登录成功之后,后端通过TokenUtil生成一个带userId和roleId的 token 字符串返回给前端。前端之后每次请求在 Header 里带上Authorization: Bearer <token>。后端用一个拦截器统一校验每个请求,解析 token 之后把用户信息放进去。核心代码大概长这样:
public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行登录接口和静态资源 if (request.getRequestURI().contains("/api/login") || request.getRequestURI().startsWith("/static/") || request.getRequestURI().startsWith("/uploads/")) { return true; } String token = request.getHeader("Authorization"); if (token == null || !token.startsWith("Bearer ")) { response.setStatus(401); return false; } // 解析token,校验签名和过期时间 Integer userId = JwtUtil.getUserId(token.replace("Bearer ", "")); if (userId == null) { response.setStatus(401); return false; } LongHolder.set(userId); return true; } }这里有两个细节必须提醒你。第一,拦截器放行名单一定要包含静态资源和上传文件的访问目录,否则页面样式全丢、图片全部 404,演示的时候极其尴尬。第二,token 过期时间不要设太长,我设的是 24 小时,但也写了刷新逻辑——每次请求时如果剩的过期时间不足两小时,就重新签一个 token 返回给前端。有了这个,代码质量比普通课设高一个档次,答辩时完全可以主动提。
4.2 线路、站点、换乘查询的算法选型
换乘方案是乘客端最受关注的功能。这里我先讲清楚一个误区:用最短路径算法没问题,但在地铁场景里大多数用户关心的是“最少换乘”而不是“最短里程”。所以我给乘客推送方案时,先用“最少换乘次数”做第一优先级,再比较总站数。
具体实现我用的是广度优先搜索(BFS),把地铁线网视为一个图:站点是节点,相邻站点之间的连通关系是边,而换乘站的本质是“同一个站点连到多条线路”。搜索过程从起点站出发,逐层扩展相邻站点,并记录走到每个站点时当前乘坐的线路编号;当发现需要通过换乘站换成另一条线路时,就记录一次换乘事件。这样找到的第一条到达终点站点的路径,天然就是换乘次数最少的。
这个算法的核心代码只需 60 行左右,答辩时解释思路也很容易:BFS 为什么能保证最少换乘?因为每一层代表“多一次乘车区间”,搜索层数浅的路径一定优先找到。如果后续想继续加“避开某条线路”或“考虑首末班时间”的限制,只需要在扩展节点时加过滤条件即可。这比一上来就写迪杰斯特拉要更贴合题目,也更好讲。
4.3 客流统计与 Excel 导出
客流统计模块要扛住“数据分析”这四个字。我做了三个维度的统计:按线路总客流排行、按站点分时客流趋势、按日期的全网客流趋势。SQL 写法核心就是聚合函数加分组。比如按站点统计最近七天总客流:
SELECT s.station_name, SUM(pf.in_count + pf.out_count) AS total_flow FROM passenger_flow pf LEFT JOIN metro_station s ON pf.station_id = s.id WHERE pf.stat_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY pf.station_id, s.station_name ORDER BY total_flow DESC;如果把日期作为查询参数,前端按天切换,图表就能联动刷新,演示效果很好。
Excel 导出的功能,我推荐用阿里巴巴的 EasyExcel 而不是原始 POI。理由是 EasyExcel 的注解模型导出,可以直接把实体对象转成报表,代码量少、内存消耗低。课设阶段把“客流统计报表导出”做成一个按钮,导出的文件带标题行、统计日期、排序好的数据,就已经超过了大部分同学只做增删改查的工作量。
5. 轨道交通安全管理模块的落地
5.1 隐患上报的完整链路:从表单到证据留存
安全管理是这个题目和普通“管理系统”拉开差距的核心模块,也是论文里最有内容可写的部分。隐患上报功能的链路是:安全巡查员登录系统后填写隐患表单,包括隐患所在站点/区段、隐患类型(设施损坏、消防隐患、信号异常、人员管理疏漏等)、隐患等级(一般/较大/重大),同时可以上传现场照片作为证据。这里有两个关键设计:
一个是图片上传的处理方式。我不会把图片存进数据库的 BLOB 字段,而是在服务器本地建一个uploads/目录,把文件存进去,数据库只存访问路径。然后写一个 Web 配置把/uploads/**映射到本地磁盘目录,这样前端用http://localhost:8080/uploads/xxx.jpg就能直接访问图片。打包部署之后,这个路径需要在配置里改成外部绝对路径,否则 jar 包重启文件就丢了。
另一个是隐患状态机的定义。我设计为:PENDING待审核 ->PROCESSING处理中 ->RESOLVED已闭环 /REJECTED已驳回。每一次状态变更都记录handle_person和handle_time,这样一条隐患就有了完整的生命周期,评审时可以说“隐患数据是可以追溯的”。没有状态流转的业务表,只能叫记录表,不能叫管理模块。
5.2 应急预案与事件处置的联动逻辑
应急模块最容易让人不知道怎么写,因为“预案”听起来很虚。我的做法是把预案做成“数据支撑”而不是“文档附件”。表里的关键字段是:event_type(关联突发事件类型)、plan_name、content(处置步骤)、level。当一条新的突发事件登记后,系统根据事件类型自动匹配对应的应急预案,并在事件详情页展示。
我当时给预案加了一个非常小的设计:在事件详情页面,系统根据event_level自动用红色、橙色、黄色标签显示事件等级,并且提供“一键启动预案”按钮,点击后把预案状态置为“已启动”,同时记录启动时间与启动人。这个功能本身代码量很小,但看起来非常有业务真实感。答辩时你只需要说“预案不是存一份 PDF,而是和事件类型、等级关联,并支持处置流程入口”,这句话的分量就已经出来了。
事件处置记录做一张独立表,字段是:事件 ID、处置人、处置内容、处置时间、处置结果(已恢复/部分恢复/待观察)。这样每个突发事件都可以展开看具体的处理过程,系统完整度一下就上去了。后续如果有心,还能统计每个处置人处理了多少事件、平均处理时长,这又可以作为“数据大屏”的分析素材。
5.3 安全数据的可视化:把安全管理做成可感知的模块
安全管理能不能可视化?完全可以。我做了三个图表在安全大屏页上:
- 隐患等级占比饼图:展示待处理隐患中一般、较大、重大各占多少比例。
- 突发事件类型柱状图:统计设备故障、人员入侵、火灾隐患等事件的数量排行。
- 月度安全事件趋势折线图:按月统计事件量,观察安全趋势。
这三个图表的数据来源都是前面说的表,SQL 聚合出来之后转成 ECharts 需要的 JSON 格式。做数据可视化最需要注意的是后端返回的数据结构和前端的映射要一致。我习惯在后端定义好count、name这类字段名,前端series里直接用,不让前端自己拼装。联调时一旦图表空白,优先检查返回 JSON 的字段名和 ECharts 配置是否对得上。
6. 可视化大屏与页面联调
6.1 ECharts 客流热力图与折线图的关键配置
我在这类推广型页面上用的核心可视化组件有两个:折线图和热力图。折线图展示“某站点今天各时段的进出站客流”,配置很简单,就是xAxis放时段,series里放两组数据(in_count和out_count)。
这里有一个经验:给折线图加上极值点标注和区域渐变填充,视觉效果会提升很多,代码量也就多几行。ECharts 的markPoint加在系列配置上就能标出峰值时段,演示时你直接就能指着说“早高峰 7-9 点进站量最大”,讲故事的能力会明显增强。
热力图则更适合展示多个站点的“客流热力排行”,visualMap组件配合scatter或自定义矩形图,按客流值自动映射颜色深浅。不过要提醒你,ECharts 的地图型热力图需要 geo 坐标数据,课设阶段不要在这个上面死磕;用站点列表加柱状排行图,照样能把“客流拥挤度”表达清楚。
6.2 管理后台的表格、表单与图片上传
管理后台是管理员每天用的界面,重点是把“增删改查”做得顺滑。我习惯每张业务表都配四个东西:查询条件区、数据表格、新增/编辑弹窗、删除确认。查询条件区至少要有模糊查询和下拉筛选,比如线路列表按状态筛选、事件列表按等级筛选。这个对用户体验的提升非常明显,也是论文截图里能看出“系统交互细节”的地方。
图片上传组件在安全隐患模块里必不可少。前端用<input type="file">配合预览,提交时通过FormData把图片和表单字段一起发送到后端接口;后端用MultipartFile接收后保存到本地。这里要注意一个坑:如果上传文件大小超过 Spring Boot 默认的 1MB,会直接报错。所以必须在配置里把spring.servlet.multipart.max-file-size和max-request-size同时改大,否则复查时发现图片传不上去,只能露怯。
6.3 前后端联调时最容易暴露的三个问题
我第一次联调时遇到的三个问题,可以给你提个醒,省得重复踩坑。
第一个是跨域问题。如果你用的是 Vue 方案,后端接口必须开启跨域支持。可以在配置类里写一个CorsFilter,允许localhost的前端端口访问;如果前后端都在同域部署,可以不用处理,但开发时大概率会遇到。
第二个是日期格式问题。Java 后端的LocalDateTime返回给前端时默认是一串很难读的格式。我建议在统一响应里配置ObjectMapper,或者用@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解,把所有时间字段格式化成可读字符串。没有它,前端的表格和表单里全是2025-06-01T12:00:00这种中间格式,看着就像还没做完。
第三个是前后端字段命名导致的 404 或空数据。现在很多前端用驼峰命名,后端用下划线命名,结果报错半天查不出来。MyBatis-Plus 可以开启驼峰映射,但如果你手写 SQL 返回的是station_name而 VO 字段是stationName,需要保证映射或起别名。建议在写 SQL 时统一加别名,省得后面排查。
7. 部署、自查与答辩:从能跑到能讲
7.1 打包部署与数据库初始化的坑
项目做完之后,第一件事不是写论文,而是把整套系统打包部署一遍,确保在一台干净的环境里能跑起来。用 Maven 打包是常规操作:
mvn clean package -DskipTests打包成功之后会生成一个target/xxx.jar。启动命令非常简单:
java -jar xxx.jar但这里有几个部署时常见的坑,我挨个说。第一个是数据库要先初始化好。你需要在 MySQL 里创建一个数据库,然后执行完整的建表语句。如果你是拿本机的 MySQL 开发,建议把建表 SQL 在项目里单独放在sql/init.sql,并把application.yml里的数据库密码改成部署环境实际用的密码。千万别用初始密码硬跑,数据库连不上是最常见的演示事故。
第二个是上传文件的路径问题。jar 包部署后,文件上传到 jar 包旁边的相对路径可能因为当前工作目录不对而找不到。比较稳妥的做法是在配置文件里指定绝对路径,比如upload.dir: /data/metro/uploads,然后代码读取这个配置。演示的时候把图片上传和展示都跑一遍,确保没有 404。
第三个是静态资源和跨域。打包部署后,如果你的前端放在单独目录或用 Nginx 转发,需要确认接口路径和静态资源路径没有冲突。实在不稳妥,可以放弃前后端分离,把 Thymeleaf 页面直接打进 jar 包,打开浏览器访问 8080 就一切正常,这是最保险的演示方式。
7.2 万字文档怎么写才能不被查重系统盯上
这个题目附带“万字文档”,写论文有个最实用的策略:与其临场编字数,不如把系统设计的过程忠实记录下来。文档目录可以参考这样的结构:
- 绪论:项目背景、国内外地铁信息化现状、课题意义
- 相关技术介绍:Spring Boot、MyBatis-Plus、MySQL、Vue/ECharts
- 需求分析:角色分析、功能性需求、非功能性需求、用例图
- 系统设计:整体架构图、功能模块划分、数据库 E-R 图、表结构说明
- 系统实现:每个模块的功能截图 + 核心代码片段 + 实现逻辑说明
- 系统测试:测试环境、测试用例表、测试结果、性能与安全性简单说明
- 总结与展望
核心技巧总结成一句话:能用表格和截图表达的内容,就不要用大段大段的文字复述。尤其是数据库表结构,用表格把每个字段列出来,再配上文字说明设计意图,这部分是天然的原创内容。代码部分,不要整个类几十行全贴,只贴最关键的业务逻辑代码并写清楚执行流程。这样算下来,一万字非常轻松就能满足,而且查重率不会难看到哪里去。
7.3 答辩现场一定会被问到的几个问题
答辩前,我强烈建议你按下面的清单自己模拟一遍,讲不顺的就对着代码重新理解:
- 系统有哪些角色,不同角色登录后能做什么?
- 换乘方案是怎么算出来的?为什么 BFS 能保证最少换乘?
- 数据库里站点和线路为什么是多对多?怎么建的表?
- 客流统计的数据从哪来的?图表的数据结构是什么样?
- 安全事件的状态怎么流转?隐患上传的图片存在哪里?
- 为什么选 Spring Boot?MyBatis-Plus 的 BaseMapper 帮你做了什么?
- 系统的安全性是怎么考虑的?JWT 过期了怎么办?
这些问题基本都是从你最容易忽略的细节里出。你能清晰回答出一个模块的数据流(从前端表单到后端接口到数据库表再到返回),就已经可以和“只背了代码却讲不出原理”的那部分同学拉开差距了。
如果让我给出一个优先级排序的建议,我会说:先确保系统在演示环境稳定运行三遍不出错,再确保核心模块的代码逻辑你全部能讲明白,最后才是文档的字数和格式。这三个都做到,这个题目稳稳就是一个优秀课设或良好以上的毕设。别在最后阶段临时换主题或者加新功能,那才是翻车率最高的操作。