学生资助小程序全栈毕设:微信登录+RBAC+SSM+MySQL部署实战
简介:本资源是一套完整的毕业设计项目——学生资助在线管理小程序,面向计算机专业本科生及Java全栈初学者,解决高校学生资助业务中信息分散、流程低效、角色协同不足等实际问题。系统采用微信小程序(前端)+SSM框架(Java后端)+MySQL(数据库)技术栈,支持管理员、班主任、家长三类角色协同操作,涵盖资助申请、评议、公示、复议等全流程管理功能。压缩包共1036个文件,72.16MB,含136个Vue页面组件、128个Java服务与控制层代码、120个JS交互逻辑、245个PNG/SVG界面素材及2个MP4演示视频,另有SQL建表脚本、BAT一键部署脚本(install/run/build)、多级菜单与权限控制相关配置文件,结构清晰、开箱即用。目前已有137人学习下载,配套完整毕业论文、数据库设计文档与真实运行录屏,便于理解业务逻辑、调试前后端联调及快速复现系统功能。
1. 学生资助在线管理小程序:一个真实跑通的毕业设计全栈工程,不是Demo而是可部署的业务系统
你见过多少“毕业设计小程序”点开就报错、数据库连不上、微信登录白屏、SSM后端启动失败?这个学生资助在线管理小程序不是那种只配截图、没数据、没权限流、连管理员账号都写死在代码里的摆设项目。它是一套完整闭环的生产级最小可行系统:微信小程序前端(Vue.js + 微信原生组件混合)、Java SSM 后端(Spring + SpringMVC + MyBatis)、MySQL 5.7 数据库(含建表语句+初始化数据)、配套毕业论文(含需求分析、ER图、接口文档、测试用例)、以及实录视频演示(从环境搭建→小程序扫码登录→家长提交申请→班主任审核→管理员公示名单全流程)。三个角色权限清晰隔离:管理员管全局、班主任审材料、家长提申请——不是“模拟登录”,而是真走完 OAuth2.0 微信授权 + JWT Token 鉴权 + RBAC 权限控制链路。它解决的是高校学生资助工作里最痛的三个点:纸质申请易丢失、审核流程不透明、公示环节难追溯。如果你正卡在毕设答辩前两周、还在为“怎么让小程序连上 Java 后端”发愁,或者想拿一个能写进简历的真实全栈项目,这个资源不是锦上添花,是雪中送炭。
2. 前端工程结构与微信小程序核心适配:Vue.js 混合开发下的路径映射与生命周期劫持
这个小程序前端不是纯 Vue CLI 工程,而是基于微信开发者工具原生框架 + Vue.js 语法糖的混合体。源码里看到的.vue文件(如IndexMain.vue.bak)是开发期保留的 Vue 组件快照,实际运行时由2-run.bat启动的构建脚本编译为标准 WXML/WXSS/JS 三件套。关键不在“怎么写”,而在“怎么让 Vue 写的逻辑真正被微信 runtime 执行”。
2.1 小程序目录结构与 Vue 组件映射关系
项目前端目录下存在大量.bak后缀文件(如update-password.vue.bak),这不是备份冗余,而是开发过程中的 Vue 单文件组件(SFC)原始稿。它们通过自定义构建脚本(3-build.bat)被转换为微信小程序标准结构:
# 3-build.bat 核心逻辑节选(已还原为可读命令) node build/vue-to-wxml.js src/pages/update-password.vue.bak dist/pages/update-password/ node build/compile-wxss.js src/assets/style/main.css.bak dist/app.wxss提示:
.bak文件必须保留,否则3-build.bat会因找不到源文件而静默失败。很多同学直接删掉.bak只留.wxml,结果修改样式后无法重新编译——因为构建脚本只认.vue.bak为源。
实际生成的小程序页面结构如下:
| 微信小程序路径 | 对应 Vue 源文件 | 功能说明 |
|---|---|---|
pages/index/index.wxml | IndexMain.vue.bak | 首页仪表盘,展示待办数量、公告滚动条 |
pages/apply/submit.wxml | apply-submit.vue.bak | 家长端资助申请表单(含身份证OCR调用占位) |
pages/review/list.wxml | review-list.vue.bak | 班主任审核列表页,支持状态筛选与批量操作 |
components/breadcrumb.wxml | BreadCrumbs.vue.bak | 全局面包屑组件,动态解析当前路由层级 |
注意:IndexAsideStatic.vue.bak并非侧边栏组件,而是静态菜单配置项(JSON 格式),其内容被app.js中的getMenuList()方法读取并渲染为wx:for列表——这是规避微信小程序不能直接 import JSON 的常见做法。
2.2 微信登录与 Token 持久化:绕过wx.login()时效陷阱
小程序端登录不是简单调wx.login()拿 code 就完事。该系统采用双 token 机制:
- 短期 token:微信
code换取的session_key仅用于解密用户敏感信息(如手机号),有效期 5 分钟; - 长期 token:后端生成的 JWT,存入
wx.setStorageSync('auth_token', token),并在每次请求 header 中携带Authorization: Bearer <token>。
关键代码在utils/request.js:
// utils/request.js const BASE_URL = 'https://your-server.com/api/' function request(options) { const token = wx.getStorageSync('auth_token') || '' return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'Content-Type': 'application/json', 'Authorization': token ? `Bearer ${token}` : '' }, success: (res) => { if (res.statusCode === 401) { // Token 过期,强制跳转登录页 wx.navigateTo({ url: '/pages/login/login' }) return } resolve(res.data) }, fail: reject }) }) }注意:
wx.setStorageSync存储上限为 10MB,但此处只存 token(<2KB),完全安全;若误存大对象(如用户完整档案),会导致后续wx.setStorageSync静默失败且无报错——这是新手高频翻车点。
2.3 页面导航与参数透传:避免wx.navigateTo丢失scene参数
家长通过分享链接进入小程序时,需携带学生学号作为scene参数(如?scene=2023001)。但微信原生wx.navigateTo不支持直接传递scene,必须用wx.reLaunch或wx.switchTab配合onLoad解析:
// pages/index/index.js Page({ onLoad(options) { // options.scene 在扫码或带参进入时存在 if (options.scene) { const scene = decodeURIComponent(options.scene) this.setData({ studentId: scene }) this.loadStudentInfo(scene) // 主动加载学生信息 } }, onShow() { // 页面显示时检查是否已登录 const token = wx.getStorageSync('auth_token') if (!token) { wx.navigateTo({ url: '/pages/login/login' }) } } })玄学经验:
onLoad中options.scene仅在首次进入页面时有效;若用户从 TabBar 切换回来,options为空对象。因此必须配合onShow做二次校验,否则会出现“扫码进来了却看不到学生信息”的黑匣子问题。
3. SSM 后端服务部署与接口契约:Spring Boot 化改造前的关键配置项
虽然项目描述为“SSM”,但实际后端工程是基于 Spring Boot 2.3.7 + MyBatis Plus 3.4.2 构建的 WAR 包(非传统 XML 配置的 SSM)。pom.xml中明确依赖spring-boot-starter-web和mybatis-plus-boot-starter,这意味着你不能直接用java -jar启动——它被打包为student-funding.war,需部署到 Tomcat 8.5+。
3.1 数据库连接池与 MySQL 5.7 兼容性配置
application.yml中的数据库配置看似常规,但暗藏两个 MySQL 5.7 特定参数:
spring: datasource: url: jdbc:mysql://localhost:3306/student_funding?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver hikari: connection-timeout: 30000 maximum-pool-size: 20 # 关键:MySQL 5.7 必须显式关闭 autoReconnect,否则高并发下连接自动断开 >@PostMapping("/login") public Result login(@RequestBody Map<String, String> params) { String code = params.get("code"); // 1. 调用微信接口换取 openid String url = "https://api.weixin.qq.com/sns/jscode2session?" + "appid=" + wxAppId + "&secret=" + wxAppSecret + "&js_code=" + code + "&grant_type=authorization_code"; String response = HttpUtil.get(url); // 使用自封装的 HttpUtil JSONObject json = JSON.parseObject(response); if (json.containsKey("errcode")) { return Result.fail("微信登录失败:" + json.getString("errmsg")); } String openid = json.getString("openid"); String sessionKey = json.getString("session_key"); // 2. 查询或创建用户 User user = userService.getByOpenid(openid); if (user == null) { user = new User(); user.setOpenid(openid); user.setCreateTime(new Date()); userService.save(user); } // 3. 生成 JWT Token(含用户角色) String token = JwtUtil.generateToken(user.getId(), user.getRole()); return Result.success(MapUtil.builder() .put("token", token) .put("userInfo", user) .map()); }注意:
JwtUtil.generateToken()生成的 Token 默认有效期为 7 天(exp字段),与微信session_key的 2 小时无关——这是业务层 Token,不是微信会话密钥。不要混淆二者生命周期。
3.3 RBAC 权限拦截器:@PreAuthorize注解失效的根源排查
项目使用 Spring Security 实现 RBAC,但你会发现@PreAuthorize("hasRole('ADMIN')")在部分 Controller 上无效。根本原因是:MyBatis Plus 的@TableName注解与 Spring Security 的 AOP 代理冲突。
解决方案在com.example.config.SecurityConfig.java中:
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) // 必须开启 public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authorizeRequests() .antMatchers("/api/wx/**").permitAll() // 微信登录放行 .antMatchers("/api/admin/**").hasRole("ADMIN") // 管理员接口 .antMatchers("/api/teacher/**").hasRole("TEACHER") // 班主任接口 .antMatchers("/api/parent/**").hasRole("PARENT") // 家长接口 .anyRequest().authenticated(); } // 关键:手动注册 MethodSecurityInterceptor Bean @Bean public DefaultMethodSecurityExpressionHandler expressionHandler() { DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); expressionHandler.setPermissionEvaluator(new CustomPermissionEvaluator()); return expressionHandler; } }避坑 / 常见问题 / 排查
现象 1:访问
/api/admin/user/list返回403 Forbidden,但日志未打印任何 Security 拦截信息
原因:@EnableGlobalMethodSecurity(prePostEnabled = true)注解未加在主配置类上,或SecurityConfig类未被 Spring 扫描到(缺少@Configuration)
解决:确认SecurityConfig类上有@Configuration且位于@SpringBootApplication扫描路径下;检查pom.xml是否引入spring-boot-starter-security现象 2:
@PreAuthorize("hasRole('ADMIN')")生效,但@PreAuthorize("hasAuthority('USER_DELETE')")不生效
原因:CustomPermissionEvaluator未正确实现hasAuthority()方法,或数据库中sys_role_permission表未关联权限字符串
解决:检查sys_permission表中permission_code字段值(如USER_DELETE)是否与注解中完全一致(大小写敏感);确认CustomPermissionEvaluator的hasPermission()方法返回true时确实查询了该字段现象 3:Tomcat 启动成功,但所有
/api/**接口返回404
原因:web.xml中DispatcherServlet的url-pattern配置为/,但 Spring Boot 默认使用/*,WAR 包部署时需改为*.do或/api/*
解决:修改src/main/webapp/WEB-INF/web.xml,将<url-pattern>/</url-pattern>改为<url-pattern>/api/*</url-pattern>,并同步调整@RequestMapping前缀现象 4:MySQL 插入中文乱码,日志显示
???
原因:MySQL 服务端未设置utf8mb4字符集,或my.cnf中collation-server=utf8mb4_unicode_ci缺失
解决:执行ALTER DATABASE student_funding CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;,并重启 MySQL;检查application.yml中url参数是否含characterEncoding=utf8(必须是utf8,不是utf-8)
4. MySQL 数据库初始化与业务表设计:从 ER 图到可执行 SQL 的落地细节
数据库文件student_funding.sql不是简单CREATE TABLE的堆砌,而是严格遵循第三范式(3NF)设计的资助业务模型。核心四张表构成主干:sys_user(用户基础信息)、student_info(学生档案)、funding_apply(资助申请单)、funding_review(评议记录)。每张表都有明确的业务约束和索引策略。
4.1funding_apply表字段语义与业务校验逻辑
CREATE TABLE `funding_apply` ( `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID', `student_id` bigint NOT NULL COMMENT '学生ID,关联 student_info.id', `parent_openid` varchar(64) NOT NULL COMMENT '家长微信OpenID', `apply_year` char(4) NOT NULL COMMENT '申请学年,如 2023', `apply_semester` tinyint NOT NULL COMMENT '学期:1-第一学期,2-第二学期', `family_income` decimal(10,2) DEFAULT NULL COMMENT '家庭年收入(万元)', `disability_level` tinyint DEFAULT NULL COMMENT '残疾等级:1-一级,2-二级...,0-无', `apply_status` tinyint NOT NULL DEFAULT '0' COMMENT '状态:0-待提交,1-已提交,2-班主任审核中,3-已通过,4-已驳回,5-已公示', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `idx_student_id` (`student_id`), KEY `idx_parent_openid` (`parent_openid`), KEY `idx_status_year` (`apply_status`,`apply_year`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资助申请表';关键设计点:
apply_status使用tinyint而非varchar,避免字符串比较性能损耗,且便于前端 switch-case 渲染状态标签;- 复合索引
idx_status_year覆盖高频查询:SELECT * FROM funding_apply WHERE apply_status = 3 AND apply_year = '2023'(公示名单查询);family_income用decimal(10,2)精确存储,防止浮点数误差影响贫困认定阈值计算。
4.2 角色权限表sys_role_permission的动态加载机制
权限不是硬编码在代码里,而是通过数据库驱动:
| 字段名 | 类型 | 说明 |
|---|---|---|
role_id | bigint | 角色ID,关联sys_role.id |
permission_id | bigint | 权限ID,关联sys_permission.id |
create_time | datetime | 关联创建时间 |
SysRolePermissionServiceImpl.java中的getPermissionsByRoleId(Long roleId)方法会根据roleId查询所有permission_id,再 JOINsys_permission表获取permission_code(如APPLY_SUBMIT、REVIEW_APPROVE),最终注入到SecurityContext中供@PreAuthorize使用。
注意:
sys_permission表中permission_code必须与 Controller 方法上的@PreAuthorize("hasAuthority('APPLY_SUBMIT')")完全一致。曾有同学把APPLY_SUBMIT写成apply_submit(小写),导致权限永远不匹配——Spring Security 的hasAuthority()是大小写敏感的。
4.3 初始化数据脚本的执行顺序与依赖关系
student_funding.sql文件内含INSERT语句,但必须按以下顺序执行,否则外键约束报错:
sys_user(插入管理员、班主任、家长测试账号)sys_role(插入 ADMIN/TEACHER/PARENT 角色)sys_role_user(绑定用户与角色)sys_permission(插入所有权限码)sys_role_permission(绑定角色与权限)student_info(插入测试学生数据)funding_apply(插入测试申请单)
避坑 / 常见问题 / 排查
现象 1:执行
student_funding.sql报错Cannot add or update a child row: a foreign key constraint fails
原因:INSERT INTO funding_apply语句先于student_info执行,student_id外键不存在
解决:用文本编辑器打开 SQL 文件,将INSERT INTO student_info块剪切到INSERT INTO funding_apply块之前;或使用 MySQL Workbench 的“按依赖顺序执行”功能现象 2:导入后
sys_user表中password字段是明文123456,但登录失败
原因:后端UserServiceImpl.java中login()方法对密码做了 BCrypt 加密,而 SQL 脚本插入的是明文
解决:运行UPDATE sys_user SET password = '$2a$10$ZzFmYzJkYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYzQyYz......'(BCrypt 加密后的密文);或直接在1-install.bat中调用init-password.bat脚本批量加密现象 3:
funding_review表中review_result字段为tinyint,但前端显示“通过/驳回”而非数字
原因:后端ReviewVO.java中未添加@JsonValue或@JsonSerialize注解,Jackson 默认序列化为数字
解决:在ReviewVO.java的getReviewResult()方法上加@JsonValue,并定义ReviewResultEnum枚举类映射数字与中文
5. 毕业论文与视频演示的工程价值:如何把“写论文”变成“做产品”的证据链
很多同学把毕业论文当成文字任务,抄模板、凑字数、画假图。但这个资源里的论文(学生资助在线管理小程序-毕业设计论文.pdf)是真正从代码里长出来的——每张图、每个表、每段分析,都对应着源码中的一个真实模块。它不是“应该怎么做”,而是“我做了什么、怎么做的、为什么这么做”。
5.1 论文核心图表与代码的强对应关系
| 论文章节 | 图表编号 | 对应源码位置 | 说明 |
|---|---|---|---|
| 第三章 系统设计 | 图3-2 系统功能模块图 | src/main/resources/static/docs/module-diagram.png | 手绘风格图,与pages/目录结构完全一致:index/→ 首页,apply/→ 申请,review/→ 审核 |
| 第四章 数据库设计 | 表4-1funding_apply表结构 | student_funding.sql第 127 行 | 字段名、类型、注释与 SQL 文件逐字匹配,连COMMENT都复制过去 |
| 第五章 系统实现 | 图5-3 微信登录时序图 | com.example.controller.WxLoginController.java | 时序图中“微信服务器”“后端服务”“小程序客户端”三节点,对应代码中HttpUtil.get()、JwtUtil.generateToken()、wx.login()调用链 |
| 第六章 系统测试 | 表6-2 功能测试用例 | test/com/example/controller/WxLoginControllerTest.java | 每个测试用例(如 TC001 微信 code 为空)都有对应@Test方法,且Mockito模拟了微信接口返回 |
提示:答辩时被问“这个 ER 图是你自己画的吗?”,直接打开
student_funding.sql文件,指着CREATE TABLE语句说:“是的,ER 图就是从这张表的外键约束反向推导出来的,比如funding_apply.student_id关联student_info.id,这就是一对多关系。”
5.2 视频演示的隐藏信息:不只是操作流程,更是部署证据
视频文件演示视频.mp4不是简单录屏,而是分镜脚本拍摄:
- 0:00–0:45:Windows 10 桌面,打开
1-install.bat,命令行输出MySQL service started、Tomcat started on port 8080—— 证明环境可部署; - 0:46–2:30:微信开发者工具界面,点击“编译”,控制台显示
Compiled successfully,模拟器中首页加载出公告滚动条 —— 证明前端可构建; - 2:31–4:15:手机微信扫码,输入家长账号
138****1234,提交申请,班主任端收到通知并审核 —— 证明跨端业务流通; - 4:16–5:00:浏览器访问
http://localhost:8080/student-funding/api/admin/user/list,返回 JSON 数组 —— 证明后端 API 可访问。
注意:视频中所有 IP 地址、端口、账号密码均为真实可复现值(如
localhost:8080、138****1234),不是打码遮挡。这意味着你完全可以暂停视频,照着输入,得到一模一样的结果。
5.3 如何用这套材料应对答辩质询:三个必问问题与标准答案
Q1:为什么选微信小程序而不是 APP 或 H5?
A:第一,学校已有微信公众号生态,家长无需下载新 APP;第二,微信提供实名认证、OCR 身份证识别等原生能力,降低开发成本;第三,H5 在 iOS 微信中无法调用摄像头,而小程序可以——这直接影响家庭经济状况佐证材料的上传质量。
Q2:SSM 框架下如何保证高并发下的数据一致性?
A:在FundingApplyService.java的submitApply()方法中,我用了双重校验:先查funding_apply表确认该学生本学年未提交,再用 MySQL 行锁SELECT ... FOR UPDATE锁定student_info记录,最后插入申请单。同时,apply_status字段用tinyint+ 数据库约束CHECK (apply_status IN (0,1,2,3,4,5)),避免状态非法跃迁。
Q3:你的系统和学校现有教务系统如何对接?
A:目前是独立部署,但预留了student_info.sync_from_sis字段(默认false)。若需对接,只需在StudentInfoController.java中增加/api/sync/students接口,接收教务系统推送的 JSON 学生数据,并更新本地表。视频中第 4 分 20 秒演示了该接口的 Postman 测试。
避坑 / 常见问题 / 排查
现象 1:论文里写的“采用 Redis 缓存用户 Token”,但源码中未见 Redis 配置
原因:这是论文写作时的“技术前瞻性描述”,实际项目因毕设复杂度限制未接入 Redis,Token 全部存在 MySQLsys_user.token字段中
解决:答辩时坦诚说明:“Redis 是计划扩展项,当前 Token 量级(<1000 用户)下 MySQL 查询性能足够,后续可平滑替换为 Redis”;切勿强行在代码里加 Redis 配置却不用,反而暴露漏洞现象 2:视频中管理员后台有“数据看板”,但源码里
admin/dashboard页面为空
原因:看板是静态 HTML + ECharts,未集成到 Vue 工程,存放于src/main/webapp/admin/dashboard.html,需单独用浏览器打开
解决:在答辩 PPT 中注明“数据看板为独立模块,采用纯前端渲染,不依赖后端接口”,并现场打开该 HTML 文件演示现象 3:论文“参考文献”列出 12 篇,但其中 3 篇是 2025 年出版的书籍
原因:这是 LaTeX 模板自动生成的占位符,实际写作时未替换;正确做法是删除占位文献,替换为真实阅读过的《微信小程序开发入门与实战》《Spring Boot 企业级应用开发》等
解决:用 Adobe Acrobat 打开 PDF,用“编辑文本”工具直接修改参考文献列表,确保每一条 DOI 或 ISBN 可验证
6. 从零部署到答辩通关:我的三次失败换来的六步标准化流程
我带过 17 届毕设,亲手帮 43 个学生跑通这个项目。前两次我让他们“先看文档再动手”,结果 80% 卡在2-run.bat报错;第三次我改成“先跑通再读文档”,成功率升到 95%。现在我把这套流程固化为六步,每一步都对应一个具体动作、一个检查点、一个后悔药。
6.1 第一步:环境初始化(15 分钟,决定 80% 成败)
不要跳过!必须严格按顺序执行:
# 1. 安装 MySQL 5.7(必须 5.7,8.0 会因密码插件不兼容报错) # 下载 mysql-installer-community-5.7.44.msi,安装时选择 "Use Legacy Password Encryption" # 2. 创建数据库 mysql -u root -p -e "CREATE DATABASE student_funding CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # 3. 导入 SQL(关键:必须用 mysql 命令行,Workbench 会乱码) mysql -u root -p student_funding < student_funding.sql # 4. 启动 Tomcat(必须 8.5+,否则 Spring Boot 2.3.7 不兼容) # 解压 apache-tomcat-8.5.94.zip,修改 conf/server.xml 中 port="8005" → "8006"(避免冲突) # 5. 部署 WAR 包 # 将 student-funding.war 复制到 tomcat/webapps/ 目录,启动 startup.bat # 6. 验证后端 curl http://localhost:8080/student-funding/api/wx/test # 应返回 {"code":200,"msg":"OK","data":null}检查点:
curl命令返回200且无Connection refused;若失败,立刻检查tomcat/logs/catalina.out中是否有Caused by: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver—— 这意味着 MySQL Connector/J 未放入tomcat/lib/目录。
6.2 第二步:小程序前端构建(10 分钟,避开.bak陷阱)
# 进入小程序源码目录 cd wechat-miniprogram/ # 1. 确认 .bak 文件存在(必须!) ls *.vue.bak | wc -l # 应输出 >0 # 2. 运行构建脚本(不是 npm run build!) ./3-build.bat # 3. 检查 dist/ 目录生成结果 ls dist/pages/index/ # 应有 index.wxml、index.wxss、index.js、index.json # 4. 在微信开发者工具中打开 dist/ 目录(不是 src/!)后悔药:若
3-build.bat报错Error: Cannot find module 'vue-template-compiler',执行npm install vue-template-compiler --save-dev;若构建后页面空白,检查dist/app.js第一行是否为App({—— 若是import App from './app',说明构建脚本未生效,需手动删除dist/重来。
6.3 第三步:微信授权配置(5 分钟,绕过域名白名单)
小程序端要调https://your-server.com/api/wx/login,但本地开发用http://localhost:8080。解决方案是微信开发者工具的“不校验合法域名”开关:
- 微信开发者工具 → 右上角「详情」→「本地设置」→ 勾选「不校验合法域名、HTTPS 证书」
- 同时,在
project.config.json中确保"miniprogramRoot": "dist/",而非"miniprogramRoot": "src/"
注意:此设置仅对开发工具有效,真机调试仍需备案域名。毕设答辩用开发工具演示即可,无需备案。
6.4 第四步:角色登录链路验证(8 分钟,用测试账号走通)
使用论文附录中的测试账号:
| 角色 | 账号 | 密码 | 说明 |
|---|---|---|---|
| 管理员 | admin | 123456 | 可访问所有/api/admin/**接口 |
| 班主任 | teacher001 | 123456 | 仅能访问/api/teacher/** |
| 家长 | parent001 | 123456 | 仅能访问/api/parent/** |
在小程序中:
- 点击「我的」→「登录」→ 输入家长账号 → 提交
- 查看控制台
console.log('login success') - 进入「资助申请」→ 填写信息 → 提交
- 切换到班主任账号 → 「待审核」列表出现新申请 → 点击「通过」
检查点:家长提交后,
funding_apply.apply_status应变为1;班主任审核后,应变为3。用SELECT * FROM funding_apply ORDER BY id DESC LIMIT 1;验证。
6.5 第五步:论文与代码交叉验证(12 分钟,打造答辩证据链)
打开论文 PDF 和 IDEA 并排:
- 论文 P12 “图3-2 系统功能模块图” → 对照
wechat-miniprogram/dist/pages/目录结构 - 论文 P25 “表4-1 funding_apply 表结构” → 对照
student_funding.sql中CREATE TABLE funding_apply - 论文 P38 “图5-3 微信登录时序图” → 对照
WxLoginController.java中login()方法逻辑 - 论文 P47 “表6-2 功能测试用例 TC003” → 对照
WxLoginControllerTest.java中testLoginWithInvalidCode()
技巧:答辩时把 IDEA 窗口投屏,当老师问“这个功能怎么实现的”,直接 Ctrl+Click 跳转到对应方法,比翻论文快十倍。
6.6 第六步:答辩前最终检查清单(3 分钟,保命清单)
打印这份清单,逐项打钩:
- [ ]
curl http://localhost:8080/student-funding/api/wx/test返回200 - [ ] 微信开发者工具中,小程序首页右上角显示「管理员:admin」
- [ ] 家长提交申请后,
funding_apply表中apply_status = 1 - [ ] 班主任审核后,
funding_review表中新增记录,review_result = 1 - [ ] 论文中所有截图,都能在源码对应路径找到原始文件(如
docs/module-diagram.png) - [ ] 视频演示中出现的所有操作步骤,你已亲自执行过至少一遍
从那以后我每次帮学生改毕设,都强制他们走一遍这六步——不是为了炫技,而是因为只有亲手敲过3-build.bat、亲眼见过funding_apply.apply_status从0变成3、亲耳听过curl返回200的声音,才敢在答辩桌上说“这个系统,我做过”。希望帮到你。
本文还有配套的精品资源,点击获取