在线考试系统

在线考试系统

一、介绍

Spring Boot+Vue前后端分离的在线考试系统

功能需求

(1)考试管理模块

管理员和教师登录系统后点击考试管理模块可以对所有考试进行查询,并且进行添加考试,添加考试可以通过添加试卷名称,试卷介绍,所属学院,所属专业,年级,考试日期,持续时间,总分,考试类型,考生提示等信息。

(2)题库管理模块

管理员和教师登录系统后,可以查询所有题库,并且增加题库,选择题型,难度,试题解析等。

(3)成绩查询模块

管理员和教师登录系统后可以查看所有学生的考试成绩,和分段成绩查询。

(4)学生管理模块

管理员和教师登录系统后可以对系统内的所有学生信息进行编辑,删除,添加等操作。

(5)教师管理模块

该模块只针对管理员开放,管理员通过对教师进行编辑,删除,添加等操作。

(6)试卷模块

学生登录系统后通过我的试卷模块进行在线考试,通过管理员和教师登录系统后台进行添加试卷,学生可以通过系统进行在线考试,考试结束后,会自动算出分数。

(7)练习模块

学生登录系统后,通过练习模块对所有题库内的试卷进行考试模拟练习,练习结束后系统会自动算出分数

(8)分数模块

学生登录系统后,通过查看自己所参加的练习和考试部分,进行分数查询。

二、管理员部分页面展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

三、教师部分页面展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

四、学生部分页面展示

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

五、部分代码

package com.wzz.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzz.Util.RedisUtil;
import com.wzz.Util.SaltEncryption;
import com.wzz.entity.QuestionBank;
import com.wzz.entity.User;
import com.wzz.entity.UserRole;
import com.wzz.service.impl.QuestionBankServiceImpl;
import com.wzz.service.impl.QuestionServiceImpl;
import com.wzz.service.impl.UserRoleServiceImpl;
import com.wzz.service.impl.UserServiceImpl;
import com.wzz.vo.CommonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping(value = "/admin")
@Slf4j
@Api(tags = "超级管理员权限相关的接口")
public class AdminController {

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private UserRoleServiceImpl userRoleService;

    @Autowired
    private QuestionServiceImpl questionService;

    @Autowired
    private QuestionBankServiceImpl questionBankService;

    //注入自己的redis工具类
    @Autowired
    private RedisUtil redisUtil;

    //jackson
    ObjectMapper mapper = new ObjectMapper();

    @GetMapping("/getUser")
    @ApiOperation("获取用户信息,可分页 ----> 查询条件(可无)(username,trueName),必须有的(pageNo,pageSize)")
    public CommonResult<List<User>> getUser(@RequestParam(required = false) String loginName,
                                            @RequestParam(required = false) String trueName,
                                            Integer pageNo, Integer pageSize) throws InterruptedException {
        log.info("执行了===>AdminController中的getUser方法");
        //参数一是当前页,参数二是每页个数
        IPage<User> userPage = new Page<>(pageNo, pageSize);
        //查询条件(可选)
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (!Objects.equals(loginName, "")) wrapper.like("username", loginName);
        if (!Objects.equals(trueName, "")) wrapper.like("true_name", trueName);
        userPage = userService.page(userPage, wrapper);
        List<User> users = userPage.getRecords();
        return new CommonResult<>(200, "success", users);
    }

    @GetMapping("/handleUser/{type}")
    @ApiOperation("管理员操作用户: type=1(启用) 2(禁用) 3(删除) userIds(需要操作的用户id)")
    public CommonResult<String> handleUser(@PathVariable("type") Integer type, String userIds) {
        log.info("执行了===>AdminController中的handleUser方法");
        //转换成数组 需要操作的用户的id数组
        String[] ids = userIds.split(",");
        if (type == 1) {//启用
            for (String id : ids) {
                //当前需要修改的用户
                User user = userService.getById(Integer.parseInt(id));
                user.setStatus(1);//设置为启用的用户
                userService.update(user, new UpdateWrapper<User>().eq("id", Integer.parseInt(id)));
            }
            return new CommonResult<>(200, "操作成功");
        } else if (type == 2) {//禁用
            for (String id : ids) {
                //当前需要修改的用户
                User user = userService.getById(Integer.parseInt(id));
                user.setStatus(2);//设置为禁用的用户
                userService.update(user, new UpdateWrapper<User>().eq("id", Integer.parseInt(id)));
            }
            return new CommonResult<>(200, "操作成功");
        } else if (type == 3) {//删除
            for (String id : ids) {
                userService.removeById(Integer.parseInt(id));
            }
            return new CommonResult<>(200, "操作成功");
        } else return new CommonResult<>(233, "操作有误");
    }

    @PostMapping("/addUser")
    @ApiOperation("管理员用户新增用户")
    public CommonResult<String> addUser(@RequestBody User user) throws NoSuchAlgorithmException {
        log.info("执行了===>AdminController中的addUser方法");
        //盐值
        String salt = UUID.randomUUID().toString().substring(0, 6);
        String newPwd = SaltEncryption.saltEncryption(user.getPassword(), salt);
        user.setPassword(newPwd);
        user.setSalt(salt);
        user.setCreateDate(new Date());
        boolean save = userService.save(user);
        return save ? new CommonResult<>(200, "操作成功") : new CommonResult<>(233, "操作失败");
    }

    @GetMapping("/getRole")
    @ApiOperation("查询系统存在的所有角色信息")
    public CommonResult<Object> getRole() {
        log.info("执行了===>AdminController中的getRole方法");
        if (redisUtil.get("userRoles") != null) {//redis中有缓存
            return new CommonResult<>(200, "success", redisUtil.get("userRoles"));
        } else {//redis无缓存
            List<UserRole> userRoles = userRoleService.list(new QueryWrapper<>());
            //设置默认缓存时间(10分钟) + 随机缓存时间(0-5分钟 )  来防止缓存雪崩和击穿
            redisUtil.set("userRoles", userRoles, 60 * 10 + new Random().nextInt(5) * 60);
            return new CommonResult<>(200, "success", userRoles);
        }
    }

}

package com.wzz.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzz.Util.CheckToken;
import com.wzz.Util.RedisUtil;
import com.wzz.Util.SaltEncryption;
import com.wzz.Util.TokenUtils;
import com.wzz.entity.User;
import com.wzz.entity.UserRole;
import com.wzz.service.impl.UserRoleServiceImpl;
import com.wzz.service.impl.UserServiceImpl;
import com.wzz.vo.CommonResult;
import com.wzz.vo.TokenVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Objects;
import java.util.Random;
import java.util.UUID;

@RestController
@RequestMapping(value = "/common")
@Slf4j
@Api(tags = "(学生,教师,管理员)通用相关接口", description = "提供相关的 Rest API")
public class CommonController {

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private UserRoleServiceImpl userRoleService;

    //注入自己的redis工具类
    @Autowired
    private RedisUtil redisUtil;

    //jackson
    ObjectMapper mapper = new ObjectMapper();

    @ApiOperation("用户注册接口")
    @PostMapping("/register")
    public CommonResult<String> Register(@RequestBody User user) throws NoSuchAlgorithmException {
        log.info("执行了===>CommonController中的register方法");
        //盐值
        String salt = UUID.randomUUID().toString().substring(0, 6);
        String newPwd = SaltEncryption.saltEncryption(user.getPassword(), salt);
        user.setPassword(newPwd);
        user.setSalt(salt);
        user.setCreateDate(new Date());
        //设置加密
        userService.save(user);
        //发放token令牌
        String token = TokenUtils.createToken(new TokenVo("1", user.getUsername(), newPwd));
        return new CommonResult<String>(200, "success", token);
    }

    @GetMapping("/check/{username}")
    @ApiOperation("用户名合法查询接口")
    public CommonResult<String> checkUsername(@PathVariable(value = "username") String username) {
        log.info("执行了===>CommonController中的checkUsername方法");
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        User user = userService.getOne(wrapper);
        if (user == null) return new CommonResult<>(200, "用户名可用");
        else return new CommonResult<>(233, "用户已存在");
    }

    @PostMapping("/login")
    @ApiOperation("用户登录接口")
    public CommonResult<String> login(@RequestParam(value = "username") String username,
                                      @RequestParam(value = "password") String password) throws NoSuchAlgorithmException {
        log.info("执行了===>CommonController中的login方法");
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        User user = userService.getOne(wrapper);
        if (user != null) {
            String newPwd = SaltEncryption.saltEncryption(password, user.getSalt());
            //对用户输入的密码加密后 对比数据库的密码 并且用户的状态是正常的
            if (newPwd.equals(user.getPassword()) && user.getStatus() == 1) {
                //发放token令牌
                String token = TokenUtils.createToken(new TokenVo(user.getRoleId() + "", user.getUsername(), newPwd));
                return new CommonResult<>(200, "success", token);
            } else {//密码错误 或者 账号封禁
                return new CommonResult<>(233, "账号密码错误,或用户状态异常");
            }
        } else return new CommonResult<>(233, "用户不存在");
    }

    @GetMapping("/logout")
    @ApiOperation(value = "用户主动退出登录")
    public CommonResult<String> logout() {
        log.info("执行了===>CommonController中的logout方法");
        return new CommonResult<>(200, "退出成功");
    }

    @GetMapping("/getMenu")
    @ApiOperation(value = "获取不同用户的权限菜单")
    public CommonResult<Object> getMenu(HttpServletRequest request) {
        log.info("执行了===>CommonController中的getMenu方法");
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        TokenVo tokenVo = new CheckToken().checkToken(request, userService);
        System.out.println(tokenVo);
        if (tokenVo != null) {//有效token
            if (redisUtil.get("menu:" + tokenVo.getRoleId()) != null) {
                return new CommonResult<>(200, "success", redisUtil.get("menu:" + tokenVo.getRoleId()));
            } else {
                String roleId = tokenVo.getRoleId();
                QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
                wrapper.eq("role_id", roleId);
                UserRole userRole = userRoleService.getOne(wrapper);
                redisUtil.set("menu:" + tokenVo.getRoleId(), userRole.getMenuInfo(), 60 * 60 * 10 + new Random().nextInt(5) * 60 * 60);
                return new CommonResult<>(200, "success", userRole.getMenuInfo());
            }

        } else {
            return new CommonResult<>(233, "认证信息有误,获取数据失败");
        }
    }

    @GetMapping("/checkToken")
    @ApiOperation("验证用户token接口")
    public CommonResult<TokenVo> checkToken(HttpServletRequest request) {
        log.info("执行了===>CommonController中的checkToken方法");
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        TokenVo tokenVo = new CheckToken().checkToken(request, userService);
        if (tokenVo != null) {//有效token
            return new CommonResult<>(200, "success", tokenVo);
        } else {
            return new CommonResult<>(233, "token无效");
        }
    }

    @GetMapping("/getCurrentUser")
    @ApiOperation("供给普通用户查询个人信息使用")
    public CommonResult<User> getCurrentUser(HttpServletRequest request) {
        log.info("执行了===>CommonController中的getCurrentUser方法");
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        TokenVo tokenVo = new CheckToken().checkToken(request, userService);
        User user = userService.getOne(new QueryWrapper<User>().eq("username", tokenVo.getUsername()));
        return new CommonResult<>(200, "查询当前用户成功", user);
    }

    @PostMapping("/updateCurrentUser")
    @ApiOperation("供给用户更改个人信息")
    public CommonResult<String> updateCurrentUser(HttpServletRequest request,@RequestBody User user) throws NoSuchAlgorithmException {
        log.info("执行了===>CommonController中的updateCurrentUser方法");
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        TokenVo tokenVo = new CheckToken().checkToken(request, userService);
        User curUser = userService.getOne(new QueryWrapper<User>().eq("username", tokenVo.getUsername()));
        if (!Objects.equals(user.getPassword(), "")){
            String newPwd = SaltEncryption.saltEncryption(user.getPassword(), curUser.getSalt());
            curUser.setPassword(newPwd);
        }
        curUser.setTrueName(user.getTrueName());
        boolean flag = userService.update(curUser, new UpdateWrapper<User>().eq("username", tokenVo.getUsername()));
        return flag ? new CommonResult<>(200,"更新成功") : new CommonResult<>(233,"更新失败");
    }
}

六、底部获取源码(9.9¥带走)

有问题,或者需要协助调试运行项目的也可以

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一杯奶茶¥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值