尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpringBoot+微信小程序垃圾分类系统设计与实现全解析

SpringBoot+微信小程序垃圾分类系统设计与实现全解析 简介这是一套基于Spring Boot的微信垃圾分类小程序完整项目资料包含可运行的前后端代码、毕业论文和答辩PPT适合计算机相关专业学生用于课程设计、毕业设计或小程序开发入门学习。资源共827个文件压缩包约21.28MB其中java文件实现后端接口与业务逻辑vue、wxml、wxss等构成小程序及管理端界面png、svg等提供页面图标素材sql文件包含数据库初始化脚本docx与ppt则为论文与答辩展示内容整体目录结构清晰、类型齐全。目前已有88人学习浏览说明该资料具备一定的参考价值。通过学习可以直接了解Spring Boot与微信小程序的前后端交互方式、垃圾分类功能的模块划分与实现思路同时借助论文和答辩PPT快速梳理项目亮点节省从零搭建和撰写文档的时间适合需要快速上手同类项目或准备答辩的读者。 做这个项目的时候我印象特别深。当时导师给的题目范围比较宽但既要体现技术含量又要有明确的业务场景最后我们几个同学不约而同选了“垃圾分类”这个方向。现在回头看这个选择确实聪明其一垃圾分类本身有清晰的业务逻辑适合做成一个完整的系统其二SpringBoot 微信小程序这个技术组合既有后端管理的深度又有移动端交互的温度正好把全栈开发的各个环节都覆盖到了。这篇博文不打算将官方文档复述一遍而是把这个项目从技术选型、核心代码、数据库设计到论文怎么写、答辩PPT怎么做的完整过程一条线讲透供准备做毕设、或者想快速上手一个完整全栈项目的朋友参考。1. 项目整体与技术选型拆解1.1 为什么是 SpringBoot 微信小程序先聊选型这是每次答辩都会被问到的问题。后端选 SpringBoot理由非常简单直接它把 Spring 生态里那些繁琐的 XML 配置全部自动化掉了一个SpringBootApplication注解就能启动整个应用开发效率比传统的 SSM 框架高出一大截。尤其是做毕设这种周期紧张的项目SpringBoot 的自动装配机制能帮你省掉少则两三天、多则一周的配置时间。而且 SpringBoot 自带 Tomcat打成一个 jar 包就能直接跑部署的时候不用单独装 Tomcat、不用配 Connector对服务器环境的要求极低。前端选微信小程序更多是站在“用户使用场景”的角度考虑。垃圾分类是一个高频但轻量的需求用户不会专门去下载一个 App而是希望在丢垃圾的当下立刻查一下“这个算什么分类”。小程序即用即走、不用安装完美匹配这个场景。另一个原因是从开发成本上看小程序的前后端交互走的是 HTTP 请求和 SpringBoot 的 RESTful API 天然衔接不需要额外处理跨域、不需要考虑 H5 的浏览器兼容性很多 UI 组件官方也直接提供了比如 picker 选择器、button 的 open-type 授权能力能省不少事。当然这套组合也有它的边界。比如小程序端无法直接访问原生手机的摄像头底层能力只能通过wx.chooseMedia调起系统相机而且拿到的图片会经过压缩做图像识别时精度会受一些影响。这些不是致命问题但选型的时候要有心理准备后续的设计也要围绕这些边界做取舍。1.2 整体架构与数据流设计整个系统从逻辑上分成三层小程序展示交互层、后端业务逻辑层、数据存储层。没有过度设计但每一层都职责清晰。小程序端负责的内容有三块用户登录态管理、垃圾分类查询与识别交互、个人中心的信息展示。后端则是一个标准的 SpringBoot 单体应用承担接口服务、业务处理、数据持久化。数据库用了 MySQL缓存部分虽然这个项目的并发量用 Redis 属于“杀鸡用牛刀”但我还是引入了 Redis 做热门垃圾词条的缓存原因很简单一是为了在论文里体现技术深度二是 Redis 处理高频查询确实能明显降低数据库的压力。这个项目运行时的大致数据流是这样的用户在小程序输入“锂电池”或拍照上传小程序把请求发送到后端/api/garbage/query后端先查 Redis 缓存如果命中了就直接返回分类结果如果没有命中再去 MySQL 的垃圾词库表里模糊匹配找到结果后异步回写 Redis。如果是拍照识别则是先把图片上传到本地服务器或云存储拿到 URL 后再调用识别服务最终把分类结果返回给小程序展示。这里有个设计要点无论识别流程多复杂返回给前端的 JSON 结构必须统一我用的固定格式是{code: 200, message: success, data: {category, description, tips}}这样小程序端的代码写起来非常清爽不需要为不同接口做不同解析。1.3 数据库表设计数据库是整个系统的地基地基没打好后面代码写起来就是空中楼阁。我这边一共设计了 6 张核心表没有复杂的关联关系但每张表都对应一个明确的业务场景。user表存储微信用户信息包括 openid、昵称、头像、注册时间。openid 是用户在某个小程序下的唯一标识一定要建唯一索引。garbage表垃圾词库表字段包括自增主键、垃圾名称、分类 ID、别名、回收指引、更新时间。这是系统的核心数据初期需要导入一份完整的垃圾分类数据集我在网上找到一份几十万条的公开数据集后来自己又手工标注补充了两千多条才把分类准确率做到了可用水平。category表分类表对应可回收物、有害垃圾、厨余垃圾、其他垃圾四大类每类附一个图标地址和描述文案。article表垃圾分类科普文章表用于小程序里的“知识科普”栏目。collect_record表用户查询记录表记录每次查询的垃圾名称、查询结果、用户 ID、时间后端可以根据这个表做统计比如最常被查询的垃圾 Top 10。admin表后台管理员的账号表这个项目管理后台直接用了 SpringBoot 的模板引擎渲染页面没有单独再做一套 Vue节省了大量时间。表结构设计里的一个心得是垃圾名称的字段建议设置成varchar(255)并且加上索引但要注意如果直接用LIKE %xxx%查索引是失效的。这里我采用的方案是精确匹配走索引模糊搜索时用前缀匹配LIKE xxx%保证索引生效实在查不到再全表扫一遍做兜底。数据量在十万级以下全表扫描其实也很快但论文里这块可以写得稍微深度一点显得你对数据库索引原理有理解。2. 核心功能设计与关键实现2.1 垃圾识别模块不是简单的“查表”如果只是做一个“输入名称返回分类”的系统那这个项目撑不起一篇合格论文的深度。我在垃圾识别模块上花了很大的心思最终实现的是一套“两段式”识别策略。第一段是关键词匹配。系统内置一份同义词库比如“塑料瓶”“矿泉水瓶”“PET瓶”都会归一化到“塑料瓶”这个标准词再映射到可回收物分类。这样做的好处是覆盖面广、零成本、速度快。第二段是模糊兜底。如果同义词库没有命中后端会使用 MySQL 的全文索引或者简单的编辑距离算法来做相似度匹配找出最接近的几条结果返回给用户让用户自己点击确认。这个设计贴近真实产品的做法——机器识别不了时就把决定权交还给用户而不是硬给一个错误答案。后来我还预留了图像识别接口。实现思路是小程序端上传图片到后端后端调用一个图像分类模型对图片进行预判返回分类结果和置信度。模型部分我直接用了别人训练好的 MobileNet 迁移模型只改了最后几层全连接层在垃圾分类数据集上微调了三十个 epoch准确率大约到了 82%。这个数字对毕设来说完全可以接受而且因为是自己动手微调的模型论文里可以写的内容就很多比如数据集怎么清洗、数据增强怎么做的、训练曲线怎么分析的。需要提醒一下图像识别这个模块如果你不是专门做算法的方向不建议从零开始训练一个深度学习模型既浪费时间硬件条件也不一定跟得上。微调别人预训练好的模型把方案思路写清楚把实验对比做出来对毕设来说已经是很出彩的亮点了。2.2 小程序端页面与交互逻辑小程序端我总共做了五个主要页面首页、识别页、科普页、个人中心、待办提醒页。挑几个有代表性的说说。首页是搜索框 分类快捷入口 热门查询榜单。搜索框聚焦后自动弹出历史查询记录用户点一下就能再次查询这个体验非常顺手。分类快捷入口就是四个圆形图标点击后进入对应分类的垃圾列表页以分页的方式展示每次加载二十条。热门查询榜单的数据来自collect_record表每次查询都会把计数加一然后按倒序取前十这个小功能不仅提升了一些用户的粘性还将整个系统的数据闭环打通了。识别页是整个项目交互最复杂的页面。用户点击“拍照识别”按钮后通过wx.chooseMedia选择拍照或相册图片拿到图片后立即在本地上传我用了wx.uploadFile将图片以multipart/form-data格式 POST 到后端的/api/upload。上传期间页面会显示一个 loading 遮罩后端返回识别结果后识别页会展示分类结果卡片卡片的颜色跟随分类变化可回收物是蓝色、有害垃圾是红色、厨余垃圾是绿色、其他垃圾是灰色颜色体系全小程序统一视觉记忆点很强。登录逻辑值得专门说一下。因为新版微信已经不再提供wx.getUserInfo弹窗授权了直接调获取用户头像昵称的接口会返回默认的灰色头像和“微信用户”四个字。我的方案是首次进入小程序时静默登录——调用wx.login拿到临时 code发给后端换取 openid后端生成一个自定义登录态 token 存到Storage。等到用户想要修改昵称头像时再引导用户主动去点击头像进行修改用wx.chooseAvatar和昵称输入框来实现。既避开了新接口的限制也保证了用户的体验流程顺畅。2.3 后台管理与数据可视化后台管理端我没有单独开发一套前端界面直接用了 SpringBoot 集成 Thymeleaf 模板引擎的方式页面虽然朴素但胜在开发效率极高免去了前后端分离项目联调时处理 CORS 和 token 的麻烦。管理员登录后可以看到几个功能词库维护增删改查垃圾条目和同义词映射、文章发布编辑垃圾分类科普文章并发布、数据概览当天查询量、累计用户数、每日查询趋势图。趋势图我用了 ECharts后端返回最近 14 天的查询数据前端用 AJAX 拉取后渲染成折线图。这个图表不仅是为了好看还有一个隐藏价值论文系统测试章节需要“系统运行效果展示”图表类截图天然比普通表格更有说服力能直观表达“系统具备数据可视化能力”这个结论。3. 实操过程从零搭建一个可运行版本3.1 环境准备与版本匹配避开版本坑版本选型是我反复强调的环节这里栽过跟头的人太多了。SpringBoot 3.x 直接要求 JDK 17而很多高校的教学环境和教材都还停留在 JDK 8如果你照着老教程敲代码很容易出现明明代码没问题、但启动就报错的尴尬局面。我的建议是选 SpringBoot 2.7.18 JDK 8 Maven 3.6.x 这个组合它非常成熟稳定网上资料几乎是遇到什么问题都能搜到答案。微信小程序开发者工具建议直接用最新的稳定版它会提示你使用的基础库版本。这个不必太纠结只要留意真机预览时手机上的微信版本别太老就行。数据库用 MySQL 5.7 或 8.0 都可以我个人推荐 8.0因为 8.0 的默认字符集是 utf8mb4存表情符号不会乱码。不过要注意8.0 的驱动类名改成了com.mysql.cj.jdbc.Driver老教程里写的com.mysql.jdbc.Driver在 8.0 下会启动报错。Redis 在开发阶段可以暂时不用装。后端的缓存代码用CacheManager接口封装了一层本地跑的时候用简单的 HashMap 模拟缓存部署到服务器时再切到 Redis 实现。这个设计的好处是开发阶段少装一个服务论文阶段还能多写一个“缓存策略的接口化设计”一举两得。3.2 小程序端关键代码实现登录流程是核心中的核心我直接贴出核心代码。前端先调用wx.login获取 code然后把这个 code 传到后端换取 openid// app.js 中的静默登录逻辑 wx.login({ success: res { if (res.code) { wx.request({ url: https://your-domain.com/api/user/login, method: POST, data: { code: res.code }, success: loginRes { const { token, userInfo } loginRes.data.data; wx.setStorageSync(token, token); this.globalData.userInfo userInfo; } }); } } });后端对应接收 code 并调用微信接口换取 openidPostMapping(/api/user/login) public Result login(RequestBody LoginRequest request) { // 1. 使用 code 调用微信 code2Session 接口 String url https://api.weixin.qq.com/sns/jscode2session?appid appId secret appSecret js_code request.getCode() grant_typeauthorization_code; String responseText restTemplate.getForObject(url, String.class); JSONObject json JSONObject.parseObject(responseText); String openid json.getString(openid); if (openid null) { return Result.error(登录失败); } // 2. 查库不存在则新注册存在则更新最近登录时间 User user userMapper.selectByOpenid(openid); if (user null) { user User.builder().openid(openid).nickname(微信用户).build(); userMapper.insert(user); } // 3. 生成登录 token 并返回 String token UUID.randomUUID().toString().replace(-, ); cacheManager.set(token, openid, 7 * 24 * 60 * 60); return Result.success(new LoginResponse(token, user)); }有几点要特别说明。第一jscode2session接口只有在真机预览或者已配置 request 合法域名时才能正常调用在开发者工具里需要勾选“不校验合法域名”选项否则会直接报http://... 不在以下 request 合法域名列表中的错误。第二code 只能用一次而且有效期只有五分钟所以不能做缓存。第三code2Session 接口的调用频率有限制如果每次进入小程序都调一次高峰期可能被限流所以我才加了 token 机制避免每次都要往微信服务器发请求。3.3 SpringBoot 后端核心编码后端的主体结构就是一个典型的 Controller-Service-Mapper 三层。Controller 层只做参数接收和结果封装Service 层写业务逻辑Mapper 层用 MyBatis-Plus 操作数据库。MyBatis-Plus 非常推荐它的BaseMapper接口已经把增删改查的方法都内置好了代码量直接少了一半而且它的条件构造器写动态 SQL 很顺手。垃圾查询接口的实现思路大概是这样的Service public class GarbageQueryService { public GarbageResult query(String name) { // 1. 先去缓存查 String cached cacheManager.get(garbage: name); if (cached ! null) { return JSON.parseObject(cached, GarbageResult.class); } // 2. 同义词归一化 String standardName synonymService.normalize(name); // 3. 查词库 LambdaQueryWrapperGarbage wrapper new LambdaQueryWrapper(); wrapper.eq(Garbage::getName, standardName) .or() .likeRight(Garbage::getName, standardName); Garbage garbage garbageMapper.selectOne(wrapper); // 4. 记录查询日志异步处理 collectRecordService.record(name, garbage null ? 未命中 : garbage.getCategoryId()); // 5. 回写缓存 ... } }这里有一个容易被忽略的细节异步记录查询日志。查询日志是需要写入数据库的如果放在主线程里同步执行每一次查询都会多一次数据库写操作在高并发场景下会成为瓶颈。我用的方案是Async注解加上线程池配置让日志写入在后台线程中执行主线程只需要专注于返回查询结果响应时间能快不少。在答辩时提这个点会显得你考虑问题有体系。application.yml里的配置也有讲究。数据源配置一定要加上useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai不然查询中文会出现乱码时间字段也容易差八个小时。文件上传的大小限制默认只有 1MB图片识别场景很容易超限我配成了 10MB但实际测试发现太大图片传到后端再压缩非常慢所以小程序端在上传前用了wx.compressImage把图片压缩到 500KB 以内两边配合才好用。3.4 本地联调与部署要点本地联调时有一个非常实用的技巧小程序开发者工具里可以打开“不校验合法域名、TLS 版本以及 HTTPS 证书”这样后端跑在http://localhost:8080就能直接被小程序访问不需要没完没了地配置 HTTPS。但注意这只适合开发调试真机预览时手机和电脑必须在同一个局域网并且要把localhost换成电脑的局域网 IP否则手机上根本访问不到。部署到线上时小程序端必须在微信公众平台配置 request 合法域名。我的服务器用的是 Nginx 做反向代理把 80/443 端口的请求转发到 SpringBoot 的 8080 端口然后在公众平台填上自己备案过的域名。这里还有个容易漏掉的坑小程序要求 request 合法域名必须是 HTTPS所以要提前去申请免费的 SSL 证书比如各种云服务商提供的免费证书就够用了。HTTPS 配置好之后用curl https://your-domain.com/api/ping做一次自测返回 JSON 就说明 Nginx 和证书都正常。部署这件事千万不要等到最后一天才开始做因为 HTTPS 证书的申请审核、小程序审核发布都有时间周期提前一两周把域名、证书、服务器都准备好后面还有充足的时间调试真机上遇到的问题。4. 常见问题与排查技巧实录4.1 小程序端获取不到用户信息这个坑几乎所有小程序开发者都踩过。微信从基础库 2.10.4 开始调整用户授权策略老的wx.getUserInfo不再弹出授权窗口直接调用只会返回默认数据。如果你去看一些稍早的教程还会教你把button open-typegetUserInfo当成标准做法实际现在早就失效了。我的对策前面讲过静默登录拿 openid 加 token用户头像昵称改为手动填写。如果你确实需要预填用户信息可以考虑用微信的「头像昵称填写能力」也就是button open-typechooseAvatar和input typenickname。这个方法受官方支持而且安全合规不用走任何审核申诉流程。4.2 小程序无法打开公众号文章这个问题的原因是公众号的文章链接域名没有配置到小程序的业务域名里。注意不是 request 合法域名而是单独的“业务域名”。配置路径是微信公众平台 → 开发管理 → 开发设置 → 业务域名。添加时需要下载一个校验文件放到该域名根目录下微信会去读取校验。校验文件只能部署在 HTTPS 域名根目录而且不能放在 Nginx 的子目录下具体操作是把这个文件放到/usr/share/nginx/html/.well-known/或者对应的 web 根目录里确保通过https://your-domain.com/校验文件名能直接访问到就能通过了。4.3 SpringBoot 版本太高导致启动失败这个问题在我的读者群里被问过不下二十次。现象是新建项目时选择了 Spring Boot 3.2.x然后导入 JDK 8 的项目启动直接报UnsupportedClassVersionError或者IllegalArgumentException: Unsupported class file major version。原因很直白Spring Boot 3.x 的字节码版本是 Java 17JDK 8 根本解析不了。还有一个隐藏比较深的坑Spring Boot 3.x 把很多自动配置类的包结构从org.springframework.boot调整成了org.springframework.boot.autoconfigure的新位置一些老版本第三方组件比如某些 MyBatis 插件、代码生成器在 3.x 下会直接ClassNotFoundException。所以结论很简单做毕设的、或者项目对 Java 版本没有硬性要求的统一用 Spring Boot 2.7.x稳如老狗能省下大把排查问题的时间。4.4 服务端接口偶发超时这个问题排查了很久。现象是请求量一大部分接口会偶发超时查看日志发现是数据库连接池的连接被占满。原因是 MySQL 的默认连接数上限是 151而 SpringBoot 的 HikariCP 默认池大小为 10按理说不至于占满。后来发现是代码里有个动态查询漏了关闭链接导致连接泄漏最终拖垮了连接池。解决办法有两个层面第一是代码层面所有查询都通过 MyBatis-Plus 管理不要自己写 JDBC 原生代码第二是在配置里加上连接池的保活和检测参数spring: datasource: hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000此外我在 controller 层加了一个全局异常处理器统一捕获超时和连接异常返回友好的错误信息前端可以提示用户“服务繁忙请稍后再试”而不是长时间白屏等待。5. 论文写作与答辩 PPT 的实战思路5.1 论文结构怎么组织才能得高分选题定了“基于 SpringBoot 的垃圾分类微信小程序的设计与实现”论文的结构就非常清晰几乎是标准的三段式绪论、设计实现、测试总结。但很多同学写设计实现时容易犯一个错——把代码从头到尾贴一遍这是大忌。论文不是代码展示而是“你要解决问题你的方案是什么你为什么这么设计”。我的建议是第二章相关技术用两到三页介绍 SpringBoot、微信小程序、MySQL、Redis 即可别抄官网介绍每段话结合本项目说明“为什么用它”。第三章需求分析把用户分成普通用户和管理员画出用例图列清楚功能性需求和非功能性需求。第四章系统设计重点展示总体架构图、功能模块图、数据库 ER 图和表结构说明这个部分要是能画出一张漂亮的架构图论文整体观感会提升很多。第五章系统实现按照登录模块、查询模块、识别模块、后台管理模块来组织每个模块先放运行截图再讲实现思路引用关键代码但记得代码要剪裁只放核心逻辑不要贴全套。第六章测试一定要写系统性的测试过程。很多同学用“我打开小程序试了一下能查到结果”来糊弄这个在答辩时很容易被老师追问。正确做法是先写测试环境再写功能测试用例表每条用例包含输入、操作步骤、预期结果、实际结果最后是你修了哪些 Bug、怎么修的。这个部分写好了答辩老师基本就不会再挑刺了。5.2 答辩 PPT 的页面设计与讲解节奏答辩 PPT 不要做成一个文章大纲的搬运也不要每页堆一整墙文字。真正好的答辩 PPT 应该像一份产品介绍核心是让评委在十五分钟内看懂你做了什么、怎么做的、有什么亮点。我建议 PPT 控制在 18 页左右封面 1 页项目背景和意义 2 页技术栈 1 页系统架构 1 页数据库设计 2 页核心功能原理 3 页功能演示截图 5 页系统测试总结 2 页总结与展望 1 页。每页的字数控制在 80 字以内核心概念用关键词加粗需要展示代码的地方每页只放 10-15 行选最核心的那段即可。讲解节奏是前 4 分钟讲背景、技术选型和架构设计中间 6 分钟演示功能从用户搜索到后台管理都要点一遍最后 3 分钟讲你的亮点和创新点比如图像识别、缓存策略、异步日志、同义词归一化这些哪里是老师在论文里能看到的亮点一定要在答辩时主动指出来不要等着老师问。5.3 答辩高频问题与应对策略答辩时老师问到概率最高的几个问题我提前整理了一份提纲这里分享给你们参考。第一个问题是“为什么选这个题目”。不要只答“垃圾分类有意义”要往深了说通过小程序解决用户分类查询的真实痛点同时系统覆盖了前后端、数据库、部署上线全流程是对大学所学知识的综合应用。第二个问题是“系统有哪些不足”。这个要提前想好。我当时的回答是目前的图像识别准确率还有提升空间知识库覆盖度也需要持续扩充未来可以考虑引入更强大的模型和自动更新机制。承认不足是正常的关键是要跟上“未来如何改进”的答案绝不能答“没有不足”。第三个高频问题会追问到技术细节比如“为什么用 Redis 做缓存”“数据库的索引怎么设计的”“小程序登录流程和传统 Web 登录有什么区别”。这些内容正好都分布在前面的章节里说明你在做项目的过程中有自己的思考而不是只会照着教程敲代码。最后一个容易忽略的点提前准备好一句话总结你的系统基于 SpringBoot 搭建高复用后台服务借助微信小程序解决垃圾分类查询与服务触达问题通过同义词归一化和图像识别极大优化了查询体验。这句话用在自己的开场白和总结里可以让整个答辩都更有条理。最后再分享一点我个人实际做项目的体会。整个项目从零到一最难的不是某一段代码写不出来而是如何把所有零散的技术点像串珠子一样串成一个完整的系统。SpringBoot 负责业务逻辑和数据持久化微信小程序负责触达用户Redis 缓存负责加速每一个环节都有它存在的理由这些理由就是你论文和答辩最好的素材。如果你正准备做类似方向的项目我的建议是不要一上来就写代码先把整体架构、表结构、接口文档梳理清楚后面写代码的速度会让你惊讶。做技术项目最重要的是有自己的思考闭环而这篇博文希望已经成为你思考起点的一部分。本文还有配套的精品资源点击获取
返回列表