拓冰建站拓冰建站
首页 / 资讯中心 / 正文

SpringBoot2+Vue3+MyBatis-Plus+MySQL8.0线上辅导班系统设计与源码解析

最近有朋友问我线上辅导班系统到底怎么做一个能交差、能演示、甚至能上线跑业务的版本我直接把这套基于SpringBoot2Vue3MyBatis-PlusMySQL8.0的源码从数据库表到接口逻辑完整对着梳理了一遍。说实话现在做Java Web项目最幸福的事情就是技术栈可以选得很现代同时又不会激进到给自己挖坑。SpringBoot2做后端底座Vue3做前端交互MyBatis-Plus管数据库CRUDMySQL8.0当存储这一套组合已经成了最近两年线上教育类、后台管理类项目的绝对主流搭配。尤其是标题里那句含文档对于准备毕业答辩、课程设计交付的人来说比代码本身还要救命——代码跑不起来可以修文档逻辑不完整答辩老师第一轮提问就能把你问穿。所以这篇文章我不打算给你贴一份源码然后说多好用而是把这套系统从需求拆解、技术选型、核心模块设计、启动部署、再到实操踩坑整个环节掰开揉碎讲一遍。不管你是拿它当毕设还是想在上面扩展功能做真实服务都能找到直接能抄作业的部分。1. 先拆需求线上辅导班系统到底要解决哪些业务问题很多同学拿到这类题目第一反应是有课程表、有用户表、能登录、能下单就够了。真这样做做完你会发现系统既不像辅导班也不像线上产品更像一个散装CRUD demo。线上辅导班系统本质上是一套在线教育交易与学习管理平台先搞清楚业务角色和业务链路才知道表怎么建、接口怎么分。1.1 用户角色与权限边界系统的用户角色至少分三档学生、讲师、系统管理员。如果你想把完整度拉开跟别人差距可以再加一个教务/班主任角色用来管理班级排课、查看学习进度、做学情统计。不过从绝大多数毕设和中小型项目的定位看三角色做扎实业务闭环已经能流转起来。学生注册登录、浏览课程、购买/报名课程、观看课程内容章节视频或图文、提交作业、发起提问。讲师管理自己名下课程、维护课程章节资料、批改作业、回复学生提问。管理员审核课程上下架、用户管理、课程分类管理、查看订单流水与销售统计。这里有个最容易被人忽视的点数据级权限。讲师只能看到自己名下的课程和提问学生只能访问已报名课程的内容。前端隐藏按钮不算权限控制真正的控制必须落到后端接口的查询条件里。比如讲师查询课程列表的SQL必须强制带teacher_id 当前登录用户id而不是把全表数据查出后让前端过滤。1.2 一条完整的业务链路画业务链路图是我拿到项目需求后做的第一件事比写代码重要得多。线上辅导班系统主链路可以概括为用户注册 → 浏览课程 → 选择课程 → 下单生成订单 → 支付/模拟支付 → 订单完成生成报名记录 → 开始学习章节 → 提交作业/提问 → 讲师批改/回复 → 学生查看反馈这条链路里最关键的一步是订单与报名分离。新手最容易图省事把购买课程做成直接往报名表里insert一条记录导致后续付款失败、重复购买、退款这些场景全部没法处理。正确做法是订单表是交易凭证报名表是权益结果订单支付成功后才生成报名记录两边通过order_id关联。这条设计一旦做对整个系统的业务逻辑就稳了一大半。1.3 这类系统真正费时间的地方把用户、课程、讲师这些基础CRUD写完大概只需要整个项目三分之一的时间剩余时间基本都耗在三个地方订单状态流转待支付、已支付、已取消、已退款、已关闭每个状态有哪些触发动作、哪些接口允许执行需要理清状态机逻辑。课程内容权限控制怎么判断当前用户有没有资格访问某个章节的视频/文档这部分涉及JWT用户身份解析和报名关系校验。后台统计报表管理员需要看课程销量、营收总额、热门课程排行这些数据需要做聚合查询也是答辩时最容易被追问的系统亮点。这三块做好了系统给人的感觉才不是玩具而是能扛得住真实业务场景的设计。2. 技术选型复盘为什么是SpringBoot2Vue3MyBatis-PlusMySQL8.0这套组合我知道肯定有人会问SpringBoot3都出了为什么还要用SpringBoot2Vue3搭配Element Plus稳不稳MyBatis-Plus会不会引入太多魔法MySQL8.0和5.7到底差在哪这些问题我在开发中每一个都认真考虑过下面把我的判断逻辑摊开讲。2.1 SpringBoot2毕业设计和中小型项目的稳妥底座SpringBoot2直到现在依然是Java服务端生产环境的主流版本。原因不是它比3强而是稳、熟、资料多。SpringBoot3强制要求JDK17而且包名从javax.*迁移到jakarta.*很多老教程和现成代码片段在SpringBoot3下直接编译不过。线上辅导班这种业务没有任何非用SpringBoot3不可的理由反而会在环境配置上浪费大量时间。SpringBoot2配JDK1.8或JDK11是目前压力最小、教程最全、遇到问题一搜就有答案的组合。选型的第一原则永远是降低不确定性而不是追最新版本。2.2 Vue3的Composition API逻辑聚合让复杂功能变清爽Vue3现在已经非常成熟生产环境可以放心用。跟Vue2比最核心的变化是Composition API组合式API它解决了Vue2里同一个功能的代码被拆散到data、methods、watch各个选项里的痛点。拿辅导班系统的课程购买功能举例页面要同时处理订单状态、支付按钮状态、倒计时、订单号展示、报名成功提示。Vue2的Options API写法下这些逻辑的变量散落在data方法散落在methods监视器散落在watch用Vue3的script setup语法糖这些状态和函数可以按功能聚在一起维护起来舒服得多。UI框架方面后台管理部分我建议直接上Element Plus它是Element UI的Vue3版本表格、表单、弹窗、分页、上传组件全都有遇到问题搜一下基本都是现成答案。如果你想要更精致的视觉风格可以选Ant Design Vue但资料和踩坑案例相对少一些。做课题、做交付优先保证查得到解决方案。2.3 MyBatis-Plus把CRUD从体力活里解放出来MyBatis-Plus不是替代MyBatis而是在MyBatis之上做增强。核心价值在于通用Mapper和条件构造器。像线上辅导班这种业务90%的数据操作是单表CRUD、分页、条件查询。用MyBatis-Plus你连XML文件都不用写实体类继承BaseMapperT就自动获得了selectById、insert、updateById、deleteById等方法。举个例子课程分类的树形查询在纯MyBatis里要写递归SQL或者写ResultMap嵌套映射。用MyBatis-Plus就简单了先用QueryWrapper把所有分类查出来内存里组装成树形结构。分类表数据量不大多一次全表查询性能完全没问题但代码量少了一半逻辑也更直白。另一个常用场景是分页查询配合MybatisPlusInterceptor注册分页插件PageT直接传页码和页大小前端分页从此告别手写LIMIT ? , ?。2.4 MySQL8.0不是跟风是真实使用体验更好MySQL8.0发布到现在已经很多年稳定性早就验证过了。选择8.0有几个非常实际的理由默认字符集是utf8mb4能原生支持emoji和特殊字符在线教育系统里学生的昵称、作业留言经常出现emoji5.7的utf8字符集插入四字节字符时直接报错。窗口函数ROW_NUMBER()、RANK()、SUM() OVER()做课程热度排名、销售统计非常方便一条SQL搞定不用写复杂的子查询。既然是新项目没有理由选老版本。需要提醒的是MySQL8.0默认认证插件是caching_sha2_password旧版本的客户端尤其是很老的Navicat会连接失败。解决方案是使用MySQL官方mysql-connector-j8.x驱动并在连接串里指定serverTimezoneAsia/Shanghai这一点在第5部分我会再详细说。3. 核心模块落地从数据库设计到接口实现这一节是整个系统的技术含金量所在我会从用户认证、课程设计、订单流程、答疑作业四个模块挑重点讲每个模块都给出可以直接落地的表结构和实现思路。3.1 用户认证与JWT的落地细节前后端分离项目的认证绕不开JWTJSON Web Token。登录流程是用户提交账号密码后端校验通过后生成一个包含用户id、用户名、角色、过期时间的token返回给前端前端存在localStorage后续每个请求都在Header里带Authorization: Bearer token。后端写一个拦截器HandlerInterceptor校验token并解析出当前用户放入ThreadLocal供业务层使用。实现时有几个坑要提前避过期时间别设太短。辅导班的学生可能上午登录、下午还在用过期时间建议至少2小时如果做了记住我可以放宽到7天。拦截器排除路径要写全至少包括登录、注册、验证码、Swagger文档、前端静态资源这几类。封号或改密后旧token依然有效。简单项目不引入Redis的话可以在token里带上用户状态字段拦截器每次解析后查一次用户状态表发现异常直接拒绝。后端生成JWT的代码逻辑不复杂但签名密钥一定要放到配置文件里不要硬编码到代码中。密钥建议至少32位随机字符串并且区分开发环境和生产环境。3.2 课程与讲师模块的数据库设计课程模块看起来就是一张course表加一张teacher表实际上有几个细节值得认真设计课程表建议字段id、title、cover_image、category_id、teacher_id、price、original_price、status0草稿/1上架/2下架、intro、create_time、update_time。其中status控制课程是否在商城展示管理员审核或讲师编辑后置为草稿。课程章节表建议字段id、course_id、chapter_title、sort、video_url、content、duration。章节排序用sort字段查询时ORDER BY sort ASC不要在业务逻辑里硬编码顺序。讲师表我建议基于user表扩展user表加role字段STUDENT/TEACHER/ADMIN讲师专属信息头衔、简介、擅长领域单独建teacher_profile表通过user_id关联。这样账号体系、登录逻辑、权限判断全部复用一套不用另外维护一套讲师账号。分类表用category表加parent_id字段支持两级分类就足够了线上辅导班常见分类就是数学、英语、编程这类两级分类足够用。多级分类会牵扯前端Tree组件的无限递归渲染和后端递归查询复杂度成倍上升收益却很低。3.3 订单流程最容易被答辩老师追问的地方订单模块做得好整套系统的含金量立刻上一个台阶。表结构建议order表id、order_no、user_id、course_id、amount、status0待支付/1已支付/2已取消/3已退款、pay_method、pay_time、create_time。student_course报名表id、student_id、course_id、order_id、create_time加唯一索引(student_id, course_id)防止重复报名。下单核心流程是创建订单生成订单号→ 模拟支付或调起真实支付 → 支付成功回调 →事务性更新订单状态、写入报名记录、扣减余额。这三步必须在一个Transactional事务中执行任何一步失败都要回滚否则会出现订单已支付但课程权限没开通的数据不一致。写事务时有一个很多新手没注意的坑同类内this调用不会走Spring代理事务注解失效。比如OrderServiceImpl里的createOrder方法调用了同类中的paySuccess()在paySuccess()上加了Transactional也是无效的。解决办法是把涉及事务的方法放到另一个Bean里或者自己注入代理对象。订单号生成建议用yyyyMMddHHmmss 随机数长度在20位左右保证业务上可读且不易重复。不要用数据库自增id当订单号很容易暴露业务量。3.4 答疑与作业提交系统完整度从有到能用的分水岭很多辅导班系统做完课程和订单就停了答疑和作业模块缺失答辩时老师一句学生怎么和老师互动直接卡壳。其实这两个模块实现成本很低但对业务闭环非常重要。答疑模块question表id、course_id、student_id、title、content、create_time、answer表id、question_id、teacher_id、content、create_time。学生提问走公开或定向都行讲师回复后学生端能看到回复内容。查询时注意权限过滤讲师只看得到自己课程下的提问学生只看得到自己发的提问。作业模块homework表id、course_id、title、content、deadline和homework_submit表id、homework_id、student_id、content、file_url、score、comment、submit_time。提交功能支持附件上传建议用本地存储或对象存储OSS讲师批改时填分数和评语。作业提交记录要加(homework_id, student_id)唯一约束确保同一份作业只能提交一次如需重交则做更新操作。这两个模块做完系统给人的感觉就是真的能运行而不是为了凑功能而存在的demo。我见过不少答辩优秀的学生项目技术难度未必高但业务闭环完整度是实打实的加分项。4. 从零跑通项目环境准备与启动全流程这一部分写给刚拿到源码、还不知道怎么把项目跑起来的人。环境配置不复杂但版本一定要对很多问题都出在自作主张升级了版本。4.1 环境清单与版本对应关系强烈建议严格按照下面的版本组合不要随意改动组件版本说明JDK1.8 或 11SpringBoot2兼容性最好的版本区间Maven3.6Java依赖管理工具Node.js16.14Vue3与Vite的运行环境npm/yarn8前端依赖安装工具MySQL8.0数据库Redis5.0可选做验证码、token黑名单时使用后端IDE建议用IDEA社区版即可前端用VSCode或WebStorm都行。前端脚手架用的是Vite不是Vue CLIVite的冷启动速度快一个数量级改代码热更新的体验也好很多。拿到项目后如果前端目录下没有node_modules先执行npm install。这一步如果下载很慢先设置镜像源npm config set registry https://registry.npmmirror.com很多同学卡在npm install卡半小时其实多半是没配镜像源。4.2 后端启动步骤后端启动分为四步每一步都可能出问题我按顺序写清楚用IDEA打开后端工程进入File → Settings → Maven检查Maven路径和settings.xml确认用的是JDK1.8或11不是JDK17。修改数据库配置打开src/main/resources/application.yml重点检查这段配置spring: datasource: url: jdbc:mysql://localhost:3306/tutor_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver创建数据库并导入初始化脚本。MySQL8.0建库命令正确写法CREATE DATABASE tutor_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后使用MySQL客户端命令行或Navicat执行源码里sql/init.sql脚本导入表结构和初始数据。 4.运行主启动类找到TutorApplication.java右键运行看到日志输出Started TutorApplication就是启动成功。接口自测建议用Postman或ApiPost先调登录接口获取token再在请求Header中加上Authorization这样能模拟前端真实调用链比在浏览器里直接敲URL靠谱。4.3 前端启动步骤前端启动三步走用VSCode打开前端目录通常叫frontend或vue-ui。执行npm install安装依赖这一步没问题的话继续下一步。找到.env.development文件确认API地址指向VITE_API_BASE_URLhttp://localhost:8080/api然后执行npm run dev浏览器访问http://localhost:5173进入系统。前端一个常见问题是刷新页面变成404。原因是Vue Router用了createWebHistoryHTML5 History模式刷新时浏览器请求了后端不存在的路径。解决办法有两个一是在开发环境改用createWebHashHistory路由模式URL里会带#但不受服务器配置限制二是让后端把非API路径全部转发到index.html。对于本项目开发阶段直接改createWebHashHistory最省事。4.4 前后端联调最隐蔽的坑跨域前端跑在5173端口后端跑在8080端口浏览器会认为是两个源跨域问题绕不开。后端要配置CorsFilterConfiguration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); config.addAllowedOrigin(http://localhost:5173); config.addAllowedMethod(*); config.addAllowedHeader(*); config.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }这里有个经验addAllowedOrigin不要用*尤其在allowCredentials(true)同时开启的情况下部分SpringBoot2.x版本会直接报错。前端地址写死是对的因为线上环境前端和后端域名本来就固定。还有一个容易误判的点是登录接口出现跨域报错但看不到响应体多半是Spring拦截器先拦截了OPTIONS预检请求要确保登录接口在拦截器排除列表里或者拦截器直接放行OPTIONS方法。5. 我实际开发中踩过的坑与处理经验技术框架本身不难难的是那些文档没写但一定会遇到的小问题。我把开发这套系统中踩过的印象最深的坑整理出来每个都带着解决方案。5.1 MyBatis-Plus的逻辑删除陷阱BaseMapper自带的deleteById默认是物理删除也就是真从表里删掉那行数据。你想做逻辑删除用户、订单这类核心数据强烈建议用逻辑删除必须做两步配置第一步实体类需要逻辑删除的字段加TableLogic注解TableLogic private Integer deleted;第二步在application.yml中声明配置mybatis-plus: global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0这样才能让删除接口变成执行UPDATE ... SET deleted 1而且所有MyBatis-Plus生成的查询都会自动追加deleted 0过滤条件。但要注意手写在XML里的原生SQL不会自动加这个条件需要自己手动补充否则会出现逻辑删除的数据还在列表里的诡异问题。5.2 Vue3响应式丢失的经典场景我在做课程列表页时遇到过页面死活不刷新的问题排查半天发现是响应式丢了。Vue3最常见的响应式丢失有两种一种是使用reactive定义对象后解构赋值导致响应性丢失// 错误写法 const state reactive({ list: [], total: 0 }) const { list, total } state // 正确做法 const list ref([]) const total ref(0) const state reactive({ list, total })另一种是赋值时进行了深拷贝比如把接口数据JSON.parse(JSON.stringify(res.data))再赋给ref此时数据虽然是新的但不会再触发视图更新。记住一个原则用ref就用ref用reactive就用reactive中间不要反复用深拷贝隔离响应式。还有一个和动态表单相关的坑如果页面里有点击添加一行课程信息的需求用v-model绑定formRows[index].title时保证formRows是用reactive([])定义的数组新增行时formRows.push({ title: , duration: })这样绑定才会生效。一旦用JSON.parse(JSON.stringify(...))复制数组再赋值新加的行就绑不上v-model了。5.3 MySQL8.0的两个实操问题第一个是连接串的时区问题很多刚跑项目的人会遇到java.sql.SQLException: The server time zone value ... is unrecognized解决办法是在JDBC连接串里加serverTimezoneAsia/Shanghai。第二个问题是驱动包版本如果用Maven引依赖推荐用dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version8.0.33/version /dependencymysql-connector-j是官方新版坐标旧坐标mysql-connector-java目前也还能用但已经不是首选。如果你是手动导入jar包的千万别拿5.x的驱动去连MySQL8.0会直接报认证插件错误。顺便说一句新项目请为数据库单独建一个业务账号不要全部用root。这不是危言耸听我见过不止一个同学的库只有一个root用户等项目分享给别人看时被随手删了库心态直接崩。5.4 文档怎么组织才能让这套源码含金量真正配得上标题这套源码自带文档是很大的优势但很多人的文档就是复制粘贴的模板答辩老师一眼就能看穿。我建议按下面的清单来组织每份文档都有明确的用途需求说明书写清楚角色、功能清单、业务流程、用例图。重点画一张业务流程图把学生购课学习和讲师管理课程两条主链路易失清楚地表达出来。数据库设计文档每张表的结构、字段含义、ER图都要有。重点说明订单表和报名表分离的设计原因这里是最容易出彩的部分。接口文档建议用Swagger/OpenAPI生成导出PDF或Markdown内容包括URL、请求参数、返回结构、权限要求。接口文档专业与否直接影响别人对你代码专业度的判断。部署文档从环境安装到前后端启动到常见问题排查写成步骤清单。哪怕是给你的同学看这条都能省下大把沟通时间。答辩汇报提纲把技术亮点JWT认证、事务控制、拦截器、MyBatis-Plus优化、数据库设计和业务闭环讲清楚。答辩不是念代码是讲设计这部分提前准备效果差别极大。我个人的习惯是代码写完第一时间补文档千万别等有时间了再写。等代码放几天再回头你连当初为什么起这个字段名都可能忘了。写文档过程和代码评审一样经常能逼自己发现设计上的破绽。我自己的体会是这套系统恰好处于一个特别舒服的工程区间没有堆微服务、没有上分布式中间件而是把一个垂直的在线教育场景老老实实做透。后端用SpringBoot2把生态和稳定性吃满前端用Vue3获得现代化的开发体验持久层靠MyBatis-Plus省下大量模板代码存储落在MySQL8.0上保持数据可靠性。四个环咬合得很顺是那种明眼人一看就知道能跑、能交付、能扩展的架构。如果你准备基于它做真实业务后续有希望扩展的方向是接入真实微信支付和支付宝支付、用对象存储加CDN承载视频点播、用Redis做登录验证码和课程排行榜。代码层面需要时刻绷紧两根弦事务边界和数据级权限这两个点不出问题系统的稳定性基本就有了保障。最后再多说一个小技巧把application.yml里的配置全部写上中文注释尤其是数据库连接、JWT密钥、文件上传路径这三处。每次迁移环境、交给别人二次开发时这些注释能省掉大量这个配置到底什么意思的沟通成本。这个细节看起来不起眼但我在深夜排查问题的时候深深感谢过当初那个愿意写注释的自己。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门