简介:基于SSM与Vue架构的少儿编程管理系统毕业设计资源,面向计算机专业毕业设计开发者及前后端分离初学者。系统按管理员与家长两类角色划分权限,完整覆盖家长管理、学生信息、课程分类、课程购买、完整课程、通知公告、留言反馈等业务模块,适合作为课程设计或毕业设计的参考原型。资源包共839个文件,大小约26.78MB,主要包含Java后端源码、Vue前端页面、JS/HTML/CSS等静态资源,同时附有SQL数据库脚本、说明文档、LW文档、PPT和启动部署脚本,能够帮助快速完成环境搭建与项目运行。目前已有143人学习使用,具备一定的参考价值。学习后能够掌握SSM框架与Vue的整合方式、权限管理思路以及电商式课程购买流程的实现细节,适用于需要完整项目源码与配套文档进行二次开发或答辩准备的读者。
1. 少儿编程管理系统是个什么题:SSM+Vue 能一次性覆盖教务和教学两件事
打开这份java毕业设计之少儿编程管理系统(ssm+vue完整源码+说明文档+LW+PPT).zip,你真正拿到的不只是代码,而是一套“学术答辩 + 工程交付”的组合包。少儿编程管理系统,面向的是编程培训机构或学校机房:主管用它排课、管课时、盯出勤,老师用它维护班级、上传课件、点评学生作品。这套系统里通常没有在线写代码的 IDE,核心业务是“教务”,不是“编译器”。
SSM 加 Vue 之所以成为毕业设计的高频组合,是因为它把 Java 后端的基础设施几乎全考了一遍:Spring 管对象、SpringMVC 收请求、MyBatis 连数据库,前端再用 Vue 做单页应用,专业跨度大但难度可控。对正在选题、想在简历里放一个完整全栈项目的人来说,这题的性价比很高:业务好讲、表结构好画、答辩能演示的页面足够多。接下来我按“先看懂结构,再跑通本地,最后学会排坑”的顺序,把这套东西拆开讲。
2. 先拆包再启动:从目录结构看清SSM后端与Vue前端的分工
拿到压缩包之后,第一件事不是急着npm install,而是先确认里面装了哪几类东西。一套规范的毕设包通常会同时包含backend(或直接叫项目名的 SSM 工程)、frontend(Vue 工程)、sql(数据库脚本)、说明文档/LW/PPT。把目录结构看清,后面所有配置都不会抓瞎。
2.1 后端四个包:Controller、Service、Mapper、Entity 之间到底谁调用谁
SSM 后端的标准分包方式几乎长一个样,我一般会先在 IDEA 里把工程按src/main/java/com.xxx下面的包结构过一遍:
src/main/java/com/xxx ├── controller // 接收前端请求,返回 JSON 或页面 ├── service // 业务逻辑:判断课时够不够、状态能不能改 ├── mapper // MyBatis 接口,对应 XML 里的 SQL ├── entity // 数据库表对应的实体类(也叫 pojo/model) ├── common // 工具类、统一返回结果 Result、异常处理 src/main/resources ├── mapper // MyBatis 的 mapper XML 文件 ├── jdbc.properties ├── spring-mvc.xml ├── spring-mybatis.xml └── mybatis-config.xml这个结构的阅读顺序很关键,直接照着 entity 走最快:先打开一个实体类(比如Student.java),看它有哪些字段,再打开对应的StudentMapper.xml看 SQL,最后看StudentController.java对外暴露了哪些接口。这样一张表一条线,能快速摸清系统到底做了哪些功能。
Controller 层里你会频繁看到类似下面的写法,这是 SSM 时代最典型的“JSON 接口 + Result 包装”:
@Controller @RequestMapping("/student") public class StudentController { @Autowired private StudentService studentService; @ResponseBody @RequestMapping("/list") public Result list(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "10") Integer limit, String keyword) { PageInfo<Student> pageInfo = studentService.queryPage(page, limit, keyword); return Result.success(pageInfo); } }逻辑说明:@Controller加@ResponseBody是 SSM 里返回 JSON 的标准姿势;PageInfo一般来自 PageHelper 分页插件,它会把total、list一起装进返回体,前端表格直接拿pageInfo.list渲染。参数说明:page是当前页码,limit是每页条数,keyword是搜索关键词,这三个参数在你用前端分页表格时会一一对应传过来。
2.2 前端 src/views 与路由:三种角色三种首页
Vue 前端里最该看的是src/views(或src/pages)和src/router/index.js。少儿编程管理系统的页面一般会按“管理员端、教师端、学员端”三个视角组织:管理员看机构总览、课程列表、订单报表;教师看我的班级、今日课表、学员出勤;学员或家长看已报课程、课时余量、作品记录。
Vue Router 里最常见的是“登录后按角色动态路由”的处理方式,而不是把所有页面一股脑配成静态路由:
const router = new VueRouter({ routes: [ { path: '/login', component: Login }, { path: '/', component: Layout, children: [ { path: 'dashboard', component: Dashboard, meta: { roles: ['admin'] } }, { path: 'student/list', component: StudentList, meta: { roles: ['admin'] } }, { path: 'class/myclass', component: MyClass, meta: { roles: ['teacher'] } } ] } ] }) // 全局前置守卫:没登录跳登录页,没权限跳 403 router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.path !== '/login' && !token) return next('/login') next() })逻辑说明:meta.roles是给路由打的“权限标签”,后端登录接口返回角色后,前端在守卫里拿角色和to.meta.roles比对,不匹配就拦截。动态路由的好处是权限逻辑集中在路由器里,页面组件不用自己判断角色。参数说明:localStorage存 token 是毕设最常见的做法,比 cookie 简单,但 XSS 风险自己要心里有数;如果你看到的是sessionStorage,那只是把有效期从“跨标签页”改成“关页面失效”的区别。
前端页面里还会大量用到“插槽”和“指令简写”。比如 Element UI 的表格列里用slot-scope(Vue 2)或#default(Vue 3)拿当前行数据来渲染状态标签,v-for写遍历时:key一定要绑稳定值,不要用数组下标。样式上,组件<style>记得加scoped,否则两个页面的 class 重名会互相污染——这是 Vue 里最容易出现的“样式冲突”问题。
2.3 数据库核心表:用一张表记住它管的是“课时”而不是“知识”
少儿编程管理系统的数据模型,核心是“学员—课程—班级—课时—作品”这条业务链。只要你把下面这几张表的关系理清,答辩时老师问“你的业务逻辑怎么设计”,你就有完整的话术:
| 表名 | 关键字段 | 说明 |
|---|---|---|
sys_user | id, username, password, role | 登录账号,角色区分管理员/教师 |
student | id, name, parent_phone, remain_hours | 学员基础信息,remain_hours是剩余课时 |
course | id, name, type, price, total_hours | 课程,type 区分 Scratch/Python/C++ |
course_class | id, course_id, teacher_id, start_date | 班级,绑定课程和授课教师 |
student_class | id, student_id, class_id, status | 选课/报名关系,status 标记在读/结课/退费 |
sign_in | id, student_id, class_id, sign_date | 签到记录,用来扣课时 |
work | id, student_id, class_id, file_url, score | 学员作品,file_url指向磁盘路径 |
CREATE TABLE `student_class` ( `id` int(11) NOT NULL AUTO_INCREMENT, `student_id` int(11) NOT NULL COMMENT '学员ID', `class_id` int(11) NOT NULL COMMENT '班级ID', `status` tinyint(4) DEFAULT '1' COMMENT '1在读 2结课 3退费', `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_student` (`student_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学员选课表';逻辑说明:SSM 项目里 MyBatis 的 SQL 大多是手写的,所以读懂字段的含义比懂 ORM 更重要。status这类字段就是业务状态的开关,前端按钮的“显示/隐藏”直接由它驱动。参数说明:utf8mb4是必须的,因为学员家长姓名可能含生僻字或表情符号;如果用老旧的utf8,一旦插入四字节字符就会报Incorrect string value。
3. 本地跑通的最小命令链:从 JDK 体检到 npm run dev 全通
“源码能打开”和“源码能跑起来”之间差着一整条环境链。这套组合涉及 JDK、Maven、Tomcat、MySQL、Node,任何一环版本踩错就全盘卡住。下面这组命令和配置是我在本地跑过无数次后的固定套路,直接抄即可。
3.1 先做版本体检:JDK 1.8、Maven 3.6、Tomcat 8.5、Node 16 的兼容组合
打开终端,依次执行下面五条命令,确保环境是“齐的”:
java -version mvn -v mysql --version node -v npm -v逻辑说明:这五条命令分别验证 JDK、Maven、MySQL、Node、npm 是否安装成功。如果哪条提示command not found,先补装对应环境再继续。参数说明:版本上我建议“能压多老压多老”——JDK 用 1.8,Maven 用 3.6 左右,Tomcat 用 8.5,Node 用 14 或 16,这套组合对毕设里的老依赖最友好。机器上如果装了多个 JDK,先确认JAVA_HOME指到了 1.8 的路径,不然下面 Maven 打包时很容易出现“编译版本 57.0 不受支持”之类的问题。
如果你用的是 IDEA,前后端可以放一个窗口里管理:后端按普通 Maven 工程打开,前端在 Terminal 面板里执行 npm 命令即可。IDEA 专业版对 Vue 有语法提示,社区版也没关系,写好vue.config.js后用命令行跑更稳。
3.2 后端启动五步:导库、改连接串、打包、部署、看日志
后端是标准的 Java Web 工程,启动流程非常固定。第一步就是初始化数据库:
mysql -uroot -p < sql/init.sql逻辑说明:把压缩包里sql目录下的数据库脚本导入本地 MySQL。如果没有现成的init.sql,就依次执行包里所有.sql文件,先建库、再建表、最后灌基础数据。参数说明:-uroot是用户名,-p会让终端交互式地提示输入密码;如果脚本里已经写了CREATE DATABASE,导入前不用手动建库。
第二步看jdbc.properties,把连接串指到本地:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/child_code?useUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=123456逻辑说明:这段配置是后端连接数据库的唯一入口,SSM 在 Spring 容器启动时读取它,包进SqlSessionFactory的数据源里。参数说明:3306是 MySQL 默认端口,child_code是数据库名,按你导入脚本里的实际库名改;useUnicode=true&characterEncoding=utf8是中文不乱码的老牌参数,不要删。如果你的 MySQL 是 8.0+,要把驱动类改成com.mysql.cj.jdbc.Driver,并在 URL 后面加serverTimezone=Asia/Shanghai,具体见第 4 章。
第三步打 war 包,并部署到 Tomcat:
mvn clean package -DskipTests cp target/child-coding-system.war /path/to/tomcat/webapps/ cd /path/to/tomcat/bin ./startup.sh逻辑说明:mvn clean package会编译源码、执行测试(这里跳过了)、打出可直接部署的 war 包;cp把 war 复制到 Tomcat 的webapps目录,Tomcat 启动时自动解压部署。参数说明:-DskipTests跳过测试代码的编译和运行,如果你的工程里没有 JUnit 测试,写不写都行;startup.sh在 Windows 下对应startup.bat。
启动后要养成看日志的习惯,部署失败的真相全在日志里:
tail -f /path/to/tomcat/logs/catalina.out看到INFO: Server startup in [xxxx] milliseconds才算成功。如果你的项目是用 IDEA 里的 Tomcat 插件直接启动的,就在 Run 窗口里看输出,注意找有没有红色ERROR,而不是只盯着浏览器是否弹出了页面。
3.3 前端启动三步:装依赖、配代理、npm run dev
后端在 8080 端口跑起来之后,前端才能开始启动。前端工程通常是一个独立的 Vue CLI 或 Vite 项目,先进到frontend目录:
cd frontend npm install逻辑说明:npm install会根据package.json把 Vue、Element UI、Axios、ECharts 等依赖全部装进node_modules。如果安装过程中出现大量红色报错,先别急着排查,大概率是下载速度太慢导致的超时,把 npm 源切到国内镜像再重试:
npm config set registry https://registry.npmmirror.com npm install参数说明:registry是 npm 的下载源地址,换源只影响下载渠道,不影响代码逻辑。装完之后,看一眼vue.config.js里的代理配置,这是前后端能不能连通的关键:
module.exports = { devServer: { port: 8081, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } } } }逻辑说明:前端开发服务器默认跑 8080,后端也是 8080,端口冲突是必然的,所以这里把前端改成 8081。所谓“代理”,就是让前端的/api开头的请求,在开发服务器这一层被转发到后端的http://localhost:8080。参数说明:pathRewrite里的^/api表示把 URL 开头的/api替换成空字符串——如果你的后端@RequestMapping里本来就没加/api前缀,那这一步必须写;changeOrigin: true是改掉请求头里的 Host 字段,避免后端的一些过滤器误判来源。
最后启动:
npm run dev看到App running at: http://localhost:8081基本就成功了一半。这时候打开浏览器访问 8081,如果登录页面能出来,但输入账号密码后卡住或转圈,问题通常出在代理或账号数据上,往下看排查章。
3.4 验收一条业务链路:从登录到给学员报一门课
环境全通之后,花五分钟把系统“用”一遍,确认没有隐藏的断点。这一步比反复看代码都管用,也有利于后面答辩时的演示节奏。先拿压缩包里说明文档里写的初始账号登录,一般是admin/123456或admin/admin123。
登录之后依次做四件事:进“课程管理”新建一个 Scratch 课程;进“学员管理”添加一个学员;进“班级管理”把学员分到一个班级;最后给这个学员做一次签到。每一步操作后,刷新一下数据库对应表,看看数据是否真的写进去了:选修课表里学员和班级是否关联,签到表的sign_date是否生成。
验证命令可以这样用:
mysql -uroot -p -e "select s.name, c.name, sc.status from student_class sc join student s on s.id=sc.student_id join course_class c on c.id=sc.class_id\G"逻辑说明:这是一条联表查询,一次性把学员、班级、选课关系的状态列出来,用\G按行展示结果避免表格撑出屏幕。如果页面操作成功而这里查不到数据,就说明前端显示和后端写入不是同一套逻辑,常见的藏雷点是前端直接 mock 了数据,或者访问的是别的接口。参数说明:-e表示直接在命令行执行 SQL 而不进入交互终端,方便脚本化验证。
4. 三个必改参数:数据库连接、跨域代理与文件上传
系统跑起来只是起点,真正决定“换一台电脑还能不能用”的,是那几个必须按实际情况改的参数。很多毕设源码包默认配置指向作者的开发环境,你直接跑必然失败。这三个位置是我每次拿到新包都会优先检查的。
4.1 jdbc.properties:MySQL 5.7 与 8.0 的驱动和 URL 写法差在哪
这是最典型的“一样的代码,环境不同结果不同”的场景。MySQL 5.7 和 8.0 在 JDBC 连接上有两处硬区别:驱动类名变了,URL 要求变了。
| 配置项 | MySQL 5.7 及以下 | MySQL 8.0+ |
|---|---|---|
| 驱动类 | com.mysql.jdbc.Driver | com.mysql.cj.jdbc.Driver |
| URL 时区 | 可不写 | 必须写serverTimezone=Asia/Shanghai |
| SSL | 默认可忽略 | 建议写useSSL=false |
| 公钥检索 | 无此问题 | 密码加密认证时需allowPublicKeyRetrieval=true |
用 8.0 的话,正确的jdbc.properties是:
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/child_code?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true jdbc.username=root jdbc.password=你自己的密码逻辑说明:MySQL 8.0 开始默认使用caching_sha2_password认证插件,旧驱动不认识这个插件,所以必须换驱动类;时区参数是因为 8.0 的 JDBC 驱动会校验服务器时区,不指定就会报The server time zone value '***' is unrecognized。参数说明:characterEncoding=utf8要和数据库的字符集保持一致,数据库是utf8mb4的话这里写utf8依然兼容,但反过来不行。
如果你的源码包里pom.xml引用的 MySQL 驱动版本是5.1.x,而本机装的是 MySQL 8.0,记得顺手更新依赖版本。改完pom.xml后执行mvn clean,强制重新拉取依赖,避免 Maven 使用本地仓库里的旧 jar。
4.2 前端 devServer.proxy 与后端 CORS:谁负责跨域
很多新手分不清“代理”和“跨域”的关系,其实它们解决的是同一个问题的两个层次。开发环境下,浏览器访问http://localhost:8081,页面里的 Axios 请求若直接发到http://localhost:8080,浏览器会因为“协议/域名/端口不一致”拦下响应,这就是跨域。代理的作用是:请求先发给同源的 8081,再由 Vue 开发服务器转发给 8080,浏览器看到的是同源请求,自然放行。
如果代码里没有配proxy,你也不要自作主张去改 Axios 的 baseURL 成后端地址——那只会把问题暴露得更晚。更靠谱的做法是后端加一个统一的 CORS 过滤器,SSM 里最常见的是用 Spring 拦截器或直接写 Filter:
@Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; response.setHeader("Access-Control-Allow-Origin", "http://localhost:8081"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, res); } }逻辑说明:这段过滤器给后端响应加上了“允许来自 8081 的跨域请求”的响应头。参数说明:Access-Control-Allow-Origin是白名单地址,如果你前端口改了,这里也要同步;Allow-Methods要包含你前端用到的所有请求方法,漏了OPTIONS会导致复杂请求直接失败——浏览器在正式 POST 前会先发一个预检请求,后端不回 200 就什么都不用谈。
注意一个优先级问题:如果前端走了proxy,后端就不需要 CORS 过滤器;如果后端配了 CORS,前端直接请求后端地址也行。两套同时存在一般也没问题,但出问题时容易混淆排查方向,所以我建议“开发环境用 proxy,上生产环境再统一开 CORS”。
4.3 上传目录别放 target:作品图片和课件的存储约定
少儿编程系统里一定有作品上传模块——学生提交的 Scratch 作品截图、老师的课件 PPT。这类功能看似简单,但存储路径选错,打包一次就丢一次数据。
最常见的错误是把上传目录放在后端 webapp 的 target 或 classes 目录下,mvn clean一执行,文件全没了。我的建议是,上传目录固定在本机某个绝对路径下,比如 Windows 的D:/upload/child-code/,并在配置里抽成一个可改的变量:
# 文件上传物理路径 file.upload.path=D:/upload/child-code/ file.upload.url=/upload/**后端把文件写到这个物理路径,同时注册一个静态资源映射,让浏览器能通过 URL 访问到这些文件。SpringMVC 的配置在spring-mvc.xml里加一段即可:
<mvc:resources mapping="/upload/**" location="file:D:/upload/child-code/" />逻辑说明:mvc:resources是 SpringMVC 处理静态资源的标准方式,mapping是外部访问的前缀路径,location指向磁盘目录。注意location里的file:前缀不能省,它告诉 SpringMVC 这是文件系统路径而不是 classpath 路径。参数说明:Windows 路径的斜杠要用正斜杠/,反斜杠在 XML 里需要转义,直接写正斜杠最省事。如果后续部署到 Linux 服务器,把location改成/home/upload/child-code/即可,配置文件里改,不用动代码。
作品表的file_url字段只存相对路径,比如/upload/2024/09/xxx.png,不要存完整带域名的 URL。这样整个系统的域名或端口变了,图片依然能通过新的前缀拼接访问,这是我在做项目交付时最常强调的细节。
5. 常见问题排查:环境翻车、依赖黑洞与联调 404
这一章不讲正常的启动步骤,专门记录我在这类项目里翻过车、也帮别人排过雷的高频故障。每一条都按照“现象 → 原因 → 解决”的格式写,你遇到对应问题时直接对号入座。
5.1 Tomcat 10 启动直接报错:javax.servlet 变 jakarta 的版本陷阱
现象:把 war 包丢进 Tomcat 10,启动后每个请求都报ClassNotFoundException: javax.servlet.Filter或java.lang.NoClassDefFoundError: javax/servlet/ServletException。
原因:Tomcat 10 开始,Servlet 规范里的包名从javax.servlet迁移到了jakarta.servlet。而 SSM 项目里的 Spring、拦截器、过滤器全部基于旧的javax编写,直接运行必然找不到类。这个坑在下载 Tomcat 时特别容易踩,因为官网现在默认首推 Tomcat 10+。
解决:换回 Tomcat 8.5 或 9.0,然后mvn clean package重新打包,清掉 Tomcat 的webapps下旧解压目录,再启动。如果你实在想用 Tomcat 10,就得把项目里所有javax.servlet的 import 改成jakarta.servlet,并升级 Spring 到 6.x——但毕设阶段没必要给自己上这个强度。
5.2 MySQL 连接失败:数据库没导进去,或者驱动没换
现象:启动后端时报Unknown database 'child_code'或Communications link failure。
原因:前者是数据库脚本根本还没导入,或者脚本里创建的库名与jdbc.properties里的库名不一致;后者是 MySQL 版本和 JDBC 驱动版本错配,8.0 的数据库配了 5.1 的驱动,连接建立失败。
解决:先登录 MySQL 执行show databases;,确认child_code库存在且没有任何建表报错。如果库存在,再看jdbc.properties的驱动类是否使用com.mysql.cj.jdbc.Driver。改完配置后必须重启 Tomcat,因为数据源是在 Spring 容器启动时创建的,不是热更新能生效的。
5.3 node-sass 编译失败:Node 版本太高是最常见的黑匣子
现象:npm install时报Error: Node Sass does not yet support your current environment,或者安装过程漫长又伴随一堆gyp ERR!红色日志。
原因:老毕设项目里常锁定node-sass这个库,它是个原生模块,需要下载二进制文件再编译,Node 版本一旦超过它的兼容范围就编译失败。这几乎是 Vue 2 项目跑新机时的头号悲剧。
解决:优先用 nvm 切换 Node 版本,nvm install 16 && nvm use 16,再删掉node_modules和package-lock.json,重新npm install。如果切换版本不方便,第二个方案是把项目里的node-sass替换成sass(即 dart-sass),改法是在package.json里删掉 node-sass、安装 sass,并检查vue.config.js或webpack里有没有sass-loader的旧配置。替换后大部分页面样式不变,但:deep()或/deep/这类穿透写法可能失效,需要微调。
5.4 页面开了接口全 404:代理没生效与后端没起来的区别
现象:浏览器能打开登录页,但登录按钮点下去一直提示“请求失败”或网络错误。打开开发者工具(F12)的 Network 面板,看到请求状态是404 Not Found或Failed to load resource。
原因:404 要分两种看。第一种,请求的 URL 是http://localhost:8081/api/student/list,说明代理规则生效但后端接口没有这个路径,问题出在后端 Controller 的@RequestMapping和前端路径没对上;第二种,请求 URL 直接是http://localhost:8080/student/list,说明代理根本没生效,axios 的 baseURL 写死了后端地址。
解决:先确认后端 Tomcat 的日志里有没有看到这个请求的访问记录。有记录说明链路通,是路径不匹配;没记录说明会话压根没到达后端,查vue.config.js的proxy是否写进devServer,以及改完配置后有没有重启npm run dev。路径不匹配时,最直接的办/strong>法是打开后端的 Controller 代码,对着@RequestMapping的前缀逐个核对,别猜。
5.5 多 JDK 混装导致的打包翻车:JAVA_HOME 指错
现象:执行mvn clean package时编译报错,提示Error: java: invalid source release: 17或Unsupported major version。
原因:Maven 打包用的 JDK 版本和项目要求的版本不一致。你自己装了 JDK 17 作为系统默认,但项目pom.xml的maven.compiler.source/target还写着 1.8,编译器拿到高版本 JDK 去按低版本标准编译,就会报这种错。
解决:终端里执行echo $JAVA_HOME(Windows 是echo %JAVA_HOME%),确认指向 JDK 1.8 的安装路径。如果系统里有多个 JDK,把JAVA_HOME环境变量切到正确版本后重新打开终端。这一步看着低级,但在“环境变量使用多个 JDK”的机器上,翻车概率相当高。我的习惯是:先跑java -version和mvn -v看它们各自认到哪个版本,两个输出不一致时先修环境再谈启动。
6. 从能跑到能答辩:留一条 curl 证据链,再体面地把源码交给老师
系统能跑、数据能写之后,还要多走一步:把“跑通”变成“能证明”。答辩时老师不会只看你现场点鼠标,他更在意过程资料。我用一个最简单的方法留下证据:用 curl 直接调后端接口,把返回结果截图放进说明文档和 LW 的测试章节里。
# 登录拿 token curl -X POST http://localhost:8080/sysUser/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"123456"}'登录成功后返回的 JSON 里通常会带一个 token 或用户信息,再拿这个 token 请求一个需要登录的接口,比如学员列表:
curl -X GET "http://localhost:8080/student/list?page=1&limit=10" \ -H "Authorization: Bearer 上面拿到的token"把这两条命令的执行结果并排截图,能一眼证明“后端接口真实可用”,比空口说“我测试过了”有力得多。截图里注意把终端的时间、路径都带上,这是评审时最可信的依据。
源码交付也是大坑。很多人在最后把整个前端文件夹压缩打包发给老师或发到群里,node_modules动辄几百 MB 起步,QQ 微信传半天传不动,解压还容易损坏。我在第一次交毕设时就干过这种事,后来学乖了:交付前删掉node_modules、target、.idea、*.iml、*.log,只保留源码和数据库脚本,并写一个README.md说明运行步骤。这是“vue 项目源码怎么发给别人”这问题的标准答案——发源码不是发“能直接跑的环境”,而是发“能被干净复现的工程”。如果你会 Git,把清理干净的文件夹提交一个初始 commit,再打成 zip,别人拉下来按 README 操作即可。
做完这套验证和清理,你会明显发现对项目的理解上了一个台阶:哪些配置是环境的、哪些是代码的、哪些是业务的,心里清清楚楚。这个状态进答辩现场,不管老师从哪个角度发问,你都能接得住。希望帮到你。
本文还有配套的精品资源,点击获取