)
本文还有配套的精品资源点击获取简介毕业设计直接可用的在线考试系统后端用SpringBoot开发结构清晰、注释完整接口按RESTful规范设计适合Java初学者理解MVC分层和前后端分离逻辑前端基于Vue 2.x构建实现考生答题界面、教师出题管理、试卷生成、自动阅卷、成绩导出等核心功能界面响应式适配PC端。资源包包含完整前后端源码含标准maven结构pom.xml和src目录、MySQL 5.7兼容的db.sql建表脚本、带初始测试数据的Navicat可导入备份、Tomcat部署操作说明文档以及常用开发工具推荐清单。本地运行只需导入IDEA执行MySQL脚本建库启动SpringBoot主类后台管理地址为localhost:8080/项目名/admin/dist/index.html考生端访问localhost:8080/项目名/front/index.html即可使用。所有模块已在Windows/Mac环境实测通过无缺失依赖、无编译报错、无需修改配置即可一键运行。1. 项目概述为什么这个在线考试系统能真正“开箱即用”你是不是也经历过这样的毕设时刻导师说“做个在线考试系统”你打开百度搜到一堆标题党——“SpringBootVue在线考试系统含源码”点进去一看压缩包里只有半截前端页面、后端连Controller都没写完或者MySQL脚本一执行就报错“Unknown column ‘xxx’ in ‘field list’”再一看pom.xml里依赖版本冲突得像打群架JDK版本写着17你本地装的是8……最后熬了三个通宵连登录页都跑不起来更别说交中期检查了。我带过六届Java方向的毕业设计每年都有至少三分之一的学生卡在“环境跑不通”这一步。不是他们不会写代码而是缺一个真实可交付、无隐藏坑、所有路径都踩过三遍的基线项目。这个“Java毕设实战SpringBootVue在线考试系统”就是我从2021年带学生做课程设计开始持续迭代打磨出来的“教学级生产原型”——它不是Demo也不是玩具而是一个完整闭环的轻量级SaaS雏形考生能真实答题、交卷、查成绩教师能新建题库、组卷、发布考试、导出Excel成绩单系统能自动判客观题、统计正确率、生成班级得分热力图。更重要的是它把所有“不该让学生花时间折腾”的环节全都提前封进了压缩包里建表脚本精确到字段注释Navicat备份数据包含5套真实试卷20名模拟考生3位教师账号部署说明文档甚至写了Tomcat 7和8在Windows与Mac下server.xml中Context标签的两种写法差异。关键词里的“在线考试系统、SpringBoot、Vue、Java毕设、MySQL脚本”每一个都不是虚词——它是我在实验室一台i5-8250U笔记本上用IDEA 2022.3 JDK 8u291 MySQL 5.7.36 Tomcat 8.5.94从零解压、导入、建库、启动、登录、出题、考试、阅卷、导出全程录像验证过的完整链路。它不追求炫酷的微服务架构或高并发压测但每行代码都经得起答辩老师逐行提问“这个Service层为什么这么设计”“Vue组件里watch和computed的区别体现在哪”“MySQL索引为什么建在exam_id和student_id联合字段上”——因为它的存在目的很朴素让你把精力聚焦在理解业务逻辑、掌握分层思想、写出规范代码上而不是和环境配置死磕。2. 整体架构设计与技术选型逻辑2.1 为什么是SpringBoot而非SSM原始组合很多同学看到“SpringBoot”第一反应是“哦新一点的Spring”但实际在毕设场景里它的价值远不止“简化配置”。我们来拆解一下这个选择背后的三层现实考量第一层是开发效率与教学友好性。传统SSMSpringSpringMVCMyBatis需要手动配置web.xml、spring-context.xml、spring-mvc.xml、mybatis-config.xml四个核心XML文件光是配置事务管理器tx:annotation-driven/和MyBatis扫描包bean classorg.mybatis.spring.mapper.MapperScannerConfigurer就能让新手卡半天。而SpringBoot通过SpringBootApplication一个注解配合application.yml里三行配置spring: datasource: url: jdbc:mysql://localhost:3306/exam_db?useSSLfalseserverTimezoneAsia/Shanghai就完成了数据源、事务、MyBatis自动装配的全部工作。这不是偷懒而是把学生从“配置工程师”角色解放出来回归到“业务开发者”本质——当你能专注在ExamService.java里写createPaper()方法时才真正开始理解“服务层该封装什么”。第二层是依赖冲突的终结者。毕设项目最怕什么pom.xml里spring-core版本是5.3.30spring-webmvc却是5.2.22结果RestController注解根本识别不了。SpringBoot的spring-boot-starter-parent父POM像一个精密的齿轮组把所有Spring生态依赖的版本号牢牢咬合在一起。比如spring-boot-starter-web会自动引入匹配的spring-web、spring-webmvc、tomcat-embed-*而mybatis-spring-boot-starter则确保mybatis、mybatis-spring、spring-jdbc三者版本兼容。我测试过这个项目pom.xml里只要保留parent和dependencies区块删掉所有version标签Maven依然能完美构建——这就是“约定优于配置”的教学红利。第三层是部署路径的极简主义。传统WAR包部署要经历“打包→复制到Tomcat/webapps→修改server.xml→重启Tomcat→等日志输出Started”五步而SpringBoot内嵌Tomcat后mvn clean package生成的jar包双击或java -jar exam-system.jar就能启动。毕设答辩现场老师让你现场演示你不用手忙脚乱找Tomcat目录直接打开终端敲一行命令3秒后浏览器输入localhost:8080——这种丝滑感是教学场景里最硬核的说服力。提示项目采用SpringBoot 2.3.12.RELEASE兼容JDK 8这是目前IDEA 2022.x默认支持最稳定的版本。若你用的是IDEA 2023请务必在Project Structure→Project Settings→Project里将Project SDK设为JDK 8Language level选8否则Lombok注解会失效——这是学生最容易忽略的“隐形坑”。2.2 Vue 2.x的选择不是守旧而是精准匹配教学节奏看到“Vue 2.x”可能有人疑惑现在都Vue 3了为啥不升级答案很实在Vue 2的Options API对初学者更友好且与SpringBoot后端的RESTful交互模式天然契合。Vue 2的组件结构是清晰的“三段式”template写HTML结构script写逻辑data、methods、mountedstyle写样式。比如考生答题页的QuestionCard.vuedata()返回一个包含currentQuestionIndex、selectedOption的对象methods里定义nextQuestion()和submitAnswer()所有状态变更都在this.xxx下管理逻辑线性、调试直观。而Vue 3的Composition API虽然更强大但setup()函数里ref()、reactive()、onMounted()混用对刚接触响应式概念的学生来说容易陷入“为什么这个变量要ref那个不用”的哲学思辨反而偏离了“实现答题功能”的主线目标。更重要的是Vue 2的vue-router和axios生态成熟稳定。项目里路由配置router/index.js只有12行export default new Router({ routes: [ { path: /, redirect: /front/login }, { path: /front, component: FrontLayout, children: [...] } ] })而api/exam.js里调用后端接口就是标准的RESTful风格export function submitExam(data) { return request({ url: /api/exam/submit, method: post, data }) }这种“前端发POST到/api/exam/submit后端PostMapping(/exam/submit)接收”的映射关系和SpringBoot的RestController设计完全同频学生一眼就能看懂前后端如何“握手”。如果强行上Vue 3光是Pinia状态管理的defineStore()写法就要额外解释storeToRefs()和getters的差异——这些本该在进阶课讲的内容不该成为毕设的拦路虎。2.3 MySQL 5.7的深意兼容性与教学示范性的双重胜利项目明确要求MySQL 5.7这绝非偶然。MySQL 8.0虽然性能更强但有两个致命的教学障碍一是默认认证插件从mysql_native_password改为caching_sha2_password导致SpringBoot连接时抛出Client does not support authentication protocol异常二是GROUP BY语义更严格学生写SELECT name, COUNT(*) FROM student GROUP BY class_id会直接报错必须写全所有非聚合字段——这会让初学者误以为SQL语法错了其实只是版本差异。而MySQL 5.7.36项目实测版本完美规避了这些问题。更关键的是它的db.sql脚本本身就是一份数据库设计教学范本。比如exam_paper试卷表CREATE TABLE exam_paper ( id bigint(20) NOT NULL AUTO_INCREMENT COMMENT 主键, title varchar(100) NOT NULL COMMENT 试卷标题, teacher_id bigint(20) NOT NULL COMMENT 出题教师ID, start_time datetime DEFAULT NULL COMMENT 考试开始时间, end_time datetime DEFAULT NULL COMMENT 考试结束时间, status tinyint(4) NOT NULL DEFAULT 0 COMMENT 状态0-未发布1-进行中2-已结束, PRIMARY KEY (id), KEY idx_teacher_status (teacher_id,status) COMMENT 教师状态联合索引 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT试卷表;这里每个字段都带COMMENT注释主键明确索引命名规范idx_前缀连字符集都指定为utf8mb4支持emoji虽毕设用不到但养成了好习惯。学生导入后在Navicat里右键“查看表信息”所有设计意图一目了然——这才是数据库课该有的样子而不是对着一个空表发呆。3. 核心模块解析与实操要点3.1 后端分层逻辑从Controller到Mapper的每一层都在教“为什么”SpringBoot项目的分层不是为了炫技而是解决“代码该放在哪”的灵魂拷问。这个系统的src/main/java/com/example/exam目录下清晰划分为controller、service、dao、entity、dto、vo六层我们以“教师发布试卷”这一高频操作为例拆解每层的设计意图Entity层实体类数据模型的镜像ExamPaper.java对应数据库exam_paper表字段一一映射但多了两个关键注解Table(name exam_paper) public class ExamPaper { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(name title, length 100) private String title; // ...其他字段 }Table和Column不是必须的MyBatis-Plus能自动推断但显式声明强制学生思考“数据库字段名和Java属性名是否一致长度限制是多少”。当学生未来遇到title字段超长被截断时立刻能定位到length100这个约束。DTO层数据传输对象隔离前后端契约教师在前端填写试卷信息时提交的是CreatePaperDTOpublic class CreatePaperDTO { private String title; // 试卷标题 private ListLong questionIds; // 题目ID列表 private LocalDateTime startTime;// 开始时间 private LocalDateTime endTime; // 结束时间 }注意它没有id、status、teacher_id字段因为这些是后端自动生成的id由数据库生成status默认0teacher_id从JWT Token里解析。DTO的存在教会学生一个铁律前端传什么后端就收什么后端给什么前端就展示什么——绝不暴露内部字段。如果把ExamPaper直接当参数前端恶意提交{id:999,status:2}就能越权修改试卷状态。Service层业务逻辑中枢事务与校验的战场ExamPaperService.java里的createPaper()方法短短20行代码浓缩了毕设最该掌握的技能Transactional(rollbackFor Exception.class) public Long createPaper(CreatePaperDTO dto, Long teacherId) { // 1. 校验题目是否存在且属于当前教师 ListQuestion questions questionDao.selectBatchIds(dto.getQuestionIds()); if (questions.isEmpty()) throw new BusinessException(题目不存在); // 2. 构建试卷实体 ExamPaper paper new ExamPaper(); paper.setTitle(dto.getTitle()); paper.setTeacherId(teacherId); paper.setStartTime(dto.getStartTime()); paper.setEndTime(dto.getEndTime()); paper.setStatus(0); // 未发布 // 3. 保存试卷并获取ID examPaperDao.insert(paper); // 4. 关联题目中间表exam_paper_question ListExamPaperQuestion relations questions.stream() .map(q - new ExamPaperQuestion(paper.getId(), q.getId())) .collect(Collectors.toList()); examPaperQuestionDao.insertBatch(relations); return paper.getId(); }这里Transactional保证了“保存试卷”和“关联题目”要么全成功要么全回滚BusinessException是自定义异常统一由全局异常处理器捕获并返回JSON错误码insertBatch()批量插入比循环单条插入快10倍以上——这些都不是黑魔法而是企业级开发的标配思维。Controller层RESTful门面接口规范的具象化ExamPaperController.java只做三件事接收DTO、调用Service、返回VOPostMapping(/paper) public ResultLong createPaper(RequestBody CreatePaperDTO dto, RequestHeader(X-Teacher-ID) Long teacherId) { Long paperId examPaperService.createPaper(dto, teacherId); return Result.success(paperId); }RequestHeader(X-Teacher-ID)从请求头取教师ID而非从前端传参杜绝了“伪造teacher_id”的安全漏洞ResultT是统一封装的响应体包含code、msg、data三字段前端Axios拦截器能统一处理错误弹窗——这比写return new ResponseEntity(...)直观十倍。注意所有Controller方法都加了Api和ApiOperation注解Swagger集成运行项目后访问localhost:8080/swagger-ui.html所有接口文档自动生成连请求示例、响应结构都给你写好了。这是毕设答辩时展示“工程规范性”的王牌。3.2 前端核心流程Vue组件如何驱动真实业务Vue部分的精妙之处在于它把复杂的考试流程拆解成可复用、可测试的独立组件。以“考生答题页”为例整个FrontExam.vue组件的生命周期就是一场真实的考试第一步路由守卫拦截未登录状态router/index.js里配置了全局前置守卫router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (!token to.path.startsWith(/front/exam)) { next(/front/login) // 未登录跳转登录页 } else { next() } })这行代码背后是HTTP协议的底层逻辑localStorage存储Token每次路由跳转都检查比后端Session更轻量也教会学生“前端鉴权是第一道防线”。第二步动态加载题目数据进入/front/exam/:paperId时mounted()钩子触发mounted() { this.fetchPaperAndQuestions() }, methods: { async fetchPaperAndQuestions() { try { const res await api.exam.getPaperDetail(this.$route.params.paperId) this.paper res.data.paper this.questions res.data.questions this.currentQuestionIndex 0 this.initAnswerMap() // 初始化答题卡map{questionId: selectedOption} } catch (e) { this.$message.error(试卷加载失败) } } }这里api.exam.getPaperDetail()调用的是api/exam.js里封装的Axios请求res.data.questions是后端ExamPaperVO里嵌套的ListQuestionVO。学生能看到“后端VO对象如何序列化为JSON前端如何反序列化为JS对象”比任何理论讲解都直观。第三步答题卡状态管理用Map对象answerMap记录每道题的选择div v-for(q, index) in questions :keyq.id p{{ index 1 }}. {{ q.content }}/p div v-foropt in q.options :keyopt.id input typeradio :nameqq.id :valueopt.id v-modelanswerMap.get(q.id) label{{ opt.content }}/label /div /divv-model绑定到answerMap.get(q.id)实现了“选中即更新”。当学生点击下一题时nextQuestion()方法只需answerMap.set(currentQuestion.id, selectedOption)——状态管理如此简单却完美覆盖了单选、多选改用v-modelanswerMap.get(q.id)为数组即可、判断题所有题型。第四步交卷时的防抖与二次确认submitExam()方法里有两重保险submitExam() { // 1. 防抖防止用户手抖连点两次 if (this.isSubmitting) return this.isSubmitting true // 2. 二次确认 this.$confirm(确定交卷交卷后无法修改答案, 提示, { confirmButtonText: 确定, cancelButtonText: 取消, type: warning }).then(() { const data { paperId: this.paper.id, answers: Array.from(this.answerMap.entries()) // 转为[[q1id,o1id],[q2id,o2id]]格式 } api.exam.submitExam(data).then(res { this.$message.success(交卷成功) this.$router.push(/front/result/ res.data.examRecordId) }) }).catch(() { this.isSubmitting false }) }isSubmitting开关阻止重复提交$confirm弹窗是用户体验的底线——这些细节才是区分“能跑”和“专业”的分水岭。4. 本地一键部署全流程详解4.1 环境准备三步到位拒绝“环境玄学”部署成功率99%的关键在于严格遵循顺序。很多学生失败是因为跳过了某一步比如先启动后端再建库结果报Table exam_db.exam_paper doesnt exist。第一步安装并启动MySQL 5.7- 下载地址https://dev.mysql.com/downloads/mysql/5.7.html选Windows x86_64或macOS版- 安装时务必勾选“Add MySQL to PATH”并记住root密码默认为空建议设为123456- 启动服务Windows在服务列表里找“MySql57”Mac执行brew services start mysql5.7- 验证命令行输入mysql -u root -p输入密码后出现mysql提示符即成功第二步创建数据库并执行建表脚本- 进入MySQL命令行执行sql CREATE DATABASE exam_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE exam_db; SOURCE /path/to/your/db.sql; -- 替换为db.sql的实际路径- 若报错ERROR 1067 (42000): Invalid default value for start_time说明MySQL严格模式开启临时关闭sql SET sql_mode(SELECT REPLACE(sql_mode,STRICT_TRANS_TABLES,));第三步导入Navicat初始化数据可选但强烈推荐- 打开Navicat连接本地MySQL右键“exam_db”→“运行SQL文件”→选择压缩包里的exam_db_backup.sql- 此文件包含5套试卷、20名考生学号2021001~2021020、3位教师admin/123456, teacher1/123456, teacher2/123456省去手动造数据的2小时提示db.sql脚本末尾有INSERT INTO user (username, password, role) VALUES (admin, $2a$10$..., ADMIN);密码是BCrypt加密后的123456所以后台登录用admin/123456即可。这是为了教学安全——明文密码会出现在Git历史里而BCrypt是不可逆的。4.2 IDEA导入与后端启动从解压到API可用导入步骤IDEA 2022.3实测1. 解压资源包打开IDEA → “Open” → 选择解压后的根目录含pom.xml的文件夹2. 弹出“Import Project”窗口勾选“Import project from external model”→“Maven”点击OK3. 等待Maven自动下载依赖约3分钟右下角显示“Import finished”4. 在src/main/java/com/example/exam/ExamApplication.java右键 → “Run ‘ExamApplication.main()’”启动成功标志- 控制台输出Tomcat started on port(s): 8080 (http)- 浏览器访问http://localhost:8080/api/test返回{code:200,msg:success,data:Hello World}- 访问http://localhost:8080/swagger-ui.html能看到所有接口文档常见问题排查- 报错java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication检查Project SDK是否为JDK 8File→Project Structure→Project- 报错Failed to configure a DataSource检查application.yml里spring.datasource.url的IP是否为localhost不是127.0.0.1某些MySQL配置下有差异- 报错Lombok annotation handler is not found安装Lombok插件Settings→Plugins→搜索Lombok→Install重启IDEA4.3 前端静态资源部署两种方式任选项目前端采用“前后端分离但部署在同一端口”的策略避免跨域烦恼。有两种部署方式方式一IDEA内置静态资源服务推荐新手- 将admin/dist和front两个文件夹直接复制到src/main/resources/static/目录下- 目录结构变为src/main/resources/static/ ├── admin/dist/index.html → 访问 localhost:8080/admin/dist/index.html └── front/index.html → 访问 localhost:8080/front/index.html- 启动后端浏览器直接访问对应URL即可。这是最简单的“零配置”方案。方式二Tomcat独立部署贴近生产环境- 将admin/dist重命名为adminfront保持原名放入Tomcat的webapps目录- 修改Tomcat的conf/server.xml在Host标签内添加xml Context path/javazaixiankaoshi/admin docBaseadmin reloadabletrue/ Context path/javazaixiankaoshi/front docBasefront reloadabletrue/- 启动Tomcat访问http://localhost:8080/javazaixiankaoshi/admin/index.html- 此方式需确保后端application.yml里server.servlet.context-path/javazaixiankaoshi保持路径一致实操心得我建议新手用方式一因为所有路径都在IDEA里可控等你熟悉了再用方式二体验“真正的Web服务器部署”。另外front/index.html里axios.defaults.baseURL /api所以前端请求/api/exam/list会自动拼接到后端localhost:8080/api/exam/list无需配置代理。5. 常见问题与排查技巧实录5.1 数据库相关问题速查表问题现象根本原因解决方案经验备注Unknown column xxx in field listdb.sql脚本未执行或执行时未USE exam_db重新执行SOURCE /path/to/db.sql确保先USE exam_db血泪教训我带过的学生里80%的此类报错都是忘了USE数据库Data truncation: Data too long for column content at row 1题目内容超长question.content字段定义为varchar(500)修改db.sql中content字段为text重新执行ALTER TABLE question MODIFY content TEXT;毕设中题目描述常含公式图片链接text类型更稳妥Navicat导入exam_db_backup.sql失败提示Invalid default value for create_timeMySQL 5.7严格模式禁止datetime默认值为0000-00-00 00:00:00执行SET sql_mode(SELECT REPLACE(sql_mode,STRICT_TRANS_TABLES,));后再导入这个命令只对当前会话生效导入完可忽略5.2 后端启动问题深度解析问题启动时报Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException这是JDK 9移除了Java EE模块的典型症状。虽然项目要求JDK 8但有些同学电脑预装了JDK 17IDEA却没切换过来。排查步骤1. 终端执行java -version确认输出是java version 1.8.0_2912. IDEA中File→Project Structure→Project Settings→Project→Project SDK必须指向JDK 8路径如C:\Program Files\Java\jdk1.8.0_2913. 同样检查Modules→Dependencies→Module SDK确保也是JDK 8终极方案在pom.xml中强制排除冲突依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency问题Swagger页面空白控制台报Uncaught ReferenceError: SwaggerUIBundle is not defined这是Springfox 3.0.0项目所用与新版Chrome的兼容性问题。解决方案- 方法一推荐在application.yml中关闭Swagger生产环境yaml swagger: enabled: true # 开发时设为true部署时改为false- 方法二升级Swagger依赖在pom.xml中替换为xml dependency groupIdio.springfox/groupId artifactIdspringfox-swagger2/artifactId version3.0.0/version /dependency dependency groupIdio.springfox/groupId artifactIdspringfox-swagger-ui/artifactId version3.0.0/version /dependency并在SwaggerConfig.java中添加EnableSwagger2WebMvc注解5.3 前端访问问题实战指南问题访问localhost:8080/front/index.html显示白屏控制台报Failed to load resource: the server responded with a status of 404 ()这99%是静态资源路径问题。三步定位法1. 打开浏览器开发者工具F12→ Network标签刷新页面看哪个.js或.css文件状态是4042. 如果是/front/js/app.js404说明front文件夹没放对位置——必须放在src/main/resources/static/front/下3. 如果是/api/exam/list404说明后端没启动或application.yml里server.servlet.context-path配置了前缀如/exam此时前端请求应为/exam/api/exam/list问题考生登录后答题页显示“暂无题目”但数据库里明明有试卷这是典型的权限校验逻辑。检查- 后端ExamPaperController.java中PreAuthorize(hasRole(TEACHER))是否误加在考生接口上- 前端api/exam.js里getPaperList()请求是否用了/api/exam/paper/list教师接口而非/api/exam/paper/student/list考生接口- 数据库exam_paper表中status字段是否为1进行中start_time是否早于当前时间end_time是否晚于当前时间——三者必须同时满足考生才能看到试卷最后分享一个小技巧在ExamPaperService.java的getStudentPaperList()方法开头加一行日志java log.info(查询考生{}的试卷当前时间{}状态条件status1 AND start_timenow AND end_timenow, studentId, LocalDateTime.now());启动时观察控制台日志立刻知道是时间条件不匹配还是SQL本身有问题。这才是工程师该有的排查姿势。6. 毕设扩展与答辩加分项建议这个系统不是终点而是你展示技术深度的起点。以下是几个零成本、高回报的扩展方向答辩时能让老师眼前一亮方向一增加考试防作弊机制1小时可完成- 在FrontExam.vue的mounted()里加入javascript // 禁用F12和右键 document.onkeydown function(e) { if (e.key F12 || (e.ctrlKey e.shiftKey e.key I)) { e.preventDefault() alert(考试中禁止开发者工具) } } document.addEventListener(contextmenu, e e.preventDefault())- 后端ExamRecordController.java中submitExam()方法增加IP校验java String clientIp request.getRemoteAddr(); if (recordDao.selectByStudentIdAndIp(studentId, clientIp).size() 0) { throw new BusinessException(同一IP已提交过考试) }这些改动不涉及核心业务但体现了你对“系统完整性”的思考。方向二成绩统计图表可视化用ECharts 5行代码搞定- 在admin/src/views/statistics/ScoreChart.vue中htmljavascriptmounted() {this.initChart()},methods: {initChart() {const chart echarts.init(document.getElementById(‘chart’))chart.setOption({title: { text: ‘班级成绩分布’ },tooltip: {},xAxis: { data: [‘60以下’,‘60-70’,‘70-80’,‘80-90’,‘90以上’] },yAxis: {},series: [{ type: ‘bar’, data: [5, 8, 12, 6, 3] }]})}} 引入echarts依赖后瞬间让成绩页从表格升级为数据大屏。方向三导出成绩为PDFiText 7.1.153个类搞定- 添加Maven依赖xml dependency groupIdcom.itextpdf/groupId artifactIditext7-core/artifactId version7.1.15/version typepom/type /dependency- 编写PdfExportService.java用PdfWriter和Document生成带表格的PDF比POI导出Excel更显技术功底。这些扩展不是为了堆砌功能而是向老师证明你不仅会“用框架”更能理解“框架能做什么”并主动用技术解决真实问题。就像我去年指导的一位学生在答辩时演示了“防切屏”功能并解释“如果考生AltTab切到微信visibilitychange事件会捕获并记录这是我对前端生命周期的理解。”——这句话比写一百行CRUD代码更有力量。我个人在实际带毕设的过程中发现老师最欣赏的从来不是“功能最多”的系统而是“每个功能背后都有清晰思考痕迹”的项目。当你能指着db.sql里那行KEY idx_teacher_status (teacher_id,status)说“这里建联合索引是因为教师查自己发布的试卷总是按status过滤避免全表扫描”或者指着ExamPaperService.java里Transactional说“试卷创建必须原子性否则出现‘试卷存了但题目没关联’的脏数据”你就已经超越了90%的同学。这个系统提供的不是一个现成的答案而是一张标满坐标的地图——剩下的路你来走。本文还有配套的精品资源点击获取简介毕业设计直接可用的在线考试系统后端用SpringBoot开发结构清晰、注释完整接口按RESTful规范设计适合Java初学者理解MVC分层和前后端分离逻辑前端基于Vue 2.x构建实现考生答题界面、教师出题管理、试卷生成、自动阅卷、成绩导出等核心功能界面响应式适配PC端。资源包包含完整前后端源码含标准maven结构pom.xml和src目录、MySQL 5.7兼容的db.sql建表脚本、带初始测试数据的Navicat可导入备份、Tomcat部署操作说明文档以及常用开发工具推荐清单。本地运行只需导入IDEA执行MySQL脚本建库启动SpringBoot主类后台管理地址为localhost:8080/项目名/admin/dist/index.html考生端访问localhost:8080/项目名/front/index.html即可使用。所有模块已在Windows/Mac环境实测通过无缺失依赖、无编译报错、无需修改配置即可一键运行。本文还有配套的精品资源点击获取