|
@@ -6,19 +6,18 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.qmth.themis.business.annotation.ApiJsonObject;
|
|
import com.qmth.themis.business.annotation.ApiJsonObject;
|
|
import com.qmth.themis.business.annotation.ApiJsonProperty;
|
|
import com.qmth.themis.business.annotation.ApiJsonProperty;
|
|
import com.qmth.themis.business.base.BasePage;
|
|
import com.qmth.themis.business.base.BasePage;
|
|
|
|
+import com.qmth.themis.business.cache.RedisKeyHelper;
|
|
import com.qmth.themis.business.constant.SystemConstant;
|
|
import com.qmth.themis.business.constant.SystemConstant;
|
|
|
|
+import com.qmth.themis.business.dto.ExamPropCountDto;
|
|
import com.qmth.themis.business.dto.MqDto;
|
|
import com.qmth.themis.business.dto.MqDto;
|
|
|
|
+import com.qmth.themis.business.dto.cache.TEStudentCacheDto;
|
|
import com.qmth.themis.business.dto.request.TEExamDto;
|
|
import com.qmth.themis.business.dto.request.TEExamDto;
|
|
import com.qmth.themis.business.dto.response.TEExamQueryDto;
|
|
import com.qmth.themis.business.dto.response.TEExamQueryDto;
|
|
-import com.qmth.themis.business.entity.TBOrg;
|
|
|
|
-import com.qmth.themis.business.entity.TBUser;
|
|
|
|
-import com.qmth.themis.business.entity.TEExam;
|
|
|
|
-import com.qmth.themis.business.entity.TEExamActivity;
|
|
|
|
|
|
+import com.qmth.themis.business.entity.*;
|
|
import com.qmth.themis.business.enums.*;
|
|
import com.qmth.themis.business.enums.*;
|
|
-import com.qmth.themis.business.service.MqDtoService;
|
|
|
|
-import com.qmth.themis.business.service.TEExamActivityService;
|
|
|
|
-import com.qmth.themis.business.service.TEExamService;
|
|
|
|
|
|
+import com.qmth.themis.business.service.*;
|
|
import com.qmth.themis.business.util.JacksonUtil;
|
|
import com.qmth.themis.business.util.JacksonUtil;
|
|
|
|
+import com.qmth.themis.business.util.RedisUtil;
|
|
import com.qmth.themis.business.util.ServletUtil;
|
|
import com.qmth.themis.business.util.ServletUtil;
|
|
import com.qmth.themis.common.contanst.Constants;
|
|
import com.qmth.themis.common.contanst.Constants;
|
|
import com.qmth.themis.common.enums.ExceptionResultEnum;
|
|
import com.qmth.themis.common.enums.ExceptionResultEnum;
|
|
@@ -32,6 +31,8 @@ import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @Description: 考试批次 前端控制器
|
|
* @Description: 考试批次 前端控制器
|
|
@@ -54,6 +55,15 @@ public class TEExamController {
|
|
@Resource
|
|
@Resource
|
|
MqDtoService mqDtoService;
|
|
MqDtoService mqDtoService;
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
+ TBExamInvigilateUserService tbExamInvigilateUserService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ TEExamStudentService teExamStudentService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ RedisUtil redisUtil;
|
|
|
|
+
|
|
@ApiOperation(value = "考试批次修改/新增接口")
|
|
@ApiOperation(value = "考试批次修改/新增接口")
|
|
@RequestMapping(value = "/save", method = RequestMethod.POST)
|
|
@RequestMapping(value = "/save", method = RequestMethod.POST)
|
|
@Transactional
|
|
@Transactional
|
|
@@ -322,4 +332,94 @@ public class TEExamController {
|
|
map.put(SystemConstant.RECORDS, basePage);
|
|
map.put(SystemConstant.RECORDS, basePage);
|
|
return ResultUtil.ok(map);
|
|
return ResultUtil.ok(map);
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @ApiOperation(value = "考试属性统计接口")
|
|
|
|
+ @RequestMapping(value = "/prop/count", method = RequestMethod.POST)
|
|
|
|
+ @ApiResponses({@ApiResponse(code = 200, message = "考试批次信息", response = TEExam.class)})
|
|
|
|
+ public Result propCount(@ApiParam(value = "考试id", required = true) @RequestParam Long examId) {
|
|
|
|
+ if (Objects.isNull(examId) || Objects.equals(examId, "")) {
|
|
|
|
+ throw new BusinessException(ExceptionResultEnum.EXAM_ID_IS_NULL);
|
|
|
|
+ }
|
|
|
|
+ TBUser tbUser = (TBUser) ServletUtil.getRequestAccount();
|
|
|
|
+ TBSession tbSession = (TBSession) ServletUtil.getRequestSession();
|
|
|
|
+ if (Objects.isNull(tbSession)) {
|
|
|
|
+ throw new BusinessException(ExceptionResultEnum.LOGIN_NO);
|
|
|
|
+ }
|
|
|
|
+ //首先查询当前监考老师所要监控的roomCode
|
|
|
|
+ QueryWrapper<TBExamInvigilateUser> examInvigilateUserQueryWrapper = new QueryWrapper<>();
|
|
|
|
+ examInvigilateUserQueryWrapper.lambda().in(TBExamInvigilateUser::getUserId, tbUser.getId()).eq(TBExamInvigilateUser::getOrgId, tbUser.getOrgId());
|
|
|
|
+ List<TBExamInvigilateUser> tbExamInvigilateUserList = tbExamInvigilateUserService.list(examInvigilateUserQueryWrapper);
|
|
|
|
+ Set<String> roomCodeSet = null;
|
|
|
|
+ if (Objects.nonNull(tbExamInvigilateUserList) && tbExamInvigilateUserList.size() > 0) {
|
|
|
|
+ roomCodeSet = tbExamInvigilateUserList.stream().map(s -> s.getRoomCode()).collect(Collectors.toSet());
|
|
|
|
+ }
|
|
|
|
+ if (Objects.nonNull(roomCodeSet) || roomCodeSet.size() == 0) {
|
|
|
|
+ throw new BusinessException("当前监考老师未设置任何监考考场");
|
|
|
|
+ }
|
|
|
|
+ //根据roomCode获取当前老师所要监考的全部应考学生数
|
|
|
|
+ QueryWrapper<TEExamStudent> teExamStudentServiceQueryWrapper = new QueryWrapper<>();
|
|
|
|
+ teExamStudentServiceQueryWrapper.lambda().in(TEExamStudent::getRoomCode, roomCodeSet);
|
|
|
|
+ List<TEExamStudent> teExamStudentList = teExamStudentService.list(teExamStudentServiceQueryWrapper);
|
|
|
|
+ Set<String> studentSet = null;
|
|
|
|
+ Set<Long> examActivityIdSet = null;
|
|
|
|
+ Integer allCount = 0;
|
|
|
|
+ Integer loginCount = 0;
|
|
|
|
+ AtomicReference<Integer> prepareCount = new AtomicReference<>(0);
|
|
|
|
+ AtomicReference<Integer> examCount = new AtomicReference<>(0);
|
|
|
|
+ AtomicReference<Integer> clientCommunicationStatusCount = new AtomicReference<>(0);
|
|
|
|
+ AtomicReference<Integer> monitorStatusSourceCount = new AtomicReference<>(0);
|
|
|
|
+ AtomicReference<Integer> alreadyComplete = new AtomicReference<>(0);
|
|
|
|
+ Integer notComplete = 0;
|
|
|
|
+ if (Objects.nonNull(teExamStudentList) && teExamStudentList.size() > 0) {
|
|
|
|
+ teExamStudentList.forEach(s -> {
|
|
|
|
+ studentSet.add(SystemConstant.STUDENT + s.getStudentId());
|
|
|
|
+ examActivityIdSet.add(s.getExamActivityId());
|
|
|
|
+ });
|
|
|
|
+ allCount = studentSet.size();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //获取已登录学生
|
|
|
|
+ List<TEStudentCacheDto> teStudentCacheDto = (List<TEStudentCacheDto>) redisUtil.multiGet(studentSet);
|
|
|
|
+ if (Objects.nonNull(teExamStudentList) && teExamStudentList.size() > 0) {
|
|
|
|
+ loginCount = teStudentCacheDto.size();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //获取已待考、考试中、已完成学生
|
|
|
|
+ examActivityIdSet.forEach(s -> {
|
|
|
|
+ Map<Long, Object> objectMap = redisUtil.getHashEntries(RedisKeyHelper.examActivityRecordCacheKey(s));
|
|
|
|
+ if (Objects.nonNull(objectMap) && objectMap.size() > 0) {
|
|
|
|
+ objectMap.forEach((k, v) -> {
|
|
|
|
+ Map<String, Object> recordIdObjectMap = redisUtil.getHashEntries(RedisKeyHelper.examRecordCacheKey(k));
|
|
|
|
+ if (Objects.nonNull(recordIdObjectMap) && recordIdObjectMap.size() > 0) {
|
|
|
|
+ //客户端通讯状态
|
|
|
|
+ Integer clientStatus = Objects.isNull(recordIdObjectMap.get("clientWebsocketStatus")) ? 0 : (Integer) recordIdObjectMap.get("clientWebsocketStatus");
|
|
|
|
+ if (clientStatus == 0) {
|
|
|
|
+ clientCommunicationStatusCount.getAndSet(clientCommunicationStatusCount.get() + 1);
|
|
|
|
+ }
|
|
|
|
+ //监控端通讯状态
|
|
|
|
+ MonitorStatusSourceEnum monitorStatus = Objects.isNull(recordIdObjectMap.get("monitorStatusSource")) ? null : (MonitorStatusSourceEnum) recordIdObjectMap.get("monitorStatusSource");
|
|
|
|
+ if (Objects.nonNull(monitorStatus) && Objects.equals(monitorStatus, MonitorStatusSourceEnum.STOP)) {
|
|
|
|
+ monitorStatusSourceCount.getAndSet(monitorStatusSourceCount.get() + 1);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ ExamRecordStatusEnum examRecordStatusEnum = (ExamRecordStatusEnum) v;
|
|
|
|
+ //已待考
|
|
|
|
+ if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FIRST_PREPARE)) {
|
|
|
|
+ prepareCount.getAndSet(prepareCount.get() + 1);
|
|
|
|
+ }
|
|
|
|
+ //考试中
|
|
|
|
+ else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.ANSWERING) || Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.RESUME_PREPARE)) {
|
|
|
|
+ examCount.getAndSet(examCount.get() + 1);
|
|
|
|
+ }
|
|
|
|
+ //已完成
|
|
|
|
+ else if (Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.FINISHED) || Objects.equals(examRecordStatusEnum, ExamRecordStatusEnum.PERSISTED)) {
|
|
|
|
+ alreadyComplete.getAndSet(alreadyComplete.get() + 1);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ notComplete = allCount - alreadyComplete.get();
|
|
|
|
+ ExamPropCountDto examPropCountDto = new ExamPropCountDto(examId, allCount, loginCount, prepareCount.get(), examCount.get(), clientCommunicationStatusCount.get(), monitorStatusSourceCount.get(), alreadyComplete.get(), notComplete);
|
|
|
|
+ return ResultUtil.ok(examPropCountDto);
|
|
|
|
+ }
|
|
}
|
|
}
|