☰
SpringBoot+Vue+MySQL陕西民俗网平台毕设全流程实战
2026/10/13 5:09:43 网站建设 项目流程

做毕业设计选这个题目的人不少,SpringBoot + Vue + MySQL 这组合已经快成高校“标准配置”了。但真正能把这套东西从零搭起来、跑通、写完论文、部署上线的人,其实并不多。我见过太多同学卡在同一个地方:源码拿到手一启动就报错,数据库脚本导进去没数据,前端页面要接口没接口,最后只能干瞪眼。这篇文章就以“中国陕西民俗网平台”为例,把我实际做这类项目时会关注的细节、踩过的坑、还有值得写进论文的技术点,全部拆开讲一遍。不管你是打算自己写一个,还是手里已经拿着这套题目想要弄明白它的原理,都会有用。

陕西民俗这个主题选得很好。它不是冷冰冰的电商或管理系统,而是自带内容展示属性:秦腔、皮影、剪纸、泥塑、社火、面花、biangbiang面、肉夹馍……这些都能撑起图文展示、分类检索、搜索、留言互动这些功能。反过来看,这些功能正好能覆盖一个毕业设计最需要的技术点:增删改查、文件上传、分页查询、多表关联、权限区分。换句话说,这个题目天然适合做成“前端展示 + 后台管理”的双端结构。下面我按自己做这类项目的顺序,把整体设计、技术实现、部署和论文写作一条线讲完。

1. 项目概况与技术选型复盘

1.1 这个平台的核心业务是什么

中国陕西民俗网平台,本质上是一个“信息展示 + 内容管理”的Web系统。面向游客或普通用户提供陕西民俗文化介绍,面向管理员提供内容维护功能。它的核心流程很简单:管理员在后台录入一条民俗内容,比如“秦腔”这个非遗项目,填好名称、分类、传承地区、历史渊源、代表作品,再上传几张图片;前端游客打开网站,在首页看到陕北民歌、关中皮影等板块,点进详情页就能浏览完整文字和图片。除此之外,还可以加搜索和留言功能。

这里要注意,毕设的难点不在业务复杂,而在“结构完整”。你不需要发明什么高深算法,但必须让评委老师看到你具备一个初级开发者的基本素养:数据库设计有外键关联、后端有清晰分层、前端有组件化思维、系统有权限控制。所以功能选型上,我一般建议砍掉花哨的、增加稳妥的。展示端保留:首页轮播、分类列表、详情页面、全文搜索、站内公告;管理端保留:用户登录、民俗内容增删改查、分类管理、轮播图管理、留言管理。这样既能体现工作量,又不至于把自己绕晕。

1.2 为什么选定 SpringBoot + Vue + MySQL 这个组合

先说结论:这套组合最大的优势是“生态成熟 + 学习资料多 + 答辩好讲”。SpringBoot 帮我们把 SSM 时代那一大堆 XML 配置全干掉了,一个启动类就能跑起后端服务,对毕业生来说,理解门槛降低了不少。Vue 的好处是组件化开发,一个页面拆成 header、carousel、list、detail,每个组件各管各的,别人看代码也能一眼看懂。MySQL 则是关系型数据库的常青树,网上资料最多,出了问题随便搜一下就有答案。

更重要的是分工明确。后端只管处理请求和返回 JSON 数据,前端只管渲染数据,两者通过 HTTP 接口通信。这种前后端分离的结构在论文里特别好写,你只需要画一个“浏览器 -> Nginx -> SpringBoot -> MySQL”的架构图,再加一张接口文档表,整个技术架构就立住了。相比 JSP + Servlet 那种混合开发,分离式的代码更干净,也更符合目前企业里的主流做法。

提示:如果你导师偏好“传统”一点,也完全可以解释成“运用当前主流前后端分离模式进行项目实践”。关键是你得能说清楚:前端由谁渲染、数据从哪来、怎么保证安全。

1.3 项目目录结构与功能模块划分

我推荐把项目拆成两个目录:backend 和 frontend,互不干扰。后端按 MVC 结构分包:controller接收请求、service写业务逻辑、mapper(或repository)操作数据库、entity放实体类、config放跨域和静态资源配置。前端用 Vue CLI 创建,按views、components、router、store、api来组织。后面你写部署文档时,能清晰地告诉别人“后端跑在 8080 端口,前端跑在 80 端口,前端请求走 /api 前缀转发到后端”,这一串流程才容易被评委真正听懂。

模块上,我一般分成四个核心模块:用户模块(登录、退出、会话保持)、民俗内容模块(多分类展示、详情、搜索)、留言模块(游客可以发表留言,管理员能删除)、系统管理模块(分类管理、轮播图管理、用户管理)。前两个模块是门面,后两个模块是工作量证明。一套完整的毕设系统,必定具备这四种能力中的至少三种,否则后面写论文会显得“功能不够”。

2. 数据库与后端接口设计要点

2.1 数据库表结构:从需求反推字段

很多同学一上来就建表,建完发现字段对不上。我的习惯是先列需求,再画表。比如“分类”表,它需要什么?至少要有分类ID、分类名称、分类描述、创建时间。“民俗内容”表呢?需要一个自增主键、一个外键指向分类ID、然后标题、内容摘要、详细正文、封面图、所属地区、是否热门、排序值、浏览量、创建时间、更新时间。“留言”表要有ID、昵称、邮箱、内容、状态(显示或隐藏)、创建时间。“管理员用户”表要有ID、用户名、密码、角色、上次登录时间。

我在项目里实际用的表大概是下面这样:

CREATE TABLE `category` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL COMMENT '分类名称', `description` varchar(255) DEFAULT NULL COMMENT '分类描述', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `folk_culture` ( `id` int(11) NOT NULL AUTO_INCREMENT, `category_id` int(11) NOT NULL COMMENT '所属分类', `title` varchar(100) NOT NULL COMMENT '标题', `summary` varchar(255) DEFAULT NULL COMMENT '摘要', `content` text COMMENT '正文', `cover_image` varchar(255) DEFAULT NULL COMMENT '封面图', `region` varchar(50) DEFAULT NULL COMMENT '所属地区', `is_hot` tinyint(1) DEFAULT '0' COMMENT '是否热门', `view_count` int(11) DEFAULT '0' COMMENT '浏览量', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_category_id` (`category_id`), CONSTRAINT `fk_category` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

建表时一定要加charset=utf8mb4。你可能觉得这是小事,但陕西民俗文章里很可能出现生僻字或特殊符号,用 utf8mb4 才能正确存储。还有注意text类型不能设置默认值,所以正文的content字段不能写DEFAULT NULL之后又想给它默认值,给默认值会直接报错。这是初学者经常踩的坑。

2.2 后端接口设计规范:别把 controller 写成一坨

后端最重要的事,是把 Controller 里的代码写薄。比如“获取民俗详情页”这个接口,很多新手会把查询分类、查内容、更新浏览量全部写在 Controller 方法里。这样做不是不能用,但后期一旦要加权限控制就非常痛苦。正确姿势是:

  • Controller 只负责接收参数、校验基础格式、调用 Service、返回 Result。
  • Service 负责业务逻辑、组合数据、异常处理。
  • Mapper 只做单表或简单多表查询。

我习惯统一返回体,类似:

@Data public class Result<T> { private Integer code; private String msg; private T data; }

所有接口都返回Result,前端拿到的永远是{code:200, msg:"ok", data:{...}}。这样统一格式之后,前端 Axios 拦截器只需要判断一次 code 处理全局异常就行。一个关键点:自定义返回类的字段最好用code而不是status,有些同学喜欢用status,结果和后端 HTTP 状态码撞名,前端判断的时候很容易混淆。

2.3 文件上传与静态资源映射

民俗网站最少不了图片。上传图片的接口要单独设计,不能把图片转成 Base64 塞进数据库,否则数据库很快就爆,而且图片没法直接通过 URL 访问。我的做法是:前端通过 FormData 上传文件到后端/api/upload,后端把文件存到本地磁盘的/uploads目录,然后返回访问路径,比如http://localhost:8080/uploads/xxx.jpg。数据库里只保存这个相对路径/uploads/xxx.jpg。

为了能让前端访问到这些图片,需要在后端配置虚拟路径映射。SpringBoot 里我一般用 WebMvcConfigurer:

@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/uploads/**") .addResourceLocations("file:" + System.getProperty("user.dir") + "/uploads/"); } }

这句话的意思是:凡是以/uploads/开头的请求,都去磁盘上找对应文件。没有这个配置,前端访问封面图全是 404。记得把放图片的uploads目录放在当前工作目录下,而不是src/main/resources里,那样打 jar 包后很难写进去。

3. 前端搭建与前后端对接实战

3.1 Vue 页面骨架与路由设计

前端广场上的优秀模板很多,但毕设最好不要用那种带大量自定义组件的重型模板,否则答辩时老师问起某个脚本功能,你答不上来。我建议自己用 Vue CLI 搭一个轻量项目,UI 库选 Element UI 或 Element Plus,上手容易、组件齐全。

首页路由是/#/,访问时加载views/Home.vue,里面放轮播图、热门推荐、分类导航。分类页面路由是/#/category?id=1,详情页是/#/detail/12。后台管理路由统一前缀/admin,比如/#/admin/login、/#/admin/list。这里要特别说一下 why:把普通用户和管理员路由分开,后面权限控制才好写。你可以用路由守卫来判断登录状态,未登录访问/admin就直接跳登录页。

轮播图组件我建议直接用 Element 的el-carousel,不要自己写 JS 轮播插件,否则又要处理自动播放、切换动画,无形中增加很多 bug。首页的民俗列表用el-card加图片,平铺整齐,适合展示。列表下方用分页组件el-pagination,后端采用pageNum和pageSize参数。

3.2 Axios 封装与跨域处理

如果后端的接口路径统一以/api开头,那么前端可以做一个简单的 Axios 实例。这里有个很关键的细节:本地开发阶段,前端跑在http://localhost:8081,后端跑在http://localhost:8080,浏览器直接请求后端会跨域。解决方案有两个:

第一种,在后端加 CORS 配置,允许某个来源跨域。适合本地联调。

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("http://localhost:8081") .allowedMethods("*") .allowedHeaders("*"); } }

第二种,在前端 vue.config.js 里配置代理:

module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true } } } };

本地用代理,打包上线后就不用开发代理了,而是由 Nginx 转发。实际上很多同学把这两种方式同时做了,结果发现开发环境没问题,部署到服务器之后,后端又出现 CORS 错误。原因就是生产环境代理已经交给了 Nginx,后端那个 CORS 配置反而允许了一个不确定来源,于是我一般只保留代理方案。部署后 Nginx 配置里加一句proxy_pass http://127.0.0.1:8080;就完事了。

3.3 后台管理页面与权限控制

后台管理页面不需要好看,但必须“好用、能说不出来”。登录成功后把返回的 token 存进localStorage,每次请求在 Axios 拦截器里加Authorization头。后端写一个过滤器或拦截器,检查请求头里的 token 是否合法。这里我强烈推荐用 JWT,因为不用额外维护 session,代码量小,还方便答辩时演示“无状态认证”。

一个细节:JWT 生成时设置过期时间,比如 2 小时。管理后台里,操作完所有内容后,cookie 失效或 token 过期,会被强制踢回登录页。这个点很加分,在答辩时可以说“系统具备身份认证和会话管理机制”。前端路由导航守卫写法:

router.beforeEach((to, from, next) => { if (to.path.startsWith('/admin') && !localStorage.getItem('token')) { next('/admin/login'); } else { next(); } });

这里面有个小坑:直接判断localStorage.getItem('token')存在,用户手动改 token,页面照样可以进。所以最好在后端接口里做一个校验,反正前端路由守卫只是体验,真正安全在后端。

4. 打包部署与文档/论文整理

4.1 前后端分别打包,别走弯路

后端打包最简单:在 IDEA 里执行 Maven 的package,或者mvn clean package -DskipTests,目标目录target下会生成一个 jar 包,比如folk-server.jar。运行命令只要一条:

java -jar folk-server.jar

注意:如果后端端口用 8080,启动后要确保服务器防火墙放行 8080,或者你通过 Nginx 代理。很多同学本地运行没问题,部署到云服务器后访问不了,第一反应是代码问题,其实九成是云主机安全组没有放行端口。

前端打包是在项目根目录执行:

npm run build

执行完成会生成dist目录。这里的静态文件就是最终的网站页面,部署时让 Nginx 指向dist目录即可。打包前建议改一下 Axios 请求的baseURL,不要写死localhost,而要写成相对路径/api,这样部署后 Nginx 转发才能命中。

4.2 一台服务器如何同时部署前后端

推荐使用 Nginx 作为入口,监听 80 端口,将静态页面交给 Nginx 处理,将/api开头的请求反向代理到 SpringBoot。这样一个域名、一个服务器就能搞定整个系统。Nginx 关键配置如下:

server { listen 80; server_name yourdomain.com; root /usr/share/nginx/html/dist; index index.html; location / { try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /uploads/ { proxy_pass http://127.0.0.1:8080; } }

注意try_files $uri $uri/ /index.html;这行,是 Vue Router 的 history 模式必需的,否则刷新详情页会 404。如果你用 hash 模式(路由带#),这行不写也行,但我不推荐 hash 模式,因为地址栏带#显得很不专业。所以为了 history 模式,Nginx 必须配这行。

数据库迁移也很重要:在本地用mysqldump -u root -p folk_db > folk.sql导出,再在服务器上mysql -u root -p < folk.sql导入。记得检查表结构里是否有DEFAULT CHARSET=utf8mb4,否则导入后可能出现乱码。

4.3 毕业论文大纲与部署文档怎么写

论文的主体,是用文字把你的设计过程讲清楚,让评委不需要运行系统也能理解。我建议按下面这个顺序写:

  • 第一章 绪论:写研究背景、意义、国内外现状。
  • 第二章 相关技术介绍:写 SpringBoot、Vue、MySQL、JWT,每个技术写 2~3 页。
  • 第三章 系统分析:写可行性分析、需求分析、用例图、数据流图。
  • 第四章 系统设计:写架构设计、功能模块设计、数据库设计、接口设计。
  • 第五章 系统实现:写每个模块的界面截图和关键代码片段。
  • 第六章 系统测试:写测试用例、结果、性能表现。

“系统设计”和“系统实现”是重中之重,导师主要看这两章。数据库设计部分一定要放 E-R 图和建表 SQL 说明;系统实现部分千万不要整页贴代码,只挑核心的方法贴 5~8 行进行说明即可。

部署文档我一般建议写成独立的一节,不要塞进论文正文。里面按步骤写:环境要求(JDK 1.8+、MySQL 5.7+、Node 12+、Nginx 1.18+),然后是后端部署步骤、前端部署步骤、Nginx 配置、数据库初始化。这份文档主要是给你自己用的,也是你在答辩现场能流畅演示的脚本。

5. 常见问题与排查技巧实录

5.1 启动报错:找不到主类或依赖冲突

后端起不来的第一类原因,是 Maven 依赖没下载完整或版本冲突。常见表现是启动类上找不到@SpringBootApplication注解对应的类。解决办法:在 IDEA 里执行mvn clean install强制重新下载,或者检查pom.xml里各种版本是否对应。我通常会把所有 SpringBoot 依赖的版本统一由父依赖管理,不单独指定,否则 Spring Boot 2.7 下的某个 starter 会带出 6.0 的 Spring Framework,两者会冲突。

第二类原因是数据库没配好。启动时大概 10 秒内报连接超时,看日志能明确发现Cannot create PoolableConnectionFactory或Communications link failure。这时不要动代码,先检查 MySQL 是否启动、用户名密码对不对、是否有远程访问权限。我的排查顺序是:先ping数据库地址,再telnet 3306,然后命令行直接连库,最后才回看配置。这个步骤写清楚能帮你迅速定位八成问题。

5.2 前端页面能打开但数据全是空的

这类问题基本出在接口调用。打开浏览器 F12,观察 Network,看某个/api/list请求返回的响应体是什么。如果返回 401,多半是登录鉴权问题;如果返回 404,检查后端接口路径是否对得上;如果返回 500,大概率是后端代码里某个字段为空,需要看后端日志。

这里有一个常见低级错误:前端使用axios.get('/category/list'),后端接口是/api/category/list,但跨域代理只把/api开头转发,所以请求路径必须完全包含/api。我一般会在前端封装一层 API 函数,把/api统一加在baseURL里,这样每个方法里的路径就不会遗漏。

5.3 部署后图片加载不出或者数据库乱码

图片 404 的原因我刚才说了,八成是 Nginx 没有转发/uploads路径,或者后端工作目录不对。修正办法是把 uploads 目录放在 jar 包同级的目录,启动命令也在那个目录下执行,保证System.getProperty("user.dir")指向正确位置。

数据库乱码的原因则通常是导入 SQL 时客户端的编码不是 utf8。执行导入前先设置:

mysql --default-character-set=utf8mb4 -u root -p folk_db < folk.sql

同时在连接字符串里加characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai。这里有个容易被忽略的点:serverTimezone必须写,否则高版本 MySQL 时区不对,系统会把时间存错,前端显示出来的时间非常奇怪。

5.4 答辩前最后要做的事

赶在交毕设前,我建议你按这个清单过一遍:第一,把所有接口都测试一次,特别是删除操作要弹确认框,防止误删。第二,将管理员默认密码改成一个简单但你能记住的。第三,写一个README.md放在项目根目录,里面写清楚启动步骤。第四,准备一份系统演示脚本,按“游客首页 -> 分类浏览 -> 详情页 -> 搜索 -> 管理员登录 -> 新增内容 -> 上传图片 -> 留言管理”的顺序走一遍。最后别忘录制一个操作视频,有些评审老师没法现场运行,视频能起到关键作用。

踩过几次坑之后,我自己的体会是:这类毕设项目,最难的从来不是某个牛逼功能,而是把“数据库建好 -> 后端接口稳定 -> 前端展示顺畅 -> 部署上线成功”这条链路打通。只要确保这条链路没有断点,哪怕界面朴素一点,论文照样能拿好成绩。如果你正在做这个陕西民俗网平台,优先把精力花在“内容增删改查 + 文件上传 + 分类检索”上,再把日志和异常处理做得干净一点,答辩时你就会有底气。

最后再分享一个小技巧:给项目里每个接口的返回数据都打一条日志,用log.info记录请求路径和耗时。一方面你自己联调时能看到后端到底在干嘛,另一方面写论文测试章节时,可以直接截日志作为“系统测试记录”,这比刻意编测试数据要自然得多,而且真实有效。

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

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

立即咨询