做校园闲置物品交易系统这个选题,算是Java Web毕业设计里非常经典的一条赛道了。标题里“SpringBoot+Vue”这个组合一亮出来,基本就锁定了前后端分离架构,再加上“完整项目源码+SQL脚本+接口文档”这几个关键词,说明这不是一个只停留在理论层面的PPT项目,而是能真正跑起来、能演示、能答辩的完整工程。我带过不少学生做类似的项目,也帮人排查过无数个跑不起来的问题,今天这篇就把这类项目从标题到落地好好拆一遍,把该讲的原理、该避的坑、该抄的作业都写清楚。
先说结论:如果你正在选毕业设计题目,或者已经选了校园闲置物品交易系统但还不知道从哪下手,这篇文章就是给你准备的。你不需要是技术大佬,只要会用IDEA、懂一点Java基础和Vue基础,跟着这篇文章的思路走,能把项目跑起来、能讲清楚核心模块、能应对答辩追问,就足够了。
1. 项目整体拆解:从标题看门道
1.1 核心需求解析:这个系统到底要解决什么问题
校园闲置物品交易系统的本质,是给在校学生提供一个“二手物品流转”的平台。你仔细想想,大学校园里有多少东西是用完就闲置的——大四学长学姐的考研资料、自行车、小风扇,新生入学要买一堆东西,老生毕业要扔一堆东西,供需匹配天然存在,只是缺一个靠谱的渠道。
QQ群和微信群的问题是信息太杂、没有商品结构化展示,朋友圈发卖货信息又容易被刷屏淹没。这个系统要解决的核心痛点就是三个:信息结构化展示、交易流程可管理、用户身份可识别。所以业务模块基本绕不开这几块:用户注册登录、商品发布与管理、商品分类浏览与搜索、站内留言/私信、订单意向或交易记录、个人中心。
这里有个很多同学容易忽略的点:毕设项目不是越复杂越好,而是越“完整自洽”越好。你用SpringBoot+Vue做一个功能闭环的闲置交易平台,比硬塞一堆微服务、消息队列、分布式事务要靠谱得多。评委看的是你对业务的理解、对技术栈的掌握、对工程化流程的熟悉度,不是看你会不会堆技术名词。
1.2 技术选型思路:为什么是SpringBoot+Vue这对组合
SpringBoot+Vue在Java Web毕设里近乎统治级地位,不是没有道理的。先看后端,SpringBoot把Spring家族那一堆繁琐的XML配置全干掉了,内嵌Tomcat,打成一个jar包就能跑,这对学生党来说太友好了。你再也不用纠结“为什么我配的web.xml不生效”“为什么Tomcat又报404”,起步门槛直接砍半。
再看前端,Vue的双向数据绑定和组件化开发,让页面交互逻辑写起来像搭积木。你要做一个商品卡片列表,写一个ProductCard.vue组件,循环渲染就行。数据一变页面自动更新,不需要像原生JS那样手动操作DOM。
前后端分离架构还有一个隐藏好处:接口文档变成必需品。你后端写了/api/product/list,前端怎么知道返回什么字段?这时候Swagger或者接口文档就派上用场了。这也是为什么标题里专门提到“接口文档”——它是前后端协作的契约,也是答辩时展示工程规范化的亮点。
1.3 项目目录结构:拿到源码后先看什么
一个规范的SpringBoot+Vue项目,拿到手先别急着点运行,先看目录结构。前端一般是这样的:
frontend/ ├── public/ ├── src/ │ ├── api/ # 封装axios请求 │ ├── assets/ # 静态资源 │ ├── components/ # 公共组件 │ ├── router/ # 路由配置 │ ├── store/ # 状态管理(Vuex/Pinia) │ ├── views/ # 页面组件 │ ├── App.vue │ └── main.js ├── package.json └── vue.config.js后端一般是这样的:
backend/ ├── src/main/java/com/example/campus/ │ ├── controller/ # 接口层 │ ├── service/ # 业务逻辑层 │ ├── mapper/ # 数据访问层 │ ├── entity/ # 实体类 │ ├── config/ # 配置类(跨域、拦截器等) │ ├── common/ # 公共返回类、异常处理 │ └── utils/ # 工具类 ├── src/main/resources/ │ ├── mapper/ # MyBatis XML文件 │ ├── application.yml │ └── sql/ # 数据库脚本 └── pom.xml这种分层结构的核心逻辑是单向依赖:Controller调Service,Service调Mapper,Entity在各层之间传递。你要是自己写项目,也务必保持这个结构,别图省事把SQL直接写在Controller里,答辩老师一眼就能看出工程素养。
2. 核心细节解析与实操要点
2.1 数据库设计:一张表都不能瞎建
SQL脚本是这个项目的灵魂。很多同学以为数据库就是建几张表,其实设计的核心在字段关系和约束。校园闲置物品交易系统一般至少需要这几张表:
| 表名 | 主要字段 | 说明 |
|---|---|---|
| user | id, username, password, nickname, avatar, phone, create_time | 用户表,密码建议用MD5或BCrypt加密 |
| category | id, name, sort | 商品分类表,如数码、书籍、生活用品 |
| product | id, user_id, category_id, title, description, price, images, status, create_time | 商品表,status用于标记在售/已售/下架 |
| order | id, product_id, buyer_id, seller_id, price, status, create_time | 交易订单表,记录买卖双方 |
| message | id, send_user_id, receive_user_id, content, create_time | 站内留言/私信表 |
| collect | id, user_id, product_id, create_time | 收藏表 |
这里有一个关键设计经验:商品表不要直接存分类名称,而是存category_id。这样做的好处是分类改名不用改商品数据,而且可以用JOIN查询把分类名带出来。同理,用户头像、商品图片不要存Base64字符串进数据库,存文件路径或URL就好。
外键约束在毕设项目里建议适可而止。我的实际经验是:逻辑外键(Java代码里关联查询)比物理外键(数据库级约束)更灵活。如果商品被删除时用户还想保留订单记录,物理外键的级联删除就会变成干扰。
2.2 接口文档:不只是给前端看的,更是答辩加分项
标题里单独把“接口文档”拎出来,说明这不是一个可有可无的附赠品。用SpringDoc或者Swagger生成接口文档是基础操作,我更推荐在项目里这样组织接口:
POST /api/user/login:登录,入参{username, password},返回token和用户信息POST /api/user/register:注册,入参{username, password, nickname}GET /api/product/list?pageNum=1&pageSize=10&keyword=自行车:分页查询商品GET /api/product/detail/{id}:商品详情POST /api/product/add:发布商品,入参含商品信息和图片URLPUT /api/product/update:修改商品DELETE /api/product/{id}:删除商品POST /api/order/create:创建订单
每个接口都要明确写清楚请求方式、请求参数、返回数据结构。我在带学生过程中发现,接口路径的命名规范能显著降低前后端联调时的沟通成本。比如用复数名词表示资源(/products),用HTTP动词表达操作意图(GET查询、POST创建、PUT更新、DELETE删除),这就是RESTful风格的核心思想,讲出来很加分。
2.3 文件上传:图片到底存哪里
闲置物品交易当然少不了商品图片。最简单的方案是上传到本地目录,然后通过一个/api/files/**的映射对外提供访问。比如在application.yml里配置:
file: upload-path: D:/campus/upload/后端接收上传后把文件写到这个目录,再把http://localhost:8080/api/files/xxx.jpg这个路径存到数据库。这个方案的问题在于:重启服务器时临时文件可能被清理,而且生产环境不能把文件放在应用目录里。但如果只是毕设演示,本地映射完全够用。
如果想加点亮点,可以引入MinIO做对象存储。MinIO是开源的对象存储服务,兼容S3协议,你只需在服务器上跑一个MinIO实例,然后在SpringBoot里集成SDK就能上传下载。答辩时讲一句“我用了独立的对象存储服务,把静态资源和业务逻辑解耦”,效果直接拉满。热搜词里也有minio加入到springboot,说明这也是当前毕设圈的热门操作。
2.4 鉴权方案:JWT还是Session
校园闲置物品交易系统需要登录后才能发布商品、下单、留言,这就涉及用户鉴权。老项目喜欢用Session,但前后端分离架构下Session有天然的痛点:前端和后端不同端口,跨域请求时Cookie维护麻烦,而且Session是存服务器内存的,不好横向扩展。
我建议用JWT(JSON Web Token),思路很简单:用户登录成功后,后端生成一个带签名和过期时间的token返回给前端;前端每次请求都把这个token放在请求头Authorization里;后端通过拦截器验证token合法性和有效期,再从token里解析出userId。
在SpringBoot里写一个拦截器或者Spring MVC的HandlerInterceptor,核心逻辑就是:
String token = request.getHeader("Authorization"); if (StringUtils.isBlank(token) || !jwtUtil.verify(token)) { response.setStatus(401); return false; }这里的JWT不需要引入太复杂的依赖,jjwt这个库就够用了。要注意JWT密钥不要写死在代码里,放到application.yml配置中,答辩时说明这是配置化管理,体现工程意识。
3. 实操过程与核心环节实现
3.1 环境准备:先把这些装好,后面的路才顺
做这个项目之前,环境一定要统一,否则后面每一个问题都可能成为卡点。我的推荐版本组合是:
| 软件 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8 或 11 | SpringBoot 2.x用JDK8,SpringBoot 3.x用JDK17+ |
| Maven | 3.8+ | 依赖管理和项目构建 |
| IDEA | 2022+ | 开发后端,自带Maven插件 |
| Node.js | 16/18 | 运行Vue项目,npm包管理 |
| MySQL | 5.7 或 8.0 | 数据库,注意8.0的驱动和密码加密方式不同 |
| Navicat | 任意版本 | 可视化导入SQL脚本 |
这里要特别提醒一句:热搜词里有“springboot版本太高”这个说法,不是空穴来风。SpringBoot 3.x把很多旧版本的用法改了,比如javax.servlet变成了jakarta.servlet,MyBatis-Plus的对应starter也要换。如果你是从网上下载的源码,大概率是SpringBoot 2.x写的,你最好就装JDK8和Maven 3.6+,别一上来就装JDK21,否则报错报到你怀疑人生。
3.2 数据库导入:SQL脚本的正确打开方式
拿到SQL脚本之后,第一步不是双击运行,而是先检查脚本的前几行。规范的项目一般会包含建库语句:
CREATE DATABASE IF NOT EXISTS campus_trading DEFAULT CHARACTER SET utf8mb4; USE campus_trading;utf8mb4这个字符集很重要,它比utf8多支持一些特殊字符(比如emoji),而且能更完整地存储中文。在Navicat里执行脚本的正确顺序是:先创建一个连接,右键“运行SQL文件”,选择脚本路径,等待执行完成。执行完之后建议刷新一下表列表,确认表都建出来了,再随便SELECT一条数据看看。
我遇到过很多次的情况是:SQL脚本里带了中文注释,但文件是GBK编码的,跑出来全是乱码。解决方案是用记事本或VS Code把文件另存为UTF-8编码后再执行,或者在执行时选择正确的字符集。这种小问题看似不起眼,但真卡住你半个钟头的时候就知道痛苦了。
另外,脚本里如果带了预置数据(admin用户、分类数据),那是最好的。我建议你自己再补两条测试数据,比如发一两个测试商品,这样演示起来画面更丰满。
3.3 后端启动:从Maven到SpringBoot成功跑起来的全套流程
打开后端项目后,IDEA会提示你Import Maven项目,选择信任并等待依赖下载。这里有个非常影响心情的问题:Maven默认仓库在国外,下载速度可能慢到让人抓狂。解决办法是在.m2/settings.xml里配置阿里云镜像。
<mirror> <id>aliyunmaven</id> <mirrorOf>central</mirrorOf> <name>阿里云公共仓库</name> <url>https://maven.aliyun.com/repository/public</url> </mirror>配完镜像再重新导入,速度会有质的飞跃。依赖下载完成后,找到src/main/java下带@SpringBootApplication注解的启动类,右键Run。看到类似这样的日志就说明启动成功:
Tomcat started on port(s): 8080 (http) with context path '' Started CampusTradingApplication in 5.432 seconds如果端口被占了,最简单的解决办法是在application.yml里改端口:
server: port: 9090改完端口之后前后端联调时注意,前端所有请求的baseURL也要跟着改。热搜词里有“idea 2026 怎么配置springboot服务 编辑配置数据 比如启动端口”,其实原理都一样,就是在application.yml里配置端口,或者在IDEA的运行配置里加--server.port=9090的VM参数。
3.4 前端启动:npm安装依赖的崩溃现场与抢救方案
Vue项目跑起来的步骤是:进入frontend目录,先执行npm install安装依赖,再执行npm run serve启动开发服务器。看起来简单,但npm install可以说是整个项目里最容易出问题的一步。
最常见的错误是node-sass安装失败,报错信息一大串,核心是Python和Visual C++ Build Tools缺失。现在多数Vue项目已经用sass替代node-sass了,如果你遇到的是老项目的node-sass,建议在package.json里把node-sass换成sass,然后删掉node_modules重新npm install。实测下来这个方案成功率极高。
还有一个问题是版本冲突。Vue 3的项目如果用了vue-router@4,那么入口文件里注册路由的方式和Vue 2完全不同:
// Vue 3版本 import { createRouter, createWebHistory } from 'vue-router' const router = createRouter({ history: createWebHistory(), routes }) app.use(router)如果你下载的是Vue 2项目,用的却是vue-router@4,控制台会直接报警告甚至白屏。遇到这种问题,建议先把package.json里的依赖版本截图看看,或者直接查项目的README说明,能少走很多弯路。
启动成功后,Vue会在终端打印出访问地址,通常是http://localhost:8081/。前端8081、后端8080,正好错开,但依然存在跨域问题,下一节就讲这个。
3.5 前后端联调:跨域问题与代理配置
前后端分离架构里,跨域是绕不开的一关。前端在8081端口,后端在8080端口,浏览器会认为它们是两个不同的源,直接请求会被CORS策略拦住。解决方案有两种,我建议采用Vue CLI的代理配置,它在前端层就能解决大部分问题。
在vue.config.js中:
module.exports = { devServer: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } }这样前端发/api/product/list的时候,开发服务器会帮它转发到http://localhost:8080/api/product/list,前端代码里根本不需要写完整的后端地址,统一用相对路径/api开头就行。这个方案的好处是:代码里没有硬编码的服务器地址,以后部署只需要改代理配置。
另一个方案是在后端加全局CORS配置:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("*") .allowedHeaders("*"); } }两个方案可以同时用,但我个人建议把重点放在前端的代理配置上,因为以后部署到线上,Nginx本身也是一个反向代理,你提前习惯“代理”这套思路,适应起来更快。
3.6 核心业务实现:发布商品这个功能怎么完整落地
我以发布商品为例,把从点击到入库的整个链路走一遍。前端页面是一个表单,包含商品标题、分类、描述、价格、图片。提交时,前端先调用上传接口拿到图片URL,再连同表单数据一起传给发布接口。
后端ProductController里有一个add接口:
@PostMapping("/add") public Result add(@RequestBody Product product) { product.setUserId(currentUserId()); product.setStatus(0); // 0表示在售 product.setCreateTime(new Date()); productService.insert(product); return Result.success(); }这里的currentUserId()从哪里来?就是之前说的JWT拦截器,在请求处理之前解析token,把userId放在ThreadLocal或请求属性中。这个做法有两个好处:一是前端不用每次手动传userId,二是后端能防止恶意用户提交别人的userId。
商品发布后,首页商品列表默认只展示status=0的商品,也就是说已下架或已售出的商品不会出现在列表里。这是一个非常细节但很重要的业务逻辑,很多新手会忽略,结果刚发布完的商品和已卖出的商品混在一起。
查询列表时还涉及分页和搜索。搜索走的是SQL动态拼接,在Mapper的XML里写:
<select id="searchProducts" resultType="com.example.entity.Product"> SELECT * FROM product <where> <if test="keyword != null and keyword != ''"> AND (title LIKE CONCAT('%', #{keyword}, '%') OR description LIKE CONCAT('%', #{keyword}, '%')) </if> <if test="categoryId != null"> AND category_id = #{categoryId} </if> AND status = 0 </where> ORDER BY create_time DESC </select>这种写法比MyBatis-Plus的QueryWrapper稍微复杂一点,但能清楚展示你对SQL的掌握程度。如果你把这一段讲清楚了,答辩时关于“搜索功能怎么实现”的追问基本就稳了。
4. 常见问题与排查技巧实录
4.1 SQL脚本导入失败:乱码、语法错误和未知列
SQL脚本导入失败的原因排行榜:第一名是乱码,第二名是MySQL版本不兼容,第三名是重复执行。
乱码问题刚才提过了,重新保存为UTF-8就能解决。MySQL版本不兼容的表现通常是unknown column或者default value语法不对,比如MySQL 8.0里时间字段可以直接用DEFAULT CURRENT_TIMESTAMP,但MySQL 5.5就部分支持。我的建议是:拿到脚本先看创建时间,如果是老脚本,手动在Navicat里建表和字段,比死磕脚本快得多。
还有一个小坑:重复执行SQL脚本时,建表语句会因为表已存在而报错。规范的项目会在脚本里加DROP TABLE IF EXISTS,如果没有,你自己在前面手动执行这个清理语句即可。
4.2 npm install成功但npm run serve报错:模块找不到
有时候npm install很顺利,但npm run serve一跑就报Module not found: Can't resolve 'xxx'。大部分原因是依赖没有完全安装,或者某个依赖的版本不兼容。
我的排查顺序是:先删掉node_modules和package-lock.json,再执行npm cache clean --force,最后重新npm install。如果还不行,就把报错的那个包单独安装一次:
npm install xxx --save-dev如果项目是从网盘下载的,压缩包里可能带着node_modules目录,建议直接删掉重新安装一遍,因为不同操作系统的原生依赖可能不兼容。
4.3 后端启动报错:数据库连接失败或驱动类找不到
SpringBoot启动时报Failed to configure a DataSource,十有八九是你没有配置数据库连接信息,或者配置里的账号密码不对。打开application.yml确认:
spring: datasource: url: jdbc:mysql://localhost:3306/campus_trading?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver这里最容易踩坑的是serverTimezone参数。MySQL 8.0默认时区是UTC,如果不设置serverTimezone=Asia/Shanghai,可能会差8个小时。另外driver-class-name在MySQL 8.0要用com.mysql.cj.jdbc.Driver,老版的com.mysql.jdbc.Driver会报驱动类找不到。
4.4 前端请求打不通:从Postman到浏览器的三重定位法
如果页面数据加载不出来,不要坐在那猜,用递进式排查:先在浏览器按F12打开Network面板,看请求状态码。
- 如果请求根本没发出,看前端代码里的
baseURL或代理配置 - 如果请求发出但报
404,看后端接口路径和前端请求路径是否一致,重点检查有没有少/api前缀 - 如果请求发出但报
401或403,看是否携带了token、token是否过期
这时候再用Postman直接打后端接口,如果Postman能通而浏览器不通,基本就是跨域或鉴权问题。大原则是先确认后端接口没问题,再排查前端,别在前端代码里改来改去然后发现后端压根没启动。
4.5 图片上传后访问404:静态资源映射没配置
如果你上传图片成功,数据库里也存了路径,但浏览器访问图片地址报404,那几乎可以肯定是SpringBoot没有把上传目录映射成静态资源。需要在配置类或配置文件中加映射:
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/api/files/**") .addResourceLocations("file:D:/campus/upload/"); }注意file:后面必须是绝对路径,结尾要带/。我这里用的是D:/campus/upload/,Win系统里反斜杠和正斜杠的混用在Linux部署时会出现问题,建议代码里统一用正斜杠。
4.6 热门坑位总结:一个表带你避雷
| 症状 | 根因 | 快速解法 |
|---|---|---|
| 前端白屏且控制台报错 | Vue版本与依赖不兼容 | 核对package.json版本,Vue3配vue-router@4 |
请求报Network Error | 后端没启动或代理配错 | 先访问http://localhost:8080/api确认后端通不通 |
| 登录后刷新就失效 | token存到了内存中 | 改用localStorage或cookie持久化存储 |
| 重启后上传图片丢失 | 上传目录是临时目录 | 配置固定的本地路径或对象存储 |
| 数据库中文乱码 | 字符集不一致 | 表结构、连接串统一使用utf8mb4 |
启动时Port already in use | 端口被占用 | netstat -ano查PID,结束进程或改端口 |
| Maven依赖变红 | 本地仓库缺包或镜像太慢 | 配置阿里云镜像,右键Maven Reimport |
5. 项目扩展与答辩要点:让毕设从做完到讲好
5.1 功能扩展:在毕设基础上加什么最加分
如果时间充裕,我建议在基础功能上加一到两个有亮点但不难实现的扩展。比如:
- WebSocket站内聊天:买卖双方在商品详情页直接在线沟通,使用SpringBoot的
WebSocket加上前端的SockJS就能实现。这个功能解决了核心痛点(用户需要沟通价格、约见面时间),演示起来很生动。 - Announcement轮播图:首页加一个公告位或轮播图,技术上是简单的列表查询+图片展示,但能给评委留下“你考虑了运营场景”的印象。
- 数据可视化:管理后台加一个统计页面,展示发布量、交易量的趋势图。用ECharts就能搞定,前端加依赖就行,后端需要写几个统计查询的接口。
- 管理员审核:商品发布后默认为待审核状态,管理员可以上架和下架商品。这正好利用了
product.status字段,只需要加一个后台管理模块。
选扩展时记住一个原则:这个功能要能在1分钟内演示且容易讲清楚,不要贪多。你加一个WebSocket聊天,答辩时打开两个浏览器窗口互发消息,这种演示的效果比你说十分钟架构设计都强。
5.2 答辩高频问题与应答思路
毕设答辩时,评委通常不会问太偏的技术,但特别喜欢问“为什么”。我整理了几个高频问题及应答方向:
问:为什么选择SpringBoot+Vue这种架构?
答:SpringBoot简化了后端开发流程,内嵌Tomcat、自动配置;Vue组件化开发提高前端代码复用率。前后端分离让分工更清晰、部署更灵活。同时我用了RESTful API和接口文档,方便前后端并行开发。
问:用户密码安全怎么处理?
答:我使用的是加盐哈希存储,也就是用BCryptPasswordEncoder对密码进行哈希处理再入库,数据库里不存明文密码,有效防止拖库后密码泄露。
问:商品搜索功能底层是怎么实现的?
答:用MyBatis动态SQL实现。根据用户是否传入关键词、分类ID,动态拼接WHERE条件,LIKE模糊查询,配合分页插件返回结果。这个方案在数据量不大时性能足够,且实现简单、可读性强。
问:如果数据量大了,这个系统哪里会成为瓶颈?
答:第一是商品图片的存储和访问,所以我用了独立的静态资源映射方案,以后可以平滑迁移到OSS或者MinIO;第二是搜索性能,随着数据量增长,LIKE查询索引会失效,可以引入ElasticSearch或者全文索引来优化;第三是接口缓存,可以用Redis缓存热门的商品列表,减少数据库压力。
这些问题不用答得面面俱到,关键是向评委展示你对系统的每一块都思考过,哪怕是不完美的方案,也比“我不知道”强一百倍。
5.3 部署上线:不让项目只活在localhost里
很多同学做完项目就放那了,但它还能做得更多。至少可以把前后端分别打包:后端用Maven的package命令打成jar,前端用npm run build生成dist目录,再用Nginx托管dist并把/api反向代理到jar的端口。
一个最简单的Nginx配置示例:
server { listen 80; server_name localhost; location / { root /home/campus/dist; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://localhost:8080; } }部署上线涉及的知识其实不多,但非常能体现工程能力。如果你能在答辩现场直接打开一个公网地址,说“这个是已经部署好的测试环境”,这种说服力比任何PPT都强。不想买服务器就用内网穿透,本地起一个服务,映射出去给评委展示也是可以的。
5.4 文档整理:README是别人认识你项目的第一窗口
最后说说项目文档。我见过太多源码包,里面塞了一堆文件,但没有一个README,下载的人根本不知道怎么跑起来。我建议你花两个小时写一份严谨的README,至少包含:
- 项目简介和功能清单
- 环境要求(JDK版本、MySQL版本、Node版本)
- 快速启动步骤(建库 -> 导入SQL -> 启动后端 -> 启动前端)
- 默认账号密码
- 常见问题FAQ
这份README不仅是给评委看的,也是给你自己未来回看项目时省力的。说实话,很多学生毕业半年后再翻自己的毕设,看着那一堆文件都能发半天呆,有一份好README就能少受这个罪。
我自己的习惯是:每写完一个模块,就顺手更新README和接口文档,别攒到最后一起写。写代码时的思路还热乎,记录的效率和质量都是最高的。等到答辩前,再对照文档快速过一遍核心功能,你就能把项目讲得又顺又深。这也是为什么这类完整项目源码通常会把SQL脚本、接口文档单独拎出来——这三个东西放在一起,才是真正能落地、能传承、能过审的一份完整交付物。
最后再分享一个小技巧:把“上传图片后通过静态URL访问”这个链路从头到尾亲手敲一遍,再把“发布商品后前端列表立即出现”这段体验调试到顺手,你就能感受到前后端分离开发真正舒服的地方。我做这类项目最大的体会是,毕设最大的价值从来不是那一张文凭,而是你亲手把一个想法变成能跑起来的系统时积累的那点感觉。这种感觉,只有真写过一遍的人才有。