在线考试系统的时间控制(倒计时)

     在线考试系统的时间控制倒计时跟一般的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 . 上面说的获取不够详细,但是实现该功能的所有步骤已经给各位展示了,谢谢大家

  • 11
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
首先,需要确定使用的按键数和对应的引脚。假设使用两个按键,一个用于开始/暂停倒计时,另一个用于重置倒计时。 其次,需要计算出倒计时时间,可以通过按下按键时增加/减少计时器的计数值来实现。例如,假设每次按下按键增加/减少1秒的倒计时时间。 接下来,需要使用定时器来实现倒计时功能。定时器的中断函数中,每隔一定时间(例如1秒)检查计数器的值是否为0,如果不为0则减1,直到计数器为0时停止倒计时。 最后,需要在程序中加入按键的检测逻辑,根据按键状态(按下或释放)执行相应的操作,例如开始/暂停倒计时、重置计数器等。 以下是基本框架代码: ``` #include <reg51.h> sbit start_stop_key = P1^0; sbit reset_key = P1^1; unsigned int countdown_time = 60; // 初始倒计时时间为60秒 unsigned int counter = 0; // 计数器 void timer0_isr() interrupt 1 // 定时器0中断函数 { TH0 = 0xFC; // 重新赋初值 TL0 = 0x67; counter--; if (counter == 0) { TR0 = 0; // 停止计时 } } void main() { TMOD = 0x01; // 定时器0工作在模式1 TH0 = 0xFC; // 计时器初值,计时1s TL0 = 0x67; ET0 = 1; // 允许定时器0中断 EA = 1; // 全局中断允许 while(1) { if (start_stop_key == 0) // 如果开始/暂停按键按下 { if (TR0 == 0) // 如果计时器未开始计时,则开始计时 { TR0 = 1; } else // 如果计时器正在计时,则暂停计时 { TR0 = 0; } while(start_stop_key == 0); // 等待按键释放 } if (reset_key == 0) // 如果重置按键按下 { counter = countdown_time; // 重置计数器 TR0 = 0; // 停止计时 while(reset_key == 0); // 等待按键释放 } } } ``` 请注意,以上代码仅为示例,需要根据实际情况进行修改和调试。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值