SpringBoot+Vue在线学习平台毕业设计全流程实战指南

发布时间:2026/10/11 14:21:32
SpringBoot+Vue在线学习平台毕业设计全流程实战指南
看到“SpringBootVue在线学习平台毕业论文指导视频”这个组合我第一反应就是标准到不能再标准的计算机毕业设计选题。这类项目我接触过太多回了从课堂作业到本科毕设再到培训机构的结业项目几乎每个学Java的学生都会在某个阶段和它打交道。你可能会觉得这题目太泛滥、没新意但说句实在话在线学习平台恰恰是每年毕业设计里“性价比”最高的题目之一。为什么这么说因为它业务逻辑足够清晰角色划分明确前端后端都有大量可展示的成果而且天然适合扩展——你加个视频播放是学习平台加个题库考试是培训系统加个会员订单就是知识付费。更关键的是SpringBoot和Vue这套前后端分离的组合是目前企业里非常主流的开发范式做完这个项目你写进简历里的技术栈是实打实的不是空中楼阁。这篇文章我就把这套系统从选题、架构、数据库设计、核心功能落地到论文撰写、常见坑位排查完整地拆一遍希望能给正在做或准备做这个题目的你一些可以直接拿去用的思路。1. 先想清楚再做在线学习平台到底在做什么很多同学拿到题目第一件事就是打开编辑器写代码这其实是本末倒置。一个系统做得快不快、答辩稳不稳百分之八十取决于前期你想清楚了没有。这部分我会把在线学习平台的业务本质、功能边界、角色权限这些最基础但最容易被忽视的内容讲透。1.1 这不是一个“视频网站”这是“教学闭环”我见过不少同学把在线学习平台做成了B站简化版——用户注册登录传几个视频能播放完事。这其实跑偏了。在线学习平台的核心不在于“视频播放”而在于“学习过程的管理”。你想啊一个学生来到这个平台他的目标是完成某一门课程的学习而老师的目标是知道哪些学生学完了、学到了什么程度管理员的目标是保证课程内容合规、平台运营顺畅。这三层诉求串起来才构成了一个完整的业务闭环。所以你在设计功能时心里要有这条链路用户登录→浏览课程→选课购买或免费加入→按章节学习记录进度→完成测验或提交作业→获得结业凭证或课程评价。缺了其中任何一环系统都只是个内容展示站而不是学习平台。答辩时老师最常问的问题就是“你的学习过程如何闭环”如果你只有播放器没有进度和评价这个问题基本就答不上来。1.2 三类角色三种诉求用“用例驱动”做需求分析在线学习平台的标准角色划分是三种学生、讲师、管理员。别小看这个划分它直接决定了你的权限设计和数据库表结构。学生端的诉求是我能快速找到想学的课、流畅地看视频、知道自己的进度、留下我的疑问。讲师端的诉求是我能上传和管理自己的课程内容、看到选课人数和学习反馈。管理员端的诉求是审核课程是否合规、管理用户状态、查看平台运营数据。做需求分析时我习惯用一个极简的用例表把每个角色的操作整理出来比如“学生-查看课程详情”“讲师-上传章节视频”“管理员-下架违规课程”。这个过程看似繁琐但你的论文里需要画用例图你的数据库设计需要依据它来建表你的接口设计也需要围绕它来定义。这一步省了后面全部乱套。1.3 技术选型的“后悔药”与“保险丝”再聊技术栈。SpringBoot Vue是目前的主流但具体用哪个版本、带不带前后端分离、要不要引入中间件这些都是有讲究的。先说版本SpringBoot建议选2.x系列里较新的稳定版比如2.7.x别一上来就冲3.x因为3.x基于Jakarta命名空间很多老教程和依赖配置都会对不上毕业设计的时间窗口里没必要给自己挖这个坑。前端Vue方面如果你熟悉Vue2直接用Vue2 Element UI生态最成熟遇到问题搜索答案最快如果你对Vue3更熟那用Vue3 Element Plus Vite也没问题但要注意Element Plus的部分组件用法和Vue2版本有差异不要混着看教程。数据库方面MySQL是默认答案几乎不需要想别的东西。要不要用Redis我的建议是如果你的系统里做了短信验证码登录、或者课程列表频繁被访问引入Redis做缓存是合理亮点如果只是毕业设计你不想增加搭建复杂度完全可以不引入答辩时诚实说“本次设计基于数据量考虑未引入中间件”也是站得住脚的。给一个很务实的建议技术选型没有绝对的最好只有和你能力最匹配的方案。一个你能完全讲清楚底层逻辑的技术栈远比一个名字唬人但你自己都说不明白的架构要好。2. 把地基打牢数据库设计与后端架构的核心套路地基决定上限。在线学习平台这个题目数据库表设计合理不合理直接影响你写代码的速度和答辩时的自信程度。这一章我把表设计的核心思路、SpringBoot项目的目录结构、以及认证鉴权这块最容易出问题的环节完整展开。2.1 核心表设计与字段设置的“最少必要”原则一个在线学习平台最少需要这几张表用户表、课程分类表、课程信息表、课程章节表、用户选课表、学习进度表如果涉及下单购买还需要订单表如果有问答互动还要有问答表和回复表。我用一张表把核心表和关键字段列出来你在建表时可以对照着看数据表核心字段设计意图userid, username, password, role, nickname, avatar, status以一敌三通过role区分三类角色避免学生表、教师表、管理员表三张表冗余course_categoryid, name, parent_id支持两级分类比如“后端开发”下挂“Java”“Python”courseid, teacher_id, category_id, title, cover, intro, price, statusstatus字段控制上下架状态teacher_id关联到讲师course_chapterid, course_id, title, sort, video_url, duration章节归属于课程sort决定播放顺序user_courseid, user_id, course_id, create_time记录用户选课关系是“我的课程”页面的数据基础study_progressid, user_id, chapter_id, finished, update_time记录章节课完成状态支撑“继续学习”功能course_orderid, order_no, user_id, course_id, amount, status, pay_time如果做知识付费模块订单表必不可少order_no要全局唯一question_answerid, user_id, course_id, content, reply_id, create_time支持课程问答区的多级回复这里要特别强调几个容易踩坑的细节不要把密码明文存数据库使用Bcrypt加密这是答辩时安全性的一个隐藏加分点。时间字段建议用datetime不要用字符串方便排序和统计。表名和字段名不要用中文也不用驼峰统一用下划线风格否则MyBatis-Plus映射会遇到麻烦。所有业务表都要有逻辑删除标记deleted和创建时间create_time这是职业道德问题也是后期维护的方便。2.2 后端项目分层与SpringBoot工程目录SpringBoot项目的目录结构我推荐严格按照Controller、Service、Mapper三层划分。这不是教条而是当你开发到中后期功能越来越多时这种清晰的分层能让你半天定位一个Bug而不是找半个小时。一个相对完整的后端包结构是这样controller接收前端请求调用Service层不写任何业务逻辑service业务逻辑的核心层处理事务、校验、组装数据mapper数据访问层继承MyBatis-Plus的BaseMapper写简单的增删改查entity与数据库表对应的实体类dto接收前端参数的传输对象避免直接拿Entity接收表单数据vo返回给前端的视图对象控制返回字段不把密码hash暴露出去config放跨域配置、拦截器配置、全局异常处理util放JWT工具类、通用返回结果封装类等关于通用返回结果我建议你定义一个Result类包含code、message、data三个字段。所有接口都返回这个结构前端统一处理这会让你对接接口的效率翻倍。全局异常处理用RestControllerAdvice注解一个类把参数校验失败、业务异常、未知异常分别处理这样即便代码出错前端拿到的也是友好的JSON而不是一串看不懂的堆栈。2.3 身份认证与权限控制JWT 拦截器的正确打开方式前后端分离最头疼的事情之一就是登录状态管理。传统Session方案在跨域场景下会遇到各种问题所以现在主流做法是JWTJSON Web Token。流程很简单用户登录成功后后端把用户id和角色信息加密生成一个token字符串返回给前端前端每次请求时把它放在请求头里带回来后端通过拦截器校验token是否合法、是否过期。但这里有几个细节你必须得搞清楚否则实际开发会非常痛苦token过期时间怎么定我建议设置两小时这是用户体验和安全性的合理折中。过期后前端通过响应里的特定code跳回登录页。哪些接口需要登录课程列表和详情是公开的但“开始学习”“提交评论”“管理课程”这些必须登录后台管理接口还必须校验管理员角色。用一个自定义注解比如RequireLogin和RequireAdmin标注在Controller方法上拦截器统一扫描会比在代码里一个个if判断优雅得多。密码加密用BCryptPasswordEncoder这是Spring Security框架自带的加密器单靠SpringBoot也可以引入spring-security-crypto这个轻量依赖不需要启动整个Security配置去拦截请求否则配置不当会把所有接口都锁死排查半天。我在代码里给你一个拦截器校验token的参考实现思路public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (!(handler instanceof HandlerMethod)) return true; HandlerMethod hm (HandlerMethod) handler; // 检查方法上是否有RequireLogin注解 if (!hm.getMethod().isAnnotationPresent(RequireLogin.class)) return true; String token request.getHeader(Authorization); if (StringUtils.isBlank(token)) { return this.outputUnauthorized(response); } try { Claims claims JwtUtil.parseToken(token); request.setAttribute(userId, claims.get(userId)); request.setAttribute(role, claims.get(role)); return true; } catch (Exception e) { return this.outputUnauthorized(response); } }注意JWT的密钥绝对不能写在代码里写死供所有人可见至少放在application.yml配置文件中答辩时随便聊一句“密钥属于敏感信息应置于服务端配置文件中”专业感立刻上升一个档次。3. 认清架构全貌前端工程化和接口联调的关键后端地基打完接下来是前端的实现。很多同学是后端写得很顺一到Vue就卡住。这一章我讲前端工程的组织方式、Axios请求封装、以及前后端联调时最经典的跨域问题和部署问题。3.1 前端路由、状态管理与模块组织Vue前端工程我通常按这样的目录组织src/api按业务模块拆分接口请求函数src/router统一管理前端路由配置嵌套路由和动态路由src/store管理全局状态比如用户信息、侧边栏开关状态src/views页面组件按模块建子目录比如views/student、views/teacher、views/adminsrc/components公共组件比如上传组件、分页组件src/utils封装Axios实例、时间格式化等工具函数当你区分了学生端、讲师端、管理端三大模块后前端的可维护性会有质的变化。每一个端对应一组页面和路由互不干扰哪怕你后面想加一个“运营后台大屏”也只是在views下新增一个文件夹而已。路由和权限的配合是另一个要点。前端的路由守卫可以在用户未登录时自动跳转到登录页可以在用户角色不匹配时提示无权限。但这只是交互层面的控制真正的权限校验重点仍然在后端的拦截器里。这里我建议你明确一下前端路由守卫核心是提升体验后端接口校验才是安全底线。3.2 Axios封装与请求拦截器的三个关键设计前端每次请求都写一堆同样的配置显然不行所以必须统一封装Axios实例。我在做这类项目时封装里至少有这三个关键设计第一请求拦截器里统一加token。从store里取出用户token放到请求头Authorization字段中这样你写的每个接口都天然携带凭证不需要手动加。第二响应拦截器里统一处理业务码。后端返回的code如果是200直接返回data给页面如果是401或者token失效码就清除本地用户信息并跳转登录页如果是500就用Element UI的Message组件弹出错误提示把后端传的message展示给用户。这样前端业务代码里只需要关心成功逻辑错误处理全部收口。第三封装一个统一的分页请求方法。因为你的课程列表、用户列表、问答列表全都需要分页把pageNum、pageSize和查询条件一起组装好返回的数据统一结构是records和total这样列表页代码可以写得很干净。3.3 前后端联调时必踩的跨域与部署坑位前后端分离项目联调时跨域问题是百分之百会碰到的。前端跑在8080端口后端跑在8081端口浏览器默认会拦截非同源的请求。解决方案有很多但作为毕业设计我推荐SpringBoot后端直接配置全局跨域代码量最少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); } }这里有个细节allowCredentials(true)时allowedOrigins不能使用要用allowedOriginPatterns()。很多同学在这里卡住报错信息又看得云里雾里其实根源就在这个配置的匹配规则上。部署环节最常见的坑位有两个。一个是前端项目打包后刷新页面出现404。这是因为Vue是单页应用路由跳转由前端接管直接刷新时服务器找不到对应的后端路由。解决办法是在后端写一个路由转发规则把所有非静态文件的请求转发到index.html。另一个是SpringBoot前端资源打包方案你可以把Vue构建后的dist目录里的内容复制到SpringBoot的static目录下实现前后端一体化部署这样只需要启动一个Java进程就能访问整个系统省去Nginx配置的复杂度非常适合毕业设计演示。4. 核心功能模块落地实操与代码思路理论说清楚了最终要落到功能代码上。在线学习平台的四个高权重模块是认证与个人中心、课程中心与学习进度、后台管理、问答与评论。我逐个拆解把实现思路、关键代码、注意事项一条龙说清楚。4.1 从登录到鉴权认证模块的完整链路登录模块表面看只有一个登录接口实际上它牵扯到注册、验证码、密码加密、token生成、用户信息获取、退出登录等一系列功能。用最务实的方式做前端表单先校验“用户名不能为空”和“密码长度至少6位”后端再用Spring的Valid注解做同样的参数校验双重校验保证数据质量。登录逻辑的核心代码模式是这样的PostMapping(/login) public Result login(RequestBody Valid LoginDTO dto) { User user userService.findByUsername(dto.getUsername()); if (user null) return Result.error(用户不存在); if (!passwordEncoder.matches(dto.getPassword(), user.getPassword())) { return Result.error(密码错误); } if (user.getStatus() 0) return Result.error(账号已禁用); String token JwtUtil.generateToken(user.getId(), user.getRole()); LoginVO vo new LoginVO(token, user.getNickname(), user.getRole(), user.getAvatar()); return Result.ok(vo); }退出登录时我的做法是前端直接清除本地存储的token和用户信息然后跳转登录页。你在答辩时可能会被问“退出登录后token还能用吗”这确实是个问题因为JWT是无状态的服务端无法主动吊销token。如果你想做严格一点的方案可以把token的jti字段存到Redis里设置过期时间退出时删掉校验时检查是否存在。但这个复杂度对毕设来说可以不做只要你能解释清楚无状态这个特性老师通常不会深究。4.2 课程浏览、选课与学习进度最核心的业务链路课程列表页是整个系统的门面。学生搜索课程、按分类筛选、查看课程卡片这些都是常规操作。真正有技术含量的点在课程详情页的“选课”和“继续学习”。选课逻辑要考虑两个问题已经选过的课不能重复选选课前要判断课程是否需要支付。免费课程直接插入user_course表生成学习记录付费课程则要跳转到订单流程。我个人建议你在这个阶段把所有定义成“免费课”把订单功能做成一个“模拟支付”的闭环这样既完整展示了业务链条又不需要真的接入支付宝微信支付。具体做法是选课后生成一条待支付订单前端展示一个支付弹窗点击“模拟支付”就让订单变更为已支付同时开通课程权限订单表里记录支付时间。这个流程不复杂但把“订单-支付-开课”的链路走通了非常加分。学习进度模块是这个系统的灵魂功能之一。我在数据库设计里放了study_progress表前端在播放视频时定时上报当前章节的播放进度或者点击“完成学习”按钮时上报完成状态。我的建议是做两个数据点播放进度百分比和完成状态。播放进度用于“我的课程”页面显示“已学60%”完成状态用于课程详情页显示“你已经学完第1章”。上报接口不需要很频繁每15秒一次足够实在偷懒的话只在点击下一章时上报也可以但体验会稍微差一点。还有一个细节视频文件存储到哪里。如果你没有服务器把视频扔到项目本地的static目录也能跑但这对毕设来说有点Low。我建议用对象存储服务比如阿里云OSS、腾讯云COS新用户可以免费试用几个月。前端用Vue集成播放器推荐video.js后端返回视频的签名URL播放体验会非常流畅答辩演示时绝对不会因为加载慢而尴尬。4.3 后台管理的关键设计课程审核与数据看板管理后台是几乎所有学生都会做的模块但做得好的不多。核心原因在于很多同学把后台做成了“数据模型的简单增删改查”觉得有表格就行忽略了后台模块的实际业务逻辑。在线学习平台的后台管理要尤其关注课程审核和上下架。当讲师上传新课程或编辑已有课程时课程状态应该是“待审核”管理员审核通过后才变为“已上架”。这个过程是业务规则不是简单的增删改查把它讲明白是你区别于普通项目的关键。具体实现上你只需要在课程表里维护status字段枚举值分为草稿0、待审核1、已上架2、已下架3然后写一个审核接口把1改成2前端表单里禁止讲师直接设置status为2即可。技术不难但体现了你的业务思考。数据看板可以说管理后台的点睛之笔。用ECharts在首页展示几条统计图表比如最近7天新增用户数、课程分类占比、课程销量排行一条SQLgroup by就能查出来。图表出来之后整个系统的完整度和答辩时的视觉冲击力会提升一个档次而你的工作量和精力消耗只增加了一点点。4.4 问答互动为系统增添“人气”的轻量级设计问答区能体现你做了“学习之外”的思考。一个简单的课程问答模块包含提问、回复、我的问题列表可能只需要两张表加三四个接口但它让这个系统从一个单向的内容播放器变成了一个具有双向交流属性的学习社区而且这个功能扩展性极强——你想加点赞、加置顶、加通知都是在现有表上做加法不会牵一发动全身。实现上question_answer表用reply_id字段来区分是问题还是回复。问题本身关联course_id回复关联父问题或者父回复的任意层级但为了简化查询你可以只做两级问题下直接挂回复不对回复做二次回复。判断系统边界比无脑堆功能重要得多。5. 毕业论文结构拆解与高效写作要点代码写完只是完成了一半毕业论文才是让毕业设计落地成“可结题”成果的关键环节。我每年都能看到代码运行流畅但论文写得一塌糊涂的案例这非常可惜。实际上论文有它内在的章法和套路的摸清了写作效率能翻倍。5.1 完整论文结构框架毕业论文通常包含这些章节摘要与关键词绪论研究背景、意义、国内外现状相关技术介绍SpringBoot、Vue、MySQL、JWT、等系统需求分析可行性分析、功能性需求、非功能性需求系统设计总体架构设计、功能模块设计、数据库设计系统实现核心模块的代码与实现说明系统测试测试用例、测试结果分析总结与展望这里有个技巧技术介绍章节不要大段复制网上铺天盖地的官方介绍。你要用自己的话用“我为什么选它”“它在本项目里负责什么”的角度来写。比如介绍SpringBoot重点不是SpringBoot的历史和官网特性而是“本项目用它构建RESTful API利用自动配置简化开发并结合MyBatis-Plus实现数据持久化”。这样的技术介绍才有灵魂而且查重率低。5.2 让需求分析和系统设计更专业的三个方法第一个方法画好用例图。用例图是需求分析的灵魂用PlantUML或者绘图工具画一张系统的整体用例图把学生、讲师、管理员分别能做的事标注清楚这一张图顶你写三千字。第二个方法把代码逻辑翻译成文字而不是贴大段代码。论文里的“系统实现”章节老师想看到的是你对某个功能的设计思路和关键实现说明不是让你贴完整的Controller。你写“课程发布时系统会先校验当前用户身份然后按草稿状态保存课程再提交审核”这样的描述远比一整页代码有价值。第三个方法数据库设计的展示不要只贴建表语句。我建议用表格的形式描述每张表的核心字段、类型、含义再用一两个E-R图展示主要表之间的关联关系。这是评审老师最爱看的部分也是你系统设计能力的直接体现。5.3 测试章节怎么写得既有说服力又不枯燥测试章节是很多同学的短板往往随便写几个“登录功能测试通过”就算完成。我建议你认真做一张测试用例表把核心功能路径都覆盖一遍。例如用例编号功能描述操作步骤预期结果测试结果TC01用户注册输入用户名和密码点击注册页面提示成功并跳转登录页通过TC02用户登录输入正确凭证提交登录返回token并进入首页通过TC03选课并开始学习点击免费课程“立即学习”选课成功并进入课程详情页通过TC04课后完成状态上报学完第1章后点击“完成学习”进度条更新为已完成通过TC05管理员上下架课程将课程状态改为下架学生端不再显示该课程通过测试用例表体现了你的测试意识和逻辑性。另一个实用建议是你在论文里可以附加1-2个典型Bug的发现与修复过程比如“文件上传大小超限引发的下载异常”会显著增强整篇论文的真实感因为这种真实调试过程的描述是编不出来的。6. 从环境搭建到项目跑通的排坑实录项目也好、论文也好最终都要求系统能跑起来。我在带学生和帮人看项目的过程中把最有共性的排坑问题整理成了一张清单基本上覆盖了你自己开发时可能遇到的百分之90的环境和联调类问题。6.1 高频环境问题与快速解决办法问题现象常见原因快速解决方案Maven依赖下载慢或失败默认中央仓库访问不稳定在settings.xml中配置阿里云镜像仓库连接MySQL时报Public Key Retrieval异常MySQL 8以上版本认证机制导致JDBC URL添加allowPublicKeyRetrievaltrueuseSSLfalse数据库中文乱码连接字符集不一致JDBC URL指定characterEncodingutf-8建库时指定utf8mb4SpringBoot启动后版本报错Java和SpringBoot版本不匹配SpringBoot 2.7.x配Java 8或113.x配Java 17不要混用前端npm install卡住依赖源访问慢使用nvm把nmp源切换为国内镜像或者用pnpm刷新页面404前端路由与后端冲突后端定义静态资源兜底转发到index.html或部署时配置try_files6.2 联调阶段最隐蔽的5个接口问题接口联调时最容易出问题的不是跨域而是以下几种场景第一前端表单提交了ID为null的字段后端却要求非空。这通常是因为前端表单绑定多绑了字段要注意使用DTO对象过滤前端不必要传来的参数。第二前端传参是JSON格式后端却用application/x-www-form-urlencoded来接收参数导致所有字段都是null。解决方法是后端Controller参数加上RequestBody前端Axios请求正确设置Content-Type为application/json。第三MyBatis-Plus的LambdaQueryWrapper使用不当。比如你调用了eq(user_id, 100)但数据库列名是user_id而实体字段是userId如果没有开启驼峰映射就会拼出错误的SQL。开启方式是在application.yml中设置mybatis-plus.configuration.map-underscore-to-camel-casetrue但MyBatis-Plus默认开启通常问题出在XML里手写SQL时没用正确的别名。第四批量删除接口只传了数组但后端接收的是ListSpringBoot是可以直接兼容的但如果前端请求路径是/delete/1,2,3后端却是POST /delete。方法名或参数形式不统一会导致404。尽早统一路径风格这是协作效率的关键。第五日期格式不兼容。前端传“2025-06-01”后端用JsonFormat(patternyyyy-MM-dd)还是解析失败大概率是因为时间字段声明成了String类型。实体类时间类型统一用LocalDateTime或Date不要用String。6.3 指导搭建视频的价值不止“能跑就行”标题里提到的“指导搭建视频”在我看来是毕业设计准备过程中很适合自己录制的复盘材料尤其对答辩展示有奇效。我在实际准备答辩时有个体会如果只看代码讲到后面自己会绕晕如果对着视频一步步演示讲述的节奏会清晰很多。录制时按四个主题来组织环境准备JDK、MySQL、Node.js的安装配置项目导入与初始化前后端启动与登录演示核心功能逐项操作演示。录制过程本身会强迫你把系统的每个细节都过一遍任何藏着掖着的问题都会提前暴露。把视频准备好答辩现场就算紧张到嘴瓢也可以直接放屏幕录制配合讲解效果远好于现场一步步操作。7. 写在最后的心里话如果你正在被这个项目折磨得焦头烂额我只想告诉你别慌。这套系统真正吃透它你能学到的远比分数多得多。你会在数据库设计中对“业务流程决定表结构”有肌肉记忆般的理解你会在跨域和联调中理解前后端协作的本质你会在写论文时把一堆散乱的技术栈整理成一个完整的工程叙事——这些能力直接用、能落地、以后找实习也能拿得出手。最后分享一个小技巧答辩展示时不要按代码结构从上到下讲而要按业务场景来讲。先打开学生端走一遍“注册→登录→搜课→选课→观看视频→完成学习”的完整链路再切老师端上传一门课程并提交审核最后用管理员账号把课程上架顺手打开数据看板展示曲线。用一条完整的故事线把系统串起来比零散地展示每个页面有效得多。这个在线学习平台你可以把它当毕业设计做完也可以把它当作学习企业级项目开发的起点。前者是一次性的后者是长期复利的。动手去敲代码吧写完的那一刻你会觉得这一路踩过的坑全部值了。