|  | @@ -296,7 +296,7 @@ public class RealExamService {
 | 
	
		
			
				|  |  |          } else {
 | 
	
		
			
				|  |  |              l.info("type EXERCISE,没有打开的考试,校验正确");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        // Check:针对练习(自主练习),进行特殊检查。
 | 
	
		
			
				|  |  | +        // Check:针对练习(old叫自主练习),进行特殊检查。
 | 
	
		
			
				|  |  |          if (StringUtils.equals(RealExamCollection.Type.SELF_EXERCISE, examCollectionType)) {
 | 
	
		
			
				|  |  |              // 已经open的考试。
 | 
	
		
			
				|  |  |              if (realExamCollectionService.existOpenedByType(RealExamCollection.Type.EXAM)) {
 | 
	
	
		
			
				|  | @@ -319,6 +319,12 @@ public class RealExamService {
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          RealExam re = selectRealExamByExamId(examId);
 | 
	
		
			
				|  |  | +        // 执行到开始考试,肯定已经登录了。
 | 
	
		
			
				|  |  | +        {
 | 
	
		
			
				|  |  | +            // 学员Id
 | 
	
		
			
				|  |  | +            Long userId = re.getUserId();
 | 
	
		
			
				|  |  | +            studentLoginSuccess(userId, studentBindIp);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |          // check:考试状态
 | 
	
		
			
				|  |  |          if (StringUtils.equals(re.getExamStatus(), RealExam.State.SUBMITTED) ||
 | 
	
		
			
				|  |  |                  StringUtils.equals(re.getExamStatus(), RealExam.State.CALCULATING_SCORE) ||
 | 
	
	
		
			
				|  | @@ -422,10 +428,10 @@ public class RealExamService {
 | 
	
		
			
				|  |  |          // Step:重新查询。已经确定simId和simState了。
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              // 修改exam表对应examId的一条数据,填充并锁定seat_id和sim_id值。
 | 
	
		
			
				|  |  | -            // 设置上seatId和simId
 | 
	
		
			
				|  |  |              re = selectRealExamByExamId(examId);
 | 
	
		
			
				|  |  |              seat = seatService.uniqueByBindIp(studentBindIp);
 | 
	
		
			
				|  |  |              l.debug("seat = {}", seat);
 | 
	
		
			
				|  |  | +            // 设置上seatId和simId
 | 
	
		
			
				|  |  |              re.setSeatId(seat.getSeatId());
 | 
	
		
			
				|  |  |              re.setSimId(seat.getCurrentSimId());
 | 
	
		
			
				|  |  |              updateRealExam(re);
 | 
	
	
		
			
				|  | @@ -508,7 +514,6 @@ public class RealExamService {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      public AjaxResult studentRefreshSimState(final String studentBindIp) {
 | 
	
		
			
				|  |  |          Seat seat = seatService.uniqueByBindIp(studentBindIp);
 | 
	
		
			
				|  |  |          // Check:Seat有效性。
 | 
	
	
		
			
				|  | @@ -520,7 +525,6 @@ public class RealExamService {
 | 
	
		
			
				|  |  |          return commCheckService.checkOneSeatState(seat, true);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      public AjaxResult checkExamId(final Long examId) {
 | 
	
		
			
				|  |  |          // Check:检查 examId 是否正确存在
 | 
	
		
			
				|  |  |          if (!exist(examId)) {
 | 
	
	
		
			
				|  | @@ -549,36 +553,6 @@ public class RealExamService {
 | 
	
		
			
				|  |  |          return AjaxResult.success(vo);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    public void studentMiddleReadRealExam() {
 | 
	
		
			
				|  |  | -        l.info("studentMiddleReadRealExam now = {}", new Date());
 | 
	
		
			
				|  |  | -        //
 | 
	
		
			
				|  |  | -        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpened();
 | 
	
		
			
				|  |  | -        if (rec == null ||
 | 
	
		
			
				|  |  | -                rec.getExamCollectionId() == null ||
 | 
	
		
			
				|  |  | -                rec.getExamCollectionId() == 0L ||
 | 
	
		
			
				|  |  | -                !StringUtils.equals(rec.getExamCollectionType(), RealExamCollection.Type.EXAM)) {
 | 
	
		
			
				|  |  | -            l.info("考试集合不匹配。不需要中间读取,rec = {}", rec);
 | 
	
		
			
				|  |  | -            return;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        {
 | 
	
		
			
				|  |  | -            RealExam reQ = new RealExam();
 | 
	
		
			
				|  |  | -            reQ.setExamCollectionId(rec.getExamCollectionId());
 | 
	
		
			
				|  |  | -            List<RealExam> reList = selectRealExamList(reQ);
 | 
	
		
			
				|  |  | -            for (RealExam re : reList) {
 | 
	
		
			
				|  |  | -                // 答题并且不超时的考试,进行中间读取
 | 
	
		
			
				|  |  | -                if (
 | 
	
		
			
				|  |  | -                        re != null && re.getExamId() != null && re.getExamId() != 0L &&
 | 
	
		
			
				|  |  | -                                StringUtils.equals(re.getExamStatus(), RealExam.State.ANSWERING) &&
 | 
	
		
			
				|  |  | -                                !checkRealExamIsTimeout(re.getExamId())
 | 
	
		
			
				|  |  | -                ) {
 | 
	
		
			
				|  |  | -                    commSendService.readOneExamAtMiddle(re);
 | 
	
		
			
				|  |  | -                } else {
 | 
	
		
			
				|  |  | -                    l.info("skip examId = {}", re != null ? re.getExamId() : null);
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * 10分钟延长时间。
 | 
	
		
			
				|  |  |       */
 | 
	
	
		
			
				|  | @@ -764,6 +738,9 @@ public class RealExamService {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  | +     * 仅仅针对先打开考试集合,后登录的情况有效。
 | 
	
		
			
				|  |  | +     * 表 mx_real_exam 中写入 seat_id,修改exam_status
 | 
	
		
			
				|  |  | +     * <p>
 | 
	
		
			
				|  |  |       * [学员]登录成功后调用
 | 
	
		
			
				|  |  |       *
 | 
	
		
			
				|  |  |       * @param userId
 | 
	
	
		
			
				|  | @@ -771,32 +748,31 @@ public class RealExamService {
 | 
	
		
			
				|  |  |       * @return
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      public AjaxResult studentLoginSuccess(final Long userId, final String ip) {
 | 
	
		
			
				|  |  | -        RealExamCollection rec = realExamCollectionService.selectRealExamCollectionOpened();
 | 
	
		
			
				|  |  | -        if (rec == null || rec.getExamCollectionId() == 0L) {
 | 
	
		
			
				|  |  | -            return AjaxResult.success("没有打开的考试集合");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        l.info("studentLoginSuccess userId = {},ip = {}", userId, ip);
 | 
	
		
			
				|  |  |          RealExam q = new RealExam();
 | 
	
		
			
				|  |  |          q.setUserId(userId);
 | 
	
		
			
				|  |  | -        q.setExamCollectionId(rec.getExamCollectionId());
 | 
	
		
			
				|  |  | +        q.setExamStatus(RealExam.State.NOT_LOGGED_IN);
 | 
	
		
			
				|  |  |          List<RealExam> list = selectRealExamList(q);
 | 
	
		
			
				|  |  |          if (list.isEmpty()) {
 | 
	
		
			
				|  |  |              return AjaxResult.success("没有学生考试数据");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        if (list.size() == 1) {
 | 
	
		
			
				|  |  | -            RealExam re = list.get(0);
 | 
	
		
			
				|  |  | -            if (StringUtils.equals(re.getExamStatus(), RealExam.State.NOT_LOGGED_IN) ||
 | 
	
		
			
				|  |  | -                    StringUtils.equals(re.getExamStatus(), RealExam.State.LOGGED_IN)) {
 | 
	
		
			
				|  |  | -                Seat s = seatService.uniqueByBindIp(ip);
 | 
	
		
			
				|  |  | -                if (s == null || s.getSeatId() == 0L) {
 | 
	
		
			
				|  |  | -                    return AjaxResult.success("没有座次信息");
 | 
	
		
			
				|  |  | +        for (RealExam re : list) {
 | 
	
		
			
				|  |  | +            RealExamCollection rec = realExamCollectionService.selectRealExamCollectionByExamCollectionId(re.getExamCollectionId());
 | 
	
		
			
				|  |  | +            // 如果考试集合状态是OPENED。
 | 
	
		
			
				|  |  | +            if (StringUtils.equals(rec.getExamCollectionState(), RealExamCollection.State.OPENED)) {
 | 
	
		
			
				|  |  | +                if (StringUtils.equalsAny(re.getExamStatus(), RealExam.State.NOT_LOGGED_IN, RealExam.State.LOGGED_IN)) {
 | 
	
		
			
				|  |  | +                    Seat seat = seatService.uniqueByBindIp(ip);
 | 
	
		
			
				|  |  | +                    if (seat == null || seat.getSeatId() == 0L) {
 | 
	
		
			
				|  |  | +                        return AjaxResult.error("没有座次信息");
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    re.setSeatId(seat.getSeatId());
 | 
	
		
			
				|  |  | +                    re.setExamStatus(RealExam.State.LOGGED_IN);
 | 
	
		
			
				|  |  | +                    updateRealExam(re);
 | 
	
		
			
				|  |  | +                    return AjaxResult.success("成功");
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                re.setSeatId(s.getSeatId());
 | 
	
		
			
				|  |  | -                re.setExamStatus(RealExam.State.LOGGED_IN);
 | 
	
		
			
				|  |  | -                updateRealExam(re);
 | 
	
		
			
				|  |  | -                return AjaxResult.success("成功");
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return AjaxResult.success("考试数据错误");
 | 
	
		
			
				|  |  | +        return AjaxResult.success("没有学生考试数据");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 |