wangliang 4 lat temu
rodzic
commit
211ffe8a7e

+ 5 - 5
themis-backend/src/main/java/com/qmth/themis/backend/api/SysController.java

@@ -229,11 +229,11 @@ public class SysController {
             tbOrgQueryWrapper.lambda().eq(TBOrg::getEnable, enable);
         }
         List<TBOrg> tbOrgList = tbOrgService.list(tbOrgQueryWrapper);
-        tbOrgList.forEach(s -> {
-            if (Objects.nonNull(s.getLogo()) && !Objects.equals(s.getLogo(), "")) {
-                s.setLogo(systemConfig.getProperty("aliyun.oss.url") + File.separator + s.getLogo());
-            }
-        });
+//        tbOrgList.forEach(s -> {
+//            if (Objects.nonNull(s.getLogo()) && !Objects.equals(s.getLogo(), "")) {
+//                s.setLogo(systemConfig.getProperty("aliyun.oss.url") + File.separator + s.getLogo());
+//            }
+//        });
         return ResultUtil.ok(tbOrgList);
     }
 

+ 3 - 3
themis-backend/src/main/java/com/qmth/themis/backend/api/TBOrgController.java

@@ -80,9 +80,9 @@ public class TBOrgController {
         } else {
             tbOrg.setUpdateId(tbUser.getId());
         }
-        if (Objects.nonNull(tbOrg.getLogo()) && !Objects.equals(tbOrg.getLogo(), "")) {
-            tbOrg.setLogo(tbOrg.getLogo().replaceAll(systemConfig.getProperty("aliyun.oss.url") + File.separator, ""));
-        }
+//        if (Objects.nonNull(tbOrg.getLogo()) && !Objects.equals(tbOrg.getLogo(), "")) {
+//            tbOrg.setLogo(tbOrg.getLogo().replaceAll(systemConfig.getProperty("aliyun.oss.url") + File.separator, ""));
+//        }
         redisUtil.setOrg(tbOrg.getId(), tbOrg);
         EhcacheUtil.put(SystemConstant.orgCodeCache, tbOrg.getCode(), tbOrg);
         tbOrgService.saveOrUpdate(tbOrg);

+ 11 - 8
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeInvigilateController.java

@@ -201,6 +201,9 @@ public class TIeInvigilateController {
         ExamCacheBean examCacheBean = teExamService.getExamCacheBean(examId);
         InvigilateListDetailBean invigilateListDetailBean = new InvigilateListDetailBean(examCacheBean.getName(), examActivityCacheBean.getCode(), examId, examActivityId, examStudentId, examRecordId, identity, examStudentName, courseNameCode, status, roomCode, roomName, breachStatus);
 
+        //考生轨迹
+
+
         //预警、异常、人脸
         //预警
         QueryWrapper<TIeInvigilateWarnInfo> tIeInvigilateWarnInfoQueryWrapper = new QueryWrapper<>();
@@ -215,7 +218,7 @@ public class TIeInvigilateController {
         Gson gson = new Gson();
         List<InvigilateListDetailBean.InvigilateWarnInfoBean> invigilateWarnInfoBeanList = gson.fromJson(gson.toJson(tIeInvigilateWarnInfoList), new TypeToken<List<InvigilateListDetailBean.InvigilateWarnInfoBean>>() {
         }.getType());
-        invigilateListDetailBean.setWarningInfos(invigilateWarnInfoBeanList);
+//        invigilateListDetailBean.setWarningInfos(invigilateWarnInfoBeanList);
 
         //异常
         QueryWrapper<TIeInvigilateExceptionInfo> tIeInvigilateExceptionInfoQueryWrapper = new QueryWrapper<>();
@@ -229,7 +232,7 @@ public class TIeInvigilateController {
 
         List<InvigilateListDetailBean.InvigilateExceptionInfoBean> invigilateExceptionInfoBeanList = gson.fromJson(gson.toJson(tIeInvigilateExceptionInfoList), new TypeToken<List<InvigilateListDetailBean.InvigilateExceptionInfoBean>>() {
         }.getType());
-        invigilateListDetailBean.setExceptionInfos(invigilateExceptionInfoBeanList);
+//        invigilateListDetailBean.setExceptionInfos(invigilateExceptionInfoBeanList);
 
         //陌生人脸
         tIeInvigilateWarnInfoQueryWrapper = new QueryWrapper<>();
@@ -240,12 +243,12 @@ public class TIeInvigilateController {
         invigilateListDetailBean.setMultipleFaceCount(multipleFaceCount);
 
         //考生轨迹
-        QueryWrapper<TEExamStudentLog> teExamStudentLogQueryWrapper = new QueryWrapper<>();
-        teExamStudentLogQueryWrapper.lambda().and(Wrapper -> Wrapper.eq(TEExamStudentLog::getExamRecordId, examRecordId).or().eq(TEExamStudentLog::getStudentId, studentId)).orderByAsc(TEExamStudentLog::getCreateTime);
-        List<TEExamStudentLog> teExamStudentLogList = teExamStudentLogService.list(teExamStudentLogQueryWrapper);
-        List<InvigilateListDetailBean.StudentLogBean> studentLogBeanList = gson.fromJson(gson.toJson(teExamStudentLogList), new TypeToken<List<InvigilateListDetailBean.StudentLogBean>>() {
-        }.getType());
-        invigilateListDetailBean.setStudentLogs(studentLogBeanList);
+//        QueryWrapper<TEExamStudentLog> teExamStudentLogQueryWrapper = new QueryWrapper<>();
+//        teExamStudentLogQueryWrapper.lambda().and(Wrapper -> Wrapper.eq(TEExamStudentLog::getExamRecordId, examRecordId).or().eq(TEExamStudentLog::getStudentId, studentId)).orderByAsc(TEExamStudentLog::getCreateTime);
+//        List<TEExamStudentLog> teExamStudentLogList = teExamStudentLogService.list(teExamStudentLogQueryWrapper);
+//        List<InvigilateListDetailBean.StudentLogBean> studentLogBeanList = gson.fromJson(gson.toJson(teExamStudentLogList), new TypeToken<List<InvigilateListDetailBean.StudentLogBean>>() {
+//        }.getType());
+//        invigilateListDetailBean.setStudentLogs(studentLogBeanList);
         return ResultUtil.ok(invigilateListDetailBean);
     }
 

+ 121 - 87
themis-backend/src/main/java/com/qmth/themis/backend/api/TIeReportController.java

@@ -1,24 +1,27 @@
 package com.qmth.themis.backend.api;
 
-import javax.annotation.Resource;
-
+import com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean;
+import com.qmth.themis.business.constant.SystemConstant;
+import com.qmth.themis.business.dto.AuthDto;
+import com.qmth.themis.business.entity.TBUser;
+import com.qmth.themis.business.enums.RoleEnum;
+import com.qmth.themis.business.service.TIeReportService;
+import com.qmth.themis.business.util.RedisUtil;
+import com.qmth.themis.business.util.ServletUtil;
+import com.qmth.themis.common.util.Result;
+import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
-import com.qmth.themis.business.service.TIeReportService;
-import com.qmth.themis.common.util.Result;
-import com.qmth.themis.common.util.ResultUtil;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
+import javax.annotation.Resource;
 
-/** 监考报表
- * @Description: 
+/**
+ * 监考报表
+ *
+ * @Description:
  * @Author: xiatian
  * @Date: 2020-08-28
  */
@@ -26,146 +29,177 @@ import io.swagger.annotations.ApiResponses;
 @RestController
 @RequestMapping("/${prefix.url.admin}/report")
 public class TIeReportController {
-    
+
     @Resource
     private TIeReportService reportService;
 
+    @Resource
+    RedisUtil redisUtil;
+
     @ApiOperation(value = "考试概览")
     @RequestMapping(value = "/exam_view", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examView(@ApiParam(value = "考试id", required = true) @RequestParam 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) {
+                           @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) {
         return ResultUtil.ok(reportService.examView(examId, examActivityId, roomCode, courseCode, name, identity));
     }
-    
+
     @ApiOperation(value = "情况统计")
     @RequestMapping(value = "/exam_view_count", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examViewCount(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examViewCount(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                @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,
+                                @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examViewCount(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
-    
+
+
     @ApiOperation(value = "缺考名单")
     @RequestMapping(value = "/exam_deficiency_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examDeficiencyList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examDeficiencyList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                     @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,
+                                     @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                     @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examDeficiencyList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "异常处理")
     @RequestMapping(value = "/exam_exception_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examExceptionList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examExceptionList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                    @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,
+                                    @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                    @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examExceptionList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "异常处理明细")
     @RequestMapping(value = "/exam_exception_list_detail", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examExceptionListDetail(@ApiParam(value = "考生id", required = true) @RequestParam Long examStudentId) {
         return ResultUtil.ok(reportService.examExceptionDetailList(examStudentId));
     }
-    
+
     @ApiOperation(value = "重考处理")
     @RequestMapping(value = "/exam_reexam_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examReexamList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examReexamList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                 @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,
+                                 @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                 @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examReexamList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "违纪名单")
     @RequestMapping(value = "/exam_breach_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examBreachList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examBreachList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                 @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,
+                                 @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                 @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examBreachList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "违纪名单明细")
     @RequestMapping(value = "/exam_breach_list_detail", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examBreachListDetail(@ApiParam(value = "考生id", required = true) @RequestParam Long examStudentId) {
         return ResultUtil.ok(reportService.examBreachListDetail(examStudentId));
     }
-    
+
     @ApiOperation(value = "撤销违纪名单")
     @RequestMapping(value = "/exam_revoke_breach_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examRevokeBreachList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examRevokeBreachList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                       @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,
+                                       @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                       @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examRevokeBreachList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "撤销违纪名单明细")
     @RequestMapping(value = "/exam_revoke_breach_list_detail", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examRevokeBreachListDetail(@ApiParam(value = "考生id", required = true) @RequestParam Long examStudentId) {
         return ResultUtil.ok(reportService.examRevokeBreachListDetail(examStudentId));
     }
-    
+
     @ApiOperation(value = "考生日志")
     @RequestMapping(value = "/exam_student_log_list", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examStudentLogList(@ApiParam(value = "考试id", required = true) @RequestParam 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,
-                             @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
-                             @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
-        return ResultUtil.ok(reportService.examStudentLogList(examId, examActivityId, roomCode, courseCode, name, identity,pageNumber,pageSize));
+                                     @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,
+                                     @ApiParam(value = "分页页码", required = true) @RequestParam int pageNumber,
+                                     @ApiParam(value = "分页数", required = true) @RequestParam int pageSize) {
+        return ResultUtil.ok(reportService.examStudentLogList(examId, examActivityId, roomCode, courseCode, name, identity, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "考生日志明细")
     @RequestMapping(value = "/exam_student_log_list_detail", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
     public Result examStudentLogListDetail(@ApiParam(value = "考生id", required = true) @RequestParam Long examStudentId) {
         return ResultUtil.ok(reportService.examStudentLogListDetail(examStudentId));
     }
+
+    @ApiOperation(value = "在线巡考报表接口")
+    @RequestMapping(value = "/patrol", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "在线巡考报表信息", response = InvigilateListPatrolReportBean.class)})
+    public Result patrolReport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId) {
+        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(reportService.patrolReport(examId, userId));
+    }
+
+    @ApiOperation(value = "考情监控报表接口")
+    @RequestMapping(value = "/exam/invigilate", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "考情监控报表信息", response = InvigilateListPatrolReportBean.class)})
+    public Result examInvigilateReport(@ApiParam(value = "考试批次id", required = false) @RequestParam(required = false) Long examId) {
+        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(reportService.examInvigilateReport(examId, userId));
+    }
 }

+ 101 - 36
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListDetailBean.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.bean.backend;
 
 import com.qmth.themis.business.enums.ExamRecordStatusEnum;
+import com.qmth.themis.business.enums.ExamTypeEnum;
 import com.qmth.themis.business.enums.ExceptionEnum;
 import com.qmth.themis.business.enums.VerifyExceptionEnum;
 import io.swagger.annotations.ApiModel;
@@ -71,18 +72,8 @@ public class InvigilateListDetailBean implements Serializable {
     @ApiModelProperty(name = "是否违纪,0:是,1:不是")
     private Integer breachStatus;
 
-    @ApiModelProperty(name = "预警信息")
-    private List<InvigilateWarnInfoBean> warningInfos;
-
-    @ApiModelProperty(name = "预警信息")
-    private List<InvigilateExceptionInfoBean> exceptionInfos;
-
-    @ApiModelProperty(name = "预警信息")
-    private List<StudentLogBean> studentLogs;
-
-    public InvigilateListDetailBean() {
-
-    }
+    @ApiModelProperty(name = "考生轨迹")
+    private List<ExamStudentTrailBean> examStudentTrailBean;
 
     public InvigilateListDetailBean(String examName, String examActivityCode, Long examId, Long examActivityId, Long examStudentId, Long examRecordId, String identity, String examStudentName, String courseNameCode, ExamRecordStatusEnum statusCode, String roomCode, String roomName, Integer breachStatus) {
         this.examName = examName;
@@ -124,28 +115,12 @@ public class InvigilateListDetailBean implements Serializable {
         this.roomName = roomName;
     }
 
-    public List<StudentLogBean> getStudentLogs() {
-        return studentLogs;
-    }
-
-    public void setStudentLogs(List<StudentLogBean> studentLogs) {
-        this.studentLogs = studentLogs;
+    public List<ExamStudentTrailBean> getExamStudentTrailBean() {
+        return examStudentTrailBean;
     }
 
-    public List<InvigilateWarnInfoBean> getWarningInfos() {
-        return warningInfos;
-    }
-
-    public void setWarningInfos(List<InvigilateWarnInfoBean> warningInfos) {
-        this.warningInfos = warningInfos;
-    }
-
-    public List<InvigilateExceptionInfoBean> getExceptionInfos() {
-        return exceptionInfos;
-    }
-
-    public void setExceptionInfos(List<InvigilateExceptionInfoBean> exceptionInfos) {
-        this.exceptionInfos = exceptionInfos;
+    public void setExamStudentTrailBean(List<ExamStudentTrailBean> examStudentTrailBean) {
+        this.examStudentTrailBean = examStudentTrailBean;
     }
 
     public Integer getBreachStatus() {
@@ -263,6 +238,28 @@ public class InvigilateListDetailBean implements Serializable {
         this.statusCode = statusCode;
     }
 
+    /**
+    * @Description: 考生轨迹bean
+    * @Param:
+    * @return:
+    * @Author: wangliang
+    * @Date: 2020/9/15
+    */
+    private class ExamStudentTrailBean implements Serializable{
+
+        @ApiModelProperty(value = "考生轨迹信息")
+        private StudentLogBean studentLogBean;
+
+        @ApiModelProperty(value = "异常信息")
+        private InvigilateExceptionInfoBean invigilateExceptionInfoBean;
+
+        @ApiModelProperty(value = "预警信息")
+        private List<InvigilateWarnInfoBean> invigilateWarnInfoBeanList;
+
+        @ApiModelProperty(value = "创建时间")
+        private Date createTime;
+    }
+
     /**
      * @Description: 预警bean
      * @Param:
@@ -290,6 +287,28 @@ public class InvigilateListDetailBean implements Serializable {
         @ApiModelProperty(value = "创建时间")
         private Date createTime;
 
+        @ApiModelProperty(value = "图片url")
+        private String photoUrl;
+
+        @ApiModelProperty(value = "视频url")
+        private String videoUrl;
+
+        public String getPhotoUrl() {
+            return photoUrl;
+        }
+
+        public void setPhotoUrl(String photoUrl) {
+            this.photoUrl = photoUrl;
+        }
+
+        public String getVideoUrl() {
+            return videoUrl;
+        }
+
+        public void setVideoUrl(String videoUrl) {
+            this.videoUrl = videoUrl;
+        }
+
         public String getInfo() {
             return info;
         }
@@ -347,6 +366,7 @@ public class InvigilateListDetailBean implements Serializable {
      * @Date: 2020/8/24
      */
     public class InvigilateExceptionInfoBean implements Serializable {
+
         @ApiModelProperty(value = "异常信息")
         private String info;
 
@@ -362,6 +382,28 @@ public class InvigilateListDetailBean implements Serializable {
         @ApiModelProperty(value = "处理时差,单位秒")
         private Integer difference;
 
+        @ApiModelProperty(value = "图片url")
+        private String photoUrl;
+
+        @ApiModelProperty(value = "视频url")
+        private String videoUrl;
+
+        public String getPhotoUrl() {
+            return photoUrl;
+        }
+
+        public void setPhotoUrl(String photoUrl) {
+            this.photoUrl = photoUrl;
+        }
+
+        public String getVideoUrl() {
+            return videoUrl;
+        }
+
+        public void setVideoUrl(String videoUrl) {
+            this.videoUrl = videoUrl;
+        }
+
         public Integer getDifference() {
             return difference;
         }
@@ -404,18 +446,19 @@ public class InvigilateListDetailBean implements Serializable {
     }
 
     /**
-     * @Description: 异常bean
+     * @Description: 考生日志bean
      * @Param:
      * @return:
      * @Author: wangliang
      * @Date: 2020/8/24
      */
     public class StudentLogBean implements Serializable {
+
         @ApiModelProperty(value = "信息")
         private String info;
 
         @ApiModelProperty(value = "类别")
-        private ExceptionEnum type;
+        private ExamTypeEnum type;
 
         @ApiModelProperty(value = "备注")
         private String remark;
@@ -423,6 +466,28 @@ public class InvigilateListDetailBean implements Serializable {
         @ApiModelProperty(value = "创建时间")
         private Date createTime;
 
+        @ApiModelProperty(value = "图片url")
+        private String photoUrl;
+
+        @ApiModelProperty(value = "视频url")
+        private String videoUrl;
+
+        public String getPhotoUrl() {
+            return photoUrl;
+        }
+
+        public void setPhotoUrl(String photoUrl) {
+            this.photoUrl = photoUrl;
+        }
+
+        public String getVideoUrl() {
+            return videoUrl;
+        }
+
+        public void setVideoUrl(String videoUrl) {
+            this.videoUrl = videoUrl;
+        }
+
         public String getInfo() {
             return info;
         }
@@ -431,11 +496,11 @@ public class InvigilateListDetailBean implements Serializable {
             this.info = info;
         }
 
-        public ExceptionEnum getType() {
+        public ExamTypeEnum getType() {
             return type;
         }
 
-        public void setType(ExceptionEnum type) {
+        public void setType(ExamTypeEnum type) {
             this.type = type;
         }
 

+ 1 - 1
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListPatrolBean.java

@@ -8,7 +8,7 @@ import java.io.Serializable;
 import java.util.Date;
 
 /**
- * @Description: 实时监控台视频返回对象
+ * @Description: 在线巡考返回对象
  * @Param:
  * @return:
  * @Author: wangliang

+ 63 - 0
themis-business/src/main/java/com/qmth/themis/business/bean/backend/InvigilateListPatrolReportBean.java

@@ -0,0 +1,63 @@
+package com.qmth.themis.business.bean.backend;
+
+import com.qmth.themis.business.enums.ExamRecordStatusEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @Description: 在线巡考报表返回对象
+ * @Param:
+ * @return:
+ * @Author: wangliang
+ * @Date: 2020/8/22
+ */
+@ApiModel("在线巡考报表返回对象")
+public class InvigilateListPatrolReportBean implements Serializable {
+
+    @ApiModelProperty(name = "虚拟考场代码")
+    private String roomCode;
+
+    @ApiModelProperty(name = "虚拟考场名称")
+    private String roomName;
+
+    @ApiModelProperty(name = "预警量")
+    private Integer warningCount;
+
+    @ApiModelProperty(name = "通讯故障数")
+    private Integer clientWebsocketStatusCount;
+
+    public String getRoomCode() {
+        return roomCode;
+    }
+
+    public void setRoomCode(String roomCode) {
+        this.roomCode = roomCode;
+    }
+
+    public String getRoomName() {
+        return roomName;
+    }
+
+    public void setRoomName(String roomName) {
+        this.roomName = roomName;
+    }
+
+    public Integer getWarningCount() {
+        return warningCount;
+    }
+
+    public void setWarningCount(Integer warningCount) {
+        this.warningCount = warningCount;
+    }
+
+    public Integer getClientWebsocketStatusCount() {
+        return clientWebsocketStatusCount;
+    }
+
+    public void setClientWebsocketStatusCount(Integer clientWebsocketStatusCount) {
+        this.clientWebsocketStatusCount = clientWebsocketStatusCount;
+    }
+}

+ 18 - 1
themis-business/src/main/java/com/qmth/themis/business/dao/TOeExamRecordMapper.java

@@ -253,5 +253,22 @@ public interface TOeExamRecordMapper extends BaseMapper<TOeExamRecord> {
 	public void updateObjectiveScore(@Param("recordId") Long recordId,@Param("score") Double score);
 
 	public TOeExamRecord findOneByPaperId(@Param("paperId")Long paperId);
-	
+
+    /**
+     * 在线巡考报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListPatrolReportBean> patrolReport(@Param("examId") Long examId, @Param("userId") Long userId);
+
+    /**
+     * 考情监考报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListPatrolReportBean> examInvigilateReport(@Param("examId") Long examId, @Param("userId") Long userId);
 }

+ 25 - 0
themis-business/src/main/java/com/qmth/themis/business/entity/TIeInvigilateExceptionInfo.java

@@ -67,6 +67,15 @@ public class TIeInvigilateExceptionInfo implements Serializable {
     @TableField(value = "difference")
     private Integer difference;
 
+    @ApiModelProperty(value = "图片url")
+    @TableField(value = "photo_url")
+    private String photoUrl;
+
+    @ApiModelProperty(value = "视频url")
+    @TableField(value = "video_url")
+    private String videoUrl;
+
+
     public TIeInvigilateExceptionInfo() {
 
     }
@@ -82,6 +91,22 @@ public class TIeInvigilateExceptionInfo implements Serializable {
         this.difference = difference;
     }
 
+    public String getPhotoUrl() {
+        return photoUrl;
+    }
+
+    public void setPhotoUrl(String photoUrl) {
+        this.photoUrl = photoUrl;
+    }
+
+    public String getVideoUrl() {
+        return videoUrl;
+    }
+
+    public void setVideoUrl(String videoUrl) {
+        this.videoUrl = videoUrl;
+    }
+
     public Integer getDifference() {
         return difference;
     }

+ 26 - 2
themis-business/src/main/java/com/qmth/themis/business/entity/TIeInvigilateWarnInfo.java

@@ -71,6 +71,14 @@ public class TIeInvigilateWarnInfo implements Serializable {
     @TableField(value = "update_time", fill = FieldFill.UPDATE)
     private Date updateTime;
 
+    @ApiModelProperty(value = "图片url")
+    @TableField(value = "photo_url")
+    private String photoUrl;
+
+    @ApiModelProperty(value = "视频url")
+    @TableField(value = "video_url")
+    private String videoUrl;
+
     public TIeInvigilateWarnInfo() {
 
     }
@@ -87,7 +95,7 @@ public class TIeInvigilateWarnInfo implements Serializable {
         this.approveStatus = 0;
     }
 
-    public TIeInvigilateWarnInfo(Long examId, Long examActivityId, Long examRecordId, Long examStudentId, String level, String info, VerifyExceptionEnum type, String remark) {
+    public TIeInvigilateWarnInfo(Long examId, Long examActivityId, Long examRecordId, Long examStudentId, String level, String info, VerifyExceptionEnum type, String photoUrl) {
         this.id = Constants.idGen.next();
         this.examId = examId;
         this.examActivityId = examActivityId;
@@ -97,7 +105,23 @@ public class TIeInvigilateWarnInfo implements Serializable {
         this.info = info;
         this.type = type;
         this.approveStatus = 0;
-        this.remark = remark;
+        this.photoUrl = photoUrl;
+    }
+
+    public String getPhotoUrl() {
+        return photoUrl;
+    }
+
+    public void setPhotoUrl(String photoUrl) {
+        this.photoUrl = photoUrl;
+    }
+
+    public String getVideoUrl() {
+        return videoUrl;
+    }
+
+    public void setVideoUrl(String videoUrl) {
+        this.videoUrl = videoUrl;
     }
 
     public static long getSerialVersionUID() {

+ 42 - 23
themis-business/src/main/java/com/qmth/themis/business/service/TIeReportService.java

@@ -1,43 +1,62 @@
 package com.qmth.themis.business.service;
 
-import java.util.List;
-import java.util.Map;
-
 import com.qmth.themis.business.base.BasePage;
 import com.qmth.themis.business.bean.backend.ExamBreachDetailListBean;
 import com.qmth.themis.business.bean.backend.ExamExceptionDetailListBean;
 import com.qmth.themis.business.bean.backend.ExamStudentLogDetailListBean;
+import com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean;
+
+import java.util.List;
+import java.util.Map;
 
 public interface TIeReportService {
-	public Map<String, Object> examView(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity);
+    public Map<String, Object> examView(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                        String name, String identity);
+
+    public BasePage examViewCount(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                  String identity, int pageNumber, int pageSize);
+
+    public BasePage examDeficiencyList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                       String identity, int pageNumber, int pageSize);
 
-	public BasePage examViewCount(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    public BasePage examExceptionList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                      String identity, int pageNumber, int pageSize);
 
-	public BasePage examDeficiencyList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    public List<ExamExceptionDetailListBean> examExceptionDetailList(Long examStudentId);
 
-	public BasePage examExceptionList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    public BasePage examReexamList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                   String identity, int pageNumber, int pageSize);
 
-	public List<ExamExceptionDetailListBean> examExceptionDetailList(Long examStudentId);
+    public BasePage examBreachList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                   String identity, int pageNumber, int pageSize);
 
-	public BasePage examReexamList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    public List<ExamBreachDetailListBean> examBreachListDetail(Long examStudentId);
 
-	public BasePage examBreachList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    public BasePage examRevokeBreachList(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                         String name, String identity, int pageNumber, int pageSize);
 
-	public List<ExamBreachDetailListBean> examBreachListDetail(Long examStudentId);
+    public List<ExamBreachDetailListBean> examRevokeBreachListDetail(Long examStudentId);
 
-	public BasePage examRevokeBreachList(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity, int pageNumber, int pageSize);
+    public BasePage examStudentLogList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                       String identity, int pageNumber, int pageSize);
 
-	public List<ExamBreachDetailListBean> examRevokeBreachListDetail(Long examStudentId);
+    public List<ExamStudentLogDetailListBean> examStudentLogListDetail(Long examStudentId);
 
-	public BasePage examStudentLogList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize);
+    /**
+     * 在线巡考报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListPatrolReportBean> patrolReport(Long examId, Long userId);
 
-	public List<ExamStudentLogDetailListBean> examStudentLogListDetail(Long examStudentId);
+    /**
+     * 考情监控报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    public List<InvigilateListPatrolReportBean> examInvigilateReport(Long examId, Long userId);
 }

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

@@ -792,7 +792,6 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         teStudentCacheDto.setUnFinishedRecordId(null);
         redisUtil.setStudent(teStudentCacheDto.getId(), teStudentCacheDto);
         checkToPersisted(recordId);
-        TEStudentCacheDto teStudent = (TEStudentCacheDto) ServletUtil.getRequestStudentAccount();
         //mq发送消息start
         MqDto mqDto = new MqDto(MqTopicEnum.themisTopic.getCode(), MqTagEnum.STUDENT.name(), SystemOperationEnum.FINISHED, MqTagEnum.STUDENT, String.valueOf(teStudentCacheDto.getId()), teStudentCacheDto.getIdentity());
         this.sendOeLogMessage(SystemOperationEnum.FINISHED, examStudentId, recordId, mqDto);

+ 317 - 312
themis-business/src/main/java/com/qmth/themis/business/service/impl/TIeReportServiceImpl.java

@@ -1,366 +1,371 @@
 package com.qmth.themis.business.service.impl;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import javax.annotation.Resource;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.OrderItem;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.google.common.collect.Lists;
 import com.qmth.themis.business.base.BasePage;
-import com.qmth.themis.business.bean.backend.ExamBreachDetailListBean;
-import com.qmth.themis.business.bean.backend.ExamBreachListBean;
-import com.qmth.themis.business.bean.backend.ExamDeficiencyListBean;
-import com.qmth.themis.business.bean.backend.ExamExceptionDetailListBean;
-import com.qmth.themis.business.bean.backend.ExamExceptionListBean;
-import com.qmth.themis.business.bean.backend.ExamReexamListBean;
-import com.qmth.themis.business.bean.backend.ExamStudentLogDetailListBean;
-import com.qmth.themis.business.bean.backend.ExamStudentLogListBean;
-import com.qmth.themis.business.bean.backend.ExamViewCountListBean;
+import com.qmth.themis.business.bean.backend.*;
 import com.qmth.themis.business.cache.bean.ExamActivityCacheBean;
 import com.qmth.themis.business.cache.bean.ExamCacheBean;
-import com.qmth.themis.business.dao.TEExamBreachLogMapper;
-import com.qmth.themis.business.dao.TEExamReexamMapper;
-import com.qmth.themis.business.dao.TEExamStudentLogMapper;
-import com.qmth.themis.business.dao.TEExamStudentMapper;
-import com.qmth.themis.business.dao.TIeInvigilateExceptionInfoMapper;
-import com.qmth.themis.business.dao.TOeExamRecordMapper;
+import com.qmth.themis.business.dao.*;
 import com.qmth.themis.business.entity.TEExamActivity;
 import com.qmth.themis.business.enums.BreachTypeEnum;
 import com.qmth.themis.business.enums.ExceptionEnum;
 import com.qmth.themis.business.service.TEExamActivityService;
 import com.qmth.themis.business.service.TEExamService;
 import com.qmth.themis.business.service.TIeReportService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 public class TIeReportServiceImpl implements TIeReportService {
-	
-	@Resource
-	TEExamStudentMapper examStudentMapper;
-	
+
+    @Resource
+    TEExamStudentMapper examStudentMapper;
+
     @Resource
     TOeExamRecordMapper examRecordMapper;
-    
+
     @Resource
     TEExamActivityService examActivityService;
-    
+
     @Resource
     TEExamService examService;
-    
+
     @Resource
     TIeInvigilateExceptionInfoMapper invigilateExceptionInfoMapper;
-    
+
     @Resource
     TEExamReexamMapper examReexamMapper;
-    
+
     @Resource
     TEExamBreachLogMapper examBreachLogMapper;
-    
+
     @Resource
     TEExamStudentLogMapper examStudentLogMapper;
 
-	@Override
-	public Map<String, Object> examView(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity) {
-		//应考人数
-		Long totalNum=0L;
-		List<Map<String,Object>> total=examStudentMapper.getTotalCount(examId, examActivityId, roomCode, courseCode);
-		Map<Long,Long> totalMap=new HashMap<Long,Long>();
-		for(Map<String,Object> map:total) {
-			Long acId=(Long)map.get("activityId");
-			Long count=(Long)map.get("cc");
-			totalMap.put(acId, count);
-			totalNum=totalNum+count;
-		}
-		//实考人数
-		Long doneNum=0L;
-		List<Map<String,Object>> doneCount=examRecordMapper.getDoneCount(examId, examActivityId, roomCode, courseCode);
-		Map<Long,Long> doneMap=new HashMap<Long,Long>();
-		for(Map<String,Object> map:doneCount) {
-			Long acId=(Long)map.get("activityId");
-			if(acId!=null) {
-				Long count=(Long)map.get("cc");
-				doneMap.put(acId, count);
-				doneNum=doneNum+count;
-			}
-			
-		}
-		//缺考人数
-		Map<Long,Long> absentMap=new HashMap<Long,Long>();
-		Date now = new Date();
-		for(Long acId:totalMap.keySet()) {
-			ExamActivityCacheBean ac=examActivityService.getExamActivityCacheBean(acId);
-			Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000);
-	        if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
-	        	Long done=doneMap.get(acId);
-	        	if(done==null) {
-	        		done=0L;
-	        	}
-	        	absentMap.put(acId, totalMap.get(acId)-done);
-	        }
-		}
-		Long absentNum=0L;
-		if(absentMap.size()>0) {
-			for(Long c:absentMap.values()) {
-				absentNum=absentNum+c;
-			}
-		}
-		//每日已考人数
-		List<Map<String,Object>> doneCountByDay=examRecordMapper.getDoneCountByDay(examId, examActivityId, roomCode, courseCode);
-		
-		Map<String, Object> ret=new HashMap<String, Object>();
-		ret.put("examTotal", totalNum);
-		ret.put("actualExamTotal", doneNum);
-		ret.put("deficiencyExamTotal", absentNum);
-		ret.put("completeOffExamTotal", totalNum-doneNum-absentNum);
-		ret.put("examTotalList", doneCountByDay);
-		
-		return ret;
-	}
-
-	@Override
-	public BasePage examViewCount(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize) {
-		//应考人数
-		IPage<ExamViewCountListBean> total = examStudentMapper.getTotalCountInfo(new Page<>(pageNumber, pageSize),examId, examActivityId, roomCode, courseCode);
-        List<ExamViewCountListBean> data=total.getRecords();
+    @Resource
+    TOeExamRecordMapper tOeExamRecordMapper;
+
+    @Override
+    public Map<String, Object> examView(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                        String name, String identity) {
+        //应考人数
+        Long totalNum = 0L;
+        List<Map<String, Object>> total = examStudentMapper.getTotalCount(examId, examActivityId, roomCode, courseCode);
+        Map<Long, Long> totalMap = new HashMap<Long, Long>();
+        for (Map<String, Object> map : total) {
+            Long acId = (Long) map.get("activityId");
+            Long count = (Long) map.get("cc");
+            totalMap.put(acId, count);
+            totalNum = totalNum + count;
+        }
+        //实考人数
+        Long doneNum = 0L;
+        List<Map<String, Object>> doneCount = examRecordMapper.getDoneCount(examId, examActivityId, roomCode, courseCode);
+        Map<Long, Long> doneMap = new HashMap<Long, Long>();
+        for (Map<String, Object> map : doneCount) {
+            Long acId = (Long) map.get("activityId");
+            if (acId != null) {
+                Long count = (Long) map.get("cc");
+                doneMap.put(acId, count);
+                doneNum = doneNum + count;
+            }
+
+        }
+        //缺考人数
+        Map<Long, Long> absentMap = new HashMap<Long, Long>();
+        Date now = new Date();
+        for (Long acId : totalMap.keySet()) {
+            ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(acId);
+            Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000);
+            if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
+                Long done = doneMap.get(acId);
+                if (done == null) {
+                    done = 0L;
+                }
+                absentMap.put(acId, totalMap.get(acId) - done);
+            }
+        }
+        Long absentNum = 0L;
+        if (absentMap.size() > 0) {
+            for (Long c : absentMap.values()) {
+                absentNum = absentNum + c;
+            }
+        }
+        //每日已考人数
+        List<Map<String, Object>> doneCountByDay = examRecordMapper.getDoneCountByDay(examId, examActivityId, roomCode, courseCode);
+
+        Map<String, Object> ret = new HashMap<String, Object>();
+        ret.put("examTotal", totalNum);
+        ret.put("actualExamTotal", doneNum);
+        ret.put("deficiencyExamTotal", absentNum);
+        ret.put("completeOffExamTotal", totalNum - doneNum - absentNum);
+        ret.put("examTotalList", doneCountByDay);
+
+        return ret;
+    }
+
+    @Override
+    public BasePage examViewCount(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                  String identity, int pageNumber, int pageSize) {
+        //应考人数
+        IPage<ExamViewCountListBean> total = examStudentMapper.getTotalCountInfo(new Page<>(pageNumber, pageSize), examId, examActivityId, roomCode, courseCode);
+        List<ExamViewCountListBean> data = total.getRecords();
         BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        if(data==null||data.size()==0) {
-        	return basePage;
+        if (data == null || data.size() == 0) {
+            return basePage;
         }
-        List<Long> activityIds=data.stream().map(e -> e.getExamActivityId()).collect(Collectors.toList());
-        
+        List<Long> activityIds = data.stream().map(e -> e.getExamActivityId()).collect(Collectors.toList());
+
         //实考
-        List<Map<String,Object>> doneCountByDay=examStudentMapper.getDoneCountByActivityIds(examId, activityIds);
-		Map<String,Long> doneMap=new HashMap<String,Long>();
-		for(Map<String,Object> map:doneCountByDay) {
-			Long acId=(Long)map.get("activityId");
-			String roomcode=(String)map.get("roomCode");
-			Long count=(Long)map.get("cc");
-			doneMap.put(acId+"-"+roomcode, count);
-		}
-		
-		//缺考
-		List<Long> absentActivityIds=new ArrayList<>();
-		Date now = new Date();
-		for(Long acid:activityIds) {
-			ExamActivityCacheBean ac=examActivityService.getExamActivityCacheBean(acid);
-			Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000);
-	        if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
-	        	absentActivityIds.add(acid);
-	        }
-		}
-		
-		Map<String,Long> absentMap=new HashMap<String,Long>();
-		if(absentActivityIds.size()>0) {
-			List<Map<String,Object>> absentCountByDay=examStudentMapper.getAbsentCountByActivityIds(examId, absentActivityIds);
-			for(Map<String,Object> map:absentCountByDay) {
-				Long acId=(Long)map.get("activityId");
-				String roomcode=(String)map.get("roomCode");
-				Long count=(Long)map.get("cc");
-				absentMap.put(acId+"-"+roomcode, count);
-			}
-		}
-		ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamViewCountListBean b:data) {
-			Long done=doneMap.get(b.getExamActivityId()+"-"+b.getRoomCode());
-			if(done==null) {
-				done=0L;
-			}
-			Long absent=absentMap.get(b.getExamActivityId()+"-"+b.getRoomCode());
-			if(absent==null) {
-				absent=0L;
-			}
-			b.setActualExamTotal(done);
-			b.setDeficiencyExamTotal(absent);
-			b.setExamName(exam.getName());
-		}
-		basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-		return basePage;
-	}
-
-	@Override
-	public BasePage examDeficiencyList(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity, int pageNumber, int pageSize) {
-		Page<ExamDeficiencyListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("t.exam_activity_id"));
-		ipage.addOrder(OrderItem.asc("t.room_code"));
-		QueryWrapper<TEExamActivity> wp = new QueryWrapper<>();
-		wp.lambda().eq(TEExamActivity::getExamId, examId);
-        List<TEExamActivity> acs= examActivityService.list(wp);
-        List<Long> absentActivityIds=new ArrayList<>();
-		Date now = new Date();
-		for(TEExamActivity ac:acs) {
-			Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000L);
-	        if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
-	        	absentActivityIds.add(ac.getId());
-	        }
-		}
-		if(absentActivityIds.size()==0) {
-        	BasePage basePage = new BasePage(Lists.newArrayList(), 1, pageSize, 0);
-        	return basePage;
+        List<Map<String, Object>> doneCountByDay = examStudentMapper.getDoneCountByActivityIds(examId, activityIds);
+        Map<String, Long> doneMap = new HashMap<String, Long>();
+        for (Map<String, Object> map : doneCountByDay) {
+            Long acId = (Long) map.get("activityId");
+            String roomcode = (String) map.get("roomCode");
+            Long count = (Long) map.get("cc");
+            doneMap.put(acId + "-" + roomcode, count);
         }
-		IPage<ExamDeficiencyListBean> total = examStudentMapper.getExamDeficiencyPage(ipage,examId, examActivityId, roomCode, courseCode,name,identity,absentActivityIds);
-        List<ExamDeficiencyListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+
+        //缺考
+        List<Long> absentActivityIds = new ArrayList<>();
+        Date now = new Date();
+        for (Long acid : activityIds) {
+            ExamActivityCacheBean ac = examActivityService.getExamActivityCacheBean(acid);
+            Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000);
+            if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
+                absentActivityIds.add(acid);
+            }
+        }
+
+        Map<String, Long> absentMap = new HashMap<String, Long>();
+        if (absentActivityIds.size() > 0) {
+            List<Map<String, Object>> absentCountByDay = examStudentMapper.getAbsentCountByActivityIds(examId, absentActivityIds);
+            for (Map<String, Object> map : absentCountByDay) {
+                Long acId = (Long) map.get("activityId");
+                String roomcode = (String) map.get("roomCode");
+                Long count = (Long) map.get("cc");
+                absentMap.put(acId + "-" + roomcode, count);
+            }
+        }
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamViewCountListBean b : data) {
+            Long done = doneMap.get(b.getExamActivityId() + "-" + b.getRoomCode());
+            if (done == null) {
+                done = 0L;
+            }
+            Long absent = absentMap.get(b.getExamActivityId() + "-" + b.getRoomCode());
+            if (absent == null) {
+                absent = 0L;
+            }
+            b.setActualExamTotal(done);
+            b.setDeficiencyExamTotal(absent);
+            b.setExamName(exam.getName());
+        }
+        basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        return basePage;
+    }
+
+    @Override
+    public BasePage examDeficiencyList(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                       String name, String identity, int pageNumber, int pageSize) {
+        Page<ExamDeficiencyListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("t.exam_activity_id"));
+        ipage.addOrder(OrderItem.asc("t.room_code"));
+        QueryWrapper<TEExamActivity> wp = new QueryWrapper<>();
+        wp.lambda().eq(TEExamActivity::getExamId, examId);
+        List<TEExamActivity> acs = examActivityService.list(wp);
+        List<Long> absentActivityIds = new ArrayList<>();
+        Date now = new Date();
+        for (TEExamActivity ac : acs) {
+            Long end = ac.getStartTime().getTime() + (ac.getOpeningSeconds() * 1000L);
+            if (now.getTime() > end) {//场次开考时间结束,未开考的都是缺考
+                absentActivityIds.add(ac.getId());
+            }
+        }
+        if (absentActivityIds.size() == 0) {
+            BasePage basePage = new BasePage(Lists.newArrayList(), 1, pageSize, 0);
+            return basePage;
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamDeficiencyListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        IPage<ExamDeficiencyListBean> total = examStudentMapper.getExamDeficiencyPage(ipage, examId, examActivityId, roomCode, courseCode, name, identity, absentActivityIds);
+        List<ExamDeficiencyListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
+        }
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamDeficiencyListBean b : data) {
+            b.setExamName(exam.getName());
+        }
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
-
-	@Override
-	public BasePage examExceptionList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize) {
-		Page<ExamExceptionListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-		IPage<ExamExceptionListBean> total = invigilateExceptionInfoMapper.getExamExceptionPage(ipage,examId, examActivityId, roomCode, courseCode,name,identity);
-        List<ExamExceptionListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+    }
+
+    @Override
+    public BasePage examExceptionList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                      String identity, int pageNumber, int pageSize) {
+        Page<ExamExceptionListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("f.exam_student_id"));
+        IPage<ExamExceptionListBean> total = invigilateExceptionInfoMapper.getExamExceptionPage(ipage, examId, examActivityId, roomCode, courseCode, name, identity);
+        List<ExamExceptionListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamExceptionListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamExceptionListBean b : data) {
+            b.setExamName(exam.getName());
+        }
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
-
-	@Override
-	public List<ExamExceptionDetailListBean> examExceptionDetailList(Long examStudentId) {
-		List<ExamExceptionDetailListBean> ret=invigilateExceptionInfoMapper.getExamExceptionDetailList(examStudentId);
-		if(ret!=null&&ret.size()>0) {
-			for(ExamExceptionDetailListBean b:ret) {
-				b.setReason(ExceptionEnum.valueOf(b.getReason()).getCode());
-			}
-		}
-		return ret;
-	}
-
-	@Override
-	public BasePage examReexamList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize) {
-		Page<ExamReexamListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-		IPage<ExamReexamListBean> total = examReexamMapper.getExamReexamPage(ipage,examId, examActivityId, roomCode, courseCode,name,identity);
-        List<ExamReexamListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+    }
+
+    @Override
+    public List<ExamExceptionDetailListBean> examExceptionDetailList(Long examStudentId) {
+        List<ExamExceptionDetailListBean> ret = invigilateExceptionInfoMapper.getExamExceptionDetailList(examStudentId);
+        if (ret != null && ret.size() > 0) {
+            for (ExamExceptionDetailListBean b : ret) {
+                b.setReason(ExceptionEnum.valueOf(b.getReason()).getCode());
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    public BasePage examReexamList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                   String identity, int pageNumber, int pageSize) {
+        Page<ExamReexamListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("f.exam_student_id"));
+        IPage<ExamReexamListBean> total = examReexamMapper.getExamReexamPage(ipage, examId, examActivityId, roomCode, courseCode, name, identity);
+        List<ExamReexamListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
+        }
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamReexamListBean b : data) {
+            b.setExamName(exam.getName());
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamReexamListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
-
-	@Override
-	public BasePage examBreachList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
-			String identity, int pageNumber, int pageSize) {
-		Page<ExamBreachListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-		IPage<ExamBreachListBean> total = examBreachLogMapper.getExamBreachPage(ipage,examId, examActivityId, roomCode, courseCode,name,identity);
-        List<ExamBreachListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+    }
+
+    @Override
+    public BasePage examBreachList(Long examId, Long examActivityId, String roomCode, String courseCode, String name,
+                                   String identity, int pageNumber, int pageSize) {
+        Page<ExamBreachListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("f.exam_student_id"));
+        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamBreachPage(ipage, examId, examActivityId, roomCode, courseCode, name, identity);
+        List<ExamBreachListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamBreachListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamBreachListBean b : data) {
+            b.setExamName(exam.getName());
+        }
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
-
-	@Override
-	public List<ExamBreachDetailListBean> examBreachListDetail(Long examStudentId) {
-		List<ExamBreachDetailListBean> ret=examBreachLogMapper.getExamBreachDetailList(examStudentId);
-		if(ret!=null&&ret.size()>0) {
-			for(ExamBreachDetailListBean b:ret) {
-				if(StringUtils.isNotBlank(b.getType())){
-					b.setType(BreachTypeEnum.valueOf(b.getType()).getCode());
-				}
-			}
-		}
-		return ret;
-	}
-
-	@Override
-	public BasePage examRevokeBreachList(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity, int pageNumber, int pageSize) {
-		Page<ExamBreachListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("f.exam_student_id"));
-		IPage<ExamBreachListBean> total = examBreachLogMapper.getExamRevokeBreachPage(ipage,examId, examActivityId, roomCode, courseCode,name,identity);
-        List<ExamBreachListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+    }
+
+    @Override
+    public List<ExamBreachDetailListBean> examBreachListDetail(Long examStudentId) {
+        List<ExamBreachDetailListBean> ret = examBreachLogMapper.getExamBreachDetailList(examStudentId);
+        if (ret != null && ret.size() > 0) {
+            for (ExamBreachDetailListBean b : ret) {
+                if (StringUtils.isNotBlank(b.getType())) {
+                    b.setType(BreachTypeEnum.valueOf(b.getType()).getCode());
+                }
+            }
+        }
+        return ret;
+    }
+
+    @Override
+    public BasePage examRevokeBreachList(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                         String name, String identity, int pageNumber, int pageSize) {
+        Page<ExamBreachListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("f.exam_student_id"));
+        IPage<ExamBreachListBean> total = examBreachLogMapper.getExamRevokeBreachPage(ipage, examId, examActivityId, roomCode, courseCode, name, identity);
+        List<ExamBreachListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
+        }
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamBreachListBean b : data) {
+            b.setExamName(exam.getName());
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamBreachListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
-
-	@Override
-	public List<ExamBreachDetailListBean> examRevokeBreachListDetail(Long examStudentId) {
-		List<ExamBreachDetailListBean> ret=examBreachLogMapper.getExamBreachDetailList(examStudentId);
-		if(ret!=null&&ret.size()>0) {
-			for(ExamBreachDetailListBean b:ret) {
-				if(StringUtils.isNotBlank(b.getType())) {
-					b.setType(BreachTypeEnum.valueOf(b.getType()).getCode());
-				}
-			}
-		}
-		return ret;
-	}
-
-	@Override
-	public BasePage examStudentLogList(Long examId, Long examActivityId, String roomCode, String courseCode,
-			String name, String identity, int pageNumber, int pageSize) {
-		Page<ExamStudentLogListBean> ipage=new Page<>(pageNumber, pageSize);
-		ipage.addOrder(OrderItem.asc("t.id"));
-		IPage<ExamStudentLogListBean> total = examStudentMapper.getPageForStudentLog(ipage,examId, examActivityId, roomCode, courseCode,name,identity);
-        List<ExamStudentLogListBean> data=total.getRecords();
-        if(data==null||data.size()==0) {
-        	BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
-        	return basePage;
+    }
+
+    @Override
+    public List<ExamBreachDetailListBean> examRevokeBreachListDetail(Long examStudentId) {
+        List<ExamBreachDetailListBean> ret = examBreachLogMapper.getExamBreachDetailList(examStudentId);
+        if (ret != null && ret.size() > 0) {
+            for (ExamBreachDetailListBean b : ret) {
+                if (StringUtils.isNotBlank(b.getType())) {
+                    b.setType(BreachTypeEnum.valueOf(b.getType()).getCode());
+                }
+            }
         }
-        ExamCacheBean exam=examService.getExamCacheBean(examId);
-		for(ExamStudentLogListBean b:data) {
-			b.setExamName(exam.getName());
-		}
-		BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+        return ret;
+    }
+
+    @Override
+    public BasePage examStudentLogList(Long examId, Long examActivityId, String roomCode, String courseCode,
+                                       String name, String identity, int pageNumber, int pageSize) {
+        Page<ExamStudentLogListBean> ipage = new Page<>(pageNumber, pageSize);
+        ipage.addOrder(OrderItem.asc("t.id"));
+        IPage<ExamStudentLogListBean> total = examStudentMapper.getPageForStudentLog(ipage, examId, examActivityId, roomCode, courseCode, name, identity);
+        List<ExamStudentLogListBean> data = total.getRecords();
+        if (data == null || data.size() == 0) {
+            BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
+            return basePage;
+        }
+        ExamCacheBean exam = examService.getExamCacheBean(examId);
+        for (ExamStudentLogListBean b : data) {
+            b.setExamName(exam.getName());
+        }
+        BasePage basePage = new BasePage(total.getRecords(), total.getCurrent(), total.getSize(), total.getTotal());
         return basePage;
-	}
+    }
 
-	@Override
-	public List<ExamStudentLogDetailListBean> examStudentLogListDetail(Long examStudentId) {
-		List<ExamStudentLogDetailListBean> ret=examStudentLogMapper.getExamStudentLogList(examStudentId);
-		return ret;
-	}
+    @Override
+    public List<ExamStudentLogDetailListBean> examStudentLogListDetail(Long examStudentId) {
+        return examStudentLogMapper.getExamStudentLogList(examStudentId);
+    }
 
+    /**
+     * 在线巡考报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    @Override
+    public List<InvigilateListPatrolReportBean> patrolReport(Long examId, Long userId) {
+        return tOeExamRecordMapper.patrolReport(examId, userId);
+    }
 
+    /**
+     * 考情监控报表接口
+     *
+     * @param examId
+     * @param userId
+     * @return
+     */
+    @Override
+    public List<InvigilateListPatrolReportBean> examInvigilateReport(Long examId, Long userId) {
+        return tOeExamRecordMapper.examInvigilateReport(examId, userId);
+    }
 }

+ 76 - 72
themis-business/src/main/resources/db/init.sql

@@ -250,9 +250,9 @@ CREATE TABLE `t_b_app` (
   `name` varchar(100) NOT NULL COMMENT '应用名',
   `access_key` varchar(100) NOT NULL COMMENT '访问凭证',
   `access_secret` varchar(100) NOT NULL COMMENT '访问密钥',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
-  `last_access_time` timestamp DEFAULT NULL COMMENT '最近访问时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
+  `last_access_time` timestamp NULL COMMENT '最近访问时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   PRIMARY KEY (`id`)
@@ -270,7 +270,7 @@ CREATE TABLE `t_b_attachment` (
   `size` double NOT NULL COMMENT '大小',
   `md5` varchar(255) NOT NULL COMMENT 'MD5',
   `remark` varchar(500) DEFAULT NULL COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='附件表';
@@ -286,8 +286,8 @@ CREATE TABLE `t_b_client_version` (
   `url` varchar(100) NOT NULL COMMENT '版本详情链接',
   `description` varchar(200) DEFAULT NULL COMMENT '版本描述',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   PRIMARY KEY (`id`)
@@ -329,14 +329,14 @@ CREATE TABLE `t_b_org` (
   `id` bigint NOT NULL COMMENT '主键',
   `code` varchar(50) NOT NULL COMMENT '机构代码,通常用学校简称表示,全局唯一',
   `name` varchar(100) NOT NULL COMMENT '名称',
-  `logo` varchar(100) DEFAULT NULL COMMENT 'logo图片url',
+  `logo` varchar(500) DEFAULT NULL COMMENT 'logo图片url',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
   `enable_simulate` tinyint DEFAULT NULL COMMENT '是否开启模考',
   `simulate_paper_id` bigint DEFAULT NULL COMMENT '模考试卷id',
   `access_key` varchar(50) DEFAULT NULL COMMENT '外部访问凭证',
   `access_secret` varchar(50) DEFAULT NULL COMMENT '外部访问密钥',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `contact_name` varchar(50) DEFAULT NULL COMMENT '联系人',
   `contact_phone` varchar(30) DEFAULT NULL COMMENT '联系人电话',
   `enable_liveness` tinyint DEFAULT NULL COMMENT '是否允许使用活体',
@@ -366,7 +366,7 @@ CREATE TABLE `t_b_privilege` (
   `parent_id` bigint(20) DEFAULT NULL COMMENT '父id',
   `sequence` int(11) DEFAULT NULL COMMENT '序号',
   `remark` varchar(100) DEFAULT NULL COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='菜单和权限';
 
@@ -525,7 +525,7 @@ CREATE TABLE `t_b_role` (
   `id` bigint NOT NULL COMMENT '主键',
   `role_code` varchar(30) NOT NULL COMMENT '角色编码',
   `role_name` varchar(50) NOT NULL COMMENT '角色名称',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `t_b_role_role_code_Idx` (`role_code`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色';
@@ -749,10 +749,10 @@ CREATE TABLE `t_b_session` (
   `device_id` varchar(100) NOT NULL COMMENT '设备标识',
   `address` varchar(100) NOT NULL COMMENT '登录IP地址',
   `access_token` varchar(50) NOT NULL COMMENT '访问令牌',
-  `last_access_time` timestamp DEFAULT NULL COMMENT '最近访问时间',
+  `last_access_time` timestamp NULL COMMENT '最近访问时间',
   `last_access_ip` varchar(100) DEFAULT NULL COMMENT '最近访问IP地址',
-  `update_time` timestamp DEFAULT NULL COMMENT '令牌更新时间',
-  `expire_time` timestamp DEFAULT NULL COMMENT '令牌强制失效时间',
+  `update_time` timestamp NULL COMMENT '令牌更新时间',
+  `expire_time` timestamp NULL COMMENT '令牌强制失效时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会话信息';
 
@@ -772,9 +772,9 @@ CREATE TABLE `t_b_task_history` (
   `result_file_path` varchar(500) DEFAULT NULL COMMENT '导出文件路径',
   `report_file_path` varchar(500) DEFAULT NULL COMMENT '报告路径',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `start_time` timestamp DEFAULT NULL COMMENT '开始时间',
-  `finish_time` timestamp DEFAULT NULL COMMENT '结束时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `start_time` timestamp NULL COMMENT '开始时间',
+  `finish_time` timestamp NULL COMMENT '结束时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='异步任务';
 
@@ -789,8 +789,8 @@ CREATE TABLE `t_b_user` (
   `mobile_number` varchar(30) DEFAULT NULL COMMENT '手机号',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
   `org_id` bigint DEFAULT NULL COMMENT '机构id',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `remark` varchar(100) DEFAULT NULL COMMENT '备注',
   `name` varchar(50) NOT NULL COMMENT '姓名',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
@@ -895,8 +895,8 @@ CREATE TABLE `t_e_exam` (
   `camera_photo_upload` tinyint DEFAULT NULL COMMENT '是否允许使用摄像头拍照答题,0:不允许,1:允许',
   `reexam_auditing` tinyint DEFAULT NULL COMMENT '重考是否审批,0:不审批,1:审批',
   `show_objective_score` tinyint DEFAULT NULL COMMENT '交卷后是否显示客观得分,0:不显示,1:显示',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `mode` varchar(30) DEFAULT NULL COMMENT '模式,together:集中统一,anytime:随到随考',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
   `archived` tinyint DEFAULT NULL COMMENT '是否归档,0:不归档,1:归档',
@@ -947,10 +947,10 @@ CREATE TABLE `t_e_exam_activity` (
   `max_duration_seconds` int DEFAULT NULL COMMENT '最大考试时长',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
   `opening_seconds` int DEFAULT NULL COMMENT '允许开考时长(分钟)',
-  `start_time` timestamp DEFAULT NULL COMMENT '开考时间',
-  `finish_time` timestamp DEFAULT NULL COMMENT '结束时间',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `start_time` timestamp NULL COMMENT '开考时间',
+  `finish_time` timestamp NULL COMMENT '结束时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   PRIMARY KEY (`id`),
@@ -980,9 +980,9 @@ CREATE TABLE `t_e_exam_breach_log` (
   `description` mediumtext COMMENT '描述',
   `status` tinyint DEFAULT NULL COMMENT '状态,0:处理,1:撤销',
   `remark` mediumtext COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `update_id` bigint DEFAULT NULL COMMENT '更新人',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生违纪处理';
@@ -1010,9 +1010,9 @@ CREATE TABLE `t_e_exam_course` (
   `audio_play_count` int DEFAULT NULL COMMENT '音频播放次数',
   `has_audio` varchar(30) DEFAULT NULL COMMENT '是否包含音频题目,0:不包含,1:包含',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   PRIMARY KEY (`id`),
   UNIQUE KEY `t_e_exam_course_examId_courseCode_Idx` (`exam_id`,`course_code`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考试科目';
@@ -1039,8 +1039,8 @@ CREATE TABLE `t_e_exam_paper` (
   `decrypt_secret` varchar(50) DEFAULT NULL COMMENT '解密密钥',
   `encrypt_mode` varchar(30) DEFAULT NULL COMMENT 'auto:自动,hand:手动',
   `need_voice_answer` tinyint DEFAULT NULL COMMENT '是否需要语音作答,0:不需要,1:需要',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `exam_id` bigint DEFAULT NULL COMMENT '考试批次id',
   `code` varchar(50) DEFAULT NULL COMMENT '试卷编码',
   `answer_path` varchar(100) DEFAULT NULL COMMENT '标答路径',
@@ -1087,12 +1087,12 @@ CREATE TABLE `t_e_exam_reexam` (
   `status` tinyint DEFAULT NULL COMMENT '状态,0:无需审核,1:待审核,2:已审核',
   `auditing_id` bigint DEFAULT NULL COMMENT '待审核人id',
   `auditing_status` tinyint DEFAULT NULL COMMENT '审核状态,0:通过,1:不通过',
-  `auditing_time` timestamp DEFAULT NULL COMMENT '审核时间',
+  `auditing_time` timestamp NULL COMMENT '审核时间',
   `auditing_suggest` varchar(1000) DEFAULT NULL COMMENT '审批意见',
   `remark` varchar(1000) DEFAULT NULL COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生重考处理';
 
@@ -1126,8 +1126,8 @@ CREATE TABLE `t_e_exam_student` (
   `select_record_id` bigint DEFAULT NULL COMMENT '最终生效的记录ID',
   `room_name` varchar(100) DEFAULT NULL COMMENT '考场名称',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   `grade` varchar(50) DEFAULT NULL COMMENT '年级',
@@ -1163,7 +1163,7 @@ CREATE TABLE `t_e_exam_student_log` (
   `type` varchar(30) DEFAULT NULL COMMENT '类型',
   `info` varchar(1000) DEFAULT NULL COMMENT '描述',
   `remark` mediumtext COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='考生轨迹';
 
@@ -1177,8 +1177,8 @@ CREATE TABLE `t_e_simulate_paper` (
   `name` varchar(100) NOT NULL COMMENT '试卷名称',
   `total_score` double NOT NULL COMMENT '总分',
   `paper_path` varchar(100) DEFAULT NULL COMMENT '题干路径',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '修改时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '修改时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '修改人id',
   PRIMARY KEY (`id`)
@@ -1197,9 +1197,9 @@ CREATE TABLE `t_e_student` (
   `mobile_number` varchar(30) DEFAULT NULL COMMENT '手机号',
   `name` varchar(30) NOT NULL COMMENT '姓名',
   `gender` varchar(20) DEFAULT NULL COMMENT '性别,man:男,woman:女',
-  `base_photo_path` varchar(100) DEFAULT NULL COMMENT '底照保存地址',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `base_photo_path` varchar(500) DEFAULT NULL COMMENT '底照保存地址',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   `enable` tinyint DEFAULT '1' COMMENT '是否启用,0:停用,1:启用',
@@ -1229,7 +1229,7 @@ CREATE TABLE `t_e_user_log` (
   `type` varchar(30) NOT NULL COMMENT '类型',
   `info` varchar(1000) DEFAULT NULL COMMENT '描述',
   `remark` mediumtext COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户轨迹';
 
@@ -1247,9 +1247,9 @@ CREATE TABLE `t_ie_exam_invigilate_call` (
   `live_url` varchar(200) DEFAULT NULL COMMENT '观看地址',
   `status` varchar(30) DEFAULT NULL COMMENT '状态',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `type` varchar(100) DEFAULT NULL COMMENT '异常类型',
   `call_status` varchar(30) DEFAULT NULL COMMENT '通话状态',
   `monitor_key` varchar(50) DEFAULT NULL COMMENT '房间号',
@@ -1271,9 +1271,9 @@ CREATE TABLE `t_ie_exam_invigilate_call_log` (
   `live_url` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '观看地址',
   `status` varchar(30) DEFAULT NULL COMMENT '状态',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
   `update_id` bigint DEFAULT NULL COMMENT '修改人id',
-  `update_time` timestamp DEFAULT NULL COMMENT '修改时间',
+  `update_time` timestamp NULL COMMENT '修改时间',
   `remark` mediumtext COMMENT '备注',
   `type` varchar(100) DEFAULT NULL COMMENT '异常类型',
   `call_status` varchar(30) DEFAULT NULL COMMENT '通话状态',
@@ -1294,8 +1294,8 @@ CREATE TABLE `t_ie_exam_invigilate_notice` (
   `receive_user_id` bigint NOT NULL COMMENT '接收人id',
   `type` varchar(30) NOT NULL COMMENT '消息类型',
   `content` varchar(1000) NOT NULL COMMENT '消息内容',
-  `send_time` timestamp DEFAULT NULL COMMENT '发送时间',
-  `receive_time` timestamp DEFAULT NULL COMMENT '接收时间',
+  `send_time` timestamp NULL COMMENT '发送时间',
+  `receive_time` timestamp NULL COMMENT '接收时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考通知消息记录';
 
@@ -1312,9 +1312,11 @@ CREATE TABLE `t_ie_invigilate_exception_info` (
   `info` mediumtext COMMENT '异常信息',
   `type` varchar(30) DEFAULT NULL COMMENT '类别',
   `remark` mediumtext COMMENT '备注',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `difference` int(11) DEFAULT NULL COMMENT '处理时差,单位秒',
+  `photo_url` varchar(500) DEFAULT NULL COMMENT '图片url',
+  `video_url` varchar(500) DEFAULT NULL COMMENT '视频url',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考异常信息';
 
@@ -1333,8 +1335,10 @@ CREATE TABLE `t_ie_invigilate_warn_info` (
   `type` varchar(30) DEFAULT NULL COMMENT '类别',
   `remark` mediumtext COMMENT '备注',
   `approve_status` tinyint DEFAULT NULL COMMENT '审阅状态,0:未阅,1:已阅',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
+  `photo_url` varchar(500) DEFAULT NULL COMMENT '图片url',
+  `video_url` varchar(500) DEFAULT NULL COMMENT '视频url',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监考预警信息';
 
@@ -1416,11 +1420,11 @@ DROP TABLE IF EXISTS `t_oe_exam_break_history`;
 CREATE TABLE `t_oe_exam_break_history` (
   `id` bigint NOT NULL COMMENT '主键',
   `exam_record_id` bigint NOT NULL COMMENT '考试记录ID',
-  `break_time` timestamp DEFAULT NULL COMMENT '断点发生时间',
+  `break_time` timestamp NULL COMMENT '断点发生时间',
   `break_reason` varchar(30) DEFAULT NULL COMMENT '断点判定原因',
   `resume_reason` varchar(300) DEFAULT NULL COMMENT '提交异常原因',
-  `prepare_time` timestamp DEFAULT NULL COMMENT '恢复候考时间',
-  `start_time` timestamp DEFAULT NULL COMMENT '恢复开考时间',
+  `prepare_time` timestamp NULL COMMENT '恢复候考时间',
+  `start_time` timestamp NULL COMMENT '恢复开考时间',
   `entry_authentication_result` varchar(30) DEFAULT NULL COMMENT '恢复开考身份验证结果',
   `entry_authentication_id` bigint DEFAULT NULL COMMENT '恢复开考身份验证记录ID',
   PRIMARY KEY (`id`)
@@ -1445,7 +1449,7 @@ CREATE TABLE `t_oe_exam_monitor_exception_history` (
   `exam_record_id` bigint NOT NULL COMMENT '考试记录id',
   `source` varchar(300) NOT NULL COMMENT '开启监控的视频源',
   `type` varchar(30) DEFAULT NULL COMMENT '异常类型',
-  `time` timestamp DEFAULT NULL COMMENT '异常时间'
+  `time` timestamp NULL COMMENT '异常时间'
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='监控异常记录';
 
 -- ----------------------------
@@ -1459,19 +1463,19 @@ CREATE TABLE `t_oe_exam_record` (
   `exam_student_id` bigint NOT NULL COMMENT '考生ID',
   `paper_id` bigint NOT NULL COMMENT '实际使用的试卷ID',
   `status` varchar(30) DEFAULT NULL COMMENT '考试状态,first_prepare:首次候考,answering:正在答题,break_off:已中断,resume_prepare:断点恢复候考,finished:已结束考试,persisted:数据已保存',
-  `first_prepare_time` timestamp DEFAULT NULL COMMENT '首次进入候考时间',
-  `first_start_time` timestamp DEFAULT NULL COMMENT '首次开考时间',
-  `last_break_time` timestamp DEFAULT NULL COMMENT '最近断点时间',
-  `last_prepare_time` timestamp DEFAULT NULL COMMENT '最近恢复候考时间',
-  `last_start_time` timestamp DEFAULT NULL COMMENT '最近恢复开考时间',
+  `first_prepare_time` timestamp NULL COMMENT '首次进入候考时间',
+  `first_start_time` timestamp NULL COMMENT '首次开考时间',
+  `last_break_time` timestamp NULL COMMENT '最近断点时间',
+  `last_prepare_time` timestamp NULL COMMENT '最近恢复候考时间',
+  `last_start_time` timestamp NULL COMMENT '最近恢复开考时间',
   `left_break_resume_count` int DEFAULT NULL COMMENT '剩余断点续考次数',
   `client_current_ip` varchar(30) DEFAULT NULL COMMENT '客户端当前IP地址',
   `client_websocket_status` varchar(30) DEFAULT NULL COMMENT '客户端websocket状态',
   `client_websocket_id` varchar(50) DEFAULT NULL COMMENT '客户端websocket连接标识',
-  `client_last_sync_time` timestamp DEFAULT NULL COMMENT '客户端最近同步时间',
+  `client_last_sync_time` timestamp NULL COMMENT '客户端最近同步时间',
   `answer_progress` double DEFAULT NULL COMMENT '答题进度',
   `duration_seconds` int DEFAULT NULL COMMENT '累计考试用时',
-  `finish_time` timestamp DEFAULT NULL COMMENT '交卷时间',
+  `finish_time` timestamp NULL COMMENT '交卷时间',
   `finish_type` varchar(30) DEFAULT NULL COMMENT '交卷原因,hand:手动交卷,auto:系统交卷,breach:违纪交卷',
   `warning_count` int DEFAULT NULL COMMENT '预警次数',
   `review_result` varchar(30) DEFAULT NULL COMMENT '审核结果,pass:通过,no_pass:不通过',
@@ -1514,7 +1518,7 @@ CREATE TABLE `t_oe_exam_simulate_history` (
   `id` bigint NOT NULL COMMENT '主键',
   `student_id` bigint NOT NULL COMMENT '个人ID',
   `paper_id` bigint NOT NULL COMMENT '模拟试卷ID',
-  `finish_time` timestamp DEFAULT NULL COMMENT '最近完成时间',
+  `finish_time` timestamp NULL COMMENT '最近完成时间',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='模拟考试记录  ';
 
@@ -1528,11 +1532,11 @@ CREATE TABLE `t_oe_face_verify_history` (
   `face_count` int DEFAULT NULL COMMENT '人脸数量',
   `similarity` double DEFAULT NULL COMMENT '相似度分数',
   `realness` double DEFAULT NULL COMMENT '真实性验证结果',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `type` varchar(30) DEFAULT NULL COMMENT 'first:初次开考,recover:恢复开考,process:过程中',
   `exception` varchar(30) DEFAULT NULL COMMENT '异常类型',
-  `photo_url` varchar(100) DEFAULT NULL COMMENT '图片保存路径',
+  `photo_url` varchar(500) DEFAULT NULL COMMENT '图片保存路径',
   `time` bigint DEFAULT NULL COMMENT '时间戳',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='人脸验证记录';
@@ -1548,8 +1552,8 @@ CREATE TABLE `t_oe_liveness_verify_history` (
   `actions` varchar(2000) DEFAULT NULL COMMENT '随机动作与结果',
   `retry` int DEFAULT NULL COMMENT '重试次数',
   `pass` tinyint DEFAULT NULL COMMENT '本地验证是否通过,0:不通过,1:通过',
-  `start_time` timestamp DEFAULT NULL COMMENT '开始时间',
-  `finish_time` timestamp DEFAULT NULL COMMENT '完成时间',
+  `start_time` timestamp NULL COMMENT '开始时间',
+  `finish_time` timestamp NULL COMMENT '完成时间',
   `exception` varchar(30) DEFAULT NULL COMMENT '异常类型',
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='活体验证记录';
@@ -1564,8 +1568,8 @@ CREATE TABLE `t_oe_simulate_paper` (
   `name` varchar(50) NOT NULL COMMENT '试卷名称',
   `total_score` double DEFAULT NULL COMMENT '总分',
   `paper_path` varchar(100) DEFAULT NULL COMMENT '题干路径',
-  `create_time` timestamp DEFAULT NULL COMMENT '创建时间',
-  `update_time` timestamp DEFAULT NULL COMMENT '更新时间',
+  `create_time` timestamp NULL COMMENT '创建时间',
+  `update_time` timestamp NULL COMMENT '更新时间',
   `create_id` bigint DEFAULT NULL COMMENT '创建人id',
   `update_id` bigint DEFAULT NULL COMMENT '更新人id',
   PRIMARY KEY (`id`)

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

@@ -468,5 +468,122 @@
 		where f.paper_id = #{paperId}
 		limit 1
 	</select>
-	
+
+	<select id="patrolReport" resultType="com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean">
+		select
+		t.roomCode,
+		t.roomName,
+		sum(t.warningCount) as warningCount,
+		count(t.client_websocket_status) as clientWebsocketStatusCount
+		from
+		(
+		select
+		s.room_code roomCode, s.room_name roomName, IFNULL(t.warning_count,
+		0) as warningCount, t.client_websocket_status
+		from
+		t_oe_exam_record t
+		left join t_e_exam_student s on
+		t.exam_student_id = s.id
+		left join t_e_exam tee on
+		tee.id = t.exam_id
+		left join t_e_exam_activity teea on
+		teea.id = t.exam_activity_id
+		inner join (
+		select
+		toer.id
+		from
+		t_oe_exam_record toer
+		where
+		EXISTS(
+		select
+		tees.id
+		from
+		t_e_exam_student tees
+		where
+		EXISTS (
+		select
+		distinct tbeiu.room_code
+		from
+		t_b_exam_invigilate_user tbeiu
+		where
+		<if test="userId != null and userId != ''">
+			tbeiu.user_id = #{userId} and
+		</if>
+		tbeiu.room_code = tees.room_code
+		and toer.exam_student_id = tees.id))) t1 on
+		t1.id = t.id
+		<where> 1 = 1
+			<if test="examId != null and examId != ''">
+				and t.exam_id = #{examId}
+			</if>
+			and s.enable = 1
+			and tee.enable = 1
+			and teea.enable = 1
+			and teea.finish_time > now()
+			and t.client_websocket_status = 'OFF_LINE'
+		</where> ) t
+		group by
+		t.roomCode,
+		t.roomName
+		order by t.roomCode
+	</select>
+
+	<select id="examInvigilateReport" resultType="com.qmth.themis.business.bean.backend.InvigilateListPatrolReportBean">
+		select
+		t.roomCode,
+		t.roomName,
+		sum(t.warningCount) as warningCount,
+		count(t.client_websocket_status) as clientWebsocketStatusCount
+		from
+		(
+		select
+		s.room_code roomCode, s.room_name roomName, IFNULL(t.warning_count,
+		0) as warningCount, t.client_websocket_status
+		from
+		t_oe_exam_record t
+		left join t_e_exam_student s on
+		t.exam_student_id = s.id
+		left join t_e_exam tee on
+		tee.id = t.exam_id
+		left join t_e_exam_activity teea on
+		teea.id = t.exam_activity_id
+		inner join (
+		select
+		toer.id
+		from
+		t_oe_exam_record toer
+		where
+		EXISTS(
+		select
+		tees.id
+		from
+		t_e_exam_student tees
+		where
+		EXISTS (
+		select
+		distinct tbeiu.room_code
+		from
+		t_b_exam_invigilate_user tbeiu
+		where
+		<if test="userId != null and userId != ''">
+			tbeiu.user_id = #{userId} and
+		</if>
+		tbeiu.room_code = tees.room_code
+		and toer.exam_student_id = tees.id))) t1 on
+		t1.id = t.id
+		<where> 1 = 1
+			<if test="examId != null and examId != ''">
+				and t.exam_id = #{examId}
+			</if>
+			and s.enable = 1
+			and tee.enable = 1
+			and teea.enable = 1
+			and teea.finish_time > now()
+			and t.client_websocket_status = 'OFF_LINE'
+		</where> ) t
+		group by
+		t.roomCode,
+		t.roomName
+		order by t.roomCode
+	</select>
 </mapper>