浏览代码

Merge branch 'dev'
123

wangliang 4 年之前
父节点
当前提交
7751ea98f7

+ 38 - 0
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java

@@ -19,6 +19,7 @@ import com.qmth.themis.business.dto.ExamPropCountDto;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.entity.*;
 import com.qmth.themis.business.enums.*;
+import com.qmth.themis.business.excel.ExportUtils;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.JacksonUtil;
 import com.qmth.themis.business.util.RedisUtil;
@@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicReference;
@@ -149,6 +151,20 @@ public class TIeInvigilateController {
         return ResultUtil.ok(basePage);
     }
 
+    @ApiOperation(value = "实时监控台视频随机列表接口")
+    @RequestMapping(value = "/list/video/random", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "监考监控信息", response = InvigilateListVideoBean.class)})
+    public Result listVideoRandom(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId, @ApiParam(value = "随机数", required = true) @RequestParam Integer randomNum) {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
+        Long userId = null;
+        if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
+            userId = tbUser.getId();
+        }
+        return ResultUtil.ok(tOeExamRecordService.invigilatePageListVideoRandom(examId, userId, randomNum));
+    }
+
     @ApiOperation(value = "监考明细管理列表接口")
     @RequestMapping(value = "/history/list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "监考明细信息", response = InvigilateListHistoryBean.class)})
@@ -324,6 +340,28 @@ public class TIeInvigilateController {
         return ResultUtil.ok(basePage);
     }
 
+    @ApiOperation(value = "进度查询列表导出接口")
+    @RequestMapping(value = "/progress/list/export", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "监考进度信息", response = InvigilateListProgressBean.class)})
+    public Result progressListExport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId,
+                                     @ApiParam(value = "考试场次id", required = false) @RequestParam(required = false) Long examActivityId,
+                                     @ApiParam(value = "虚拟考场代码", required = false) @RequestParam(required = false) String roomCode,
+                                     @ApiParam(value = "科目代码", required = false) @RequestParam(required = false) String courseCode,
+                                     @ApiParam(value = "姓名", required = false) @RequestParam(required = false) String name,
+                                     @ApiParam(value = "证件号", required = false) @RequestParam(required = false) String identity,
+                                     HttpServletResponse response) throws Exception {
+        TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
+        AuthDto authDto = (AuthDto) redisUtil.get(SystemConstant.userOauth + "::" + tbUser.getId());
+        //如果有监考员角色,只能查看自己所监考的考场,巡考员和管理员则可以查看全部考场
+        Long userId = null;
+        if (authDto.getRoleCodes().toString().contains(RoleEnum.INVIGILATE.name())) {
+            userId = tbUser.getId();
+        }
+        List<InvigilateListProgressBean> invigilateListProgressBeanList = tOeExamRecordService.invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId);
+        ExportUtils.exportEXCEL("进度信息", InvigilateListProgressBean.class, invigilateListProgressBeanList, response);
+        return ResultUtil.ok(Collections.singletonMap("success", true));
+    }
+
     @ApiOperation(value = "违纪处理接口")
     @RequestMapping(value = "/breach", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "{\"success\":true}", response = Result.class)})

+ 62 - 40
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java

@@ -1,24 +1,16 @@
 package com.qmth.themis.business.dao;
 
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.qmth.themis.business.bean.backend.ExaminationMonitorHourWarnCountBean;
-import com.qmth.themis.business.bean.backend.InvigilateListBean;
-import com.qmth.themis.business.bean.backend.InvigilateListHistoryBean;
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolBean;
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean;
-import com.qmth.themis.business.bean.backend.InvigilateListProgressBean;
-import com.qmth.themis.business.bean.backend.InvigilateListVideoBean;
-import com.qmth.themis.business.bean.backend.InvigilateListWarningBean;
+import com.qmth.themis.business.bean.backend.*;
 import com.qmth.themis.business.dto.response.TEExamUnFinishDto;
 import com.qmth.themis.business.entity.TOeExamRecord;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
 /**
  * @Description: 考试记录 Mapper 接口
@@ -111,6 +103,16 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
                                                                   @Param("monitorStatusSource") String monitorStatusSource,
                                                                   @Param("userId") Long userId);
 
+    /**
+     * 实时监控台视频随机列表
+     *
+     * @param examId
+     * @param userId
+     * @param randomNum
+     * @return
+     */
+    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(@Param("examId") Long examId, @Param("userId") Long userId, @Param("randomNum") Integer randomNum);
+
     /**
      * 查询在线巡考列表
      *
@@ -206,6 +208,26 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
                                                                         @Param("identity") String identity,
                                                                         @Param("userId") Long userId);
 
+    /**
+     * 进度查询列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param name
+     * @param identity
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListProgressBean> invigilatePageProgressListExport(@Param("examId") Long examId,
+                                                                         @Param("examActivityId") Long examActivityId,
+                                                                         @Param("roomCode") String roomCode,
+                                                                         @Param("courseCode") String courseCode,
+                                                                         @Param("name") String name,
+                                                                         @Param("identity") String identity,
+                                                                         @Param("userId") Long userId);
+
     /**
      * 监考明细管理列表
      *
@@ -248,20 +270,20 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
                                                                       @Param("clientWebsocketStatus") String clientWebsocketStatus,
                                                                       @Param("monitorStatusSource") String monitorStatusSource,
                                                                       @Param("userId") Long userId);
-    
-	public List<Map<String,Object>> getDoneCount(@Param("examId") Long examId, @Param("activityId") Long activityId,
-			@Param("roomCode") String roomCode,@Param("courseCode")  String courseCode);
-	
-	public List<Map<String,Object>> getDoneCountByDay(@Param("examId") Long examId, @Param("activityId") Long activityId,
-			@Param("roomCode") String roomCode,@Param("courseCode")  String courseCode);
 
-	public Long getCountByExamId(@Param("examId") Long examId);
-	
-	public List<TOeExamRecord> getListByExamIdAndStartId(@Param("examId")Long examId,@Param("startId") Long startId);
+    public List<Map<String, Object>> getDoneCount(@Param("examId") Long examId, @Param("activityId") Long activityId,
+                                                  @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+
+    public List<Map<String, Object>> getDoneCountByDay(@Param("examId") Long examId, @Param("activityId") Long activityId,
+                                                       @Param("roomCode") String roomCode, @Param("courseCode") String courseCode);
+
+    public Long getCountByExamId(@Param("examId") Long examId);
 
-	public void updateObjectiveScore(@Param("recordId") Long recordId,@Param("score") Double score);
+    public List<TOeExamRecord> getListByExamIdAndStartId(@Param("examId") Long examId, @Param("startId") Long startId);
 
-	public TOeExamRecord findOneByPaperId(@Param("paperId")Long paperId);
+    public void updateObjectiveScore(@Param("recordId") Long recordId, @Param("score") Double score);
+
+    public TOeExamRecord findOneByPaperId(@Param("paperId") Long paperId);
 
     /**
      * 在线巡考报表接口
@@ -281,19 +303,19 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
      */
     public List<InvigilateListPatrolReportBean> examInvigilateReport(@Param("examId") Long examId, @Param("userId") Long userId);
 
-	public TOeExamRecord findOneByExamId(@Param("examId")Long examId);
+    public TOeExamRecord findOneByExamId(@Param("examId") Long examId);
+
+    public Long getExamingCount();
+
+    public Long getExceptionCount();
+
+    public Long getWarnCount();
+
+    public List<Map<String, Object>> getOrgExamingCount();
+
+    public List<Map<String, Object>> getOrgDistribution();
+
+    public List<Map<String, Object>> getTypeDistribution();
 
-	public Long getExamingCount();
-	
-	public Long getExceptionCount();
-	
-	public Long getWarnCount();
-	
-	public List<Map<String,Object>> getOrgExamingCount();
-	
-	public List<Map<String,Object>> getOrgDistribution();
-	
-	public List<Map<String,Object>> getTypeDistribution();
-	
-	public List<ExaminationMonitorHourWarnCountBean> getWarnTrend(@Param("startTime")Date startTime);
+    public List<ExaminationMonitorHourWarnCountBean> getWarnTrend(@Param("startTime") Date startTime);
 }

+ 57 - 28
themis-business/src/main/java/com/qmth/themis/business/service/TOeExamRecordService.java

@@ -1,21 +1,16 @@
 package com.qmth.themis.business.service;
 
-import java.util.List;
-import java.util.Map;
-
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.qmth.themis.business.bean.backend.InvigilateListBean;
-import com.qmth.themis.business.bean.backend.InvigilateListHistoryBean;
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolBean;
-import com.qmth.themis.business.bean.backend.InvigilateListProgressBean;
-import com.qmth.themis.business.bean.backend.InvigilateListVideoBean;
-import com.qmth.themis.business.bean.backend.InvigilateListWarningBean;
+import com.qmth.themis.business.bean.backend.*;
 import com.qmth.themis.business.entity.TOeExamRecord;
 import com.qmth.themis.business.enums.ExamTypeEnum;
 import com.qmth.themis.business.enums.LivenessTypeEnum;
 import com.qmth.themis.business.enums.VerifyExceptionEnum;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * @Description: 考试记录 服务类
  * @Param:
@@ -131,7 +126,7 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
                                                         Long userId);
 
     /**
-     * 查询实时监控台列表
+     * 查询实时监控台视频列表
      *
      * @param iPage
      * @param examId
@@ -161,6 +156,16 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
                                                                   String monitorStatusSource,
                                                                   Long userId);
 
+    /**
+     * 实时监控台视频随机列表
+     *
+     * @param examId
+     * @param userId
+     * @param randomNum
+     * @return
+     */
+    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(Long examId, Long userId, Integer randomNum);
+
     /**
      * 查询在线巡考列表
      *
@@ -256,6 +261,26 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
                                                                         String identity,
                                                                         Long userId);
 
+    /**
+     * 进度查询列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param name
+     * @param identity
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListProgressBean> invigilatePageProgressListExport(Long examId,
+                                                                        Long examActivityId,
+                                                                        String roomCode,
+                                                                        String courseCode,
+                                                                        String name,
+                                                                        String identity,
+                                                                        Long userId);
+
     /**
      * 监考明细管理列表
      *
@@ -300,25 +325,29 @@ public interface TOeExamRecordService extends IService<TOeExamRecord> {
                                                                       Long userId);
 
 
-	/**
-	 * 重新算分
-	 */
-	void calculateScore(Long recordId);
+    /**
+     * 重新算分
+     */
+    void calculateScore(Long recordId);
+
+    /**
+     * 获取考试记录数
+     *
+     * @param examId
+     * @return
+     */
+    Long getCountByExamId(Long examId);
 
-	/**获取考试记录数
-	 * @param examId
-	 * @return
-	 */
-	Long getCountByExamId(Long examId);
+    /**
+     * 批量获取考试记录
+     *
+     * @param examId
+     * @param startId
+     * @return
+     */
+    List<TOeExamRecord> getListByExamIdAndStartId(Long examId, Long startId);
 
-	/**批量获取考试记录
-	 * @param examId
-	 * @param startId
-	 * @return
-	 */
-	List<TOeExamRecord> getListByExamIdAndStartId(Long examId, Long startId);
-	
-	TOeExamRecord findOneByPaperId(Long paperId);
+    TOeExamRecord findOneByPaperId(Long paperId);
 
-	TOeExamRecord findOneByExamId(Long examId);
+    TOeExamRecord findOneByExamId(Long examId);
 }

+ 101 - 97
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -1,69 +1,39 @@
 package com.qmth.themis.business.service.impl;
 
-import java.io.File;
-import java.math.BigDecimal;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-
-import javax.annotation.Resource;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
 import com.alibaba.fastjson.JSONArray;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.qmth.themis.business.bean.backend.InvigilateListBean;
-import com.qmth.themis.business.bean.backend.InvigilateListHistoryBean;
-import com.qmth.themis.business.bean.backend.InvigilateListPatrolBean;
-import com.qmth.themis.business.bean.backend.InvigilateListProgressBean;
-import com.qmth.themis.business.bean.backend.InvigilateListVideoBean;
-import com.qmth.themis.business.bean.backend.InvigilateListWarningBean;
+import com.qmth.themis.business.bean.backend.*;
 import com.qmth.themis.business.cache.ExamRecordCacheUtil;
 import com.qmth.themis.business.cache.RedisKeyHelper;
-import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
-import com.qmth.themis.business.cache.bean.ExamCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentAnswerCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentCacheBean;
-import com.qmth.themis.business.cache.bean.ExamStudentPaperStructCacheBean;
-import com.qmth.themis.business.cache.bean.ObjectiveAnswerCacheBean;
+import com.qmth.themis.business.cache.bean.*;
 import com.qmth.themis.business.config.SystemConfig;
 import com.qmth.themis.business.constant.SpringContextHolder;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TOeExamRecordMapper;
 import com.qmth.themis.business.dto.MqDto;
 import com.qmth.themis.business.dto.response.TEExamUnFinishDto;
-import com.qmth.themis.business.entity.TEExamStudent;
 import com.qmth.themis.business.entity.TOeExamAnswer;
 import com.qmth.themis.business.entity.TOeExamRecord;
-import com.qmth.themis.business.enums.ExamRecordStatusEnum;
-import com.qmth.themis.business.enums.ExamTypeEnum;
-import com.qmth.themis.business.enums.LivenessTypeEnum;
-import com.qmth.themis.business.enums.MqTagEnum;
-import com.qmth.themis.business.enums.MqTopicEnum;
-import com.qmth.themis.business.enums.ObjectiveScorePolicyEnum;
-import com.qmth.themis.business.enums.VerifyExceptionEnum;
-import com.qmth.themis.business.service.MqDtoService;
-import com.qmth.themis.business.service.TEExamActivityService;
-import com.qmth.themis.business.service.TEExamPaperService;
-import com.qmth.themis.business.service.TEExamService;
-import com.qmth.themis.business.service.TEExamStudentService;
-import com.qmth.themis.business.service.TOeExamAnswerService;
-import com.qmth.themis.business.service.TOeExamRecordService;
+import com.qmth.themis.business.enums.*;
+import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.util.FileUtil;
 import com.qmth.themis.common.util.SimpleBeanUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.math.BigDecimal;
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 /**
  * @Description: 考试记录 服务实现类
@@ -98,7 +68,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
 
     @Resource
     TEExamStudentService examStudentService;
-    
+
     @Resource
     TEExamActivityService examActivityService;
 
@@ -155,8 +125,8 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     @Override
     public Long saveByPrepare(Long examId, Long examActivityId, Long examStudentId, Long paperId,
                               Integer serialNumber) {
-    	ExamActivityCacheBean ac=examActivityService.getExamActivityCacheBean(examActivityId);
-    	ExamCacheBean exam=examService.getExamCacheBean(examId);
+        ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(examActivityId);
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
         TOeExamRecord er = new TOeExamRecord();
         er.setId(Constants.idGen.next());
         er.setExamId(examId);
@@ -361,11 +331,11 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
 //            examStudentService.saveOrUpdate(examStudent);
             //上传个人试卷结构
             ExamStudentPaperStructCacheBean struct = (ExamStudentPaperStructCacheBean) redisUtil.get(RedisKeyHelper.studentPaperStructKey(recordId));
-            if(struct!=null) {
-	            File structFile = new File(dir + "struct.json");
-	            FileUtil.saveAsFile(structFile.getAbsolutePath(), struct.getContent());
-	            SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
-	            OssUtil.ossUpload(systemConfig.getOssEnv(3), structFilePath, structFile);
+            if (struct != null) {
+                File structFile = new File(dir + "struct.json");
+                FileUtil.saveAsFile(structFile.getAbsolutePath(), struct.getContent());
+                SystemConfig systemConfig = SpringContextHolder.getBean(SystemConfig.class);
+                OssUtil.ossUpload(systemConfig.getOssEnv(3), structFilePath, structFile);
             }
         } finally {
             FileUtil.deleteFolder(dir);
@@ -515,6 +485,19 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         return tOeExamRecordMapper.invigilatePageListVideo(iPage, examId, examActivityId, roomCode, paperDownload, status, name, identity, minWarningCount, maxWarningCount, clientWebsocketStatus, monitorStatusSource, userId);
     }
 
+    /**
+     * 实时监控台视频随机列表
+     *
+     * @param examId
+     * @param userId
+     * @param randomNum
+     * @return
+     */
+    @Override
+    public List<InvigilateListVideoBean> invigilatePageListVideoRandom(Long examId, Long userId, Integer randomNum) {
+        return tOeExamRecordMapper.invigilatePageListVideoRandom(examId, userId, randomNum);
+    }
+
     /**
      * 查询在线巡考列表
      *
@@ -585,6 +568,23 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         return tOeExamRecordMapper.invigilatePageProgressList(iPage, examId, examActivityId, roomCode, courseCode, name, identity, userId);
     }
 
+    /**
+     * 进度查询列表导出
+     *
+     * @param examId
+     * @param examActivityId
+     * @param roomCode
+     * @param courseCode
+     * @param name
+     * @param identity
+     * @param userId
+     * @return
+     */
+    @Override
+    public List<InvigilateListProgressBean> invigilatePageProgressListExport(Long examId, Long examActivityId, String roomCode, String courseCode, String name, String identity, Long userId) {
+        return tOeExamRecordMapper.invigilatePageProgressListExport(examId, examActivityId, roomCode, courseCode, name, identity, userId);
+    }
+
     /**
      * 监考明细管理列表
      *
@@ -613,49 +613,49 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
     public IPage<InvigilateListHistoryBean> invigilatePageListHistory(IPage<Map> iPage, Long examId, Long examActivityId, String roomCode, String courseCode, String status, Integer breachStatus, String finishType, String name, String identity, Integer minMultipleFaceCount, Integer maxMultipleFaceCount, Integer minExceptionCount, Integer maxExceptionCount, Integer minWarningCount, Integer maxWarningCount, String clientWebsocketStatus, String monitorStatusSource, Long userId) {
         return tOeExamRecordMapper.invigilatePageListHistory(iPage, examId, examActivityId, roomCode, courseCode, status, breachStatus, finishType, name, identity, minMultipleFaceCount, maxMultipleFaceCount, minExceptionCount, maxExceptionCount, minWarningCount, maxWarningCount, clientWebsocketStatus, monitorStatusSource, userId);
     }
-    
+
     /**
      * 重新算分
      */
     @Transactional
     @Override
     public void calculateScore(Long recordId) {
-    	
-    	TOeExamRecord rec=this.getById(recordId);
-    	
+
+        TOeExamRecord rec = this.getById(recordId);
+
         Map<String, ObjectiveAnswerCacheBean> map = examPaperService.getObjectiveAnswerCacheBean(rec.getPaperId());
         if (map == null || map.size() == 0) {
-            log.debug("no ObjectiveAnswerCacheBean for calculateObjectiveScore recordId:"+recordId);
+            log.debug("no ObjectiveAnswerCacheBean for calculateObjectiveScore recordId:" + recordId);
             return;
         }
         QueryWrapper<TOeExamAnswer> wp = new QueryWrapper<>();
-		wp.lambda().eq(TOeExamAnswer::getExamRecordId, recordId);
-		List<TOeExamAnswer> answers=examAnswerService.list(wp);
-		if(answers==null||answers.size()==0) {
-			log.debug("no ObjectiveAnswer for calculateObjectiveScore recordId:"+recordId);
-			return;
-		}
-		BigDecimal tatolscore = new BigDecimal(0.0);
-		for(TOeExamAnswer answer:answers) {
-			Double score=calculateScoreForQuestion(answer, map);
-			if(score!=null) {
-				tatolscore=tatolscore.add(new BigDecimal(score));
-			}
-		}
+        wp.lambda().eq(TOeExamAnswer::getExamRecordId, recordId);
+        List<TOeExamAnswer> answers = examAnswerService.list(wp);
+        if (answers == null || answers.size() == 0) {
+            log.debug("no ObjectiveAnswer for calculateObjectiveScore recordId:" + recordId);
+            return;
+        }
+        BigDecimal tatolscore = new BigDecimal(0.0);
+        for (TOeExamAnswer answer : answers) {
+            Double score = calculateScoreForQuestion(answer, map);
+            if (score != null) {
+                tatolscore = tatolscore.add(new BigDecimal(score));
+            }
+        }
 
         // 设置客观分总分
-		tOeExamRecordMapper.updateObjectiveScore(recordId, tatolscore.doubleValue());
+        tOeExamRecordMapper.updateObjectiveScore(recordId, tatolscore.doubleValue());
     }
-    
-    private Double calculateScoreForQuestion(TOeExamAnswer answer,Map<String, ObjectiveAnswerCacheBean> map) {
-    	Long recordId=answer.getExamRecordId();
-    	Integer mainNumber=answer.getMainNumber();
-    	Integer subNumber=answer.getSubNumber();
-    	Integer subIndex=answer.getSubIndex();
-    	String key = RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex);
+
+    private Double calculateScoreForQuestion(TOeExamAnswer answer, Map<String, ObjectiveAnswerCacheBean> map) {
+        Long recordId = answer.getExamRecordId();
+        Integer mainNumber = answer.getMainNumber();
+        Integer subNumber = answer.getSubNumber();
+        Integer subIndex = answer.getSubIndex();
+        String key = RedisKeyHelper.examAnswerHashKey(mainNumber, subNumber, subIndex);
         ObjectiveAnswerCacheBean cb = map.get(key);
         if (cb == null) {
-        	log.debug("not a objective question  recordId:"+answer.getExamRecordId()+" key:"+key);
+            log.debug("not a objective question  recordId:" + answer.getExamRecordId() + " key:" + key);
             return null;
         }
 
@@ -696,36 +696,40 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
         }
 
         examAnswerService.saveOrUpdate(answer);
-        
+
         return answer.getScore();
     }
-    
-    /**获取考试记录数
+
+    /**
+     * 获取考试记录数
+     *
      * @param examId
      * @return
      */
     @Override
     public Long getCountByExamId(Long examId) {
-    	return tOeExamRecordMapper.getCountByExamId(examId);
+        return tOeExamRecordMapper.getCountByExamId(examId);
     }
-    
-    /**批量获取考试记录
+
+    /**
+     * 批量获取考试记录
+     *
      * @param examId
      * @param startId
      * @return
      */
     @Override
-    public List<TOeExamRecord> getListByExamIdAndStartId(Long examId,Long startId) {
-    	return tOeExamRecordMapper.getListByExamIdAndStartId(examId, startId);
+    public List<TOeExamRecord> getListByExamIdAndStartId(Long examId, Long startId) {
+        return tOeExamRecordMapper.getListByExamIdAndStartId(examId, startId);
+    }
+
+    @Override
+    public TOeExamRecord findOneByPaperId(Long paperId) {
+        return tOeExamRecordMapper.findOneByPaperId(paperId);
     }
 
-	@Override
-	public TOeExamRecord findOneByPaperId(Long paperId) {
-		return tOeExamRecordMapper.findOneByPaperId(paperId);
-	}
-	
-	@Override
-	public TOeExamRecord findOneByExamId(Long examId) {
-		return tOeExamRecordMapper.findOneByExamId(examId);
-	}
+    @Override
+    public TOeExamRecord findOneByExamId(Long examId) {
+        return tOeExamRecordMapper.findOneByExamId(examId);
+    }
 }

+ 5 - 0
themis-business/src/main/resources/db/init.sql

@@ -517,6 +517,8 @@ INSERT INTO `t_b_privilege` VALUES (150, '报表-在线巡考', '/api/admin/repo
 INSERT INTO `t_b_privilege` VALUES (151, '报表-考情监控-人数', '/api/admin/report/examination_monitor/count', 'LINK', 60, 36, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (152, '报表-考情监控-预警分布', '/api/admin/report/examination_monitor/warn_distribution', 'LINK', 60, 37, NULL, '2020-08-01 13:08:31');
 INSERT INTO `t_b_privilege` VALUES (153, '报表-考情监控-预警时间趋势', '/api/admin/report/examination_monitor/warn_trend', 'LINK', 60, 38, NULL, '2020-08-01 13:08:31');
+INSERT INTO `t_b_privilege` VALUES (154, '实时监控台视频随机列表', '/api/admin/invigilate/list/video/random', 'LINK', 60, 39, NULL, '2020-08-01 13:08:31');
+INSERT INTO `t_b_privilege` VALUES (155, '进度查询列表导出', '/api/admin/invigilate/progress/list/export', 'LINK', 60, 40, NULL, '2020-08-01 13:08:31');
 COMMIT;
 
 -- ----------------------------
@@ -740,6 +742,9 @@ INSERT INTO `t_b_role_privilege` VALUES (185, 'INSPECTION', 150);
 INSERT INTO `t_b_role_privilege` VALUES (186, 'INSPECTION', 151);
 INSERT INTO `t_b_role_privilege` VALUES (187, 'INSPECTION', 152);
 INSERT INTO `t_b_role_privilege` VALUES (188, 'INSPECTION', 153);
+INSERT INTO `t_b_role_privilege` VALUES (189, 'INVIGILATE', 154);
+INSERT INTO `t_b_role_privilege` VALUES (190, 'ADMIN', 155);
+INSERT INTO `t_b_role_privilege` VALUES (191, 'INVIGILATE', 155);
 COMMIT;
 
 -- ----------------------------

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

@@ -211,6 +211,18 @@
 		order by t.roomCode
 	</select>
 
+	<select id="invigilatePageListVideoRandom" resultType="com.qmth.themis.business.bean.backend.InvigilateListVideoBean">
+		<include refid="invigilatePageHead" />
+		,t.monitor_live_url as monitorLiveUrl
+		,(select count(1) from t_ie_invigilate_warn_info tiiwi where tiiwi.exam_record_id = t.id and tiiwi.approve_status = 0) as warningNew
+		,date_format(date_sub(date_add(teea.start_time, interval IFNULL(teea.max_duration_seconds, tee.max_duration_seconds) second), interval teea.max_duration_seconds / 60 - t.duration_seconds minute),'%H:%i:%s') as remainTime
+		<include refid="invigilatePageMiddle" />
+		<if test="examId != null and examId != ''">
+			and t.exam_id = #{examId}
+		</if>
+		ORDER BY RAND() LIMIT #{randomNum}
+	</select>
+
 	<select id="invigilatePagePatrolList" resultType="com.qmth.themis.business.bean.backend.InvigilateListPatrolBean">
 		select (@i := @i + 1) as seq,t.* from(<include refid="invigilatePageHead" />
 		,(select count(1) from t_ie_invigilate_exception_info tiiei where tiiei.exam_record_id = t.id) as exceptionCount
@@ -393,6 +405,60 @@
 		order by tees.room_code
 	</select>
 
+	<select id="invigilatePageProgressListExport" resultType="com.qmth.themis.business.bean.backend.InvigilateListProgressBean">
+		select
+		distinct tee.id as examId,
+		tee.name as examName,
+		teea.id as examActivityId,
+		teea.code as examActivityCode,
+		tees.room_code as roomCode,
+		tees.room_name as roomName,
+		tees.`identity`,
+		tees.name,
+		tees.course_code as courseCode,
+		tees.course_name as courseName,
+		(tee.exam_count - tees.already_exam_count) as leftExamCount,
+		if((select count(1) from t_oe_exam_record toer where toer.exam_student_id =
+		tees.id and (toer.status = 'FINISHED' or toer.status = 'PERSISTED') >
+		0),'已完成','未完成') as status
+		from
+		t_e_exam_student tees
+		left join t_e_exam tee on
+		tee.id = tees.exam_id
+		left join t_e_exam_activity teea on
+		teea.id = tees.exam_activity_id
+		inner join (select distinct tbeiu.room_code from t_b_exam_invigilate_user
+		tbeiu
+		<if test="userId != null and userId != ''">
+			where tbeiu.user_id = #{userId}
+		</if>
+		) t on t.room_code = tees.room_code
+		<where>
+			<if test="examId != null and examId != ''">
+				and tees.exam_id = #{examId}
+			</if>
+			<if test="examActivityId != null and examActivityId != ''">
+				and tees.exam_activity_id = #{examActivityId}
+			</if>
+			<if test="roomCode != null and roomCode != ''">
+				and tees.room_code = #{roomCode}
+			</if>
+			<if test="courseCode != null and courseCode != ''">
+				and tees.course_code like CONCAT('%', #{courseCode},'%')
+			</if>
+			<if test="name != null and name !=''">
+				and tees.name like CONCAT('%', #{name},'%')
+			</if>
+			<if test="identity != null and identity !=''">
+				and tees.identity like CONCAT('%', #{identity},'%')
+			</if>
+			and tee.enable = 1
+			and teea.enable = 1
+			and tees.enable = 1
+		</where>
+		order by tees.room_code
+	</select>
+
 	<select id="invigilatePageListHistory" resultType="com.qmth.themis.business.bean.backend.InvigilateListHistoryBean">
 		select (@i := @i + 1) as seq,t.* from(
 		<include refid="invigilatePageHead" />