
儿童教育网站项目实战SpringBoot 整合 Vue.js 前后端分离架构从建表到部署一次讲透如果你正在为“计算机毕业设计选什么题”纠结或者手头刚好接了一个 SpringBoot 基于 Vue.js 的儿童教育网站要落地那这篇东西应该能帮你省掉不少弯路。儿童教育网站本质上是一套“学前教育资源数字化服务系统”面向家长和孩子提供课程点播、亲子互动、学习打卡这类能力。前端用 Vue.js 负责页面展示和交互后端用 SpringBoot 提供接口服务是典型的前后端分离架构。我完整跑通过一个类似的少儿在线学习互动平台从选题、建表、写接口到打包部署都踩过不少坑。下面把能直接抄作业的部分整理出来按需求设计、后端实现、前端联调、部署演示、避坑排查五块来讲每块都会解释清楚为什么这么做而不是只给结论。1. 项目需求拆解先把“儿童教育网站”变成一张能落地的功能地图很多同学拿到这类题目第一反应是打开后台管理系统模板直接套结果做完发现界面挺好看业务逻辑全是一堆增删改查答辩时连“你这个项目解决什么真实问题”都答不利索。所以第一步千万别急着写代码先把需求拆清楚。1.1 三类角色三条主业务线儿童教育网站至少要有三类角色家长、孩子、管理员。为什么不是简单的“用户管理员”因为家长和孩子虽然共用同一个平台但使用场景完全不一样。家长侧注册登录、浏览课程、给孩子选课、查看学习进度、查看成长报告、充值或领取优惠券。孩子侧登录后进入“学习中心”看视频课、做互动练习、打卡、获取星星和勋章。管理员侧课程分类管理、课程上下架、内容审核、评论管理、数据看板。这三条业务线不是平行的而是围绕“孩子到底学没学、学到哪”这条核心数据链展开。家长选课 - 孩子学习 - 产生学习记录 - 家长查看反馈这才是学前资源的完整闭环。如果只是做一套课程展示网站缺少学习记录这个环节项目就会显得特别单薄。1.2 功能清单到数据库模型的翻译过程需求拆完就要翻译成数据模型。我在设计表结构时总结了两个核心原则第一一张表只描述一件事第二表之间的关联尽量用外键字段表达不要绕圈子。以这个项目为例核心表大概是这么几张用户表包含家长和孩子用角色字段区分孩子表记录 parent_id 关联家长课程分类表、课程表、课程章节表学习记录表记录某个孩子对某个章节的学习进度、状态、最近学习时间积分/星星表记录孩子获得的奖励评论表包含审核状态字段公告表、轮播图表、订单表如果要做付费课程这里最容易被忽略的是“学习记录表”。很多同学以为课程表是最核心的其实学习记录才是这个项目的灵魂。家长端“我的孩子”页面能看到的进度百分比孩子端“继续学习”按钮跳转到第几章节都靠这张表支撑。哪怕功能再简单也必须把这张表设计扎实。建表时建议直接用 MySQL 的 InnoDB 引擎字符集用 utf8mb4因为课程标题、评论内容都可能包含 emoji 符号utf8mb4 才能存得下。下面是学习记录表的一个参考 SQL字段不用多但关键字段不能少CREATE TABLE study_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, child_id BIGINT NOT NULL COMMENT 孩子用户ID, course_id BIGINT NOT NULL COMMENT 课程ID, chapter_id BIGINT NOT NULL COMMENT 章节ID, study_status TINYINT DEFAULT 0 COMMENT 0未完成 1已完成, progress INT DEFAULT 0 COMMENT 章节内学习进度(0-100), last_study_time DATETIME DEFAULT NULL COMMENT 最近学习时间, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_child_chapter (child_id, chapter_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT学习记录表;注意 UNIQUE KEY 的设计。一个孩子对同一个章节只保留一条记录后续学习就更新这条记录的 progress 和 study_status这样才能支撑“继续学习”功能也不会因为重复点击产生脏数据。1.3 为什么前后端分离在这里是加分项而不是花架子现在做毕设标题里不带“前后端分离架构”好像都少了点什么但这个架构在儿童教育网站里确实有真实价值。前端 Vue.js 负责渲染后端 SpringBoot 只吐 JSON这是目前企业项目的主流分工方式两个人可以并行开发前端调接口、后端改逻辑互不阻塞。更重要的是答辩时好讲。你可以清晰地说清楚用户点击课程 - 前端 Axios 请求 /api/course/detail - 后端 Controller 接收参数 - Service 处理业务 - Mapper 查询数据库 - 返回 JSON - 前端渲染。这个链路在面试官听来非常清楚。还有一个细节要注意前后端分离意味着部署时前端代码和后端 Jar 包是两套产物。常见做法有两种一种是把前端构建出来的 dist 目录复制到 SpringBoot 的 static 目录下打成单 Jar 运行另一种是用 Nginx 托管前端静态资源再反向代理到后端的 8080 端口。考试和面试时这两条路都得能说清楚后面部署章节我再展开。2. SpringBoot 后端设计与核心实现后端是这类系统的地基。地基不牢前端写得再花哨演示的时候随时可能塌。这一节我按照实际开发顺序来讲技术选型、数据库设计、接口层设计、内容安全每一步都是实战经验。2.1 技术选型够用、好讲、不过度设计技术栈选择有一个很现实的标准不是越高级越好而是你要能给答辩老师讲明白还要能在有限时间内把功能写出来。我在这个项目里用的组合是SpringBoot 2.7 MyBatis-Plus MySQL 8.0 JWT Redis可选。为什么不直接上 Spring Security因为 Spring Security 对新手不友好配置复杂一个过滤链就能把人绕晕。毕业设计阶段用 JWT HandlerInterceptor 实现登录鉴权代码量少、逻辑直观、自己完全能讲清楚。如果项目本身有“用户”“权限”“评论审核”这些环节JWT 方案已经够覆盖了。ORM 我用 MyBatis-Plus不是因为它性能比 MyBatis 强而是它的内置 BaseMapper 自带单表 CRUD可以省掉大量重复的 XML 文件。这个项目里只有多表关联查询和复杂统计才需要手写 SQL其他单表操作直接用 Wrapper 条件构造器解决开发效率至少提升一倍。Redis 属于可加可不加的项。我当时加了用来缓存课程分类列表和热门课程效果很明显首页接口压力瞬间降下来。但如果你对 Redis 不熟不加也不扣分只要在答辩时能说清楚“为什么这里可以用缓存、什么条件下缓存会失效”就已经是加分项了。2.2 数据库设计学习记录表是这个项目的心脏后端开发的第一步永远是设计数据库。前面给了学习记录表的 SQL这里再补两张关键表的设计思路。第一张是用户表。家长和孩子都存在一张表里用 role 字段区分孩子表加 parent_id 外键。这个设计比“家长表孩子表分开建”要方便得多因为登录逻辑可以统一走一套。登录时根据账号查用户后端再判断角色跳转到不同首页前端做路由拦截时也非常顺。第二张是课程表。我建议至少包含这些字段课程标题、封面图 URL、分类 ID、适用年龄区间、课程简介、上下架状态、点击量、创建时间。注意“适用年龄区间”这个字段学前教育平台特别强调年龄分层3-4 岁和 5-6 岁孩子适用的内容完全不同这个字段可以作为前台筛选条件也可以作为推荐逻辑的基础。课程与章节是一对多关系章节表里要有章节序号、章节标题、视频 URL、章节时长、是否免费试看。是否免费试看这个字段很关键它撑起的是课程详情页的“试看前3分钟”功能。没有试看逻辑的儿童教育平台变现路径是不完整的答辩时被问到商业模式就答不上来。2.3 接口层设计统一返回体、登录鉴权与文件上传后端接口层最大的坑是每个接口返回的数据格式不统一。有的返回 Map有的直接返回实体类前端拿到数据后不知所措。我从项目一开始就定了统一返回体ResultT所有接口必须走这一层。Data public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }配合统一异常处理RestControllerAdvice所有业务异常、参数校验异常都能按照统一格式返回前端拦截器只需要判断 code 是不是 200 就行不用每个接口单独处理错误逻辑。登录鉴权我用 JWT 加拦截器。用户在登录接口拿到 token 后前端把它存到 localStorage在 Axios 的请求拦截器里带上Authorization头后端写一个 LoginInterceptor 拦截/api/**路径从 token 里解析出用户 ID 和角色放入 ThreadLocal。除了登录、注册、课程列表这些公开接口要放行其他接口一律拦截。还有个高频场景是文件上传。课程封面、孩子作品图片、头像都要用到 MultipartFile。毕设阶段不建议一开始就接阿里云 OSS因为涉及密钥配置、跨域问题容易卡住。先在本地配置一个upload.path路径把文件写入磁盘再给前端返回一个可访问的 URL 映射地址等系统跑通了再把这个上传逻辑抽象出来接 OSS 也不迟。注意本地路径千万别写在业务代码里硬编码放到 application.yml 里方便后续部署环境调整。2.4 内容审核与家长控制让系统多一个运营后台儿童教育内容有特殊性课程视频、评论内容都不应该无审核直接上线。这个需求在毕设里不只是“合规要求”它其实为你增加了一个完整的后台管理场景。具体来说课程表和评论表各加一个status字段取值分别是待审核、已通过、已驳回。管理员后台只在 status1已通过的数据里操作孩子在客户端看到的内容也必须过滤掉非通过状态。评论功能更是如此孩子或家长发表评论后先进入待审核管理员审核通过后才在前端展示。我当时的做法是给孩子端评论列表接口加了一个条件WHERE status 1管理员审核接口则能查到所有状态的记录。这个小设计在答辩时特别好讲因为它体现了“儿童内容平台必须有内容安全机制”这个业务认知比单纯把 CRUD 做完高一个档次。家长控制的设计也一样家长账号可以查看孩子的学习报告设置每日学习时长。这个功能做起来其实不复杂无非是家长端多一个“我的孩子”页面后台通过 parent_id 查出孩子的学习记录计算今日总时长。但它的意义在于让系统真正具备“亲子共育”的场景而不是一个纯粹的儿童视频网站。3. Vue.js 前端交互设计与联调前端要用 Vue.js 把“儿童感”做出来。儿童教育网站不能做得跟后台管理系统一样灰扑扑的它必须让家长觉得放心让孩子觉得好玩。这一节我按搭建骨架、鉴权封装、核心页面、跨域联调四个角度展开。3.1 用 Vite Vue3 搭建前端骨架现在做 Vue 项目我建议直接用 Vite Vue 3不要再碰 Vue 2 加 Webpack 那套老组合。Vite 启动速度快、依赖安装简单而且 Vue 3 的组合式 API 写起来比 Options API 更顺手代码组织也更清晰。前端项目结构可以这么规划src ├── api // 所有请求接口统一封装 │ ├── course.js │ ├── user.js │ └── study.js ├── assets // 静态资源 ├── components // 通用组件 ├── router // 路由配置 ├── store // Pinia 状态管理 ├── views │ ├── parent // 家长端页面 │ │ ├── Home.vue │ │ ├── CourseList.vue │ │ └── ChildReport.vue │ └── child // 孩子端页面 │ ├── StudyCenter.vue │ └── TaskList.vue └── utils // 请求封装等工具UI 组件库用 Element Plus 就够但要做一件事覆盖它的默认样式让整体视觉偏圆润、偏明亮。比如给全局 CSS 设置圆角变量--el-border-radius-base: 12px卡片式布局加大阴影按钮用绿色或橙色主色调孩子的学习页面可以单独用一套更鲜艳的配色。前端整体视觉观感是答辩第一印象这个时间花得值。3.2 路由守卫与 Axios 封装业务代码不和鉴权逻辑混在一起前端鉴权绝对不能在每个页面里写一遍“判断有没有token”必须统一处理。路由配置里在需要登录才能访问的路由 meta 上标记requiresAuth: true然后在router.beforeEach里做判断router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next({ path: /login, query: { redirect: to.fullPath } }) } else { next() } })Axios 封装是另一个容易踩坑的地方。请求拦截器统一加 token响应拦截器统一处理业务错误和 401 状态。当后端返回 401 时前端自动跳转登录页并清除本地 token这个逻辑只写一处所有接口都会生效。service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] token } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { ElMessage.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res }, error { if (error.response?.status 401) { localStorage.removeItem(token) router.push(/login) } ElMessage.error(error.message || 网络异常) return Promise.reject(error) } )3.3 三个核心页面的实现思路课程列表页是家长端访问量最高的页面。我建议用左侧分类 Tab 加右侧课程卡片的形式每个卡片展示封面、标题、年龄区间和点击量。分类切换通过调用接口传 categoryId 实现不要把所有数据一次性加载出来再前端筛选这样既慢又不专业。课程详情页要分上下两个区域上面是视频播放器下面是课程章节列表。视频播放我直接用原生 video 标签设置preloadmetadata提高首屏加载速度。章节列表中已完成的学习记录打上“已学完”标记未学习的显示“继续学习”按钮。后端接口返回课程详情时顺带把当前用户的学习记录一并返回前端就不用再发第二次请求。孩子端的学习中心是卖点页面。我做了两个核心模块今日任务和打卡日历。今日任务从后端查出来按“待完成/已完成”分组展示打卡日历用轮询接口查最近30天的学习记录在日历上标记打勾。这个页面对应的是孩子侧“坚持学习”的激励逻辑看起来简单但它是整个平台“互动”属性的集中体现。3.4 跨域与联调Vite 代理是最省心的姿势前后端分离开发时前端跑在 5173 端口后端跑在 8080 端口必然遇到跨域问题。处理方式有两种后端写 CORS 配置或者前端用代理。我的经验是优先在前端解决用 Vite 的 proxy 配置不仅开发环境省心还可以在后端不写任何跨域代码的情况下完成联调。// vite.config.js export default defineConfig({ server: { port: 3000, proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })前端所有请求统一加/api前缀代理会把/api开头请求转发到后端同时后端接口的 context-path 也设置为/api这样开发环境和生产环境的请求路径就是一致的。等部署到服务器时前端是一套静态文件后端是一个 Jar 包跨域问题交给 Nginx 转发处理前端代码一行都不用改。这个方案是我实测下来最不容易出错的。4. 打包部署与答辩演示准备能从本地跑通到能在服务器上跑通中间还隔着不少坑。很多同学演示前才发现“首页能进课程详情打不开”大多都是部署阶段没处理好静态资源和接口路径的关系。这一节把部署路线讲清楚。4.1 前后端产物怎么组合运行后端打完包是xxx.jar用java -jar就能跑。前端npm run build生成 dist 目录里面是静态 HTML、JS、CSS。两套产物组合方式我强烈推荐 Nginx 方案因为它更接近真实项目。Nginx 配置的关键就两块root 指向前端 dist 目录处理静态资源location /api 反代到后端。server { listen 80; server_name your-domain.com; location / { root /usr/share/nginx/html/dist; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }注意try_files这一行。Vue Router 使用 history 模式时刷新某个子路由会出现 404比如直接访问/course/1Nginx 不知道这个路径对应哪个静态文件必须靠try_files ... /index.html把请求兜回前端入口由 Vue Router 自己处理。4.2 演示数据与初始化 SQL 的准备答辩演示最怕的是空数据。评审老师打开课程列表发现一个课程都没有后续功能根本不用看了。所以准备工作里最不能省的一步就是准备一份初始化 SQL除了建表还要插入 10 门左右课程、每门课 3 到 5 个章节、一个家长账号、一个孩子账号、若干条学习记录。我的建议是学习记录里的“最近学习时间”做成最近三天的这样演示时打卡日历不是空白的进度条也能展示出各种状态。课程封面图片不要全部用外链万一现场没网整个页面就会很难看。本地准备一份 images 目录放到静态资源里用相对路径引用。视频文件体积大用外链或本地小文件都行但要提前测试能否流畅播放。4.3 Docker 与宝塔部署的加分操作部署方式写到 Docker 会在技术答辩中明显加分因为 Docker 本身是当前后端技术的热点。我当时的做法是写一个简单的 Dockerfile把 Jar 包打进镜像再用 docker-compose 同时启动 MySQL 和项目容器一条命令把所有服务拉起来。如果你第一次接触可以先用宝塔面板的可视化界面部署点几下就能把 Jar 启动脚本和 MySQL 都配置好亲测对新手非常友好。无论用哪种方式部署完一定要做一次“全新环境验证”清空浏览器缓存用手机访问服务器公网地址从注册账号开始走一遍完整流程。这一步能发现很多只在开发环境看不出来的问题比如前端资源路径引用错误、数据库连接配置没改、上传文件目录权限不足。5. 常见问题排查与避坑记录最后集中整理一下我在这个项目里遇到的典型问题做成速查表再挑几个印象最深的坑详细讲讲希望能帮你少走弯路。5.1 高频问题速查表现象可能原因解决思路前端页面白屏Vue 路由 history 模式没有配置 try_filesNginx 加入try_files $uri $uri/ /index.html接口报 CORS 错误跨域没有走代理或后端没配置跨域开发环境用 Vite proxy生产环境用 Nginx 反向代理登录后刷新页面状态丢失只存了 token 没存用户信息刷新时用 token 调用/user/info重新拉取用户信息课程列表接口超时单表查询没有做分页后端使用 MyBatis-Plus 分页插件前端传 pageNum/pageSize上传图片后访问 404本地路径映射没配置后端配置资源映射把 upload.path 映射到/upload/**数据库插入中文乱码数据库或连接串字符集不是 utf8mb4建表指定 utf8mb4JDBC URL 加characterEncodingutf8mb4评论提交后前端不显示评论是待审核状态被过滤检查 status 字段的过滤条件确认管理后台审核流程每次重启 Jar 后上传的文件丢失文件写进了项目部署目录上传路径改为系统绝对路径如/data/upload不要放 static 下5.2 三个让我印象最深的坑第一个坑是前端拿到的 JSON 字段名对不上。MySQL 表字段是下划线风格比如parent_id后端若直接放回实体类MyBatis 默认开启驼峰映射才能转成parentId。当时没开这个配置前端一直取到 undefined。解决办法是在 application.yml 里加一句map-underscore-to-camel-case: true或者干脆在实体类上给接口字段写清楚注解。第二个坑是文件上传路径。我曾经把上传目录设置成项目根目录下的 upload本地调试没问题部署到服务器后每次用java -jar重启都会因为目录不存在或权限不足报错。后来改成在系统绝对路径/data/upload下存储并在 WebMvc 配置里做静态资源映射问题一次解决。记住一个原则程序里的文件写入路径永远不要依赖当前工作目录。第三个坑是 Element Plus 的表格分页和后端 Page 对象对接不上。前端把current和pageSize传给后端后端返回total和records但两边的字段名如果对不上表格就会一直显示空白。我的习惯是后端统一返回 MyBatis-Plus 的 Page 对象前端 Axios 直接读res.data.records和res.data.total组件绑定对应字段避免转换。5.3 答辩演示前一定要检查的细节演示前一天按下面的清单过一遍能避免至少 80% 的突发状况。第一预置两个演示账号一个家长一个孩子密码简单好记直接放在演示文稿第一页第二确认演示设备能访问部署地址如果是本地启动提前把项目跑起来不要让老师看着你敲命令第三清掉测试过程中产生的垃圾数据比如姓名乱填的用户、重复的评论第四复习几个“计算公式”比如学习进度百分比是怎么算的、打卡日历的连续天数是怎么统计的这两个问题几乎必被问到。我个人在实际操作中的体会是儿童教育网站这个题目的难度和亮点之间平衡得很好关键技术点都是主流方向不容易跑偏真正拉开差距的是你有没有把“孩子的学习体验”这个细节想清楚。当时我把打卡日历和学习报告放在最显眼的位置答辩时老师明显对这部分更有兴趣。如果时间紧先把课程展示和学习记录两块做透其他功能可以往后排。最后再分享一个小技巧项目里随便哪个页面遇到问题优先看浏览器控制台和 Network 面板前端报错和后端报错都要能看懂排查速度能快一倍。