SpringBoot+Vue轻松实现考试管理系统

简介

本系统基于 Spring Boot 搭建的方便易用、高颜值的教学管理平台,提供多租户、权限管理、考试、练习、在线学习等功能。主要功能为在线考试、练习、刷题,在线学习。课程内容支持图文、视频,考试类型支持考试、练习、问卷。

源码下载

网盘链接 密码8418

在这里插入图片描述
在这里插入图片描述

题型支持单选题、多选题、判断题、简答题、视频、语音,题目内容支持图文、视频等。支持题库、刷题功能。

本版本为 Spring Boot 版本,没有太多中间件依赖,使用、部署都非常方便,并且持续更新维护。

架构设计

在这里插入图片描述

功能概述

在这里插入图片描述

项目分 web 前台、后台管理、小程序三部分,前台、小程序主要提供考试功能,后台提供基础管理、考试管理功能。

web 前台主要功能:提供在线考试、课程学习、练习等功能。

后台主要功能:系统管理(单位管理、用户管理、部门管理、角色管理、菜单管理、操作日志、代码生成),考务管理(课程管理、考试管理、题库管理、成绩管理)。

部署指南

1. 新建数据库

我们可以使用 navicat 新建数据库,数据库名可以自定义,字符集和排序规则是确定的。

在这里插入图片描述

2. 运行 SQL 文件

我们导入源码中 init.sql 新建相关表,初始化数据。
在这里插入图片描述

3. 修改配置文件

我们把两个 yml 配置文件复制到 sg-user-service 目录中的 resource 目录中,按需进行修改,比如 MySQL 数据库用户名密码,redis 密码等。

4. 编译 jar 包

我们要检查电脑上是否安装 gradle,运行以下指令测试。

>gradle -v
------------------------------------------------------------
Gradle 8.5
------------------------------------------------------------Build time:   2023-11-29 14:08:57 UTC        
Revision:     28aca86a7180baa17117e0e5ba01d8ea9feca598Kotlin:       1.9.20
Groovy:       3.0.17
Ant:          Apache Ant(TM) version 1.10.13 compiled on January 4 2023
JVM:          17.0.9 (Oracle Corporation 17.0.9+11-LTS-jvmci-23.0-b21)
OS:           Windows 11 10.0 amd64

我们直接在根目录下运行打包指令,并跳过测试。

gradle build -x test

生成的 jar 包在 build/libs 目录下,运行 java -jar xxx.jar,后端的部署就完成了。

5. 运行前端

我们再进入 frontend/sg-exam-app 目录,运行 npm install 下载依赖,下载完成后运行npm run dev 启动运行。

后台管理项目存放在 frontend/sg-exam-app-admin 目录,运行 pnpm install 下载依赖,下载完成后运行npm run dev 启动运行。

前端部署完成。

代码讲解

下面这段代码是用来展示后台首页数据,其中 userVo 用来查询用户数量,dto 返回给客户端做数据展示功能。

首页数据

/*** 获取管控台首页数据*/@GetMapping@Operation(summary = "后台首页数据展示", description = "后台首页数据展示")public R<DashboardDto> dashboard() {String tenantCode = SysUtil.getTenantCode();DashboardDto dto = new DashboardDto();// 查询用户数量UserVo userVo = new UserVo();userVo.setTenantCode(tenantCode);dto.setOnlineUserNumber(userService.userCount(userVo).toString());// 租户数量dto.setTenantCount(tenantService.tenantCount().toString());// 查询考试数量ExaminationDashboardDto dashboardDto = examRecordService.findExamDashboardData(tenantCode);if (dashboardDto != null) {if (dashboardDto.getExaminationCount() != null) {dto.setExaminationNumber(dashboardDto.getExaminationCount().toString());}if (dashboardDto.getExamUserCount() != null) {dto.setExamUserNumber(dashboardDto.getExamUserCount().toString());}if (dashboardDto.getExaminationRecordCount() != null) {dto.setExaminationRecordNumber(dashboardDto.getExaminationRecordCount().toString());}}return R.success(dto);}

考试管理

这段代码是一个使用Java语言和Spring框架编写的RESTful API控制器。它定义了一系列的HTTP GET和POST请求方法,用于处理与考试信息管理相关的业务逻辑。下面是对这段代码的详细解释:

  1. @Slf4j:这是一个日志注解,用于在控制类中注入一个日志对象,方便记录日志。
  2. @AllArgsConstructor:这是一个Lombok注解,用于自动生成所有字段的构造函数。
  3. @Tag(name = "考试信息管理"):这是一个自定义注解,用于标记这个控制器属于哪个功能模块。
  4. @RestController:表示这是一个RESTful风格的控制器,它将返回JSON格式的数据。

接下来是部分方法的解释:

  • canStart:这个方法通过GET请求方式,提供查询是否能开始考试的功能。它接受一个Long类型的参数id,表示考试的ID。方法内部会查询该ID对应的考试信息,并检查考试是否已经开始,以及是否有结束时间限制。
  • examination:这个方法通过GET请求方式,提供根据考试ID获取考试信息的功能。
  • detail:这个方法通过GET请求方式,提供根据考试ID获取考试详细信息的功能。
  • getMembers:这个方法通过GET请求方式,提供根据考试ID获取考试成员ID的功能。
  • anonymousUserGet:这个方法通过GET请求方式,提供根据考试ID获取考试信息的功能,但是这个方法专门为匿名用户设计。
@Slf4j
@AllArgsConstructor
@Tag(name = "考试信息管理")
@RestController
@RequestMapping("/v1/examination")
public class ExaminationController extends BaseController {private final IExaminationService examinationService;private final IExamPermissionService examPermissionService;@GetMapping("canStart")@Operation(summary = "查询是否能开始考试", description = "查询是否能开始考试")public R<Boolean> canStart(@RequestParam Long id) {boolean canStart = false;Examination examination = examinationService.get(id);if (examination != null) {if (examination.getStartTime() != null && examination.getEndTime() != null) {long currentMillis = System.currentTimeMillis();canStart = ((currentMillis > examination.getStartTime().getTime()) && (examination.getEndTime().getTime() > currentMillis));} else {// 没有限制考试时间canStart = true;}}return R.success(canStart);}@GetMapping("/{id}")@Operation(summary = "获取考试信息", description = "根据考试 ID 获取考试信息")public R<Examination> examination(@PathVariable Long id) {return R.success(examinationService.get(id));}@GetMapping("/{id}/detail")@Operation(summary = "获取考试详细信息", description = "根据考试 id 获取考试详细信息")public R<ExaminationDto> detail(@PathVariable Long id) {return R.success(examinationService.getDetail(id));}@GetMapping("/{id}/getMembers")@Operation(summary = "获取考试成员 ID", description = "根据考试 ID 获取考试成员 ID")public R<MemberDto> getMembers(@PathVariable Long id) {return R.success(examPermissionService.getMembers(ExamConstant.PERMISSION_TYPE_EXAM, id));}@GetMapping("/anonymousUser/{id}")@Operation(summary = "获取考试信息", description = "根据考试 id 获取考试详细信息")public R<Examination> anonymousUserGet(@PathVariable Long id) {return R.success(examinationService.get(id));}@GetMapping("examinationList")@Operation(summary = "获取考试列表")public R<PageInfo<ExaminationDto>> examinationList(@RequestParam Map<String, Object> condition,@RequestParam(value = PAGE, required = false, defaultValue = PAGE_DEFAULT) int pageNum,@RequestParam(value = PAGE_SIZE, required = false, defaultValue = PAGE_SIZE_DEFAULT) int pageSize) {return R.success(examinationService.examinationList(condition, pageNum, pageSize));}@GetMapping("userExaminationList")@Operation(summary = "获取用户有权限的考试列表")public R<PageInfo<ExaminationDto>> userExaminationList(@RequestParam Map<String, Object> condition,@RequestParam(value = PAGE, required = false, defaultValue = PAGE_DEFAULT) int pageNum,@RequestParam(value = PAGE_SIZE, required = false, defaultValue = PAGE_SIZE_DEFAULT) int pageSize) {return R.success(examinationService.userExaminationList(condition, pageNum, pageSize));}@RequestMapping("subjectList")@Operation(summary = "获取题目列表")public R<PageInfo<SubjectDto>> subjectList(@RequestParam Map<String, Object> condition,@RequestParam(value = PAGE, required = false, defaultValue = PAGE_DEFAULT) int pageNum,@RequestParam(value = PAGE_SIZE, required = false, defaultValue = PAGE_SIZE_DEFAULT) int pageSize,SubjectDto subjectDto) {return R.success(examinationService.findSubjectPageById(subjectDto, condition, pageNum, pageSize));}@PostMapping@Operation(summary = "创建考试", description = "创建考试")@SgLog(value = "创建考试", operationType = OperationType.INSERT)public R<Boolean> add(@RequestBody @Valid ExaminationDto examinationDto) {examinationDto.setCommonValue();return R.success(examinationService.insertExamination(examinationDto) > 0);}@PutMapping("{id}")@Operation(summary = "更新考试信息", description = "根据考试 ID 更新考试的基本信息")@SgLog(value = "更新考试", operationType = OperationType.UPDATE)public R<Boolean> update(@PathVariable Long id, @RequestBody @Valid ExaminationDto examinationDto) {examinationDto.setId(id);examinationDto.setCommonValue();return R.success(examinationService.updateExamination(examinationDto) > 0);}@DeleteMapping("{id}")@Operation(summary = "删除考试", description = "根据 ID 删除考试")@SgLog(value = "删除考试", operationType = OperationType.DELETE)public R<Boolean> delete(@PathVariable Long id) {Examination examination = examinationService.get(id);if (examination != null) {examination.setCommonValue();return R.success(examinationService.delete(examination) > 0);}return R.success(Boolean.FALSE);}@PostMapping("deleteAll")@Operation(summary = "批量删除考试", description = "根据考试 id 批量删除考试")@SgLog(value = "删除考试", operationType = OperationType.DELETE)public R<Boolean> deleteAll(@RequestBody Long[] ids) {return R.success(examinationService.deleteAll(ids) > 0);}@GetMapping("nexSubjectNo/{id}")@Operation(summary = "获取下一题的序号")public R<Integer> nexSubjectNo(@PathVariable Long id) {return R.success(examinationService.nextSubjectNo(id));}@PostMapping("batchAddSubjects/{id}")@Operation(summary = "批量添加题目")@SgLog(value = "批量添加题目", operationType = OperationType.INSERT)public R<Boolean> batchAddSubjects(@PathVariable Long id, @RequestBody List<SubjectDto> subjects) {return R.success(examinationService.batchAddSubjects(id, subjects));}@PostMapping("randomAddSubjects/{id}")@Operation(summary = "随机添加题目")@SgLog(value = "随机添加题目", operationType = OperationType.INSERT)public R<Boolean> randomAddSubjects(@PathVariable Long id, @RequestBody RandomSubjectDto params) {return R.success(examinationService.randomAddSubjects(id, params));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/232523.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修改安卓apk设置为安卓主屏幕(launcher)

修改安卓apk 将apk可以设置安卓主屏幕 原理&#xff1a; 将打包好的apk文件进行拆包增加配置文件在重新编译回apk包 需要得相关文件下载 解包 apktool :https://pan.baidu.com/s/1oyCIYak_MHDJCvDbHj_qEA?pwd5j2xdex2jar&#xff1a;https://pan.baidu.com/s/1Nc-0vppVd0G…

将 Python 和 Rust 融合在一起,为 pyQuil® 4.0 带来和谐

文章目录 前言设定方向从 Rust 库构建 Python 软件包改装 pyQuil异步困境回报&#xff1a;功能和性能结论 前言 pyQuil 一直是在 Rigetti 量子处理单元&#xff08;QPUs&#xff09;上构建和运行量子程序的基石&#xff0c;通过我们的 Quantum Cloud Services&#xff08;QCS™…

GLTF编辑器设置3D纺织纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种纹理映射技术&#xff0c;通过改变顶点的位置来模拟细…

Window端口占用处理

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

【教学类-45-02】X-Y之间的三连减题(a-b-c=)

作品展示&#xff1a; 背景需求&#xff1a; 【教学类-45-01】X-Y之间的三连加题(abc)-CSDN博客文章浏览阅读5次。【教学类-45-01】X-Y之间的三连加题(abc)https://blog.csdn.net/reasonsummer/article/details/135436915 有了三连加怎么能没有三连减&#xff0c;修改参数&am…

普中STM32-PZ6806L开发板(HAL库函数实现-读取内部温度)

简介 主芯片STM32F103ZET6&#xff0c;读取内部温度其他知识 内部温度所在ADC通道 温度计算公式 V25跟Avg_Slope值 参考文档 stm32f103ze.pdf 电压计算公式 Vout Vref * (D / 2^n) 其中Vref代表参考电压&#xff0c; n为ADC的位数&#xff0c; D为ADC输入的数字信号。 实现…

C++ 二进制图片的读取和blob插入mysql_stmt_init—新年第一课

关于二进制图片的读取和BLOB插入一共包含五步 第一步&#xff1a;初始化 MYSQL_STMT* stmt mysql_stmt_init(&mysql); 第二步&#xff1a;预处理sql语句 mysql_stmt_prepare(stmt,sql,sqllen); 第三步&#xff1a;绑定字段 mysql_stmt_bind_param(stmt,bind); 第四…

CSS3 边框border、outline、box-shadow

1 border 语法&#xff1a;border: width style color 2 outline 语法&#xff1a;outline: width style color 2.1 outline-offet MDN解释&#xff1a;用于设置outline与一个元素边缘或边框之间的间隙 即&#xff1a;设置outline相对border外边缘的偏移&#xff0c;可以为…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-9PID控制器

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-9PID控制器&#xff09; P —— Proportional I —— Integral D —— Derivative 当前误差/过去误差/误差的变化趋势 K p ⋅ e K_{\mathrm{p}}\cdot e Kp​⋅e&#xff1a;比…

弹性搜索引擎Elasticsearch:本地部署与远程访问指南

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言系统环境1. Windows 安装Elasticsearch2. 本地访问Elasticsearch3. Windows 安装…

[元带你学: eMMC协议 31] CRC 错误检测保证可靠性

依公知及经验整理,原创保护,禁止转载。 专栏 《元带你学: eMMC 协议》 <<<< 返回总目录 <<<< 前言 图片来源: www.elprocus.com 对于 eMMC 存储设备,CRC 校验在数据传输过程中起到了重要的作用。它能够检测出数据在存储和传输过程中的错误,确保…

手拉手springboot3整合mybatis-plus多数据源

环境介绍 技术栈 springbootmybatis-plusmysql 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 17 Spring Boot 3.1.7 dynamic-datasource 3.6.1 mybatis-plus 3.5.3.2 加入依赖 <dependency><groupId>com.baomidou</groupId><arti…

8 单链表---带表头节点

上节课所学的顺序表的缺点 顺序表的最大问题&#xff1a;插入和删除时需要移动大量元素 链式存储的定义 链式存储的逻辑结构 链表中的基本概念&#xff1a; 注意&#xff1a;表头节点并不属于数据元素 单链表图示&#xff1a; 把3个需要的结构体定义出来&#xff1a; typdef …

【数据结构】二叉树的概念及堆

前言 我们已经学过了顺序表、链表、栈和队列这些属于线性结构的数据结构&#xff0c;那么下面我们就要学习我们第一个非线性结构&#xff0c;非线性结构又有哪些值得我们使用的呢&#xff1f;那么接下来我们就将谈谈树的概念了。 1.树的概念与结构 1.1树的概念 树是一种非线性…

docker拉取镜像提示 remote trust data does not exist for xxxxxx

1、How can I be sure that I am pulling a trusted image from docker 2、docker: you are not authorized to perform this operation: server returned 401. 以上两个问题可以试试以下解决办法 DOCKER_CONTENT_TRUSTfalse 本人是使用jenkins部署自己的项目到docker容器出现…

MvvmToolkit的使用

背景&#xff1a;MvvmLight不更新了&#xff0c;用Toolkit代替 1、首先下载好社区版本的NuGet包 2、ViewModel中需要继承ObservableObject&#xff0c;查看ObservableObject可以看到里面有实现好InotifyPropertyChanged。 3、对于属性的set&#xff0c;可以简写成一行&#xff…

多线程高级知识点

多线程高级知识点 1.ThreadLocal 1.1 什么是 ThreadLocal&#xff1f; ​ ThreadLocal 叫做本地线程变量&#xff0c;意思是说&#xff0c;ThreadLocal 中填充的的是当前线程的变量&#xff0c;该变量对其他线程而言是封闭且隔离的&#xff0c;ThreadLocal 为变量在每个线程…

qt三大控件

1.QListWidget控件 先在ui界面将 QListWidget拖出来竖直对齐 再去代码中实现文本插入 两种插入方式 方法1 //listWidget使用 有左右中间对齐需求QListWidgetItem * itemnew QListWidgetItem("床前明月光"); // //上面只是独立的一句话,没有关联起来ui-&g…

6.OpenResty系列之深入理解(二)

1. 日志输出 vim /usr/local/openresty/nginx/conf/nginx.conf默认配置如下 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid logs/nginx.pid;http {#log_format main $remote_addr - $remote_user [$time…

计算机Java项目|基于Springboot实现患者管理系统

作者主页&#xff1a;编程指南针 作者简介&#xff1a;Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容&#xff1a;Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 文末获取源码 项目编号&#xff1a;KS-032…