ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

SpringBoot+Vue美食评测系统全栈实践指南

SpringBoot+Vue美食评测系统全栈实践指南 简介本资源是一套面向Java全栈开发初学者与课程设计者的美食评测系统完整实践方案聚焦人工智能在信息化管理中的落地应用解决餐饮领域用户评价、菜品检索与个性化推荐等典型业务问题。压缩包共667个文件含190个Java后端逻辑代码、133个Vue前端组件、161个SVG图标资源及68个PNG界面素材辅以MyBatis持久层配置XML、Spring Boot启动脚本bat和论文配套静态资源整体48.43MB结构清晰、模块解耦度高。已有65人学习下载适合用于毕业设计参考、Spring BootVue工程化教学或信息管理系统实战训练。读者可直接运行前后端分离架构复现用户登录、美食搜索、多维度评分、个人中心等核心功能并结合13000字论文深入理解需求分析、数据库ER建模、RESTful接口设计及潜在AI推荐模块的扩展思路。1. 为什么一个「美食评测系统」要选 SpringBoot Vue它真能跑通从登录到写评、查店、看热榜的完整链路你手头拿到的这个.zip文件表面看是「源代码数据库13000字论文」三件套但背后是一套被高校课程设计、毕设答辩和中小餐饮SaaS原型反复验证过的全栈技术组合后端用 SpringBoot 做 RESTful 接口与事务控制前端用 Vue 实现响应式交互与路由跳转MySQL 存储用户、店铺、菜品、评分、图片路径等结构化数据。它不是玩具 Demo——真实部署时能支撑 500 用户并发提交评测、按口味标签筛选餐厅、查看近7天热门菜品TOP10也不是过度工程——没有引入 Kafka 或 Redis 集群所有核心功能注册/登录、发布评测、上传图片、分页查询、模糊搜索都落在 SpringBoot 的RestController和 Vue 的vue-routeraxios调用链上。适合两类人一是计算机专业大三学生正卡在「怎么把数据库表变成可点击的网页」这一步二是刚转前端的开发者想通过一个有真实业务逻辑非 TodoList的项目搞懂 Vue 组件如何接收后端 JSON 并渲染成带星级评分的卡片。它不教你怎么写论文但论文里所有系统截图、ER图、接口文档、测试用例都来自你本地跑起来的这套代码。2. 搭建环境从解压 ZIP 到前后端同时启动的最小可行路径2.1 解压后目录结构必须确认的 5 个关键位置拿到.zip后不要直接双击运行先解压并检查以下路径是否存在这是后续所有操作的前提food-review-system/ ├── backend/ ← SpringBoot 项目根目录含 pom.xml │ ├── src/main/java/com/example/foodreview/ │ └── src/main/resources/application.yml ├── frontend/ ← Vue 项目根目录含 package.json │ ├── src/ │ │ ├── api/ ← 封装 axios 请求的目录重点看 index.js │ │ ├── router/ ← 路由配置index.js 中应有 /login, /home, /detail/:id │ │ └── views/ ← 页面组件Login.vue, Home.vue, ReviewForm.vue 等 │ └── vue.config.js ← 必须存在用于配置跨域代理见 2.3 ├── database/ ← SQL 脚本目录food_review.sql 是建库建表语句 ├── docs/ ← 论文 PDF 和 Word 版非运行必需 └── README.md ← 作者写的快速启动说明优先读它提示如果frontend/src/api/index.js里 baseURL 写的是http://localhost:8080而你的后端端口是8081必须立刻修改否则所有请求 404。Vue 项目本身不处理跨域靠vue.config.js的devServer.proxy转发到后端。2.2 后端启动SpringBoot 项目必须调的 3 个参数进入backend/目录用 IntelliJ IDEA 或 VS Code 打开不要直接点绿色三角运行。先检查src/main/resources/application.yml中以下三项spring: datasource: url: jdbc:mysql://localhost:3306/food_review?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 123456 # ← 这里必须是你本地 MySQL 的真实密码 jpa: hibernate: ddl-auto: update # ← 关键设为 update 可自动建表设为 validate 则只校验不建表 show-sql: true properties: hibernate: format_sql: trueurl中的food_review是数据库名必须与database/food_review.sql里CREATE DATABASE food_review;一致username/password必须匹配你本机 MySQL 服务的登录凭证若用 Docker 运行 MySQL请确认容器端口映射为3306ddl-auto: update是开发阶段最安全的选项首次启动时自动创建user,restaurant,review等表后续加字段会自动新增列不会删数据。启动命令终端执行cd backend mvn spring-boot:run -Dspring.profiles.activedev看到Tomcat started on port(s): 8080 (http)即表示后端就绪。2.3 前端启动Vue 依赖安装与跨域代理配置进入frontend/目录执行npm install # 若报错 node-sass改用 npm install --legacy-peer-deps # 启动前检查 vue.config.js 是否包含以下代理配置vue.config.js必须有如下内容否则浏览器控制台将出现 CORS 错误module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, // ← 必须与后端实际端口一致 changeOrigin: true, pathRewrite: { ^/api: // ← 把前端请求的 /api/login 映射为后端的 /login } } } } }然后启动npm run serve访问http://localhost:8080注意Vue 默认端口是8080但此时已被后端占用所以实际是http://localhost:8081—— 查看终端输出确认。若页面显示「欢迎来到美食评测系统」且无控制台红字说明前后端通信成功。2.4 数据库初始化3 步执行 SQL 脚本避免「表不存在」异常不要用 IDEA 自带的 Database 工具直接拖入.sql文件——它可能忽略CREATE DATABASE语句。推荐用命令行# 1. 登录 MySQL mysql -u root -p # 2. 执行建库建表假设 SQL 文件路径为 /path/to/food_review.sql mysql source /path/to/food_review.sql; # 3. 验证表是否生成 mysql USE food_review; mysql SHOW TABLES; -- 应看到review, restaurant, user, tag, review_tag 等至少 5 张表food_review.sql中的关键约束必须存在review.user_id外键关联user.idreview.restaurant_id外键关联restaurant.idreview.score字段类型为TINYINT CHECK (score BETWEEN 1 AND 5)—— 这是评分合法性的数据库层保障。注意如果执行source报错Unknown database food_review说明CREATE DATABASE food_review;语句未被执行需手动执行该语句后再重试。3. 核心功能落地从用户注册到发布一条带图评测的完整代码链3.1 后端接口ReviewController如何接收 Vue 提交的 JSONbackend/src/main/java/com/example/foodreview/controller/ReviewController.java中发布评测的核心方法是PostMapping(/reviews) public ResponseEntityMapString, Object createReview(RequestBody ReviewDTO reviewDTO) { // 1. 校验 DTONotBlank, Min(1), Max(5) 注解已写在 ReviewDTO 类中 if (!reviewDTO.isValid()) { MapString, Object error new HashMap(); error.put(code, 400); error.put(message, 评分必须为1-5评论不能为空); return ResponseEntity.badRequest().body(error); } // 2. 保存主表 review Review review new Review(); review.setUserId(reviewDTO.getUserId()); review.setRestaurantId(reviewDTO.getRestaurantId()); review.setScore(reviewDTO.getScore()); review.setContent(reviewDTO.getContent()); review.setCreatedAt(LocalDateTime.now()); reviewRepository.save(review); // ← JPA 自动生成 INSERT 语句 // 3. 处理多对多标签如「辣」「甜」「适合约会」 for (String tagName : reviewDTO.getTags()) { Tag tag tagService.findOrCreate(tagName); // 先查后建避免重复 reviewTagRepository.save(new ReviewTag(review.getId(), tag.getId())); } MapString, Object result new HashMap(); result.put(code, 200); result.put(message, 评测发布成功); result.put(reviewId, review.getId()); return ResponseEntity.ok(result); }RequestBody ReviewDTO表明 SpringBoot 会自动将前端 POST 的 JSON 解析为 Java 对象reviewDTO.isValid()是自定义校验逻辑比单纯用Valid更灵活例如判断content.length() 500reviewTagRepository.save(...)使用复合主键实体ReviewTag对应数据库中的关联表review_tag。3.2 前端调用Vue 组件中如何组装 FormData 并上传图片frontend/src/views/ReviewForm.vue中用户填写表单并点击「发布」时关键逻辑在submitReview方法methods: { async submitReview() { const formData new FormData(); formData.append(userId, this.userId); formData.append(restaurantId, this.restaurantId); formData.append(score, this.score); formData.append(content, this.content); // 图片文件必须用 File 对象 append不能转 base64 if (this.imageFile) { formData.append(image, this.imageFile); // ← 后端 Controller 需用 RequestParam 接收 } // 标签数组转为字符串用逗号分隔 formData.append(tags, this.selectedTags.join(,)); try { const res await api.post(/reviews, formData, { headers: { Content-Type: multipart/form-data } // ← 必须显式设置 }); this.$message.success(评测发布成功); this.$router.push(/detail/${res.data.reviewId}); } catch (err) { this.$message.error(发布失败 err.response?.data?.message || 网络错误); } } }FormData是浏览器原生 API专为文件上传设计若用JSON.stringify()发送图片后端收到的是[object File]字符串headers: { Content-Type: multipart/form-data }不能手动设置——浏览器会自动添加边界boundary手动设置反而导致 400api.post()调用的是frontend/src/api/index.js中封装的 axios 实例其 baseURL 已设为/api因此最终请求 URL 是http://localhost:8081/api/reviews经vue.config.js代理到http://localhost:8080/reviews。3.3 数据库同步当 Vue 提交「川菜」「火锅」两个标签时MySQL 怎么存food_review.sql中tag表结构为CREATE TABLE tag ( id BIGINT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL UNIQUE, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );而review_tag关联表为CREATE TABLE review_tag ( review_id BIGINT NOT NULL, tag_id BIGINT NOT NULL, PRIMARY KEY (review_id, tag_id), FOREIGN KEY (review_id) REFERENCES review(id) ON DELETE CASCADE, FOREIGN KEY (tag_id) REFERENCES tag(id) ON DELETE CASCADE );当用户提交[川菜,火锅]时后端执行查询SELECT id FROM tag WHERE name 川菜→ 若无则INSERT INTO tag(name) VALUES(川菜)同理处理火锅插入两条记录到review_tag(1001, 201)和(1001, 202)其中1001是新评测 ID201/202是标签 ID。提示这种设计避免了在review表中用VARCHAR存逗号分隔的标签违反第一范式也避免了每次查「带川菜标签的评测」时用LIKE %川菜%导致全表扫描。4. 论文写作支撑从系统截图到 ER 图哪些内容可直接复用4.1 论文中必须出现的 4 类系统截图及生成方式你的 13000 字论文不是空谈架构所有图表必须来自你本地运行的系统。以下是可一键截取的高质量配图截图类型访问路径截图要点说明是否需登录系统首页http://localhost:8081/显示顶部导航栏首页/发现/我的、轮播图3 张美食图、热门餐厅卡片带星级和评分否评测详情页http://localhost:8081/detail/1URL 中1为任意存在的 review.id截图需包含菜品图、评分星标、评论文字、发布时间、点赞按钮否后台管理页http://localhost:8081/admin需先用管理员账号如admin/123456登录截图展示「审核评测」「禁用用户」两个操作按钮及表格数据是移动端适配效果Chrome 开发者工具 → Toggle device toolbar → 选 iPhone 12截图显示导航栏折叠为汉堡菜单、卡片宽度自适应、字体大小未缩放过度否注意所有截图必须关闭浏览器地址栏和开发者工具面板使用系统自带截图工具WinShiftS / CmdShift4保证边框干净。不要用 QQ 截图其水印会被学校查重系统识别。4.2 ER 图绘制用 MySQL Workbench 逆向工程生成标准图不要手动画 ER 图用官方工具保证学术规范性打开 MySQL Workbench连接本地food_review数据库菜单栏Database → Reverse Engineer...勾选全部表review,user,restaurant,tag,review_tag完成后右键 Diagram →Export as PNG在论文中插入时图标题写为「图 3.1 美食评测系统实体关系图」并在正文中说明「review_tag表实现review与tag的多对多关系符合第三范式要求」。生成的 ER 图中review_tag表必须显示为菱形关系实体两端连线标注1..*这是数据库课程设计得分关键点。4.3 接口文档表格从 Swagger UI 直接导出可复制的 Markdown后端项目已集成 SpringDoc OpenAPISwagger 3启动后访问http://localhost:8080/swagger-ui.html点击ReviewController下的POST /reviews展开Example Value复制 JSON 示例点击Model查看ReviewDTO字段说明整理为论文中的「表 4.2 评测发布接口参数说明」参数名类型必填说明示例值userIdLong是用户ID从登录态获取1001restaurantIdLong是餐厅ID由前端列表页传入2001scoreInteger是评分范围 1-54contentString是评论正文长度 10-500 字「锅底香而不腻…」tagsString[]否标签数组前端转为逗号分隔字符串[麻辣,适合聚餐]imageFile否图片文件MIME 类型为 image/*二进制流提示此表格直接决定论文「系统设计」章节的严谨性。若表格中缺少image参数或未注明 MIME 类型在答辩时会被质疑「文件上传功能未实现」。5. 常见故障排查当「页面空白」「404」「图片不显示」时按顺序查这 5 个点5.1 页面完全空白90% 是 Vue 路由模式与后端静态资源冲突现象访问http://localhost:8081/显示白屏控制台无报错Network 标签页中index.html返回 200 但app.js404。原因Vue CLI 默认用history模式但后端未配置 fallback。当用户直接访问/detail/1时请求被发给后端而 SpringBoot 没有GetMapping(/detail/{id})返回 404。解决方案一推荐改用hash模式在frontend/src/router/index.js中const router new VueRouter({ mode: hash, // ← 改这里 routes: [ /* ... */ ] });重启npm run serveURL 变为http://localhost:8081/#/detail/1问题消失。方案二后端加静态资源映射需改backend/src/main/java/com/example/foodreview/config/WebConfig.javaOverride public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/**) .addResourceLocations(classpath:/static/); }并在backend/src/main/resources/static/下放index.htmlVue 打包后的文件但此方案增加部署复杂度。5.2 图片上传后不显示检查后端application.yml的文件路径配置现象评测发布成功但详情页图片区域为空白浏览器 Network 中图片请求返回 404。原因Vue 前端渲染的img :srcreview.imageUrl /中imageUrl是相对路径如/uploads/20240510/abc.jpg但 SpringBoot 未配置该路径为静态资源。解决在backend/src/main/resources/application.yml中添加spring: servlet: context-path: /api # ← 确保所有接口以 /api 开头避免与静态资源冲突 resources: static-locations: classpath:/static/,file:./uploads/ # ← 关键指定 uploads 目录为静态资源然后确保后端代码中保存图片时写入./uploads/20240510/abc.jpg并返回给前端的imageUrl为/uploads/20240510/abc.jpg。5.3 登录后无法跳转到首页Vue Router 的beforeEach守卫未生效现象输入账号密码接口返回{code:200}但页面仍停留在登录页URL 未变。原因frontend/src/router/index.js中的全局前置守卫未正确拦截登录成功响应。检查该文件是否包含router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.meta.requiresAuth !token) { next(/login); } else if (to.path /login token) { next(/home); // ← 关键登录成功后有 token应跳首页 } else { next(); } });若缺失else if (to.path /login token)分支则登录后不会自动跳转。5.4 数据库中文乱码application.yml与 MySQL 服务端编码不一致现象后台管理页中餐厅名称显示为????但用 MySQL 命令行查SELECT name FROM restaurant正常。原因SpringBoot 连接 URL 缺少characterEncodingutf-8或 MySQL 服务端默认编码非utf8mb4。解决修改application.yml的 JDBC URLurl: jdbc:mysql://localhost:3306/food_review?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltruecharacterEncodingutf-8登录 MySQL执行ALTER DATABASE food_review CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;重启后端服务。5.5 论文查重率高3 个必须修改的「通用描述」模板不要直接复制 ZIP 包内docs/下的论文文字以下三处是查重雷区必须重写摘要首句❌ 原文「随着互联网技术的发展人们的生活方式发生了巨大变化……」✅ 改写「本系统聚焦于解决用户在探店决策中缺乏结构化参考信息的问题通过量化评分、标签聚合与图文评测将主观用餐体验转化为可检索、可排序的数据资产。」技术选型理由❌ 原文「Vue 框架具有轻量、高效、双向绑定等优点……」✅ 改写「选用 Vue 2.6非 Vue 3是因为其 Options API 与本项目中mixins封装的表单校验逻辑兼容性更好且学校实验室机房的 Node.js 版本v14.17.0对 Vue CLI 4 的支持更稳定。」系统测试用例❌ 原文「测试了登录、注册、发布评测等功能……」✅ 改写「设计 7 个边界测试用例① 输入 501 字评论触发前端 maxlength 拦截② 连续 3 次输错密码触发后端账户锁定JWT Token 失效③ 上传 15MB 图片返回413 Payload Too Large④ 搜索词含 SQL 关键字如OR 11被 MyBatis#{}预编译自动过滤……」提示最后一条「SQL 关键字测试」是加分项——证明你理解了 MyBatis 的#{}与${}区别且在ReviewMapper.xml中所有参数均使用#{}这是数据库课程设计的高分证据。本文还有配套的精品资源点击获取
返回列表