web 考试 练习

This commit is contained in:
flower 2019-01-21 01:19:25 +08:00
parent 5fe928d3e7
commit 4a322070ca
9 changed files with 634 additions and 6 deletions

View File

@ -0,0 +1,177 @@
package com.ruoyi.cms.controller;
import com.ruoyi.common.base.AjaxResult;
import com.ruoyi.exam.domain.*;
import com.ruoyi.exam.service.*;
import com.ruoyi.framework.jwt.JwtUtil;
import com.ruoyi.framework.web.exception.base.BaseException;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysUserService;
import com.sun.tools.internal.ws.wsdl.document.jaxws.Exception;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.*;
/**
* Created by flower on 2019/1/21.
*/
@Controller
@RequestMapping("/web")
public class CmsExaminationController {
private String prefix = "web/examination/";
@Autowired
private IExamExaminationService examExaminationService;
@Autowired
private IExamPaperService examPaperService;
@Autowired
private IExamUserExaminationService examUserExaminationService;
@Autowired
private ISysUserService sysUserService;
@Autowired
private IExamExaminationUserService examExaminationUserService;
@Autowired
private IExamUserExaminationQuestionService examUserExaminationQuestionService;
@Autowired
private IExamQuestionService examQuestionService;
@Autowired
private IExamPaperQuestionService examPaperQuestionService;
@Autowired
private IExamPaperTypeNumberService examPaperTypeNumberService;
@RequestMapping("/examination")
@GetMapping()
public String list() {
return prefix + "list";
}
@RequestMapping("/examination/start/{id}")
@GetMapping()
public String start(@PathVariable String id, ModelMap mmap) {
ExamExamination examExamination = examExaminationService.selectById( id );
SysUser sysUser = sysUserService.selectUserByLoginName( JwtUtil.getLoginName() );
Integer userId = Integer.parseInt( sysUser.getUserId().toString() );
//考试类型
String type = examExamination.getType();
//试卷ID
Integer examPaperId = examExamination.getExamPaperId();
//考试次数
Integer examNumber = examExamination.getExamNumber();
//考试时长
Integer timeLength = examExamination.getTimeLength();
//考试记录ID
Integer examUserExaminationId = -1;
if(1==1){
throw new BaseException("已超过" + examNumber + "次考试,");
}
ExamUserExamination insert = new ExamUserExamination();
//正式考试
if (type.equals( "2" )) {
ExamUserExamination examUserExamination = new ExamUserExamination();
examUserExamination.setVipUserId( userId );
examUserExamination.setExamPaperId( examPaperId );
examUserExamination.setExamExaminationId( Integer.parseInt( id ) );
//考试记录集合
List<ExamUserExamination> userExamination = examUserExaminationService.selectLastOne( examUserExamination );
// 最后一次考试
ExamUserExamination last;
//超过考试次数
if (userExamination.size() >= examNumber) {
last = userExamination.get( 0 );
//最后一次考试已交卷直接返回
if (last.getUpdateDate() != null && !last.getUpdateDate().equals( "" )) {
throw new BaseException("已超过" + examNumber + "次考试,");
// return error( 500, "已超过" + examNumber + "次考试," );
} else {
// 最后一次考试未交卷但超过考试时长,直接返回
if (last.getCreateDate().getTime() + timeLength * 60 * 1000 < new Date().getTime()) {
throw new BaseException( "已超过" + examNumber + "次考试," );
}
}
}
if (userExamination.size() <= 0 //考试次数小于0
|| userExamination.get( 0 ).getUpdateDate() != null //最后一次考试已交卷
|| userExamination.get( 0 ).getCreateDate().getTime() + timeLength * 60 * 1000 < new Date().getTime()//最后一次考试已超过考过时长
) {
insert.setExamExaminationId( Integer.parseInt( id ) );
insert.setVipUserId( userId );
insert.setCreateDate( new Date() );
insert.setExamPaperId( examPaperId );
insert.setDelFlag( "0" );
insert.setScore( 0 );
examUserExaminationService.insertOne( insert );
examUserExaminationId = insert.getId();
} else {
examUserExaminationId = userExamination.get( 0 ).getId();
}
}
ExamPaper examPaper = examPaperService.selectById(examPaperId);
List<ExamQuestionVO> data = new ArrayList<>();
List<ExamQuestionVO> list = examPaperService.selectQuestionAndItemByPaperId( examPaperId );
//随机试卷
if(examPaper.getType().equals("2")){
Collections.shuffle( list );
ExamPaperTypeNumber examPaperTypeNumber = new ExamPaperTypeNumber();
examPaperTypeNumber.setExamPaperId(examPaperId);
List<ExamPaperTypeNumber> examPaperTypeNumbers = examPaperTypeNumberService.selectList(examPaperTypeNumber);
//三种题型的数量
int one=0,two=0,three=0;
for (ExamPaperTypeNumber item : examPaperTypeNumbers) {
if(item.getExamQuestionType()==1){
one = item.getNumber();
}
if(item.getExamQuestionType()==2){
two = item.getNumber();
}
if(item.getExamQuestionType()==3){
three = item.getNumber();
}
}
for (ExamQuestionVO item : list) {
if(item.getType().equals("1")&&one>0){
data.add(item);
one--;
}
if(item.getType().equals("2")&&two>0){
data.add(item);
two--;
}
if(item.getType().equals("3")&&three>0){
data.add(item);
three--;
}
}
}else{
data = list;
}
//是否乱序
if (examExamination.getQuestionDisorder().equals( "2" )) {
Collections.shuffle( list );
}
mmap.put( "data", data );
mmap.put( "examUserExaminationId", examUserExaminationId );
mmap.put( "examExamination", examExamination );
return prefix+"deatil";
}
}

View File

@ -0,0 +1,53 @@
package com.ruoyi.cms.controller;
import com.ruoyi.exam.domain.ExamQuestionVO;
import com.ruoyi.exam.service.IExamPracticeService;
import com.ruoyi.exam.service.IExamQuestionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* Created by flower on 2019/1/18.
*/
@Controller
@RequestMapping("/web")
public class CmsPracticeController {
@Autowired
private IExamPracticeService examPracticeService;
@Autowired
private IExamQuestionService examQuestionService;
private String prefix = "web/practice/";
@RequestMapping("/practice")
@GetMapping()
public String list() {
return prefix + "list";
}
@RequestMapping("/practice/start/{id}")
@GetMapping()
public String start(@PathVariable String id, ModelMap mmap) {
HashMap<String, Object> map = new HashMap<>();
map.put("practiceId", id);
List<ExamQuestionVO> result = examQuestionService.selectQuestionListByPracticeId(map);
if (map.containsKey("disorder") && map.get("disorder").toString().equals("1")) {
Collections.shuffle(result);
}
mmap.put("data", result);
return prefix + "detail";
}
}

View File

@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<meta charset="utf-8">
<header th:include="web/index::cmsHeader"></header>
<body>
<div class="fly-header layui-bg-black" th:replace="web/index::top">
</div>
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="fly-panel">
<div class="layui-col-md12">
<div class="layui-card" th:each="question:${data}">
<div class="layui-card-header"><span th:text="${question.title}"></span>
<span th:if="${question.type=='1'}">(单选)</span>
<span th:if="${question.type=='2'}">(多选)</span>
<span th:if="${question.type=='3'}">(判断)</span>
</div>
<div class="layui-card-body" th:each="item:${question.questionItem}">
<input th:class="${question.id}+'useranswer'" th:if="${question.type=='2'}" type="checkbox" th:name="${question.id}" th:value="${item.number}">
<input th:class="${question.id}+'useranswer'" th:if="${question.type != '2'}" type="radio" th:name="${question.id}" th:value="${item.number}">
[[${item.number}]]:
<span th:text="${item.content}"></span>
</div>
<div class="layui-card-body">
<button class="layui-btn layui-btn-warm" th:onclick="'analysis('+${question.id}+',\''+${question.answer}+'\')'">解析</button>
</div>
<div class="layui-card-body" hidden th:id="${question.id}+'answer'">
解析:正确答案[[${question.answer}]]<br>
[[${question.label}]]
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="fly-footer" th:replace="web/index::cmsBottom">
</div>
<script src="/web/res/layui/layui.js"></script>
<script src="/js/jquery.min.js"></script>
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_30088308'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "w.cnzz.com/c.php%3Fid%3D30088308' type='text/javascript'%3E%3C/script%3E"));</script>
<script type="text/javascript">
var layer;
$(function(){
layui.use('layer', function(){
layer = layui.layer;
});
})
function analysis(id,answer) {
var userAnswer = $("."+id+"useranswer:checked").val();
if(userAnswer != answer){
layer.msg('回答错误', {icon: 2});
$.ajax({
type : 'post',
url:"/api/v1/practice/answer",
contentType:"application/json",
data:"["+id+"]",
success : function(result) {
if (result.code != web_status.SUCCESS) {
$.modal.msgError(result.msg);
}
}
});
}
$("#"+id+"answer").show()
}
</script>
</body>
</html>

View File

@ -0,0 +1,124 @@
<!DOCTYPE HTML>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<meta charset="utf-8">
<link rel="stylesheet" th:href="@{/web/res/layui/css/layui.css}">
<link rel="stylesheet" th:href="@{/web/res/css/global.css}">
<body>
<div class="fly-header layui-bg-black" th:replace="web/index::top">
</div>
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="fly-panel">
<table class="layui-hide" id="test" lay-filter="test"></table>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="start">开始考试
</a>
<!--<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>-->
</script>
</div>
</div>
</div>
</div>
<div class="fly-footer" th:replace="web/index::cmsBottom">
</div>
<script src="/web/res/layui/layui.js"></script>
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_30088308'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "w.cnzz.com/c.php%3Fid%3D30088308' type='text/javascript'%3E%3C/script%3E"));</script>
<script type="text/javascript">
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#test'
,url:'/api/v1/examination/list'
,title: '用户数据表'
,cols: [ [
{checkbox: true}
,{field: 'name', title: '考试名称'}
,{field: 'trainCourseName', title: '课程名称'}
,{field: 'timeLength', title: '考试时长'}
,{field: 'passMark', title: '及格分数'}
,{title: '操作',toolbar: '#barDemo'}
] ]
,request: {
pageName: 'pageNumber' //页码的参数名称默认page
,limitName: 'pageSize' //每页数据量的参数名默认limit
}
,response: {
statusCode: 200 //规定成功的状态码默认0
}
,page: true
});
//头工具栏事件
table.on('toolbar(test)', function(obj){
var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'getCheckData':
var data = checkStatus.data;
layer.alert(JSON.stringify(data));
break;
case 'getCheckLength':
var data = checkStatus.data;
layer.msg('选中了:'+ data.length + ' 个');
break;
case 'isAll':
layer.msg(checkStatus.isAll ? '全选': '未全选');
break;
};
});
//监听行工具事件
table.on('tool(test)', function(obj){
var data = obj.data;
//console.log(obj)
if(obj.event === 'del'){
layer.confirm('真的删除行么', function(index){
obj.del();
layer.close(index);
});
} else if(obj.event === 'edit'){
layer.prompt({
formType: 2
,value: data.email
}, function(value, index){
obj.update({
email: value
});
layer.close(index);
});
}
});
table.on('tool(test)', function(obj){ //注tool 是工具条事件名test 是 table 原始容器的属性 lay-filter="对应的值"
var data = obj.data //获得当前行数据
,layEvent = obj.event; //获得 lay-event 对应的值
if(layEvent === 'start'){
window.location.href = "/web/practice/start/"+data.id;
}
})
});
</script>
</body>
</html>

View File

@ -31,10 +31,10 @@
<a th:href="@{/web}"><i class="iconfont icon-jiaoliu"></i>课程</a>
</li>
<li class="layui-nav-item">
<a href="case/case.html"><i class="iconfont icon-iconmingxinganli"></i>练习</a>
<a th:href="@{/web/practice}"><i class="iconfont icon-iconmingxinganli"></i>练习</a>
</li>
<li class="layui-nav-item">
<a href="http://www.layui.com/" target="_blank"><i class="iconfont icon-ui"></i>考试</a>
<a th:href="@{/web/examination}"><i class="iconfont icon-ui"></i>考试</a>
</li>
</ul>

View File

@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<meta charset="utf-8">
<header th:include="web/index::cmsHeader"></header>
<body>
<div class="fly-header layui-bg-black" th:replace="web/index::top">
</div>
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="fly-panel">
<div class="layui-col-md12">
<div class="layui-card" th:each="question:${data}">
<div class="layui-card-header"><span th:text="${question.title}"></span>
<span th:if="${question.type=='1'}">(单选)</span>
<span th:if="${question.type=='2'}">(多选)</span>
<span th:if="${question.type=='3'}">(判断)</span>
</div>
<div class="layui-card-body" th:each="item:${question.questionItem}">
<input th:class="${question.id}+'useranswer'" th:if="${question.type=='2'}" type="checkbox" th:name="${question.id}" th:value="${item.number}">
<input th:class="${question.id}+'useranswer'" th:if="${question.type != '2'}" type="radio" th:name="${question.id}" th:value="${item.number}">
[[${item.number}]]:
<span th:text="${item.content}"></span>
</div>
<div class="layui-card-body">
<button class="layui-btn layui-btn-warm" th:onclick="'analysis('+${question.id}+',\''+${question.answer}+'\')'">解析</button>
</div>
<div class="layui-card-body" hidden th:id="${question.id}+'answer'">
解析:正确答案[[${question.answer}]]<br>
[[${question.label}]]
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="fly-footer" th:replace="web/index::cmsBottom">
</div>
<script src="/web/res/layui/layui.js"></script>
<script src="/js/jquery.min.js"></script>
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");
document.write(unescape("%3Cspan id='cnzz_stat_icon_30088308'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "w.cnzz.com/c.php%3Fid%3D30088308' type='text/javascript'%3E%3C/script%3E"));</script>
<script type="text/javascript">
var layer;
$(function(){
layui.use('layer', function(){
layer = layui.layer;
});
})
function analysis(id,answer) {
var userAnswer = $("."+id+"useranswer:checked").val();
if(userAnswer != answer){
layer.msg('回答错误', {icon: 2});
$.ajax({
type : 'post',
url:"/api/v1/practice/answer",
contentType:"application/json",
data:"["+id+"]",
success : function(result) {
if (result.code != web_status.SUCCESS) {
$.modal.msgError(result.msg);
}
}
});
}
$("#"+id+"answer").show()
}
</script>
</body>
</html>

View File

@ -0,0 +1,83 @@
<!DOCTYPE HTML>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<meta charset="utf-8">
<link rel="stylesheet" th:href="@{/web/res/layui/css/layui.css}">
<link rel="stylesheet" th:href="@{/web/res/css/global.css}">
<body>
<div class="fly-header layui-bg-black" th:replace="web/index::top">
</div>
<div class="layui-container">
<div class="layui-row layui-col-space15">
<div class="layui-col-md12">
<div class="fly-panel">
<table class="layui-hide" id="test" lay-filter="test"></table>
<script type="text/html" id="barDemo">
<a class="layui-btn layui-btn-xs" lay-event="start">开始练习</a>
<!--<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>-->
</script>
</div>
</div>
</div>
</div>
<div class="fly-footer" th:replace="web/index::cmsBottom">
</div>
<script src="/web/res/layui/layui.js"></script>
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_30088308'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "w.cnzz.com/c.php%3Fid%3D30088308' type='text/javascript'%3E%3C/script%3E"));</script>
<script type="text/javascript">
layui.use('table', function(){
var table = layui.table;
table.render({
elem: '#test'
,url:'/api/v1/practice/list'
,title: '练习表'
,cols: [ [
{checkbox: true}
,{field: 'trainCourseName', title: '课程名称'}
,{field: 'name', title: '考试名称'}
,{title: '操作',toolbar: '#barDemo'}
] ]
,request: {
pageName: 'pageNumber' //页码的参数名称默认page
,limitName: 'pageSize' //每页数据量的参数名默认limit
}
,response: {
statusCode: 200 //规定成功的状态码默认0
}
,page: true
});
table.on('tool(test)', function(obj){ //注tool 是工具条事件名test 是 table 原始容器的属性 lay-filter="对应的值"
var data = obj.data //获得当前行数据
,layEvent = obj.event; //获得 lay-event 对应的值
if(layEvent === 'start'){
window.location.href = "/web/practice/start/"+data.id;
}
})
});
</script>
</body>
</html>

View File

@ -60,11 +60,12 @@ public class ApiExaminationController extends BaseController {
@GetMapping("/v1/examination/list")
public AjaxResult list(ExamExamination examExamination) {
SysUser sysUser = sysUserService.selectUserByLoginName( JwtUtil.getLoginName() );
// SysUser sysUser = sysUserService.selectUserByLoginName( JwtUtil.getLoginName() );
//
Map<String, Object> map = new HashMap<>();
map.put( "ination", examExamination );
map.put( "userId", sysUser.getUserId() );
// map.put( "userId", sysUser.getUserId() );
map.put( "userId", 1 );
List<ExamExamination> list = examExaminationService.selectListFromWeb( map );
AjaxResult success = success( "查询成功" );
success.put( "data", list );

View File

@ -37,7 +37,7 @@ public class ApiPracticeController extends BaseController {
* @return
*/
@GetMapping("/v1/practice/list")
public AjaxResult list(@RequestParam ExamPractice examPractice) {
public AjaxResult list(ExamPractice examPractice) {
List<ExamPracticeVO> list = examPracticeService.selectListFromWeb(examPractice);
AjaxResult success = success("查询成功");