SpringBoot+Vue校园视频平台:从零搭建到答辩全指南
1. 校园视频平台毕设选它到底值不值每年毕业设计选题季我都会被问到同一个问题“学长我想做个视频平台用Spring Boot加Vue行不行”我的回答通常很直接行而且这个组合非常稳。你看到的这个标题“基于SpringBoot Vue校园系视频平台系统”几乎就是这类题目的标准配置它之所以能成为计算机毕业设计里的常青树原因其实不复杂一方面前后端分离的架构是目前企业开发的主流形态面试官看着顺眼另一方面Spring Boot加Vue的技术栈覆盖了后端、前端、数据库、权限、文件存储、视频流处理等多个维度足够撑起一篇有分量的毕业论文。但我要先给你泼一盆冷水这类项目最大的坑不在技术本身而在于很多同学图省事直接去下载一个“完美源码”结果答辩的时候连项目结构都讲不明白被老师追问几个细节就直接卡壳。我见过太多这种翻车现场了。所以这篇博文我不会只给你贴一段代码让你抄我会把整个校园视频平台从零搭建的思路、数据库设计、核心功能实现到答辩准备一条龙讲清楚。不管你最终是打算自己敲一遍还是在现成源码基础上改造你都需要理解这个系统每一层到底在干什么、为什么这么做。这个项目适合谁三种人最爱第一Java方向的学生想通过一个项目把Spring Boot、MyBatis-Plus、JWT这些知识点串联起来第二前端方向的学生想练手Vue全家桶、Element UI组件库、视频播放器集成这些实战技能第三就是那些已经工作但想巩固全栈能力的开发新人。无论你是哪一类读完这篇文章你应该能回答这几个问题数据库为什么这么建表视频为什么走m3u8切片而不是直接传MP4跨域问题怎么处理部署的时候需要注意什么2. 整体设计思路与技术选型拆解2.1 前后端分离到底“分”的是什么校园视频平台这类系统核心用户是学生和教师两类角色功能无外乎浏览视频、上传视频、搜索、评论、收藏、个人中心。功能看着简单但你如果真做成一个单体项目——也就是前端页面由Thymeleaf模板直接渲染后端一把梭——那这个毕设的技术含量就大打折扣了。前后端分离不是说把代码分成两个文件夹就叫分离它的本质是两个独立的工程通过HTTP接口通信。前端工程跑在Node环境下负责渲染页面、路由跳转、状态管理后端工程跑在Tomcat内嵌容器里只负责提供RESTful API和业务逻辑处理。我为什么建议你一定要做前后端分离第一个理由是就业导向。你去翻一下现在的Java岗位JD十个有八个要求“熟悉前后端分离开发模式”你毕设里体现了这个面试的时候就有话可讲。第二个理由是调试体验。前端用Vite或者Vue CLI启动后实时热更新改一行代码浏览器立刻刷新后端用Spring Boot DevTools也能做到改代码自动重启开发效率比传统JSP高了一个量级。第三个理由是部署灵活前端构建出静态资源后丢到Nginx后端打成Jar包跑在服务器上两边互不干扰。当然前后端分离也有代价。最典型的就是跨域问题。浏览器为了安全默认不允许一个端口上的页面去请求另一个端口上的接口。你在Vue开发服务器默认8080端口去访问Spring Boot默认8081端口的时候就会遇到CORS报错。解决思路一般有两种要么在后端配置CORS允许跨域要么通过Nginx做反向代理把 /api 前缀的请求转发到后端服务器。我个人的习惯是后端开发阶段用CrossOrigin注解或者一个CorsConfig配置类搞定上线阶段再交给Nginx处理。这样分工明确也符合企业实践。2.2 Spring Boot版本怎么选高了真的会出问题热搜词里有一条是“springboot版本太高”这个坑我还真踩过。很多同学在毕设开始前搜教程看到最新的Spring Boot 3.x版本就跃跃欲试结果项目搭到一半发现这个依赖不支持、那个配置变了心态直接崩了。我的建议很简单做毕设用Spring Boot 2.7.x这个稳定版本就好。为什么因为2.x版本生态成熟,网上能找到的教程、遇到过的坑、开源社区的回答数量都是最多的你遇到问题基本都能搜到解决方案。3.x版本虽然性能更好但它要求Java 17起步而且很多老版本的第三方库比如某些MyBatis-Plus版本、某些OSS SDK没有及时适配会带来一系列兼容性麻烦。这里给你一个非常具体的参考配置JDK建议用1.8或者11如果你用2.7.18这个终极版用JDK 8完全没问题。Maven仓库坐标大概是这样的parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version relativePath/ /parent依赖方面视频平台系统常用到的起步依赖有spring-boot-starter-webWeb开发、spring-boot-starter-data-jpa或者MyBatis数据访问、spring-boot-starter-security安全控制可选、spring-boot-starter-validation参数校验、spring-boot-starter-data-redis缓存可选。这里我要多说一句Spring Boot版本高低的本质不是“新就好用”而是“生态追踪”。你做毕设的目的是在有限时间内把项目完整跑通并讲明白没必要为了追新版本给自己增加排障碍的时间成本。等到你工作了在真实项目中再按团队的技术规范来选择版本也不迟。2.3 Vue怎么选Vue 2还是Vue 3环境怎么配热词里关于Vue的搜索量很大特别是“vue安装及环境配置”和“idea开发vue项目”。如果你Spring Boot选了2.7.x那前端这边我建议直接用Vue 3加Vite构建工具。别犹豫Vue 3从2020年发布到现在已经非常稳定了而且组合式APIComposition API会让你写代码的逻辑更清晰答辩的时候也更有内容可以讲。Vite比Vue CLIWebpack启动速度快得多大型项目冷启动从几十秒压缩到一两秒开发体验完全不同。Vue环境配置这块我把步骤给你理一下。第一步去Node官网下载Node.js 16或者18的长期支持版本安装的时候一路默认就行注意安装完成后要重新开一个终端窗口敲node -v和npm -v验证一下。第二步用npm install -g vue/cli或者直接创建Vite项目。我更推荐Vite方式npm create vitelatest campus-video -- --template vue cd campus-video npm install npm run dev第三步就是装UI组件库。做后台管理类的页面Element Plus几乎是首选。执行npm install element-plus然后在main.js里引入import { createApp } from vue import ElementPlus from element-plus import element-plus/dist/index.css import App from ./App.vue const app createApp(App) app.use(ElementPlus) app.mount(#app)这里注意一点Element Plus的按需导入虽然能减少打包体积但配置起来稍麻烦毕设项目我建议直接全量引入代码好写维护也没压力。Vue装完之后再配一下Vue Router路由和Pinia状态管理这两个是Vue生态里的标配视频平台的多页面跳转和用户登录状态管理都得靠它们。2.4 视频播放方案m3u8切片才是正解做视频平台绕不开一个问题视频怎么播最朴素的做法是后端存一个MP4文件的URL前端用标签直接播放。但你如果真这么干视频文件一大比如超过200MB浏览器直接播就会很卡拖动进度条要等半天甚至直接假死。毕设演示的时候遇到这种状况那种尴尬我不想再体验第二次。所以业界标准的做法是HTTP Live Streaming也就是HLS协议把一个大视频切分成无数个小分片后缀是.ts再用一个.m3u8索引文件去描述这些分片的播放顺序。前端播放器读取m3u8文件按顺序加载ts分片就能实现边下边播画质清晰、拖动流畅。具体怎么操作后端用FFmpeg工具把用户上传的视频转码成m3u8格式。我用一个真实的命令行给你演示ffmpeg -i input.mp4 -profile:v baseline -level 3.0 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls output.m3u8这个命令的意思是读取input.mp4把视频切成长度约10秒一片的ts分片并生成output.m3u8索引文件。参数-hls_time 10控制每个切片时长-hls_list_size 0表示不限制分片数量。如果是1080p高清视频还可以加上-c:v libx264 -crf 23 -preset medium压一下码率否则转出来的文件体积会很夸张。前端怎么播放m3u8如果你用的Vue我推荐video.js加videojs-contrib-hls插件。注意一点如果你用Vue 3原生video.js的HLS支持在部分浏览器上不够完整需要额外处理。一个比较省事的做法是安装hls.js这个库它兼容性好而且社区活跃。前端页面里引入hls.js后判断当前浏览器是否原生支持HLSSafari不支持就走hls.js加载if (video.canPlayType(application/vnd.apple.mpegurl)) { video.src videoUrl } else if (Hls.isSupported()) { const hls new Hls() hls.loadSource(videoUrl) hls.attachMedia(video) }这样用户看视频就非常顺滑了。锅里的肉始终有视频永远不会等你。3. 数据库设计与核心表结构3.1 从需求倒推建表五张核心表不能少数据库设计是答辩时老师必问的环节一问一个准。你要能说清楚每个表的字段为什么这么设计。校园视频平台我建议至少包含这几张核心表用户表user、视频表video、分类表category、评论表comment、收藏表favorite。如果还想做得更完整还可以加一张视频点赞表video_like或者播放记录表play_history。用户表字段不复杂id主键、username用户名、password密码、nickname昵称、avatar头像地址、role角色0学生、1教师、create_time创建时间。密码不能明文存一定用BCrypt加密后存入数据库。Spring Security或者Spring Boot自带的BCryptPasswordEncoder就能干这个事。这里要提一句很多人图省事建表时不加create_time、update_time等到后面做“最近发布”和排序功能时又回来补开学季这种返工我见得太多了建议你一上来就把这两个字段加上。视频表是核心中的核心设计的时候要想清楚一个视频不仅要有基本元数据更要有存储地址、封面图、转码状态、播放量这些业务字段。基本结构如下id视频唯一标识user_id上传用户ID外键关联用户表category_id所属分类IDtitle视频标题description简介cover_url封面图地址video_url原始视频地址或m3u8地址duration视频时长秒play_count播放次数status状态0转码中、1已发布、2下架视频表里有两个设计细节值得留意。第一play_count这种字段我建议直接冗余在视频表里而不是通过统计播放记录表来count因为count查询在数据量大时非常慢而且视频平台的播放次数本身就是个展示型数据实时性要求没那么高加一个字段更新即可。第二video_url我在生产环境中存的其实是m3u8文件所在的目录路径前端拼URL时动态拼前缀这样换域名或者换OSS的时候不用改数据库。这个思路是从实际项目里总结出来的虽然毕设阶段可能感觉不到好处但答辩时可以主动讲出来会显得你考虑问题很周全。3.2 评论表和收藏表别小看它们的设计评论表设计最重要的点是自关联。因为评论要支持楼中楼回复最简单的方式是加一个parent_id字段默认为0表示顶层评论不为0则表示回复的是哪条评论。再搭配reply_user_id记录被回复人的ID前端做功能的时候就非常轻松。表结构核心字段id、video_id、user_id、parent_id、reply_user_id、content、create_time。收藏表是典型的多对多关系拆解。用户和视频是多对多一个用户可以收藏多个视频一个视频也可以被多个用户收藏。为了描述这个关系必须拆一张关联表favoriteid、user_id、video_id、create_time。查询某个用户是否已收藏某视频只需要查这张表有没有对应记录。删除收藏就是删记录。这里的唯一性约束要加上联合唯一索引user_id, video_id确保同一用户对同一个视频不会产生重复收藏记录。分类表就很简单了id、name、sort。毕设阶段可以在启动时手动插入几条数据比如编程语言、软件教程、考研考公、校园活动、其他等。这一块没什么技术含量但注意要在文档里写清楚分类数据是如何初始化的答辩时有细节可讲。3.3 数据库增删改查的规范写法热词里有“数据库增删改查”这个基础功夫还是要练扎实。你用JPA还是MyBatis-Plus我推荐后者。MyBatis-Plus在国内使用率极高它把单表的增删改查简化到几乎不需要写SQL。引入依赖后用BaseMapper 接口继承就能获得insert、deleteById、selectById、updateById这些方法再配合lambdaQueryWrapper做条件查询开发效率高到飞起。举个例子写一个分页查询视频列表的接口public PageResultVideo getVideoList(int page, int size, Long categoryId) { PageVideo pageInfo new Page(page, size); LambdaQueryWrapperVideo wrapper new LambdaQueryWrapper(); if (categoryId ! null) { wrapper.eq(Video::getCategoryId, categoryId); } wrapper.orderByDesc(Video::getCreateTime); videoMapper.selectPage(pageInfo, wrapper); return new PageResult(pageInfo.getRecords(), pageInfo.getTotal()); }注意几个细节字段使用Lambda表达式既安全又省得写字符串导致拼写错误排序用orderByDesc按创建时间倒序status要加过滤器只查出已发布状态转码中的视频还没生成完就不能放出来。这套写法在整个项目里可以复用几乎所有的列表查询都是同一个套路写完一个功能其他的都是“复制改”。4. 核心功能实操与代码讲解4.1 用户登录注册与JWT权限控制校园视频平台的登录注册功能我强烈建议用JWTJSON Web Token方案而不是传统的Session。因为前后端分离后后端服务不再保存用户登录状态而是签发一个令牌给前端。前端每次请求时把这个令牌放在HTTP请求头里后端校验通过就放行。这样做的好处是服务无状态方便以后做多实例部署。具体流程前端用户在登录页输入用户名密码后端接收后先用BCryptPasswordEncoder去比对密码是否匹配。匹配成功就用userId、用户名、角色等信息生成一个JWT令牌有效期设个24小时就行设置太长不安全太短则用户频繁需要重新登录体验不好。后端取值校验可以写一个拦截器或者用一个简单的OncePerRequestFilterpublic class JwtAuthenticationFilter extends OncePerRequestFilter { Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String token request.getHeader(Authorization); if (StringUtils.hasText(token) token.startsWith(Bearer )) { token token.substring(7); // 解析token获得userId存入request属性 Long userId JwtUtil.parseToken(token); request.setAttribute(userId, userId); } chain.doFilter(request, response); } }注册的流程就更直接了前端提交username、password、nickname后端先查一下username是否已存在存在就返回“用户名已被注册”不存在就进行密码加密然后插入用户表。注意这一步的参数校验不能省略用户名和密码都不能为空密码长度至少6位使用Valid注解加DTO校验就能做到。4.2 视频上传、转码与访问路径设计视频上传是这个项目的重头戏。用户选中本地视频文件后前端先把文件对象通过axios传到后端后端接收MultipartFile将其写入磁盘的指定目录。目录结构建议按日期分层比如 /data/video/20240401/ 下面存放当天的视频文件这样以后清理旧数据或者做存储分析都很方便。核心代码PostMapping(/api/video/upload) public Result upload(RequestParam(file) MultipartFile file, RequestParam Long categoryId, HttpServletRequest request) { if (file.isEmpty()) { return Result.error(文件不能为空); } // 校验文件类型只允许mp4等常见格式 String originalFilename file.getOriginalFilename(); String suffix originalFilename.substring(originalFilename.lastIndexOf(.)); if (!suffix.equals(.mp4)) { return Result.error(仅支持MP4格式); } // 生成唯一文件名避免冲突 String fileName UUID.randomUUID().toString().replace(-, ) suffix; // 保存原始文件到临时目录 file.transferTo(new File(uploadDir fileName)); // 存入数据库status设为0转码中 // 异步调用FFmpeg转码脚本 transcodeService.transcodeToHls(fileName); return Result.success(上传成功); }上传后的转码动作一定要用异步线程池去执行不能堵在主请求里。因为转码可能要几十秒甚至几分钟用户不可能在页面上干等那么久。用Async注解标记一个转码方法或者手动丢进线程池执行都可以。转码完成后要更新数据库中的video_url字段并把status改成1。访问路径设计上有个容易踩坑的点如果把视频文件放在Spring Boot的static目录下虽然开发和测试省事但生产环境极不推荐。更好的方案是单独配置一个资源映射让 /videos/** 前缀映射到磁盘上的存储目录。这样视频文件和应用程序完全解耦将来换服务器、扩展存储都有余地。配置方式也简单spring: mvc: static-path-pattern: /videos/** resources: static-locations: file:D:/data/video/4.3 前端视频播放器页面封装前端视频播放页需要做两件事视频详情展示加播放器集成。页面布局一般是页面左上方是video播放器下面是标题、作者、播放量、简介、评论区域。播放器我建议封装成一个独立组件这样视频详情页、用户个人页、后台预览都能复用。封装VideoPlayer.vue组件时props接收videoUrlwatch监听url变化后重新加载播放器。这里有一个非常关键的cleanup操作组件卸载时一定要调用hls.destroy()方法否则组件来回切换会内存泄漏播放几次之后页面明显变卡。很多人的Vue项目写着写着就卡成PPT十有八九就是没有销毁播放器实例。评论区域也别做得太简单。发评论的时候需要把当前视频ID、用户ID、内容一起提交提交成功后刷新评论列表。回复评论时除了评论内容还要传parent_id和reply_user_id。前端为了方便回复输入框就放在每条评论下方点击“回复”按钮时把这个评论的信息填入表单输入完成后POST到同一接口。这样评论楼层的数据结构在后端统一处理前端代码也会清爽很多。4.4 搜索功能怎么做才不low搜索功能如果只是查出标题里包含关键字的视频那太初级了。至少要做到两点第一模糊匹配标题和简介两个字段第二搜索后能按相关度或者时间排序。用一个更专业的词来描述这就是“简单站内搜索”。当然如果只是用MySQL的LIKE来做数据量在几千条时也没什么问题wrapper.like(Video::getTitle, keyword) .or(wrapper.like(Video::getDescription, keyword));想要更进一步给视频表加一个“热度”字段用播放量的对数、点赞数、评论数组合成一个热度值搜索时把热度作为排序条件之一。毕设阶段如果不想引入Elasticsearch说实话引入ES对毕设有点过度设计而且答辩时候容易被追问集群、分片这些问题那就用MySQL的LIKE加上一个排序字段来撑着已经够用了。5. 常见问题排查与避坑手册5.1 Spring Boot版本过高引发的连锁地震前面我提了“springboot版本太高”这里把具体惨状展开一下。有同学用Spring Boot 3.2去整合MyBatis-Plus结果发现默认的mybatis-plus-boot-starter版本下无法启动报错多是“NoSuchMethodError”或者“Failed to instantiate”。为什么因为Spring Boot 3.x是基于Jakarta EE规范的javax.servlet命名空间变成了jakarta.servlet。第三方库如果不更新到适配版本就会因为包名对不上而启动失败。排错思路也不难看一眼控制台的错误日志找第一行Caused by的位置绝大多数时候就是某个依赖版本不对。别再全网搜“为什么报错NoSuchMethodError”了先确认你Spring Boot版本是多少再回去看对应库的兼容矩阵。方法总比问题多但前提是你得知道问题出在哪一层。5.2 前后端联调时的CORS跨域与接口对接跨域报错长这样CORS policy: No Access-Control-Allow-Origin header is present on the requested resource. 此时我用过的比较省心的解决方案是后端写一个配置类Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }这段配置允许所有来源跨域访问。毕设阶段这样做没问题但我要提醒一句生产环境allowedOriginPatterns不应该写“*”而应该只写前端的域名。接口联调时还有另一个高频问题前端传参格式和后端接收不一致要么用qs库将对象转成URLSearchParams格式要么后端统一用RequestBody接收JSON选择一套方案然后全项目统一不要一会儿用表单格式一会儿用JSON。保持代码风格的一致性是让项目不“廉价”的关键。5.3 视频播放黑屏或转码卡住的排查清单视频上传后页面黑屏、播放不出画面这个问题的排查路径很固定。第一步看FFmpeg执行的日志看转码有没有完成、m3u8文件是否生成。第二步看m3u8文件里的ts分片引用路径是相对路径还是绝对路径如果引用路径里写死了本机磁盘路径前端自然访问不到。第三步看前端播放时的Network面板点击那个ts分片请求看返回状态码如果404就说明路径拼接有问题如果200却还黑屏就要检查CORS了因为m3u8和ts文件序列默认是跨域的服务器需要响应正确的CORS头。再一个常见问题是FFmpeg命令执行权限不足导致转码失败。Windows下如果装的是Linux子系统或者使用了某些压缩版FFmpeg路径配置错就会静默失败。建议转码方法里加异常日志的记录把FFmpeg的完整输出写到日志文件里排查时直接打开看具体是哪一步失败能省下一大堆时间。5.4 数据库连接不上和中文乱码数据库连不上翻来覆去就那几个原因密码写错了、端口写错了、IP写了localhost但MySQL绑定的地址不是、MySQL服务没启动。你在application.yml里配置数据源时一定要加上useUnicodetruecharacterEncodingutf8防止中文乱码。连接MySQL 8.x时驱动类要写 com.mysql.cj.jdbc.Driver写旧的com.mysql.jdbc.Driver虽然有时候不报错但会有警告答辩时被看到不专业。完整的配置参考spring: datasource: url: jdbc:mysql://localhost:3306/campus_video?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver建表时统一utf8mb4字符集不要用默认的latin1。utf8mb4比utf8多支持了emoji字符集评论功能大家发个表情也不至于乱码。6. 交付三件套源码、数据库、文档怎么准备做毕业设计老师最看重的不只是功能跑通更是你交上来的东西“像不像一个完整的工程”。标题里强调“源码数据库文档”这三个交付物我按照经验帮你把每个部分应该长什么样理清楚。源码这块前端和后端要分两个独立文件夹每个下面都要有清晰的README.md文件。README里至少要包含项目简介、技术栈列表、启动步骤怎么装依赖、怎么初始化数据库、怎么启动后端、怎么启动前端、默认账号密码。不要小看这个README答辩时老师很可能直接打开你的项目按你的文档一步步操作你的文档写得越顺畅老师心里的分就给得越高。后端项目的代码结构以常见的controller、service、mapper、entity、config、utils分层为佳每层的职责要单一不要在Controller里写一大段业务逻辑不要在Service里拼接HTML这个坏毛病我在很多下载的源码里见过看见就想骂人。数据库交付物有两种形式。第一种是创建一个database.sql文件包含建表语句和初始化的测试数据。但有些老师会直接要求你提供数据库脚本所以我建议你把建库、建表、插入初始数据分成三段SQL用注释分隔方便老师按顺序执行。第二种是使用数据库管理工具导出一个备份文件。我个人推荐前者因为.sql文件用文本编辑器就能查看而且兼容性最好老师不管是MySQL 5.7还是8.0都能顺利导入。文档是重头戏一般包括开题报告、需求分析、系统设计、数据库设计、系统实现、总结致谢这些章节。系统设计中的功能模块图、流程图不要画那种又花哨又空洞的图要跟你的代码实际实现一一对应。数据库设计部分把ER图和表结构说明贴全每个字段的中文含义写清楚。系统实现部分不要期望口头描述能糊弄过去配关键功能截图把核心代码段贴上去并逐段解释。别忘了准备一个“系统演示说明”讲清楚演示时先展示什么、再展示什么、如果用测试账号登录后能做什么操作。另外提醒一个很多人会忽略的细节项目里的配置文件不要出现你自己的绝对路径比如D盘某处文件夹。所有路径尽量用相对路径或者是可从application.yml里配置的可变量这体现的是工程素养。前端所有请求地址可以单独抽出一个api.js文件统一管理baseURL不要在每个组件里硬编码localhost加端口。如果交作业时老师换个机器运行硬编码的地址就会让人跑不起来印象分直接腰斩。7. 答辩准备与演示技巧别让好项目毁在嘴上其实代码写完了项目能跑起来你的毕设已经完成80%了。剩下那20%是答辩。很多技术很强的同学最后栽在答辩环节不是因为他没做出来而是他没法把自己的工作清晰地传达给老师。我建议你答辩前准备一个“演示脚本”严格按顺序过一遍先登录系统展示正常登录、错误密码登录接着浏览首页视频列表展示分类筛选、搜索功能然后点开一个视频播放展示播放器加载、评论展示接着发一条评论展示评论功能、权限校验再切换用户或者进入后台展示管理员和普通用户的不同权限最后讲数据库的几个关键表和字段设计。演示过程中最容易被提问的知识点十有八九集中在这几个位置事务管理是怎么做的——比如用户点赞时点赞表插入记录和视频表点赞数加一这两步是不是在一个事务里缓存用没用、为什么用分页是怎么实现的上传视频过程中如果网络断开了怎么处理这里可以坦诚讲清楚毕设阶段有考虑但不完善然后说出你的改进思路老师反而会觉得你思路清晰。当年我见过一个学生被问到缓存时说“还没做但这块可以优化计划在查询视频列表时用Redis缓存热数据”老师笑了笑直接放过。关键不在于你要把所有功能做到完美而在于你要能指明系统的边界和后续扩展方向。这比空吹牛强一万倍。8. 我踩过的几个坑提前告诉你最后分享几条实操中积累下来的经验都是常规文档不会写的。第一前端依赖安装时npm经常因为网络问题卡住或者慢到怀疑人生。可以先执行npm config set registry https://registry.npmmirror.com 换成国内镜像这会让你省下大半天的安装等待时间。第二Maven同样有镜像问题在Maven的settings.xml里配置阿里云镜像下载依赖的速度差别巨大。第三校园视频平台如果视频量不大几百个视频没必要单独用OSS存储放到本地磁盘就够但如果视频量真的上来了记得把存储策略调整成对象存储加CDN加速这些答辩时都可以当成“系统演进方向”讲出来。还有一点是关于部署的。你应该至少学会把整个项目在本地以“生产模式”跑一遍。也就是前端执行npm run build生成dist静态文件然后用Nginx托管再单独启动后端Jar包。这个过程走通后你对整个前后端交互的理解会产生质的变化。很多人平时开发依赖Vite的代理转发从来没有意识到真实环境里静态资源和API的分离是什么状态。我确信你走完这一步再写总结时会写出很多别人写不出的东西。如果你正在做这个题目做完之后你会发现这个项目表面上是一套视频平台系统实际上它把Java后端开发、前端工程化、数据库设计、多媒体处理、文档编写的能力全都串了一遍。这就是它作为毕业设计的最大价值——它逼着你把大学四年学的东西从碎片变成体系。哪怕你以后不从事Web开发这套从需求分析到设计到实现的完整闭环思维走到哪里都用得上。祝你在做毕设的这段时间里少熬夜多产出答辩顺利。