简介:面向高校计算机专业毕业设计需求,这份学生资助在线管理小程序资源基于微信小程序与SSM框架开发,系统区分管理员、班主任、家长三类角色,覆盖公告发布、资助申请、评议审核、名单公示、申请复议等业务环节。家长在微信小程序端注册登录并提交资助申请,班主任审核,管理员通过Java后台处理数据,MySQL存储,前后端以JSON交互。包内共1036个文件,压缩包约72.16MB,包含Java源码、Vue页面、微信小程序前端文件(wxml/wxss/js)、SQL脚本、毕业论文文档、演示视频、安装运行批处理脚本,以及图片图标、XML配置、CSS样式等资源,目录结构清晰。已有137人学习下载,适合需要快速完成毕业设计或系统学习SSM微信小程序全栈开发的读者,提供可直接部署的完整方案,配合视频演示降低上手难度,兼具参考与二次开发价值。
1. 学生资助在线管理小程序:微信小程序 + Java 的 SSM 后台,毕设资源先看这三件事
资助申请这类业务放在线下走,家长交材料、班主任核对、管理员做名单公示,整套流程又慢又容易漏。学生资助在线管理小程序这套资源,前端是微信小程序,后台用 Java 的 SSM 框架,数据统一落在 MySQL,相当于把申请、审核、评议、公示到复议的完整闭环搬到了移动端和管理后台两端。它的价值在于提供了一套能直接跑起来的完整参考:源码、数据库、论文、操作演示都齐,适合毕业设计需要完整系统的学生,也适合想快速上手小程序加 Java 联调的开发者。这篇笔记会把运行原理、启动步骤和最容易踩坑的地方拆开讲细。
2. SSM 后端与微信小程序的通信骨架:JSON 数据流与三角色权限边界
理解这套项目,建议先别急着点运行,而是想清楚一个问题:小程序端和后端之间到底在传什么。整个学生资助在线管理小程序的业务交互,本质上是小程序通过 HTTP 请求把 JSON 数据发给 Java 后端,后端用 SSM 框架处理完再返回 JSON。这个链路一旦理清,后面改接口、调权限、排错都会顺很多。
2.1 SSM 每一层在这个项目里负责什么
SSM 是 Spring、SpringMVC、MyBatis 三件套的合称,在这套系统里分工很明确。Spring 是粘合剂,controller、service、mapper 这些对象都由它创建并管理依赖关系,事务边界也在这一层控制,比如资助申请提交时,要保证“写申请记录”和“更新学生状态”要么都成功、要么都回滚。SpringMVC 负责接收请求,把小程序传来的 URL 映射到对应的 controller 方法上,再把返回值序列化成 JSON 写回响应。MyBatis 负责数据库访问,通过 mapper 接口和 XML 文件把 SQL 语句与 Java 对象互相转换。
这里有个常见的认知偏差:很多同学以为 SSM 项目里 view 层还是 JSP 页面,但在这个资源里,后端返回的是一段 JSON,真正的界面在小程序端和管理端页面里。后端承担的职责是业务逻辑和数据存取,不再负责拼页面,这也正是“前后端分离”在这套项目里的落地方式。管理端能看到的那批 vue 文件,说明管理后台是 Vue 组件化的界面,后端只提供接口数据。
分层结构里值得一口气记住的调用链是:小程序页面调用 wx.request → SpringMVC 的 Controller 接收 JSON → Service 层处理业务规则 → MyBatis 的 Mapper 操作 MySQL → 结果逐层返回并封装成 JSON。调试的时候只要沿着这条链路排查,基本就能定位问题发生在哪一层。
2.2 小程序端怎么和后台对上话:wx.request 与接口约定
小程序端发起网络请求用 wx.request,和浏览器里的 ajax 类似,但有几个容易翻车的细节。先看一段最常见的请求封装代码:
// utils/request.js 里封装通用请求,页面里直接调用 const BASE_URL = 'http://127.0.0.1:8080/ssm-server'; // 改成你的后端地址 function submitApplication(data) { wx.request({ url: BASE_URL + '/api/application/submit', method: 'POST', data: JSON.stringify(data), header: { 'Content-Type': 'application/json' }, success(res) { if (res.data.code === 200) { // 提交成功,跳转到进度页 wx.navigateTo({ url: '/pages/progress/progress' }); } else { wx.showToast({ title: res.data.msg, icon: 'none' }); } } }); }这段代码里有三个要点。第一,method 必须与后端接口一致,比如 POST 对应 @PostMapping,写成 GET 就会直接 405。第二,header 里的 Content-Type 要声明成 application/json,因为后端接收的是 JSON 字符串而不是表单参数,如果漏掉,SpringMVC 的 @RequestBody 就解析不出数据。第三,前后端要约定一个统一的返回结构,比如 code 为 200 表示成功,msg 带提示信息,data 放业务数据。这套约定在资源的 controller 代码里已经实现,你的页面里只要照着这个结构解析就行。
后端对应的入口方法长这样:
@RestController @RequestMapping("/api/application") public class ApplicationController { @Autowired private ApplicationService applicationService; @PostMapping("/submit") public Result submit(@RequestBody ApplicationDTO dto) { // 1. 校验:家长只能为自己的孩子提交,班主任不能代交 if (dto.getParentId() == null) { return Result.error("缺少家长身份"); } // 2. 落库,初始状态为“待班主任审核” applicationService.submit(dto); return Result.ok(); } }注意 @RequestBody 这个注解,它告诉 SpringMVC 把请求体里的 JSON 反序列化成 ApplicationDTO 对象。DTO 里的字段名要和前端 data 里传的键完全一致,比如前端传 studentId,后端就要写 private Integer studentId,大小写都不能错,否则这个字段就是 null。我习惯的做法是后端先不写任何业务代码,直接在 controller 里把 DTO 原样打印出来,确认字段映射没问题再往下写。
2.3 三角色权限:管理员、班主任、家长的数据隔离
这套系统的角色边界非常清晰,刚好可以用一张表讲明白。不同角色的主要操作范围如下:
| 角色 | 使用端 | 主要操作 | 核心数据表 |
|---|---|---|---|
| 管理员 | 管理后台 | 班主任管理、家长管理、公告管理、名单公示、回执公告、系统管理 | 管理员表、公告表、名单公示表 |
| 班主任 | 微信小程序 | 审核资助申请、处理申请复议、查看名单公示 | 资助申请表、复议表 |
| 家长 | 微信小程序 | 提交资助申请、查看公告、查看回执 | 学生表、资助申请表、回执表 |
权限落地的常见做法是维护登录会话,后端在用户登录成功后把角色标识放进 session 或 token 里,然后用拦截器统一控制接口访问。比如管理端接口全部要求 admin 角色,小程序端家长接口要求 parent 角色。拦截器伪代码如下:
public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String role = (String) request.getSession().getAttribute("role"); if ("admin".equals(role) || "teacher".equals(role) || "parent".equals(role)) { return true; } response.setStatus(401); return false; } }这段代码的核心逻辑是:拿不到角色就直接返回 401,不让请求继续往后走。实际项目里还要区分角色能访问哪些路径,比如 /api/teacher/** 必须验证 teacher 或 admin 角色,/api/parent/** 必须验证 parent 角色。这套资源里角色过滤的部分是写在 controller 方法里的,改造时建议抽出拦截器统一管理,否则每个方法都要写一遍角色判断,后期维护成本很高。
3. 把资助申请主流程跑通:从 MySQL 建库到小程序端联调
拿到压缩包之后,最要紧的事情是先把项目跑起来。很多同学卡在第一步,不是代码有问题,而是环境版本不匹配或者配置文件没改。这一章按顺序走一遍,目标是让你在 20 分钟内看到登录页面。
3.1 需要哪些工具与版本组合
这套项目基于 SSM 框架,常见搭配是 JDK 1.8、Maven 3.6 左右、MySQL 5.7 或 8.0,再加微信开发者工具稳定版。版本选择上有两条实用经验:第一,别用太新的 JDK,JDK 17 及以上跑 SSM 老项目容易遇到模块化报错,编译期折腾半天,最后换回 JDK 1.8 就安静了。第二,MySQL 用 5.7 最省事,如果用的是 8.0,驱动要换成 mysql-connector-java 8.x,并且连接参数里要加 serverTimezone,不然后端启动时大概率报时区错误。
数据库管理工具可用 Navicat 这类客户端,或者直接用命令行。微信开发者工具需要先注册一个小程序测试号,本地调试时不需要正式 appid,选测试号即可。
3.2 MySQL 数据库导入与初始化
打开控制台进入 MySQL,执行以下命令导入项目提供的 SQL 文件:
mysql -u root -p -h 127.0.0.1 < student_aid.sql如果 SQL 文件比较大,也可以图形化操作:先新建一个数据库,再右键运行 SQL 文件,选择项目的 .sql 文件并执行。导入完成后检查一下表名和库名,确认是否与后端配置文件里的库名一致。
后端数据库连接配置通常在 src/main/resources 下的 application.yml 或 jdbc.properties 文件里,改成你本机的账号密码:
spring: datasource: url: jdbc:mysql://localhost:3306/student_aid?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456这里的 url 参数里,最重要是 useUnicode 和 characterEncoding,这两个参数保证中文不乱码。serverTimezone 是给 MySQL 8.0 用的,5.7 不加也能跑。改完密码后,先在后端启动一次,确认日志里没有数据库连接异常,再进入下一步。
3.3 后端服务的启动:从 1-install.bat 到 3-build.bat
项目根目录下的三个 .bat 文件,从命名看就是一套标准流程:1-install.bat 通常做依赖安装,2-run.bat 启动后端服务,3-build.bat 打包构建。双击执行前,建议先用命令行手动跑一遍,能看到完整输出。
# 第一次运行,安装依赖并跳过测试 mvn clean install -DskipTests # 日常开发时启动,Spring Boot 内嵌 Tomcat mvn spring-boot:run # 打包成可执行的 jar,用于最终部署 mvn clean package -DskipTests java -jar target/student-aid.jarskipTests 这个参数值得说一下:很多同学打包时没跳过测试,结果测试类里连不上测试数据库,构建直接失败,其实毕业设计项目里的测试类通常不是重点,打包时跳过能省掉不少麻烦。启动成功后,控制台会打印 Spring Boot 的启动日志和端口号,默认一般是 8080。
另外,源码里还有一批 .bak 文件,比如 main.css.bak、update-password.vue.bak、IndexMain.vue.bak,这些是开发过程中留下的备份文件,不是正式代码,IDE 扫描项目时会忽略它们。我一般不去删它们,毕竟万一改坏了界面,这些 bak 就是后悔药。
3.4 小程序端连接后台:修改 baseUrl 和域名校验
小程序端和后端联调,最关键的是网络地址。在 app.js 的 globalData 里找到 baseUrl 配置,改成后端服务所在电脑的 IP:
// app.js App({ globalData: { baseUrl: 'http://192.168.1.100:8080', // 改成你的后端 IP 和端口 } });这个地址有个大坑:如果只在模拟器里跑,可以用 127.0.0.1,但要在手机真机上调试,就必须用电脑的局域网 IP,因为手机上的 localhost 指向手机自己,根本访问不到电脑。另外,微信开发者工具默认会校验合法域名,本地调试时必须在工具栏点击“详情”,勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”,否则请求会被微信拦截,控制台报 errno 错误。这个勾选只是本地开发用的,真正上线时后端必须换成备案过的 HTTPS 域名,并在小程序管理后台配置 request 合法域名,这是微信侧的硬性要求。
4. 资助申请、评议与名单公示:核心模块的改法与参数说明
跑起来之后,这套系统里最有分析价值的是资助申请和名单公示这条主流程。它涉及家长提交、班主任审核、管理员评议、名单公示、回执公告和申请复议六个环节,数据模型和状态流转设计的质量,直接决定论文能不能写出深度。
4.1 家长提交资助申请:状态机与关键字段
资助申请是整个系统的数据源头,核心表结构大致如下:
CREATE TABLE `aid_application` ( `id` INT NOT NULL AUTO_INCREMENT COMMENT '申请记录ID', `student_id` INT NOT NULL COMMENT '学生ID', `parent_id` INT NOT NULL COMMENT '家长ID', `class_id` INT DEFAULT NULL COMMENT '班级ID,用于班主任过滤', `reason` VARCHAR(500) DEFAULT NULL COMMENT '申请理由', `status` TINYINT DEFAULT 0 COMMENT '0待审核 1已通过 2已驳回 3待评议 4已公示 5已回执', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资助申请表';status 字段是整个流程的状态机。家长提交后初始值是 0,班主任审核通过变 1,驳回变 2;通过后管理员发起评议,状态变 3;评议通过并公示后变 4;家长确认回执后变 5。这个状态流转建议在 Java 代码里定义成枚举,而不是在业务方法里写裸数字:
public enum AidStatus { WAIT_TEACHER(0, "待班主任审核"), PASSED(1, "已通过"), REJECTED(2, "已驳回"), WAIT_REVIEW(3, "待管理员评议"), PUBLIC(4, "已公示"), RECEIPT(5, "已回执"); private final int code; private final String desc; AidStatus(int code, String desc) { this.code = code; this.desc = desc; } public int getCode() { return code; } }状态断言是这类业务里很容易漏掉的部分。比如已经被驳回的申请,家长不能再次提交;已经公示的记录,管理员不能直接改状态。我在这类项目里习惯在每个状态变更方法开头加一句“当前状态是否允许跳转到目标状态”的判断,不符合就抛业务异常。这样表面上多写了几行,但能挡住大量不规范操作。
4.2 班主任审核与管理员评议:MyBatis 动态 SQL 的查询条件
班主任登录小程序后,默认看到的是自己班级的待审核列表。这个查询接口的 Mapper 里会用到 MyBatis 最核心的动态 SQL,先看 XML:
<select id="selectForTeacher" resultType="com.example.pojo.AidApplication"> select * from aid_application where status = #{status} <if test="classId != null"> and class_id = #{classId} </if> order by create_time desc </select>这里 classId 为空时查全部,不为空时查指定班级。但真正做权限控制时,classId 不能由前端传过来,而是从后端登录 session 里取班主任绑定的班级编号。我见过一个典型翻车案例:后端接口接收前端传的 classId,结果学生改一下请求参数就能看到全校的资助申请记录,论文答辩时导师一问权限隔离就答不上来。
正确做法是后端强制从 session 拿:
Integer classId = (Integer) request.getSession().getAttribute("teacherClassId");这个值在班主任登录时写入 session,查询时直接使用,前端传的 classId 一律忽略。管理员评议的逻辑类似,但过滤条件从 class_id 换成 status=3 的待评议记录,并且需要支持按批次查看。
4.3 名单公示与回执公告:批次号设计避免改数据翻车
名单公示和回执公告是这条流程里最容易出数据一致性问题的地方。常见错误是直接把 aid_application 的当前状态当成公示名单来展示,结果公示期间某个申请被误改了,历史公示页面也跟着变。避坑方法是给公示表加一个批次号字段:
-- 在名单公示表上增加批次字段,回执公告也关联同一批次 ALTER TABLE public_list ADD COLUMN batch_no VARCHAR(32) COMMENT '公示批次号';批次号在管理员发起某次公示时生成,比如 2025A001,公示名单和回执公告都按这个批次号查询。这样一来,即便后续申请记录被修改,已经生成的历史公示快照也不受影响。这个设计在论文里可以单独写一节“数据一致性设计”,比单纯堆功能更有说服力。
5. 常见问题与避坑:域名校验、端口占用、字段映射与越权
这一章整理五条最常见的运行问题,全部按“现象 → 原因 → 解决”给你排好。这几条是我在多个类似项目里反复踩过的,按出现频率从高到低排。
5.1 微信开发者工具打开后白屏或请求失败
现象:小程序编译成功,但页面空白,控制台报 request fail 或 errno 错误,后端也没有收到任何请求日志。
原因:第一,工具栏里没有勾选“不校验合法域名”;第二,baseUrl 写成了 127.0.0.1,但实际是手机真机调试,手机访问不到电脑的 localhost。
解决:本地调试在微信开发者工具右上角点击“详情 → 本地设置”,勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”;然后把 app.js 里的 baseUrl 改成电脑的局域网 IP。如果都不行,关掉电脑防火墙或把后端端口加入允许列表,这种问题多半是防火墙拦截了局域网访问。
5.2 数据库导入报错或后端连不上库
现象:导入 SQL 时提示 Unknown database,或者后端启动时 datasource 连接失败,报 Access denied for user。
原因:SQL 文件如果包含 CREATE DATABASE 语句,执行前当前连接必须有 create 权限;Access denied 则是配置文件里的账号密码和数据库实际不一致。
解决:先登录 MySQL 执行建库语句,再指定数据库导入表结构和数据;然后核对 application.yml 里的 username 和 password。还有一个容易漏的点:MySQL 8.0 对密码加密方式有要求,老项目里用的驱动版本可能不支持 caching_sha2_password,要么降低数据库用户的加密方式,要么升级驱动再加 serverTimezone 参数。
5.3 端口被占用导致后端启动失败
现象:后端启动两三秒后直接退出,控制台打出一行 Port 8080 was already in use, 或 BindException。
原因:本机已经有别的服务占用了 8080 端口,常见的是其他 Java 程序或某个开发工具内置服务。
解决:Windows 下先确认谁占用了端口,再决定是释放还是更换端口。
# 查看 8080 端口占用情况 netstat -ano | findstr :8080 # 找到 PID 后结束进程 taskkill /PID <pid> /F不想杀进程就直接改后端端口,比如在 application.yml 里配 server.port=8081,然后同步修改小程序端 baseUrl 里的端口号。
5.4 小程序端有响应但列表数据为空
现象:wx.request 返回成功,日志里也能看到后端返回了 JSON,但页面列表就是空的,或者字段显示 undefined。
原因:JSON 字段名对不上。数据库列名是 create_time,MyBatis 开启了驼峰映射后 Java 属性是 createTime,如果后端直接把这个对象序列化成 JSON,前端却在模板里写的是 create_time,拿到就是 undefined;反之亦然。
解决:统一全链路字段命名。比较快的处理方式是给 DTO 或实体类加 JSON 别名注解:
public class ApplicationVO { @JsonProperty("create_time") private Date createTime; }我个人的习惯是全部用驼峰命名,前端小程序模板里也写驼峰,只在数据库列名和 MyBatis 映射那里保留下划线,这样中间环节最少。
5.5 班主任登录后能看到全校申请记录
现象:班主任账号登录小程序,列表里展示的居然是所有班级的资助申请,而且还能审核其他班的数据。
原因:查询接口的过滤条件只判断了 status,没有限制班级范围,或者 classId 从前端 request 里取,被篡改成别的值。
解决:后端强制从登录 session 中读取当前班主任的班级编号,过滤条件直接拼在 SQL 里,前端没有传参的入口。管理员账号不受此限制,因为管理员本来就要查看全校数据。这个问题也是论文答辩时评委最喜欢追问的点,提前改好能省很多麻烦。
6. 进阶:把毕业设计的答辩演示变成能验收的项目
项目跑通只是第一步,答辩时导师看的是你对系统的掌控力和边界处理能力。我建议你在正式演示前,把下面三件事做掉,能让整个项目的完成度上一个台阶。
第一件事是准备一份可重复的验证清单,每次演示前强制走一遍。清单内容大致是:从空数据库重建开始,执行 SQL 文件、启动后端、登录三种角色,按“家长提交申请 → 班主任审核通过 → 管理员评议 → 名单公示 → 家长确认回执”完整跑通一次。不要只演示一次,而是停掉后端、重启后再走一遍,确认没有依赖内存态数据的隐藏问题。第二件事是给后端加一张简单的操作日志表,记录谁在什么时间做了什么操作。比如家长提交申请、班主任审核通过、管理员公示名单,这些动作写入一条日志:
CREATE TABLE `operation_log` ( `id` INT PRIMARY KEY AUTO_INCREMENT, `user_type` VARCHAR(20) COMMENT '角色类型:admin/teacher/parent', `user_id` INT COMMENT '操作用户ID', `action` VARCHAR(50) COMMENT '操作名称:submit/review/publish', `detail` VARCHAR(500) COMMENT '操作详情', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志表';这张表在答辩现场非常实用,导师问“系统怎么保证操作可追溯”,你直接把日志查询页面打开,现场演示一条记录怎么产生、怎么查询,比嘴上解释有说服力得多。第三件事是把数据库备份脚本写进启动说明里,答辩前用备份文件恢复一次数据环境,避免现场演示时因为前面同学动过数据而翻车。
这几件事做完,这个毕业设计就从“能运行”变成了“能验收”。从那以后我每次接手这类资源,都会先跑一遍从空库到登录的完整链路,确认三个角色都能正常进出,再看功能细节,这个习惯帮我避掉了很多现场演示的雷。希望帮到你。
本文还有配套的精品资源,点击获取