【修改】 1、时间闪烁问题;2、学生端登录概率没有检测到考试中;3、监控页面停止考试,增加考试时间操作更新ws
This commit is contained in:
@@ -33,6 +33,7 @@ import pc.exam.pp.module.exam.service.stuPaperScore.StuPaperScoreService;
|
|||||||
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
|
import pc.exam.pp.module.exam.service.stu_paper_file.StuPaperFileService;
|
||||||
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.*;
|
import pc.exam.pp.module.judgement.controller.admin.autoTools.vo.*;
|
||||||
import pc.exam.pp.module.judgement.service.TaskManager;
|
import pc.exam.pp.module.judgement.service.TaskManager;
|
||||||
|
import pc.exam.pp.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -48,7 +49,7 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/tool")
|
@RequestMapping("/tool")
|
||||||
@Tag(name = "测试判分")
|
@Tag(name = "学生端WS交互")
|
||||||
@Validated
|
@Validated
|
||||||
public class AutoToolsController {
|
public class AutoToolsController {
|
||||||
@Resource
|
@Resource
|
||||||
@@ -144,6 +145,7 @@ public class AutoToolsController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/startExam")
|
@PostMapping("/startExam")
|
||||||
public CommonResult<String> startExam(@RequestBody StuInTheExam stuInTheExam) {
|
public CommonResult<String> startExam(@RequestBody StuInTheExam stuInTheExam) {
|
||||||
|
|
||||||
HttpServletRequest request = ServletUtils.getRequest();
|
HttpServletRequest request = ServletUtils.getRequest();
|
||||||
// 获取登录token
|
// 获取登录token
|
||||||
String token = null;
|
String token = null;
|
||||||
@@ -152,6 +154,12 @@ public class AutoToolsController {
|
|||||||
securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
|
securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
|
||||||
// 获取登录用户
|
// 获取登录用户
|
||||||
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
|
||||||
|
// userId 是否存在
|
||||||
|
String wsKey = taskManager.getTaskById(String.valueOf(loginUser.getId()));
|
||||||
|
if (wsKey != null) {
|
||||||
|
// 停止任务
|
||||||
|
taskManager.stopTask(wsKey);
|
||||||
|
}
|
||||||
int startTime = 0;
|
int startTime = 0;
|
||||||
// 查找对应的task
|
// 查找对应的task
|
||||||
EducationPaperParam educationPaperParam = educationPaperParamService.selectEducationPaperParamByTaskId(stuInTheExam.getTaskId());
|
EducationPaperParam educationPaperParam = educationPaperParamService.selectEducationPaperParamByTaskId(stuInTheExam.getTaskId());
|
||||||
@@ -202,9 +210,7 @@ public class AutoToolsController {
|
|||||||
// 返回数据-网络状态
|
// 返回数据-网络状态
|
||||||
stuTheExamInfo.setNetwork("强");
|
stuTheExamInfo.setNetwork("强");
|
||||||
// 创建对应的线程池
|
// 创建对应的线程池
|
||||||
if (loginUser != null) {
|
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId());
|
||||||
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId());
|
|
||||||
}
|
|
||||||
return CommonResult.success(token);
|
return CommonResult.success(token);
|
||||||
}
|
}
|
||||||
return CommonResult.success("未登录");
|
return CommonResult.success("未登录");
|
||||||
@@ -235,8 +241,6 @@ public class AutoToolsController {
|
|||||||
key = loginUser.getId() + "_" + monitorDO.getTaskId() + "_" + paperId;
|
key = loginUser.getId() + "_" + monitorDO.getTaskId() + "_" + paperId;
|
||||||
return CommonResult.success(key);
|
return CommonResult.success(key);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return CommonResult.success("0");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -256,19 +260,20 @@ public class AutoToolsController {
|
|||||||
// 如果继续考试,需要关闭之前的,重新开始ws
|
// 如果继续考试,需要关闭之前的,重新开始ws
|
||||||
String taskManagerId = loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId();
|
String taskManagerId = loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId();
|
||||||
taskManager.stopTask(taskManagerId);
|
taskManager.stopTask(taskManagerId);
|
||||||
if (loginUser != null) {
|
// 获取试卷详情
|
||||||
// 获取试卷详情
|
ExamPaperVo examPaperVo = educationPaperQuService.selectPaperQuListByPaperId(stuInTheExam.getPaperId());
|
||||||
ExamPaperVo examPaperVo = educationPaperQuService.selectPaperQuListByPaperId(stuInTheExam.getPaperId());
|
// 获取剩余的时间
|
||||||
// 获取剩余的时间
|
String key = "userCache:" + stuInTheExam.getTaskId() + ":" + loginUser.getId();
|
||||||
String key = "userCache:" + stuInTheExam.getTaskId() + ":" + loginUser.getId();
|
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||||
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
if (info != null) {
|
||||||
if (info != null) {
|
// 获取随机ID
|
||||||
// 获取随机ID
|
String temporaryId = info.getTemporaryId();
|
||||||
String temporaryId = info.getTemporaryId();
|
// 获取交互时间,作用:暂停时间,仅限于非考试
|
||||||
// 获取开始时间
|
long times = 0;
|
||||||
String startTimeExam = info.getStartTime();
|
if (!info.getTaskType().equals("1")) {
|
||||||
|
String interactiveTime = info.getInteractiveTime();
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
LocalDateTime targetTime = LocalDateTime.parse(startTimeExam, formatter);
|
LocalDateTime targetTime = LocalDateTime.parse(interactiveTime, formatter);
|
||||||
LocalDateTime currentTime = LocalDateTime.now();
|
LocalDateTime currentTime = LocalDateTime.now();
|
||||||
Duration duration = Duration.between(currentTime, targetTime);
|
Duration duration = Duration.between(currentTime, targetTime);
|
||||||
// 两者相差的时间
|
// 两者相差的时间
|
||||||
@@ -276,7 +281,159 @@ public class AutoToolsController {
|
|||||||
// 获取一共要考试多长时间
|
// 获取一共要考试多长时间
|
||||||
long remainingTime = info.getRemainingTime();
|
long remainingTime = info.getRemainingTime();
|
||||||
// 判断剩余时间是否大于等于两者相差的时间
|
// 判断剩余时间是否大于等于两者相差的时间
|
||||||
long times = remainingTime - Math.abs(secondsDifference);
|
times = remainingTime - Math.abs(secondsDifference);
|
||||||
|
} else {
|
||||||
|
// 考试状态下的
|
||||||
|
// 自动计算剩余的考试时间,就是不进行暂停时间,想要增加时间需要手动添加
|
||||||
|
// 获取考试结束时间
|
||||||
|
String endTime = info.getEndTime();
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
LocalDateTime targetTime = LocalDateTime.parse(endTime, formatter);
|
||||||
|
LocalDateTime currentTime = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(currentTime, targetTime);
|
||||||
|
// 两者相差的时间
|
||||||
|
long secondsDifference = duration.getSeconds();
|
||||||
|
if (secondsDifference > 0) {
|
||||||
|
return CommonResult.error(1_0001_003,"考试已经结束,无法继续考试");
|
||||||
|
}
|
||||||
|
// 判断剩余时间是否大于等于两者相差的时间
|
||||||
|
times = secondsDifference;
|
||||||
|
}
|
||||||
|
// 开启ws
|
||||||
|
// 获取上传文件时间
|
||||||
|
String time = examPaperVo.getEducationPaperParam().getUploadTime();
|
||||||
|
// 将分钟继续转换成秒
|
||||||
|
stuInTheExam.setTimes(Integer.parseInt(time) * 60);
|
||||||
|
// 倒计时
|
||||||
|
AtomicInteger countdown = new AtomicInteger((int) times);
|
||||||
|
// 创建初始返回数据
|
||||||
|
StuTheExamInfo stuTheExamInfo = new StuTheExamInfo();
|
||||||
|
// 返回数据-剩余时间
|
||||||
|
stuTheExamInfo.setTime(formatLongDuration(countdown.get()));
|
||||||
|
// 返回数据-上传文件状态 0:上传;1:不上传
|
||||||
|
stuTheExamInfo.setUpload(1);
|
||||||
|
// 返回数据-结束考试 0:结束;1:不结束
|
||||||
|
stuTheExamInfo.setEndStatus(1);
|
||||||
|
// 返回数据-网络状态
|
||||||
|
stuTheExamInfo.setNetwork("强");
|
||||||
|
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId());
|
||||||
|
// 将数组的值进行复制
|
||||||
|
BeanUtils.copyProperties(examPaperVo, examRestartPaperVo);
|
||||||
|
examRestartPaperVo.setWsToken(token);
|
||||||
|
// 查询学生文件下载地址
|
||||||
|
examRestartPaperVo.setTemporaryId(temporaryId);
|
||||||
|
List<StuPaperFileDO> stuPaperFileS = stuPaperFileService.findByStuIDAndPaperId(loginUser.getId(), stuInTheExam.getPaperId(), temporaryId);
|
||||||
|
stuPaperFileS.forEach(stuPaperFileDO -> {
|
||||||
|
if (stuPaperFileDO.getType() == 0) {
|
||||||
|
// 将文件地址存放,方便前端继续下载处理
|
||||||
|
examRestartPaperVo.setFileUrl(stuPaperFileDO.getUrl());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return CommonResult.success(examRestartPaperVo);
|
||||||
|
} else {
|
||||||
|
return CommonResult.error(1_0001_001,"没有找到对应的考试信息");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止考试
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
@GetMapping("/stopExam")
|
||||||
|
public CommonResult<Boolean> stopExam(@RequestParam("taskId") String taskId, @RequestParam("paperId") String paperId) {
|
||||||
|
String userId = null;
|
||||||
|
userId = String.valueOf(SecurityFrameworkUtils.getLoginUserId());
|
||||||
|
// 将userId 拼接 taskId 作为key
|
||||||
|
// 防止不同试卷ID冲突
|
||||||
|
userId += "_" + taskId + "_" + paperId;
|
||||||
|
// 删除对应的线程池
|
||||||
|
taskManager.stopTask(userId);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止考试(更改考试状态,管理员操作)
|
||||||
|
*
|
||||||
|
* @return true
|
||||||
|
*/
|
||||||
|
@GetMapping("/stopExamForAdmin")
|
||||||
|
public CommonResult<Boolean> stopExamForAdmin(@RequestParam("userId") String userId, @RequestParam("taskId") String taskId, @RequestParam("paperNum") String paperNum) {
|
||||||
|
String paperId = educationPaperService.selectPaperByPaperNum(paperNum);
|
||||||
|
// 将userId 拼接 taskId 作为key
|
||||||
|
// 防止不同试卷ID冲突
|
||||||
|
userId += "_" + taskId + "_" + paperId;
|
||||||
|
// 删除对应的线程池
|
||||||
|
taskManager.stopTask(userId);
|
||||||
|
return CommonResult.success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 学生端考试没有结束对出,继续进行开始(需要返回下载文件地址,任务ID)
|
||||||
|
@PostMapping("/reStartExamForAdmin")
|
||||||
|
public CommonResult<ExamRestartPaperVo> reStartExamForAdmin(@RequestBody StuInTheExam stuInTheExam) {
|
||||||
|
// 获取学生ID
|
||||||
|
String stuId = stuInTheExam.getStuId();
|
||||||
|
String taskId = stuInTheExam.getTaskId();
|
||||||
|
String token = "";
|
||||||
|
// 通过学生ID查询token
|
||||||
|
Set<String> oauth2_access_token_set = stringRedisTemplate.keys("oauth2_access_token:*");
|
||||||
|
for (String oauth2_access_token : oauth2_access_token_set) {
|
||||||
|
OAuth2AccessTokenDO oAuth2AccessTokenDO = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(oauth2_access_token), OAuth2AccessTokenDO.class);
|
||||||
|
// 判断账号是否登录过
|
||||||
|
if (oAuth2AccessTokenDO != null && String.valueOf(oAuth2AccessTokenDO.getUserId()).equals(stuId)) {
|
||||||
|
// 说明登录了,别的地方登录了,请重新登录
|
||||||
|
token = oAuth2AccessTokenDO.getAccessToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String paperId = educationPaperService.selectPaperByPaperNum(stuInTheExam.getPaperId());
|
||||||
|
HttpServletRequest request = ServletUtils.getRequest();
|
||||||
|
ExamRestartPaperVo examRestartPaperVo = new ExamRestartPaperVo();
|
||||||
|
// 如果继续考试,需要关闭之前的,重新开始ws
|
||||||
|
String taskManagerId = stuId + "_" + taskId + "_" + paperId;
|
||||||
|
taskManager.stopTask(taskManagerId);
|
||||||
|
if (stuId != null) {
|
||||||
|
// 获取试卷详情
|
||||||
|
ExamPaperVo examPaperVo = educationPaperQuService.selectPaperQuListByPaperId(paperId);
|
||||||
|
// 获取剩余的时间
|
||||||
|
String key = "userCache:" + taskId + ":" + stuId;
|
||||||
|
MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class);
|
||||||
|
if (info != null) {
|
||||||
|
// 获取随机ID
|
||||||
|
String temporaryId = info.getTemporaryId();
|
||||||
|
// 获取交互时间,作用:暂停时间,仅限于非考试
|
||||||
|
long times = 0;
|
||||||
|
if (!info.getTaskType().equals("1")) {
|
||||||
|
String interactiveTime = info.getInteractiveTime();
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
LocalDateTime targetTime = LocalDateTime.parse(interactiveTime, formatter);
|
||||||
|
LocalDateTime currentTime = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(currentTime, targetTime);
|
||||||
|
// 两者相差的时间
|
||||||
|
long secondsDifference = duration.getSeconds();
|
||||||
|
// 获取一共要考试多长时间
|
||||||
|
long remainingTime = info.getRemainingTime();
|
||||||
|
// 判断剩余时间是否大于等于两者相差的时间
|
||||||
|
times = remainingTime - Math.abs(secondsDifference);
|
||||||
|
} else {
|
||||||
|
// 考试状态下的
|
||||||
|
// 自动计算剩余的考试时间,就是不进行暂停时间,想要增加时间需要手动添加
|
||||||
|
// 获取考试结束时间
|
||||||
|
String endTime = info.getEndTime();
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
LocalDateTime targetTime = LocalDateTime.parse(endTime, formatter);
|
||||||
|
LocalDateTime currentTime = LocalDateTime.now();
|
||||||
|
Duration duration = Duration.between(currentTime, targetTime);
|
||||||
|
// 两者相差的时间
|
||||||
|
long secondsDifference = duration.getSeconds();
|
||||||
|
if (secondsDifference > 0) {
|
||||||
|
return CommonResult.error(1_0001_003,"考试已经结束,无法继续考试");
|
||||||
|
}
|
||||||
|
// 判断剩余时间是否大于等于两者相差的时间
|
||||||
|
times = secondsDifference;
|
||||||
|
}
|
||||||
// 开启ws
|
// 开启ws
|
||||||
// 获取上传文件时间
|
// 获取上传文件时间
|
||||||
String time = examPaperVo.getEducationPaperParam().getUploadTime();
|
String time = examPaperVo.getEducationPaperParam().getUploadTime();
|
||||||
@@ -294,13 +451,13 @@ public class AutoToolsController {
|
|||||||
stuTheExamInfo.setEndStatus(1);
|
stuTheExamInfo.setEndStatus(1);
|
||||||
// 返回数据-网络状态
|
// 返回数据-网络状态
|
||||||
stuTheExamInfo.setNetwork("强");
|
stuTheExamInfo.setNetwork("强");
|
||||||
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), loginUser.getId() + "_" + stuInTheExam.getTaskId() + "_" + stuInTheExam.getPaperId());
|
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), stuId + "_" + stuInTheExam.getTaskId() + "_" + paperId);
|
||||||
// 将数组的值进行复制
|
// 将数组的值进行复制
|
||||||
BeanUtils.copyProperties(examPaperVo, examRestartPaperVo);
|
BeanUtils.copyProperties(examPaperVo, examRestartPaperVo);
|
||||||
examRestartPaperVo.setWsToken(token);
|
examRestartPaperVo.setWsToken(token);
|
||||||
// 查询学生文件下载地址
|
// 查询学生文件下载地址
|
||||||
examRestartPaperVo.setTemporaryId(temporaryId);
|
examRestartPaperVo.setTemporaryId(temporaryId);
|
||||||
List<StuPaperFileDO> stuPaperFileS = stuPaperFileService.findByStuIDAndPaperId(loginUser.getId(), stuInTheExam.getPaperId(), temporaryId);
|
List<StuPaperFileDO> stuPaperFileS = stuPaperFileService.findByStuIDAndPaperId(Long.valueOf(stuId), paperId, temporaryId);
|
||||||
stuPaperFileS.forEach(stuPaperFileDO -> {
|
stuPaperFileS.forEach(stuPaperFileDO -> {
|
||||||
if (stuPaperFileDO.getType() == 0) {
|
if (stuPaperFileDO.getType() == 0) {
|
||||||
// 将文件地址存放,方便前端继续下载处理
|
// 将文件地址存放,方便前端继续下载处理
|
||||||
@@ -315,27 +472,6 @@ public class AutoToolsController {
|
|||||||
return CommonResult.error(1_0001_002,"没有找到对应的学生信息");
|
return CommonResult.error(1_0001_002,"没有找到对应的学生信息");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 停止考试
|
|
||||||
*
|
|
||||||
* @return true
|
|
||||||
*/
|
|
||||||
@GetMapping("/stopExam")
|
|
||||||
public CommonResult<Boolean> stopExam(@RequestParam("taskId") String taskId, @RequestParam("paperId") String paperId) {
|
|
||||||
HttpServletRequest request = ServletUtils.getRequest();
|
|
||||||
String userId = null;
|
|
||||||
if (request != null) {
|
|
||||||
userId = String.valueOf(SecurityFrameworkUtils.getLoginUserId());
|
|
||||||
// 将userId 拼接 taskId 作为key
|
|
||||||
// 防止不同试卷ID冲突
|
|
||||||
userId += "_" + taskId + "_" + paperId;
|
|
||||||
// 删除对应的线程池
|
|
||||||
taskManager.stopTask(userId);
|
|
||||||
return CommonResult.success(true);
|
|
||||||
}
|
|
||||||
return CommonResult.success(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 时间转换
|
// 时间转换
|
||||||
public static String formatLongDuration(int totalSeconds) {
|
public static String formatLongDuration(int totalSeconds) {
|
||||||
return TaskManager.formatLongDuration(totalSeconds);
|
return TaskManager.formatLongDuration(totalSeconds);
|
||||||
|
@@ -6,7 +6,7 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class StuInTheExam {
|
public class StuInTheExam {
|
||||||
// 学生ID
|
// 学生ID
|
||||||
// private String stuId;
|
private String stuId;
|
||||||
// 倒计时开始时间 单位秒
|
// 倒计时开始时间 单位秒
|
||||||
private int startTimes;
|
private int startTimes;
|
||||||
// 定时上传文件时间
|
// 定时上传文件时间
|
||||||
|
Reference in New Issue
Block a user