作者主页:编程千纸鹤
作者简介:Java、前端、Python开发多年,做过高程,项目经理,架构师
主要内容:Java项目开发、毕业设计开发、面试技术整理、最新技术分享
收藏点赞不迷路 关注作者有好处
文末获得源码
项目编号:JL
一,项目简介
随着计算机技术的不断发展,我们的日常生活和工作都与计算机技术的关系越来越密切。计算机技术的发展改变了我们日常的生活和工作习惯,也改变了社会的发展速度,使得我们的生活更加便利和高效。伴随着计算机技术发展起来的互联网技术将我们的生活带领进信息化时代,改变了我们的学习和工作环境,例如我们经常面对的考试也随着互联网技术的发展产生了改变,伴随着信息技术的发展,在线无纸化的考试系统应运而生,不仅彻底改变了传统纸质考试的习惯和环境,更是提高了考试效率,保证了考试效果,达到了考试目的[1]。传统的纸质考试具有很多局限性和不足,主要包括以下几点:
1.传统纸质考试需要较多的人力资源和时间资源进行题目的设定,同时题目的难易程度和考核价值水平很难达到基本的要求;
2.传统纸质考试的阅卷采用人工的方式,人工阅卷难免会出现阅卷差错或者分数合算差错,这也会对考试的效果造成影响;
3.传统纸质考试的人工阅卷模式也会浪费大量的人力资源和时间资源,不能保证工作效率和工作质量;
4.传统纸质考试对考试的总结能力较差,不能够全面具体的分析考试结果,教师也很难得到基本的考试结果分析的数据信息,而这些数据信息是提高教学质量和教学效果的关键因素;
5.传统纸质考试对考试时间以及考试纪律的要求不能达到统一,这也会影响到考试的公平性。根据以上分析的传统纸质考试的不足之处,新型的结合计算机技术以及互联网技术的在线考试系统应运而生,不仅通过一种新的技术解决了传统纸质考试的基本问题,还提供了一种新的考试思路和考试理念,纠正了传统纸质考试的弊端,提供更加合理有效的考试过程。
二,环境介绍
三,技术说明
四,功能列表
4.1 学生系统功能
4.2 管理系统功能
4.3 小程序功能
五,数据库设计
仅展示部分数据库字段设计
5.1试卷表
5.2 试卷答案表
5.3 题目表
5.4 学科表
5.5 用户表
5.6 用户日志表
其他表的设计省略............
六,系统展示
6.1 后台管理
主页
用户管理
试卷管理
题目管理
添加题目
添加试卷
任务管理
教育管理
成绩管理
6.2 学生端
首页登录与注册
学生端首页
试卷中心
考试记录
错题本
个人中心
6.3 小程序端
登录与注册
首页
试卷考试
考试记录
我的
七,核心代码展示
@Servicepublic class TaskExamServiceImpl extends BaseServiceImpl<TaskExam> implements TaskExamService {protected final static ModelMapper modelMapper = ModelMapperSingle.Instance();private final TaskExamMapper taskExamMapper;private final TextContentService textContentService;private final ExamPaperMapper examPaperMapper;@Autowiredpublic TaskExamServiceImpl(TaskExamMapper taskExamMapper, TextContentService textContentService, ExamPaperMapper examPaperMapper) {super(taskExamMapper);this.taskExamMapper = taskExamMapper;this.textContentService = textContentService;this.examPaperMapper = examPaperMapper;}@Overridepublic PageInfo<TaskExam> page(TaskPageRequestVM requestVM) {return PageHelper.startPage(requestVM.getPageIndex(), requestVM.getPageSize(), "id desc").doSelectPageInfo(() ->taskExamMapper.page(requestVM));}@Override@Transactionalpublic void edit(TaskRequestVM model, User user) {ActionEnum actionEnum = (model.getId() == null) ? ActionEnum.ADD : ActionEnum.UPDATE;TaskExam taskExam = null;if (actionEnum == ActionEnum.ADD) {Date now = new Date();taskExam = modelMapper.map(model, TaskExam.class);taskExam.setCreateUser(user.getId());taskExam.setCreateUserName(user.getUserName());taskExam.setCreateTime(now);taskExam.setDeleted(false);//保存任务结构TextContent textContent = textContentService.jsonConvertInsert(model.getPaperItems(), now, p -> {TaskItemObject taskItemObject = new TaskItemObject();taskItemObject.setExamPaperId(p.getId());taskItemObject.setExamPaperName(p.getName());return taskItemObject;});textContentService.insertByFilter(textContent);taskExam.setFrameTextContentId(textContent.getId());taskExamMapper.insertSelective(taskExam);} else {taskExam = taskExamMapper.selectByPrimaryKey(model.getId());modelMapper.map(model, taskExam);TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());//清空试卷任务的试卷Id,后面会统一设置List<Integer> paperIds = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class).stream().map(d -> d.getExamPaperId()).collect(Collectors.toList());examPaperMapper.clearTaskPaper(paperIds);//更新任务结构textContentService.jsonConvertUpdate(textContent, model.getPaperItems(), p -> {TaskItemObject taskItemObject = new TaskItemObject();taskItemObject.setExamPaperId(p.getId());taskItemObject.setExamPaperName(p.getName());return taskItemObject;});textContentService.updateByIdFilter(textContent);taskExamMapper.updateByPrimaryKeySelective(taskExam);}//更新试卷的taskIdList<Integer> paperIds = model.getPaperItems().stream().map(d -> d.getId()).collect(Collectors.toList());examPaperMapper.updateTaskPaper(taskExam.getId(), paperIds);model.setId(taskExam.getId());}@Overridepublic TaskRequestVM taskExamToVM(Integer id) {TaskExam taskExam = taskExamMapper.selectByPrimaryKey(id);TaskRequestVM vm = modelMapper.map(taskExam, TaskRequestVM.class);TextContent textContent = textContentService.selectById(taskExam.getFrameTextContentId());List<ExamResponseVM> examResponseVMS = JsonUtil.toJsonListObject(textContent.getContent(), TaskItemObject.class).stream().map(tk -> {ExamPaper examPaper = examPaperMapper.selectByPrimaryKey(tk.getExamPaperId());ExamResponseVM examResponseVM = modelMapper.map(examPaper, ExamResponseVM.class);examResponseVM.setCreateTime(DateTimeUtil.dateFormat(examPaper.getCreateTime()));return examResponseVM;}).collect(Collectors.toList());vm.setPaperItems(examResponseVMS);return vm;}@Overridepublic List<TaskExam> getByGradeLevel(Integer gradeLevel) {return taskExamMapper.getByGradeLevel(gradeLevel);}}
@Servicepublic class AuthenticationServiceImpl implements AuthenticationService {private final UserService userService;private final SystemConfig systemConfig;@Autowiredpublic AuthenticationServiceImpl(UserService userService, SystemConfig systemConfig) {this.userService = userService;this.systemConfig = systemConfig;}/*** @param username username* @param password password* @return boolean*/@Overridepublic boolean authUser(String username, String password) {User user = userService.getUserByUserName(username);return authUser(user, username, password);}@Overridepublic boolean authUser(User user, String username, String password) {if (user == null) {return false;}String encodePwd = user.getPassword();if (null == encodePwd || encodePwd.length() == 0) {return false;}String pwd = pwdDecode(encodePwd);return pwd.equals(password);}@Overridepublic String pwdEncode(String password) {return RsaUtil.rsaEncode(systemConfig.getPwdKey().getPublicKey(), password);}@Overridepublic String pwdDecode(String encodePwd) {return RsaUtil.rsaDecode(systemConfig.getPwdKey().getPrivateKey(), encodePwd);}}
<view class="exam-page"><view class="view-wrap"><view class="exam-count-down">{{remainTimeStr}}</view></view><view class="view-wrap-hidden"></view><view><view class="exam-name-title"><h1>{{form.name}}</h1></view><form bindsubmit='formSubmit'><i-panel title="{{titleItem.name}}" wx:for="{{form.titleItems}}" wx:for-item="titleItem" wx:key="{{titleItem.name}}" i-class="exam-panel-title"><i-cell-group i-class="exam-cell"><i-cell wx:for="{{titleItem.questionItems}}" wx:key="{{titleItem.id}}" wx:for-item="questionItem"><view wx:if="{{questionItem.questionType === 1}}"><rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" /><radio-group class="radio-group" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}"><label class="radio" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label"><radio color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" /><rich-text nodes="{{radioItem.prefix}}. {{radioItem.content}}" class="exam-item-left" /></label></radio-group></view><view wx:elif="{{questionItem.questionType === 2}}"><rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" class="exam-item-left" style="line-height:35px" /><checkbox-group class="exam-item-left" style="margin-left:10px" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}"><label wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label"><checkbox color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" /><rich-text nodes="{{radioItem.prefix}}. {{radioItem.content}}" class="exam-item-left" /></label></checkbox-group></view><view wx:elif="{{questionItem.questionType === 3}}"><rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" class="exam-item-left" style="line-height:35px" /><radio-group class="radio-group" class="exam-item-left" style="margin-left:10px" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}"><label class="radio" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="radioItem" class="exam-radio-item-label"><radio color="#2d8cf0" value="{{radioItem.prefix}}" checked="{{radioItem.checked}}" class="exam-item-left" /><rich-text nodes="{{radioItem.content}}" class="exam-item-left" /></label></radio-group></view><view wx:elif="{{questionItem.questionType === 4}}"><rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" /><view class="exam-input-contain" wx:for="{{questionItem.items}}" wx:key="{{questionItem.prefix}}" wx:for-item="inputItem" wx:for-index="idx"><view class="exam-input-contain-label">{{inputItem.prefix}}</view><input class="exam-input-contain-content" maxlength="-1" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}_{{idx}}" /></view></view><view wx:else><rich-text nodes="{{questionItem.itemOrder}}. {{questionItem.title}}" /><view class="exam-textarea-contain"><textarea placeholder="答案" maxlength="-1" name="{{questionItem.itemOrder}}_{{questionItem.id}}_{{questionItem.questionType}}"></textarea></view></view></i-cell></i-cell-group></i-panel><view><button class="i-btn i-btn-primary i-btn-square" form-type='submit'>提交</button></view><i-action-sheet visible="true" visible="{{timeOutShow}}" mask-closable="{{ false }}"><view slot="header" style="padding: 16px"><view class="exam-timeout-title">考试试卷结束,请提交试卷!</view><button class="i-btn i-btn-primary i-btn-square" form-type='submit'>提交</button></view></i-action-sheet></form><i-modal title="考试结果" visible="{{modalShow}}" bind:ok="returnRecord" bind:cancel="returnRecord"><view>得分:{{result}}</view></i-modal><i-spin size="large" fix wx:if="{{ spinShow }}"></i-spin><i-message id="message" /></view></view>
八,项目部署
8.1 目录结构
获取到源码进行解压后,文件列表如下:
8.2 导入数据库
打开Navicat(或者其他数据库连接工具也可),导入资料中的sql文件。
8.3 后端源码部署
8.3.1 导入源码
打开idea,新建工程【可以任意目录】。把解压后的xzs目录复制到创建好的idea工程中。进行导入。
导入进来之后,idea会进行编译。编译之后没有出现错误说明导入成功。
8.3.2 修改配置文件
修改数据库连接配置,在application-dev.yml配置文件中修改成自己的数据库名和自己的密码。
8.3.3 启动项目
SpringBoot的程序启动类,相信大部分小伙伴们都知道该怎么启动。不过在这里还是要写一下,以防个别小伙伴不知道。在src下找到XzsApplication启动类,在该类中进行右键运行即可。最后查看控制台有没有报错信息。没有报错信息,启动成功。
上面说明启动成功
8.4 管理员端和学生端部署
管理员端和学生端部署操作都是一样的,在这里以管理员端为例进行演示。
打开vscode【用其他前端开发工具打开也可】,导入资料中的vue目录下的xzs-admin工程,学生端是xzs-student。打开vscode的终端,进行安装依赖和启动项目。
8.4.1 安装依赖
命令:npm install
8.4.2 启动项目
命令:npm run serve
运行成功,端口号8002
8.5 小程序端部署
8.5.1 微信小程序开发工具下载与安装
开发工具的官方下载地址为:https://mp./debug/wxadoc/dev/devtools/download.html。
不支持Windows XP和Windows 7系统,建议使用WIN10。我这里选择Windows 64版本的安装包。
安装过程比较简单,不用设置什么,按照提示来就行了。下面是每一步详细截图
8.5.2 项目部署
打开微信开发工具---> 选择导入--->找到资料中的wx目录,导入xzs_student
到这一步会提示,输入appId,如果自己有就写自己的,没有的话,点击测试,使用测试号
导入进来之后,会自动提示是否运行,选择【信任并运行】
运行成功 。到此整个项目部署就已经完成了
九,项目总结
该项目是PC端+小程序端。Java做为后端支持。代码结构规整,源码容易阅读,功能完善,非常适合做为毕设来使用。
如果觉得《微信小程序|考试系统|基于微信小程序和SpringBoot+VUE的智能考试系统毕业设计》对你有帮助,请点赞、收藏,并留下你的观点哦!