☰
SpringBoot+Vue美食烹饪互动平台:全栈实战与答辩指南
2026/10/17 8:44:19 网站建设 项目流程

做毕设选型的时候,我见过太多人一上来就扎进"管理系统增删改查"的老套路,结果答辩时老师随便问一句"你的项目解决了什么真实问题",就卡住了。相比之下,SpringBoot+Vue做美食烹饪互动平台这个方向,天然自带内容属性、互动属性和可视化效果,属于那种"一眼就能看出工作量、细问也有技术点可以讲"的选题。这也是为什么我拿到这套完整源码加上SQL脚本和接口文档的项目时,第一反应是先替你拆一遍:它到底覆盖了哪些真实开发场景,哪些地方是答辩高光点,哪些坑是必须提前排掉的。

这篇文章我就从项目整体设计、数据库脚本、后端接口、前端页面、联调部署五个维度,把这个美食烹饪互动平台掰开揉碎地讲一遍。不管是正准备拿它当毕设框架,还是想照着它学会一套完整的前后端分离项目的写法,都可以顺着这篇文章把整个项目跑通、吃透。

1. 这套美食互动源码到底解决什么问题

先聊选题。SpringBoot+Vue这个组合本身不算稀奇,但"烹饪互动平台"这四个字决定了它和普通信息管理系统有本质区别——它不只是一个展示数据的壳,还有用户发布菜谱、收藏点赞、评论交流这一整套UGC闭环。毕设里最怕的就是"做得出来但说不清楚",而这个项目天然有一条完整的故事线:用户注册登录,浏览分类菜谱,点进详情看步骤,收藏下来以后做,自己做好的菜再发布上去,别人可以点赞评论。

架构上,项目拆成了前后端分离的两个端。后端以SpringBoot为核心,提供一套RESTful接口,负责用户认证、菜谱管理、分类检索、评论收藏等业务逻辑;前端用Vue写单页应用,通过axios调用接口,路由层面做了登录拦截。数据库放在MySQL里,SQL脚本一次性建库建表插初始数据,接口文档把每个接口的入参出参罗列清楚。

对毕设来说,这套结构最大的好处是技术覆盖面够宽。后端能讲到拦截器、统一异常处理、参数校验、事务;前端能讲到组件化、路由守卫、状态管理、网络请求封装;数据库能讲到表关系设计、索引、外键策略;再加上源码、SQL脚本、接口文档三件套,开题报告、中期检查、毕业论文的素材一次性全齐了。

站在答辩的角度,这个项目还有一个隐性优势——演示效果好。菜品图片、分类筛选、详情页步骤图,视觉效果天然比纯表格的项目高一个档次。而且"美食"是评审老师熟悉的生活场景,不需要花五分钟解释业务背景,一上来就能进入技术细节。很多同学做管理系统,答辩时老师问"这样一个系统给谁用",往往答得含糊;但烹饪互动平台可以清楚地说出用户画像和使用场景,这是选题本身的红利。

不过要说清楚一件事:拿到源码只是起点,不是终点。我见过不少同学把项目跑通之后就以为完事大吉,结果答辩被问到"为什么这几个表要这么设计""这个字段为什么放这张表",一下就露馅了。源码能给你省的是编码时间,但你要把每个模块的设计理由吃透,这篇文章后面几节我会把关键的设计逻辑全部展开,你照着捋一遍,心里就有底了。

2. 从SQL脚本反推数据库设计:这些表为什么这么建

拿到压缩包先别急着启动,第一件事是打开SQL脚本看表结构。数据库设计是整套系统的地基,也是答辩时老师最爱深挖的部分。这套脚本里的表结构并不复杂,但每一张表的存在都是有道理的,我挨个说一下。

2.1 核心表与字段设计

基础表是用户表。用户表里除了常规的用户名、密码、昵称、头像、手机号之外,还带了一个角色字段,用来区分普通用户和管理员。这里有个小设计值得注意:密码字段存的是BCrypt加密后的哈希值,不是明文。答辩时可以主动提一句"密码没有明文落库,用的是BCrypt加盐哈希",这属于安全意识加分项。

然后是菜谱表。这张表是整个系统的信息中枢,字段包括菜谱标题、分类ID、封面图、简介、食材清单、步骤描述、作者ID、浏览量、点赞量、收藏量、创建时间。你在SQL脚本里会看到两个比较"重"的字段——食材清单和步骤描述,这类多值字段如果在规范设计里应该拆子表,但实际项目里很多团队为了查询效率会采用JSON字符串或者用特定分隔符拼接。这个取舍就是答辩点:你可以说"考虑到毕设体量,用冗余字段减少联表查询,如果后期数据量大可以拆成食材表和步骤表",把权衡说清楚,比闷头写代码强得多。

分类表比较简单,就是分类ID、分类名、排序号、图标地址。这里需要注意:分类表不是摆设,前端首页的分类导航、菜谱列表的分类筛选都依赖它。如果你拿到手的脚本里初始数据已经带了一批分类和数据,那演示效果会好很多,不用自己手动造数据。

2.2 互动行为的三张表:收藏、点赞、评论

互动是这个项目区别于普通管理系统的关键,对应收藏表、点赞表和评论表。

收藏表的设计要点是唯一约束。同一用户对同一菜谱只能收藏一次,所以SQL里对用户ID和菜谱ID建了联合唯一索引。评论表的字段包括评论内容、评论时间、评论人的ID、菜谱ID,如果想要支持回复功能,还会加一个parent_id字段实现楼中楼。点赞表的设计思路和收藏表类似,但要注意一点:点赞和收藏在业务上是两个动作,很多新手会图省事把两个状态合并成一个字段,比如在菜谱表里加一个"是否收藏",这在大数据量下会出问题,因为这会导致查询某用户是否收藏某个菜谱时必须先查菜谱表,而不是从用户维度查。这套脚本把收藏点赞拆成独立表,一是为了性能,二是为了后续做"我的收藏""我赞过的"这类用户中心功能时不用来回查。

从SQL脚本里你还能看到大部分表都带create_time和update_time两个时间字段。这不是凑数,更新时间和创建时间是两个不同的语义,比如管理员修改了菜谱的审核状态,创建时间不能动,但更新时间要刷新。很多同学自己建表时经常漏掉update_time,后面做数据统计或者排查问题时才发现没得查。这套脚本的时间字段设计是规范的,建议你写论文时把这几个字段单独讲讲。

索引方面,脚本里的常用查询字段基本都建了索引,比如菜谱表的分类ID、作者ID、创建时间,评论表的菜谱ID。索引不是越多越好,但如果查询频繁的字段不建索引,数据量到了几千条之后分页查询就会明显变慢,答辩时现场演示卡顿非常尴尬。建了索引之后,用EXPLAIN看一眼执行计划,这也是能拿来讲的加分细节。

2.3 数据库设计里的三个实操心得

看了这么多份SQL脚本,我觉得这套脚本里有三个做法值得你重点理解:

第一个是逻辑删除。很多表里会有一个deleted字段,默认值为0,删除操作是UPDATE而不是DELETE。这样做的目的是保留历史数据。你在答辩时可以说"为了防止用户误删数据、也为了后台能追溯操作记录,这里采用软删除方案"。但注意,如果你用了逻辑删除,所有查询SQL都要记得加上deleted=0的过滤条件,这是最容易漏的地方,后期接口查出来一堆"幽灵数据"基本都是这个原因。

第二个是冗余字段的设计思路。菜谱表里的浏览量和点赞量属于冗余统计字段,真正精确的数据应该从操作日志或点赞表里count而来。直接存一个数字字段,更新时加1,查询时直接取,好处是性能好、实现简单,坏处是数据不一致风险(比如用户取消点赞,你得记得减回去)。这个方案的取舍逻辑要能讲明白,属于典型的"以空间换时间"。

第三个是表和表之间的关联方式。外键在脚本里一般不会强加,关联逻辑放在业务代码里维护。这个做法很多人不理解——数据库不加外键不就是设计不规范吗?其实现在很多互联网项目的实践都是"应用层维护关联,数据库不加物理外键",因为物理外键在大并发下会拖慢写入性能,而且一旦外键约束出错,排查问题很麻烦。你在答辩时主动把这个观点讲出来,比背教科书上的"必须有外键"更能体现你对真实开发的理解。

3. SpringBoot后端的核心接口与关键实现

数据库设计好了,接下来看后端代码。这套项目的后端结构是标准的SpringBoot三层架构:Controller接收请求、Service处理业务逻辑、Mapper操作数据库。我建议你先从Controller层入手,把整个系统的接口列表过一遍,确认每个功能模块的入口长什么样,然后再往Service层和Mapper层深入。

3.1 用户认证这一块的实现套路

用户模块里最核心的是注册、登录和身份校验。注册接口的入参一般是用户名和密码,Service层会先查一次用户是否已存在,不存在才进行密码加密并落库。登录接口验证用户名密码后,会签发一个Token返回给前端,后续所有需要身份的请求在请求头里带上这个Token,后端通过拦截器统一校验。

Token技术选型方面,这套项目用的是JWT,因为JWT天然适合前后端分离——服务端不需要存Session,Token本身携带用户标识和过期时间,只要密钥不泄露,可以跨服务验证。实现上,拦截器会拦截未放行的请求路径,从请求头取出Token,解析验证通过后把用户信息放入请求上下文,后续Controller里直接拿当前用户。这段逻辑放在一个统一的拦截器类里,代码量不大,但是整个后端的一个关键链路。答辩讲到"登录态是怎么保持的"时,能把这个链路讲清楚,就是一个完整的技术闭环。前端拿到Token后存在本地,每次请求在拦截器里自动加在Authorization头上,后端再解析,整个就是一套标准的认证方案。

密码加密用的BCrypt,每次加密结果都不一样,普通人看到数据库里的密码也还原不出明文。这里建议不要换成MD5——MD5虽然也能用,但已经属于过时方案,没有加盐的MD5用彩虹表可以秒破。你主动在项目里使用高成本哈希算法,属于安全意识的正面展示。

3.2 菜谱与分类接口的设计逻辑

菜谱模块的接口是整个系统里最丰富的,包括菜谱列表分页查询、按分类筛选、按关键词搜索、菜谱详情、发布菜谱、更新菜谱、删除菜谱。其中最核心的是列表分页查询接口,入参一般包含pageNum、pageSize、categoryId、keyword,Service层根据这些条件组装查询语句,返回一个分页对象——既包含当前页数据列表,也包含总条数。

这里我特别提醒一点:如果菜谱有逻辑删除字段,查询列表时Service层必须默认过滤掉已删除记录。很多人调试时发现"我删掉的菜谱还在列表里"或者"列表里总条数不对",十有八九就是漏了这个过滤条件。这套项目的SQL里如果你看到WHERE deleted = 0,说明设计者考虑过这个点;如果没看到,建议你动手补上,因为删除功能要做的话,逻辑删除是底线。

菜谱详情的实现也有讲究。详情接口除了返回菜谱基本信息以外,还要带上发布者的昵称和头像、分类名、评论列表、当前用户是否已收藏已点赞。这意味着一进入详情页,前端就要并行请求多个数据源,或者后端提供一个聚合接口减少请求次数。不管哪种方式,你在讲解时都可以强调"查询接口不只是单表查询,而是涉及多表关联和逻辑组装",这能体现出你做的不是玩具项目。

发布菜谱接口需要注意两点。第一是参数校验,菜谱标题不能为空、步骤描述不能太短、分类必须存在,这些校验要么用Spring的@Valid注解,要么在Service里手动判断。第二是事务,发布菜谱时可能同时要更新用户的发布数量,两个操作要么同时成功要么同时失败,所以Service层要加@Transactional注解。你可以在答辩时特意说一句"涉及多表写入的操作都加了事务保证数据一致性",这是评委爱听的工程意识。

3.3 互动接口的幂等与并发问题

点赞、收藏、评论这三个互动接口看起来简单,实际上坑不少。拿点赞来说,前端用户连续点两次赞,后端如果只做INSERT而不加判断,就会出现一条用户对同一菜谱的多条点赞记录。接口设计时要先把"是否已点赞"查一遍,再决定是INSERT还是DELETE。这套项目的做法通常是在Service层的点赞方法里先查记录存在性,存在则取消点赞,不存在则新增点赞。同理,收藏接口也建议这样做。

并发情况也要考虑。假设同时有100个人点赞,菜谱表里的点赞数字段如果每次都是"先查旧值再加一",在高并发下可能丢失更新。更稳妥的做法是用SQL原子操作:UPDATE recipe SET like_count = like_count + 1 WHERE id = ?。这种写法在数据库层面保证了原子性,不需要额外加锁。这属于进阶优化点,你如果能把这一句讲出来,答辩的深度立刻不一样。

评论接口相对简单一些,校验评论内容不能为空,然后插入评论表,再更新菜谱表的评论数。这里的更新同样建议用原子操作。接口层面还要考虑"对不存在的菜谱评论"这种情况,需要先判断菜谱是否存在。如果评论支持回复功能,那parent_id字段就派上用场了:接口入参带parent_id说明是回复某条评论,不带就是根评论。

3.4 统一返回格式与异常处理:容易被忽略的工程细节

打开Controller代码你会发现,所有接口返回的都是一个统一的结果对象,比如Result.success(data)或Result.error(code, msg)。这个设计非常重要,前后端分离项目中,前端每个请求都要判断业务是否成功,如果每个接口的返回结构都不一样,前端写起来会非常痛苦。统一的返回结构包含三个字段:状态码、提示信息、数据体。请求成功返回200,业务失败返回业务码,系统异常返回500,前端就能根据状态码做统一处理。

配套的是全局异常处理器。Controller里不catch异常,所有异常抛到全局处理器里统一处理,处理器根据异常类型返回不同的提示信息。这样做的好处是Controller代码清爽,且不会出现"异常信息直接暴露给用户"的问题。你可以在全局处理器里专门捕获参数校验异常、业务异常、兜底的Exception,分别返回对应的错误文案。答辩时这一段可以单独讲三分钟:"如何通过统一异常处理避免接口异常信息泄漏",听起来很有工程素养。

4. Vue前端页面与后端接口的对接细节

看前端代码之前,先说一个前端项目的整体目录结构。Vue项目里通常有views目录放页面组件,router目录放路由配置,api目录放接口请求封装,utils目录放工具函数,components目录放通用组件。你把代码解压后看一眼目录,基本就能判断这个项目的前端工程化水平。

4.1 页面结构与核心交互流程

美食烹饪互动平台的页面一般包括首页、菜谱列表页、菜谱详情页、登录注册页、个人中心页、发布菜谱页。首页通常展示轮播图或者推荐菜谱,分类导航栏从分类表读取数据,每个分类点击后跳转到对应筛选条件的菜谱列表页。列表页的核心是分页展示,登录注册页用表单校验,详情页展示菜谱信息、作者信息、评论列表,支持当前用户收藏点赞。发布菜谱页是一个完整的表单页,包含标题、分类、封面图上传、食材清单、步骤描述,封面图上传是其中比较有技术含量的交互——需要调用后端的文件上传接口,把返回的图片URL再拼进表单数据里。

路由配置这块,前端需要在路由守卫里做登录拦截。简单说就是:当用户访问需要登录才能看的页面(比如个人中心、发布页),前端先检查本地有没有Token,没有就跳转到登录页并带上回跳地址。登录成功后可以跳转回原来的页面,而不是永远回到首页。这个体验细节看起来小,但对用户的完整度感知影响很大,也属于答辩时可以提的"用户思维"。

4.2 axios封装:请求拦截器和响应拦截器的用法

前端和后端对接大部分工作都集中在axios的封装上。一个合格的axios封装必须做两件事:请求拦截器自动加Token,响应拦截器统一处理业务状态码和HTTP状态码。所谓请求拦截器,就是在每个请求发出之前,从本地取出Token并加到请求头里,这样你就不用在每个方法里手动写"Token: xxx"了。响应拦截器的逻辑一般是:先判断HTTP状态码,200走正常流程;401说明登录过期,清掉本地Token并跳转登录页;业务状态码不为200时弹出错误提示。

文件上传接口特殊一点。上传文件时Content-Type要设为multipart/form-data,不能直接用普通的JSON格式。前端用FormData对象把文件塞进去,axios不用手动设置Content-Type,浏览器会自动带上boundary。后端用SpringBoot的MultipartFile接文件,存到配置好的上传目录,返回一个可访问的URL。这个流程涉及前后端的格式协商,对接不上时往往就是Content-Type没配对。

4.3 前端交互中的三个常见问题

我在看毕设前端代码时,重复出现三个问题,这套项目虽然基本规避了,但你对照自己写的时候要留意。

第一个是本地存储的Token过期处理。Token有时效,过了有效期后端会返回401或401开头的业务码。有些前端不做统一处理,只在某个接口报错时弹一个"登录过期"的提示,用户点掉之后还在当前页面继续操作,后面每次请求都会再次报错,体验非常割裂。正确的做法是在响应拦截器里判断到登录失效,清空登录信息、跳转登录页、提示用户重新登录,一个动作闭环完成。

第二个是列表页和详情页的参数传递。跳转详情页时,常见的做法是路由里带一个菜谱ID,详情页拿到ID后再请求后端接口。有些前端新手会把整个菜谱对象传过去,这样详情页虽然瞬间有数据了,但刷新页面后对象丢失,页面就白屏了。正确的做法是只传ID,进详情页通过ID拉取最新数据——这样不仅刷新不丢,还能保证数据是最新的。

第三个是发布表单的图片预览。用户选择封面图后应该立即在前端预览,不能选完图片后一点反应都没有。实现方式是用FileReader把图片读成base64,赋值给img标签的src。这个小交互能明显提升"项目完成度"的感知,但很多项目会漏掉。如果你拿到的前端代码里没有预览功能,建议自己补上,逻辑很简单但演示效果很加分。

5. 前后端联调:接口文档怎么用、跨域怎么解决

源码、SQL脚本、接口文档这三件套里,接口文档的存在感往往最低,但联调阶段它才是真正的核心。前后端分离项目里,前端和后端是两个进程,各自独立启动,前端通过网络请求访问后端的接口。联调时最常见的两个问题,一个是接口文档和实际接口不同步,另一个是跨域请求被拦截。

5.1 接口文档的正确打开方式

拿到接口文档后,先把每个接口的四要素摸清楚:请求方法、请求路径、请求参数、返回结构。然后对照后端Controller代码逐个核对,确认文档里的URL路径和@RequestMapping注解里的路径完全一致,参数名和@RequestParam或者实体类的字段名保持一致。字段名大小写不一致是最隐蔽的问题——数据库里是createTime,Java类里是createTime,前端写成createtime,联调时就报字段不存在,排查半天不知道问题在哪。

一个好的接口文档还应该标注出哪些接口需要登录。查看菜谱列表是公开接口,不需要Token;发布菜谱是受保护接口,必须带Token。前端封装axios时,通常会有公开请求和带认证请求两条路径。如果你拿到手的接口文档里没有标注这个信息,你可以根据后端拦截器的放行路径反推出来,这一步梳理清楚,前端路由守卫和后端拦截器的配置就能对齐。

还有一个实用技巧:联调阶段建议安装一个接口调试工具,直接在工具里请求后端接口,看返回数据是否符合预期。这样能快速区分问题是出在后端还是前端。如果后端单独调试没问题、前端调用就报错,那问题大概率出在请求参数格式、请求头缺失或者跨域上,排查范围一下子就缩小了。

5.2 跨域问题:原理和一劳永逸的解法

跨域是前后端分离项目联调阶段一定会遇到的坑。浏览器出于安全策略,默认禁止一个源(协议、域名、端口)的页面去请求另一个源的接口。你在本地开发时前端运行在localhost:8080,后端运行在localhost:9090,两个端口不同就已经构成跨域。表现就是浏览器控制台报"CORS"相关的错误,请求根本发不出去。

解法有好几种,最常用的是在后端加一个CORS配置类,允许指定来源的跨域请求。更简单的做法是写一个WebMvcConfigurer的配置,在addCorsMappings里放行所有路径和所有来源,设置允许的请求方法和请求头,并让前端请求携带凭证。这样后端一启动就全局生效,不用每个接口单独处理。另一种思路是用反向代理——前端开发服务器配一个代理,把接口请求转发到后端地址,这样浏览器看到的是同源的请求,也能绕开跨域。生产环境部署时,前后端一般由同一个Nginx服务转发,本身就不存在跨域,所以跨域问题主要出现在开发阶段。

5.3 从一次联调案例看完整排查链路

我举一个典型的联调场景:前端调"发布菜谱"接口,结果返回"系统异常",后端控制台打了一行空指针异常的日志。拿到这个情况,排查链路应该是这样的。

第一步,先在后端日志里找到异常栈,看是哪个类哪一行报的空指针。通常会发现是Service层取用户信息时拿到的对象为null,也就是当前请求上下文里没有用户。这时候回查前端axios封装,发现发布菜谱的请求没有带Authorization头,自然就会定位为"Token没有随请求发送"。再看请求拦截器,发现拦截器里读取Token的变量名和存储Token的变量名不一致,导致Token拿不到、头就没加上。改掉这个变量名问题就解决了。

这个例子的启示是:联调报错不要慌,顺着"请求头-拦截器-后端上下文"这个链路一层层查,很快就定位了。最怕的就是前端报错就改前端、后端报错就改后端,两边各改各的,结果问题反而越改越多。先判断是请求没到达后端还是后端处理报错,这是联调排错的第一步。

6. 从零跑通整个项目的实操步骤

源码拿到了,环境装好了,怎么把项目完整地跑起来,这是所有拿到二手项目的人第一个要跨过的坎。这个环节90%的报错不是代码逻辑问题,而是环境配置问题。下面我把完整流程走一遍,其中每个容易卡的节点都会单独提醒。

6.1 后端启动的完整步骤和Java环境避坑

第一步,导入SQL脚本。用Navicat或命令行连接MySQL,新建一个数据库,字符集选utf8mb4,然后执行压缩包里的SQL脚本。这里建库时务必选utf8mb4,不然后端插入菜谱详情里的中文和生僻字会出现乱码或报错。

第二步,打开后端的SpringBoot项目,修改application.yml里的数据库连接配置,把用户名、密码改成你本地的。如果你的MySQL端口不是默认的3306,连接地址也要一起改。还要检查一个配置项:文件上传的本地存储路径,是否有对应的目录,Windows和Linux路径写法不一样,启动前先把它改正确。

第三步,启动项目。如果你用的IDE是Idea,直接右键运行启动类。启动成功后控制台会打印SpringBoot的Logo和端口号。如果启动失败,最常见的原因按出现频率排:数据库连接失败、端口被占用、配置文件里有个别字段没对齐。

碰到端口被占用,两个解决办法:一是把占用端口的进程找出来关掉,二是在配置文件里换一个端口。换个端口的话要注意,前端项目里axios封装中配置的基础URL也要同步改,前后端的端口必须对齐,这是一环扣一环的。

6.2 前端启动的完整步骤和Node版本问题

前端项目启动相对简单,但要先装依赖。在项目根目录下执行npm install,如果你有代理或者镜像源配置不干净,可以换成国内镜像源,装起来会快很多。装完依赖后执行npm run serve,开发服务器启动后控制台会打印访问地址,一般是localhost:8080,打开浏览器访问即可。

前端启动常见的坑有三个。第一个是Node版本太新或太老导致npm install报错,建议使用Node的长期支持版本(比如14.x或16.x)。第二个是node_modules没装全,启动时报模块找不到,此时看报错信息缺什么模块就npm install什么,或者干脆删掉node_modules重新装一遍。第三个是后端还没启动,前端页面能打开但所有列表数据都是空的,打开控制台能看到接口请求报错——这时候不是前端问题,是后端还没就绪。

6.3 生产环境部署的两种方式

如果毕设答辩要求现场演示,本地开发模式跑起来就够了。但如果老师要求部署到服务器上演示,就需要了解生产环境的部署方式。

第一种简单方案:前端项目执行npm run build,构建产物会生成一个dist目录,里面是纯静态文件。后端项目打成Jar包,用java -jar直接启动。把dist目录里的文件放到一个静态目录下,后端也可以一并托管这些静态文件,这样访问后端端口就能打开整个前端页面。这种方式没有跨域问题,因为前端页面和后端接口来自同一个服务。

第二种规范方案:服务器上装一个Nginx,负责托管前端静态文件和转发后端API请求。这种方案的路径更清晰,也更贴近公司实际部署方式,但配置Nginx反向代理需要多花一点时间。对于纯毕设演示场景,第一种方案已经足够,如果你愿意多学一种部署方式,写在论文的"部署与测试"章节里也是加分项。

6.4 兜底:跑不通时的高效排错清单

把运行链路捋了一遍之后,我把最容易出问题的点整理成一张表,你照着排查效率会高很多。

现象大概率原因排查方向
后端启动报数据库连接失败application.yml里账号密码或端口不对检查MySQL连接配置和MySQL服务是否启动
后端启动提示端口被占用端口被其他进程占用换端口或关掉占用进程
SQL脚本执行报错数据库字符集不对或脚本重复执行建库时选utf8mb4,确认表是否已存在
前端npm install报错Node版本不匹配或依赖源问题切换Node版本或换镜像源
页面打开但列表为空后端没启动或前端请求地址不对检查后端启动状态和axios基础URL
登录后请求仍报401Token没存入本地或请求拦截器没加Token检查登录后Token存储和请求拦截逻辑
图片上传后访问不到上传目录配置错误或静态资源映射缺失检查上传路径和资源映射配置
跨域报错后端没有配置CORS或配置未生效检查CORS配置类并重启后端

这张表覆盖了我见过的大部分运行问题。如果是表里没有的情况,回到两个基础动作:看后端控制台完整报错信息,看浏览器控制台完整报错信息。报错信息是排错的第一线索,不要一上来就到处改代码,先看日志再说。

这套项目真正跑通的那一刻,你能感受到的其实是"一条完整链路到达终点"的踏实感:数据库里建好了表,后端接口返回了数据,前端页面渲染出菜品,用户点击收藏后数字加一。做毕设最忌只盯着自己的一亩三分地,全程把所有环节走一遍,收获的是对整个Web开发闭环的体感。代码可以借,但"自己亲手把项目跑通、把每个环节的坑填平"的体验,才是这套源码真正留给你的东西。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询