简介:这份资源是面向高校计算机相关专业学生与Java初学者的一套互助学习平台毕业设计完整方案,采用微信小程序前端搭配Java后端与MySQL数据库,适合作为毕业设计、课程设计或全栈入门练手项目。压缩包共1306个文件,约25.37MB,涵盖java后端源码、js与vue前端逻辑、wxml与wxss小程序页面样式、json配置、sql建库脚本以及png、svg等界面素材,另附mp4演示视频与说明文档,结构完整便于按模块查阅。功能上管理员端包含个人中心、学生管理、课程分类与课程信息管理、课程评价、学习计划、留言板、学习论坛及系统管理,小程序用户可注册登录、浏览课程、查看评价、制定学习计划并留言互动。目前已有127人学习下载,读者可据此获得可直接运行的源码、数据库脚本与演示录屏,快速理解小程序与Java后端联调思路,并在此基础上完成二次开发与答辩准备。
1. 互助学习小程序毕设:从选题到跑通,一套能交差的完整路径
每年到了毕设季,总有一批同学卡在同一个地方:题目定了「基于微信小程序+Java后端的互助学习系统」,听起来方向明确,真动手却发现不知道从哪一行代码写起。前端小程序怎么和后端联调、数据库表怎么设计、登录态怎么维持、最后答辩演示怎么不出洋相——这些问题没人系统讲过,网上搜到的又大多是零散片段。这篇笔记就是冲着这个场景来的:把互助学习类小程序毕设从技术选型、环境搭建、核心功能实现到部署演示的完整链路拆开,每一步都落到能直接抄的代码和参数上。适合正在做微信小程序+Java方向毕设的本科生,也适合想拿一个前后端分离项目练手的初级开发者。读完你至少能拿到一套可运行的最小系统骨架,知道哪些坑必须提前绕开。
2. 技术选型与环境搭建:为什么这套组合最适合毕设
2.1 小程序端选原生还是 uni-app
做毕设最怕的是时间不够。原生微信小程序开发用 WXML+WXSS+JS,配合微信开发者工具,调试链路最短,遇到问题搜到的答案也最多。uni-app 的优势是能一套代码多端发布,但毕设场景下你只需要跑在微信里,多出来的编译层反而会增加排查成本。我一般建议毕设选原生,除非导师明确要求跨端。
原生小程序的目录结构很清晰:pages放页面,utils放工具函数,app.js管全局逻辑,app.json配路由和窗口样式。一个容易翻车的点是顶部导航栏高度——自定义导航栏时需要用wx.getSystemInfoSync()拿到状态栏高度,再叠加 44px 的标题栏,否则不同机型上标题会被刘海挡住。这个细节答辩时老师不一定看,但演示时手机一换就露馅。
2.2 Java 后端选 Spring Boot 还是 SSM
2024 年了,毕设后端直接用 Spring Boot 3.x + MyBatis-Plus,不要再去手写 SSM 的 XML 配置。Spring Boot 的起步依赖让 pom.xml 干净很多,内嵌 Tomcat 也让部署少一个步骤。MyBatis-Plus 更是毕设利器——单表增删改查不用写 SQL,分页插件配一下就能用。
版本选择上,JDK 17 + Spring Boot 3.2.x 是当前稳妥的组合。注意 Spring Boot 3 要求 JDK 17 起步,如果你学校机房还装着 JDK 8,要么换机器要么降到 Spring Boot 2.7。数据库用 MySQL 8.0,字符集选utf8mb4,排序规则utf8mb4_unicode_ci,这样 emoji 和生僻字都不会出问题。
2.3 前后端分离的目录结构与跨域配置
前后端分离项目实战里,跨域是第一个拦路虎。小程序请求走wx.request,不受浏览器同源策略限制,但开发者工具里调试时如果直接访问本地后端,仍然可能遇到跨域提示。稳妥做法是在 Spring Boot 里加一个全局 CORS 配置:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") // 毕设阶段放开,生产环境要收紧 .allowedMethods("GET", "POST", "PUT", "DELETE") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } }allowedOriginPatterns而不是allowedOrigins,是因为后者在allowCredentials=true时不允许用*。maxAge设 3600 秒,减少预检请求次数。这个配置放在config包下,启动类能扫描到即可。
后端目录按controller、service、mapper、entity、config、utils分包。实体类用 Lombok 的@Data省掉 getter/setter,但注意 IDE 要装 Lombok 插件,否则编译报错。数据库连接池用 HikariCP,Spring Boot 默认自带,application.yml里配好 url、username、password 就行。
3. 数据库设计与核心表结构:互助学习系统的骨架
3.1 用户表与登录态设计
互助学习系统的核心实体是用户、问题、回答、点赞/收藏。用户表t_user至少包含:id(bigint 自增)、openid(varchar 32,唯一索引)、nickname、avatar_url、phone(varchar 11,可空)、create_time、update_time。openid 是微信登录后拿到的用户唯一标识,必须加唯一索引,否则同一用户重复插入会出脏数据。
微信小程序登录获取手机号的流程分两步:先wx.login拿 code 换 openid 和 session_key,再通过getPhoneNumber按钮触发手机号授权,把加密数据传给后端解密。后端解密用微信提供的 AES 工具类,session_key 从 Redis 里取。毕设阶段如果不想引入 Redis,可以把 session_key 存 MySQL,但要注意过期时间。
CREATE TABLE `t_user` ( `id` BIGINT NOT NULL AUTO_INCREMENT, `openid` VARCHAR(32) NOT NULL COMMENT '微信openid', `nickname` VARCHAR(64) DEFAULT NULL, `avatar_url` VARCHAR(255) DEFAULT NULL, `phone` VARCHAR(11) DEFAULT NULL, `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP, `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uk_openid` (`openid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;update_time用ON UPDATE CURRENT_TIMESTAMP自动维护,省得每次 update 都手动 set。字符集和排序规则跟前面说的一致。
3.2 问题、回答与互动表
问题表t_question:id、user_id、title、content、subject(学科分类)、view_count、status(0 待解决 1 已解决)、create_time。回答表t_answer:id、question_id、user_id、content、is_accepted(是否被采纳)、create_time。点赞表t_like:id、user_id、target_type(1 问题 2 回答)、target_id、create_time,user_id + target_type + target_id建联合唯一索引防止重复点赞。
用 MyBatis-Plus 根据 Java 实体类生成建表 SQL 是个提效技巧。在实体类上加@TableName和@TableField注解,然后用 MyBatis-Plus 的代码生成器或手写一段反射逻辑,就能把字段映射成 DDL。不过毕设阶段更推荐直接手写 SQL 建表,因为字段类型和索引需要精细控制,自动生成的反而不容易调。
3.3 分页查询与索引优化
问题列表页需要分页,MyBatis-Plus 的分页插件配置如下:
@Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }查询时用Page<Question> page = new Page<>(pageNum, pageSize);再调questionMapper.selectPage(page, wrapper)。索引方面,t_question的subject和create_time建联合索引,因为列表页常按学科筛选再按时间倒序。t_answer的question_id建普通索引,回答列表按问题 ID 查。
注意:分页插件只对 MyBatis-Plus 自带的
selectPage生效,手写 XML 的 SQL 需要自己处理 limit。
4. 小程序端核心页面与后端接口联调
4.1 登录页与全局状态管理
小程序登录页的逻辑:页面加载时调wx.login拿 code,把 code 发给后端/api/auth/login,后端用 code 换 openid,查库或新建用户,返回一个自定义 token(可以用 JWT)。小程序把 token 存到wx.setStorageSync('token', token),后续请求在 header 里带上。
// pages/login/login.js Page({ onLoad() { wx.login({ success: (res) => { if (res.code) { wx.request({ url: 'http://localhost:8080/api/auth/login', method: 'POST', data: { code: res.code }, success: (resp) => { const { token, userInfo } = resp.data.data; wx.setStorageSync('token', token); wx.setStorageSync('userInfo', userInfo); wx.switchTab({ url: '/pages/index/index' }); } }); } } }); } });wx.switchTab用于跳转到 tabBar 页面,普通页面用wx.navigateTo。token 存 storage 而不是 globalData,是因为小程序冷启动后 globalData 会丢失,storage 不会。
后端登录接口用 JWT 生成 token,密钥写在application.yml里,过期时间设 7 天。拦截器里校验 token,放行登录接口和静态资源。
4.2 问题列表与发布页
问题列表页用scroll-view或直接onReachBottom实现上拉加载。请求后端/api/question/page?pageNum=1&pageSize=10&subject=数学,返回分页数据。发布页用textarea和picker收集标题、内容、学科,提交到/api/question/add。
一个常见坑是textarea在弹窗里层级过高,会盖住其他组件。解决办法是用cover-view或者把弹窗改成页面跳转。毕设阶段建议直接用独立页面发布,避开这个玄学问题。
4.3 回答与采纳功能
回答列表按create_time升序排,被采纳的回答置顶。采纳操作只有提问者能执行,后端要校验question.user_id == currentUserId。采纳后把t_answer.is_accepted置 1,同时把t_question.status置 1。
@Transactional public void acceptAnswer(Long answerId, Long userId) { Answer answer = answerMapper.selectById(answerId); Question question = questionMapper.selectById(answer.getQuestionId()); if (!question.getUserId().equals(userId)) { throw new BusinessException("只有提问者可以采纳"); } answer.setIsAccepted(1); answerMapper.updateById(answer); question.setStatus(1); questionMapper.updateById(question); }@Transactional保证两个更新要么都成功要么都回滚。BusinessException是自定义异常,全局异常处理器捕获后返回统一格式。
5. 避坑与排查:毕设开发中最容易翻车的 5 个点
5.1 小程序请求本地后端失败
现象:开发者工具里请求http://localhost:8080报错,真机调试更是完全连不上。原因:开发者工具需要勾选「不校验合法域名」,真机则要求后端有公网 IP 或内网穿透。解决:开发阶段在开发者工具「详情-本地设置」里勾选不校验域名;真机演示时把后端部署到云服务器,或者用内网穿透工具把本地端口映射出去。答辩前一定要在真机上完整走一遍流程。
5.2 数据库中文乱码
现象:插入的中文在数据库里显示成问号。原因:建库或建表时字符集不是utf8mb4,或者连接 URL 没指定编码。解决:建库语句加DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci,JDBC URL 加?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai。已经建好的表用ALTER TABLE t_user CONVERT TO CHARACTER SET utf8mb4;转换。
5.3 MyBatis-Plus 字段映射失败
现象:查询返回的实体字段全是 null。原因:数据库字段是下划线命名(如create_time),实体是驼峰(createTime),但没开启驼峰映射。解决:application.yml里加mybatis-plus.configuration.map-underscore-to-camel-case: true。这个配置默认是 true,但如果你手动改过 MyBatis 配置可能会覆盖掉。
5.4 登录态过期后接口 401
现象:用户用了一段时间后,所有请求返回 401。原因:JWT 过期了,但小程序没处理。解决:在后端拦截器返回 401 时,前端统一拦截,清除本地 token 并跳转登录页。封装一个request工具函数,在fail或状态码判断里处理。
5.5 答辩演示时后端服务挂了
现象:演示到一半,后端突然报错或没响应。原因:本地跑的 Spring Boot 被误关,或者数据库连接池耗尽。解决:答辩前把后端打成 jar 包,用nohup java -jar xxx.jar &挂在服务器上,数据库连接池最大连接数调到 20 以上。准备一个录屏作为备用,万一现场网络或服务出问题,直接放录屏。
6. 部署上线与答辩演示的进阶技巧
部署环节,毕设最省事的方案是买一台最低配的云服务器,装宝塔面板,用宝塔部署 Spring Boot 项目和 MySQL。宝塔的 Java 项目管理器可以直接上传 jar 包,设置开机自启。小程序端在微信公众平台配置服务器域名,把后端接口域名加进去,注意必须是 HTTPS。如果没有域名,可以用云服务器 IP 加自签证书,但微信要求域名备案,所以毕设阶段更实际的做法是答辩时用开发者工具演示,不发布正式版。
验证系统是否跑通,我习惯按这个顺序检查:先看后端启动日志有没有报错,再用 Postman 调登录接口拿 token,然后用 token 调问题列表接口,最后打开小程序走一遍完整流程。每一步都确认数据正确,而不是只看页面能不能打开。
一个具体技巧:在application.yml里配置多环境,application-dev.yml连本地数据库,application-prod.yml连服务器数据库。打包时用--spring.profiles.active=prod指定。这样本地开发和服务器部署互不干扰。
# application-dev.yml spring: datasource: url: jdbc:mysql://localhost:3306/study_helper?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai username: root password: 123456答辩演示前,我会把整个流程录一遍屏,包括登录、发问题、回答、采纳、退出。录屏用 OBS 或者系统自带录屏工具,存成 mp4。这样即使现场出问题,也能从容切到录屏。另外,数据库提前造好 20 条问题、50 条回答的数据,别让老师看到一个空系统。
最后说个血泪经验:毕设代码一定要用 Git 管理,每天 commit 一次。我见过太多人改代码改崩了想回退,结果发现没有版本记录,只能重写。GitHub 私有仓库或者 Gitee 都行,别省这一步。希望帮到你。
本文还有配套的精品资源,点击获取