【修改】 服务器与学生端ws交互,学生端异常退出后,再次考试时间异常的情况

This commit is contained in:
dlaren
2025-09-10 09:55:21 +08:00
parent da0338111a
commit 0c7765b8aa
2 changed files with 72 additions and 77 deletions

View File

@@ -116,63 +116,61 @@ public class AutoToolsController {
securityProperties.getTokenHeader(), securityProperties.getTokenParameter()); securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
// 获取登录用户 // 获取登录用户
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
// 通过token获取用户redis信息获取refreshToken
OAuth2AccessTokenDO oAuth2AccessTokenDO = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get("oauth2_access_token:" + token), OAuth2AccessTokenDO.class);
int startTime = 0; int startTime = 0;
if (oAuth2AccessTokenDO != null) { // 查找对应的task
String refreshToken = oAuth2AccessTokenDO.getRefreshToken(); EducationPaperParam educationPaperParam = educationPaperParamService.selectEducationPaperParamByTaskId(stuInTheExam.getTaskId());
// 查找对应的task String isSession = educationPaperParam.getIsSession();
EducationPaperParam educationPaperParam = educationPaperParamService.selectEducationPaperParamByTaskId(stuInTheExam.getTaskId()); if (isSession.equals("0")) {
String isSession = educationPaperParam.getIsSession(); // 设置了场次
if (isSession.equals("0")) { // 剩余时间需要继续计算
// 设置了场次 EducationPaperPerson educationPaperPerson = educationPaperPersonMapper.selectByTaskIdAndPersonId(stuInTheExam.getTaskId(), String.valueOf(loginUser.getId()));
// 剩余时间需要继续计算 EducationPaperSession educationPaperSession = educationPaperSessionMapper.selectEducationPaperSessionBySessionId(educationPaperPerson.getSessionId());
EducationPaperPerson educationPaperPerson = educationPaperPersonMapper.selectByTaskIdAndPersonId(stuInTheExam.getTaskId(), String.valueOf(loginUser.getId())); //结束时间
EducationPaperSession educationPaperSession = educationPaperSessionMapper.selectEducationPaperSessionBySessionId(educationPaperPerson.getSessionId()); Date endTime = educationPaperSession.getEndTime();
//结束时间 Date nowTime = new Date();
Date endTime = educationPaperSession.getEndTime(); // 将 Date 转换为 Instant
Date nowTime = new Date(); Instant endInstant = endTime.toInstant();
// 将 Date 转换为 Instant Instant nowInstant = nowTime.toInstant();
Instant endInstant = endTime.toInstant(); // 计算秒数差
Instant nowInstant = nowTime.toInstant(); long diffInSeconds = Duration.between(nowInstant, endInstant).getSeconds();
// 计算秒数差 startTime = (int) diffInSeconds;
long diffInSeconds = Duration.between(nowInstant, endInstant).getSeconds(); } else {
startTime = (int) diffInSeconds; // 没有设置场次
} else { // 剩余时间直接读取数据
// 没有设置场次 String isTime = educationPaperParam.getIsTime();
if (isTime.equals("0")) {
// 设置了时间
// 剩余时间直接读取数据 // 剩余时间直接读取数据
String isTime = educationPaperParam.getIsTime(); long seconds = educationPaperParam.getExamTime().toLocalTime().toSecondOfDay();
if (isTime.equals("0")) { startTime = (int) seconds;
// 设置了时间 } else {
// 剩余时间直接读取数据 // 没有设置时间 默认1小时 = 3600秒
long seconds = educationPaperParam.getExamTime().toLocalTime().toSecondOfDay(); startTime = 3600;
startTime = (int) seconds;
} else {
// 没有设置时间 默认1小时 = 3600秒
startTime = 3600;
}
} }
// 判断是否存在对应的场次
// 定时上传文件时间
String time = educationPaperParam.getUploadTime();
// 将分钟继续转换成秒
stuInTheExam.setTimes(Integer.parseInt(time) * 60);
// 倒计时
AtomicInteger countdown = new AtomicInteger(startTime);
// 创建初始返回数据
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, refreshToken, countdown, new AtomicInteger(0));
return CommonResult.success(refreshToken);
} }
// 判断是否存在对应的场次
// 定时上传文件时间
String time = educationPaperParam.getUploadTime();
// 将分钟继续转换成秒
stuInTheExam.setTimes(Integer.parseInt(time) * 60);
// 倒计时
AtomicInteger countdown = new AtomicInteger(startTime);
// 创建初始返回数据
StuTheExamInfo stuTheExamInfo = new StuTheExamInfo();
// 返回数据-剩余时间
stuTheExamInfo.setTime(formatLongDuration(countdown.get()));
// 返回数据-上传文件状态 0上传1不上传
stuTheExamInfo.setUpload(1);
// 返回数据-上传文件状态 0结束1不结束
stuTheExamInfo.setEndStatus(1);
// 返回数据-网络状态
stuTheExamInfo.setNetwork("");
// 创建对应的线程池
if (loginUser != null) {
taskManager.startTask(stuInTheExam, stuTheExamInfo, token, countdown, new AtomicInteger(0), String.valueOf(loginUser.getId()));
}
System.out.println("--------------token------------------" + token);
return CommonResult.success(token);
} }
return CommonResult.success("未登录"); return CommonResult.success("未登录");
} }
@@ -185,17 +183,12 @@ public class AutoToolsController {
@GetMapping("/stopExam") @GetMapping("/stopExam")
public CommonResult<Boolean> stopExam() { public CommonResult<Boolean> stopExam() {
HttpServletRequest request = ServletUtils.getRequest(); HttpServletRequest request = ServletUtils.getRequest();
String token = null; String userId = null;
if (request != null) { if (request != null) {
token = SecurityFrameworkUtils.obtainAuthorization(request, userId = String.valueOf(SecurityFrameworkUtils.getLoginUserId());
securityProperties.getTokenHeader(), securityProperties.getTokenParameter()); // 删除对应的线程池
OAuth2AccessTokenDO oAuth2AccessTokenDO = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get("oauth2_access_token:" + token), OAuth2AccessTokenDO.class); taskManager.stopTask(userId);
if (oAuth2AccessTokenDO != null) { return CommonResult.success(true);
// 删除对应的线程池
String refreshToken = oAuth2AccessTokenDO.getRefreshToken();
taskManager.stopTask(refreshToken);
return CommonResult.success(true);
}
} }
return CommonResult.success(false); return CommonResult.success(false);
} }

View File

@@ -27,28 +27,30 @@ public class TaskManager {
private final Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>(); private final Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>();
/** 开始任务(每秒执行一次) */ /** 开始任务(每秒执行一次) */
public void startTask(StuInTheExam stuInTheExam, StuTheExamInfo stuTheExamInfo, String token, AtomicInteger countdown, AtomicInteger counter) { public void startTask(StuInTheExam stuInTheExam, StuTheExamInfo stuTheExamInfo, String token, AtomicInteger countdown, AtomicInteger counter, String userId) {
// 判断 token 的线程是否存在,存在则不进行任何动作 // 判断 token 的线程是否存在,存在则不进行任何动作
if (tasks.containsKey(token)) { if (tasks.containsKey(userId)) {
log.info("任务 {} 已存在,未重复启动", token); log.info("任务 {} 已存在,未重复启动", userId);
return; // TODO 删除,重置倒计时
tasks.remove(userId);
// return;
} }
tasks.computeIfAbsent(token, k -> { tasks.computeIfAbsent(userId, k -> {
Runnable task = safe(() -> { Runnable task = safe(() -> {
int current = counter.incrementAndGet(); int current = counter.incrementAndGet();
int remaining = countdown.decrementAndGet(); int remaining = countdown.decrementAndGet();
log.debug("任务 {} tick at {}", token, System.currentTimeMillis()); log.debug("任务 {} tick at {}", userId, System.currentTimeMillis());
if (current == stuInTheExam.getTimes()) { if (current == stuInTheExam.getTimes()) {
stuTheExamInfo.setUpload(0); stuTheExamInfo.setUpload(0);
counter.set(0); counter.set(0);
} }
if (remaining <= 0) { if (remaining <= 0) {
ScheduledFuture<?> future = tasks.remove(token); ScheduledFuture<?> future = tasks.remove(userId);
if (future != null) { if (future != null) {
future.cancel(false); future.cancel(false);
stuTheExamInfo.setEndStatus(0); stuTheExamInfo.setEndStatus(0);
log.info("任务 {} 已完成并取消", token); log.info("任务 {} 已完成并取消", userId);
} }
} }
stuTheExamInfo.setTime(formatLongDuration(remaining)); stuTheExamInfo.setTime(formatLongDuration(remaining));
@@ -56,18 +58,18 @@ public class TaskManager {
}); });
return scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS); return scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);
}); });
log.info("任务 {} 已启动", token); log.info("任务 {} 已启动", userId);
} }
/** 结束任务 */ /** 结束任务 */
public void stopTask(String token) { public void stopTask(String userId) {
ScheduledFuture<?> future = tasks.get(token); ScheduledFuture<?> future = tasks.get(userId);
if (future != null) { if (future != null) {
future.cancel(false); future.cancel(false);
tasks.remove(token); tasks.remove(userId);
log.info("任务 {} 已停止", token); log.info("任务 {} 已停止", userId);
} else { } else {
log.warn("任务 {} 不存在", token); log.warn("任务 {} 不存在", userId);
} }
} }