做毕设最怕什么?不是方案选型的时候犹豫不决,也不是代码写不出来的那种抓狂,而是好不容易把功能都码完了,结果一运行全是红字报错,或者给导师演示的时候小程序白屏打不开。这两年,基于SpringBoot+小程序这套组合做高校生活互助平台,在计算机毕设里几乎可以说是“标配级”选题。我帮人调试过好几个同类的项目,也陪着踩过不计其数的坑,所以这篇文章就从一个实际交付的角度,把这个项目从头到尾掰开了讲清楚,包含技术选型逻辑、核心模块设计、关键问题排查,以及顺手给你的文档和答辩建议。
这套项目能干什么?简单说,就是做一个微信小程序端的校园跑腿/互助社区,学生可以在上面发代取快递、拼单、借书、帮忙带饭这类需求,其他学生看到后可以抢单或接单,双方在线完成交易闭环,后台管理端负责用户、分类、订单和统计管理。它既覆盖了小程序端、后端接口、数据库设计、权限控制、状态流转这些毕设考察重点,又因为是贴近校园生活的话题,答辩时讲需求背景也顺理成章。适合Java基础还行但没做过完整项目的同学,也适合想快速落地一个能跑、能演示、能扩展的毕设的应届生。
1. 项目整体设计思路:从哪里开始拆分这个互助平台
拿到课题先别急着写代码,我见过太多人上来就建工程、写实体类,结果做到一半发现模块缺胳膊少腿,前端调接口的时候才发现字段对不上,返工返到怀疑人生。先把设计捋清楚,后面每一步都是顺水推舟的事。
1.1 需求定位:解决什么问题,核心用户是谁
高校生活互助平台的需求来源非常具体:大学生活中,代取快递、食堂带饭、临时借书、二手闲置、拼单凑单是高频场景。这些场景有一个共同特点——需求临时、金额小、距离近、社交关系较紧密。所以平台的核心不是社交,不是社区内容,而是“需求撮合与履约闭环”。
从用户角色拆,主要分三类:
- 需求发布方:学生A,需要有人帮忙取快递,发布任务,支付报酬或积分享谢。
- 需求承接方:学生B,在平台上浏览待接单任务,接单后完成并获得收益。
- 管理员:负责用户审核、分类管理、订单仲裁、数据统计等运营操作。
整个系统的核心链路就一条:发布需求 → 系统通知/展示 → 承接方接单 → 线下履约 → 确认完成 → 评价结算。这个链路才是项目的灵魂,后面的表结构、接口设计、小程序页面,全部要围着它转。
1.2 技术选型:为什么是SpringBoot + 微信小程序
技术上这个组合几乎是毕设最优解,没有之一。
后端用SpringBoot,理由很实在:一是生态成熟,整合MyBatis-Plus、Redis、JWT、微信支付都有大量现成资料,遇到问题随便一搜就有答案;二是自动配置机制能省掉大量XML配置,代码结构清晰,适合写进毕设论文的“系统设计”章节;三是SpringBoot是Java岗位面试的绝对高频考点,做完这个项目你等于把Spring的核心机制、自动配置原理、拦截器、事务管理这些全过了一遍。
小程序端选微信原生而非uni-app,原因也很朴素:你只有一套端,不需要跨平台,原生小程序语法直接、调试工具好用,社区里踩坑案例也最多,出了问题容易找到解决办法。如果选uni-app,虽然能跨端,但反倒增加了一层的复杂度,对毕设来说没必要。
数据库用MySQL,持久层用MyBatis-Plus,这就不用说了,国产毕设三件套,文档多、资料全,导师也认。
1.3 模块划分:哪些功能必须做,哪些可以往后放
功能优先级是最考验“毕设统筹能力”的地方。我建议按MVP思路划分,主力先搞定主链路,再补辅助功能。
必须做(主链路):
- 用户登录注册(微信授权登录 + token管理)
- 需求发布(标题、描述、分类、报酬、地址、联系方式)
- 需求大厅与详情(按分类筛选、分页加载)
- 接单/取消操作(含状态变更)
- 我的发布和我的接单列表
- 管理员后台(用户管理、订单管理、分类管理)
有条件就做(加分项):
- 消息通知(订单状态变化时微信订阅消息或站内信)
- 评价系统
- 数据统计(ECharts图表展示每天单量、分类占比)
- 举报和信用分机制
可以做但优先级低(非必要不碰):
- 在线支付(涉及商户号、微信支付V3接口申请,流程长,个人开发容易卡壳,你宁可做成“平台积分”或者“线下结算”也不要在支付上耗太久)
- 实时聊天(需要WebSocket,成本和复杂度都高,可以用电话/微信号代替)
这里有个很实际的建议:把单体平台做到功能闭环、演示流畅,比追求大而全但到处是洞的项目,在答辩时得分高得多。
2. 核心细节解析与实操要点:后端与小程序端的实现关键点
确定好模块之后,进入真正写代码的阶段。这一节我把后端和小程序端最容易出问题、也最容易体现“专业度”的细节拿出来单独讲,每一个都是我实际调过的坑。
2.1 后端工程结构与统一响应体设计
SpringBoot工程结构我建议按业务模块分包,而不是按技术分层分包。两种风格差别很大:
按技术分包(controller、service、mapper这种)在简单项目里还凑合,但一旦业务多了,改一个功能要跨好几个包,非常痛苦。按业务分包则清爽得多:
com.campus.help ├── common // 公共类:统一响应、异常、工具类 │ ├── Result.java │ ├── ResultCode.java │ └── GlobalExceptionHandler.java ├── config // 配置类:拦截器、跨域、微信参数 ├── module │ ├── user // 用户模块:controller/service/mapper/entity │ ├── demand // 需求模块 │ ├── order // 订单模块 │ └── admin // 管理端模块 └── util // JWT工具、距离计算等这里最核心的公共类就是Result。前后端分离开发,接口返回的数据格式一定要统一,否则前端解析的时候会被你逼疯。我个人惯用的结构:
{ "code": 200, "message": "success", "data": {} }对应的Java类也很简洁:
public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.setCode(200); result.setMessage("success"); result.setData(data); return result; } public static <T> Result<T> error(Integer code, String message) { Result<T> result = new Result<>(); result.setCode(code); result.setMessage(message); return result; } }所有Controller的返回值都统一走这个Result,配合全局异常处理器,前端不管拿到什么响应,只需要解析code判断业务成功与否,解析data取数据即可。
2.2 数据库表设计:不是建表,是建模
互助平台的表结构不复杂,但有几张表的好坏会直接影响代码的复杂度和需求变更的承受能力。核心表我一般这样设计:
用户表(user)
- id、openid、nickname、avatar、phone、credit_score、status、create_time
需求表(demand)
- id、user_id(发布人)、title、description、category_id、reward、status、address、contact、create_time、update_time
订单表(order_info,订单不是“Order”,Order是SQL关键字,容易出坑)
- id、demand_id、publish_user_id、accept_user_id、status、accept_time、finish_time、cancel_reason
分类表(category)
- id、name、icon、sort
消息表(message)
- id、from_user_id、to_user_id、content、is_read、create_time
这些表之间有几个设计要点:
- 需求表和订单表为什么要分开?因为一个需求可能被多次接单尝试(虽然我们最终做的是先到先得),拆开更灵活,后续要支持“多人竞标”也更合理。
- status字段不要用魔法值散落各处,建议用枚举类常量统一管理,比如OrderStatusEnum包含WAITING、ACCEPTED、FINISHED、CANCELLED、REPORTED。
- 金额字段用int存“分”而不是decimal存“元”,可以完美避开浮点数精度问题。
2.3 小程序端的请求封装与登录态管理
小程序端的核心在于统一管理请求,千万不要在每一个页面里都直接wx.request。我在项目中习惯封装一个request.js模块:
const BASE_URL = 'https://yourdomain.com/api' function request(url, method, data) { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + url, method: method, data: data, header: { 'Content-Type': 'application/json', 'Authorization': wx.getStorageSync('token') || '' }, success(res) { if (res.statusCode === 200) { resolve(res.data) } else if (res.statusCode === 401) { wx.navigateTo({ url: '/pages/login/login' }) reject(res) } else { reject(res) } }, fail(err) { reject(err) } }) }) }登录态这块是很多人栽跟头的地方。微信小程序登录的完整链路是:wx.login获取临时code → 传给后端 → 后端拿着code + appid + secret去微信接口换openid和session_key → 后端生成自定义token返回给小程序 → 小程序保存token,后续请求带着token。
注意,openid是用户唯一标识,但不要直接拿openid当token用,因为openid如果暴露,别人拿你的openid就能伪装你。正确做法是后端用JWT生成一个带过期时间的token,把userId放进去,小程序端每次请求在拦截器中校验token。
2.4 管理端的定位:复用后端接口还是一套独立系统
很多同类毕设做着做着,管理端就做成了一个小程序里的隐藏页面,这样做也不是不行,但演示的时候总感觉差点意思。我建议管理端做成简单的Web页面,用Vue + Element-UI这类后台管理框架,复用后端接口,只暴露管理员token才能访问的接口。这样技术栈覆盖更全,论文里也能多写一个“子系统的设计与实现”。
如果时间实在不够,退一步就是小程序里加一个管理员入口,进入专门的“管理页”,接口上做好权限校验。这两种方案我都在项目里试过,前者视觉效果更专业,后者代码量更少。按毕设时间规划来取舍就行。
3. 实操过程与核心环节实现:从建表到接口打通的全流程
这一部分我直接按实操顺序写,尽量还原我在配置这个项目时的完整流程,包括一些你可能没注意到的关键细节。
3.1 工程初始化与依赖配置
创建SpringBoot项目的时候,网上很多教程直接用IDE的Spring Initializr,但如果你网络不好,创建项目超时是常有的事。我的做法是直接去start.spring.io下载压缩包,或者在阿里云镜像地址创建,速度快很多。
要用到的核心依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>4.4.0</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>MyBatis-Plus版本别乱升,3.5.x是比较稳的区间。有些人图新鲜装了4.x,结果一大堆API不兼容,光修这些就够你折腾一个礼拜。
application.yml配置这里有个细节值得注意——数据库密码、appsecret这类敏感信息不要明文写在配置文件里。毕设里虽然没人真的攻击你,但论文里如果贴了配置截图,把密码露出来,答辩时被问“安全问题”就尴尬了。可以用jasypt做加密,或者至少用环境变量引用:
spring: datasource: url: jdbc:mysql://localhost:3306/campus_help?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: ${DB_PASSWORD}3.2 表结构自动创建:MyBatis-Plus的初始化模式
建表这事,我在项目里走过弯路。一开始我用Navicat手动建表,后来换了台电脑,发现数据库没有了,建表脚本也没保存,气得头疼。后来我直接把建表语句放到项目里的schema.sql,配置SpringBoot启动时自动执行SQL脚本,这样不管换到哪台机器,跑一下项目表就自动建好了,配合数据初始化data.sql,开发效率直线上升。
还有一种玩法是用MyBatis-Plus的自动建表功能,但篇幅有限不说具体实现,简单提示:通过实现MyBatis-Plus的IDatabaseIdProvider接口,配合数据库元数据判断表是否存在,不存在就执行CREATE TABLE语句。这个方法在“表不存在自动建表”这个需求下非常实用,我已经把它集成到了项目启动类里,每次部署新环境都省事。
spring: sql: init: schema-locations: classpath:schema.sql >@Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setConnectTimeout(5000); factory.setReadTimeout(5000); return new RestTemplate(factory); }登录接口返回的token,我建议设置7天有效期,如果用户7天不登录再重新授权。这里有个细节:token过期和刷新机制不用做得太复杂,小程序端每次启动时先检查本地token是否存在,存在就直接用,调用接口返回401再跳登录页。这套逻辑在毕设里完全够用,不建议引入Redis做token黑白名单,增加复杂度没必要。
3.4 需求发布和接单的状态流转
需求发布接口很简单,就是把你填的表单插到demand表。但接单接口就需要注意并发问题了。同一个需求,理论上只能被一个人接单。如果两个人同时点“接单”按钮,代码逻辑是:
- 先查demand的status是否为WAITING
- 如果是,把status改成ACCEPTED并插入订单记录
在高并发下,两个请求可能同时查到WAITING,然后都去更新,导致两个人都接单成功。解决办法一般有两种:
一种是通过乐观锁,在demand表里加version字段,更新的时候带上version条件:
UPDATE demand SET status = 'ACCEPTED', version = version + 1 WHERE id = #{id} AND status = 'WAITING'如果受影响行数为0,说明已经被别人抢了,就返回“手慢了,需求已被接走”。
另一种是用分布式锁,但毕设项目不需要引入Redisson这种重量级组件。我用的是乐观锁方案,代码简单、逻辑清晰,答辩时还能解释一下“乐观锁与悲观锁的区别”,这可是面试和答辩的经典题,你提前实践过就更有说服力。
3.5 小程序端的核心页面实现要点
小程序端的页面不多,但有几个页面的实现值得单独说。
需求大厅页面,核心是列表渲染和分页。用onReachBottom触底加载下一页,加上loading状态防止重复请求。分页参数用pageNum和pageSize,后端用MyBatis-Plus的Page对象直接处理:
Page<DemandVO> page = demandMapper.selectDemandPage( new Page<>(pageNum, pageSize), categoryId, keyword );这里要注意,不要直接在Service里new Page,而是作为参数传入Mapper,这样MyBatis-Plus才能正确执行分页插件。
发布需求页面,需要注意表单校验。报酬可以不填,但标题、描述、联系方式必须填,前后端双重校验。前端校验为了用户体验,后端校验为了数据安全,两者各司其职。
订单详情页面,要区分“我发布的”和“我接单的”两种视角。我发布的订单,可以取消(如果还是WAITING状态);我接单的订单,可以标记“已完成”。状态不同,操作按钮不同,后端通过userId和订单角色来判断是否有操作权限。
动态设置标题这个小功能我也提一下,小程序原生里可以在onLoad时wx.setNavigationBarTitle:
wx.setNavigationBarTitle({ title: '需求详情' })3.6 文件上传:头像上传与图片附件
用户头像和需求图片上传,这个小功能看似简单,但坑不少。后端接口用MultipartFile接收,保存到本地磁盘或OSS,再返回可访问的URL。
如果是本地保存,需要配置静态资源映射:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/upload/**") .addResourceHandler("file:" + uploadPath + "/"); } }更推荐的做法是接七牛云或阿里云OSS,免费额度对学生党来说完全够用,而且不用考虑服务器磁盘空间和备份问题。上传成功后返回的URL直接存到数据库的avatar字段或demand的image字段里,前端用image组件直接渲染。
这里有一个必须提醒的安全点:上传接口一定要做登录校验和文件类型校验,否则别人可以往你服务器上丢任何文件。我在文件类型校验时用白名单机制,只允许jpg、png、gif、mp4这几种,并且校验文件的MIME类型而不是只靠文件名后缀。
4. 常见问题与排查技巧实录:从开发调试到部署上线的避坑指南
这个章节是我最想写的内容,因为相同的问题我眼睁睁看着好几个人来回踩。有些坑其实只要知道解决方案,30秒就能解决,不知道的时候能卡一整天。
4.1 后端启动失败与接口调不通的经典场景
问题一:项目启动直接报错,提示无法连接数据库。
排查思路:先确认MySQL有没有启动,账号密码对不对,然后看yml里的URL,localhost和127.0.0.1有时候会因为MySQL的认证插件问题连不上。解决方法是把URL改成127.0.0.1,或者在MySQL里配置user允许指定host访问。最近碰到比较多的是MySQL 8.0以上版本用的caching_sha2_password认证,老版本驱动可能不支持,升级mysql-connector-java到8.0+即可。
问题二:前端请求接口返回404。
这个多半不是真的没有接口,而是SpringBoot的context-path配置不对。如果你在yml里设置了server.servlet.context-path: /api,那所有接口路径都要以/api开头,前端路径如果没加上就会404。前端BASE_URL里的域名不要加上/api,而在具体接口路径里统一加上,才不会乱了套。
问题三:请求跨域,控制台报CORS error。
跨域说到底是后端没配跨域过滤器。这里有一个真正的坑:如果你用了Spring Security或者拦截器,跨域配置可能会被拦截器挡在前面导致不生效。解决办法是既配置CorsFilter,又要确保拦截器不拦截OPTIONS预检请求。我在项目中习惯直接实现一个CorsFilter交给Spring管理,同时在拦截器里放行所有OPTIONS方法。
4.2 小程序端白屏、加载失败、无法显示图片
小程序白屏,最常见的原因有三个。
第一个是app.json里注册的页面路径写错了,小程序启动时找不到首页,就白屏。这个错误控制台其实有报错,但很多人不看控制台,光顾着刷新页面了。
第二个是基础库版本太低。有些新API在低版本基础库上不支持,比如wx.getUserProfile要求基础库2.10.4以上。解决方法是检查app.json里的"libVersion"配置,或者在"详情-本地设置"里选一个较高版本的基础库。注意,真机调试和模拟器的表现可能有差异,真机上尤其注意基础库版本。
第三个是接口请求失败导致页面数据没渲染出来。这个要后端配合,前端必须把接口调用封装到统一请求模块里,在fail回调里至少弹一个toast提示“网络异常”,不能什么都不做让用户感觉像白屏了。
图片显示不出来,大都是域名没配置到微信公众平台的downloadFile合法域名里,或者图片URL是http不是https。小程序规定所有网络请求和图片资源都必须是HTTPS协议(开发工具可以勾选不校验),上线前要把资源都放到HTTPS环境下。
4.3 微信支付的坑:没想清楚就先别接
和小程序关联的高频词里“小程序微信支付v3对接”出现频率特别高,而此类项目的实践里“由于小程序违规,支付功能暂时无法使用”这类情况也并非个例。这里我把话说透:个人开发者在微信支付这条路上遇到的问题往往是资质与类目审核范围问题,前后需要企业主体/个体工商户主体、商户号申请、开通对应支付权限、平台审核等多个环节,任何一个环节卡住,支付就走不通。
所以我的建议是:毕设项目里先不要做真实支付,可以把支付模块设计为“线下支付+订单状态确认”模式。具体是,发布需求时报酬用积分或“面付”表示,接单方完成后点击“确认完成”,发布方点击“确认并付款(线下)”,订单就走到已完成状态。如果你的课题要求有支付模块,那你最多做到微信支付V3接口代码层面打通,通过测试商户号模拟下单,并在论文里说明“实际部署需商家资质”,这样既符合实践,又不会被支付资质问题卡死。
如果非要对接V3,重点提醒几个高频错误:
- 商户证书路径加载要用绝对路径或classpath,测试和正式环境路径要区分
- 支付回调的签名验证必须做,不能直接信任回调内容
- 回调接口返回给微信的响应格式要求是
{"code":"SUCCESS","message":"成功"},返回其他格式微信会一直重试 - 金额单位是分,不是元,1元要传100
4.4 服务器部署:域名、HTTPS与备案
小程序上线调用接口要求HTTPS,意味着你需要一个备案过的域名和SSL证书。学生党可以买一台轻量级服务器,注册一个域名,备案流程可能需要一两周,所以这个事要提前弄,别等小程序代码写完了才想起来。
部署方式建议用Docker,把SpringBoot项目打成jar包,写一个Dockerfile,然后配合docker-compose一键启动MySQL和jar包。记得在服务器安全组放行80端口、443端口和3306端口(3306只对内网开放)。Nginx做反向代理和SSL终止:
server { listen 443 ssl; server_name yourdomain.com; ssl_certificate /etc/nginx/ssl/yourdomain.pem; ssl_certificate_key /etc/nginx/ssl/yourdomain.key; location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }有个我踩过的坑:SpringBoot应用启动后监听的是8080端口,小程序端发起请求时带了/api前缀,Nginx转发到后端时要去掉这个前缀。如果配置不当,后端会报404。
另外,微信公众平台要把服务器域名配置到request合法域名里面,开发环境可以在开发者工具右上角“详情-本地设置-不校验合法域名”,但真机预览和上线必须配置合法域名,不然请求直接拦截。
4.5 文档撰写与答辩准备的几个策略
毕设文档是很多人的最后一道坎。有的项目代码写得挺好,但文档一塌糊涂,答辩被问到细节时支支吾吾,分数直接打七折。
写文档的思路我建议反过来:先画系统架构图和流程图,再写文字。用Draw.io或者ProcessOn把整体架构图、业务流程图、时序图、ER图画好,这些图放在文档里直接拉升文档的专业度。文字部分不要大段抄代码,而是写清楚“为什么这么设计”——为什么用JWT而不是Session,为什么用乐观锁而不是悲观锁,为什么分表分字段要这么设计。导师看重的不是你把代码贴上去,而是你的思考过程。
答辩演示的时候,建议准备一份“演示脚本”,分三步走:
- 先一句话说清楚平台是干什么的,解决什么痛点
- 按用户链路演示:登录 → 发布需求 → 切换账号接单 → 完成订单 → 后台看到订单数据变化
- 展示1-2个技术亮点,比如乐观锁处理并发接单、自定义异常全局处理、敏感信息加密配置
这里有个细节:演示时提前把小程序开发工具的网络面板打开,接口返回的JSON可以直接展示给评委看,证明这个接口是真的通了,而不是前端Mock的数据。这一招非常加分。
5. 项目扩展方向与个人实践心得
主流程做完了,如果还有精力,或者你希望论文的内容更丰满、答辩时更有底气,下面是几个既有实操价值又不会被质疑“工作量不够”的扩展方向。
5.1 低成本高价值的扩展功能
第一个是消息通知模块。订单状态从WAITING到ACCEPTED、从ACCEPTED到FINISHED,用户需要感知。微信订阅消息是一次性订阅,每次用户操作时弹窗询问是否允许通知,授权后后端可以通过接口推送一条模板消息。这块代码量不大,但论文里能写一整个章节,而且答辩演示效果很好——你发布需求,另一个账号接单,发布方手机上立刻收到一条微信服务通知。
第二个是信用评分体系。每个用户有初始信用分,接单后不履行职责、恶意取消、被投诉等会扣分,顺利完成任务加分。信用分的高低可以影响接单优先级或者发布需求时需要缴纳的虚拟保证金。这个扩展完全是纯后端逻辑,不动小程序端核心代码,工作量可控,但讲出来就比“普通CRUD”上了一个档次。
第三个是管理员数据看板。用ECharts做折线图展示每天的新增订单量,饼图展示分类下单量占比,柱状图展示用户活跃度。虽然是简单聚合查询,但视觉效果很专业,放在系统管理端首页非常提气。
第四个是基于关键词的智能推荐。这个听着高大上,实现起来也不复杂——用MySQL的全文索引或者简单分词匹配,把用户的历史求助/接单记录出现过的关键词提取出来,当新需求发布时优先推荐给可能感兴趣的用户。如果配合HanLP这类分词工具,还能在论文里写“引入自然语言处理技术优化检索效果”,这个技术点非常出彩。
5.2 我做这个项目时踩过的坑和总结的经验
最后说几个纯个人经验,不是什么大道理,但都是真金白银换来的。
第一,开发时一定要用Git做版本管理,每次完成一个功能点就commit一次。这个项目我前前后后改了十几轮,如果没有版本管理,中间想回退一个接口的设计就痛苦万分。哪怕只有一个本地仓库,也比没有强。
第二,接口文档不一定要用Swagger,但至少要在代码里写清楚注释,或者维护一份简单的Markdown接口说明。特别是字段含义和状态码,过了一个月你自己回来看都不一定记得当时设计的意图,更别说导师和后续维护者了。
第三,别在还没跑通主链路的时候去调UI。很多同学喜欢先做前端页面,把界面调得非常漂亮,但接口一个都没对接。我的习惯是后端接口先写完,用Apifox测通,再开始写页面,写页面时每个接口直接对接真实数据,不造假数据,这样开发过程中暴露的问题最多,解决完项目也就稳了。
第四,遇到报错先读英文原版报错信息,不要直接复制去百度。SpringBoot的报错信息虽然长,但核心原因往往就在前几行,比如ClassNotFoundException、Port 8080 was already in use.这些一眼就知道是缺依赖或端口占用。培养这个习惯,你的排查效率会翻倍。
第五,也是我个人最有体会的一点:代码可以写得不完美,但逻辑流程一定要自洽。答辩的时候,评审问“为什么你这里这么设计”,比的不是谁的方案最优,而是谁更能说清楚自己的设计理由。只要你每个关键决定都是思考过的,哪怕导师不认可这个方案,他也会认可你的思考过程和表达能力。
如果你正卡在某个报错上,或者不确定自己模块划分得对不对,按这篇文章的顺序重新梳理一遍:先把主链路涉设计理清楚,再逐层实现接口,最后做联调和加固。这套项目本身不算复杂,静下心来做,两周时间足够跑通全流程。最重要的是,做完之后你能把每一步都讲清楚,那这个毕设就是真正属于你自己的作品。