From 355c7e2b45285506bca99462fc322ebbb8ff0a9e Mon Sep 17 00:00:00 2001 From: dlaren Date: Tue, 16 Sep 2025 22:59:29 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91=201?= =?UTF-8?q?=E3=80=81=E7=9B=91=E6=8E=A7=E9=A1=B5=E9=9D=A2=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=80=83=E8=AF=95=E4=B8=AD=E7=9A=84=E8=80=83=E8=AF=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=80=83=E8=AF=95=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/monitor/MonitorController.java | 2 +- .../admin/monitor/vo/MonitorPageReqVO.java | 55 +++--- .../admin/monitor/vo/MonitorRespVO.java | 8 +- .../admin/monitor/vo/MonitorWsVo.java | 16 ++ .../admin/monitor/vo/StuMonitorStatusVo.java | 1 + .../dal/dataobject/monitor/MonitorDO.java | 6 +- .../exam/service/monitor/MonitorService.java | 2 +- .../service/monitor/MonitorServiceImpl.java | 166 ++++++++++-------- 8 files changed, 150 insertions(+), 106 deletions(-) create mode 100644 exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorWsVo.java diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/MonitorController.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/MonitorController.java index 1e96510f..9d794c34 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/MonitorController.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/MonitorController.java @@ -209,7 +209,7 @@ public class MonitorController { @PostMapping("/updateMonitorStatus") @Operation(summary = "改变考生状态") - public CommonResult updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) { + public CommonResult updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) { return success(monitorService.updateMonitorStatus(stuMonitorStatusVo)); } diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorPageReqVO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorPageReqVO.java index a18ac909..a02be5ae 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorPageReqVO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorPageReqVO.java @@ -3,10 +3,13 @@ package pc.exam.pp.module.exam.controller.admin.monitor.vo; import com.baomidou.mybatisplus.annotation.TableLogic; import lombok.*; + import java.util.*; + import io.swagger.v3.oas.annotations.media.Schema; import pc.exam.pp.framework.common.pojo.PageParam; import org.springframework.format.annotation.DateTimeFormat; + import java.time.LocalDateTime; import static pc.exam.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -16,42 +19,44 @@ import static pc.exam.pp.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) public class MonitorPageReqVO extends PageParam { -private String [] monitorId; + private String[] monitorId; -@Schema(description = "用户账号", example = "芋艿") -private String username; + @Schema(description = "用户账号", example = "芋艿") + private String username; -@Schema(description = "用户姓名", example = "赵六") -private String nickname; + @Schema(description = "用户姓名", example = "赵六") + private String nickname; -@Schema(description = "班级", example = "芋艿") -private String className; + @Schema(description = "班级", example = "芋艿") + private String className; -@Schema(description = "考试状态", example = "2") -private String examStatus; + @Schema(description = "考试状态", example = "2") + private String examStatus; -@Schema(description = "成绩") -private String score; + @Schema(description = "成绩") + private String score; -@Schema(description = "试卷编号") -private String paperNum; + @Schema(description = "试卷编号") + private String paperNum; -@Schema(description = "场次", example = "赵六") -private String taskName; + @Schema(description = "场次", example = "赵六") + private String taskName; -private String taskId; + private String taskId; -private String taskType; + private String taskType; -@Schema(description = "机器ip") -private String ip; + @Schema(description = "机器ip") + private String ip; -@Schema(description = "剩余时间") -@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) -private LocalDateTime[] remainingTime; + @Schema(description = "剩余时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] remainingTime; -@Schema(description = "创建时间") -@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) -private LocalDateTime[] createTime; + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + + } \ No newline at end of file diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorRespVO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorRespVO.java index 9c2e02c3..bc5c4bec 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorRespVO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorRespVO.java @@ -48,8 +48,12 @@ public class MonitorRespVO { @ExcelProperty(value = "剩余时间", converter = SecondsToTimeConverter.class) private String remainingTime; - - @ExcelProperty("创建时间") private LocalDateTime createTime; + @ExcelProperty("开始时间") + private String startTime; + + @ExcelProperty("结束时间") + private String endTime; + } diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorWsVo.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorWsVo.java new file mode 100644 index 00000000..904ffd61 --- /dev/null +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/MonitorWsVo.java @@ -0,0 +1,16 @@ +package pc.exam.pp.module.exam.controller.admin.monitor.vo; + +import lombok.Data; + +@Data +public class MonitorWsVo { + + private String type; + + private String stuId; + + private String taskId; + + private String paperNum; + +} diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/StuMonitorStatusVo.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/StuMonitorStatusVo.java index 9d36700b..c56e6c7f 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/StuMonitorStatusVo.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/controller/admin/monitor/vo/StuMonitorStatusVo.java @@ -9,4 +9,5 @@ import java.util.List; public class StuMonitorStatusVo { private List monitorIds; private String status; + private String times; } diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/monitor/MonitorDO.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/monitor/MonitorDO.java index 72407c1f..70f6cdf7 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/monitor/MonitorDO.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/dal/dataobject/monitor/MonitorDO.java @@ -75,12 +75,16 @@ public class MonitorDO extends BaseDO { * 临时ID */ private String temporaryId; - /** * 开始时间 */ private String startTime; + /** + * 结束时间 + */ + private String endTime; + /** * 交互时间 */ diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorService.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorService.java index 70fec9c1..63be6765 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorService.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorService.java @@ -66,5 +66,5 @@ public interface MonitorService { List getPaperTaskList(String id); //改变考生状态 - Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo); + MonitorWsVo updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo); } \ No newline at end of file diff --git a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorServiceImpl.java b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorServiceImpl.java index 2d2fe52f..2fd8c8ed 100644 --- a/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorServiceImpl.java +++ b/exam-module-exam/exam-module-exam-biz/src/main/java/pc/exam/pp/module/exam/service/monitor/MonitorServiceImpl.java @@ -55,7 +55,7 @@ import static pc.exam.pp.module.system.enums.ErrorCodeConstants.MONITOR_NOT_EXIS @Service @Validated public class MonitorServiceImpl implements MonitorService { - @Autowired + @Resource private RedisTemplate redisTemplate; @Resource private MonitorMapper monitorMapper; @@ -309,6 +309,9 @@ public class MonitorServiceImpl implements MonitorService { long finalRemaining = Math.min(remainingSeconds, examDurationSeconds); // 4. 设置和返回 info.setRemainingTime(finalRemaining); + // 5. 通过计算获取endTime考试结束时间 + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + info.setEndTime(end.format(fmt)); // 判分后更新记录 monitorMapper.updateById(info); return finalRemaining; @@ -319,6 +322,12 @@ public class MonitorServiceImpl implements MonitorService { //开启测评时长限制 没开启场次 -直接返回测评时长 if ("1".equals(educationPaperParam.getIsSession()) && "0".equals(educationPaperParam.getIsTime())) { info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay()); + // 通过计算获取endTime考试结束时间 + DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime now = LocalDateTime.now(); // 本地日期时间 + LocalDateTime target = now.plusSeconds((long) examTime.toLocalTime().toSecondOfDay()); + // 没有考场更新结束时间 + info.setEndTime(target.format(fmt)); stringRedisTemplate.opsForValue().set("userCache:" + stuMonitorPaperVo.getTaskId() + ":" + stuMonitorPaperVo.getStuId(), JsonUtils.toJsonString(info)); monitorMapper.updateById(info); return (long) examTime.toLocalTime().toSecondOfDay(); @@ -367,8 +376,9 @@ public class MonitorServiceImpl implements MonitorService { } // 重置开始时间&交互时间 if (info != null) { - info.setStartTime(null); - info.setInteractiveTime(null); + info.setStartTime(""); + info.setInteractiveTime(""); + info.setEndTime(""); } MonitorDO monitorDOs = null; if (info != null) { @@ -438,87 +448,71 @@ public class MonitorServiceImpl implements MonitorService { } @Override - public Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo) { + public MonitorWsVo updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo) { + MonitorWsVo monitorWsVo = new MonitorWsVo(); String status = stuMonitorStatusVo.getStatus(); + String times = stuMonitorStatusVo.getTimes(); List monitorIds = stuMonitorStatusVo.getMonitorIds(); - if ("1".equals(status) || "0".equals(status)) { - //新增或更新 - for (String monitorId : monitorIds) { - MonitorDO monitorDO = monitorMapper.selectById(monitorId); - String taskId = monitorDO.getTaskId(); - String stuId = monitorDO.getStuId(); - String key = "userCache:" + taskId + ":" + stuId; - monitorDO.setExamStatus(status); - monitorMapper.updateById(monitorDO); - MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class); - EducationPaperParam educationPaperParam = educationPaperParamMapper.selectEducationPaperParamByTaskId(taskId); - Time examTime = educationPaperParam.getExamTime(); - - if (info == null) { - MonitorDO monitorDO1 = monitorMapper.selectOne(new QueryWrapper().eq("stu_id", stuId).eq("task_id", taskId)); - PersonRepDto personRepDto = educationPaperPersonMapper.selectUserById(stuId); - String name = educationPaperTaskMapper.selectEducationPaperTaskNameByid(taskId); - EducationPaperTask educationPaperTask = educationPaperTaskMapper.selectEducationPaperTaskByTaskId(taskId); - monitorDO1.setScore("0"); - monitorDO1.setTaskId(taskId); - monitorDO1.setTaskType(educationPaperTask.getTaskType()); - monitorDO1.setExamStatus(status); - monitorDO1.setPaperNum(""); - monitorDO1.setIp(""); - monitorDO1.setStuId(stuId); - monitorDO1.setUsername(personRepDto.getUsername()); - monitorDO1.setNickname(personRepDto.getNickname()); - - //如果开启了 时长限制 或者考场 - if ("0".equals(educationPaperParam.getIsTime()) || "0".equals(educationPaperParam.getIsSession())) { - monitorDO1.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay()); - } - stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO1)); - monitorMapper.updateById(monitorDO1); - } else { - //如果开启了 时长限制 或者考场 - if ("0".equals(educationPaperParam.getIsTime()) || "0".equals(educationPaperParam.getIsSession())) { - info.setRemainingTime((long) examTime.toLocalTime().toSecondOfDay()); - } - info.setScore("0"); - info.setPaperNum(""); - info.setIp(""); + for (String monitorId : monitorIds) { + MonitorDO monitorDO = monitorMapper.selectById(monitorId); + // 任务ID + String taskId = monitorDO.getTaskId(); + // 学号 + String stuId = monitorDO.getStuId(); + // redis_key + String key = "userCache:" + taskId + ":" + stuId; + // 获取缓存数据 + MonitorDO info = JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(key), MonitorDO.class); + // 如果考试状态存在,更新考试状态 + if (status != null) { + if (info != null) { info.setExamStatus(status); - stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info)); + // 如果状态是0和2,清除剩余时间 + if ("0".equals(status) || "2".equals(status)) { + info.setRemainingTime(0L); + info.setPaperNum(""); + info.setIp(""); + info.setStartTime(""); + info.setEndTime(""); + info.setInteractiveTime(""); + // 更新 + stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info)); + monitorMapper.updateById(info); + monitorWsVo.setStuId(stuId); + monitorWsVo.setType("STOP"); + monitorWsVo.setTaskId(taskId); + monitorWsVo.setPaperNum(info.getPaperNum()); + return monitorWsVo; + } + // 如果是考试状态1,更新剩余时间 + if ("1".equals(status)) { + long time = parseTimeToSeconds(times); + // 当考试中的状态的时候,才获取times字段 + long nowTimes = info.getRemainingTime(); + info.setRemainingTime(nowTimes + time); + // 更新结束时间 + String endTime = info.getEndTime(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + LocalDateTime targetTime = LocalDateTime.parse(endTime, formatter); + LocalDateTime newTime = targetTime.plusSeconds(time); + String newEndTimeStr = newTime.format(formatter); + info.setEndTime(newEndTimeStr); + // 更新 + stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(info)); + monitorMapper.updateById(info); + monitorWsVo.setStuId(stuId); + monitorWsVo.setType("RESTART"); + monitorWsVo.setTaskId(taskId); + monitorWsVo.setPaperNum(info.getPaperNum()); + return monitorWsVo; + } } - - - } - - } - - if ("2".equals(status)) { - //删除 - for (String monitorId : monitorIds) { - MonitorDO monitorDO = monitorMapper.selectById(monitorId); - String taskId = monitorDO.getTaskId(); - String stuId = monitorDO.getStuId(); - String key = "userCache:" + taskId + ":" + stuId; - monitorDO.setRemainingTime(0L); - if ("0".equals(monitorDO.getTaskType())) { - monitorDO.setExamStatus("0"); - stringRedisTemplate.opsForValue().set(key, JsonUtils.toJsonString(monitorDO)); - - } else { - monitorDO.setExamStatus(status); - redisTemplate.delete(key); - } - - monitorMapper.updateById(monitorDO); - - } } - - return true; - + return monitorWsVo; } + public List filterSpecialtyList(List inputList) { if (inputList == null || inputList.isEmpty()) { return Collections.emptyList(); @@ -544,5 +538,25 @@ public class MonitorServiceImpl implements MonitorService { }).collect(Collectors.toList()); } + public static long parseTimeToSeconds(String time) { + if (time == null) throw new IllegalArgumentException("time is null"); + String t = time.trim(); + if (t.isEmpty()) throw new IllegalArgumentException("time is empty"); + String[] parts = t.split(":"); + if (parts.length < 1 || parts.length > 3) { + throw new IllegalArgumentException("Unsupported time format: " + time); + } + + long total = 0; + for (String p : parts) { + if (!p.matches("\\d+")) { + throw new IllegalArgumentException("Invalid numeric part in time: " + p); + } + int value = Integer.parseInt(p); + if (value < 0) throw new IllegalArgumentException("Negative value not allowed: " + p); + total = total * 60 + value; + } + return total; + } }