资讯动态

SSM后端+微信小程序:社区垃圾回收管理系统全栈实战教程

发布时间:2026/9/26 5:26:02 来源:尧图企业网站定制
简介一套基于微信小程序的社区垃圾回收管理系统SSM后端毕业设计源码案例面向计算机专业毕业生、课程设计学习者及微信小程序/后端开发爱好者。系统涵盖用户管理、垃圾回收请求提交、垃圾分类指导、任务分配、进度跟踪与数据统计等核心功能并通过微信小程序与后端SSM框架的集成演示了完整的业务交互流程。资源共916个文件以java、vue、js、xml、sql等代码与配置为主辅以png/svg界面素材、mp4演示视频及docx说明文档压缩包整体58.9MB结构清晰便于按模块查阅。压缩包内附完整源码、数据库文件、演示视频、使用说明及环境安装说明并包含安装运行脚本与备份配置等细节项目经严格调试可稳定运行可直接用于毕业设计、课程设计或期末大作业。目前已有53人学习下载适合希望深入理解SSM框架实战、微信小程序前后端联调及数据库设计的读者。1. 社区垃圾回收管理系统一个能把毕业设计讲圆的全栈闭环每到毕设季最怕的就是选题听起来很大、做出来很空。基于微信小程序的社区垃圾回收管理系统恰好相反业务足够接地气——居民预约回收、回收员上门称重、后台审核积分三个角色三条链路每一环都能在数据库里找到对应记录答辩时老师问“数据怎么流转”你可以从微信小程序一路讲到 MySQL 表。这正是这套 SSM 后端源码案例的价值它不是单页增删改查 demo而是一条能真实跑通的业务闭环。标题里的“ssm 后端”指的是 Spring SpringMVC MyBatis 这套经典 Java 组合搭配微信开发者工具编写的小程序前端再加上一份初始化数据库脚本。适合两类人一是选 Java 课设或毕设题、需要完整可运行项目打底的学生二是想搞懂小程序与 Java 后端如何联调的入门开发者。读完这篇你应该能做到把 ZIP 里的源码在本地跑起来同时能讲清楚每个核心接口背后的表结构和状态变化。2. 技术架构拆解SSM 后端 微信小程序为什么是毕设最稳的前后端分离组合2.1 SSM 三层结构Controller 不做业务、Service 管事务、Mapper 只查数据很多人一看到 SSM 就说“过时了”但放在毕业设计这个场景里它的价值恰恰是“配置看得见、分层讲得清”。Spring Boot 一个注解把 Tomcat、数据源、MyBatis 全自动装配好答辩时老师问“Tomcat 怎么加载你的应用”“事务加在哪一层”你反而答不上来传统 SSM 的配置是显式的web.xml里注册 DispatcherServletspring-mvc.xml里开启注解驱动mybatis-config.xml里配 mapper 扫描。每一行配置都能对应一个面试考点这是它适合作为毕设框架的核心原因。分层约定比框架本身更重要。我一般会这样拆Controller 只接收参数、调用 Service、封装返回值不写 SQL、不写业务判断Service 层处理业务规则并用Transactional管事务Mapper 层只做数据库读写。以“创建回收订单”为例三层的接口签名分别是// Controller只做参数接收和结果返回 RestController RequestMapping(/api/order) public class OrderController { Autowired private OrderService orderService; PostMapping(/create) public Result create(RequestBody RecycleOrder order) { // 小程序端传 JSON这里直接绑定到实体 return Result.success(orderService.createOrder(order)); } }// Service业务规则都在这里比如校验地址、生成订单号 Service public class OrderServiceImpl implements OrderService { Autowired private OrderMapper orderMapper; Override Transactional(rollbackFor Exception.class) public RecycleOrder createOrder(RecycleOrder order) { order.setOrderNo(generateOrderNo()); order.setStatus(0); // 0待接单 order.setCreateTime(new Date()); orderMapper.insert(order); return order; } }// Mapper一个接口方法对应一条 SQL public interface OrderMapper { int insert(RecycleOrder order); RecycleOrder selectByOrderNo(String orderNo); }这里的核心逻辑是Controller 里不要写order.setStatus(0)这类业务初始化一旦多个入口都要创建订单规则就散落了。把“新订单默认待接单”收拢到 Service后续加“预约时间段校验”“同一用户未完成订单限制”都只改一处。参数上注意RequestBody要求小程序端Content-Type必须为application/json如果前端用application/x-www-form-urlencoded提交这里会直接 415这是联调时第一个容易翻车的地方。2.2 数据库表设计社区回收业务的 6 张核心表与关键字段做毕设最忌讳一上来就写代码先把表设计出来接口基本就定了一半。一个能支撑答辩的垃圾回收系统最少需要下面这 6 张表它们的依赖关系从用户到订单再到积分流水恰好覆盖三条角色链路表名作用关键字段user居民/回收员/管理员统一用户表user_id, openid, nickname, role, phone, pointsrecycle_category可回收物分类纸类/塑料/金属等category_id, name, unit_price每公斤积分recycle_order回收订单主表order_id, order_no, user_id, category_id, weight, status, address, create_timeorder_assign回收员接单记录assign_id, order_id, recycler_id, assign_timepoints_record积分流水表每次变动一条记录record_id, user_id, order_id, change_value, change_type, create_timepoints_goods积分兑换商品goods_id, name, points_required, stock其中最关键的是recycle_order.status字段我把订单状态设计成0 待接单 / 1 已接单 / 2 已上门 / 3 已完成 / 4 已取消。什么叫“讲得清数据库设计”就是你能说清楚为什么weight允许为 null——因为用户下单时只是预约、并不知道重量weight要等回收员上门称重后回填如果你把它设置为 NOT NULL预约单根本插不进去。这类细节答辩老师一听就知道是真正跑过流程的。建表 SQL 我用 InnoDB 引擎和 utf8mb4 字符集这是社区回收系统两个必须注意的点InnoDB 保证事务里“扣积分 写流水”要么全成功要么全失败utf8mb4 是因为小程序端用户昵称可能带 Emoji用 utf8 会直接报Incorrect string valueCREATE TABLE recycle_order ( order_id INT NOT NULL AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL COMMENT 订单编号唯一, user_id INT NOT NULL COMMENT 下单居民, category_id INT NOT NULL COMMENT 回收分类, weight DECIMAL(10,2) DEFAULT NULL COMMENT 称重公斤数接单后回填, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待接单 1已接单 2已上门 3已完成 4已取消, address VARCHAR(255) NOT NULL COMMENT 上门回收地址, create_time DATETIME NOT NULL, PRIMARY KEY (order_id), UNIQUE KEY uk_order_no (order_no), KEY idx_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;建表时要顺手把索引加上order_no要唯一所以建唯一索引user_id高频查询所以建普通索引。常见误用是只在order_id主键上建索引随着测试数据量变大按用户查订单会越来越慢。另外注意 MyBatis 的驼峰映射问题表字段create_time映射到 Java 属性createTime需要在applicationContext.xml里开启mapUnderscoreToCamelCase否则查询出来createTime永远是 null。2.3 接口契约小程序 wx.request 与后端 JSON 的统一返回格式微信小程序端不像 Web 前端有 axios 拦截器它的网络请求基础方法就是wx.request所以接口返回格式必须统一否则前端写起来会非常痛苦。我这里的约定是后端所有接口都返回同一个 JSON 结构code表示业务状态码200 成功、401 未登录、500 异常msg给人看的提示信息data放真正的数据。小程序端封装如下// utils/request.js — 小程序端统一请求封装 const BASE_URL http://127.0.0.1:8080/recycle; function request(path, method, data, needLogin true) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method: method || GET, data: data || {}, header: { Content-Type: application/json, token: wx.getStorageSync(token) || }, success: (res) { const body res.data; if (body.code 200) { resolve(body.data); } else if (body.code 401) { // token 过期跳登录页 wx.navigateTo({ url: /pages/login/login }); reject(body); } else { wx.showToast({ title: body.msg || 请求失败, icon: none }); reject(body); } }, fail: (err) reject(err) }); }); }这段封装解决了三个实际问题第一每个页面不用重复写wx.request的完整参数第二正确把 token 加到请求头后端拦截器只认这个字段第三把业务错误统一弹 toast而不是每个页面各自处理。参数上我会特别强调BASE_URL里的/recycle是后端项目的上下文路径它由 IDEA 部署时的Application context决定很多联调失败都出在这个路径对不上。后端对应的统一返回对象也很简单不需要引入第三方库public class Result { private Integer code; private String msg; private Object data; public static Result success(Object data) { Result r new Result(); r.code 200; r.msg success; r.data data; return r; } // getter/setter 省略 }这里有个细节Result必须提供无参构造和 getter否则 Jackson 在序列化时会报No serializer found。另外接口返回不要直接return orderMapper.selectByOrderNo(...)一旦后期要加个字段、隐藏某些敏感数据直接返回实体类会很被动。包一层Result的成本极低但职责边界清晰得多。2.4 角色与权限居民、回收员、管理员的三条操作链路同一个user表通过role字段区分三种角色比单独建三张表更符合小型系统的实际做法。居民端看到的是“我要卖废品”发布回收预约、查看订单状态、查积分、兑换商品回收员端看到的是“我要接单”待接单列表、上门称重录入、订单完成管理员端则是“我要管理”用户列表、订单总览、分类价格维护。权限控制在后端做而不是靠前端隐藏按钮。这里用最基础的拦截器方案定义一个LoginInterceptor拦截/api/**从请求头取 token查数据库拿到用户角色存到ThreadLocal或 request 属性里。然后对/api/admin/**接口单独判断role 2不是管理员直接返回 403。小程序端隐藏入口只是用户体验真正的权限边界必须在后端守死这个意识在答辩时值很多分。3. 从 ZIP 解压到小程序真机预览SSM 项目的完整启动清单3.1 环境版本怎么对齐JDK、Maven、Tomcat、MySQL、微信开发者工具拿到标题里的源码包后第一件事不是打开 IDEA 就点运行而是先检查环境。SSM 项目对版本敏感JDK 版本不匹配是最常见的启动失败原因。我建议按这套基准来配JDK 8绝大多数毕设源码基于 8 编写用 11 或 17 大概率碰到旧库不兼容、Maven 3.6 以上、Tomcat 8.5 或 9、MySQL 5.7不要一上来用 MySQL 8如果源码里的驱动是com.mysql.jdbc.DriverMySQL 8 下会直接启动报错需要换成com.mysql.cj.jdbc.Driver、微信开发者工具最新稳定版。具体版本以解压后pom.xml里实际声明的依赖为准不要盲目升级。比如pom.xml里写的是mysql-connector-java 5.1.47你本地装 MySQL 8 还能连但必须把驱动类名改掉否则连接池初始化必然失败。先看文件再动手能省掉一整晚排查时间。3.2 导入数据库SQL 脚本执行与 jdbc.properties 连接配置修改源码包里一般会有一个.sql文件这是整个系统的数据基础必须先导入。不要用 Navicat 图形界面直接双击执行命令行执行能让你更清楚看到报错信息# 登录 MySQLroot 密码按你本地实际填写 mysql -u root -p123456 # 在 MySQL 命令行内创建数据库注意字符集 mysql CREATE DATABASE IF NOT EXISTS recycle DEFAULT CHARSET utf8mb4; mysql USE recycle; mysql SOURCE D:/path/to/recycle.sql;导入完成后验证一下SHOW TABLES;应该能看到 6 张以上业务表SELECT * FROM user;应该能看到测试账号。这里有一个高频翻车点如果你手动在 Navicat 里新建数据库时选了utf8而 SQL 文件里某些表的注释或测试数据带 Emojisource 导入会中断。所以建库语句尽量用上面这段指定 utf8mb4。后端连接数据库的配置在src/main/resources/jdbc.properties文件里核心改两处数据库密码和连接串参数jdbc.drivercom.mysql.jdbc.Driver jdbc.urljdbc:mysql://127.0.0.1:3306/recycle?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai jdbc.usernameroot jdbc.password123456characterEncodingutf8控制中文写入不乱码serverTimezone必须有否则 MySQL 8 和 JDK 8 配合时会报The server time zone value的时区错误。如果你的 MySQL 是 8.0把jdbc.driver换成com.mysql.cj.jdbc.Driver。改完配置后重新 Maven 编译保证target/classes/jdbc.properties被刷新IDEA 里直接改源文件不代表编译产物已更新。3.3 启动后端IDEA 打包部署 Tomcat 的两种方法SSM 项目的启动方式跟 Spring Boot 的main方法不一样它必须丢进 Tomcat 才能跑。我推荐两种方法任选其一即可方法一是 Maven 打包后部署到本地 Tomcat 的 webapps 目录# 在项目根目录执行跳过测试减少时间 mvn clean package -DskipTests # 把生成的 war 包复制到 Tomcat webapps 目录 cp target/recycle.war D:/apache-tomcat-9.0.65/webapps/ # 启动 Tomcat cd D:/apache-tomcat-9.0.65/bin startup.bat方法二是在 IDEA 里配置 Tomcat ServerRun→Edit Configurations→ 点加号选 Tomcat Server Local在Deployment选项卡把 war exploded 添加进去Application context填/recycle然后直接点运行。方法二适合调试改代码后重新 build 即可热更新方法一适合答辩前最终环境验证两个都建议会。启动成功的标志不是 Tomcat 弹窗而是日志里出现INFO: Server startup in xxx ms。如果启动过程中报NoClassDefFoundError或ClassNotFoundException优先怀疑依赖没下载完全执行mvn clean idea:idea重新生成 IDEA 工程文件。另外注意 IDAEIntelliJ IDEA自带的 Tomcat 集成有时会把Application context默认写成/recycle_war_exploded小程序端 BASE_URL 如果写成/recycle接口会全部 404统一改一边即可。3.4 小程序端联调合法域名、不校验、IP 与端口的三处配置后端跑起来后用微信开发者工具导入小程序端代码目录。导入后的第一步不是看页面而是改请求地址。开发者工具默认的安全策略会拦截http://127.0.0.1:8080这类请求报错信息是url not in domain list。开发阶段的解法是右上角详情→本地设置→ 勾选不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书。如果你在开发者工具模拟器里能用、但手机预览一片空白那就是第二处配置的问题真机上的127.0.0.1指向手机自己而不是你的电脑。改法是把request.js里的 BASE_URL 换成电脑的局域网 IP比如http://192.168.1.100:8080/recycle手机和电脑连同一个 WiFi 才能访问。第三处是 Tomcat 必须监听所有网卡而不是只监听本机回环检查 Tomcatconf/server.xml里的 Connector 配置Connector port8080 protocolHTTP/1.1 connectionTimeout20000 redirectPort8443 address0.0.0.0/address0.0.0.0表示监听所有网卡如果不写这个参数某些 Tomcat 发行版默认只允许本机访问手机自然连不上。改完重启 Tomcat在小程序端重新编译预览看到订单列表接口返回数据就说明链路通了。4. 把核心业务串起来登录鉴权、回收订单状态机与积分计算4.1 登录鉴权wx.login 换 openid后端签发 token微信小程序的登录体系不能套用传统的用户名密码。常规做法是小程序端调用wx.login拿到临时code把 code 发给后端后端拿着 code 调用微信接口换取openid用 openid 作为用户唯一标识去user表查找查不到就自动注册一个新用户然后生成 token 返回给前端。毕设项目里微信接口调用可能受限于没有正式 AppID我建议用测试号或者直接简化成“前端传模拟 openid”但代码结构要预留真实接口的位置RestController RequestMapping(/api/auth) public class AuthController { Autowired private UserService userService; PostMapping(/login) public Result login(RequestBody LoginRequest req) { // req.getCode() 来自 wx.login真实场景下后端用 code 换 openid // 开发阶段可以直接把 code 当作测试标识或传 mockOpenId String openid userService.exchangeOpenId(req.getCode()); User user userService.findOrCreateByOpenid(openid); String token userService.createToken(user.getUserId()); return Result.success(new LoginResponse(token, user)); } }token 的生成不需要引入 JWT 这种重东西一个UUID.randomUUID().toString()就够然后存到user_token表里user_id、token、expire_time。每次请求携带 token 时后端查表看是否存在且未过期。这样做的好处是管理员封禁用户时可以直接删 token 记录用户立刻失效比无状态 JWT 更好控制答辩讲“踢人下线”时也更有底气。4.2 回收订单状态机从“待接单”到“已完成”的闭环回收订单最忌讳直接 UPDATEstatus字段。如果前端传入什么就改什么用户可以手动把订单改成已完成积分系统就崩了。正确做法是写一个状态机只允许合法的状态迁移路径public class OrderStatusMachine { // 定义允许的状态流转当前状态 - 可到达状态 public static boolean canTransit(int current, int target) { switch (current) { case 0: // 待接单 return target 1 || target 4; // 可接单或取消 case 1: // 已接单 return target 2 || target 4; // 可上门或取消 case 2: // 已上门 return target 3; // 称重后完成 default: // 已完成或已取消为终态不可再动 return false; } } }配合状态机的使用方式是更新前先查当前状态调用canTransit校验通过后再执行UPDATE recycle_order SET status #{target} WHERE order_id #{id} AND status #{current}。这里的 WHERE 条件里带上status #{current}是关键它保证在并发场景下两个请求不会同时把同一订单从同一种状态改到不同状态。受影响行数为 0 说明状态已被别人改过直接提示“订单状态已更新请刷新页面”。这个设计在答辩演示时也非常好讲打开数据库手动执行一条UPDATE recycle_order SET status 3 WHERE order_id 1再用小程序端操作这个订单系统会拒绝非法流转。这就是“业务规则落在后端而不是前端”的实证。4.3 积分与兑换最容易重复发放的两个典型坑积分系统是这套代码里业务价值最高的部分也是最容易出 bug 的地方。第一个坑是重复发放回收员点击“完成订单”时如果代码写成先加积分再改状态接口超时导致前端重试一次用户积分就被加了两次。解决方式是把积分发放放到与状态更新同一个事务里并且先更新状态再写流水Service public class PointsServiceImpl implements PointsService { Override Transactional(rollbackFor Exception.class) public void settleOrder(RecycleOrder order) { // 1. 乐观锁更新状态返回 0 说明订单已处理过 int rows orderMapper.completeOrder(order.getOrderId()); if (rows 0) { throw new BizException(订单已完成请勿重复操作); } // 2. 计算积分重量(kg) * 分类单价 int points calculatePoints(order); // 3. 插入积分流水 更新用户积分总额两条写操作在同一事务 pointsRecordMapper.insert(new PointsRecord(order.getUserId(), order.getOrderId(), points)); userMapper.increasePoints(order.getUserId(), points); } }第二个坑是积分流水的唯一性没有约束。points_record表里要建一个唯一索引uk_order_id(order_id)一个订单只能产生一条积分流水。就算事务写漏了、代码逻辑被并发穿透数据库层面的唯一索引也能兜底。我自己的习惯是凡是涉及钱的字段积分本质上是平台负债必须在代码和数据库两层设防只靠一层总有翻车的一天。4.4 后端跨域与响应格式的细节管理端 Web 页面也需要复用接口有些毕设会额外做一个 Web 管理端Vue 或 JSP来管理分类和订单这时候就要处理跨域问题。小程序端因为不是浏览器环境wx.request没有同源策略限制所以不存在跨域但浏览器里的管理端访问http://localhost:8080/api/**时端口不同就属于跨域。常见做法是在后端加一个全局 CORS 过滤器Component public class CorsFilter implements Filter { Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response (HttpServletResponse) res; response.setHeader(Access-Control-Allow-Origin, *); response.setHeader(Access-Control-Allow-Methods, GET, POST, PUT, DELETE, OPTIONS); response.setHeader(Access-Control-Allow-Headers, Content-Type, token); chain.doFilter(req, res); } }注意Access-Control-Allow-Headers里必须包含token否则小程序端自定义的请求头会被浏览器拦截。如果管理端需要携带 cookie 做会话管理Allow-Origin就不能写*要写具体域名并加上Access-Control-Allow-Credentials: true。这块细节很多人忽略等到联调 Vue 管理端时才踩进去。5. 微信小程序 SSM 联调避坑毕业答辩现场必查 5 个高频问题5.1 现象小程序报url not in domain list或ERR_CERT_COMMON_NAME_INVALID这个报错基本每个用本地后端联调的毕设都会遇到。url not in domain list是因为微信开发者工具默认校验 request 合法域名本地 IP 不在白名单ERR_CERT_COMMON_NAME_INVALID则将域名指向了 HTTPS 证书问题最常见于你配置了某个域名但证书域名不匹配。原因微信小程序线上环境要求所有请求域名必须是 HTTPS 且在后台配置过合法域名而本地开发没有这个条件。解决开发者工具里点右上角详情→本地设置→ 勾选不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书。如果你在做线上演示需要在小程序管理后台把后端接口域名加入 request 合法域名并且域名必须备案且配置有效 SSL 证书。答辩演示现场请优先用开发者工具模拟器不要赌真机网络。5.2 现象后端启动成功调用接口报Invalid bound statement (not found)这个报错是 SSM 项目特有的“黑匣子”问题接口类方法存在但 MyBatis 找不到对应的 SQL 映射文件。最常见的原因是 IDEA 在 Maven 构建时没有把src/main/resources/mapper/目录下的 XML 文件复制到target/classes。你打开target/classes/mapper看一眼如果目录为空或没有对应 XML就是这个原因。解决在pom.xml里显式声明 resource 目录让 Maven 把 xml 文件也当作资源打包build resources resource directorysrc/main/java/directory includes include**/*.xml/include /includes /resource resource directorysrc/main/resources/directory /resource /resources /build改完执行mvn clean package -DskipTests重新编译确认target/classes下出现 mapper XML 再重启。另一个容易被忽略的原因是mybatis-config.xml里的 mapper 扫描路径写错比如包名多写了一个.mapper同样报这个错。排查时先看编译产物、再看扫描配置别上来就怀疑代码逻辑。5.3 现象数据库存进去的中文变成???中文乱码是 SSM MySQL 的经典养老问题出现位置不同原因完全不同。如果你往recycle_order插入“废纸回收”后查出来是问号先执行SHOW CREATE TABLE recycle_order看表字符集不是 utf8mb4 就删表重建如果表没问题检查jdbc.properties的 URL 里有没有characterEncodingutf8都检查完还是乱码最后排查 IDEA 的控制台输出编码和 HTTP 请求编码。解决乱码按这个顺序执行最快第一步把jdbc.url的参数补全为useUnicodetruecharacterEncodingutf8useSSLfalse第二步确认建表 SQL 里每个表都显式写了DEFAULT CHARSETutf8mb4不要依赖 MySQL 全局默认第三步在 Spring MVC 配置里加一个 CharacterEncodingFilter强制请求和响应都使用 UTF-8。注意 XML 里写要转义成amp;直接写characterEncodingutf8useSSL会导致 XML 解析失败。5.4 现象模拟器一切正常手机真机预览时接口请求全部失败这种情况在答辩前一周出现最让人焦虑开发者工具模拟器里订单列表正常加载换成真机预览就白屏或一直 loading。原因一句话解释真机上的127.0.0.1是手机自己不是你的电脑。BASE_URL 里的本机地址到真机上就是错误的。解决把utils/request.js的 BASE_URL 改成电脑在局域网内的 IPIPv4 地址可在命令行执行ipconfigWindows或ifconfigmacOS查到。手机和电脑连同一个 WiFi 后访问http://192.168.x.x:8080/recycle测试一下能通再编译小程序真机预览。特别注意 Windows 防火墙可能拦截 8080 端口入站请求要到高级安全 Windows Defender 防火墙里为 Tomcat 添加入站规则这一步是玄学中的常见真凶我毕业那年就卡在这上面整整一天。手机端记得勾选开发者工具工具栏里的“真机调试”它会自动做端口转发可以让局域网的问题少一些。5.5 现象接口返回 404 或 405小程序端提示“request:fail”接口能通但状态码不对先分清是后端没路由还是前端请求方式不对。404 先去浏览器地址栏直接访问http://127.0.0.1:8080/recycle/api/order/list如果浏览器也 404说明后端上下文路径或 Controller 的 RequestMapping 不匹配检查 IDEA 部署配置里的 Application context。如果浏览器能访问但小程序 404基本是 BASE_URL 路径拼错。405 则几乎一定是前端请求方法和后端定义不一致前端用 POST后端GetMapping前端 GET后端PostMapping改一边即可。另一个隐蔽问题是ResponseBody注解缺失。在旧版本 SpringMVC 里Controller 方法如果没加ResponseBody返回的对象会被视图解析器当逻辑视图名去找 JSP 页面结果就是返回 404 或者 HTML 结构而非 JSON。现在项目如果用了RestController就没这个问题但如果是类上写Controller、方法上没加ResponseBody接口必然出问题。排查时先点开 Controller 类看整体注解再逐一核对方法和前端请求参数。6. 给答辩加分的进阶验证接口留痕、统计接口与演示节奏设计6.1 用 Postman 整理接口测试用例导出 JSON 提交存档答辩时不要只演示小程序界面老师更想看的是后端是否“有接口、有逻辑”。用 Postman 把核心接口整理成一套可复跑用例按顺序创建登录、创建回收订单、接单、完成订单、积分查询五个请求。每请求设置好 Headers 里的 token、Body 的 JSON 数据并把断言写进 Tests 标签。这套用例能在答辩现场直接重放证明系统不是页面截图而是真实服务。关键做法创建订单接口前置脚本里用登录接口返回的 token 作为全局变量后续请求自动引用。6.2 加一个“近 7 日回收量统计”接口30 行代码提升系统厚度垃圾分类回收管理系统如果只有增删改查答辩深度不够。可以给管理端加一个统计接口按天统计已完成订单的总重量。SQL 写好后端对应加一个统计 Mapper 即可SELECT DATE(create_time) AS stat_date, COUNT(*) AS order_count, IFNULL(SUM(weight), 0) AS total_weight FROM recycle_order WHERE status 3 AND create_time DATE_SUB(CURDATE(), INTERVAL 7 DAY) GROUP BY DATE(create_time) ORDER BY stat_date;这个 SQL 返回 7 行数据小程序管理端或 Web 端用 ECharts 画一张折线图系统从“数据录入工具”变成“能辅助决策的管理系统”答辩时展示的维度完全不一样。注意status 3只统计已完成的订单避免把已取消的订单也算进回收量。6.3 演示脚本节奏先业务、再数据、后接口见过太多答辩翻车现场一上来打开小程序点来点去老师不知道你在做什么你也不知道下一步碰哪个按钮。建议按三段式演示第一阶段用小程序端完成“发布回收预约”这一完整动作等后端日志打印出 SQL 时顺势说“数据已经写进数据库”第二阶段切换到 Navicat 或 MySQL 命令行执行SELECT * FROM recycle_order ORDER BY create_time DESC展示新插入的记录同时强调状态字段是 0待接单第三阶段用 Postman 重放一次接单接口展示 payload 和响应再把数据库刷新给老师看状态变成 1。前中后三条链路串起来老师很容易跟上你的思路。演示前把测试数据清理干净、把数据库密码改成好输入的短密码、把 Tomcat 停止脚本的路径抄在手机备忘录里这些都是现场不可控因素的后悔药。我第一次跑这类 SSM 毕设项目时在 MyBatis 的 mapper XML 没被打进 target 目录这个坑里卡了一整个下午项目跑通后我把这个排查顺序记成了习惯先看编译产物再看配置文件最后才怀疑代码。希望你拿到这套源码后把更多的精力花在理解工作流程、补一个属于自己的统计功能上而不是夜里十一点对着报错日志发呆。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑