Spring+Vue在线教育微信小程序:全栈开发与毕业设计避坑指南 每年到了毕业设计季后台收到的高频问题永远是“系统怎么选型”“代码跑不起来怎么办”。今天要聊的这个项目——基于Spring Vue的在线教育微信小程序——恰恰是这类问题的高性价比答案。它一个人占了微信小程序端、Vue管理端、Spring Boot后端三条链路覆盖课程展示、视频播放、下单支付、课程评价这一整条业务闭环还配了一套LW论文文档直接构成毕业设计交付物的标准形态。无论你是第一次做全栈项目、对前后端分离一脸懵的新手还是想快速搭一套能拿去答辩的系统的老手这篇只讲实操和避坑的经验帖应该都能让你少走几段弯路。1. 项目整体设计与技术选型思路拆解1.1 三个端分别解决什么问题先把这个项目拆回最初的问题一套在线教育系统最少需要几个入口站在学生的角度要能打开手机选课、看视频、下单、写评价站在运营的角度管理员要能上传课程、维护分类、查看订单站在架构的角度两个入口不能直接操作同一套业务代码得有人管接口、管权限、管数据。于是这个项目从架构上就天然分成三块微信小程序面对学生做C端流量入口Vue管理后台面对运营人员做B端管理入口Spring Boot后端统一暴露REST接口处理登录、订单、课程等核心业务最后落库到MySQL。选用微信小程序而不是纯H5核心原因在于获客成本和体验完整度。学生微信扫一扫就能进入课程首页不需要另外装新应用自动带着微信身份体系注册门槛降到零。这种“微信原生能力加业务接口调用”的组合也是市面上在线教育产品的常见形态。Vue管理端独立部署而不是塞进小程序是因为两端的交互模型完全不同管理端是密集的表单、表格、富文本编辑适合PC大屏操作小程序是轻量、随时随地的浏览点击适合小屏单列。硬把两边塞到一起只会互相拖累。Spring Boot是整个系统的“大脑”。课程数据、订单数据、用户数据都汇总在这一层对外暴露统一REST API对内封装登录鉴权、文件上传、订单回调等公共能力。选Spring Boot而不是更老的SSH方案理由很实在内嵌Tomcat免去部署步骤、自动配置省掉大量XML、生态里现成组件多MyBatis-Plus管数据库、Spring Security管权限、JWT管登录令牌。毕业设计周期本来就短能省时间的技术组件都是好朋友。1.2 为什么这套选型最适合毕业设计有读者可能会问直接Spring Boot Thymeleaf做服务端渲染不是更简单吗答案是能跑但展示效果和答辩加分项差着一截。毕业设计评审重点关注系统分层是否清晰、有没有完整的用户端和管理端、是否体现主流的开发方式服务端渲染方案只能覆盖一半要求。一旦老师问“前端框架用了什么”场面会有点冷。这套技术栈最大的优势是“每一层都能单独讲故事”。论文里可以写小程序的微信登录流程可以写Vue管理端的组件化页面设计可以写Spring Boot的接口安全与控制层逻辑。答辩演示时三个端轮着展示内容密度比单一网页系统高一个量级老师能提的问题方向也完全不同。另一个隐性红利是Vue和小程序语法高度接近。组件化思维、生命周期概念、数据绑定方式都能互相迁移。很多学生先写完管理端再写小程序几乎是无缝切换。这套“一次学习两端复用”的体验在整个毕设周期里非常划算。加上现在各大招聘岗位里Vue和Java的需求量都很大做完这个项目写进简历项目经历和技能栈是能对上的。1.3 整体数据流与调用链路把三端串起来看一次完整操作长这样学生在小程序点开课程详情页小程序通过wx.request发请求到Spring Boot后端Controller校验入参转交Service层处理业务再通过MyBatis-Plus查询MySQL查询结果以JSON格式返回给小程序页面渲染成课程信息。管理端的流程本质上完全一致只是前端变成Vue页面权限校验多了一层管理员角色判断。登录链路稍微特殊一些小程序用wx.login拿起临时code请求后端后端拿着code去微信的code2Session接口换openid再用openid查user表没注册就自动创建用户最后签发JWT令牌返回小程序。后续所有请求都带这个令牌后端拦截器解析通过才放行。这段流程展开写就是论文的一大章节具体代码实现我在第四部分给出来。先把这条链路理解清楚整个项目的骨架基本就立住了。2. 功能模块拆解与数据库设计2.1 用户端围绕“学”字设计功能用户端的功能设计不能简单照搬电商的“首页、分类、购物车、我的”四件套。在线教育最核心的目标是让学生快速找到想学的课并且顺畅地学完。功能上我建议这样拆首页承载流量分发放轮播图、推荐课程、热门分类分类页解决检索需求按学科层级组织课程课程详情页是转化核心要同时呈现课程封面、讲师信息、价格、课程大纲和用户评价视频播放页是学习的主场景支持章节切换、试看、播放进度记录个人中心承载订单、收藏、学习记录和账号信息。对应到小程序页面就是首页、课程列表、课程详情、视频播放、个人中心这几个导航入口外加订单确认和支付流程页。有一个体验点特别容易被忽略视频试看。完全不试看用户判断不了课程质量下单很犹豫全部开放又失去收费逻辑。常见做法是前3分钟免费到时间后弹出购买引导。后端在视频地址上做时长控制前端用video组件自带的timeupdate事件配合提示体验做得巧妙的话答辩时反而是亮点。作为毕业设计不需要人工客服、直播互动、作业批改这类重功能但上面说的基础能力必须齐。它们覆盖了业务闭环也足够支撑论文里“需求分析”和“系统功能设计”两个章节的写作。2.2 管理端把课程运营这件事做完整管理端的功能可以列很多但核心是运营闭环。建议保留五个模块贪多反而做不深。课程管理负责录入课程标题、封面、价格、课程简介挂载章节视频支持上下架操作。分类管理负责维护层级分类首页结构调整时能快速重组。订单管理查看订单列表和订单状态处理失效订单或退款。用户管理查看注册用户列表和学习状态必要时禁用异常账号。数据看板展示课程总数、用户总数、订单总数、销售金额答辩时数据一刷可视化能力和统计能力都体现出来了。技术实现建议直接用Vue 3 Element Plus表格、表单、弹窗都是现成组件。写一套通用CRUD模板之后五个模块的增删改查工作量能压得很低。安全上所有管理员接口统一走JWT鉴权管理端登录后令牌存localStorage请求拦截器自动加Authorization头后端对非管理员角色直接返回403。这层设计不用很复杂但论文里有这一段安全性描述就不再空泛。2.3 核心数据表设计与关系说明数据库设计是“看起来很简单实际最容易翻车”的部分。核心表我列了七张关键字段已经标出照着建表基本能跑通整套业务表名职责关键字段user用户表学生/管理员同表id、openid、nickname、avatar、phone、role、statuscategory课程分类id、name、parent_id、sortcourse课程主信息id、category_id、title、cover、price、intro、statuscourse_chapter课程章节id、course_id、title、sort、video_url、duration、is_freeorders订单表id、order_no、user_id、course_id、amount、status、pay_timecomment课程评价id、course_id、user_id、content、star、create_timefavorite收藏关系表id、user_id、course_id、create_time几个需要理解的设计点。user表用role字段区分管理员和学生而不是拆成两张表因为两边的登录流程完全复用只是权限不同。orders表用order_no做唯一业务号所有对账操作都以它为准不要信任自增主键。course_chapter表用is_free字段控制试看章节比在后端代码里写死灵活得多。category表用parent_id实现自关联支持无限层级分类就算现在只做两级也保留了扩展空间。还有一个容易踩的坑是索引。订单表按user_id查、课程表按category_id查、评价表按course_id查这些字段都要建普通索引。数据量小的时候没感觉答辩演示如果导入几千条测试数据没有索引的查询延迟肉眼可见。我建议在测试阶段就导入两千条以上模拟数据提前暴露出性能问题别等到答辩现场才卡顿。3. 实操搭建从零把项目跑起来3.1 前置环境准备清单第一次跑这套项目环境准备是决定体验的第一个门槛。清单如下JDK 1.8或11、Maven 3.6以上、MySQL 5.7或8.0、Redis、Node.js 14以上、微信开发者工具最新稳定版。JDK推荐1.8兼容性最稳后续如果换电脑或换JDK版本基本不会出幺蛾子。Maven一定要配阿里云镜像否则拉依赖能等到怀疑人生。mirror idaliyunmaven/id mirrorOfcentral/mirrorOf name阿里云公共仓库/name urlhttps://maven.aliyun.com/repository/public/url /mirrorRedis在这个项目里主要用来做热点数据缓存和验证码存储。登录令牌我用JWT无状态实现所以Redis不是硬依赖不装项目也能跑。但建议还是装上一方面后端代码里能多写一层缓存逻辑论文内容更丰富另一方面也方便后续扩展比如做验证码、做接口限流都用得上。3.2 Spring Boot后端搭建步骤后端建议直接用IDEA新建Spring Initializr项目groupId可以按自己学校的学号规范来artifactId就叫online-education。pom.xml里加入Web、MySQL驱动、MyBatis-Plus、Redis、Lombok、JWT工具这几类核心依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3/version /dependency dependency groupIdcom.auth0/groupId artifactIdjava-jwt/artifactId version3.19.2/version /dependency创建项目后先写application.yml把数据源URL、数据库账号密码、Redis连接、服务端口、JWT密钥配置好。这里有个细节MyBatis-Plus 3.x如果不用XML文件写SQL是可以省略mapper-locations配置的直接在Mapper接口里用注解或BaseMapper自带方法就行。启动类上加上MapperScan指定Mapper包路径。接下来写第一个实体类User、对应Mapper、Service、Controller用MyBatis-Plus的BaseMapper查一条用户数据用Postman调通这个接口。后端骨架立住之后再继续补课程、订单、评价这些模块。这里有个很重要的经验不要一上来就写完所有业务代码。我第一次做的时候贪快一次性写了五个实体和全部Controller结果同时报出十几个错误依赖冲突、Mapper扫描不到、数据库字段对不上全混在一起根本不知道从哪开始改。先把“一个实体能被查出来”的最小链路跑通后面的模块都是复制这个套路效率反而更高。3.3 Vue管理端搭建与接口联调Vue管理端用Vue CLI创建项目建议选Vue 3版本包管理用npm或pnpm都行。核心依赖是vue-router、pinia、element-plus、axios。创建后先配路由和布局左侧菜单对应课程管理、订单管理、用户管理等模块右边内容区用router-view渲染。联调阶段最烦的是跨域。前端跑在5173或者8080端口后端跑在8080端口浏览器会拦截跨域请求。处理办法是在vue.config.js里配置devServer代理把/api前缀的请求转发到Spring Boot地址// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, pathRewrite: { ^/api: } } } } }配置好之后先把管理端登录页和后端登录接口打通跑通“登录拿令牌进首页”这条路再开始写课程增删改查。Element Plus的表格组件配上分页组件再加上后端统一返回Page结构管理端页面很快就成型了。判断管理端做得好不好有一条很实用的验收标准管理员能不能在不碰数据库的前提下完成一门课程从录入到上架的全部操作。能做到管理端闭环就合格了。3.4 微信小程序端初始化与登录闭环小程序端用微信开发者工具新建项目AppID可以先选测试号。选原生小程序还是uni-app追求简单直接就用原生如果想要一套代码以后同时出H5和App版本那就用uni-app。毕设场景我建议原生少一层编译问题排查时也更快定位。小程序开工先做三件事配置app.json的页面路由和tabBar导航封装request工具类统一处理请求前缀和后端返回结构再写登录逻辑。登录核心代码如下wx.login({ success: res { wx.request({ url: http://localhost:8080/api/auth/login, method: POST, data: { code: res.code }, success: resp { const token resp.data.data.token wx.setStorageSync(token, token) } }) } })登录完成后首页就可以拉接口展示轮播图和推荐课程了。到这一步小程序端骨架通了页面能请求后端、后端能查到数据库并返回JSON、页面能正常渲染。整个项目从“能编译”跨入了“能演示”的阶段。4. 关键功能实现登录、视频、支付三块硬骨头4.1 微信登录与手机号获取微信登录是整个项目的身份基础值得单独讲透。完整流程小程序wx.login拿到临时code请求后端后端拿着code调微信jscode2session接口传入appid、secret、code换回openid和session_key后端用openid在user表里查用户不存在就自动注册一个新用户账号最后签发JWT返回小程序小程序把token存到Storage后续所有请求都带上。注意一个code只能用一次用完即失效。调试的时候如果你先把code复制到Postman里测了一遍又拿同一个code回小程序跑必然报invalid code。正确做法是每次登录都重新wx.login获取新code后端无状态处理不要缓存code。手机号获取和微信登录是两件事。登录用的是wx.login的code手机号获取是用户在小程序点击“获取手机号”按钮后前端拿到encryptedData和iv后端配合session_key解密。真实环境要求小程序完成企业认证才有权限毕设阶段建议做一个模拟手机号输入框替代在论文里如实说明这种演示范式即可不影响整体评分。4.2 视频点播与试看机制在线教育的核心内容交付是视频。小程序video组件原生支持mp4和m3u8两种格式实际产品为了网络播放体验通常把视频文件传到对象存储转码切成HLS分片m3u8后再交付。毕设项目没有专业转码服务的时候直接放mp4链接功能验收也一样过关不用过度纠结格式。具体实现上课程列表页展示课程封面课程详情页展示章节视频列表并标注哪些是试看章节播放页根据course_chapter表的is_free字段决定用户能播到哪一段。试看机制有两种常见实现一种是服务端生成带播放时长限制的地址时间到了就失效另一种是前端监听video组件的timeupdate事件超过试看时常后暂停播放并弹出购买引导。后者实现简单、演示效果直观毕设完全够用。还有个细节容易被忽略小程序页面栈最多10层wx.navigateTo跳转过深会触发上限。播放页里最好把课程详情信息、章节大纲列表、用户评价列表聚合在一个滚动容器里能用组件聚合的页面就不要单独开页既保体验又避坑。4.3 微信支付与订单状态机支付流程是业务闭环的最后一环也是最容易在答辩时卡壳的部分。完整业务流是这样小程序把课程ID发给后端后端创建订单初始状态为待支付生成唯一order_no返回订单号和支付参数小程序调wx.requestPayment拉起支付收银台用户付款成功后微信服务器回调后端预置的支付通知接口后端校验签名确保金额一致把订单状态改为已支付并给用户开通课程观看权限。没有真实商户号怎么做这是个人项目毕设最常见的问题两个方案可以选。一是去申请微信支付商户号但需要公司资质个人开发者很难拿下来。二是答辩演示时使用模拟支付小程序做一个模拟支付按钮点击后跳到“支付成功页面”后端同步把订单改为已支付。论文里把真实流程写完整演示环节用模拟逻辑不能把模拟方案当真实技术设计写进论文这点分寸要把握住。订单状态机值得认真设计待支付、已支付、已完成外加一个已取消。未支付订单超过30分钟自动关闭可以用定时任务扫描也可以在查询时动态判断超时。答辩老师问“超时订单如何处理”能答出这一套状态机设计比临时编一个答案强得多。5. 常见问题与排查技巧实录5.1 高频运行问题速查表把实际操作中遇到过的高频问题整理成一张速查表排查时直接对照省很多时间问题现象常见原因解决方案小程序请求接口报域名不合法未配置request合法域名开发阶段勾选“不校验合法域名”登录报40029 code无效code被重复使用或已过期重新wx.login获取新code不缓存code后端接口报跨域错误前端与后端端口不同配置CORS过滤器或Vue devServer代理管理端打包后刷新404history路由未配置回退改用hash模式或后端配置回退到index.html查询结果与实体字段对不上驼峰映射未开启配置map-underscore-to-camel-caseMaven依赖下载极慢默认中央仓库慢配置阿里云镜像源Spring Boot启动报端口占用8080已被其他程序占用改server.port或杀掉占用进程小程序页面跳转无响应navigateTo超过10层限制改用redirectTo或reLaunch这些问题的共性在于大部分都能在开发阶段靠配置规避。真正头疼的是那些“一切看着正常但就是不对”的运行时问题下面三个坑我在实现时逐个熬夜踩过写出来给大家提个醒。5.2 三个让我熬夜的坑以及最终解法坑一课程列表接口返回了全部数据前端分页组件却只显示第一页。原因是后端没有写分页查询直接返回了全量List前端拿到全量当分页结果渲染。解决办法是用MyBatis-Plus的Page类做分页接口接收pageNum和pageSize返回total和records两个字段前端分页组件绑定这两个值。这次之后我把所有列表接口都统一成这套返回结构联调成本直线下降。坑二小程序第一次登录成功过几天再打开就直接掉到未登录状态。排查发现小程序只在启动时调用了一次wx.login而后端签发的token过期之后没有自动续期逻辑。解决办法是在request工具类里加一个401响应拦截遇到token失效就重新wx.login再自动重放原请求。这个方案加上之后整个演示过程再没出现过“突然登出”的尴尬场面。坑三本地开发接口全部正常但用手机真机预览时小程序直接白屏。原因是手机请求的是localhost根本不是电脑的地址。解决办法是后端启动时监听0.0.0.0小程序请求地址改成电脑在同一WiFi下的局域网IP同时在开发者工具里勾选“不校验合法域名”。这个坑第一次做小程序的人基本都绕不开提前写出来能帮大家省一晚。5.3 答辩前必须验证的完整演示路径答辩演示最容易翻车的点不在功能本身而在“链路没有提前完整走一遍”。照着这份清单在答辩前一晚过一遍能规避大多数意外冷启动整个项目启动MySQL和Redis启动Spring Boot启动Vue管理端打开微信开发者工具全过程不超过10分钟每一步都没有红色报错。用管理员账号登录管理端新建一门测试课程上传封面和视频设置价格与试看章节点击上架。刷新小程序首页确认新课程出现在推荐列表并能正常进入详情页。在小程序下单购买课程走模拟支付流程支付完成后个人中心能看到订单状态变化课程详情页显示“已购买”。提交一条课程评价管理端评论区能看到这条新增记录。对照管理端数据看板的数字和数据库实际记录数确保统计一致。这条路径覆盖了“新增、展示、交易、评价、数据统计”的完整业务闭环。全部走通之后等于把项目最有说服力的部分提前彩排了一遍。建议再录一份演示视频备份万一现场网络抽风还能边播边讲不至于冷场。我个人做完这个项目的最大体会是真正的难点反而不是某个框架的用法而是把每一条业务链路的数据流全部理顺。登录、下单、支付、评价每个环节都牵扯至少两端的配合。动手写代码前先把数据流图画清楚后面所有工作都只是执行层面的问题了。另外LW文档一定要和源码对应着写答辩老师翻开文档里某个接口的描述顺手在源码里能找到对应实现这种匹配感比堆砌多少文字都有说服力。最后分享一个后续扩展方向这套架构完全可以平移到校园二手交易、会议室预约、校园订餐这类场景把核心表换一换业务流换一换下个项目就又是一个新课题。