wangliang 1 жил өмнө
parent
commit
724ac5269b

+ 14 - 1
themis-admin/src/main/java/com/qmth/themis/admin/api/TEExamController.java

@@ -95,6 +95,9 @@ public class TEExamController {
     @Resource
     CommonService commonService;
 
+    @Resource
+    TEExamSummaryService teExamSummaryService;
+
     @ApiOperation(value = "考试批次修改/新增接口")
     @RequestMapping(value = "/save", method = RequestMethod.POST)
     @Transactional
@@ -464,7 +467,8 @@ public class TEExamController {
     @RequestMapping(value = "/prop/count", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "考试属性信息", response = ExamPropCountDto.class)})
     public Result propCount(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-                            @ApiParam(value = "考试场次id") @RequestParam(required = false) Long examActivityId) {
+                            @ApiParam(value = "考试场次id") @RequestParam(required = false) Long examActivityId,
+                            @ApiParam(value = "是否刷新") @RequestParam(required = false) boolean freshen) {
         if (Objects.isNull(examId) || Objects.equals(examId, "")) {
             throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
         }
@@ -495,11 +499,20 @@ public class TEExamController {
         List<TEExamSummary> teExamSummaryAllList = new ArrayList<>();
         if (Objects.nonNull(examId) && Objects.nonNull(examActivityId) && !CollectionUtils.isEmpty(roomCodeSet)) {
             for (String s : roomCodeSet) {
+                if (freshen) {
+                    teExamSummaryService.examSummary(examId, examActivityId, Objects.nonNull(s) ? new HashSet<>(Arrays.asList(s)) : null);
+                }
                 teExamSummaryAllList.addAll(themisCacheService.addExamSummaryCache(examId, examActivityId, s));
             }
         } else if (Objects.nonNull(examId) && Objects.nonNull(examActivityId)) {
+            if (freshen) {
+                teExamSummaryService.examSummary(examId, examActivityId, null);
+            }
             teExamSummaryAllList.addAll(themisCacheService.addExamSummaryCache(examId, examActivityId));
         } else {
+            if (freshen) {
+                teExamSummaryService.examSummary(examId, null, null);
+            }
             teExamSummaryAllList.addAll(themisCacheService.addExamSummaryCache(examId));
         }
         ExamPropCountDto examPropCountDto = new ExamPropCountDto(examId, 0, 0, 0, 0, 0, new BigDecimal(0));

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/constant/SystemConstant.java

@@ -209,7 +209,7 @@ public class SystemConstant {
     public static final Long AFTER_AUDIO_ATTACHMENT_ID = 2L;
     public static final Integer BEFORE_AUDIO_SECOND = 60;
     public static final Integer AFTER_AUDIO_SECOND = 900;
-    public static final long FINISH_DELAY_TIME = 1000 * 60 * 5;
+    public static final long FINISH_DELAY_TIME = 1000 * 60 * 1;
     //    public static final String AUTH_INFO_CACHE = "auth:info:cache";
     public static final String EXAM_AUDIO_CACHE = "exam:audio:cache";
     public static final String ATTACHMENT_CACHE = "attachment:cache";

+ 13 - 3
themis-business/src/main/java/com/qmth/themis/business/dao/TEExamStudentMapper.java

@@ -76,8 +76,8 @@ public interface TEExamStudentMapper extends CustomBaseMapper<TEExamStudent> {
                                                                @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity, @Param("activityIds") List<Long> activityIds);
 
     public List<ExamDeficiencyListBean> getExamDeficiencyPageExport(@Param("examId") Long examId,
-                                                                     @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
-                                                                     @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity, @Param("activityIds") List<Long> activityIds);
+                                                                    @Param("activityId") Long activityId, @Param("roomCode") String roomCode,
+                                                                    @Param("courseCode") String courseCode, @Param("name") String name, @Param("identity") String identity, @Param("activityIds") List<Long> activityIds);
 
 
     public IPage<ExamStudentLogListBean> getPageForStudentLog(IPage<ExamStudentLogListBean> iPage, @Param("orgId") Long orgId, @Param("examId") Long examId,
@@ -89,7 +89,7 @@ public interface TEExamStudentMapper extends CustomBaseMapper<TEExamStudent> {
 
     public void updateCurrentRecordId(@Param("examStudentId") Long examStudentId, @Param("currentRecordId") Long currentRecordId);
 
-    public void updateAlreadyExamCountAndCurrentRecordId(@Param("examStudentId") Long examStudentId,@Param("alreadyExamCount") Integer alreadyExamCount, @Param("currentRecordId") Long currentRecordId);
+    public void updateAlreadyExamCountAndCurrentRecordId(@Param("examStudentId") Long examStudentId, @Param("alreadyExamCount") Integer alreadyExamCount, @Param("currentRecordId") Long currentRecordId);
 
     /**
      * 查询学生成绩信息
@@ -140,4 +140,14 @@ public interface TEExamStudentMapper extends CustomBaseMapper<TEExamStudent> {
      * @return
      */
     public List<TEExamStudent> findAlreadyExamCountZero(@Param("examId") Long examId, @Param("examActivityId") Long examActivityId, @Param("id") Long id, @Param("examRecordId") Long examRecordId);
+
+    /**
+     * 获取缺考考生
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @return
+     */
+    public Integer getAbsentCount(@Param("examId") Long examId, @Param("examActivityId") Long examActivityId, @Param("roomCode") String roomCode);
 }

+ 10 - 0
themis-business/src/main/java/com/qmth/themis/business/service/TEExamStudentService.java

@@ -121,4 +121,14 @@ public interface TEExamStudentService extends IService<TEExamStudent> {
      * @return
      */
     public List<TEExamStudent> findAlreadyExamCountZero(Long examId, Long examActivityId, Long id, Long examRecordId);
+
+    /**
+     * 获取缺考考生
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @return
+     */
+    public Integer getAbsentCount(Long examId, Long examActivityId, String roomCode);
 }

+ 5 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -50,6 +50,7 @@ import java.math.BigDecimal;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 /**
  * @Description: 考试批次 服务实现类
@@ -156,6 +157,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         if (Objects.isNull(examId)) {
             Map<String, Set<Long>> examList = themisCacheService.getOrgExamListCache(orgId.toString());
             if (!CollectionUtils.isEmpty(examList)) {
+                examList = examList.entrySet().stream()
+                        .sorted(Map.Entry.comparingByKey())
+                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
                 for (Map.Entry<String, Set<Long>> entry : examList.entrySet()) {
                     List<TEExamActivityWaitDto> teExamActivityWaitList = teExamActivityService.getWaitingExam(studentId, entry.getValue(), null);
                     list = this.waitingExamCommon(list, teExamActivityWaitList);
@@ -164,6 +168,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         } else {
             Set<Long> examActivityIdSet = themisCacheService.getOrgExamListCache(orgId.toString(), examId.toString());
             if (!CollectionUtils.isEmpty(examActivityIdSet)) {
+                examActivityIdSet = examActivityIdSet.stream().sorted().collect(Collectors.toCollection(LinkedHashSet::new));
                 List<TEExamActivityWaitDto> teExamActivityWaitList = teExamActivityService.getWaitingExam(studentId, examActivityIdSet, null);
                 list = this.waitingExamCommon(list, teExamActivityWaitList);
             }

+ 13 - 0
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamStudentServiceImpl.java

@@ -233,4 +233,17 @@ public class TEExamStudentServiceImpl extends ServiceImpl<TEExamStudentMapper, T
     public List<TEExamStudent> findAlreadyExamCountZero(Long examId, Long examActivityId, Long id, Long examRecordId) {
         return teExamStudentMapper.findAlreadyExamCountZero(examId, examActivityId, id, examRecordId);
     }
+
+    /**
+     * 获取缺考考生
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @return
+     */
+    @Override
+    public Integer getAbsentCount(Long examId, Long examActivityId, String roomCode) {
+        return this.baseMapper.getAbsentCount(examId, examActivityId, roomCode);
+    }
 }

+ 13 - 18
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamSummaryServiceImpl.java

@@ -1,6 +1,5 @@
 package com.qmth.themis.business.service.impl;
 
-import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
@@ -8,6 +7,7 @@ import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TEExamSummaryMapper;
 import com.qmth.themis.business.entity.TEExamSummary;
 import com.qmth.themis.business.service.TEExamActivityService;
+import com.qmth.themis.business.service.TEExamStudentService;
 import com.qmth.themis.business.service.TEExamSummaryService;
 import com.qmth.themis.business.service.ThemisCacheService;
 import com.qmth.themis.business.util.UidUtil;
@@ -18,7 +18,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
-import java.util.Date;
 import java.util.Objects;
 import java.util.Set;
 
@@ -40,6 +39,9 @@ public class TEExamSummaryServiceImpl extends ServiceImpl<TEExamSummaryMapper, T
     @Resource
     ThemisCacheService themisCacheService;
 
+    @Resource
+    TEExamStudentService teExamStudentService;
+
     /**
      * 统计考试信息
      *
@@ -72,26 +74,19 @@ public class TEExamSummaryServiceImpl extends ServiceImpl<TEExamSummaryMapper, T
             teExamSummary.setExamActivityId(examActivityId);
             teExamSummary.setRoomCode(s);
             ExamActivityCacheBean ac = teExamActivityService.getExamActivityCacheBean(examActivityId);
-            //换算开始时间、侯考时间、结束时间
-            Long startTime = ac.getStartTime() - (ac.getPrepareSeconds() * 1000);
-            Integer openingSecondsTemp = ac.getOpeningSeconds();
-            openingSecondsTemp = Objects.nonNull(openingSecondsTemp) && openingSecondsTemp.intValue() == 0 ? SystemConstant.DEFAULT_OPENING_SECONDS : openingSecondsTemp;
-            Long finalPrepareTime = ac.getStartTime() + (openingSecondsTemp * 1000);
+//            //换算开始时间、侯考时间、结束时间
+//            Long startTime = ac.getStartTime() - (ac.getPrepareSeconds() * 1000);
+//            Integer openingSecondsTemp = ac.getOpeningSeconds();
+//            openingSecondsTemp = Objects.nonNull(openingSecondsTemp) && openingSecondsTemp.intValue() == 0 ? SystemConstant.DEFAULT_OPENING_SECONDS : openingSecondsTemp;
+//            Long finalPrepareTime = ac.getStartTime() + (openingSecondsTemp * 1000);
             Long endTime = ac.getFinishTime() + SystemConstant.FINISH_DELAY_TIME;//交卷时间加5分钟,后台交卷可能未完成
             long timestamp = System.currentTimeMillis();
-            if (startTime <= timestamp || teExamSummary.getPrepareCount().intValue() > 0) {//侯考
-                teExamSummary.setAbsentCount(teExamSummary.getTotalCount() - teExamSummary.getPrepareCount());
-            }
-            log.info("examSummary examId:{},examActivityId:{},startTime:{},finalPrepareTime:{},endTime:{}", examId, ac.getId(), DateUtil.format(new Date(startTime), "yyyy-MM-dd HH:mm:ss"), DateUtil.format(new Date(finalPrepareTime), "yyyy-MM-dd HH:mm:ss"), DateUtil.format(new Date(endTime), "yyyy-MM-dd HH:mm:ss"));
-            //最后侯考时间已过且未结束考试,当前侯考数设为0
-            if (finalPrepareTime <= timestamp) {
-                teExamSummary.setPrepareCount(0);
-            }
-            //交卷
+//            //交卷
             if (endTime <= timestamp) {//当考试场次结束时间已过,缺考=全部应考-已完成考试
                 teExamSummary.setAbsentCount(teExamSummary.getTotalCount() - teExamSummary.getFinishCount());
-            } else {//否则缺考=全部应考-侯考数(0)-考试中-已完成考试
-                teExamSummary.setAbsentCount(teExamSummary.getTotalCount() - teExamSummary.getPrepareCount() - teExamSummary.getExamCount() - teExamSummary.getFinishCount());
+            } else {
+                Integer absentCount = teExamStudentService.getAbsentCount(examId, examActivityId, s);
+                teExamSummary.setAbsentCount(Objects.nonNull(absentCount) ? absentCount : 0);
             }
             TEExamSummary teExamSummaryDb = this.getOne(new QueryWrapper<TEExamSummary>().lambda()
                     .eq(TEExamSummary::getExamId, examId)

+ 41 - 0
themis-business/src/main/resources/mapper/TEExamStudentMapper.xml

@@ -480,4 +480,45 @@
             </if>
         </where>
     </select>
+
+    <select id="getAbsentCount" resultType="java.lang.Integer">
+        select sum(t.c) from(select
+        count(distinct t.id) as c
+        from
+        t_e_exam_student t
+        left join t_oe_exam_record toer on
+        toer.exam_student_id = t.id
+        <where> 1 = 1
+            <if test="examId != null and examId != ''">
+                and t.exam_id = #{examId}
+            </if>
+            <if test="examActivityId != null and examActivityId != ''">
+                and t.exam_activity_id = #{examActivityId}
+            </if>
+            <if test="roomCode != null and roomCode != ''">
+                and t.room_code = #{roomCode}
+            </if>
+            and toer.id is null
+        </where>
+        union all
+        select
+        count(distinct t.id) as c
+        from
+        t_e_exam_student t
+        left join t_oe_exam_record toer on
+        toer.exam_student_id = t.id
+        <where> 1 = 1
+            <if test="examId != null and examId != ''">
+                and t.exam_id = #{examId}
+            </if>
+            <if test="examActivityId != null and examActivityId != ''">
+                and t.exam_activity_id = #{examActivityId}
+            </if>
+            <if test="roomCode != null and roomCode != ''">
+                and t.room_code = #{roomCode}
+            </if>
+            and toer.status in ('FIRST_PREPARE', 'JUNK')
+            and toer.client_websocket_status = 'OFF_LINE' and t.already_exam_count = 0
+        </where>) t
+    </select>
 </mapper>

+ 3 - 3
themis-business/src/main/resources/mapper/TEExamSummaryMapper.xml

@@ -5,7 +5,7 @@
     <select id="examSummary" resultType="com.qmth.themis.business.entity.TEExamSummary">
         select
             count(1) as totalCount,
-            sum(case when t.status = 'FIRST_PREPARE' then 1 else 0 end) as prepareCount,
+            sum(case when t.status = 'FIRST_PREPARE' and t.client_websocket_status = 'ON_LINE' then 1 else 0 end) as prepareCount,
             sum(case when t.client_websocket_status = 'ON_LINE' then 1 else 0 end) as onlineCount,
             sum(case when t.client_websocket_status = 'OFF_LINE' or t.client_websocket_status is null then 1 else 0 end) as offlineCount,
             sum(case when t.camera_monitor_status = 'STOP' or t.screen_monitor_status = 'STOP' or t.mobile_first_monitor_status = 'STOP' or t.mobile_second_monitor_status = 'STOP' then 1 else 0 end) as monitorStopCount,
@@ -14,9 +14,9 @@
             sum(t.warning_unread) as warningUnread,
             sum(t.warning_multiple_face_count) as warningMultipleFaceCount,
             sum(t.exception_count) as exceptionCount,
-            sum(case when (t.status = 'FINISHED' or t.status = 'PERSISTED') then 1 else 0 end) as finishCount
+            sum(case when (t.status = 'FINISHED' or t.status = 'PERSISTED' or s.already_exam_count > 0) then 1 else 0 end) as finishCount
         from t_e_exam_student s
-            left join t_oe_exam_record t on t.id=s.current_record_id
+            left join t_oe_exam_record t on t.id = s.current_record_id
         <where> 1 = 1
             <if test="examId != null and examId != ''">
                 and s.exam_id = #{examId}

+ 2 - 2
themis-business/src/main/resources/mapper/TOeExamRecordMapper.xml

@@ -127,7 +127,7 @@
             and toer.paper_download = #{paperDownload}
         </if>
         <if test="status == null or status == ''">
-            and toer.status in ('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
+            and ((toer.status = 'FIRST_PREPARE' and toer.client_websocket_status = 'ON_LINE') or toer.status in ('ANSWERING', 'BREAK_OFF', 'RESUME_PREPARE'))
         </if>
         <if test="cameraMonitorStatus != null and cameraMonitorStatus != ''">
             and toer.camera_monitor_status = upper(#{cameraMonitorStatus})
@@ -158,7 +158,7 @@
             <if test="orgId != null and orgId != ''">
                 and tee.org_id = #{orgId}
             </if>
-            and t.status in('FIRST_PREPARE','ANSWERING','BREAK_OFF','RESUME_PREPARE')
+            and ((toer.status = 'FIRST_PREPARE' and toer.client_websocket_status = 'ON_LINE') or toer.status in ('ANSWERING', 'BREAK_OFF', 'RESUME_PREPARE'))
         </where>
         ORDER BY RAND() LIMIT #{randomNum}
     </select>