ARTICLE DETAIL

资讯详情

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

SpringBoot+Vue垃圾分类管理系统:从开发到部署的完整实战

SpringBoot+Vue垃圾分类管理系统:从开发到部署的完整实战 做毕设的都知道“垃圾分类管理系统”这六个字已经不知道出现在多少学校的选题列表里了。但真上手之后才发现这题目看着像 CRUD 堆砌实际做起来却要你把登录鉴权、权限路由、多表关联、状态流转、图表统计全走一遍。我拿到这套 SpringBootVue 城市垃圾分类管理系统管理平台源码的时候第一反应是“终于不是那种只有登录和列表页的玩具了”——项目用 JavaMySQL 做后端持久层前端是 Vue 全家桶前后端分离开发跑起来之后用户端、回收员端、管理端三条角色线都有完整页面和接口拿来当毕设、课设或者 SpringBoot 学习练手都合适。我前后花了两天把整条链路从环境搭建到打包部署完整跑了两遍中间踩了不少老教程和新版本之间的坑。这篇就按“选题拆解 → 环境搭建 → 核心模块实现 → 联调部署 → 问题排查 → 答辩提分”的顺序把我实际验证过的东西全部交底包括 springboot 版本太高带来的一连串兼容性问题、Vue 打包进 SpringBoot 之后刷新 404 的处理、MySQL 连接报错的排查思路这些网上讲得稀碎的点。1. 垃圾分类系统拆解这项目到底在做什么技术选型为什么这么定1.1 业务功能清单一个看起来简单、做起来五脏俱全的题目城市垃圾分类管理系统业务核心就两件事教居民正确分类以及把回收流程线上化。对应到功能模块常见的成熟版本大致包含这样几条线用户端注册登录、垃圾分类查询按物品名搜索所属类别、分类知识库浏览可回收/有害/厨余/其他四大类、在线预约回收填写地址和上门时间、积分查看与兑换、个人资料修改。管理端分类词条管理增删改查垃圾物品及对应类别、预约单管理审核、派单、标记完成、用户管理、积分规则配置、数据统计看板各类别占比、每日回收订单量趋势。回收员端收到派单后上门回收确认完成后系统自动给用户加积分。这套功能列表很讨巧因为它覆盖了考核最爱的几个能力点多角色权限控制、一对多和多对多表关系、事务操作扣积分、改订单状态必须原子性、聚合统计查询、前端路由守卫和状态展示。换句话说答辩时老师问“这个系统里你遇到过什么难点”你永远有东西可以讲而不是只能说“我做了个增删改查”。1.2 为什么坚持前后端分离而不是 JSP 单体一把梭很多课设模板还在用 JSPServlet但如果你要做的是 SpringBootVue 这套那本质上是选择了前后端分离架构。这里有一个核心原因值得在文档和答辩里反复强调接口即契约前端只管渲染后端只管数据两边的改动不会互相踩脚。实际开发中的体感差异也很明显。调试 JSP 页面时改个样式还得重新编译打包而 Vue 项目里配了热更新之后改样式、改文案、调接口返回值的渲染逻辑都是秒级反馈。更别提现在 Vue 生态里的 Element UI 组件库表格、表单、步骤条、弹窗全部现成你只需要写数据和方法页面观感立刻就能达到“能答辩”的水平。另外要提醒一句毕设文档里千万不要只写“用了前后端分离”要写清楚分离之后接口怎么对接、跨域怎么处理、部署的时候前端静态资源打到哪里这些才是老师真正会追问的点。对比维度单体 JSP 方案前后端分离方案开发分工后端顺手写页面耦合度高前后端并行开发接口先行调试体验修改后编译重启前端热更新后端热部署答辩加分较低架构老旧能讲出路由、状态管理、跨域等知识点部署难度打一个 war 包前端打包后放入后端 static 目录或独立部署1.3 技术栈组合逻辑为什么偏偏是 Java MySQL技术选型不是越新越好而是越“稳”越好。后端用 SpringBoot是因为它默认内嵌 Tomcat一个java -jar就能起服务省掉配置外部容器的麻烦Starter 机制让整合 MyBatis、MySQL 驱动、参数校验都变成加依赖加配置的事这对学生项目来说太友好了。搭配 MyBatis 或 MyBatis-Plus 做持久层SQL 写起来直观也方便你在文档里放“复杂查询”的截图。数据库选 MySQL图的是它覆盖面广、网上资料多、面试常问。相比于 H2 这种嵌入式数据库MySQL 能让你真正讲清楚索引、事务隔离级别、外键约束这些东西而相比于 SQL ServerMySQL 安装简单跨平台而且 5.7 和 8.0 都有海量踩坑记录。如果导师没有强制指定数据库MySQL 就是这个题目下最不会出错的选择。为什么不选 Python Django 或 Node通常是因为学校课程体系以 Java 为主你的毕业设计要和课程设计、实训项目对齐否则答辩时老师对技术栈不熟悉反而问你更多奇怪问题。2. 从零跑通 SpringBootVue 环境的完整路径2.1 版本匹配关系这一步错了后面全是泪环境搭建阶段最大的坑不是不会装而是版本之间互相不兼容。SpringBoot 2.x 和 3.x 看似只是大版本升级实际改动非常伤3.x 强制要求 JDK 17 起并且把javax.*包名迁移到了jakarta.*很多老教程里的代码和第三方 starter 直接编译不过。我实测下来推荐两套组合你根据自己电脑上已有的环境选一套就好组合方案JDKSpringBootVueUI 组件库MySQL稳妥型JDK 8 / 112.7.x2.xElement UI5.7 / 8.0较新型JDK 173.2.x3.xElement Plus8.0如果你在 IDEA 里创建项目时默认拉到的是 SpringBoot 3.x但你照着 SpringBoot 2.x 的教程写会发现在导入javax.servlet或者某些 starter 时直接报红。这时候千万别硬肛要么把 SpringBoot 版本在pom.xml里改成 2.7.x要么把所有javax改成jakarta并且确认你用的第三方组件有对应适配版本。这也是热词里“springboot版本太高”的真实场景——老教程 新框架的组合能让你卡一整天。2.2 MySQL 安装与数据库初始化本地装还是 Docker 装MySQL 安装方式有两条路。一条是直接下载 installer 装到本机Windows 上安装 5.7 或 8.0 记得选“Developer Default”然后一路 Next期间设置 root 密码。另一条是 Docker 一把梭我机器上就用的 Docker命令很简单docker run --name mysql -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -d mysql:5.7这里有个我踩过的坑如果你本机已经装了 MySQL 占用了 3306 端口Docker 容器会一直报端口冲突日志里反复出现Error starting userland proxy: listen tcp 0.0.0.0:3306: bind: address already in use。这时候不要慌把宿主机端口换个映射比如-p 3307:3306连接 URL 里对应写成jdbc:mysql://localhost:3307/xxx就行。数据库初始化也别偷懒。拿到源码后先看 SQL 脚本通常包含建库、建表、插入初始化数据三部分。执行时注意字符集要指定utf8mb4分类名称、垃圾物品名称这些字段全是中文如果字符集不对查询和展示都会出现乱码CREATE DATABASE IF NOT EXISTS garbage_sorting DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;用 Navicat 或命令行执行脚本时建议直接source整个 .sql 文件而不是手动一段段复制这样可以避免漏掉外键约束导致后面的关联查询出问题。导入完成之后用一条简单查询验证一下比如select * from garbage_item limit 10;能看到分类数据和物品数据就说明底子打好了。2.3 SpringBoot 工程初始化与核心配置后端工程推荐用 IDEA 的 Spring Initializr 创建选好 Maven 项目、Java 版本然后添加 Web、MySQL、MyBatis 依赖。这里要注意如果你用的是 MyBatis-Plus建议直接引入mybatis-plus-boot-starter因为老版本mybatis-plus和 SpringBoot 3.x 的兼容性有问题必须用 3.5.x 以上的新版本。启动前把application.yml配置好我一般习惯把环境相关的信息写在这里方便后面部署时只改这一处server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/garbage_sorting?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: map-underscore-to-camel-case: true global-config: db-config: id-type: auto这段配置里最容易出问题的就是 URL 参数。MySQL 8.0 的驱动要求allowPublicKeyRetrievaltrue否则连接时会报Public Key Retrieval is not allowed我后面会详细讲这个。时区参数serverTimezoneAsia/Shanghai也必不可少不加的话插入时间字段会直接报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized这个错误信息在控制台里长得跟乱码一样第一次遇到的人很容易懵。2.4 Vue 前端工程搭建与环境配置前端部分Vue2 项目用vue create创建Vue3 也可以用同一个命令但选 3.x 预设。创建完先别急着写业务代码先把 UI 组件库装上。Vue2 对应 Element UIVue3 对应 Element Plus两者接口略有差异别搞混了。npm install element-ui --save npm install axios --save npm install vue-router3 --save安装依赖慢是老生常谈的问题国内直接 npm install 卡到怀疑人生。最有效的办法是先把 registry 换成淘宝镜像npm config set registry https://registry.npmmirror.com换源之后再装速度完全是两个世界。装完依赖后配置main.js挂载 Element UI 和路由启动npm run serve浏览器能打开默认页面就说明前端骨架通了。启动之后立刻做一次前后端连通测试在 Vue 里通过 axios 请求后端的一个简单接口比如/api/user/list看能不能返回 JSON。这一步如果在开发早期完成后面所有模块调试都会很顺而不是写完了所有页面才发现接口根本调不通。3. 核心功能模块设计与实现从登录鉴权到回收预约3.1 登录鉴权与多角色权限控制垃圾分类系统有三种角色普通用户、回收员、管理员。如果每个角色都单独写一套登录逻辑代码会爆炸。项目里通常的做法是共用一张user表用role字段区分身份登录后返回一个 token前端把 token 存到localStorage每次请求带头部。实现细节上毕设级的项目不太建议硬上 Spring Security配置链长、概念多、答辩容易问崩。更轻量可靠的做法是 JWT 手写拦截器登录成功后用用户的 id 和角色生成 token自定义一个AuthInterceptor放行/api/login、/api/register这类开放接口其余接口统一校验 token校验不通过直接返回 401。业务代码里再用HandlerInterceptor里的用户信息判断权限比如“只有管理员能调用”删除词条”接口”。这个方案的优点是原理透明代码量可控而且特别适合答辩老师问“权限是怎么控制的”你可以从 token 生成规则、拦截器注册、前端路由守卫三层讲下来每个环节都能展开这是纯用框架会给答案的选手比不了的。3.2 垃圾分类知识库最核心也是最好做的一块垃圾分类查询是这个系统的门面用户打开页面第一眼看到的就是搜索框和四大分类卡片。后端表结构一般是两张表category分类表和garbage_item垃圾物品表物品表通过category_id外键关联分类表。查询接口的核心逻辑是模糊搜索加分页Override public PageGarbageItem searchItems(String keyword, PageGarbageItem page) { LambdaQueryWrapperGarbageItem wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.isNotBlank(keyword), GarbageItem::getName, keyword) .orderByAsc(GarbageItem::getCategoryId); return this.page(page, wrapper); }前端搜索框绑定的值通过watch监听用户输入完按回车或点击搜索按钮触发接口调用返回结果用卡片栅格渲染。这里有个提升体验的细节在garbage_item表的name字段上建一个普通索引。数据量小的时候感觉不到差别但答辩时你说“我在搜索字段上加了索引查询走的是索引扫描”这一句话就能和“无脑 CRUD”区分开。分类知识库的前端展示建议用 Tab 切换的形式别把所有分类堆在一个长页面上。Element UI 的el-tabs组件就够了每个 Tab 里放一个分类的物品列表用户浏览起来很直观。如果你想让项目多一点亮点可以在分类卡片上配对应颜色的图标——可回收蓝色、有害红色、厨余绿色、其他灰色这属于典型的低成本高感知优化。3.3 回收预约与状态流转最能讲故事的业务闭环回收预约模块是整套系统的灵魂因为它不是单表操作而是一条完整的状态链路用户提交预约 → 管理员审核或自动通过→ 回收员接单 → 上门回收确认完成 → 系统自动给用户增加积分。预约单表的核心字段大概是这些预约单号、用户 id、联系电话、上门地址、预约时间段、回收物品描述、重量估算可选、状态字段。状态字段我建议直接用Integer存数值0 待接单、1 进行中、2 已完成、3 已取消前端用一个状态标签组件把数字映射成不同颜色的文案。这几个状态之间的流转一定要放在后端 Service 层处理并且加上事务注解Transactional(rollbackFor Exception.class) public boolean completeOrder(Long orderId) { RecycleOrder order orderService.getById(orderId); if (order null || order.getStatus() ! 1) { throw new ServiceException(订单不存在或状态不允许操作); } // 修改订单状态为已完成 order.setStatus(2); orderService.updateById(order); // 给用户加积分这里写积分流水 userService.addPoints(order.getUserId(), 10); return true; }Transactional在这里意义重大假设订单状态改成已完成之后积分加成功的第二步失败了如果没有事务就会出现“订单显示完成但用户没拿到积分”的问题加了事务之后两个操作要么一起成功要么一起回滚。我见过太多学生在这个地方漏写事务注解答辩被老师一句“如果加积分失败怎么办”直接问倒。前端的预约表单校验也别忽略。地址、联系方式必填回收时间不能选过去的时间这些用 Element UI 的rules配置就能实现。预约完成后用户可以在“我的预约”列表里看到订单状态用el-steps步骤条展示当前进度这一步虽然只是展示但业务完整度瞬间就上来了。3.4 积分与兑换模块从流水表到事务一致积分系统如果只加不减就是个非常学不到东西的模块。成熟的模板会把它做成完整的积分流水体系用户每次完成回收获得积分积分记录写入points_record积分流水表积分可以在积分商城兑换商品兑换成功后扣减用户总积分并记录消费流水。积分流水表的设计值得多说两句。它至少要包含这些字段用户 id、变动积分正负值、变动类型回收获得、兑换扣除、活动赠送、关联业务单号、创建时间。把关联业务单号存进去这个习惯非常好因为你在任何地方看到积分变动都能反查回去是哪笔订单产生的。写到文档里就是“我的积分流水可以追溯到业务来源”这在数据库设计里叫可追溯性。扣减积分的代码要注意并发问题。简化的写法是“先查用户积分 → 判断是否足够 → 执行扣减”这种写法在并发情况下会出现超扣。如果你想让项目上点档次可以在 update 语句里带条件UPDATE user SET points points - #{amount} WHERE id #{userId} AND points #{amount}受影响行数大于 0 才说明扣减成功否则提示积分不足这就用到了乐观锁的思想。这段代码和解释写进论文里含金量是肉眼可见的高。3.5 后台数据看板用聚合查询给系统增值管理后台的首页如果只有一条“欢迎语”答辩时多少有点露怯。加分做法是一个 ECharts 数据看板左侧分类占比饼图右侧每日回收单量折线图。前端用 ECharts 调用this.chart echarts.init(this.$refs.chartBox); this.chart.setOption({ series: [{ type: pie, data: this.categoryStats }] });后端提供聚合接口MyBatis 里写一句分组查询就行select idcountByCategory resultTypemap SELECT c.name AS name, COUNT(*) AS value FROM recycle_order o JOIN garbage_item g ON o.item_id g.id JOIN category c ON g.category_id c.id WHERE o.status 2 GROUP BY c.name /select返回ListMapString, Object给前端ECharts 支持直接接收这种结构。这个模块的技术含量不高但视觉效果非常好——数据一出来整个系统“管理系统”的定位就立住了而不是单纯的“查询工具”。4. 前后端联调与部署跨域、路由、打包放进 SpringBoot4.1 跨域配置开发环境和生产环境两套打法前后端分离开发时前端跑在 8080 端口Vue dev server 默认端口后端跑在 8080 端口SpringBoot 默认端口端口不一样浏览器就会拦截跨域请求。开发环境最简单的做法是利用 Vue dev server 的代理功能在vue.config.js里配置module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }这样前端请求/api/login时dev server 会转发到后端的http://localhost:8080/api/login浏览器看到请求是同源的不会产生跨域问题。这种做法只对开发环境有效因为生产环境下前端静态资源已经打进后端包了根本不存在跨域。如果某些接口需要本机单独调试也可以在后端做全局 CORS 配置。注意一个大坑allowCredentials(true)时allowedOrigins不能写*必须写具体域名或使用allowedOriginPatterns。很多帖子只复制了前几行代码结果配完发现带 cookie 的请求全部被拦截卡半天找不到原因。4.2 axios 封装与路由权限控制前端请求如果每个页面都axios.get一把梭后期维护会非常痛苦。建议在src/utils/request.js里封装一个 axios 实例给所有请求统一加 token统一处理错误码service.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers[Authorization] Bearer token; } return config; }); service.interceptors.response.use( response { const res response.data; if (res.code ! 200) { this.$message.error(res.msg); if (res.code 401) { router.push(/login); } return Promise.reject(new Error(res.msg)); } return res; }, error { this.$message.error(网络请求失败); return Promise.reject(error); } );路由权限控制是在前端保证角色隔离的关键。最简单的实现是在vue-router的全局前置守卫里判断用户已登录但没有该页面的权限就跳回首页未登录访问受保护页面就统一跳转到登录页并记录要回跳的路径。这套逻辑代码量不大但能体现出你对前端路由的很清楚。路由守卫和导航守卫的面试价值很高写在简历和论文里都能算一个亮点。4.3 Vue 打包放进 SpringBoot刷新 404 的根治方案这一步就是热词“vue打包放进springboot中”对应的场景。在本地所有功能都调通之后前端跑npm run build会生成一个dist目录里面是编译压缩后的静态文件。把这些文件直接复制到后端项目的src/main/resources/static目录下再重新打包后端SpringBoot 内置 Tomcat 就会自动把static目录当作静态资源根目录。但是这里有一个经典的大坑Vue Router 如果用的是 history 模式URL 路径是/login、/order/detail/1这样的真实路径。浏览器直接访问这些路径时后端没有对应的 ControllerSpringBoot 会返回 404 白屏。解决办法是写一个 ViewController 把非/api开头的路由全部转发到index.htmlController public class ViewController implements WebMvcConfigurer { Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController(/{path:[^\\.]*}).setViewName(forward:/index.html); } }这段配置我实测有效原理是把所有不带点后缀的路径都交给前端路由去处理。如果你在部署后出现“首页能开刷新就 404”的情况十有八九就是少了这一步。4.4 整体打包部署与运行验证部署阶段终极大法就是把前后端合成一个 jar 包这样你只需要给答辩老师演示一条命令视觉上非常干净mvn clean package -DskipTests java -jar target/garbage-system-1.0.0.jar启动成功之后浏览器访问http://localhost:8080看到的就是打包后的前端页面。验证时最好按用户完整流程走一遍注册 → 登录 → 搜垃圾 → 预约回收 → 管理员审核 → 回收员接单 → 完成订单 → 查积分。这一套流程走下来项目就从“凑合的 CRUD”升级成了“完整可演示的业务系统”。我每次帮朋友调试都会提醒演示之前准备一组测试账号用管理员、回收员、用户三个账号分别登录过一遍常出现的问题就是只测了用户端切到管理端发现菜单权限控制没写好。5. 常见问题与排查技巧实录这一节把我会实际遇到的报错和网络热词里最常搜的问题做个速查每个都给出定位思路和解决方法。现象常见原因解决方法启动报Unable to find a single main class工程里存在多个带main方法的类检查测试目录或 Demo 类删除多余的main入口MySQL 连接报Public Key Retrieval is not allowedMySQL 8.0 驱动默认不允许获取公钥在 JDBC URL 加allowPublicKeyRetrievaltrue前端页面点击后刷新变成 404Vue Router history 模式没有后端配合添加 ViewController 转发到index.html前端请求接口报跨域错误开发环境代理没配或后端 CORS 没配优先用 devServer proxy生产环境不存在跨域依赖包下载超时默认 Maven 中央仓库速度慢换成阿里云镜像https://maven.aliyun.com/repository/publicDocker 启动 MySQL 失败宿主机 3306 端口被占用换映射端口或先停掉本机占用进程中文乱码数据库字符集或连接 URL 没指定编码数据库和表统一使用utf8mb4URL 带characterEncodingutf85.1 springboot 版本太高导致的依赖兼容问题如果你创建项目时选的是 SpringBoot 3.x但下载的源码或教程是 2.x最常见的问题就是导入第三方 starter 时爆出ClassNotFoundException或者方法签名不兼容。这里我建议新手不要纠结版本适配直接把 SpringBoot 版本降到 2.7.x然后重新mvn clean一次。SpringBoot 2.7 是目前生态最舒服的版本JDK 8 就能跑MySQL 驱动、MyBatis-Plus、Druid 全部完美兼容学完基础再去看 3.x 的新特性完全不迟。另外注意到热词里有“idea 2026 怎么配置 springboot服务 编辑配置数据 比如启动端口”这个问题本质就是修改application.yml里的server.port。IDEA 里如果你改了端口但启动还显示旧端口打开 Run Configuration 看有没有 Environment variables 覆盖配置没有的话大概率是只改了 target 目录之外的源文件没重新编译执行mvn clean compile再启动就好了。5.2 MySQL 8.0 的诡异报错allowPublicKeyRetrieval 与 SSLMySQL 5.7 升到 8.0 之后驱动从com.mysql.jdbc.Driver换成了com.mysql.cj.jdbc.Driver连接参数也变严格了。最典型的报错就是上面表格里的Public Key Retrieval is not allowed这是因为 8.0 默认使用 caching_sha2_password 认证插件第一次连接需要获取服务器的公钥。解决方式有两种一种是在 JDBC URL 里加allowPublicKeyRetrievaltrueuseSSLfalse另一种是把数据库用户改成mysql_native_password认证。前者对项目无侵入推荐优先用。还有一种隐蔽问题是你写了useSSLtrue但本机 MySQL 没配置 SSL 证书Tomcat 启动时会一直打印 SSL 连接警告甚至在某些环境下直接连接超时。我现在的习惯是一律写useSSLfalse开发环境完全够用不要在无关紧要的地方浪费时间。5.3 Vue 打包后刷新 404 的完整排查顺序这个问题我在实际帮人调试时遇到过不止三次排查顺序建议固定下来第一步确认前端用的路由模式是不是history如果是hash模式根本不会有这个问题第二步确认dist目录的文件确实已经复制到static目录第三步确认后端加没加 ViewController 转发。三步走完90% 的 404 都能解决。如果转发了还是 404看看是不是请求路径里带了文件后缀比如/api开头registry.addViewController(/{path:[^\\.]*})这段正则会把带点号的路径排除在外如果你把index.html也拦截了那 Vue 的桥接就失效了。按这个套路排查比在搜索引擎里零散找答案高效得多。5.4 MySQL 在 Windows 上安装和 Docker 失败的通用排查本机装 MySQL 5.7 最常出现的是安装到最后一步服务启动失败原因通常是之前的残留服务占用了 3306 端口或者安装目录路径有中文。看到 MSI 安装器提示“service failed to start”时不用卸载重来先打开服务管理器看 MySQL 服务状态用管理员权限跑一下net start mysql再去看错误日志。道理很简单安装器只是没帮你启动成功不代表服务本身有问题。如果你选择 Docker 方案容器启动失败时不要反复docker run重启先用docker logs mysql看日志。日志里如果是端口冲突改-p 3307:3306映射如果是初始化 SQL 挂了可能是你挂在/docker-entrypoint-initdb.d的脚本里有语法错误。docker 容器日志是一切排查的入口。6. 作为毕设/课设的提分思路与源码阅读顺序6.1 答辩高频问题与答题思路这个项目到答辩环节老师大概率会围绕这几个角度提问我提前列出来你逐个准备系统有哪些角色权限是怎么做的 → 从 user 表 role 字段、登录后 token 携带角色、后端拦截器判断、前端路由守卫四层展开。数据库表之间的关联关系 → 画出 ER 图讲清 category 一对多 garbage_item、user 一对多 recycle_order、recycle_order 与 points_record 的关联。积分扣减为什么用points #{amount}条件 → 讲乐观锁避免并发超扣。首页图表数据怎么来的 → 讲 GROUP BY 聚合查询返回 ListMap 给前端渲染。项目里有哪张表数据量可能最大怎么优化 → 回收订单表、积分流水表讲加索引、分页查询、按时间归档。为什么选前后端分离架构 → 结合开发效率、维护成本、部署方式展开别只说“老师要求的”。每道题你手头都要有一个系统中真实对应的模块做例证不能只背概念。比如问你权限你直接说“Admin 用户登录后会看到一个 用户管理 菜单普通用户看不到这是前端路由守卫做的同时后端接口在拦截器里也判断了角色即使绕过前端直接调接口也会被拦截”——这种答案一听就是自己写过代码的人。6.2 拿到这套源码后的阅读顺序建议源码的阅读顺序和业务开发顺序基本一致。我的建议是先看数据库脚本把表结构关系记住然后看实体类再看 Mapper 接口和 XML理解每个 SQL 在干什么然后看 Service 层的业务逻辑Controller 只需要快速扫一眼每个接口的路径和参数。前端从router配置开始读知道有哪些页面然后逐个页面看如何调用接口。别迷信“从 Controller 入口开始看”因为你没有表结构知识时看 Controller 也是一头雾水。我的经验是先花半小时把数据库表摸透后面的代码阅读会突然变得异常顺畅——所有业务问题到最后都是数据表关系的问题。这条规律适用于任何管理类系统。6.3 如果你还想让项目再多两个亮点基础功能全部跑通后扩展方向非常多但我不建议做太重的扩展。低成本高收益的方向有这么几个一个是给垃圾查询加一个“扫码识别”的入口其实不需要真做图像识别用一个表单承载物品拍照上传后端匹配最接近的垃圾名称返回分类即可另一个是把积分商城加一个简单的兑换记录导出 Excel 功能用 EasyExcel 几行代码就能实现再一个是对系统里的定时任务做说明比如每周统计回收数据如果会一点定时框架可以加上。这些点缀足以让你的项目在一堆纯 CRUD 作品里显得不一样。把自己当成这个系统的用户去走一遍流程从我个人的经验来说调试这套系统的过程价值远大于“把代码跑起来”本身。你会在改 bug 中真正理解 SpringBoot 的自动配置是怎么回事、Vue 的响应式数据为什么这么设计、MySQL 的事务隔离为什么重要——这些东西在课堂上学的时候都是零散的点被一个实际项目串起来之后才会变成真正的能力。最后再分享一个小技巧初始化数据库之后一定要预置十几条常见的垃圾物品数据比如“香蕉皮”对应厨余垃圾、“废电池”对应有害垃圾、“报纸”对应可回收垃圾。演示的时候直接搜这些词界面反馈最快也最不容易出岔子。如果你只是在演示现场临时输入一个冷门物品名既可能匹配不到数据也可能因为输入法切换问题浪费半分钟这种低级失误在答辩现场太常见了。把这套流程完整走一遍你会发现垃圾分类管理系统这个题真的能让你把大学四年学的东西串起来。
返回列表