在线考试系统的时间控制倒计时跟一般的html倒计时的区别:html可以很轻松地实现倒计时,但是页面刷新的同时,时间回到原点,根本没啥用。但是在线考试系统的时间控制是通过时间同步来实现真真正正的倒计时以达到刷新页面但是时间继续倒计而不会回到原点
思路:1 .点击进入考试
2 .在数据库获取试题,同时通过userId和subject_id判断score表是否含有该对象,没有则新增该对象,对象的exam_time字段为new Date() ,也就是进来考试的时间,保存到数据库---(这里不懂不必纠结,下面 有详细的解析)
3 .通过编译工具自带的Calendar 获取当前时间,减去刚进时的时间得到过了多长时间,然后 考试总时间 - 过了的时间 = 离考试结束时间 ,用session保存离考试结束时间
实战胜于解说思路千万倍,现在开始进行详细的实战演练,下面我只说重点,还有很多方法自己去写
1 .获取试题
@Override
public Map<Integer, List<ExamTest>> getExamTestBySub_idAndUser_id(Integer sub_id, String user_id) throws Exception {
//得到所有试题类型列表
List<ExamTestType> testTypeLis = iexamTestHibernateService.findAllExamType();
//存储各个类型的分值
Map<Integer, Integer> testTypeScoreMap = new HashMap<Integer, Integer>();
List<ExamTest> testList = null;
//存储各个类型的题目列表
Map<Integer, List<ExamTest>> testListMap = new HashMap<Integer, List<ExamTest>>();
if (!testTypeLis.isEmpty()) {
for (ExamTestType type : testTypeLis) {
testTypeScoreMap.put(type.getTestTypeId(), type.getTestTypeScore());
testList = iexamTestHibernateService.getTestListBySubAndTestType(1, type.getTestTypeId());
testListMap.put(type.getTestTypeId(), testList);
}
}else{
return null;
}
ExamSubjectHibernate subject = iexamTestHibernateService.getSubjectById(sub_id);
if(subject == null){
return null;
}
Integer totalTestScore = subject.getTotalScore().intValue();
Integer totalTestCount = subject.getTestCount();
System.out.println("totalTestScore:" + totalTestScore);
System.out.println("totalTestCount:" + totalTestCount);
if(!TestUtils.checkSubjectCountWithScore(totalTestCount, totalTestScore, testTypeScoreMap)){
return null;
}
//获取各个题目类型数量
Map<Integer,Integer> TestCountByEachTestType = TestUtils.getTestCountByEachTestType(totalTestCount, testTypeScoreMap);
//随机生成试题
Map<Integer,List<ExamTest>> resultMap = new HashMap<Integer,List<ExamTest>>();
for(Integer key:TestCountByEachTestType.keySet()){
Integer count = TestCountByEachTestType.get(key);
List<ExamTest> list = testListMap.get(key);
List<ExamTest> resultTestList = TestUtils.getRondomTestList(count, list);
resultMap.put(key, resultTestList);
}
//以下才是重点,通过user_id和subject_id判断该对象是否存在数据库,不存在则new一个保存,score表字段看下图
ExamScore score = examSubjectDAO.getScoreBySubId_AND_UserId(user_id, sub_id);
if(score==null){
score = new ExamScore();
score.setSub_id(sub_id);
score.setUser_id(user_id);
score.setExam_time(new Date()); //进入考试的系统时间为考试开始时间
if(!resultMap.isEmpty()){
iExamHibernateDAO.saveExamScore(score); //保存对象,如下图id为24的对象就是我刚进来考试时添加的
iExamHibernateDAO.flush();
}
}
return resultMap;
}
score表:这是我刚刚进入考试系统保存
2 .控制器代码:
@RequestMapping(value = "/toTest/{sub_id}") // request code
public String toTest(HttpServletRequest req, HttpSession session, Model model, @PathVariable Integer sub_id)
throws Exception {
ExamUserRole exam = (ExamUserRole) session.getAttribute("examUser");
UserHibernate user = exam.getUserHibernate();
ExamSubjectHibernate subject = iExamTestHibernateService.getSubjectById(sub_id);
//获取试题
Map<Integer, List<ExamTest>> examTest = iExamTestHibernateService.getExamTestBySub_idAndUser_id(sub_id,
user.getUserId());
//获取用户考试对象
ExamScore score = teacherService.getScoreBySubId_AND_UserId(user.getUserId(), sub_id);
long remainingTime = 0;
if(score!=null){
Calendar startTime = Calendar.getInstance();
startTime.setTime(score.getExam_time());
Calendar currentTime = Calendar.getInstance();
currentTime.setTime(new Date());
long startSecond = startTime.getTimeInMillis();
long currentSecond = currentTime.getTimeInMillis();
long totleSecond = subject.getTotalTime() * 60;
remainingTime = (totleSecond-(currentSecond-startSecond)/1000);
}else{
remainingTime = subject.getTotalTime() * 60;
}
req.setAttribute("examTest", examTest);
req.setAttribute("subject", subject);
if(remainingTime>=0){
req.setAttribute("remainingTime", remainingTime);
}else{
req.setAttribute("remainingTime", 0);
}
return "student/ExamTest";
}
3 .前端获取剩余时间:
该时间是以秒为单位;js处理该时间
$(document).ready(function(){
window.onload = function(){
var totleSecond = initTimer();
startTime(totleSecond); //开始倒计时
}
function initTimer(){
var totleSecond = Number($("#remainingTime").val()) //获取上图的input的剩余时间
return totleSecond;
}
function startTime(totleSecond){
$("#time").text(formatTime(totleSecond));
var timer = setInterval(function(){
totleSecond -= 1 ;
$("#remainingTime").val(totleSecond); //给上图的input更新剩余时间
if(totleSecond >=0 ){
$("#time").text(formatTime(totleSecond));
}else{
AutoSubmit();
alert("考试结束!")
clearInterval(timer);
$("#remainingTime").val("");
}
},1000)
}
function formatTime(totleSecond){
var hour = Math.floor(totleSecond/3600);
var minute = Math.floor((totleSecond%3600)/60);
var second = Math.floor(totleSecond%60);
hour = formatTimeNumber(hour);
minute = formatTimeNumber(minute)
second = formatTimeNumber(second);
return (hour +":"+minute+":"+second)
}
function formatTimeNumber(number){
if(number<10){
return "0"+number;
}else{
return number;
}
}}
4 .测试:
(刷新页面,倒计时依然进行,而且不回到原点,实现倒计时)
5 . 上面说的获取不够详细,但是实现该功能的所有步骤已经给各位展示了,谢谢大家