SpringBoot+Vue高校在线考试系统 附带详细运行指导视频

文章目录

一、项目演示

项目演示地址: 视频地址

二、项目介绍

项目描述:这是一个基于SpringBoot+Vue框架 开发的高校在线考试系统。首先,这是一个前后端分离的项目,代码简洁规范,注释说明详细,易于理解和学习。其次,这项目功能丰富,具有一个高校在线考试系统该有的所有功能。

项目功能:此项目分为三个 角色:学生教师管理员

学生 有登录、查看我的课程信息、查看我的考试信息、考试答题、查看我的成绩信息、查看公告信息、修改个人信息等功能。

教师 有登录、查看数据统计信息、查看学期信息、查看我的课程信息、管理我的题库信息、管理我的课程考试信息、管理我的课程成绩信息、查看公告信息和修改个人信息等功能。

管理员有登录、查看数据统计信息、管理所有学生信息、管理所有教师信息、管理所有管理员信息、管理所有教学组织信息、管理所有学期信息、管理所有课程信息、管理所有题库信息、管理所有课程考试信息、管理所有课程成绩信息和管理所有公告信息等功能。

应用技术:SpringBoot + Vue3.0 + MySQL + MyBatis + Redis + ElementUI-Plus + Vite

运行环境:IntelliJ IDEA2019.3.5 + MySQL5.7 + Redis5.0.5 + JDK1.8 + Maven3.6.3 + Node14.16.1 + Visual Studio Code(以上工具在项目压缩包中都自带)

三、运行截图

四、主要代码

1.考试交卷代码

java 复制代码
    /**
     * 提交考试
     *
     * @param examDTO
     * @return
     */
    @Override
    public ResponseDTO<Boolean> submitExam(ExamDTO examDTO) {
        if (CommonUtil.isEmpty(examDTO.getId())) {
            return ResponseDTO.errorByMsg(CodeMsg.DATA_ERROR);
        }

        // 获取考试信息
        Exam exam = examMapper.selectByPrimaryKey(examDTO.getId());
        if (exam == null) {
            return ResponseDTO.errorByMsg(CodeMsg.EXAM_NOT_EXIST);
        }

        // 获取当前登录用户(学生)
        String userId = examDTO.getUserId();
        if (CommonUtil.isEmpty(userId)) {
            return ResponseDTO.errorByMsg(CodeMsg.DATA_ERROR);
        }

        User user = userMapper.selectByPrimaryKey(userId);
        if (user == null) {
            return ResponseDTO.errorByMsg(CodeMsg.USER_NOT_EXIST);
        }

        // 获取考试题目
        QuestionExample questionExample = new QuestionExample();
        questionExample.createCriteria().andQuestionBankIdEqualTo(exam.getQuestionBankId());
        List<Question> questionList = questionMapper.selectByExample(questionExample);

        // 获取学生答案
        Map<String, String> answers = examDTO.getAnswers();
        if (answers == null) {
            answers = java.util.Collections.emptyMap();
        }

        // 计算成绩
        int totalScore = 0;
        for (Question question : questionList) {
            String userAnswer = answers.get(question.getId());
            String correctAnswer = question.getAnswer();

            if (!CommonUtil.isEmpty(userAnswer) && !CommonUtil.isEmpty(correctAnswer)) {
                // 多选题需要比较每个选项是否都正确
                if (question.getType() == 2) {
                    // 多选题:将答案按逗号分隔并排序后比较
                    String[] userAnswersArray = userAnswer.split(",");
                    String[] correctAnswersArray = correctAnswer.split(",");
                    java.util.Arrays.sort(userAnswersArray);
                    java.util.Arrays.sort(correctAnswersArray);
                    if (java.util.Arrays.equals(userAnswersArray, correctAnswersArray)) {
                        totalScore += question.getScore();
                    }
                } else {
                    // 单选题、判断题:直接比较答案
                    if (userAnswer.equals(correctAnswer)) {
                        totalScore += question.getScore();
                    }
                }
            }
        }

        // 计算用时(分钟)
        Integer timeUsed = examDTO.getTimeUsed();
        if (timeUsed == null) {
            timeUsed = 0;
        }

        // 计算获得学分(60分以上获得学分)
        int earnedScore = totalScore >= 60 ? 3 : 0;

        // 创建成绩记录
        Score score = new Score();
        score.setId(UuidUtil.getShortUuid());
        score.setUserId(userId);
        score.setCourseId(exam.getCourseId());
        score.setExamId(exam.getId());
        score.setScore(totalScore);
        score.setTimeUsed(timeUsed);
        score.setRank(0); // 排名稍后统一计算
        score.setEarnedScore(earnedScore);

        // 保存成绩
        int result = scoreMapper.insert(score);
        if (result <= 0) {
            return ResponseDTO.errorByMsg(CodeMsg.SCORE_SAVE_ERROR);
        }

        // 提交考试后,重新计算该考试所有学生的排名
        scoreService.updateRankByExamId(exam.getId());

        return ResponseDTO.successByMsg(true, "提交成功!您的成绩是:" + totalScore + "分");
    }

2.保存题库信息代码

java 复制代码
	/**
     * 保存题库信息
     *
     * @param questionBankDTO
     * @return
     */
    @Override
    public ResponseDTO<Boolean> saveQuestionBank(QuestionBankDTO questionBankDTO) {
        CodeMsg validate = ValidateEntityUtil.validate(questionBankDTO);
        if (!validate.getCode().equals(CodeMsg.SUCCESS.getCode())) {
            return ResponseDTO.errorByMsg(validate);
        }
        QuestionBank questionBank = CopyUtil.copy(questionBankDTO, QuestionBank.class);
        if (CommonUtil.isEmpty(questionBank.getId())) {
            questionBank.setId(UuidUtil.getShortUuid());
            if (questionBankMapper.insertSelective(questionBank) == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.QUESTION_BANK_ADD_ERROR);
            }
        } else {
            if (questionBankMapper.updateByPrimaryKeySelective(questionBank) == 0) {
                return ResponseDTO.errorByMsg(CodeMsg.QUESTION_BANK_EDIT_ERROR);
            }
        }
        return ResponseDTO.successByMsg(true, "保存成功!");
    }

3.用户登录代码

java 复制代码
    /**
     * 用户登录操作
     *
     * @param userDTO
     * @return
     */
    @Override
    public ResponseDTO<UserDTO> login(UserDTO userDTO) {
        // 进行是否为空判断
        if (CommonUtil.isEmpty(userDTO.getNo())) {
            return ResponseDTO.errorByMsg(CodeMsg.NO_EMPTY);
        }
        if (CommonUtil.isEmpty(userDTO.getPassword())) {
            return ResponseDTO.errorByMsg(CodeMsg.PASSWORD_EMPTY);
        }
        // 对比学号/学工号和密码是否正确
        UserExample userExample = new UserExample();
        userExample.createCriteria().andNoEqualTo(userDTO.getNo()).andPasswordEqualTo(userDTO.getPassword())
                .andRoleIdEqualTo(userDTO.getRoleId());
        List<User> userList = userMapper.selectByExample(userExample);
        if (userList == null || userList.size() != 1) {
            return ResponseDTO.errorByMsg(CodeMsg.NO_PASSWORD_ERROR);
        }
        // 生成登录token并存入Redis中
        UserDTO selectedUserDto = CopyUtil.copy(userList.get(0), UserDTO.class);
        String token = UuidUtil.getShortUuid();
        selectedUserDto.setToken(token);
        // 把token存入redis中 有效期1小时
        stringRedisTemplate.opsForValue().set("USER_" + token, JSON.toJSONString(selectedUserDto), 3600,
                TimeUnit.SECONDS);
        return ResponseDTO.successByMsg(selectedUserDto, "登录成功!");
    }
相关推荐
wuxia21188 小时前
在5种环境中编写点击元素改变内容和颜色的JavaScript程序
javascript·微信小程序·vue·jquery·react
Sweet锦9 小时前
Vue3 集成 ApexCharts 避坑指南:从动画失效到自定义指令的完美解决方案
vue·echarts
就改了9 小时前
ElasticsearchRestTemplate使用方法详解!!!
java·elasticsearch·springboot
王小王-1231 天前
基于深度学习的个性化音乐推荐系统的设计与开发
人工智能·深度学习·mysql·vue·推荐算法·个性化音乐推荐系统·音乐预测
alexander0681 天前
使用vite脚手架,快速创建一个vue3的项目
vue
toooooop83 天前
UniApp Vue2 动态修改 SCSS 伪类颜色
vue
这是个栗子3 天前
微信小程序开发(九)- uni-app微信小程序商城
微信小程序·小程序·uni-app·vue·vuex
鹤鸣的日常4 天前
前端运行时动态环境变量方案
前端·react.js·docker·前端框架·vue·gitlab
来杯@Java5 天前
学生选课管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·maven·mybatis