SpringBoot 配微信小程序做智能停车系统,这两年算是一个很典型的毕业设计/实训项目选题。我前前后后帮人看过不少类似的项目,也亲手改过几套源码,发现一个规律:真正卡住人的往往不是业务代码本身,而是“项目拿到手之后怎么跑起来”以及“跑起来之后怎么跟面试官/答辩老师把技术点讲清楚”。这篇文章我就以“基于SpringBoot智能停车系统小程序”这个项目为例,从需求拆解、后端设计、小程序端实现、部署排错到答辩讲解,把整套东西完整捋一遍。文章里的思路和代码片段都是基于常见实践补充的,你拿到任何一套类似源码,都可以按这个框架去理解它、改造它、把它讲明白。
这个项目适合谁?三类人最合适:一是准备毕业设计的学生,需要一套完整可演示、可扩展的系统;二是想练手SpringBoot+小程序全栈开发的自学者,想看看真实项目里业务是怎么串起来的;三是已经在工作、需要快速接手类似项目的开发者,想跳过弯路直接看关键实现。不管你是哪类,这篇文章的目标只有一个——帮你把这个项目从“能跑”变成“能吃透”。
1. 项目到底做什么:需求梳理与系统拆解
1.1 智能停车系统的核心业务场景
先别急着看代码,先把业务想清楚。停车场管理这件事,线下核心痛点是三块:车主找车位难、停车场收费管理乱、管理人员对车位状态不清楚。智能停车系统要解决的,就是用线上化的方式把这几个环节串起来。
对于小程序端用户来说,核心诉求是:查车位、预约车位、导航到车位、停车结束一键缴费、查看停车记录。对于后台管理端来说,核心诉求是:车位信息管理、订单管理、收费规则设置、用户管理、基础数据统计。
这里的“智能”二字,体现在哪里?不是说你装了几个摄像头就叫智能,而是系统能通过车位状态的实时流转(空闲/占用/预约中)、订单的自动计费、异常状态的提醒,让停车场运营从被动管理变成主动管理。在这个项目里,车位状态流转和订单计费就是最核心的业务逻辑,也是你在答辩时最值得展开讲的部分。
1.2 技术选型:为什么是SpringBoot+微信小程序
技术选型这件事,很多同学是“别人用什么我就用什么”,但答辩老师一问“为什么”,就答不上来。我帮你把理由理清楚。
后端选SpringBoot,理由很实在:第一,SpringBoot的自动装配机制让配置变得极其轻量,一个内嵌Tomcat就能跑起来,不需要额外部署WAR包,这对学生项目和中小型系统来说非常友好;第二,Spring生态成熟,SpringMVC、MyBatis、Spring Security这些组件跟它无缝整合,网上资料多,遇到问题搜得到;第三,SpringBoot的starter机制让你只需要引入依赖就能获得对应能力,比如spring-boot-starter-data-redis、spring-boot-starter-validation,全部约定优于配置,开发效率高。
小程序端选微信小程序,核心原因是触达成本低。用户不用下载App,扫一扫或者微信里搜一下就能用,这非常符合停车场这种“低频但刚需”的场景。再一个,小程序提供了完整的登录体系、支付能力(微信支付)、消息通知能力(订阅消息),做停车缴费这种闭环业务特别合适。相比H5,小程序在调用微信原生能力方面更顺畅,用户体验也更好。
这里多说一句,很多人在选型时会纠结“为什么不用Vue+ElementUI做管理后台”。实际上,这个项目里管理后台用SpringBoot的Thymeleaf模板引擎或者前后端分离都行。如果你拿到的是前后端分离版本,那后端就是纯接口服务,小程序和管理后台都通过HTTP调用接口,这种结构职责更清晰,也更好扩展。
1.3 系统模块与功能清单
拿到一套源码,第一件事不是急着启动,而是先看项目结构,搞清楚它包含哪些模块。我以最常见的分层方式给你拆一下:
- 用户端(微信小程序):微信登录、首页车位地图/列表、车位查询、车位预约、一键导航、扫码/手动入场、停车计时、在线缴费、停车记录、个人中心。
- 管理端(Web页面):管理员登录、车位管理(增删改查、状态修改)、停车场信息管理、收费规则设置、订单管理、用户管理、数据统计看板。
- 后端接口服务(SpringBoot):用户与管理员鉴权、车位与停车场业务接口、订单与计费接口、支付回调接口、数据统计接口。
对照源码看的时候,建议你按“登录鉴权 → 车位流转 → 订单计费 → 数据统计”这条主线去读,不要一头扎进细节里出不来。先把主流程跑通,再去理解细枝末节。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 后端核心设计:SpringBoot实现的关键细节
2.1 数据库表设计:从用户到订单的完整链路
停车系统要管的数据其实不复杂,核心表就几张:用户表、管理员表、停车场表、车位表、订单表、收费规则表。再加上可能的预约表、停车记录表。
我拿最常见的表结构给你说几个关键设计点。
用户表(user)一般包含:openid(微信唯一标识)、nickname、avatar、phone、create_time。注意openid一定要加唯一索引,这是小程序登录体系里的核心字段。
停车场表(parking_lot)包含:name、address、total_space、available_space、latitude、longitude、fee_rule_id。这里有一个点:available_space(剩余车位)是高频查询字段,但同时也是高频更新字段,后面我会专门讲并发问题。
车位表(parking_space)包含:parking_lot_id、space_no、status(0空闲、1占用、2预约)。这里注意,车位表的状态是业务流转的关键,所有接口的增删改查最终都要落到这个状态字段上。
订单表(order)是整张表里最复杂的,包含:order_no(订单号)、user_id、parking_space_id、entry_time、exit_time、duration、total_fee、status(0进行中、1已完成、2已取消)、payment_time。订单表要建立user_id和status的联合索引,因为用户查询自己的停车记录、管理员查询订单列表都是高频操作。
收费规则表(fee_rule)一般包含:first_hour_fee(首小时费用)、additional_hour_fee(超时每小时费用)、max_daily_fee(单日封顶费用)。计费逻辑是整个系统里最容易出bug的地方,后面我会详细展开。
2.2 车位状态管理的并发控制
这是整个项目里技术含量最高的一个点。场景是这样的:两个用户同时看到同一个空闲车位,同时点击预约,如果不做任何控制,两个人都可能预约成功,但车位只有一个,这就会产生超卖。
解决方案有几种,由简单到复杂排列:
最基础的是数据库层面的行锁。用SELECT ... FOR UPDATE把车位行锁住,然后再判断状态并更新。伪代码如下:
sql复制-- 开启事务
SELECT * FROM parking_space WHERE id = #{spaceId} FOR UPDATE;
-- 在代码中判断 status 是否为 0
-- 如果是 0,执行 UPDATE parking_space SET status = 2 WHERE id = #{spaceId};
-- 提交事务
这种写法在单体应用、低并发场景下完全够用,也是很多毕业设计采用的做法。它的优点是简单可靠,缺点是锁的粒度比较粗,如果事务处理时间过长,会影响其他请求。
第二种是乐观锁方案。在车位表里加一个version字段,更新时带上版本号:
sql复制UPDATE parking_space SET status = 2, version = version + 1
WHERE id = #{spaceId} AND status = 0 AND version = #{oldVersion};
通过受影响行数来判断是否更新成功,如果返回0,说明车位状态已经被别人改了,需要提示用户重新选择。这种方案性能更好,但需要在代码里处理更新失败的逻辑。
第三种是Redis分布式锁。在高并发场景下,用Redis的SETNX加锁,锁车位ID,拿不到锁就直接返回失败。这个方案需要引入Redis依赖,对于毕业设计来说可能稍微重了一点,但如果你在简历里写了“使用Redis解决了车位并发预约问题”,面试官一般都会眼前一亮。
实操建议:如果你是学生项目,用synchronized或者数据库行锁就足够了,面试时把并发问题的场景和解决方案讲清楚,比盲目堆技术更能体现你的思考深度。
2.3 微信登录:从code到openid的完整链路
小程序登录是很多人第一个卡住的点,尤其是报错类似获取登录后的微信用户失败:wx1cb4398e1413dce7的时候,很多人根本不知道从哪排查。我先讲原理,再讲排查。
微信小程序的登录流程是:小程序端调用wx.login()拿到一个临时凭证code,然后把code发送给后端;后端拿着code去微信接口服务换openid和session_key,接口地址是:
text复制https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code
后端在SpringBoot里一般用RestTemplate或HttpClient发起这个请求。核心代码类似:
java复制@Autowired
private RestTemplate restTemplate;
public Map<String, String> wxLogin(String code) {
String url = "https://api.weixin.qq.com/sns/jscode2session?appid="
+ appId + "&secret=" + appSecret
+ "&js_code=" + code + "&grant_type=authorization_code";
String result = restTemplate.getForObject(url, String.class);
// 解析 result,拿到 openid、session_key、unionid
// 然后根据 openid 查询用户,不存在则自动注册
// 生成自定义登录态 token(JWT 或 UUID)返回给前端
}
拿到openid之后,后端一般会生成一个自定义的登录凭证(通常是JWT)返回给小程序端,小程序端后续请求都带上这个token,后端通过拦截器校验token并解析出用户身份。
排查获取登录后的微信用户失败这个报错时,按这几个顺序查:第一,小程序端app.js里的appid是否跟你注册的小程序AppID一致,很多人用的是测试号,但后端配置的是真实AppID;第二,后端配置的appSecret是否跟AppID匹配;第三,后端服务器的域名/IP是否在小程序后台的“request合法域名”里配置过(如果是在开发者工具里调试,可以勾选“不校验合法域名”);第四,确认wx.login()返回的code没有被重复使用,一个code只能用一次。
2.4 订单计费:状态机与金额计算的坑
停车计费是整个后端业务里最容易写乱的地方。我给你一个经过验证的思路。
订单状态用状态机来管理。定义几个状态:PAYING(停车中/待支付)、PAID(已支付)、CLOSED(已关闭)。状态流转路径是:入场创建订单(PAYING)→ 出场计算费用 → 用户支付 → PAID;如果用户长时间不支付,系统定时任务把订单置为CLOSED。
计费逻辑一定要单独抽一个方法,不要写在Controller里。核心逻辑是:根据入场时间和出场时间计算停车时长,然后根据收费规则计算费用。这里有个很常见的坑——不足一小时按一小时算,还是按分钟累计?不同的停车场规则不一样。
我给一个常见的计费规则实现示例:
java复制public BigDecimal calcFee(Date entryTime, Date exitTime, FeeRule rule) {
long minutes = Duration.between(entryTime.toInstant(), exitTime.toInstant()).toMinutes();
if (minutes <= 0) {
minutes = 1;
}
// 免费时段判断:如果首小时免费,则先扣减
if (rule.getFreeMinutes() != null && minutes <= rule.getFreeMinutes()) {
return BigDecimal.ZERO;
}
minutes -= Optional.ofNullable(rule.getFreeMinutes()).orElse(0);
// 首小时费用
BigDecimal fee = rule.getFirstHourFee();
// 超过首小时的部分,按额外小时计费(不足15分钟按15分钟,或者向上取整)
long extraHours = (minutes - 60 + 59) / 60;
if (extraHours > 0) {
fee = fee.add(rule.getAdditionalHourFee().multiply(BigDecimal.valueOf(extraHours)));
}
// 单日封顶
if (rule.getMaxDailyFee() != null && fee.compareTo(rule.getMaxDailyFee()) > 0) {
fee = rule.getMaxDailyFee();
}
return fee;
}
注意,上面是简化示例,真实项目里还要考虑跨天、节假日规则、免费时长、不同车型费率等。在做毕业设计时,建议至少把“首小时+超时累加+单日封顶”这三个规则实现完整,并且写几个单元测试来验证边界情况,这在答辩时会成为很大的加分项。
关于金额计算,有两条铁律:第一,金额计算一律用BigDecimal,禁止用double;第二,费用计算放在后端,小程序端只做展示,绝对不要在前端算金额,否则用户可以篡改请求参数白嫖。
3. 小程序端实操:登录、车位查询与预约实现
3.1 项目导入与开发者工具配置
拿到小程序端源码后,第一个动作是用微信开发者工具导入项目。导入时需要注意几个配置:
- AppID:如果是自己的小程序,选“使用测试号”会导致部分能力不可用,最好注册一个小程序账号,把真实的AppID填进去。
- 后端接口地址:开发者工具右上角“详情”→“本地设置”里,勾选“不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书”,否则本地联调时请求会被拦截。这个选项只用于开发调试,上线前一定要关掉。
- 新版开发者工具默认会开启
ES6转ES5,如果你的源码里用了async/await,建议开启这个选项,避免在低版本微信上出现兼容问题。
导入成功后,先看utils/request.js或api.js,这里面封装了所有接口请求。常见封装方式是:用wx.request发送请求,请求头带上Authorization token字段,响应拦截器统一判断HTTP状态码和业务状态码,401时自动跳转登录页。理解了这个文件,你就知道整个小程序端是怎么跟后端通信的了。
3.2 登录流程实现与常见报错处理
登录流程在小程序端的实现一般是这样的:页面onLoad时先检查本地缓存有没有token,没有则调用wx.login()获取code,然后调后端登录接口,拿到token后存到wx.setStorageSync里。
这里有一个经常被忽略的细节:wx.login()得到的code有效期只有5分钟,而且只能用一次。如果你在onLoad里调了登录,又在onShow里调了一次,第二次一定会失败。所以正确的做法是:不要每次进入页面都重新登录,优先使用本地缓存的token,token过期后再走静默登录流程。
常见的报错和处理办法我整理成一个清单:
| 报错信息 | 原因 | 解决方案 |
|---|---|---|
request:fail |
请求失败,通常是域名未配置或本地未勾选不校验合法域名 | 开发环境勾选不校验域名,生产环境在小程序后台配置request合法域名 |
获取登录后的微信用户失败 |
code无效、appid不一致或后端解析失败 | 检查appid和secret,检查code是否被重复使用 |
appid not found |
AppID不存在或格式不对 | 到小程序后台确认AppID |
401 Unauthorized |
token缺失或过期 | 检查请求头是否带了token,检查后端token校验逻辑 |
url not in domain list |
请求域名不在白名单 | 生产环境在小程序后台添加域名白名单 |
3.3 车位查询与预约页面实现要点
车位查询页面是这个小程序的门面,一般有两种展示方式:列表和地图。列表方式简单直接,用scroll-view做滚动列表,每一行显示车位编号、位置、状态(空闲/占用/预约中)和预约按钮。地图方式会更炫一点,用map组件配合markers展示车位满空状态,用户点marker可以查看车位详情。
我建议你在做的时候,把“列表+地图”都做出来,因为答辩时评委大概率会问“你的车位状态是怎么实时更新的”。地图方案涉及加载停车场平面图坐标、生成marker、切换状态后刷新marker等逻辑,讲起来内容丰富得多。
对于用户点击“预约”按钮,前端应该做两件事:第一,跳转到确认页面,展示车位信息、入场时间和计费规则预览;第二,在用户确认后调用后端预约接口,成功后向前端提示“预约成功,请在XX分钟内入场”。这里给用户一个入场倒计时,是很多商业停车App都有的设计,加上去会让你的项目更有完整性。
3.4 页面适配:顶部导航栏与底部安全区
小程序适配是新手容易踩坑的地方。最常见的两个问题是:iPhoneX等机型底部小黑条遮挡内容、不同机型顶部导航栏高度不一致。
我直接给你一个通用的解决方案。
对于底部安全区,使用env(safe-area-inset-bottom):
css复制.footer {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
对于顶部导航栏高度,不要写死。用胶囊按钮的位置动态计算:
js复制const systemInfo = wx.getSystemInfoSync();
const menuButton = wx.getMenuButtonBoundingClientRect();
const navHeight = menuButton.bottom + (menuButton.top - systemInfo.statusBarHeight) * 2;
这段代码是业内通用做法。把导航栏高度动态计算出来,各机型都能适配。如果你看到源码里写的是固定高度padding-top: 64rpx,建议改成动态计算方式,这个小细节在演示时很能博好感。
4. 部署与联调:把系统完整跑起来
4.1 本地环境准备:JDK、Maven、MySQL、Redis
通常一个完整的SpringBoot后端依赖以下环境:JDK 1.8(或项目pom里指定的版本)、Maven 3.6+、MySQL 5.7+(或8.0)、Redis(如果项目里用到缓存或分布式锁)。
这里单独说一下SpringBoot版本太高这个坑。很多项目源码用的是SpringBoot 2.x,比如2.5、2.7,但如果你比较新,直接开了Spring Initializr新建了个3.x项目,就可能遇到一堆兼容问题。SpringBoot 3.x要求JDK 17+,且很多旧版本的依赖(比如mybatis-spring-boot-starter)还没有对应的兼容版本。我的建议是:拿到源码第一件事,看pom.xml里SpringBoot的版本和JDK版本,然后严格按这个版本去准备环境,不要自作主张升级大版本。如果你确实想用新版,也要有心理准备去解决依赖兼容问题。
4.2 数据库初始化与配置文件修改
数据库初始化通常是这套流程:在MySQL里新建一个数据库(比如smart_parking),然后导入项目里的sql文件。导入时注意sql文件的字符集,推荐用utf8mb4,否则中文会出现乱码。
导入成功后,修改后端的配置文件。如果你用的是application.yml,重点检查这几项:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/smart_parking?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: your_password
redis:
host: localhost
port: 6379
password:
这里有个很容易踩的坑:MySQL 8.0的驱动是com.mysql.cj.jdbc.Driver,而MySQL 5.7及以下常用的是com.mysql.jdbc.Driver。如果你的数据库是8.0,但源码里配置的是老驱动,启动时会报ClassNotFoundException或者连接失败。看pom.xml里的mysql-connector-java版本就能判断。
如果你在部署时用的是高版本JDK(比如JDK 17)跑老项目,可能会遇到java.lang.reflect.InaccessibleObjectException这类反射相关报错,这是因为新版JDK对反射做了模块化限制。最简单的解决办法是换回JDK 8,而不是去加一堆--add-opens参数。
4.3 前后端联调:局域网真机测试
在小程序开发者工具里跑通之后,建议再做一步“真机预览”。步骤是:手机和电脑连同一个WiFi,后端启动时不绑定localhost,而是绑定0.0.0.0,小程序端请求地址改成电脑的局域网IP,比如http://192.168.1.100:8080。然后在开发者工具里点击“真机调试”,手机扫码即可预览。
这一步往往能暴露出很多模拟器上看不出来的问题,比如接口超时、图片加载失败、真机上的TLS校验。有一点要注意:真机调试时,小程序不能勾选“不校验合法域名”,但微信允许在真机调试模式下忽略域名校验,如果你在真机预览时发现请求全部失败,先确认是否开了调试模式。
4.4 服务器部署:从打包到云服务器运行
如果只是毕业设计演示,本地运行完全够了。但如果你想给项目增加“已部署上线”这个亮点,可以尝试部署到云服务器上。流程如下:
第一步,打包后端项目:
bash复制mvn clean package -DskipTests
在target目录下会生成一个xxx.jar文件。这就是可以直接运行的可执行包。
第二步,把jar包上传到服务器,然后后台运行:
bash复制java -jar smart-parking.jar --spring.profiles.active=prod > app.log 2>&1 &
生产环境的数据库、Redis等配置建议单独写到application-prod.yml里,用--spring.profiles.active=prod指定。
第三步,如果你的服务器有域名,记得在小程序后台配置request合法域名,并要求该域名已备案且支持HTTPS。如果暂时没有域名,可以先在小程序开发者工具里演示,不影响系统功能。
如果你想用Docker部署,可以参考这样一个简单的Dockerfile:
dockerfile复制FROM openjdk:8-jdk-alpine
MAINTAINER your_name
COPY target/smart-parking.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
但要注意,如果你的宿主机环境是Apple Silicon芯片(M1/M2),并且你用的是JDK 1.8,就可能遇到镜像兼容问题。这里建议直接装Docker Desktop后运行容器,不要用老的openjdk:8-jdk-alpine镜像,因为新机器上启动会比较慢。实际的兼容性问题建议以当前环境实测为准。
5. 常见问题排查与避坑指南
5.1 后端启动失败排查
后端启动失败,九成是以下三个原因:
一是端口被占用。默认SpringBoot端口是8080,如果你本机已经有服务占用了8080,启动就会报Port already in use。解决办法是换端口,在配置文件里改server.port,或者在启动时指定:
bash复制java -jar app.jar --server.port=8081
二是数据库连接不上。检查数据库服务是否启动、url里的IP和端口对不对、用户名密码是否正确、数据库是否已经导入了sql文件。遇到Access denied for user,就是用户名或密码错了;遇到Unknown database,就是数据库名不对或还没创建。
三是依赖下载失败。Maven编译时卡在下载依赖,或者报Cannot resolve symbol,大概率是网络问题或镜像源问题。国内建议在settings.xml里配置阿里云镜像:
xml复制<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
配置完镜像后,重新执行mvn clean install。
5.2 小程序端请求失败排查清单
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 所有请求都失败 | 域名未配置/未勾选不校验合法域名 | 打开开发者工具“详情”→“本地设置”,勾选不校验合法域名 |
| 只有部分请求失败 | 后端接口路径写错或参数不对 | 打开Network面板,看具体报错信息 |
| 请求成功但数据为空 | 后端接口返回了空列表,或数据查询条件不对 | 用Postman直接调后端接口验证 |
| 时区问题导致时间差8小时 | MySQL连接时未指定serverTimezone | 在jdbc url里加serverTimezone=Asia/Shanghai |
5.3 部署文档到底怎么读
很多源码附带部署文档,但文档写得参差不齐。我的建议是:不要从头到尾读,而是按“需要什么查什么”的方式去用。先看“环境要求”章节,确认版本;再看“数据库初始化”,执行sql脚本;再看“配置文件修改”,改数据库密码;再看“启动步骤”,启动后端;最后看“小程序配置”,改appid和接口地址。如果文档里写的东西和你实际跑起来的不一致,以实际运行结果为准,把差异记录下来,这本身就是一种收获。
6. 从能跑到能讲:答辩与面试的表达思路
项目跑起来只是第一步,能讲清楚才是拉开差距的地方。我辅导过不少同学,发现他们最常犯的毛病是:“我的系统实现了登录、预约、缴费……”全在背功能列表。这个讲法很平,没有亮点。
我建议你换一个思路,按“问题→方案→亮点”来组织表达。
比如讲车位预约并发问题。你可以这样说:“这个项目里最核心的难点是车位预约的并发控制。刚开始实现的时候,我直接用普通的update语句更新车位状态,后来测试发现,两个用户同时预约同一个车位时会出现超卖。后来我改用数据库行锁的方案,先SELECT FOR UPDATE锁住车位记录,再判断状态更新,解决了这个问题。再后来我了解到可以用Redis分布式锁来进一步提高并发能力,但由于当前项目规模不大,行锁方案已经能满足需求,所以在架构上保留了这个扩展空间。”
这段表达里,你展示的不只是“你会调接口”,而是“你有遇到问题、分析问题、解决问题的完整链路”。这才是答辩和面试真正考察的能力。
当然,你在改代码之前一定要先理解代码,不要一上来就改。拿到任何一套源码,按顺序做四件事:看清项目结构、跑通主流程、画出核心表关系图、理解关键接口的调用链。做完这四步,这套源码才真正变成了你的东西。
7. 写在最后的实操心得
啰嗦了这么多,最后分享几个我实际带项目时的心得,希望能让你少走点弯路。
第一,环境问题不要死磕。如果你在配置环境时卡了超过两个小时,最快的解决办法不是继续硬试,而是换一个更稳妥的环境组合。比如SpringBoot 2.7配JDK 1.8配MySQL 5.7,这个组合我实测过无数遍,基本不会出问题。等系统跑通了,再慢慢去研究高版本的特性不迟。
第二,善用断点调试和日志。很多同学遇到Bug第一反应是打印一堆System.out,但我更推荐你在关键接口里用断点调试,一步一步看数据是怎么流转的。SpringBoot的@RestControllerAdvice可以做全局异常处理,把异常信息记录到日志里,这样排查问题会快很多。另外,SpringBoot的spring-boot-starter-actuator暴露了/actuator/health端点,部署后可以用它来快速判断服务是否存活。
第三,如果有时间,一定要给核心业务方法写单元测试。不需要覆盖全部,只测三个核心模块:计费规则、车位状态流转、订单状态流转。写测试不是为了那点覆盖率,而是让你在改代码的时候有底气——保证这次改动不会把原来的功能改坏。在答辩时,你还能收获一句“这位同学有工程意识”的评价。
第四,项目做完之后,强烈建议你把它整理成一篇文档,记录你做过哪些功能、遇到过哪些坑、怎么解决的、项目结构怎么设计。一方面,这是你后续答辩和面试时最靠谱的“提词器”;另一方面,写作的过程会逼你重新审视整个系统,很多之前模糊的地方都会变得清晰起来。
智能停车这个选题,说难不难,说简单也不简单。它的核心价值在于让你完整走一遍“前端小程序+后端服务+数据库设计+部署上线”的全流程,这恰恰是实际工作中非常需要、但课本上很难学到的能力。把这套东西吃透,收获的绝不仅仅是一个能跑的项目。
