【新增】 1、监控页面支持考试中的考试增加考试时间
This commit is contained in:
@@ -209,7 +209,7 @@ public class MonitorController {
|
||||
|
||||
@PostMapping("/updateMonitorStatus")
|
||||
@Operation(summary = "改变考生状态")
|
||||
public CommonResult<Boolean> updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) {
|
||||
public CommonResult<MonitorWsVo> updateMonitorStatus(@Valid @RequestBody StuMonitorStatusVo stuMonitorStatusVo) {
|
||||
return success(monitorService.updateMonitorStatus(stuMonitorStatusVo));
|
||||
}
|
||||
|
||||
|
@@ -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[] createTime;
|
||||
|
||||
@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;
|
||||
|
||||
}
|
@@ -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;
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
}
|
@@ -9,4 +9,5 @@ import java.util.List;
|
||||
public class StuMonitorStatusVo {
|
||||
private List<String> monitorIds;
|
||||
private String status;
|
||||
private String times;
|
||||
}
|
||||
|
@@ -75,12 +75,16 @@ public class MonitorDO extends BaseDO {
|
||||
* 临时ID
|
||||
*/
|
||||
private String temporaryId;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
private String startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
private String endTime;
|
||||
|
||||
/**
|
||||
* 交互时间
|
||||
*/
|
||||
|
@@ -66,5 +66,5 @@ public interface MonitorService {
|
||||
List<EducationPaperTask> getPaperTaskList(String id);
|
||||
|
||||
//改变考生状态
|
||||
Boolean updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo);
|
||||
MonitorWsVo updateMonitorStatus(StuMonitorStatusVo stuMonitorStatusVo);
|
||||
}
|
@@ -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<String> 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<MonitorDO>().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<TentSpecialy> filterSpecialtyList(List<TentSpecialy> 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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user